From 6707a038bab02d93998b32a70cd211219fa7f7d8 Mon Sep 17 00:00:00 2001 From: Jacob Gadikian Date: Wed, 12 Apr 2023 02:45:20 +0700 Subject: [PATCH 001/131] add async-icq support to juno --- app/keepers/keepers.go | 62 ++++++++++++++++++++++++++++-------------- app/keepers/keys.go | 2 ++ app/keepers/querier.go | 25 +++++++++++++++++ app/modules.go | 9 ++++++ go.mod | 1 + go.sum | 2 ++ 6 files changed, 80 insertions(+), 21 deletions(-) create mode 100644 app/keepers/querier.go diff --git a/app/keepers/keepers.go b/app/keepers/keepers.go index 9241e07a9..894a7d537 100644 --- a/app/keepers/keepers.go +++ b/app/keepers/keepers.go @@ -72,6 +72,9 @@ import ( feesharekeeper "github.com/CosmosContracts/juno/v15/x/feeshare/keeper" feesharetypes "github.com/CosmosContracts/juno/v15/x/feeshare/types" + icqkeeper "github.com/strangelove-ventures/async-icq/v4/keeper" + icqtypes "github.com/strangelove-ventures/async-icq/v4/types" + // 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" @@ -106,6 +109,7 @@ type AppKeepers struct { UpgradeKeeper upgradekeeper.Keeper ParamsKeeper paramskeeper.Keeper IBCKeeper *ibckeeper.Keeper // IBC Keeper must be a pointer in the app, so we can SetRouter on it correctly + ICQKeeper icqkeeper.Keeper IBCFeeKeeper ibcfeekeeper.Keeper IBCHooksKeeper *ibchookskeeper.Keeper PacketForwardKeeper *packetforwardkeeper.Keeper @@ -121,6 +125,7 @@ type AppKeepers struct { // make scoped keepers public for test purposes ScopedIBCKeeper capabilitykeeper.ScopedKeeper + ScopedICQKeeper capabilitykeeper.ScopedKeeper ScopedICAControllerKeeper capabilitykeeper.ScopedKeeper ScopedFeeMockKeeper capabilitykeeper.ScopedKeeper ScopedICAHostKeeper capabilitykeeper.ScopedKeeper @@ -174,6 +179,7 @@ func NewAppKeepers( scopedIBCKeeper := appKeepers.CapabilityKeeper.ScopeToModule(ibchost.ModuleName) scopedICAControllerKeeper := appKeepers.CapabilityKeeper.ScopeToModule(icacontrollertypes.SubModuleName) scopedICAHostKeeper := appKeepers.CapabilityKeeper.ScopeToModule(icahosttypes.SubModuleName) + scopedICQKeeper := appKeepers.CapabilityKeeper.ScopeToModule(icqtypes.ModuleName) scopedTransferKeeper := appKeepers.CapabilityKeeper.ScopeToModule(ibctransfertypes.ModuleName) scopedWasmKeeper := appKeepers.CapabilityKeeper.ScopeToModule(wasm.ModuleName) @@ -322,6 +328,40 @@ func NewAppKeepers( scopedTransferKeeper, ) + // Stargate Queries + accepted := wasmkeeper.AcceptedStargateQueries{ + // ibc + "/ibc.core.client.v1.Query/ClientState": &ibcclienttypes.QueryClientStateResponse{}, + "/ibc.core.client.v1.Query/ConsensusState": &ibcclienttypes.QueryConsensusStateResponse{}, + "/ibc.core.connection.v1.Query/Connection": &ibcconnectiontypes.QueryConnectionResponse{}, + + // governance + "/cosmos.gov.v1beta1.Query/Vote": &govtypes.QueryVoteResponse{}, + + // staking + "/cosmos.staking.v1beta1.Query/Delegation": &stakingtypes.QueryDelegationResponse{}, + "/cosmos.staking.v1beta1.Query/Redelegations": &stakingtypes.QueryRedelegationsResponse{}, + "/cosmos.staking.v1beta1.Query/UnbondingDelegation": &stakingtypes.QueryUnbondingDelegationResponse{}, + "/cosmos.staking.v1beta1.Query/Validator": &stakingtypes.QueryValidatorResponse{}, + + // token factory + "/osmosis.tokenfactory.v1beta1.Query/Params": &tokenfactorytypes.QueryParamsResponse{}, + "/osmosis.tokenfactory.v1beta1.Query/DenomAuthorityMetadata": &tokenfactorytypes.QueryDenomAuthorityMetadataResponse{}, + "/osmosis.tokenfactory.v1beta1.Query/DenomsFromCreator": &tokenfactorytypes.QueryDenomsFromCreatorResponse{}, + } + + // ICQ Keeper + appKeepers.ICQKeeper = icqkeeper.NewKeeper( + appCodec, + appKeepers.keys[icqtypes.StoreKey], + appKeepers.GetSubspace(icqtypes.ModuleName), + appKeepers.IBCKeeper.ChannelKeeper, // may be replaced with middleware + appKeepers.IBCKeeper.ChannelKeeper, + &appKeepers.IBCKeeper.PortKeeper, + scopedICQKeeper, + accepted, // accept the same queries that we accept for wasm. + ) + appKeepers.PacketForwardKeeper.SetTransferKeeper(appKeepers.TransferKeeper) appKeepers.ICAHostKeeper = icahostkeeper.NewKeeper( @@ -378,27 +418,6 @@ func NewAppKeepers( tfOpts := bindings.RegisterCustomPlugins(&appKeepers.BankKeeper, &appKeepers.TokenFactoryKeeper) wasmOpts = append(wasmOpts, tfOpts...) - // Stargate Queries - accepted := wasmkeeper.AcceptedStargateQueries{ - // ibc - "/ibc.core.client.v1.Query/ClientState": &ibcclienttypes.QueryClientStateResponse{}, - "/ibc.core.client.v1.Query/ConsensusState": &ibcclienttypes.QueryConsensusStateResponse{}, - "/ibc.core.connection.v1.Query/Connection": &ibcconnectiontypes.QueryConnectionResponse{}, - - // governance - "/cosmos.gov.v1beta1.Query/Vote": &govtypes.QueryVoteResponse{}, - - // staking - "/cosmos.staking.v1beta1.Query/Delegation": &stakingtypes.QueryDelegationResponse{}, - "/cosmos.staking.v1beta1.Query/Redelegations": &stakingtypes.QueryRedelegationsResponse{}, - "/cosmos.staking.v1beta1.Query/UnbondingDelegation": &stakingtypes.QueryUnbondingDelegationResponse{}, - "/cosmos.staking.v1beta1.Query/Validator": &stakingtypes.QueryValidatorResponse{}, - - // token factory - "/osmosis.tokenfactory.v1beta1.Query/Params": &tokenfactorytypes.QueryParamsResponse{}, - "/osmosis.tokenfactory.v1beta1.Query/DenomAuthorityMetadata": &tokenfactorytypes.QueryDenomAuthorityMetadataResponse{}, - "/osmosis.tokenfactory.v1beta1.Query/DenomsFromCreator": &tokenfactorytypes.QueryDenomsFromCreatorResponse{}, - } querierOpts := wasmkeeper.WithQueryPlugins( &wasmkeeper.QueryPlugins{ Stargate: wasmkeeper.AcceptListStargateQuerier(accepted, bApp.GRPCQueryRouter(), appCodec), @@ -478,6 +497,7 @@ func NewAppKeepers( appKeepers.ScopedIBCKeeper = scopedIBCKeeper appKeepers.ScopedTransferKeeper = scopedTransferKeeper + appKeepers.ScopedICQKeeper = scopedICQKeeper appKeepers.scopedWasmKeeper = scopedWasmKeeper appKeepers.ScopedICAHostKeeper = scopedICAHostKeeper appKeepers.ScopedICAControllerKeeper = scopedICAControllerKeeper diff --git a/app/keepers/keys.go b/app/keepers/keys.go index 4a9c2934b..024141f9c 100644 --- a/app/keepers/keys.go +++ b/app/keepers/keys.go @@ -25,6 +25,7 @@ import ( ibctransfertypes "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types" ibchost "github.com/cosmos/ibc-go/v4/modules/core/24-host" ibchookstypes "github.com/osmosis-labs/osmosis/x/ibc-hooks/types" + icqtypes "github.com/strangelove-ventures/async-icq/v4/types" packetforwardtypes "github.com/strangelove-ventures/packet-forward-middleware/v4/router/types" ) @@ -37,6 +38,7 @@ func (appKeepers *AppKeepers) GenerateKeys() { authzkeeper.StoreKey, feegrant.StoreKey, icahosttypes.StoreKey, ibcfeetypes.StoreKey, tokenfactorytypes.StoreKey, feesharetypes.StoreKey, wasm.StoreKey, icacontrollertypes.StoreKey, ibchookstypes.StoreKey, packetforwardtypes.StoreKey, + icqtypes.StoreKey, ) appKeepers.tkeys = sdk.NewTransientStoreKeys(paramstypes.TStoreKey) diff --git a/app/keepers/querier.go b/app/keepers/querier.go new file mode 100644 index 000000000..692d99325 --- /dev/null +++ b/app/keepers/querier.go @@ -0,0 +1,25 @@ +// this file used from osmosis, ref: https://github.com/osmosis-labs/osmosis/blob/2ce971f4c6aa85d3ef7ba33d60e0ae74b923ab83/app/keepers/querier.go +// Original Author: https://github.com/nicolaslara + +package keepers + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + abci "github.com/tendermint/tendermint/abci/types" +) + +// QuerierWrapper is a local wrapper around BaseApp that exports only the Queryable interface. +// This is used to pass the baseApp to Async ICQ without exposing all methods +type QuerierWrapper struct { + querier sdk.Queryable +} + +var _ sdk.Queryable = QuerierWrapper{} + +func NewQuerierWrapper(querier sdk.Queryable) QuerierWrapper { + return QuerierWrapper{querier: querier} +} + +func (q QuerierWrapper) Query(req abci.RequestQuery) abci.ResponseQuery { + return q.querier.Query(req) +} diff --git a/app/modules.go b/app/modules.go index 0e71683ae..ab49ed534 100644 --- a/app/modules.go +++ b/app/modules.go @@ -52,6 +52,8 @@ import ( ibchost "github.com/cosmos/ibc-go/v4/modules/core/24-host" ibchooks "github.com/osmosis-labs/osmosis/x/ibc-hooks" ibchookstypes "github.com/osmosis-labs/osmosis/x/ibc-hooks/types" + icq "github.com/strangelove-ventures/async-icq/v4" + icqtypes "github.com/strangelove-ventures/async-icq/v4/types" packetforward "github.com/strangelove-ventures/packet-forward-middleware/v4/router" packetforwardtypes "github.com/strangelove-ventures/packet-forward-middleware/v4/router/types" ) @@ -64,6 +66,7 @@ var maccPerms = map[string][]string{ stakingtypes.BondedPoolName: {authtypes.Burner, authtypes.Staking}, stakingtypes.NotBondedPoolName: {authtypes.Burner, authtypes.Staking}, govtypes.ModuleName: {authtypes.Burner}, + icqtypes.ModuleName: nil, ibctransfertypes.ModuleName: {authtypes.Minter, authtypes.Burner}, icatypes.ModuleName: nil, ibcfeetypes.ModuleName: nil, @@ -88,6 +91,7 @@ var ModuleBasics = module.NewBasicManager( slashing.AppModuleBasic{}, ibc.AppModuleBasic{}, ibcfee.AppModuleBasic{}, + icq.AppModuleBasic{}, feegrantmodule.AppModuleBasic{}, upgrade.AppModuleBasic{}, evidence.AppModuleBasic{}, @@ -139,6 +143,8 @@ func appModules( wasm.NewAppModule(appCodec, &app.WasmKeeper, app.StakingKeeper, app.AccountKeeper, app.BankKeeper), ica.NewAppModule(&app.ICAControllerKeeper, &app.ICAHostKeeper), ibchooks.NewAppModule(app.AccountKeeper), + // IBC modules + icq.NewAppModule(app.ICQKeeper), packetforward.NewAppModule(app.PacketForwardKeeper), } } @@ -199,6 +205,7 @@ func orderBeginBlockers() []string { icatypes.ModuleName, packetforwardtypes.ModuleName, ibcfeetypes.ModuleName, + icqtypes.ModuleName, tokenfactorytypes.ModuleName, feesharetypes.ModuleName, globalfee.ModuleName, @@ -231,6 +238,7 @@ func orderEndBlockers() []string { icatypes.ModuleName, packetforwardtypes.ModuleName, ibcfeetypes.ModuleName, + icqtypes.ModuleName, tokenfactorytypes.ModuleName, feesharetypes.ModuleName, globalfee.ModuleName, @@ -263,6 +271,7 @@ func orderInitBlockers() []string { icatypes.ModuleName, packetforwardtypes.ModuleName, ibcfeetypes.ModuleName, + icqtypes.ModuleName, tokenfactorytypes.ModuleName, feesharetypes.ModuleName, globalfee.ModuleName, diff --git a/go.mod b/go.mod index b2b050b70..bda950861 100644 --- a/go.mod +++ b/go.mod @@ -17,6 +17,7 @@ require ( github.com/prometheus/client_golang v1.14.0 github.com/spf13/cast v1.5.0 github.com/spf13/cobra v1.7.0 + github.com/strangelove-ventures/async-icq/v4 v4.0.0-rc0 github.com/strangelove-ventures/packet-forward-middleware/v4 v4.0.5 github.com/stretchr/testify v1.8.2 github.com/tendermint/tendermint v0.34.27 diff --git a/go.sum b/go.sum index cf347ebef..a1d8331d2 100644 --- a/go.sum +++ b/go.sum @@ -961,6 +961,8 @@ github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DM github.com/spf13/viper v1.15.0 h1:js3yy885G8xwJa6iOISGFwd+qlUo5AvyXb7CiihdtiU= github.com/spf13/viper v1.15.0/go.mod h1:fFcTBJxvhhzSJiZy8n+PeW6t8l+KeT/uTARa0jHOQLA= github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4/go.mod h1:RZLeN1LMWmRsyYjvAu+I6Dm9QmlDaIIt+Y+4Kd7Tp+Q= +github.com/strangelove-ventures/async-icq/v4 v4.0.0-rc0 h1:foE/5O2/XiqGsdTKx3R0BTfKgW9KnUYyQLZt0WFSesE= +github.com/strangelove-ventures/async-icq/v4 v4.0.0-rc0/go.mod h1:thzXHoaK1MgPDCjN7Rp9A/VcHA4cmjQpKCtVNt2O2xk= github.com/strangelove-ventures/packet-forward-middleware/v4 v4.0.5 h1:KKUqeGhVBK38+1LwThC8IeIcsJZ6COX5kvhiJroFqCM= github.com/strangelove-ventures/packet-forward-middleware/v4 v4.0.5/go.mod h1:4zAtg449/JISRmf+sbmqolqSLP+QJBh+EtWkWtt/AKE= github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= From 2aefeef5dc94046f55099faf1780a1acde22aaf4 Mon Sep 17 00:00:00 2001 From: Jacob Gadikian Date: Wed, 12 Apr 2023 02:49:22 +0700 Subject: [PATCH 002/131] save keepers.go --- app/keepers/keepers.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/keepers/keepers.go b/app/keepers/keepers.go index 894a7d537..4640eaee1 100644 --- a/app/keepers/keepers.go +++ b/app/keepers/keepers.go @@ -359,7 +359,7 @@ func NewAppKeepers( appKeepers.IBCKeeper.ChannelKeeper, &appKeepers.IBCKeeper.PortKeeper, scopedICQKeeper, - accepted, // accept the same queries that we accept for wasm. + NewQuerierWrapper(bApp), ) appKeepers.PacketForwardKeeper.SetTransferKeeper(appKeepers.TransferKeeper) From a431cc3efd5c2606484c9c80c9cc857b6f4e72cb Mon Sep 17 00:00:00 2001 From: Jacob Gadikian Date: Wed, 12 Apr 2023 02:51:57 +0700 Subject: [PATCH 003/131] create icq module, and add to ibc router --- app/keepers/keepers.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/app/keepers/keepers.go b/app/keepers/keepers.go index 4640eaee1..75a180608 100644 --- a/app/keepers/keepers.go +++ b/app/keepers/keepers.go @@ -72,6 +72,7 @@ import ( feesharekeeper "github.com/CosmosContracts/juno/v15/x/feeshare/keeper" feesharetypes "github.com/CosmosContracts/juno/v15/x/feeshare/types" + icq "github.com/strangelove-ventures/async-icq/v4" icqkeeper "github.com/strangelove-ventures/async-icq/v4/keeper" icqtypes "github.com/strangelove-ventures/async-icq/v4/types" @@ -481,12 +482,16 @@ func NewAppKeepers( wasmStack = wasm.NewIBCHandler(appKeepers.WasmKeeper, appKeepers.IBCKeeper.ChannelKeeper, appKeepers.IBCFeeKeeper) wasmStack = ibcfee.NewIBCMiddleware(wasmStack, appKeepers.IBCFeeKeeper) + // create ICQ module + icqModule := icq.NewIBCModule(appKeepers.ICQKeeper) + // Create static IBC router, add transfer route, then set and seal it ibcRouter := porttypes.NewRouter(). AddRoute(ibctransfertypes.ModuleName, transferStack). AddRoute(wasm.ModuleName, wasmStack). AddRoute(icacontrollertypes.SubModuleName, icaControllerStack). - AddRoute(icahosttypes.SubModuleName, icaHostStack) + AddRoute(icahosttypes.SubModuleName, icaHostStack). + AddRoute(icqtypes.ModuleName, icqModule) appKeepers.IBCKeeper.SetRouter(ibcRouter) From 331a47abe1b48faf14f58dbf084d607791479556 Mon Sep 17 00:00:00 2001 From: Jacob Gadikian Date: Wed, 12 Apr 2023 03:17:47 +0700 Subject: [PATCH 004/131] return the accepted stargate queries for contracts to their correct location --- app/keepers/keepers.go | 44 +++++++++++++++++++++--------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/app/keepers/keepers.go b/app/keepers/keepers.go index 75a180608..9e2c8f390 100644 --- a/app/keepers/keepers.go +++ b/app/keepers/keepers.go @@ -329,28 +329,6 @@ func NewAppKeepers( scopedTransferKeeper, ) - // Stargate Queries - accepted := wasmkeeper.AcceptedStargateQueries{ - // ibc - "/ibc.core.client.v1.Query/ClientState": &ibcclienttypes.QueryClientStateResponse{}, - "/ibc.core.client.v1.Query/ConsensusState": &ibcclienttypes.QueryConsensusStateResponse{}, - "/ibc.core.connection.v1.Query/Connection": &ibcconnectiontypes.QueryConnectionResponse{}, - - // governance - "/cosmos.gov.v1beta1.Query/Vote": &govtypes.QueryVoteResponse{}, - - // staking - "/cosmos.staking.v1beta1.Query/Delegation": &stakingtypes.QueryDelegationResponse{}, - "/cosmos.staking.v1beta1.Query/Redelegations": &stakingtypes.QueryRedelegationsResponse{}, - "/cosmos.staking.v1beta1.Query/UnbondingDelegation": &stakingtypes.QueryUnbondingDelegationResponse{}, - "/cosmos.staking.v1beta1.Query/Validator": &stakingtypes.QueryValidatorResponse{}, - - // token factory - "/osmosis.tokenfactory.v1beta1.Query/Params": &tokenfactorytypes.QueryParamsResponse{}, - "/osmosis.tokenfactory.v1beta1.Query/DenomAuthorityMetadata": &tokenfactorytypes.QueryDenomAuthorityMetadataResponse{}, - "/osmosis.tokenfactory.v1beta1.Query/DenomsFromCreator": &tokenfactorytypes.QueryDenomsFromCreatorResponse{}, - } - // ICQ Keeper appKeepers.ICQKeeper = icqkeeper.NewKeeper( appCodec, @@ -419,6 +397,28 @@ func NewAppKeepers( tfOpts := bindings.RegisterCustomPlugins(&appKeepers.BankKeeper, &appKeepers.TokenFactoryKeeper) wasmOpts = append(wasmOpts, tfOpts...) + // Stargate Queries + accepted := wasmkeeper.AcceptedStargateQueries{ + // ibc + "/ibc.core.client.v1.Query/ClientState": &ibcclienttypes.QueryClientStateResponse{}, + "/ibc.core.client.v1.Query/ConsensusState": &ibcclienttypes.QueryConsensusStateResponse{}, + "/ibc.core.connection.v1.Query/Connection": &ibcconnectiontypes.QueryConnectionResponse{}, + + // governance + "/cosmos.gov.v1beta1.Query/Vote": &govtypes.QueryVoteResponse{}, + + // staking + "/cosmos.staking.v1beta1.Query/Delegation": &stakingtypes.QueryDelegationResponse{}, + "/cosmos.staking.v1beta1.Query/Redelegations": &stakingtypes.QueryRedelegationsResponse{}, + "/cosmos.staking.v1beta1.Query/UnbondingDelegation": &stakingtypes.QueryUnbondingDelegationResponse{}, + "/cosmos.staking.v1beta1.Query/Validator": &stakingtypes.QueryValidatorResponse{}, + + // token factory + "/osmosis.tokenfactory.v1beta1.Query/Params": &tokenfactorytypes.QueryParamsResponse{}, + "/osmosis.tokenfactory.v1beta1.Query/DenomAuthorityMetadata": &tokenfactorytypes.QueryDenomAuthorityMetadataResponse{}, + "/osmosis.tokenfactory.v1beta1.Query/DenomsFromCreator": &tokenfactorytypes.QueryDenomsFromCreatorResponse{}, + } + querierOpts := wasmkeeper.WithQueryPlugins( &wasmkeeper.QueryPlugins{ Stargate: wasmkeeper.AcceptListStargateQuerier(accepted, bApp.GRPCQueryRouter(), appCodec), From 41d65ee4e7db979769cf6c8d6ff0754d440917fb Mon Sep 17 00:00:00 2001 From: Jacob Gadikian Date: Mon, 24 Apr 2023 11:41:22 +0700 Subject: [PATCH 005/131] sdk 47 upgrade --- proto/Dockerfile | 39 + proto/buf.gen.doc.yml | 5 + proto/buf.gen.gogo.yaml | 4 +- proto/buf.gen.gogo.yml | 8 + proto/buf.lock | 4 +- proto/buf.yaml | 4 +- .../v1beta1/authorityMetadata.proto | 17 + .../tokenfactory/v1beta1/genesis.proto | 32 + .../osmosis/tokenfactory/v1beta1/params.proto | 26 + .../osmosis/tokenfactory/v1beta1/query.proto | 71 + proto/osmosis/tokenfactory/v1beta1/tx.proto | 109 + x/feeshare/genesis_test.go | 2 +- x/feeshare/integration_test.go | 10 +- x/feeshare/keeper/keeper.go | 2 +- x/feeshare/keeper/keeper_test.go | 4 +- x/feeshare/module.go | 2 +- x/feeshare/types/feeshare.pb.go | 2 +- x/feeshare/types/genesis.pb.go | 2 +- x/feeshare/types/query.pb.go | 4 +- x/feeshare/types/tx.pb.go | 4 +- x/mint/client/rest/grpc_query_test.go | 2 +- x/mint/client/testutil/suite.go | 2 +- x/mint/keeper/grpc_query_test.go | 2 +- x/mint/keeper/integration_test.go | 10 +- x/mint/keeper/keeper.go | 2 +- x/mint/keeper/querier.go | 2 +- x/mint/keeper/querier_test.go | 2 +- x/mint/module.go | 2 +- x/mint/module_test.go | 6 +- x/mint/types/genesis.pb.go | 2 +- x/mint/types/mint.pb.go | 2 +- x/mint/types/query.pb.go | 4 +- x/tokenfactory/README.md | 155 + x/tokenfactory/bindings/custom_msg_test.go | 331 ++ x/tokenfactory/bindings/custom_query_test.go | 74 + x/tokenfactory/bindings/helpers_test.go | 92 + x/tokenfactory/bindings/message_plugin.go | 370 +++ x/tokenfactory/bindings/queries.go | 57 + x/tokenfactory/bindings/query_plugin.go | 122 + .../bindings/testdata/download_releases.sh | 19 + .../bindings/testdata/token_reflect.wasm | Bin 0 -> 2194768 bytes x/tokenfactory/bindings/testdata/version.txt | 1 + x/tokenfactory/bindings/types/msg.go | 68 + x/tokenfactory/bindings/types/query.go | 59 + x/tokenfactory/bindings/types/types.go | 37 + x/tokenfactory/bindings/validate_msg_test.go | 414 +++ .../bindings/validate_queries_test.go | 115 + x/tokenfactory/bindings/wasm.go | 29 + x/tokenfactory/client/cli/query.go | 122 + x/tokenfactory/client/cli/tx.go | 333 ++ x/tokenfactory/keeper/admins.go | 49 + x/tokenfactory/keeper/admins_test.go | 522 +++ x/tokenfactory/keeper/bankactions.go | 86 + x/tokenfactory/keeper/createdenom.go | 95 + x/tokenfactory/keeper/createdenom_test.go | 163 + x/tokenfactory/keeper/creators.go | 29 + x/tokenfactory/keeper/genesis.go | 58 + x/tokenfactory/keeper/genesis_test.go | 59 + x/tokenfactory/keeper/grpc_query.go | 35 + x/tokenfactory/keeper/keeper.go | 87 + x/tokenfactory/keeper/keeper_test.go | 64 + x/tokenfactory/keeper/msg_server.go | 209 ++ x/tokenfactory/keeper/msg_server_test.go | 247 ++ x/tokenfactory/keeper/params.go | 18 + x/tokenfactory/module.go | 229 ++ x/tokenfactory/simulation/genesis.go | 25 + x/tokenfactory/simulation/operations.go | 411 +++ x/tokenfactory/simulation/params.go | 23 + x/tokenfactory/testhelpers/consts.go | 8 + x/tokenfactory/testhelpers/suite.go | 66 + x/tokenfactory/types/authorityMetadata.go | 15 + x/tokenfactory/types/authorityMetadata.pb.go | 351 ++ x/tokenfactory/types/authzcodec/codec.go | 24 + x/tokenfactory/types/capabilities.go | 21 + x/tokenfactory/types/codec.go | 48 + x/tokenfactory/types/denoms.go | 68 + x/tokenfactory/types/denoms_test.go | 132 + x/tokenfactory/types/errors.go | 23 + x/tokenfactory/types/events.go | 18 + x/tokenfactory/types/expected_keepers.go | 38 + x/tokenfactory/types/genesis.go | 51 + x/tokenfactory/types/genesis.pb.go | 649 ++++ x/tokenfactory/types/genesis_test.go | 139 + x/tokenfactory/types/keys.go | 49 + x/tokenfactory/types/msgs.go | 277 ++ x/tokenfactory/types/msgs_test.go | 451 +++ x/tokenfactory/types/params.go | 70 + x/tokenfactory/types/params.pb.go | 383 +++ x/tokenfactory/types/query.pb.go | 1332 ++++++++ x/tokenfactory/types/query.pb.gw.go | 355 +++ x/tokenfactory/types/tx.pb.go | 2829 +++++++++++++++++ 91 files changed, 12553 insertions(+), 40 deletions(-) create mode 100644 proto/Dockerfile create mode 100644 proto/buf.gen.doc.yml create mode 100644 proto/buf.gen.gogo.yml create mode 100755 proto/osmosis/tokenfactory/v1beta1/authorityMetadata.proto create mode 100755 proto/osmosis/tokenfactory/v1beta1/genesis.proto create mode 100755 proto/osmosis/tokenfactory/v1beta1/params.proto create mode 100755 proto/osmosis/tokenfactory/v1beta1/query.proto create mode 100755 proto/osmosis/tokenfactory/v1beta1/tx.proto create mode 100644 x/tokenfactory/README.md create mode 100644 x/tokenfactory/bindings/custom_msg_test.go create mode 100644 x/tokenfactory/bindings/custom_query_test.go create mode 100644 x/tokenfactory/bindings/helpers_test.go create mode 100644 x/tokenfactory/bindings/message_plugin.go create mode 100644 x/tokenfactory/bindings/queries.go create mode 100644 x/tokenfactory/bindings/query_plugin.go create mode 100755 x/tokenfactory/bindings/testdata/download_releases.sh create mode 100755 x/tokenfactory/bindings/testdata/token_reflect.wasm create mode 100644 x/tokenfactory/bindings/testdata/version.txt create mode 100644 x/tokenfactory/bindings/types/msg.go create mode 100644 x/tokenfactory/bindings/types/query.go create mode 100644 x/tokenfactory/bindings/types/types.go create mode 100644 x/tokenfactory/bindings/validate_msg_test.go create mode 100644 x/tokenfactory/bindings/validate_queries_test.go create mode 100644 x/tokenfactory/bindings/wasm.go create mode 100644 x/tokenfactory/client/cli/query.go create mode 100644 x/tokenfactory/client/cli/tx.go create mode 100644 x/tokenfactory/keeper/admins.go create mode 100644 x/tokenfactory/keeper/admins_test.go create mode 100644 x/tokenfactory/keeper/bankactions.go create mode 100644 x/tokenfactory/keeper/createdenom.go create mode 100644 x/tokenfactory/keeper/createdenom_test.go create mode 100644 x/tokenfactory/keeper/creators.go create mode 100644 x/tokenfactory/keeper/genesis.go create mode 100644 x/tokenfactory/keeper/genesis_test.go create mode 100644 x/tokenfactory/keeper/grpc_query.go create mode 100644 x/tokenfactory/keeper/keeper.go create mode 100644 x/tokenfactory/keeper/keeper_test.go create mode 100644 x/tokenfactory/keeper/msg_server.go create mode 100644 x/tokenfactory/keeper/msg_server_test.go create mode 100644 x/tokenfactory/keeper/params.go create mode 100644 x/tokenfactory/module.go create mode 100644 x/tokenfactory/simulation/genesis.go create mode 100644 x/tokenfactory/simulation/operations.go create mode 100644 x/tokenfactory/simulation/params.go create mode 100644 x/tokenfactory/testhelpers/consts.go create mode 100644 x/tokenfactory/testhelpers/suite.go create mode 100644 x/tokenfactory/types/authorityMetadata.go create mode 100644 x/tokenfactory/types/authorityMetadata.pb.go create mode 100644 x/tokenfactory/types/authzcodec/codec.go create mode 100644 x/tokenfactory/types/capabilities.go create mode 100644 x/tokenfactory/types/codec.go create mode 100644 x/tokenfactory/types/denoms.go create mode 100644 x/tokenfactory/types/denoms_test.go create mode 100644 x/tokenfactory/types/errors.go create mode 100644 x/tokenfactory/types/events.go create mode 100644 x/tokenfactory/types/expected_keepers.go create mode 100644 x/tokenfactory/types/genesis.go create mode 100644 x/tokenfactory/types/genesis.pb.go create mode 100644 x/tokenfactory/types/genesis_test.go create mode 100644 x/tokenfactory/types/keys.go create mode 100644 x/tokenfactory/types/msgs.go create mode 100644 x/tokenfactory/types/msgs_test.go create mode 100644 x/tokenfactory/types/params.go create mode 100644 x/tokenfactory/types/params.pb.go create mode 100644 x/tokenfactory/types/query.pb.go create mode 100644 x/tokenfactory/types/query.pb.gw.go create mode 100644 x/tokenfactory/types/tx.pb.go diff --git a/proto/Dockerfile b/proto/Dockerfile new file mode 100644 index 000000000..f5e6f162c --- /dev/null +++ b/proto/Dockerfile @@ -0,0 +1,39 @@ +# This Dockerfile is used for proto generation +# To build, run `make proto-image-build` + +FROM bufbuild/buf:1.7.0 as BUILDER + +FROM golang:1.19-alpine + + +RUN apk add --no-cache \ + nodejs \ + npm \ + git \ + make + +ENV GOLANG_PROTOBUF_VERSION=1.28.0 \ + GOGO_PROTOBUF_VERSION=1.3.2 \ + GRPC_GATEWAY_VERSION=1.16.0 + + +RUN go install github.com/cosmos/cosmos-proto/cmd/protoc-gen-go-pulsar@latest +RUN go install google.golang.org/protobuf/cmd/protoc-gen-go@v${GOLANG_PROTOBUF_VERSION} +RUN go install github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway@v${GRPC_GATEWAY_VERSION} \ + github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger@v${GRPC_GATEWAY_VERSION} + +# install all gogo protobuf binaries +RUN git clone https://github.com/regen-network/protobuf.git; \ + cd protobuf; \ + go mod download; \ + make install + +# we need to use git clone because we use 'replace' directive in go.mod +# protoc-gen-gocosmos was moved to to in cosmos/gogoproto but pending a migration there. +RUN git clone https://github.com/regen-network/cosmos-proto.git; \ + cd cosmos-proto/protoc-gen-gocosmos; \ + go install . + +RUN npm install -g swagger-combine + +COPY --from=BUILDER /usr/local/bin /usr/local/bin diff --git a/proto/buf.gen.doc.yml b/proto/buf.gen.doc.yml new file mode 100644 index 000000000..6a18570df --- /dev/null +++ b/proto/buf.gen.doc.yml @@ -0,0 +1,5 @@ +version: v1 +plugins: + - name: doc + out: ../docs/proto + opt: ../docs/proto/protodoc-markdown.tmpl,proto-docs.md diff --git a/proto/buf.gen.gogo.yaml b/proto/buf.gen.gogo.yaml index 9c8ba0a4b..1d1910836 100644 --- a/proto/buf.gen.gogo.yaml +++ b/proto/buf.gen.gogo.yaml @@ -2,7 +2,7 @@ version: v1 plugins: - name: gocosmos out: .. - opt: plugins=grpc,Mgoogle/protobuf/any.proto=github.com/cosmos/cosmos-sdk/codec/types + opt: plugins=grpc,Mgoogle/protobuf/duration.proto=github.com/gogo/protobuf/types,Mgoogle/protobuf/struct.proto=github.com/gogo/protobuf/types,Mgoogle/protobuf/timestamp.proto=github.com/gogo/protobuf/types,Mgoogle/protobuf/wrappers.proto=github.com/gogo/protobuf/types,Mgoogle/protobuf/any.proto=github.com/cosmos/cosmos-sdk/codec/types,Mcosmos/orm/v1alpha1/orm.proto=github.com/cosmos/cosmos-sdk/api/cosmos/orm/v1alpha1 - name: grpc-gateway out: .. - opt: logtostderr=true,allow_colon_final_segments=true + opt: logtostderr=true,allow_colon_final_segments=true \ No newline at end of file diff --git a/proto/buf.gen.gogo.yml b/proto/buf.gen.gogo.yml new file mode 100644 index 000000000..855ea251a --- /dev/null +++ b/proto/buf.gen.gogo.yml @@ -0,0 +1,8 @@ +version: v1 +plugins: + - name: gocosmos + out: .. + opt: plugins=grpc,Mgoogle/protobuf/any.proto=github.com/cosmos/cosmos-sdk/codec/types + - name: grpc-gateway + out: .. + opt: logtostderr=true,allow_colon_final_segments=true \ No newline at end of file diff --git a/proto/buf.lock b/proto/buf.lock index f7e7eb4b6..fae8adcbe 100644 --- a/proto/buf.lock +++ b/proto/buf.lock @@ -8,7 +8,7 @@ deps: - remote: buf.build owner: cosmos repository: cosmos-sdk - commit: e0cedba5309948a0b4734cab8e311723 + commit: 8dc523b705c34317bfd4a961fba89e72 - remote: buf.build owner: cosmos repository: gogo-proto @@ -16,4 +16,4 @@ deps: - remote: buf.build owner: googleapis repository: googleapis - commit: 75b4300737fb4efca0831636be94e517 + commit: 5ae7f88519b04fe1965da0f8a375a088 diff --git a/proto/buf.yaml b/proto/buf.yaml index 4a643443a..c621b97be 100644 --- a/proto/buf.yaml +++ b/proto/buf.yaml @@ -1,5 +1,5 @@ version: v1 -name: buf.build/CosmosContracts/juno +name: buf.build/osmosis-labs/osmosis deps: - buf.build/cosmos/cosmos-sdk - buf.build/cosmos/cosmos-proto @@ -19,3 +19,5 @@ lint: - SERVICE_SUFFIX - PACKAGE_VERSION_SUFFIX - RPC_REQUEST_STANDARD_NAME + ignore: + - tendermint \ No newline at end of file diff --git a/proto/osmosis/tokenfactory/v1beta1/authorityMetadata.proto b/proto/osmosis/tokenfactory/v1beta1/authorityMetadata.proto new file mode 100755 index 000000000..b0c2fe756 --- /dev/null +++ b/proto/osmosis/tokenfactory/v1beta1/authorityMetadata.proto @@ -0,0 +1,17 @@ +syntax = "proto3"; +package osmosis.tokenfactory.v1beta1; + +import "gogoproto/gogo.proto"; +import "cosmos/base/v1beta1/coin.proto"; + +option go_package = "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/types"; + +// DenomAuthorityMetadata specifies metadata for addresses that have specific +// capabilities over a token factory denom. Right now there is only one Admin +// permission, but is planned to be extended to the future. +message DenomAuthorityMetadata { + option (gogoproto.equal) = true; + + // Can be empty for no admin, or a valid osmosis address + string admin = 1 [ (gogoproto.moretags) = "yaml:\"admin\"" ]; +} \ No newline at end of file diff --git a/proto/osmosis/tokenfactory/v1beta1/genesis.proto b/proto/osmosis/tokenfactory/v1beta1/genesis.proto new file mode 100755 index 000000000..a14f0336b --- /dev/null +++ b/proto/osmosis/tokenfactory/v1beta1/genesis.proto @@ -0,0 +1,32 @@ +syntax = "proto3"; +package osmosis.tokenfactory.v1beta1; + +import "gogoproto/gogo.proto"; +import "osmosis/tokenfactory/v1beta1/authorityMetadata.proto"; +import "osmosis/tokenfactory/v1beta1/params.proto"; + +option go_package = "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/types"; + +// GenesisState defines the tokenfactory module's genesis state. +message GenesisState { + // params defines the paramaters of the module. + Params params = 1 [ (gogoproto.nullable) = false ]; + + repeated GenesisDenom factory_denoms = 2 [ + (gogoproto.moretags) = "yaml:\"factory_denoms\"", + (gogoproto.nullable) = false + ]; +} + +// GenesisDenom defines a tokenfactory denom that is defined within genesis +// state. The structure contains DenomAuthorityMetadata which defines the +// denom's admin. +message GenesisDenom { + option (gogoproto.equal) = true; + + string denom = 1 [ (gogoproto.moretags) = "yaml:\"denom\"" ]; + DenomAuthorityMetadata authority_metadata = 2 [ + (gogoproto.moretags) = "yaml:\"authority_metadata\"", + (gogoproto.nullable) = false + ]; +} \ No newline at end of file diff --git a/proto/osmosis/tokenfactory/v1beta1/params.proto b/proto/osmosis/tokenfactory/v1beta1/params.proto new file mode 100755 index 000000000..36ffafa82 --- /dev/null +++ b/proto/osmosis/tokenfactory/v1beta1/params.proto @@ -0,0 +1,26 @@ +syntax = "proto3"; +package osmosis.tokenfactory.v1beta1; + +import "gogoproto/gogo.proto"; +import "osmosis/tokenfactory/v1beta1/authorityMetadata.proto"; +import "cosmos_proto/cosmos.proto"; +import "cosmos/base/v1beta1/coin.proto"; + +option go_package = "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/types"; + +// Params defines the parameters for the tokenfactory module. +message Params { + repeated cosmos.base.v1beta1.Coin denom_creation_fee = 1 [ + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", + (gogoproto.moretags) = "yaml:\"denom_creation_fee\"", + (gogoproto.nullable) = false + ]; + + // if denom_creation_fee is an empty array, then this field is used to add more gas consumption + // to the base cost. + // https://github.com/CosmWasm/token-factory/issues/11 + uint64 denom_creation_gas_consume = 2 [ + (gogoproto.moretags) = "yaml:\"denom_creation_gas_consume\"", + (gogoproto.nullable) = true + ]; +} \ No newline at end of file diff --git a/proto/osmosis/tokenfactory/v1beta1/query.proto b/proto/osmosis/tokenfactory/v1beta1/query.proto new file mode 100755 index 000000000..0d5795ce8 --- /dev/null +++ b/proto/osmosis/tokenfactory/v1beta1/query.proto @@ -0,0 +1,71 @@ +syntax = "proto3"; +package osmosis.tokenfactory.v1beta1; + +import "gogoproto/gogo.proto"; +import "google/api/annotations.proto"; +import "cosmos/base/query/v1beta1/pagination.proto"; +import "osmosis/tokenfactory/v1beta1/authorityMetadata.proto"; +import "osmosis/tokenfactory/v1beta1/params.proto"; + +option go_package = "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/types"; + +// Query defines the gRPC querier service. +service Query { + // Params defines a gRPC query method that returns the tokenfactory module's + // parameters. + rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { + option (google.api.http).get = "/osmosis/tokenfactory/v1beta1/params"; + } + + // DenomAuthorityMetadata defines a gRPC query method for fetching + // DenomAuthorityMetadata for a particular denom. + rpc DenomAuthorityMetadata(QueryDenomAuthorityMetadataRequest) + returns (QueryDenomAuthorityMetadataResponse) { + option (google.api.http).get = + "/osmosis/tokenfactory/v1beta1/denoms/{denom}/authority_metadata"; + } + + // DenomsFromCreator defines a gRPC query method for fetching all + // denominations created by a specific admin/creator. + rpc DenomsFromCreator(QueryDenomsFromCreatorRequest) + returns (QueryDenomsFromCreatorResponse) { + option (google.api.http).get = + "/osmosis/tokenfactory/v1beta1/denoms_from_creator/{creator}"; + } +} + +// QueryParamsRequest is the request type for the Query/Params RPC method. +message QueryParamsRequest {} + +// QueryParamsResponse is the response type for the Query/Params RPC method. +message QueryParamsResponse { + // params defines the parameters of the module. + Params params = 1 [ (gogoproto.nullable) = false ]; +} + +// QueryDenomAuthorityMetadataRequest defines the request structure for the +// DenomAuthorityMetadata gRPC query. +message QueryDenomAuthorityMetadataRequest { + string denom = 1 [ (gogoproto.moretags) = "yaml:\"denom\"" ]; +} + +// QueryDenomAuthorityMetadataResponse defines the response structure for the +// DenomAuthorityMetadata gRPC query. +message QueryDenomAuthorityMetadataResponse { + DenomAuthorityMetadata authority_metadata = 1 [ + (gogoproto.moretags) = "yaml:\"authority_metadata\"", + (gogoproto.nullable) = false + ]; +} + +// QueryDenomsFromCreatorRequest defines the request structure for the +// DenomsFromCreator gRPC query. +message QueryDenomsFromCreatorRequest { + string creator = 1 [ (gogoproto.moretags) = "yaml:\"creator\"" ]; +} + +// QueryDenomsFromCreatorRequest defines the response structure for the +// DenomsFromCreator gRPC query. +message QueryDenomsFromCreatorResponse { + repeated string denoms = 1 [ (gogoproto.moretags) = "yaml:\"denoms\"" ]; +} diff --git a/proto/osmosis/tokenfactory/v1beta1/tx.proto b/proto/osmosis/tokenfactory/v1beta1/tx.proto new file mode 100755 index 000000000..5a95b7047 --- /dev/null +++ b/proto/osmosis/tokenfactory/v1beta1/tx.proto @@ -0,0 +1,109 @@ +syntax = "proto3"; +package osmosis.tokenfactory.v1beta1; + +import "gogoproto/gogo.proto"; +import "cosmos/base/v1beta1/coin.proto"; +import "cosmos/bank/v1beta1/bank.proto"; + +option go_package = "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/types"; + +// Msg defines the tokefactory module's gRPC message service. +service Msg { + rpc CreateDenom(MsgCreateDenom) returns (MsgCreateDenomResponse); + rpc Mint(MsgMint) returns (MsgMintResponse); + rpc Burn(MsgBurn) returns (MsgBurnResponse); + rpc ChangeAdmin(MsgChangeAdmin) returns (MsgChangeAdminResponse); + rpc SetDenomMetadata(MsgSetDenomMetadata) + returns (MsgSetDenomMetadataResponse); + rpc ForceTransfer(MsgForceTransfer) returns (MsgForceTransferResponse); +} + +// MsgCreateDenom defines the message structure for the CreateDenom gRPC service +// method. It allows an account to create a new denom. It requires a sender +// address and a sub denomination. The (sender_address, sub_denomination) tuple +// must be unique and cannot be re-used. +// +// The resulting denom created is defined as +// . The resulting denom's admin is +// originally set to be the creator, but this can be changed later. The token +// denom does not indicate the current admin. +message MsgCreateDenom { + string sender = 1 [ (gogoproto.moretags) = "yaml:\"sender\"" ]; + // subdenom can be up to 44 "alphanumeric" characters long. + string subdenom = 2 [ (gogoproto.moretags) = "yaml:\"subdenom\"" ]; +} + +// MsgCreateDenomResponse is the return value of MsgCreateDenom +// It returns the full string of the newly created denom +message MsgCreateDenomResponse { + string new_token_denom = 1 + [ (gogoproto.moretags) = "yaml:\"new_token_denom\"" ]; +} + +// MsgMint is the sdk.Msg type for allowing an admin account to mint +// more of a token. For now, we only support minting to the sender account +message MsgMint { + string sender = 1 [ (gogoproto.moretags) = "yaml:\"sender\"" ]; + cosmos.base.v1beta1.Coin amount = 2 [ + (gogoproto.moretags) = "yaml:\"amount\"", + (gogoproto.nullable) = false + ]; + string mintToAddress = 3 + [ (gogoproto.moretags) = "yaml:\"mint_to_address\"" ]; +} + +message MsgMintResponse {} + +// MsgBurn is the sdk.Msg type for allowing an admin account to burn +// a token. For now, we only support burning from the sender account. +message MsgBurn { + string sender = 1 [ (gogoproto.moretags) = "yaml:\"sender\"" ]; + cosmos.base.v1beta1.Coin amount = 2 [ + (gogoproto.moretags) = "yaml:\"amount\"", + (gogoproto.nullable) = false + ]; + string burnFromAddress = 3 + [ (gogoproto.moretags) = "yaml:\"burn_from_address\"" ]; +} + +message MsgBurnResponse {} + +// MsgChangeAdmin is the sdk.Msg type for allowing an admin account to reassign +// adminship of a denom to a new account +message MsgChangeAdmin { + string sender = 1 [ (gogoproto.moretags) = "yaml:\"sender\"" ]; + string denom = 2 [ (gogoproto.moretags) = "yaml:\"denom\"" ]; + string new_admin = 3 [ (gogoproto.moretags) = "yaml:\"new_admin\"" ]; +} + +// MsgChangeAdminResponse defines the response structure for an executed +// MsgChangeAdmin message. +message MsgChangeAdminResponse {} + +// MsgSetDenomMetadata is the sdk.Msg type for allowing an admin account to set +// the denom's bank metadata +message MsgSetDenomMetadata { + string sender = 1 [ (gogoproto.moretags) = "yaml:\"sender\"" ]; + cosmos.bank.v1beta1.Metadata metadata = 2 [ + (gogoproto.moretags) = "yaml:\"metadata\"", + (gogoproto.nullable) = false + ]; +} + +// MsgSetDenomMetadataResponse defines the response structure for an executed +// MsgSetDenomMetadata message. +message MsgSetDenomMetadataResponse {} + +message MsgForceTransfer { + string sender = 1 [ (gogoproto.moretags) = "yaml:\"sender\"" ]; + cosmos.base.v1beta1.Coin amount = 2 [ + (gogoproto.moretags) = "yaml:\"amount\"", + (gogoproto.nullable) = false + ]; + string transferFromAddress = 3 + [ (gogoproto.moretags) = "yaml:\"transfer_from_address\"" ]; + string transferToAddress = 4 + [ (gogoproto.moretags) = "yaml:\"transfer_to_address\"" ]; +} + +message MsgForceTransferResponse {} \ No newline at end of file diff --git a/x/feeshare/genesis_test.go b/x/feeshare/genesis_test.go index 541417d22..797408d82 100644 --- a/x/feeshare/genesis_test.go +++ b/x/feeshare/genesis_test.go @@ -11,7 +11,7 @@ import ( "github.com/CosmosContracts/juno/v15/app" "github.com/CosmosContracts/juno/v15/x/feeshare" "github.com/CosmosContracts/juno/v15/x/feeshare/types" - tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + tmproto "github.com/cometbft/cometbft/proto/tendermint/types" ) type GenesisTestSuite struct { diff --git a/x/feeshare/integration_test.go b/x/feeshare/integration_test.go index 814136856..778b9a4d2 100644 --- a/x/feeshare/integration_test.go +++ b/x/feeshare/integration_test.go @@ -3,13 +3,13 @@ package feeshare_test import ( "encoding/json" - abci "github.com/tendermint/tendermint/abci/types" - "github.com/tendermint/tendermint/libs/log" - tmproto "github.com/tendermint/tendermint/proto/tendermint/types" - dbm "github.com/tendermint/tm-db" + dbm "github.com/cometbft/cometbft-db" + abci "github.com/cometbft/cometbft/abci/types" + "github.com/cometbft/cometbft/libs/log" + tmproto "github.com/cometbft/cometbft/proto/tendermint/types" + "cosmossdk.io/simapp" junoapp "github.com/CosmosContracts/juno/v15/app" - "github.com/cosmos/cosmos-sdk/simapp" "github.com/CosmosContracts/juno/v15/x/mint/types" sdk "github.com/cosmos/cosmos-sdk/types" diff --git a/x/feeshare/keeper/keeper.go b/x/feeshare/keeper/keeper.go index 557af3995..773cdc5f3 100644 --- a/x/feeshare/keeper/keeper.go +++ b/x/feeshare/keeper/keeper.go @@ -3,11 +3,11 @@ package keeper import ( "fmt" + "github.com/cometbft/cometbft/libs/log" "github.com/cosmos/cosmos-sdk/codec" storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" - "github.com/tendermint/tendermint/libs/log" wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" revtypes "github.com/CosmosContracts/juno/v15/x/feeshare/types" diff --git a/x/feeshare/keeper/keeper_test.go b/x/feeshare/keeper/keeper_test.go index 5c4743b23..054a74cd1 100644 --- a/x/feeshare/keeper/keeper_test.go +++ b/x/feeshare/keeper/keeper_test.go @@ -5,11 +5,11 @@ import ( "testing" "time" + tmrand "github.com/cometbft/cometbft/libs/rand" + tmproto "github.com/cometbft/cometbft/proto/tendermint/types" "github.com/cosmos/cosmos-sdk/baseapp" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/suite" - tmrand "github.com/tendermint/tendermint/libs/rand" - tmproto "github.com/tendermint/tendermint/proto/tendermint/types" wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" diff --git a/x/feeshare/module.go b/x/feeshare/module.go index 85053054b..9aac445a7 100644 --- a/x/feeshare/module.go +++ b/x/feeshare/module.go @@ -6,6 +6,7 @@ import ( "fmt" "math/rand" + abci "github.com/cometbft/cometbft/abci/types" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" codectypes "github.com/cosmos/cosmos-sdk/codec/types" @@ -16,7 +17,6 @@ import ( "github.com/gorilla/mux" "github.com/grpc-ecosystem/grpc-gateway/runtime" "github.com/spf13/cobra" - abci "github.com/tendermint/tendermint/abci/types" "github.com/CosmosContracts/juno/v15/x/feeshare/client/cli" "github.com/CosmosContracts/juno/v15/x/feeshare/keeper" diff --git a/x/feeshare/types/feeshare.pb.go b/x/feeshare/types/feeshare.pb.go index 3327bcc83..81a400508 100644 --- a/x/feeshare/types/feeshare.pb.go +++ b/x/feeshare/types/feeshare.pb.go @@ -5,7 +5,7 @@ package types import ( fmt "fmt" - proto "github.com/gogo/protobuf/proto" + proto "github.com/cosmos/gogoproto/proto" io "io" math "math" math_bits "math/bits" diff --git a/x/feeshare/types/genesis.pb.go b/x/feeshare/types/genesis.pb.go index ec9768848..c67c9ef91 100644 --- a/x/feeshare/types/genesis.pb.go +++ b/x/feeshare/types/genesis.pb.go @@ -7,7 +7,7 @@ import ( fmt "fmt" github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types" _ "github.com/cosmos/gogoproto/gogoproto" - proto "github.com/gogo/protobuf/proto" + proto "github.com/cosmos/gogoproto/proto" io "io" math "math" math_bits "math/bits" diff --git a/x/feeshare/types/query.pb.go b/x/feeshare/types/query.pb.go index 67983a6e1..4a925fa6e 100644 --- a/x/feeshare/types/query.pb.go +++ b/x/feeshare/types/query.pb.go @@ -8,8 +8,8 @@ import ( fmt "fmt" query "github.com/cosmos/cosmos-sdk/types/query" _ "github.com/cosmos/gogoproto/gogoproto" - grpc1 "github.com/gogo/protobuf/grpc" - proto "github.com/gogo/protobuf/proto" + grpc1 "github.com/cosmos/gogoproto/grpc" + proto "github.com/cosmos/gogoproto/proto" _ "google.golang.org/genproto/googleapis/api/annotations" grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" diff --git a/x/feeshare/types/tx.pb.go b/x/feeshare/types/tx.pb.go index 456d0979a..eba3eeb02 100644 --- a/x/feeshare/types/tx.pb.go +++ b/x/feeshare/types/tx.pb.go @@ -7,8 +7,8 @@ import ( context "context" fmt "fmt" _ "github.com/cosmos/gogoproto/gogoproto" - grpc1 "github.com/gogo/protobuf/grpc" - proto "github.com/gogo/protobuf/proto" + grpc1 "github.com/cosmos/gogoproto/grpc" + proto "github.com/cosmos/gogoproto/proto" _ "google.golang.org/genproto/googleapis/api/annotations" grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" diff --git a/x/mint/client/rest/grpc_query_test.go b/x/mint/client/rest/grpc_query_test.go index 982c32214..f7c8a58fd 100644 --- a/x/mint/client/rest/grpc_query_test.go +++ b/x/mint/client/rest/grpc_query_test.go @@ -11,7 +11,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" grpctypes "github.com/cosmos/cosmos-sdk/types/grpc" - "github.com/gogo/protobuf/proto" + "github.com/cosmos/gogoproto/proto" "github.com/stretchr/testify/suite" minttypes "github.com/CosmosContracts/juno/v15/x/mint/types" diff --git a/x/mint/client/testutil/suite.go b/x/mint/client/testutil/suite.go index 12f3f8566..a7638c36d 100644 --- a/x/mint/client/testutil/suite.go +++ b/x/mint/client/testutil/suite.go @@ -4,8 +4,8 @@ import ( "fmt" "strings" + tmcli "github.com/cometbft/cometbft/libs/cli" "github.com/stretchr/testify/suite" - tmcli "github.com/tendermint/tendermint/libs/cli" "github.com/CosmosContracts/juno/v15/x/mint/client/cli" minttypes "github.com/CosmosContracts/juno/v15/x/mint/types" diff --git a/x/mint/keeper/grpc_query_test.go b/x/mint/keeper/grpc_query_test.go index e2fb71c5f..8d22bf419 100644 --- a/x/mint/keeper/grpc_query_test.go +++ b/x/mint/keeper/grpc_query_test.go @@ -4,8 +4,8 @@ import ( gocontext "context" "testing" + tmproto "github.com/cometbft/cometbft/proto/tendermint/types" "github.com/stretchr/testify/suite" - tmproto "github.com/tendermint/tendermint/proto/tendermint/types" "github.com/CosmosContracts/juno/v15/app" "github.com/CosmosContracts/juno/v15/x/mint/types" diff --git a/x/mint/keeper/integration_test.go b/x/mint/keeper/integration_test.go index 9218885fd..36a630eb7 100644 --- a/x/mint/keeper/integration_test.go +++ b/x/mint/keeper/integration_test.go @@ -3,13 +3,13 @@ package keeper_test import ( "encoding/json" - abci "github.com/tendermint/tendermint/abci/types" - "github.com/tendermint/tendermint/libs/log" - tmproto "github.com/tendermint/tendermint/proto/tendermint/types" - dbm "github.com/tendermint/tm-db" + dbm "github.com/cometbft/cometbft-db" + abci "github.com/cometbft/cometbft/abci/types" + "github.com/cometbft/cometbft/libs/log" + tmproto "github.com/cometbft/cometbft/proto/tendermint/types" + "cosmossdk.io/simapp" junoapp "github.com/CosmosContracts/juno/v15/app" - "github.com/cosmos/cosmos-sdk/simapp" "github.com/CosmosContracts/juno/v15/x/mint/types" sdk "github.com/cosmos/cosmos-sdk/types" diff --git a/x/mint/keeper/keeper.go b/x/mint/keeper/keeper.go index 0fc908d91..935c5d0d1 100644 --- a/x/mint/keeper/keeper.go +++ b/x/mint/keeper/keeper.go @@ -1,7 +1,7 @@ package keeper import ( - "github.com/tendermint/tendermint/libs/log" + "github.com/cometbft/cometbft/libs/log" "github.com/CosmosContracts/juno/v15/x/mint/types" "github.com/cosmos/cosmos-sdk/codec" diff --git a/x/mint/keeper/querier.go b/x/mint/keeper/querier.go index 0f1d24f23..bd4399a54 100644 --- a/x/mint/keeper/querier.go +++ b/x/mint/keeper/querier.go @@ -1,7 +1,7 @@ package keeper import ( - abci "github.com/tendermint/tendermint/abci/types" + abci "github.com/cometbft/cometbft/abci/types" "github.com/CosmosContracts/juno/v15/x/mint/types" "github.com/cosmos/cosmos-sdk/codec" diff --git a/x/mint/keeper/querier_test.go b/x/mint/keeper/querier_test.go index 1cd5bd7ce..6bd8d8581 100644 --- a/x/mint/keeper/querier_test.go +++ b/x/mint/keeper/querier_test.go @@ -11,7 +11,7 @@ import ( "github.com/CosmosContracts/juno/v15/x/mint/types" sdk "github.com/cosmos/cosmos-sdk/types" - abci "github.com/tendermint/tendermint/abci/types" + abci "github.com/cometbft/cometbft/abci/types" ) func TestNewQuerier(t *testing.T) { diff --git a/x/mint/module.go b/x/mint/module.go index a27df0d34..a1ede3e55 100644 --- a/x/mint/module.go +++ b/x/mint/module.go @@ -6,10 +6,10 @@ import ( "fmt" "math/rand" + abci "github.com/cometbft/cometbft/abci/types" "github.com/gorilla/mux" "github.com/grpc-ecosystem/grpc-gateway/runtime" "github.com/spf13/cobra" - abci "github.com/tendermint/tendermint/abci/types" "github.com/CosmosContracts/juno/v15/x/mint/client/cli" "github.com/CosmosContracts/juno/v15/x/mint/client/rest" diff --git a/x/mint/module_test.go b/x/mint/module_test.go index 00b994a09..811dfc988 100644 --- a/x/mint/module_test.go +++ b/x/mint/module_test.go @@ -3,12 +3,12 @@ package mint_test import ( "testing" + abcitypes "github.com/cometbft/cometbft/abci/types" + tmproto "github.com/cometbft/cometbft/proto/tendermint/types" "github.com/stretchr/testify/require" - abcitypes "github.com/tendermint/tendermint/abci/types" - tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + "cosmossdk.io/simapp" "github.com/CosmosContracts/juno/v15/x/mint/types" - "github.com/cosmos/cosmos-sdk/simapp" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" ) diff --git a/x/mint/types/genesis.pb.go b/x/mint/types/genesis.pb.go index 5bf586341..d9c0f8732 100644 --- a/x/mint/types/genesis.pb.go +++ b/x/mint/types/genesis.pb.go @@ -6,7 +6,7 @@ package types import ( fmt "fmt" _ "github.com/cosmos/gogoproto/gogoproto" - proto "github.com/gogo/protobuf/proto" + proto "github.com/cosmos/gogoproto/proto" io "io" math "math" math_bits "math/bits" diff --git a/x/mint/types/mint.pb.go b/x/mint/types/mint.pb.go index 730abfa9e..5f78dc8a2 100644 --- a/x/mint/types/mint.pb.go +++ b/x/mint/types/mint.pb.go @@ -7,7 +7,7 @@ import ( fmt "fmt" github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types" _ "github.com/cosmos/gogoproto/gogoproto" - proto "github.com/gogo/protobuf/proto" + proto "github.com/cosmos/gogoproto/proto" io "io" math "math" math_bits "math/bits" diff --git a/x/mint/types/query.pb.go b/x/mint/types/query.pb.go index 855eb759f..d569d9693 100644 --- a/x/mint/types/query.pb.go +++ b/x/mint/types/query.pb.go @@ -8,8 +8,8 @@ import ( fmt "fmt" github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types" _ "github.com/cosmos/gogoproto/gogoproto" - grpc1 "github.com/gogo/protobuf/grpc" - proto "github.com/gogo/protobuf/proto" + grpc1 "github.com/cosmos/gogoproto/grpc" + proto "github.com/cosmos/gogoproto/proto" _ "google.golang.org/genproto/googleapis/api/annotations" grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" diff --git a/x/tokenfactory/README.md b/x/tokenfactory/README.md new file mode 100644 index 000000000..7d6644e45 --- /dev/null +++ b/x/tokenfactory/README.md @@ -0,0 +1,155 @@ +# Token Factory + +The tokenfactory module allows any account to create a new token with +the name `factory/{creator address}/{subdenom}`. Because tokens are +namespaced by creator address, this allows token minting to be +permissionless, due to not needing to resolve name collisions. A single +account can create multiple denoms, by providing a unique subdenom for each +created denom. Once a denom is created, the original creator is given +"admin" privileges over the asset. This allows them to: + +- Mint their denom to any account +- Burn their denom from any account +- Create a transfer of their denom between any two accounts +- Change the admin. In the future, more admin capabilities may be added. Admins + can choose to share admin privileges with other accounts using the authz + module. The `ChangeAdmin` functionality, allows changing the master admin + account, or even setting it to `""`, meaning no account has admin privileges + of the asset. + +## Messages + +### CreateDenom + +Creates a denom of `factory/{creator address}/{subdenom}` given the denom creator +address and the subdenom. Subdenoms can contain `[a-zA-Z0-9./]`. + +```go +message MsgCreateDenom { + string sender = 1 [ (gogoproto.moretags) = "yaml:\"sender\"" ]; + string subdenom = 2 [ (gogoproto.moretags) = "yaml:\"subdenom\"" ]; +} +``` + +**State Modifications:** + +- Fund community pool with the denom creation fee from the creator address, set + in `Params`. +- Set `DenomMetaData` via bank keeper. +- Set `AuthorityMetadata` for the given denom to store the admin for the created + denom `factory/{creator address}/{subdenom}`. Admin is automatically set as the + Msg sender. +- Add denom to the `CreatorPrefixStore`, where a state of denoms created per + creator is kept. + +### Mint + +Minting of a specific denom is only allowed for the current admin. +Note, the current admin is defaulted to the creator of the denom. + +```go +message MsgMint { + string sender = 1 [ (gogoproto.moretags) = "yaml:\"sender\"" ]; + cosmos.base.v1beta1.Coin amount = 2 [ + (gogoproto.moretags) = "yaml:\"amount\"", + (gogoproto.nullable) = false + ]; +} +``` + +**State Modifications:** + +- Safety check the following + - Check that the denom minting is created via `tokenfactory` module + - Check that the sender of the message is the admin of the denom +- Mint designated amount of tokens for the denom via `bank` module + +### Burn + +Burning of a specific denom is only allowed for the current admin. +Note, the current admin is defaulted to the creator of the denom. + +```go +message MsgBurn { + string sender = 1 [ (gogoproto.moretags) = "yaml:\"sender\"" ]; + cosmos.base.v1beta1.Coin amount = 2 [ + (gogoproto.moretags) = "yaml:\"amount\"", + (gogoproto.nullable) = false + ]; +} +``` + +**State Modifications:** + +- Saftey check the following + - Check that the denom minting is created via `tokenfactory` module + - Check that the sender of the message is the admin of the denom +- Burn designated amount of tokens for the denom via `bank` module + +### ChangeAdmin + +Change the admin of a denom. Note, this is only allowed to be called by the current admin of the denom. + +```go +message MsgChangeAdmin { + string sender = 1 [ (gogoproto.moretags) = "yaml:\"sender\"" ]; + string denom = 2 [ (gogoproto.moretags) = "yaml:\"denom\"" ]; + string newAdmin = 3 [ (gogoproto.moretags) = "yaml:\"new_admin\"" ]; +} +``` + +### SetDenomMetadata + +Setting of metadata for a specific denom is only allowed for the admin of the denom. +It allows the overwriting of the denom metadata in the bank module. + +```go +message MsgChangeAdmin { + string sender = 1 [ (gogoproto.moretags) = "yaml:\"sender\"" ]; + cosmos.bank.v1beta1.Metadata metadata = 2 [ (gogoproto.moretags) = "yaml:\"metadata\"", (gogoproto.nullable) = false ]; +} +``` + +**State Modifications:** + +- Check that sender of the message is the admin of denom +- Modify `AuthorityMetadata` state entry to change the admin of the denom + +## Expectations from the chain + +The chain's bech32 prefix for addresses can be at most 16 characters long. + +This comes from denoms having a 128 byte maximum length, enforced from the SDK, +and us setting longest_subdenom to be 44 bytes. + +A token factory token's denom is: `factory/{creator address}/{subdenom}` + +Splitting up into sub-components, this has: + +- `len(factory) = 7` +- `2 * len("/") = 2` +- `len(longest_subdenom)` +- `len(creator_address) = len(bech32(longest_addr_length, chain_addr_prefix))`. + +Longest addr length at the moment is `32 bytes`. Due to SDK error correction +settings, this means `len(bech32(32, chain_addr_prefix)) = len(chain_addr_prefix) + 1 + 58`. +Adding this all, we have a total length constraint of `128 = 7 + 2 + len(longest_subdenom) + len(longest_chain_addr_prefix) + 1 + 58`. +Therefore `len(longest_subdenom) + len(longest_chain_addr_prefix) = 128 - (7 + 2 + 1 + 58) = 60`. + +The choice between how we standardized the split these 60 bytes between maxes +from longest_subdenom and longest_chain_addr_prefix is somewhat arbitrary. +Considerations going into this: + +- Per [BIP-0173](https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki#bech32) + the technically longest HRP for a 32 byte address ('data field') is 31 bytes. + (Comes from encode(data) = 59 bytes, and max length = 90 bytes) +- subdenom should be at least 32 bytes so hashes can go into it +- longer subdenoms are very helpful for creating human readable denoms +- chain addresses should prefer being smaller. The longest HRP in cosmos to date is 11 bytes. (`persistence`) + +For explicitness, its currently set to `len(longest_subdenom) = 44` and `len(longest_chain_addr_prefix) = 16`. + +Please note, if the SDK increases the maximum length of a denom from 128 bytes, +these caps should increase. + +So please don't make code rely on these max lengths for parsing. diff --git a/x/tokenfactory/bindings/custom_msg_test.go b/x/tokenfactory/bindings/custom_msg_test.go new file mode 100644 index 000000000..ba411ce1f --- /dev/null +++ b/x/tokenfactory/bindings/custom_msg_test.go @@ -0,0 +1,331 @@ +package bindings_test + +import ( + "encoding/json" + "fmt" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/CosmWasm/wasmd/x/wasm/keeper" + wasmvmtypes "github.com/CosmWasm/wasmvm/types" + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/CosmosTokenFactory/token-factory/app" + bindings "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/bindings/types" + "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/types" +) + +func TestCreateDenomMsg(t *testing.T) { + creator := RandomAccountAddress() + osmosis, ctx := SetupCustomApp(t, creator) + + lucky := RandomAccountAddress() + reflect := instantiateReflectContract(t, ctx, osmosis, lucky) + require.NotEmpty(t, reflect) + + // Fund reflect contract with 100 base denom creation fees + reflectAmount := sdk.NewCoins(sdk.NewCoin(types.DefaultParams().DenomCreationFee[0].Denom, types.DefaultParams().DenomCreationFee[0].Amount.MulRaw(100))) + fundAccount(t, ctx, osmosis, reflect, reflectAmount) + + msg := bindings.TokenMsg{CreateDenom: &bindings.CreateDenom{ + Subdenom: "SUN", + }} + err := executeCustom(t, ctx, osmosis, reflect, lucky, msg, sdk.Coin{}) + require.NoError(t, err) + + // query the denom and see if it matches + query := bindings.TokenQuery{ + FullDenom: &bindings.FullDenom{ + CreatorAddr: reflect.String(), + Subdenom: "SUN", + }, + } + resp := bindings.FullDenomResponse{} + queryCustom(t, ctx, osmosis, reflect, query, &resp) + + require.Equal(t, resp.Denom, fmt.Sprintf("factory/%s/SUN", reflect.String())) +} + +func TestMintMsg(t *testing.T) { + creator := RandomAccountAddress() + osmosis, ctx := SetupCustomApp(t, creator) + + lucky := RandomAccountAddress() + reflect := instantiateReflectContract(t, ctx, osmosis, lucky) + require.NotEmpty(t, reflect) + + // Fund reflect contract with 100 base denom creation fees + reflectAmount := sdk.NewCoins(sdk.NewCoin(types.DefaultParams().DenomCreationFee[0].Denom, types.DefaultParams().DenomCreationFee[0].Amount.MulRaw(100))) + fundAccount(t, ctx, osmosis, reflect, reflectAmount) + + // lucky was broke + balances := osmosis.BankKeeper.GetAllBalances(ctx, lucky) + require.Empty(t, balances) + + // Create denom for minting + msg := bindings.TokenMsg{CreateDenom: &bindings.CreateDenom{ + Subdenom: "SUN", + }} + err := executeCustom(t, ctx, osmosis, reflect, lucky, msg, sdk.Coin{}) + require.NoError(t, err) + sunDenom := fmt.Sprintf("factory/%s/%s", reflect.String(), msg.CreateDenom.Subdenom) + + amount, ok := sdk.NewIntFromString("808010808") + require.True(t, ok) + msg = bindings.TokenMsg{MintTokens: &bindings.MintTokens{ + Denom: sunDenom, + Amount: amount, + MintToAddress: lucky.String(), + }} + err = executeCustom(t, ctx, osmosis, reflect, lucky, msg, sdk.Coin{}) + require.NoError(t, err) + + balances = osmosis.BankKeeper.GetAllBalances(ctx, lucky) + require.Len(t, balances, 1) + coin := balances[0] + require.Equal(t, amount, coin.Amount) + require.Contains(t, coin.Denom, "factory/") + + // query the denom and see if it matches + query := bindings.TokenQuery{ + FullDenom: &bindings.FullDenom{ + CreatorAddr: reflect.String(), + Subdenom: "SUN", + }, + } + resp := bindings.FullDenomResponse{} + queryCustom(t, ctx, osmosis, reflect, query, &resp) + + require.Equal(t, resp.Denom, coin.Denom) + + // mint the same denom again + err = executeCustom(t, ctx, osmosis, reflect, lucky, msg, sdk.Coin{}) + require.NoError(t, err) + + balances = osmosis.BankKeeper.GetAllBalances(ctx, lucky) + require.Len(t, balances, 1) + coin = balances[0] + require.Equal(t, amount.MulRaw(2), coin.Amount) + require.Contains(t, coin.Denom, "factory/") + + // query the denom and see if it matches + query = bindings.TokenQuery{ + FullDenom: &bindings.FullDenom{ + CreatorAddr: reflect.String(), + Subdenom: "SUN", + }, + } + resp = bindings.FullDenomResponse{} + queryCustom(t, ctx, osmosis, reflect, query, &resp) + + require.Equal(t, resp.Denom, coin.Denom) + + // now mint another amount / denom + // create it first + msg = bindings.TokenMsg{CreateDenom: &bindings.CreateDenom{ + Subdenom: "MOON", + }} + err = executeCustom(t, ctx, osmosis, reflect, lucky, msg, sdk.Coin{}) + require.NoError(t, err) + moonDenom := fmt.Sprintf("factory/%s/%s", reflect.String(), msg.CreateDenom.Subdenom) + + amount = amount.SubRaw(1) + msg = bindings.TokenMsg{MintTokens: &bindings.MintTokens{ + Denom: moonDenom, + Amount: amount, + MintToAddress: lucky.String(), + }} + err = executeCustom(t, ctx, osmosis, reflect, lucky, msg, sdk.Coin{}) + require.NoError(t, err) + + balances = osmosis.BankKeeper.GetAllBalances(ctx, lucky) + require.Len(t, balances, 2) + coin = balances[0] + require.Equal(t, amount, coin.Amount) + require.Contains(t, coin.Denom, "factory/") + + // query the denom and see if it matches + query = bindings.TokenQuery{ + FullDenom: &bindings.FullDenom{ + CreatorAddr: reflect.String(), + Subdenom: "MOON", + }, + } + resp = bindings.FullDenomResponse{} + queryCustom(t, ctx, osmosis, reflect, query, &resp) + + require.Equal(t, resp.Denom, coin.Denom) + + // and check the first denom is unchanged + coin = balances[1] + require.Equal(t, amount.AddRaw(1).MulRaw(2), coin.Amount) + require.Contains(t, coin.Denom, "factory/") + + // query the denom and see if it matches + query = bindings.TokenQuery{ + FullDenom: &bindings.FullDenom{ + CreatorAddr: reflect.String(), + Subdenom: "SUN", + }, + } + resp = bindings.FullDenomResponse{} + queryCustom(t, ctx, osmosis, reflect, query, &resp) + + require.Equal(t, resp.Denom, coin.Denom) +} + +func TestForceTransfer(t *testing.T) { + creator := RandomAccountAddress() + osmosis, ctx := SetupCustomApp(t, creator) + + lucky := RandomAccountAddress() + rcpt := RandomAccountAddress() + reflect := instantiateReflectContract(t, ctx, osmosis, lucky) + require.NotEmpty(t, reflect) + + // Fund reflect contract with 100 base denom creation fees + reflectAmount := sdk.NewCoins(sdk.NewCoin(types.DefaultParams().DenomCreationFee[0].Denom, types.DefaultParams().DenomCreationFee[0].Amount.MulRaw(100))) + fundAccount(t, ctx, osmosis, reflect, reflectAmount) + + // lucky was broke + balances := osmosis.BankKeeper.GetAllBalances(ctx, lucky) + require.Empty(t, balances) + + // Create denom for minting + msg := bindings.TokenMsg{CreateDenom: &bindings.CreateDenom{ + Subdenom: "SUN", + }} + err := executeCustom(t, ctx, osmosis, reflect, lucky, msg, sdk.Coin{}) + require.NoError(t, err) + sunDenom := fmt.Sprintf("factory/%s/%s", reflect.String(), msg.CreateDenom.Subdenom) + + amount, ok := sdk.NewIntFromString("808010808") + require.True(t, ok) + + // Mint new tokens to lucky + msg = bindings.TokenMsg{MintTokens: &bindings.MintTokens{ + Denom: sunDenom, + Amount: amount, + MintToAddress: lucky.String(), + }} + err = executeCustom(t, ctx, osmosis, reflect, lucky, msg, sdk.Coin{}) + require.NoError(t, err) + + // Force move 100 tokens from lucky to rcpt + msg = bindings.TokenMsg{ForceTransfer: &bindings.ForceTransfer{ + Denom: sunDenom, + Amount: sdk.NewInt(100), + FromAddress: lucky.String(), + ToAddress: rcpt.String(), + }} + err = executeCustom(t, ctx, osmosis, reflect, lucky, msg, sdk.Coin{}) + require.NoError(t, err) + + // check the balance of rcpt + balances = osmosis.BankKeeper.GetAllBalances(ctx, rcpt) + require.Len(t, balances, 1) + coin := balances[0] + require.Equal(t, sdk.NewInt(100), coin.Amount) +} + +func TestBurnMsg(t *testing.T) { + creator := RandomAccountAddress() + osmosis, ctx := SetupCustomApp(t, creator) + + lucky := RandomAccountAddress() + reflect := instantiateReflectContract(t, ctx, osmosis, lucky) + require.NotEmpty(t, reflect) + + // Fund reflect contract with 100 base denom creation fees + reflectAmount := sdk.NewCoins(sdk.NewCoin(types.DefaultParams().DenomCreationFee[0].Denom, types.DefaultParams().DenomCreationFee[0].Amount.MulRaw(100))) + fundAccount(t, ctx, osmosis, reflect, reflectAmount) + + // lucky was broke + balances := osmosis.BankKeeper.GetAllBalances(ctx, lucky) + require.Empty(t, balances) + + // Create denom for minting + msg := bindings.TokenMsg{CreateDenom: &bindings.CreateDenom{ + Subdenom: "SUN", + }} + err := executeCustom(t, ctx, osmosis, reflect, lucky, msg, sdk.Coin{}) + require.NoError(t, err) + sunDenom := fmt.Sprintf("factory/%s/%s", reflect.String(), msg.CreateDenom.Subdenom) + + amount, ok := sdk.NewIntFromString("808010809") + require.True(t, ok) + + msg = bindings.TokenMsg{MintTokens: &bindings.MintTokens{ + Denom: sunDenom, + Amount: amount, + MintToAddress: lucky.String(), + }} + err = executeCustom(t, ctx, osmosis, reflect, lucky, msg, sdk.Coin{}) + require.NoError(t, err) + + // can burn from different address with burnFrom + amt, ok := sdk.NewIntFromString("1") + require.True(t, ok) + msg = bindings.TokenMsg{BurnTokens: &bindings.BurnTokens{ + Denom: sunDenom, + Amount: amt, + BurnFromAddress: lucky.String(), + }} + err = executeCustom(t, ctx, osmosis, reflect, lucky, msg, sdk.Coin{}) + require.NoError(t, err) + + // lucky needs to send balance to reflect contract to burn it + luckyBalance := osmosis.BankKeeper.GetAllBalances(ctx, lucky) + err = osmosis.BankKeeper.SendCoins(ctx, lucky, reflect, luckyBalance) + require.NoError(t, err) + + msg = bindings.TokenMsg{BurnTokens: &bindings.BurnTokens{ + Denom: sunDenom, + Amount: amount.Abs().Sub(sdk.NewInt(1)), + BurnFromAddress: reflect.String(), + }} + err = executeCustom(t, ctx, osmosis, reflect, lucky, msg, sdk.Coin{}) + require.NoError(t, err) +} + +type ReflectExec struct { + ReflectMsg *ReflectMsgs `json:"reflect_msg,omitempty"` + ReflectSubMsg *ReflectSubMsgs `json:"reflect_sub_msg,omitempty"` +} + +type ReflectMsgs struct { + Msgs []wasmvmtypes.CosmosMsg `json:"msgs"` +} + +type ReflectSubMsgs struct { + Msgs []wasmvmtypes.SubMsg `json:"msgs"` +} + +func executeCustom(t *testing.T, ctx sdk.Context, osmosis *app.TokenApp, contract sdk.AccAddress, sender sdk.AccAddress, msg bindings.TokenMsg, funds sdk.Coin) error { + wrapped := bindings.TokenFactoryMsg{ + Token: &msg, + } + customBz, err := json.Marshal(wrapped) + require.NoError(t, err) + + reflectMsg := ReflectExec{ + ReflectMsg: &ReflectMsgs{ + Msgs: []wasmvmtypes.CosmosMsg{{ + Custom: customBz, + }}, + }, + } + reflectBz, err := json.Marshal(reflectMsg) + require.NoError(t, err) + + // no funds sent if amount is 0 + var coins sdk.Coins + if !funds.Amount.IsNil() { + coins = sdk.Coins{funds} + } + + contractKeeper := keeper.NewDefaultPermissionKeeper(osmosis.WasmKeeper) + _, err = contractKeeper.Execute(ctx, contract, sender, reflectBz, coins) + return err +} diff --git a/x/tokenfactory/bindings/custom_query_test.go b/x/tokenfactory/bindings/custom_query_test.go new file mode 100644 index 000000000..278c60352 --- /dev/null +++ b/x/tokenfactory/bindings/custom_query_test.go @@ -0,0 +1,74 @@ +package bindings_test + +import ( + "encoding/json" + "fmt" + "testing" + + "github.com/stretchr/testify/require" + + wasmvmtypes "github.com/CosmWasm/wasmvm/types" + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/CosmosTokenFactory/token-factory/app" + bindings "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/bindings/types" +) + +func TestQueryFullDenom(t *testing.T) { + actor := RandomAccountAddress() + tokenz, ctx := SetupCustomApp(t, actor) + + reflect := instantiateReflectContract(t, ctx, tokenz, actor) + require.NotEmpty(t, reflect) + + // query full denom + query := bindings.TokenQuery{ + FullDenom: &bindings.FullDenom{ + CreatorAddr: reflect.String(), + Subdenom: "ustart", + }, + } + resp := bindings.FullDenomResponse{} + queryCustom(t, ctx, tokenz, reflect, query, &resp) + + expected := fmt.Sprintf("factory/%s/ustart", reflect.String()) + require.EqualValues(t, expected, resp.Denom) +} + +type ReflectQuery struct { + Chain *ChainRequest `json:"chain,omitempty"` +} + +type ChainRequest struct { + Request wasmvmtypes.QueryRequest `json:"request"` +} + +type ChainResponse struct { + Data []byte `json:"data"` +} + +func queryCustom(t *testing.T, ctx sdk.Context, tokenz *app.TokenApp, contract sdk.AccAddress, request bindings.TokenQuery, response interface{}) { + wrapped := bindings.TokenFactoryQuery{ + Token: &request, + } + msgBz, err := json.Marshal(wrapped) + require.NoError(t, err) + fmt.Println(string(msgBz)) + + query := ReflectQuery{ + Chain: &ChainRequest{ + Request: wasmvmtypes.QueryRequest{Custom: msgBz}, + }, + } + queryBz, err := json.Marshal(query) + require.NoError(t, err) + fmt.Println(string(queryBz)) + + resBz, err := tokenz.WasmKeeper.QuerySmart(ctx, contract, queryBz) + require.NoError(t, err) + var resp ChainResponse + err = json.Unmarshal(resBz, &resp) + require.NoError(t, err) + err = json.Unmarshal(resp.Data, response) + require.NoError(t, err) +} diff --git a/x/tokenfactory/bindings/helpers_test.go b/x/tokenfactory/bindings/helpers_test.go new file mode 100644 index 000000000..41d14131a --- /dev/null +++ b/x/tokenfactory/bindings/helpers_test.go @@ -0,0 +1,92 @@ +package bindings_test + +import ( + "os" + "testing" + "time" + + "github.com/stretchr/testify/require" + + "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/crypto/ed25519" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + + "github.com/cosmos/cosmos-sdk/simapp" + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/CosmWasm/wasmd/x/wasm/keeper" + "github.com/CosmosTokenFactory/token-factory/app" +) + +func CreateTestInput() (*app.TokenApp, sdk.Context) { + osmosis := app.Setup(false) + ctx := osmosis.BaseApp.NewContext(false, tmproto.Header{Height: 1, ChainID: "osmosis-1", Time: time.Now().UTC()}) + return osmosis, ctx +} + +func FundAccount(t *testing.T, ctx sdk.Context, osmosis *app.TokenApp, acct sdk.AccAddress) { + err := simapp.FundAccount(osmosis.BankKeeper, ctx, acct, sdk.NewCoins( + sdk.NewCoin("uosmo", sdk.NewInt(10000000000)), + )) + require.NoError(t, err) +} + +// we need to make this deterministic (same every test run), as content might affect gas costs +func keyPubAddr() (crypto.PrivKey, crypto.PubKey, sdk.AccAddress) { + key := ed25519.GenPrivKey() + pub := key.PubKey() + addr := sdk.AccAddress(pub.Address()) + return key, pub, addr +} + +func RandomAccountAddress() sdk.AccAddress { + _, _, addr := keyPubAddr() + return addr +} + +func RandomBech32AccountAddress() string { + return RandomAccountAddress().String() +} + +func storeReflectCode(t *testing.T, ctx sdk.Context, tokenz *app.TokenApp, addr sdk.AccAddress) uint64 { + wasmCode, err := os.ReadFile("./testdata/token_reflect.wasm") + require.NoError(t, err) + + contractKeeper := keeper.NewDefaultPermissionKeeper(tokenz.WasmKeeper) + codeID, _, err := contractKeeper.Create(ctx, addr, wasmCode, nil) + require.NoError(t, err) + + return codeID +} + +func instantiateReflectContract(t *testing.T, ctx sdk.Context, tokenz *app.TokenApp, funder sdk.AccAddress) sdk.AccAddress { + initMsgBz := []byte("{}") + contractKeeper := keeper.NewDefaultPermissionKeeper(tokenz.WasmKeeper) + codeID := uint64(1) + addr, _, err := contractKeeper.Instantiate(ctx, codeID, funder, funder, initMsgBz, "demo contract", nil) + require.NoError(t, err) + + return addr +} + +func fundAccount(t *testing.T, ctx sdk.Context, tokenz *app.TokenApp, addr sdk.AccAddress, coins sdk.Coins) { + err := simapp.FundAccount( + tokenz.BankKeeper, + ctx, + addr, + coins, + ) + require.NoError(t, err) +} + +func SetupCustomApp(t *testing.T, addr sdk.AccAddress) (*app.TokenApp, sdk.Context) { + tokenz, ctx := CreateTestInput() + wasmKeeper := tokenz.WasmKeeper + + storeReflectCode(t, ctx, tokenz, addr) + + cInfo := wasmKeeper.GetCodeInfo(ctx, 1) + require.NotNil(t, cInfo) + + return tokenz, ctx +} diff --git a/x/tokenfactory/bindings/message_plugin.go b/x/tokenfactory/bindings/message_plugin.go new file mode 100644 index 000000000..b6acde281 --- /dev/null +++ b/x/tokenfactory/bindings/message_plugin.go @@ -0,0 +1,370 @@ +package bindings + +import ( + "encoding/json" + + wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" + wasmvmtypes "github.com/CosmWasm/wasmvm/types" + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + + bindingstypes "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/bindings/types" + tokenfactorykeeper "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/keeper" + tokenfactorytypes "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/types" +) + +// CustomMessageDecorator returns decorator for custom CosmWasm bindings messages +func CustomMessageDecorator(bank *bankkeeper.BaseKeeper, tokenFactory *tokenfactorykeeper.Keeper) func(wasmkeeper.Messenger) wasmkeeper.Messenger { + return func(old wasmkeeper.Messenger) wasmkeeper.Messenger { + return &CustomMessenger{ + wrapped: old, + bank: bank, + tokenFactory: tokenFactory, + } + } +} + +type CustomMessenger struct { + wrapped wasmkeeper.Messenger + bank *bankkeeper.BaseKeeper + tokenFactory *tokenfactorykeeper.Keeper +} + +var _ wasmkeeper.Messenger = (*CustomMessenger)(nil) + +// DispatchMsg executes on the contractMsg. +func (m *CustomMessenger) DispatchMsg(ctx sdk.Context, contractAddr sdk.AccAddress, contractIBCPortID string, msg wasmvmtypes.CosmosMsg) ([]sdk.Event, [][]byte, error) { + if msg.Custom != nil { + // only handle the happy path where this is really creating / minting / swapping ... + // leave everything else for the wrapped version + var contractMsg bindingstypes.TokenFactoryMsg + if err := json.Unmarshal(msg.Custom, &contractMsg); err != nil { + return nil, nil, sdkerrors.Wrap(err, "token factory msg") + } + if contractMsg.Token == nil { + return nil, nil, sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, "nil token field") + } + tokenMsg := contractMsg.Token + + if tokenMsg.CreateDenom != nil { + return m.createDenom(ctx, contractAddr, tokenMsg.CreateDenom) + } + if tokenMsg.MintTokens != nil { + return m.mintTokens(ctx, contractAddr, tokenMsg.MintTokens) + } + if tokenMsg.ChangeAdmin != nil { + return m.changeAdmin(ctx, contractAddr, tokenMsg.ChangeAdmin) + } + if tokenMsg.BurnTokens != nil { + return m.burnTokens(ctx, contractAddr, tokenMsg.BurnTokens) + } + if tokenMsg.SetMetadata != nil { + return m.setMetadata(ctx, contractAddr, tokenMsg.SetMetadata) + } + if tokenMsg.ForceTransfer != nil { + return m.forceTransfer(ctx, contractAddr, tokenMsg.ForceTransfer) + } + } + return m.wrapped.DispatchMsg(ctx, contractAddr, contractIBCPortID, msg) +} + +// createDenom creates a new token denom +func (m *CustomMessenger) createDenom(ctx sdk.Context, contractAddr sdk.AccAddress, createDenom *bindingstypes.CreateDenom) ([]sdk.Event, [][]byte, error) { + bz, err := PerformCreateDenom(m.tokenFactory, m.bank, ctx, contractAddr, createDenom) + if err != nil { + return nil, nil, sdkerrors.Wrap(err, "perform create denom") + } + // TODO: double check how this is all encoded to the contract + return nil, [][]byte{bz}, nil +} + +// PerformCreateDenom is used with createDenom to create a token denom; validates the msgCreateDenom. +func PerformCreateDenom(f *tokenfactorykeeper.Keeper, b *bankkeeper.BaseKeeper, ctx sdk.Context, contractAddr sdk.AccAddress, createDenom *bindingstypes.CreateDenom) ([]byte, error) { + if createDenom == nil { + return nil, wasmvmtypes.InvalidRequest{Err: "create denom null create denom"} + } + + msgServer := tokenfactorykeeper.NewMsgServerImpl(*f) + + msgCreateDenom := tokenfactorytypes.NewMsgCreateDenom(contractAddr.String(), createDenom.Subdenom) + + if err := msgCreateDenom.ValidateBasic(); err != nil { + return nil, sdkerrors.Wrap(err, "failed validating MsgCreateDenom") + } + + // Create denom + resp, err := msgServer.CreateDenom( + sdk.WrapSDKContext(ctx), + msgCreateDenom, + ) + if err != nil { + return nil, sdkerrors.Wrap(err, "creating denom") + } + + if createDenom.Metadata != nil { + newDenom := resp.NewTokenDenom + err := PerformSetMetadata(f, b, ctx, contractAddr, newDenom, *createDenom.Metadata) + if err != nil { + return nil, sdkerrors.Wrap(err, "setting metadata") + } + } + + return resp.Marshal() +} + +// mintTokens mints tokens of a specified denom to an address. +func (m *CustomMessenger) mintTokens(ctx sdk.Context, contractAddr sdk.AccAddress, mint *bindingstypes.MintTokens) ([]sdk.Event, [][]byte, error) { + err := PerformMint(m.tokenFactory, m.bank, ctx, contractAddr, mint) + if err != nil { + return nil, nil, sdkerrors.Wrap(err, "perform mint") + } + return nil, nil, nil +} + +// PerformMint used with mintTokens to validate the mint message and mint through token factory. +func PerformMint(f *tokenfactorykeeper.Keeper, b *bankkeeper.BaseKeeper, ctx sdk.Context, contractAddr sdk.AccAddress, mint *bindingstypes.MintTokens) error { + if mint == nil { + return wasmvmtypes.InvalidRequest{Err: "mint token null mint"} + } + rcpt, err := parseAddress(mint.MintToAddress) + if err != nil { + return err + } + + coin := sdk.Coin{Denom: mint.Denom, Amount: mint.Amount} + sdkMsg := tokenfactorytypes.NewMsgMint(contractAddr.String(), coin) + + if err = sdkMsg.ValidateBasic(); err != nil { + return err + } + + // Mint through token factory / message server + msgServer := tokenfactorykeeper.NewMsgServerImpl(*f) + _, err = msgServer.Mint(sdk.WrapSDKContext(ctx), sdkMsg) + if err != nil { + return sdkerrors.Wrap(err, "minting coins from message") + } + + if b.BlockedAddr(rcpt) { + return sdkerrors.Wrapf(err, "minting coins to blocked address %s", rcpt.String()) + } + + err = b.SendCoins(ctx, contractAddr, rcpt, sdk.NewCoins(coin)) + if err != nil { + return sdkerrors.Wrap(err, "sending newly minted coins from message") + } + return nil +} + +// changeAdmin changes the admin. +func (m *CustomMessenger) changeAdmin(ctx sdk.Context, contractAddr sdk.AccAddress, changeAdmin *bindingstypes.ChangeAdmin) ([]sdk.Event, [][]byte, error) { + err := ChangeAdmin(m.tokenFactory, ctx, contractAddr, changeAdmin) + if err != nil { + return nil, nil, sdkerrors.Wrap(err, "failed to change admin") + } + return nil, nil, nil +} + +// ChangeAdmin is used with changeAdmin to validate changeAdmin messages and to dispatch. +func ChangeAdmin(f *tokenfactorykeeper.Keeper, ctx sdk.Context, contractAddr sdk.AccAddress, changeAdmin *bindingstypes.ChangeAdmin) error { + if changeAdmin == nil { + return wasmvmtypes.InvalidRequest{Err: "changeAdmin is nil"} + } + newAdminAddr, err := parseAddress(changeAdmin.NewAdminAddress) + if err != nil { + return err + } + + changeAdminMsg := tokenfactorytypes.NewMsgChangeAdmin(contractAddr.String(), changeAdmin.Denom, newAdminAddr.String()) + if err := changeAdminMsg.ValidateBasic(); err != nil { + return err + } + + msgServer := tokenfactorykeeper.NewMsgServerImpl(*f) + _, err = msgServer.ChangeAdmin(sdk.WrapSDKContext(ctx), changeAdminMsg) + if err != nil { + return sdkerrors.Wrap(err, "failed changing admin from message") + } + return nil +} + +// burnTokens burns tokens. +func (m *CustomMessenger) burnTokens(ctx sdk.Context, contractAddr sdk.AccAddress, burn *bindingstypes.BurnTokens) ([]sdk.Event, [][]byte, error) { + err := PerformBurn(m.tokenFactory, ctx, contractAddr, burn) + if err != nil { + return nil, nil, sdkerrors.Wrap(err, "perform burn") + } + return nil, nil, nil +} + +// PerformBurn performs token burning after validating tokenBurn message. +func PerformBurn(f *tokenfactorykeeper.Keeper, ctx sdk.Context, contractAddr sdk.AccAddress, burn *bindingstypes.BurnTokens) error { + if burn == nil { + return wasmvmtypes.InvalidRequest{Err: "burn token null mint"} + } + + coin := sdk.Coin{Denom: burn.Denom, Amount: burn.Amount} + sdkMsg := tokenfactorytypes.NewMsgBurn(contractAddr.String(), coin) + if burn.BurnFromAddress != "" { + sdkMsg = tokenfactorytypes.NewMsgBurnFrom(contractAddr.String(), coin, burn.BurnFromAddress) + } + + if err := sdkMsg.ValidateBasic(); err != nil { + return err + } + + // Burn through token factory / message server + msgServer := tokenfactorykeeper.NewMsgServerImpl(*f) + _, err := msgServer.Burn(sdk.WrapSDKContext(ctx), sdkMsg) + if err != nil { + return sdkerrors.Wrap(err, "burning coins from message") + } + return nil +} + +// forceTransfer moves tokens. +func (m *CustomMessenger) forceTransfer(ctx sdk.Context, contractAddr sdk.AccAddress, forcetransfer *bindingstypes.ForceTransfer) ([]sdk.Event, [][]byte, error) { + err := PerformForceTransfer(m.tokenFactory, ctx, contractAddr, forcetransfer) + if err != nil { + return nil, nil, sdkerrors.Wrap(err, "perform force transfer") + } + return nil, nil, nil +} + +// PerformForceTransfer performs token moving after validating tokenForceTransfer message. +func PerformForceTransfer(f *tokenfactorykeeper.Keeper, ctx sdk.Context, contractAddr sdk.AccAddress, forcetransfer *bindingstypes.ForceTransfer) error { + if forcetransfer == nil { + return wasmvmtypes.InvalidRequest{Err: "force transfer null"} + } + + _, err := parseAddress(forcetransfer.FromAddress) + if err != nil { + return err + } + + _, err = parseAddress(forcetransfer.ToAddress) + if err != nil { + return err + } + + coin := sdk.Coin{Denom: forcetransfer.Denom, Amount: forcetransfer.Amount} + sdkMsg := tokenfactorytypes.NewMsgForceTransfer(contractAddr.String(), coin, forcetransfer.FromAddress, forcetransfer.ToAddress) + + if err := sdkMsg.ValidateBasic(); err != nil { + return err + } + + // Transfer through token factory / message server + msgServer := tokenfactorykeeper.NewMsgServerImpl(*f) + _, err = msgServer.ForceTransfer(sdk.WrapSDKContext(ctx), sdkMsg) + if err != nil { + return sdkerrors.Wrap(err, "force transferring from message") + } + return nil +} + +// createDenom creates a new token denom +func (m *CustomMessenger) setMetadata(ctx sdk.Context, contractAddr sdk.AccAddress, setMetadata *bindingstypes.SetMetadata) ([]sdk.Event, [][]byte, error) { + err := PerformSetMetadata(m.tokenFactory, m.bank, ctx, contractAddr, setMetadata.Denom, setMetadata.Metadata) + if err != nil { + return nil, nil, sdkerrors.Wrap(err, "perform create denom") + } + return nil, nil, nil +} + +// PerformSetMetadata is used with setMetadata to add new metadata +// It also is called inside CreateDenom if optional metadata field is set +func PerformSetMetadata(f *tokenfactorykeeper.Keeper, b *bankkeeper.BaseKeeper, ctx sdk.Context, contractAddr sdk.AccAddress, denom string, metadata bindingstypes.Metadata) error { + // ensure contract address is admin of denom + auth, err := f.GetAuthorityMetadata(ctx, denom) + if err != nil { + return err + } + if auth.Admin != contractAddr.String() { + return wasmvmtypes.InvalidRequest{Err: "only admin can set metadata"} + } + + // ensure we are setting proper denom metadata (bank uses Base field, fill it if missing) + if metadata.Base == "" { + metadata.Base = denom + } else if metadata.Base != denom { + // this is the key that we set + return wasmvmtypes.InvalidRequest{Err: "Base must be the same as denom"} + } + + // Create and validate the metadata + bankMetadata := WasmMetadataToSdk(metadata) + if err := bankMetadata.Validate(); err != nil { + return err + } + + b.SetDenomMetaData(ctx, bankMetadata) + return nil +} + +// GetFullDenom is a function, not method, so the message_plugin can use it +func GetFullDenom(contract string, subDenom string) (string, error) { + // Address validation + if _, err := parseAddress(contract); err != nil { + return "", err + } + fullDenom, err := tokenfactorytypes.GetTokenDenom(contract, subDenom) + if err != nil { + return "", sdkerrors.Wrap(err, "validate sub-denom") + } + + return fullDenom, nil +} + +// parseAddress parses address from bech32 string and verifies its format. +func parseAddress(addr string) (sdk.AccAddress, error) { + parsed, err := sdk.AccAddressFromBech32(addr) + if err != nil { + return nil, sdkerrors.Wrap(err, "address from bech32") + } + err = sdk.VerifyAddressFormat(parsed) + if err != nil { + return nil, sdkerrors.Wrap(err, "verify address format") + } + return parsed, nil +} + +func WasmMetadataToSdk(metadata bindingstypes.Metadata) banktypes.Metadata { + denoms := []*banktypes.DenomUnit{} + for _, unit := range metadata.DenomUnits { + denoms = append(denoms, &banktypes.DenomUnit{ + Denom: unit.Denom, + Exponent: unit.Exponent, + Aliases: unit.Aliases, + }) + } + return banktypes.Metadata{ + Description: metadata.Description, + Display: metadata.Display, + Base: metadata.Base, + Name: metadata.Name, + Symbol: metadata.Symbol, + DenomUnits: denoms, + } +} + +func SdkMetadataToWasm(metadata banktypes.Metadata) *bindingstypes.Metadata { + denoms := []bindingstypes.DenomUnit{} + for _, unit := range metadata.DenomUnits { + denoms = append(denoms, bindingstypes.DenomUnit{ + Denom: unit.Denom, + Exponent: unit.Exponent, + Aliases: unit.Aliases, + }) + } + return &bindingstypes.Metadata{ + Description: metadata.Description, + Display: metadata.Display, + Base: metadata.Base, + Name: metadata.Name, + Symbol: metadata.Symbol, + DenomUnits: denoms, + } +} diff --git a/x/tokenfactory/bindings/queries.go b/x/tokenfactory/bindings/queries.go new file mode 100644 index 000000000..b648b6468 --- /dev/null +++ b/x/tokenfactory/bindings/queries.go @@ -0,0 +1,57 @@ +package bindings + +import ( + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" + + bindingstypes "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/bindings/types" + tokenfactorykeeper "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/keeper" +) + +type QueryPlugin struct { + bankKeeper *bankkeeper.BaseKeeper + tokenFactoryKeeper *tokenfactorykeeper.Keeper +} + +// NewQueryPlugin returns a reference to a new QueryPlugin. +func NewQueryPlugin(b *bankkeeper.BaseKeeper, tfk *tokenfactorykeeper.Keeper) *QueryPlugin { + return &QueryPlugin{ + bankKeeper: b, + tokenFactoryKeeper: tfk, + } +} + +// GetDenomAdmin is a query to get denom admin. +func (qp QueryPlugin) GetDenomAdmin(ctx sdk.Context, denom string) (*bindingstypes.AdminResponse, error) { + metadata, err := qp.tokenFactoryKeeper.GetAuthorityMetadata(ctx, denom) + if err != nil { + return nil, fmt.Errorf("failed to get admin for denom: %s", denom) + } + return &bindingstypes.AdminResponse{Admin: metadata.Admin}, nil +} + +func (qp QueryPlugin) GetDenomsByCreator(ctx sdk.Context, creator string) (*bindingstypes.DenomsByCreatorResponse, error) { + // TODO: validate creator address + denoms := qp.tokenFactoryKeeper.GetDenomsFromCreator(ctx, creator) + return &bindingstypes.DenomsByCreatorResponse{Denoms: denoms}, nil +} + +func (qp QueryPlugin) GetMetadata(ctx sdk.Context, denom string) (*bindingstypes.MetadataResponse, error) { + metadata, found := qp.bankKeeper.GetDenomMetaData(ctx, denom) + var parsed *bindingstypes.Metadata + if found { + parsed = SdkMetadataToWasm(metadata) + } + return &bindingstypes.MetadataResponse{Metadata: parsed}, nil +} + +func (qp QueryPlugin) GetParams(ctx sdk.Context) (*bindingstypes.ParamsResponse, error) { + params := qp.tokenFactoryKeeper.GetParams(ctx) + return &bindingstypes.ParamsResponse{ + Params: bindingstypes.Params{ + DenomCreationFee: ConvertSdkCoinsToWasmCoins(params.DenomCreationFee), + }, + }, nil +} diff --git a/x/tokenfactory/bindings/query_plugin.go b/x/tokenfactory/bindings/query_plugin.go new file mode 100644 index 000000000..cbef51ac7 --- /dev/null +++ b/x/tokenfactory/bindings/query_plugin.go @@ -0,0 +1,122 @@ +package bindings + +import ( + "encoding/json" + "fmt" + + wasmvmtypes "github.com/CosmWasm/wasmvm/types" + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + + bindingstypes "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/bindings/types" +) + +// CustomQuerier dispatches custom CosmWasm bindings queries. +func CustomQuerier(qp *QueryPlugin) func(ctx sdk.Context, request json.RawMessage) ([]byte, error) { + return func(ctx sdk.Context, request json.RawMessage) ([]byte, error) { + var contractQuery bindingstypes.TokenFactoryQuery + if err := json.Unmarshal(request, &contractQuery); err != nil { + return nil, sdkerrors.Wrap(err, "osmosis query") + } + if contractQuery.Token == nil { + return nil, sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, "nil token field") + } + tokenQuery := contractQuery.Token + + switch { + case tokenQuery.FullDenom != nil: + creator := tokenQuery.FullDenom.CreatorAddr + subdenom := tokenQuery.FullDenom.Subdenom + + fullDenom, err := GetFullDenom(creator, subdenom) + if err != nil { + return nil, sdkerrors.Wrap(err, "osmo full denom query") + } + + res := bindingstypes.FullDenomResponse{ + Denom: fullDenom, + } + + bz, err := json.Marshal(res) + if err != nil { + return nil, sdkerrors.Wrap(err, "failed to marshal FullDenomResponse") + } + + return bz, nil + + case tokenQuery.Admin != nil: + res, err := qp.GetDenomAdmin(ctx, tokenQuery.Admin.Denom) + if err != nil { + return nil, err + } + + bz, err := json.Marshal(res) + if err != nil { + return nil, fmt.Errorf("failed to JSON marshal AdminResponse: %w", err) + } + + return bz, nil + + case tokenQuery.Metadata != nil: + res, err := qp.GetMetadata(ctx, tokenQuery.Metadata.Denom) + if err != nil { + return nil, err + } + + bz, err := json.Marshal(res) + if err != nil { + return nil, fmt.Errorf("failed to JSON marshal MetadataResponse: %w", err) + } + + return bz, nil + + case tokenQuery.DenomsByCreator != nil: + res, err := qp.GetDenomsByCreator(ctx, tokenQuery.DenomsByCreator.Creator) + if err != nil { + return nil, err + } + + bz, err := json.Marshal(res) + if err != nil { + return nil, fmt.Errorf("failed to JSON marshal DenomsByCreatorResponse: %w", err) + } + + return bz, nil + + case tokenQuery.Params != nil: + res, err := qp.GetParams(ctx) + if err != nil { + return nil, err + } + + bz, err := json.Marshal(res) + if err != nil { + return nil, fmt.Errorf("failed to JSON marshal ParamsResponse: %w", err) + } + + return bz, nil + + default: + return nil, wasmvmtypes.UnsupportedRequest{Kind: "unknown token query variant"} + } + } +} + +// ConvertSdkCoinsToWasmCoins converts sdk type coins to wasm vm type coins +func ConvertSdkCoinsToWasmCoins(coins []sdk.Coin) wasmvmtypes.Coins { + var toSend wasmvmtypes.Coins + for _, coin := range coins { + c := ConvertSdkCoinToWasmCoin(coin) + toSend = append(toSend, c) + } + return toSend +} + +// ConvertSdkCoinToWasmCoin converts a sdk type coin to a wasm vm type coin +func ConvertSdkCoinToWasmCoin(coin sdk.Coin) wasmvmtypes.Coin { + return wasmvmtypes.Coin{ + Denom: coin.Denom, + // Note: tokenfactory tokens have 18 decimal places, so 10^22 is common, no longer in u64 range + Amount: coin.Amount.String(), + } +} diff --git a/x/tokenfactory/bindings/testdata/download_releases.sh b/x/tokenfactory/bindings/testdata/download_releases.sh new file mode 100755 index 000000000..5413f3bf7 --- /dev/null +++ b/x/tokenfactory/bindings/testdata/download_releases.sh @@ -0,0 +1,19 @@ +#!/bin/bash +set -o errexit -o nounset -o pipefail +command -v shellcheck > /dev/null && shellcheck "$0" + +if [ $# -ne 1 ]; then + echo "Usage: ./download_releases.sh RELEASE_TAG" + exit 1 +fi + +tag="$1" + +# From CosmosContracts/token-bindings + +url="https://github.com/CosmWasm/token-bindings/releases/download/$tag/token_reflect.wasm" +echo "Downloading $url ..." +wget -O "token_reflect.wasm" "$url" + +rm -f version.txt +echo "$tag" >version.txt \ No newline at end of file diff --git a/x/tokenfactory/bindings/testdata/token_reflect.wasm b/x/tokenfactory/bindings/testdata/token_reflect.wasm new file mode 100755 index 0000000000000000000000000000000000000000..c27ec80a02330fe5bd590f0a981b8a3fb7150f40 GIT binary patch literal 2194768 zcmeFa542rZUGKa8?7h$5ea=3~Nt-sIti6-AC$)zLElF*CZ**nQQm(vl@jc!c+%X)l zRGMoWN+}`o;Jtg>1FaY@cnMe~AZSoDQ9*)~OA*un1p`(I_x5Vhs^MC^L5oDKSfxJR z=llE3xz^hIoSdAL)^UB$q|I7;t@-CSf4|@S{hf2JDI?J+ORi}7&BZDL(e zDxp;eLe1Z4u-wUoU!fQ7ViVj>#WuL|bGGqQw>(lKT-tZt$)6;9S2mmPzWudhH~+wm zdw1V-b26r1^q%+j@IzBA=X`N+u^K zCnhG_lau*mo~M&}mgl4^=5m$$+V*ybL~mq<&zWY)c$Zckx%H)q&ja2;?(}=wKof3ZGj{RbMEuWRyvoD z8U7F9PNpFm@2D4C*dQIVs`g0SLW9mA~I+MKZbUKsk)e~T*?J=;iKFjB5*T$#n zIS`Ds$HvCi^M5v`rq#9m z(|`Y^?9SiL4`m-sH!Y=KNdI$sBK>0eQ2Jlf-%Ec#eK`G6`UmMBrjMlm(|fbKLE4+r zyMCgzKmFnKN7CO+e*-D|%jvQ7gXyoPN7E0bA5TA*ekwhl{#N=c=_k`aN*_o+n|?a| zO#0OJ6e~QwJ>;u^svInyV^SfIQWq+9cLH5VlpJx9p`*QXt*^}83v|3dz) z{L}e~{LA^D=YNs^Wb3i~Yx!U1?`R!tO@8Dn^KWncbUSOI6SgezCn=95uNZW;+I^8O zWJ!N4yEePFNEegVb={;GTgb-yu)ajL7z_?~h=71|n)ZF$#8G5(4o|JT;>c#-$s zR(D<3Ei&G`>mGo*P%RX>LsPd?~y4X{u9RwP!I&`jlJ9t_;{~3w7s}f^+HSZjr@xiLt zFa%Vn1TT(C1E*Dt_1Ffg*BRTg{ttuh6UynNZ7LEcTKN}!qoz#iZ`7-jN;-tTG* z0=C!9ilj_-WXW{y#mebDHd?OGm={H-=xocb+?mb80oKwgMO0v14fOVS1B0=uiTT0g z&OD(zda$QSF}V|JGes$*n#Yno&V^Hdnx^?(fjf&=3^IT0Tq%}Fh1>)H2YH$98?=hF z;Q#O4G)T*F7;W6{?s`r6?AP|;I8dFdLZ+TJia&N_^IVd$<%8^LXqoV^k*hV9F@)ZK zc!Thi!IS-*Mz~4TZy|uW&`fJOQ_XR;Ge}CxFTL*iZdxSjFE5hb$L^+yWUBXTex+;? z2l}Y`7mk5hMAvXn2dJWF!Oqt|Gkx=f1<3}{)#~uD18@u7{xo^aBK+> znT+>0rWQaHhC*((Y6j$#U(htWI+^yWf~S0s)ow%ddC`FDMqPUcH8XrL){bOYrr(Rn zwDE!-wBUN4LD%s?+sG@SmNCm+sOd$&EtY7D>so?C+)%WACW`owd0V!%W@OL}gKKO) z1Hj>0i@}6Yhw%XubY>V1POAw{3vdKND+o!=`v98{B`I33DBBWodesRc&W2Lg9kk12 zA^FS_sNa!DPSIR)Me;d4km$3jKH^5JCOGvf3eJ&Mqu{h6COD18X_57Qa+n_UP$s<- zBDm&W4%Hes8yM$7aWFgR?96+P)WDCO8riD3J!1uF*O!JAy_-@{RY$ zT%+k8APU&~v9>^~`YgtR zM&nhb(MIY*jY^|gvC$S>qp9&on2{DDVXTM|rY)7wDO$Y`$4OVTr4JHNZTbMJv?a?` zFv#+b4H#f_3ksx6Nm(1 zwhqQbpM~CiPA>f@1|3Nh`K9{-j27lstLTIYVudIOj%MjdRY51YyXWLpDZXNMmTX z;W;OzhES{K96ARLBS|PX9qzGFeljqLUoC?8eB<>as_O)sN%D`f(|Z3i9BnG1GC)`7hxw z1>aT(e?iwVO}D82;ZR(RVbkT?3H?;2%ZL7jGWeU(q*S<70lXL%9i@!vp%xm*BYd?6 z3K74GVhGu1jAZ}f8OV15y|SC+Z+sh`fdzDpRwg_#zAJBhHOaST&)`C}Xi-nD7PTzW z-v1*@eCmn0bUHc>O*7n7MoI|hQ!;N5zzb3;+xPT7uis_TN2@F*+Z0{%zxugAkh@Dy zgxD-^kSPLQelxkAhcouj+xT>76Q|eO{B{40b<#&mSyV`lZswh-svh5Lafb~hkCth%8~LVV@=emXTxRKWW3 zf_sVN6ONt6K{moS8U`?pMdJ>+1g}zB%QIA>DeJ9nqXzO6R$|usoa1>RdmTn9thP@{ zgN5vl{)8^K#U2*2TMRcTKxX|(>vp{SzxT{!X+kh@qWtg=V-De0zxy8Jg%=Q}?oSd` zEweJ^^~daW+h1?uO~xB<$1v$FVOEZxp{3MY8ei5DonJ?seO&1#w^c;(iT)%b-ykwh zKrclXjC`$PQdEVE8097lYYr-Kc=irj#te{Ib<-L0$22zuaypI+!0qrRFTr00>wBUB zeoMLG1wfORk0**g_Z6W&?YBG?LLmwEl`%{-*C>FIXI?n|eSXW%{01ktx`>#wE<|id zp-u!s=%ibB()LbfrWLQeu8+SSOu`lVD8{bqb{RC0$bh)6c+C0YxcI`kiw^N$4VUIG zx`QCts??ChC2rf9eLoHh4#G=C0xJuL{dC05OVtL<5vuZnXZ?kQHm}s`Y93xHy$Jcvf z@B2h^O`wjG!lsiUP>eC&pHhO20?W#2Bo8qsr_Gu+vROnmFCXM7c~mGaL}8j2AX0gb+JQMjVxmhMU(>ssEFa#G(oex=T%NcqS>E zekzg7oc(u}L7TKHQlpcRJ0;4pn?4vg%&U;M!`gHB+_n>A>nSGIJ@7WLm-Bpkwr3|ke(JvcqWo4VX9hEJucjo zfpmE4fjhuzMTIK!GAJm9NWf7|;LnQ0)d;YLduujED}Gq&a1-TR%d*hwK+P^#aip0=v{ zWa_uOc}9Y^6OF$^#9%|l9UPy8kXJ$() z?Skzy|7nYr0Pp|UGc%PX@y|5Rl#vIL-wsonPTaJDr52O9ex3_ivgmSIbdat5BkVa{ zW!Ftp)$KHkiiCDlb%F&NTx3d_a7jw?`pNXHrFL1d0taczOwR}erfdTl7kE`!pVxJ< zqttylcmWc#?reXmDsFEvh4!aiEK#L!-@-^~dqdUsy{Xv_KvN#@+cdnF6h`X9_6?Pt z$q;VnK$j(ZE1|Wrozm;mew<=1cNBdK-XeN!9N_(G) zXt$Tx1=4~6dhCZx<_`bTq?-o=ArZNhZDXLy7T!W>CC2p_IbytNVr_a_)d@&92lH=y z!Np?oQX7sKR=E8p!kwpfS97kk@Sc!oFpIh55zg2HNae-kCrb z9s+eVky?8(f_(_wPUP3tY>s~|&YFzA!sIevp)^iQ0HI@ zkB)&LfHho|sla!eoG0KIu8J&YrbggKW4Jsr9AJB)yjPiLBCYXe?5ySUsT z%q%9i`M@%TSQ}J$u9J7WF&)N>4ZNmZ2JOtG`L-qy6Qm)kR%|bfe{@3H<7z^h=)=0k zOP5@dnKINe=9M*ocP>I9vOwofw4=3<$ny+U@x6wtVs-|3fdWs;DYcJH9EzjGS#E&l zSGDw-q^;UJl4&lJI})|uwgF1hOYn>_@yp(8ZDnCr9;za{-@Yz?^qt54`Rej}rt&#- zd9|+WB<4)5%O!Zy=9F;>Cmz1m1-^*7idso)gh|%H%O++Hz@yeP}Z90xh1@T=Ia9xhfLT<1{is4F*uo?$LC!+o?T$c{eale>$(k zHPT1I+ROl$$jkr!P9I3t&wT{ZW+0 z)_^93*>A1h-^rpfeB!2o)|U(>5QvD5>(tH*OmxiX_y0nbFIW=Rp3Umn3wie2^|PL; zyr@5?%MJZ?x;!6vx(JN1DUi2g=GA<@pI$gHIMv`R`j?Z_qn;|)qR?!j(G-RHn-;hkDBDlP=-_1hc!&VKqAuWy= zW-X8NrXz;SI^>AuC5{-byd1H%Ojs(2a06TPswh$IADcE-L}HFfIopTzopXbMCuO;h zmY6?#X|ktZ>--n)wtm^%!q4FDoZcwSVb?+h90@V8myc{0S$;+ z);WR$Us@|1B+(p}!!Uw_0-rT42<kY0;>s+C*!J@smHSBnm5);RU#O9S(#@TLoR=#6kcSy+S+i20|n$sFoa4p z$y%xHv2pBr@wA)UeT0mDSV%uER-RVuHoLaK(Llf|5)VG_`d3Qyf?1Mz@6mi7fGGt^ zEy>|F&!z zX$*rv@5-WJp{Lf)R%@pPa#&AI!763=D_Ol*T&ta0Tg|Vnaa&}DfVLZWAizx3jFo7P z0PrF61C(R|0pc4J7ItBD(KX|w8=CGp7}LYv@5nc@mGqkQJ^@55yVC<9sHIph5)qVm z30%pR(<`t&s4VBT;+qNH8aSJK0V-92l9n`$k8rj|jRq4?Q-udwXIOFdp8vhA4S`eq ze`)mjms<6@tGqm#0X@iw8J{Ekwx`a#yF_xb55JfVCw-1&X5(7kVuh?vD*SshF=KM5 zYPd@Lyf0(g=jB1YS;!7$gE(X8@STkgjk9@nFm#$&aNqJi!K))eoCmLt+stlBZ&*Zee?wTbNDHOGnEs%t#?EcMUW7 zjd70W81UN|urPfIz^>;yFQH~ac7uNL|N6B^#SNMYmRQfGf%3djsc7#N-|j&J;9gh3 z{V)(VVEYoV39^SB2WyauZ0oY_95s9U=NWF!7dM_5Zu^T39G@7*v58#qhc=0sFsPcT zK^14LtJCX9#q)(+q~Zo$na-BCJEK&bF#>PE-k)JRi<0c^@+(d0$NoJf*=Hmi(-Il8 zfXICGQ(t^@=lV@NHNj|&z=-F2Gg#GA#fCF9qvQkf`p(3 zr0LBSos0Dn*vPVB=!8W_u>uHrd3<=Dea>XhVshN)nAT;(Lgil)SjieQ-v(Sh@h++V zy!Ts@+am%Noa z##JU%3=$_tW2wTy+=d9tG?m1JWwViv3TcSx+@waZXnAvVor`M-)KA*FdH7J#LYg$A z|NE`6O2K}@n0z6-KkfJ7Q$~oS`~&s=p$d+pf`g9J z{`pE2nBLu@VrntFw${83=HUG3jhs*9QzlK)-^%}Uo|W1nhJ-D6vPH^bjNxo$7#NxT zO5Yx-;Snsq2rRlDag3O2=O~GBP;bMmJ3{esEUNR~Y8;2cI9mPl4IJ{j5wme!V0_U4 z<)AfJVf5W@vK-(k^5tMUn5#{ew^b&~fzVabpP{RZ`Tr8Fj55?+s$Y8AL>-VA9}Z?B z@@9f7cd76dj23Woer2@GI6m#Y@F}AO1k6=PRQ{|1-H!&NWq(9s)nmhzQ?DY~dR8?| zlUB9vyx?BYCRdJZDfaJh+iz$XElb{hocEQ{Vo6%YQa4kBDk(cRWVEnG!Ia{qx?;4f z?#c~JlV2)pV@$4GaOPxEJpR|8{N;{WEQ8ve`|MjJdneb~+*HmuePew^Xb3>R>@RXD`}^gfG=tNL*`XE1=waHRglp}w3p zEgO132G7MivSYdyJF-vcO7#7HUAOMY%rm=Go>{T=x-MpvDeAs21B=fafTcIH0t3vZC!pKK-F1o&U91HilNGx+Y=HZ6#b_>(oiJJP-_U#7 z=&8(BL!=V4%SQHXjqSZ|B*8^CHk`55$7VRL$2V)SDdtB`9!jz%hXk4*d4HP+5?nY{ zHg7#Y{VtH@vZ&9=`ZvYy>-#R8P(`nEgNV`Eysz~6Wku1K2%=hyODY#X7uLy8bDvbV z^8DWc^vn`z@e|ChN{b)ohpnLfj#?evs-C3+Z;AT*GEej)axPapi1Wo^B@{tJ+=NBx zS*63J$+i-jpv>j94!_)W_+`Yc23lnD9n}!XM)1p%4FGYIn-woJ9GC`oBt#AFEx;$f zez#Hc-^6ifDGs`+)xXR@nG-19NYvl)MFR}2(D{xUlP~EP^q>_w;Pb`Jb^R}lcGnHw z4aN=KJcs`cZ3R!wj!_@a$t&*?7|awI3?j+~L33}dH1~`!Q<&zSAqZQz=C=2)xo0fU zS)q;qdvir?>DJG+0d-Y>L2t`kRG+T5XQpHYSZ7{vZ@&O#W+&!apVL^#|J@ogwINSj zpW|j#P}(zU%AVA1G#2tBS{e)apUC@H2&qgYmJ`}Uaz&HJUNl85{yGB{voJ5Vm;atf zLt@d_t>s_eEybJ5si3;IFKY?`B_XyQIn{_b zY=vuQTy<}SZrIvR#=;rT%)712RCh5`6nh7SDQ*ZZ=X55l=zng%C@yn^fcVQ?^&)xW zz-!eT*1tJMP30n*+zf(+ri$kPu51Yw7!pP`Nj@#LGc3u&N^*LLxU(KabeEWLO`zI$ z2C6+rSH$0fq{U^@Y^!%6&3K-MTpcuE1}TBuD!^~ zJsh+b=@HtfwAaH?dl^6vH^;0*iia-HXeJ*Yv&@FDR7_Wccg?hbhPD0Xmr18jSIBSZ zEoy7YoU~$d6cKMvX&jZN@^PT4Rv(Ay%7yIF+%2w?dH*tD@sYg$TqXOL0rzd7cmy>#PbbzukLORkuhr*(xv9@7<5^OP<4239jEzoWT30HYF}Y=I%Ob_aqLqmr8D zQQ&{MP1oSuDW)~%9(HxH0B2;(0VLpa@CbrTut!J%vkJGGQL`_I*}(u-qoNtH$8(!k z<#E`j-8&pjln3+vqPjnkYvIbGTdvrej9BM^F<=&XXuPa$(QsJ~S`3uFWsR&)4(wFh z;w|m3g;EVYxvkF-EhxJ zegM&uXVNBkV|Xtqnjtbdu6VrYeMt`>^m2td!L)e)F6M}S@c;CMbTkPEzsMv%2I>o1dy zyU#TPcq$e|WarGeYW*^eoQX3l#K#du*JkEvc5Qq_f!8$&S|g5);+civX_NxSG;j!mSys6b`NxmdQh3e z-eC)ee-~5(O;?I|R|-w*itp-obGFxoFnd>F_AZ%Z!tCopEdO~b{awZL8W@@?c3jsT z6g&0Lj$&uzC#9u$)*pIi)U08Cpr&X8W|W=4WaYsFnXM6A25A>aGawzwIt=B}&IIWe zLA7NFDpoeE1btF&-BVmCd6P(dewW{E-cvl!?+`m=4E2_scRTzJI_|W)f*o1oyI2O~ z={YU0Xso)3Mk=ejj%8%!JPH9dT8Eo?u&|IqOzv4QU(>MmMHG@wwzPx39|#LXtZ$_} z;2VT;+B*_08(&_5NxS;;ip><*mLm;%yR;w>O)x1jcp>xbg8qfm8$A0Iep+HhkubAS z*4a$5U(D7jSsKiAczL#0S+R`*>%uhORAa(cwv_o(s9BWyw^au-Bd~+61F3H-rb#$hg`g6lGiv;RDjPm5h#;F=~5dMjeueXJXV` zOqommaLp9P+T?O*9f;lpWSHGr@!pto#m4@X$foat4$mvr^>)zb?@<0xn`Tdq0!N_$#N>9sbq$q^bVboC6SMKnlJOLw{Wbk=pOE`TR;wGCe@a51F z6gI*KK)iN=A`4J1zE-S>rEb8IwH!9&Y9$tWh8D`>+}a-C(3mZM0$tM0%UCj9nI(rZ zwr66=RIHdbIZl}1S<-wa6aW%Y=t}blaAE_J>ev+-n3WP@z3{H_Hx=0jc6}?o`yOq{ zwN%7|U_*PUgcYrSJ(eM2S(f|>+k(4|){&;Z1y=${Yl7_{Q8HSsJzEiGY)Ab#XYI2z zb&LHf*SL7vrLY#~`y3E%ahKMzgxbyxW>^`TTmxlMwwBLVi>I}?u$4?qq%4+aEkII! z{r6b!FrkEEUcTQXbBKts1+-cKpR&}Moh5=xmXca#ySz2k<|_%zqpB$_3N6x+rt*=d zsKJ;T>!*iyTG{&PHYJAEPq(#x+A3;2^L;^y{1;(a#IIoGggFsV78H}AvH~Eom^?je z%?uqIi1$$)+|7{fY;HS^nt-tePct#Yqu1zNVZ@v{a;Nq~Bv2+P&xJId{^;*@h@V=> znk}Rui)1aZ6Ktde-H}CNG|_nkpy_aIcqmMXdYR7DH_}X-px4fIPcyGMs(b(O4I++B z3`2*8a~hsr_-TBlfy;@V_PV;>PhQ5 z46tz&`e$M5~pf4%I5WyZb@s}I2R4!|34Gv`p-sCD{!;0QcLabYGC+>Tvm4G_Po z^T?Tl&&aXsKb5ycX)S>d)aFp)FmC!Ms1p?{(u7Ub8jJrG$q7Yi`2?eqc=_KD4XHkr zGD-?P@M9VvN?bD?C)_U9eT45R2TKy}LSFI+R$ z<22Ze|Mh{2Y9Hh2ytzL?Yc}bz+Ml4cWww&jEh54jrqo$uhH0n2Qt@G>nT^^|9Q#$WdZplTV4BF?LJL2wwW^al-tlkkAAvTHzvWlAqi%? zyTf5tgcD~h3C6S~A!UbI*?ahzX2r!GLmCVOVE)83 z80T4`F0DHRg9R>UL>AYYT3^&?oApJ8K2a&GF_OM8{q4(|?c5}LLdqvJQ-cboXwHvV zfHt@{v!c;`xd#=F=0f;F_WnFlNxzQd=0mg6Enu*#bFIb_eXPe6bf>gqWMjIEMSBT5 zFHxtR@?JaEYRc1O-Mqvgm(1>LOOjoG`o|ypxx>Hm@P{7fWY`R{b+8K~#X!-l_ad3W z2Z&@b4)-EvN!^qj?ghN_0%_76?IocX@o>rb=&I;2p9PUx2iO=o*CPodg%{GI0|!i~ z3a*56#SCRZd0&o}(#*^M7VH7sOO%OHL@8Q|?WZ$&t6Iv-Ml$3M%%Mb`GjJSS$g3&b zA^G7ihu69uVPWafObGV3KVwK9uUFF?v6P%%-s9Ab6Y2%*Ol zC!>k#79BA=Lz-H>+VreNsCJT8;?q)3mE^qA1SfixS+{)uF4yGThDy$@)ABkb zT!NreXW_KyAj~A?x|)PtTXpxJKf>xglW<*;#bwWlAO7t>``Yi{_h^uC-C+rLp0}ST zW)`g*X+NX=4H8Z38tqHAZIEzUXR@u)zGT}5mu=cvP_Wd#*Z_cP0NA5!(<7>HaM{*{ z-s6&Oq&S=hW&={Y^uBII*`~IO*}VhX<;AWolWyInbX$LzzFk>IlvS$*lu-^FwxGiK zp@(9=u5#F~b|22cr)PrA>M^k^poYcn zBZ%DxHA3Pc$HM}Ii=$9?Q%jzOtRErA{p;G*%u>sS;w zTazh9ZheLs^qN@_a(P|qXKj$fh~8(Uc@)PuI;7u#%UT0Xza&>&9r?g2)n^*=Oar5~ zH`I;rudgD{PcQtD%?*Cn=>P@XRoL0#W-_jUAQjx$p^#Z}E3i8ECv$yW$rzqrkK}_D z*0b>C!5IJWVjzW({d!?Y?!jqr0LKkb8S%VrdU3Jk%S;qXNqh;1ND zD@n)Pw0hL6Bacvm)Zw{Q#ps=MD7Q6`&Q>ukWDn&)P3OSpDJkNus*hjU&~bCFJUs)J zhm|G-pa^@*U^*+Jwf)kiHrU`JU@|nMQc(n|PIQ@tv3bGPE|Z6|J22SzP4xK)jA&96 zQZcXwtyHnWGxDjHv5iyS*``5u#!J%F@bn3Swa{C%WY&sOkU05>>@>IVfa>bxK9QW* z=TR16V839fP5GjI#L&v-mv9OzA|&1TvXh|d;Qp)4;D8P9aFYQJu&t7|St@CmUDm?yriG8^Q9}jQ=54wZJlIg=iMx~ z%MNm5JTGe+djBRGdM~XEJ((D@GV;y?s?94Hchk|hn-0dE?I1Mc4n^Ic7EYsq$5wDR z@T`m*cwPuAu(qGH7PY~s-{*|_V#8`>Tz&Xl_X7 zgn*=f-iT?{FsbCwaQ2GmPcBIMR@26Z`O8ra9x*eDnPnr}z&JKb8f@;$VWMmWW@8bh z*D);$Ha58bc-)MFP-)mYkei7}j5-S}4;d>y4+ZOLEBrB0nw}vDibDu?mBeBNglwH* zAY`5agjotI7SZpT)`U$}`^d7|J_Ne3wPm)i_;?T>(KcG9=b{BB%nmmAE+$DZIO$o+ z1E&%Vwx0ctyNeAUxMyH;g6TubW|*-{pElPTQ@2dMOFC#CKr18NvJPa~tk^R?#d2AX z_bbz#1mq5M4p)qU6S{I9ZfzmLiztM~P*6*@4KT{$XYI`Imn?=@^1{(2CN}q?K;(?; zsA=brm8EiYpx}tvD4Dgntr56-Z`xPb3#oa?!(tMf9=M90@vO{*T4ZWFTUIZJU$&hs zh$rTfd7x}*)22;2IG_&9N49j4ZDo__WKXjDdIqk0FU$PmT6E58(4M7KW^%dMoE`Ry zwTZ1EGTFq2jOV-%A1;g_z&VE7lfQvS%R^ZT2iC|UL@k`fkzW_tQ2@HWFM*0n0qimJtLThl6F|OChf3fP1+&1 zOxl69^>IVhtQ3?G( zj%PXe);WT+?pylH+f}R3tRWgF`j#&6?2u00VyXfh%bGRR9=@JLGOHj=L^DJa(a+ZM z!8x<|C8bTFoIPf&WhH!JvffVb^)T02n2N#v_1a+PKm{|{1;NPx!6Uk|X!c=UH$w!j zCHoSve6s5|4OmZ2@YYT@JgzG)l`U_;Vf+Xl-XT59%$qpO?Y8`6)@QYi`aMj)@6cvt5pEapE0oRBSXnetj};Q=?CB<1+|62`?;VNi zs{aG@Z%qQ%kMR8O6l>!763z3;DwEMTm3C?e&*r2N zfL`mtm=_w3{1~E?FkUlFjVv*ah9xG6L=y9ec*to$iOAICISU0N_C&!CnwcB?R!0-e z+VoMqW8o7&HYxA_NohXq5r$8Fp$<>6sO*HO)A^pQ7`iOd`9#)SF40V&S5lOO@VTCF zXu)#NL{?w!S&JfQ}*3OEz`p?GiO|x0G1M8 znZT%{^_1+|ptV97{u}jISdsumxmn4n(ITx_w+vGYo8d5 zs;%(dXK#2ZJLfL0*5SA-_V6V;wP3t#_3qcW1TpQW;{Ju~o=kDs8yK7~lWPkAK?iIQ z+jNn>QK$SjuUgy>_)s9I)u8$CdGiCZ=p~+LRS}1HhmSq;WpsVY)2HA@3$c6qRdN70 zwgJb^Y_n`uUbR!5hq3G73G+JJ(O=CHoqQo?AtACT|>!CaX zBEv(Yk?`TTPWAmi;Zqs<&`A6;qiSbxiau8$PJwUO=JwHH^3_yARv9UExOV(2)uly3 z`_tR_>Vai*uTwdzrOzL5`!FAK;C7N*R&3~25zXnGMl3<=j6NosL)Soas2^yq7vgfB z7+;V3XAI$YQCw6K>|^C$7>joz0}8^xgfOE7$$m7}y%j^U%9wkro9ROtadkYJY#NL* z3z4|hmv5b$X~@1@&{ETjG*&Tg8_shIj1RgE#_cv4mtaH-uMNhGvi5`aI#j#?^qQJqpj!|0sB>FRsQZ5g|IarX8M|4q(pA zshLh&>vs|pnl4Jd9P~lE{HopI1@%7G5G|Z*A1CEwY19&I1?E0X%2UjS_q@TNryn!L zxL$4o_@Icz7#j2P6po>uunOPiWm|Hi%lT(QppZYKizyUN8VppmLQvI?Z{-L+(UoTq zIm}Bt)oCv)wG`3ucmo~yR1qDg z*NTp__Y@FJiy)MQL+>Y==scJD<(q#@1e&IuD@7Qt_Hn4*5P{CA#g8wk#YtKsV(d*m zU^m{Tll;2w`c<$=KzEcbdHD{5l=U3vLKn64PeYdqX1;-BbYb-8LYLwC<zPU^X0B=?S<&3(v^r#jZlOxZ$~L$Rm#K}k;qfa<5%6G!c-`5JCzbbBAN zM;PLDL8||%JvG%C&5=UJr;PybsP|zjU~vi8t^4;&L{5~g^2gq&JALWfbZb@_y%M>6 z$hLVrOG9zt%vPv;q@iveuGNjK_9uSCTDMWUB(^Zha^b#uPeI+N#c+I$4Xt;t#uX`& zpBY@?iS}fA;+cf9=cWL0ZXWjhF|iSMdw-BaK84(u&9! zHpc6Oj}^muKIPl>m*o9HN5{!vi;D2F%PR9tP9lbE;%IjdT?S8WZ^>t(U1Moc8Oz9w zD0@8VRJJ*!mS|U&(_->?Af)@~E5EXdwel(Tme% z6|&fv&zUS?`aUe7qX}l`>pUfQ=pW@#iq{+dS-a_- zs`froiy^kg4Hc6|E(!df>LOZpPZ@Y~mGBX+xC#E_&cb3;rl<q(y>{3me)7Xd3bP{mZ49YAOaGDOWW+WuiWY2+j_lu{Om-6GcK4&gh+}9JG`rQrfCCPWoy; zQf8V!oGnCC=O@W>DjY*tmX$!g-;K3iM*b|~&(<;FS4%9VXi2WUkJe~ZWH1oKOS-a7 zgMW8_qa>QDS+e)B`knSNo;{RjqyXkXF(X}tH>r(uXLhqoh&4q8&sN9;incy15b^}E zFRJl+6(7kpvDaf)Devo`ZW{QQhisw(%j`5Q0M)n`xyMol1$Bjf1d?-2{8CecX~u&F zYrLv<) zi##kxjCo!aApKhvmSXZ%h+C-f7 zESUZj8n>9bw+)^15IM3Ig`~5#m}nuljbj9AV;$w9^nob;iRlVwmlofW%H{{1oruCF zxA3_vaf_@cE!BIfbyc&KoS`50r<(Bw9-Rh0znP=9c0LRc&S*fqSrC)<6gJHt!fmJ_R?TBc6q$c9`OHny zH@#5;du(`;KFyO=N+g+47}^M7e1G6SsNcylE8i9FLio>_6{@a*@84%t30V6Ks^T_JDQ@R>G>dD)R4C4CVgT>bTt3Sbvh`|fVJ}++0{h@4ue&r|MV!1LmBaYS1^*#9ox;eA)D4TG)?Mr z#7$%bS{k97>!G#!rccqlTD#E{JWkPaNE!XJGKGF*-7_b^-)#bXBsdfWxlNmI-y|}9 zV7{j>f->^il)d{$CCbOh)BXp$V}E2*l;Z`iVHW;3+eLN;@AE98-1a1`NzUk#4el~V zp!4!44Cv-cg>w|;_8o|`i}JOM@Em4v9E!=A_u3eABH#*g#u$L)?pl2&^T3BFo0Y#1 zXk0HVI!7d_(Wi+G&H+hrD2AjDICpB_K~XJveG0>faYmDhU z%_1uf#aQI&py*J8t5P&f%rzS}X4gJN!^Y~aNgV|fNWcvlHX)F|?D_vE459aq*N5ny zAV>DJq%4W=lmGc)%la&HWRxJX#H|z*4MA4Kln=V-%ebPO(uiaSZZKwe+jGd5BlGc_`P8jW%oRT4Be=Xx(r8@fUx& zqfM?>sMxWfe^}eCe`ak=)?eS1;+cy*qX=xlS2AOGTa|M}rCu+Mq5t0s^c5Zih z??1hfM2BNlbgzq~<=3o87K$*VM_b9tKeHlZp@^YwxRt#811mD^MHKrL4~b{aN@{D4 zAY-)*O;sB?y47Y!73>;aIZ);3EWsaOfL;wI+AJm-&e1iPNNC{1Ay1c29bBJHHMSI{ zRU#b%*kYdY$Xn%ejI#s9_Tf2+Brlgzg)Vh>k7WY6wPj2pHLb*fTFA?z)&hC=>d19Z zOgGFQYbz~%T|TRXQq2xV)wgp4ILAdCv6#fA9opDu`=e~Z$C$;CZ8u}Ju}?4h%+;(h zS9w;?RoDUOeXUNMUxXMfNetN4)YWo_wG}iUnTgi|R+cRV@sSmA;u%OxJOd+6JYKUF zA#S)+CGFaq)Wp-PsW9JC^cur2wx@Ty&VW1JgSCJV`@^gz?msxE8QrlVfPMVKS4 z#zmM`#C9Y_9zfdqHokg-GRTStYO?!RobE~cwtzF1*6C-G5v_7F=jbby$K1Y7Wv!<6 z^5u$wX1+<6yK%|jOc#^EY$y!UOE2`92W>I*H5@!4uogG(ImF}TTMme8C$QTpuC3t} zEA8h?2rsJH_XdZBf6*k>E}?eFIkuf0s&&e7H@0{caHI@$s2sb)v+wb9QQ%4KBxRRvKqvSL z=oE1F)r^2dTL-K-B|IsBsHRFqR_!Du4cpwl2aFUD0d{@m^e4ahXCHXyM;{M6NtLi2 zZNykm?MD_I1t4eyE7D*=7RL8}RgyjsaT1|wNpKD-Z-+g=K{ktT1ha4SJ<~w7)zg-~ zgn@#@rw2_PO)@^ zn*J)8RY_PJ$V<)x z*K8XlCYbmKJ?S{`lf+K?LRFWw!^@<6p(;9wT5C{+#CXgA@ktTBAZBn<|UTh&0HU2BfaQ*vHpo>j(+^qS-+ zhWWXB4dc;km{{3s;52uPm(OZ#($6ob=(y^x z1_@&pA_s*pFT>jMuAzLT@UelKnvBF4AgJ!HzyACu|MVxn{`(*O%b@UOEsZu36h2$! zS8gQQoZ4kE>H?Z{u3SKyRju+#JC#98W#4N1qC2$*I8vfsSnWQdiGBE>ZX+xATN@4k zZ={X9yxU5&EB6lsA!Ua-#SR%$O*a#DG)b87^MkR9Q|u{vw#g}48X7#Y2gjP6ak>IN3v> zsEwiEsoYcV_#fx&+%NZn-eq z2W29K?M{l>K6sTrLmkXcdBS*Wg1O;G+yK&xIa~@EvzWY8?g@85se^93ip9C&cj+1D z9cB%*v66rxtOvD5I1bKG;T7U0$+lZ^78I&{8I?DmCAbv9t>X z2;(jk8n~*f(=hn9E2sx!xxVk3yV(|lAi~9vu|>6wY<&vyR$|567#$YQU^IiU7K0lj zFXL?Bg^uJconZ)@U8=|USyOx4C|!Gx##L&uzj-iTY40HRIaMnL4+J81MVQSG{4<`- z?Kqn|XP(Uq$yX$Z<-#beqa$0sst0j4cmDr3n}6Lk#ktPrPgynTzqQR~3YtIWv)FdP zA&dTH7Ms9e2h!6yi~nfoKs=5U{O4o6S?pe16=U~sh;2sWD(kI$^iyAav&HVM(9>hM zS!@$E>sC~~Sv$wfA?9@78arJ>6d#4aU_-yPZ5pcc-zwvhuIYM3>25#a@kwgpclkIoN)?knPjC zr`m{16~3xS!@9+k(5eB>lLM`V!ev0m=|_-Bj^EL{)56eXNaE%_-BX z=#-7L8l5sL5^FbRg+5{{Hq%*sXB(ppt3q|P*V1_tO11`Rvq6bL?{vgD5Kb0 z*0SY~W5d61OvveRkqJZ775m*{?8o`q#(TF_ymv|-1V)WT@p{$1@jGmrzB9OrC~V<7 z#{pJQix1gK?ZGzZ>t+1&{l1HzLaG7;i^*;EUhbE6aYr=b@c}k;HSp+F7?I#DPL>T` z1y6`hhArL7fu6m8_`lwYt+}@h#&A+4u~cIU`OtF{{y*vM(wJFd3txUl2 z%&8xL<(Ps(oA{b+YX5KX@X*o8N(aH*CpcXq?S0U)9=H}dYohvfnqPVK>r@Agz;}== z@$qoh`$Ywt>iN31JGHQXthA&3Tjc@L61K;iwz-iCGEKG=pYI>59!f)6LiR)lf12x)9UN+|2gb;jalLnp;65b}j@cofr&|X9qXz$}toLrguX3kbWmlg* zXqEfhk~qZjTjf1|JHhRe-%fJ-q-}cc%L}79KvwZ-HS##00O6^=L8f2U$rD-lNG}dD zsI<4?%SNrmL4|k?1nF&TWRgN|Sb%3Pz z>q6_azE=oun>S7<);2DL`l=uwUJ7VY zsZR$!Wu(n|gITX>eS-d28}f4CQOE2hRhjkA-H1Y7KA;1^(DLJk;T{5+Zzuj}O2yFo#k69=kE&4=_dR3YxtpU208pBu1-z;q5u| z2Q>qK^rjl7;AwKvE7*eizApQs^R*Pk@&w<(_DEG<1~odwgGJPVMSTaD4O5 ziNYF$^&BGH%b6Q1{pFBWqE~}?`}$WgZ{PmP3jeSx>X^?zPuPbxm`T;wT=lf)pWmp? z5-*Q1h6bF!2%LiNh~SeqK?B~^I(=Ryv8HK+R`vCoDZXAar?g(HJUHCYJ8i&f>Yz7; z0`Qi+of&aI=T`~S+|f)G<7U@HwyRx@2ozT&)9$N8Y1%Y40~p0Ey1l!o1g=8LbO#yzUH$9<9qOK16aF zBV*llSX?t8rgn0qF~HB*6bz*cDCkkhT`NLRkwAt{a+Nxs^?Cixw^FaM(L*5w!YDIEYWf7az> zE#}n!p&*o&NxDO46gbpk{`Za_&TsIIPX__TX^MM50!D?HOMPwHKY%rsH?-}Us+@PvMEP?v|C@tEAMUHp4XasD#x z6ict~}^->>*LHvf~(mV}3{WB#`Q}8BgfS*A^ew6*8O- zN};M@LIqtm=U?9q%r6YIwk3aycs-2`LKm_e5+a#@H->j7juBtEEN|_tc+5o>HVS(*F(ZI^9WLl z4fx7xTY?X{(stNSw;iI2KYUJ9tbu+$3Ecl}howDD@xJI3_WDQk10s)On8CRClLJp?K9~V(^VYh{c4TNY&UeudEAQ8xjjETo!Hag z7@oHG^5If1%c7eL!!1uYsQ|VC8I{f4{%vOu-|jJ?)`*{70}N zt@(m(7Zo<6Wory^xS=l_e$~`TZ%Qi64FYQids8proK%vm21t^1UC%$z0@YAqOh2>u zjMY$KrqU4S#&VSkn=uuJeXj_^JVK!S+Mm7Wr^c>#?ImMsp8ij*ti9HIwX{*qrmd=_ zO#0Dkj29hp5(j)9%u+;08~n7wh&Go`G9O%V>B7Kk#r3EG5WmsQz)p46sJMA&3 zKFvXv>S``ZV!mHjw7?NvQCy#FU6cI0-It$kxllgL&(##yPp@buznfYso5{4sybcn5 zMp|n|ANC{lXCh<;t@VkPnLC2_Ucm;u2XsYiy+v17o|V@6F+Hoa)m!zR5%1Ua6x`M@ zL%$l>_LTG58MGGlDv7ioEv=548q0KLx?~zlv&H=YN`^6t&x`dt5OabHjjJnK40&o= z?4-q(k!P`np@cJ&O^?{T62GezwANQReCY&tK!tWNt@ZmYl!4eqOw}sy2S&73WEs<1 zI@Q9dxUT-Fs3gVkUriZ&uX+EN5We5=?EF$SJ0BjMoqw3fQk~(;(0D=hv^-%ARHF4E z>|ynBBJFQLY%xXU+ni!ByU>11OZv)}M#j;V#fDnyey-~Gxccqd2bE0D_SH%`-XE+i z@mzGEkS~`)o+mZ^woK_+(&|V?JzKckWW@j})3j zoXzV5XK+7U?_;6f{i6&Py&J1mcYD;TSLnJgb;WqpnklC+8FWPE5lS`v2aw8`m~KZL zJB-Sh(7c;@xM|C-tiN?v(!Y2ZOD^LFbMbS=bLP?@28A8Y>XbW!q0_TZvSQ`;d$18b z*?VD6o(;*5+L1Uk4B2~)+>6N}A3jChubGiQlBqfm;ukqFMx=EJ$qx%KjNKP0z5+do(4?!Qtfg{)3JLs8{4Y%2h zooU(rcPn39eAwihVjd4zXg}*!j@zB32l)NAZkP ziRbDrEVdZGwBQ#_;PWaRdBYdUZapfqgu-sdbDSHQ)mQstiP{j>=u2A^Q(@}k06C;wyThFMKjFKqz(V# zGxbmMRk-WBxP;d6N&Ehrb!;UyEb|YiFPy6J&<3L_W*_PWQ^nR@+4pfg?nM>H z442pl3<2ek;-U(fu7dQ{6#ok)^_gucE1!fmYM)>};IaPh9C zJMZpqEn3f$!dQT#U0LGtpXn{AUFEGw)fs_9v0~wWCSf8BqVjd!TFiZ5*SFHU@7YNZ z+f9we%!z1=*Lo&7`dCrkL?55-HuTwtyK&|t@&cDii4M?R6;6x+26MenI}0ol{_1au zeL1T}Y$e5(8EL^3h0`h@!R>`dH#K>5lf`!)8JB8y+RybqF0za?gtpt_F5;@KSO`O? z2(8pZzn*OzX92;&{AZ}FAlIrrTeSZSl_A;cl?iN(@TgD!m9Sh7$*JjmE)$vRQ*nls z5v~xP6Ry$}XDkU}FwymyWUg?xq6+~Pv5RI*=H&P_DfBdatco!UQO;l^E?nrRBZ zF7lBWCy6_KeTbhJo~_sGOUen$_{mv5H3=@2+Al7t6`pCG}az0Cp5=T%G9w*!+6uRXJ z=u&LCI(b~zAhCkY0Ep4(Aq-j@J^Tn}1uet1y$2*)I@orqXc4s8J;lPVh5d&ITgu*R2O+k(<(lMc^1mM~DNNwr^$MoIc^wV}t5I`uT9*LrY>dT&2#NDBtW#{dcjHO_@GC3Fd{3_;rGM!W^; zYuyJC7rU$S-Vw(@M!T$8BD^6l-d2A#9QRj?2#d)b78T6Ju@(0zDx#Fq;F6Lry2H1_ z7!w{YMyDbt`&#s3W*DYBVkK9x3lPzCd0w;((?6V2sKnuZCS%!7J&zLOSqL0vDB9~>a z^-2pvJV$sF9y3hN+Azu7(b1fMn^Ok>*INT{^kGCH)Sp?TzX6*}MEDWW6av8VafPB= zo!GZnghuHFxv9l0w#K@?Yg!l-atP~+^)b(Mt8f*zXk%!eAc2qs{;ad(lqN;-`z^5{ z$z*=Ab(>qW&00GNTXGM@KS6L%*@>q#W(J##4pu|80B02rwO$n{Rchlt^~+V!PJspM z2nh=SBAhH_4}`SLae2&?sRD`bX4H+W7sB@4p4u=)!X|=dobo0m9fabS8E%9!r`2?e$g(n)x46+hP6kEu` z_88?g{z_R1=pXYBQ)DKFV@y%KM_`%m7K^*YVojOP<3{eGr(s#70BUH~Ds7+k9L-?QlsWe_-NY`GZR!?r8qNk;zmsiGPN)!$AXG>@Tp|`n^v6(*Nw8-m z?Lf}5k#ICNrywAma)X7!{HVh8Q4S8L93URB^}JK_RL%r*NOr`(h=QtNepmoADWKO zbrfwMK~c;yTp~-cmIw=~TM4?$Rad7wDa9a}2ceDu`YuRsDF!8^wHu*fsPy~uj0M&y z=+OkvC5p}}h|@3B3^|5=Gq37Fa1uc#%~H!OuqdV|q@0;$)G1`pk0AiIV7=g6)M0+? zs7BuxDBir7Z1k}TrxswRN&G$Jl{a8|0aL6|an6yXF#mP7ZrBB1SkQ-qB^iPzugNFB zX2bFj6Mnl>fN1$8%BVi87=-YWnf-$yC8a=!0uW*Zc@9@67My^s9_vW=)FX7$cqDQZ ztrIg@h#`#?7gY)qyUNxvU}vFB$Ru}U6JC-0l_hd*HRO5aLsi&zJtLF9vmRXW88M7n zaEu#;=i|{Fx0jVbuPT99)5-S-dl|!nZ#I7xoCcO-Ae~R#uw0rEb?WL(Se~&3w+ED zYyf6)&1f&USXoT4PDBUH6hwv_ye*Mzrkrwb!!V8cd5uF+bghpUsX^CUQdT59`19Wi4zg#|~g@*$RH%UNHh7ayYf8TH~R8a$?H zpgD{|&MIkOVN#UGxD6KjC%6q3`^UA6x}?^!#an=WpFp=oT*=3BNtA{Iu!LO`nv>QI z&H2Jt=21mscL11as9@%5@uRqsR_d3EOQo@Mi(}nTxR{BH0xg-MjDo`|Bd?I zZ3^q856LOi=xy3EWDA49R}bazm5Ju^_j17k)99zzOjofP*YYTIJMojph=&uI5li)c zHj2QbdD->Qz67Uv`zpQCDrP-jX%(}c*LwxzpB>HXRm@tjXKI*Daklc^#k4qJc$GW- z2jGTQxohcLQlMNLtK6M^Vj4r5!dEdPnYxlp(;OibSK06^)3dB>?_=^#Xq$f`hlMt6 zM{U?PM{AUcwRl-j4hjD<;wN(6i%GRIQB2ZKCA((t z(@ehKYWmiVxW>FZ&O`RI>-_`Vj@i5`k8#`a+sEDjpLk%UJm&Y}rSg4#Z!AbB2k7LW z%wDrVLjWe+n}rbW#j55$Ud~1q?*RrV7dY#xu#JuWb}J{D)o%;V5hz&tAShLubDTK- z$$vi#sM;N9V<^}dv}90h1AnZNk?CDA688rw?QLvS91Ld|MK#-jac{@Y{z*npbU9X+$L>4A++gRI78 z#-hv;$5o9BF(>O;*=xcp*g{K(<7}2^XJJc*f;Tign`M03+um_uyPImr+j37x56@;* zj!8+m3MC~iU6<$_uoTNH`QA-48JPmfN*WGZ7A)pNNs@222NvQ^D7VSnt>z-HAFf_M zGWwe7OM%l_s80}0n{s1ie|xfi%TA^Gt!kdIckqGj!m8eB#YVlaR<7I%n<>s-;^~3T zkjWmg3OXV2=;WTTDecd*l+9>heWkxe0y<}Kyg+^4YInxQCs?+az&AWs6myav#61%! zeaf1JH^DQOtD0pIpXpdqd#01WLb!2)>%?c6gYj8AKC=aH@u{e6OaseDf~g80 z#FZ^47y-dnZLO(F9;;Y5Y4s{hpfG-+)jA?T9qYiZHdcEg4HChd`bOIPLItNnWljXP zq{fsFTSHUrarVF3DGJ@>T%urXm6IHwm`2R#habM2iG7&k=p7wn191J6I|I{qOfO{9 zCUw}{**hRDBkLC6DCJ)jw1-k=l&F=N77)-ir<*b;on$0k#+pCfF=Vz!PxpCcy_(p8 z(1jGXwux3}9KE3hk8ME=EG4COkhjCIIlz5KHeIx3{*G5;ZUJZ;*pbNEh!B3v@3BwG z^5)n(k4Zsox2U&3%ecX?piOly=X_VwZM}TL}%KF+99E(PW@f) zPwu8guu13J@&!Nb#oRyJo7(o{<^vL}9bkQ_>O70uspaT`HAUk(qpzl?#yqIQPwy@a3MQroh)SUo@UQ7ja)%>1%Z%$b{>aT z;)=u)5q<|al8DAD?wTfw4OxHYib+I9sTQwAYi4|`;~)4z7iQ)CCc=H06X1Moyq5m4 z&gfNO->+y9YGIchL@d<+!n6by*{$4AMkp}XUMkKWy*fEMp}2QMp@-;Biyt)dh-oqUb2s zPLRYPJ1X1Lmp#~!7~+RGw?=)ji_=46M6z;%syu6(E{r)aJ*2X47tP8e)|7{asr-J< zqXou8Vv&XH$oL@lZiwh`66|8~Ub@lskYm(N`G0kPLQv45olsp9znMs}Q%^aE(Dk1b_f2`t@Nkvo*B2b)2&v59ny}UZ14rq zW%7bD-PfO%8BJ1!6R(n_v~LbvzloWWadXEK(=iCH^``3Wf| zt1nZ81;b$Kz@+*?x-m~C`(10A2!kv=i&%TL@F|SZYN;3oTmxpDgTBpF4VwVfZu+eJ zk6lTnpPBXm5wJ)=z6SyM7QP0yjcGaP+R8?z>0*NXON;Jd*oqY-S@~|H92#{p?nb08 zzW?M-YUykQgAbOdQavL7fl1ia!nAxr58uw3(C~*39r=IRd;4g+ud}}MyxsSEr7Ovn z9lvqTjRV(U69d6=Vgo)dcEYrO0E<7;wfYDA$C&()cswjRGllD7s7y>N7pKT=!pPLq zC_`9F?xYi$W{MIFqcEY!tDz&ep;20QmfV_F0hcP^w)6RZpS|~Q|IRu0>dICevxv2P z&pE%B{rc?Z`93fE*-uc)=U9T`r>7IE=5b1kU}j1>?O;`Fua3niGfZZgb&S0W!D%tKShR;HW1#2Osj6P>q><)<)T%v8n^17!9T4mmLo|9!c%m4wd8xS?O zf+Wp!BEm=kt9jxg^0Q350#ytaLj z0J;u?-~d(4147q=W~;ppA5MT}E5Rp+sG2z+T_v59fF8dJ_{*SAMHS)Io<#NZ7&5~~ z?cjpg2gCx7ay6FW`0rV$(D*>wmT64xU7aUaL!uxSKo$YS7`(**H3COH&L_xq7}Q4{ zHbzGs2Kbop*?Vem8Upn1w*}}^Nr0+Vn4=pRs>ahQ#HhPXDkO}g?hz}Rlv_#l2c4o059LwJ-ntDepWS}SlYmg_>&*_)kpMB zR$oN_hpA~F>Pn-@*r7(eftp3xsZ=SyL(KMh_d!Q~%-;BXBONq%FC}RMb@%6%H97ex}B={Rfu+W$z?Dz3!3#g?C&W@#`ebNn5TsX6?~~e1?MJaDP|~=K>_}q zN@JnG0eM;$Qj87F`vOpa9^gPxx6dwQMM_P7ejyGg$gR`0GpRCG0-R(;L(8u04*;&w zdg0O}N7$nqeZ#VNGgj%wa@MbwlYV9RZT)I49M%x{h&(00R9l7P+!E_obE4KpR>|L0 z=~thnp=#V|HO@&bLcdxL1!&zWr)ouX5r+f!cVGh5Wd=h0glnZ2@|sm;e>x3<%0Ct5 zqX!rzNi%1F=Tur~SEZPyspml&m3DP;MMH&8Vr8_f&kHLAI`H}ON{qF>pI=$i!os6O z48l4n*m=|Tj{o&fpW5n-*NQ$xB#0ULIuEbvAu!I2hw$7>A6g#nt@WY3l$-$l-dMV3 zFbt$OZZZ#@(Q1*AX(9(h!q);K_M{JK>M43fzELktA@tl#- z#NJHzSj<6d_>~nKx`lTx#8(!WheuLY?!%)ZHDq6yWuz5U@?zy(ouiDaoRClGlUI+e z>Kub(`n7lmS}kv5;W^^FZ%48qU34w@O08-YzG6u+wY;Tg&0gNozV$y6^9w^r5J5|y zI=|BBQ(8C{eHxs$KK1g-q28y|bNX=7%gyTyk}CSt$rUj`%c9VyPOY>QyOR`w;569S zu_1e;II2QL0SUvU*|40RZopHSxkm#k^=Ebi43naTOl|B~)fBN;vudGqOB>uY#T*^d zulX*6a2C?gM1EeMO!pamGTl--HL-%3!@fh`p4X)l=6A&u_ly~*X6{5<%obtN%_D5H z;gp5>t4WhBaSaFn_=dC08JeakH<0J0_~|Fu&k89%w<7Blk!dSoV)@hxh6mbsvdway zP3-Js@LF+LaYk5ex8YZCNxdpeWgmLr9qD9T6{fNo({v-e!xF_LV%{ioO7>pyY~UcE zS0&w87K(~LE5hSbq^>e~0^maj!gy;j=?)#kzN*%gA$x2}UV?}uFReZ+x}g$gAFG7f z@#wP$&4!lnkY%gjgfLSWMJ3Fh_P{wjKnuSm%$~H)n?;%M1=-b7Wg*N~;ds_fup4~< z?pOrcKHU&Itm8&0!HjTYC5yF{B-YG7E!GCI*DZPS2564jB+P5RA7;aWR%IhAj z)B42bi3ATuh46ZM^-%BWW%Zzq12SIdS3E8hOFcXZ571Es54M8@Qt5-gY4J?Br*?@7 zFvBk2CuK6(17`|E@#}pMVqw=|o!Uu+TAa)l@`-wbt6d6hAUt+N8wL~6keR}sjxnl7 zR%Mr2RrotMG&}6>}(u(JxM;*Z)-gL-@@KF*RYQl9K9Qhf) zAiQzdl8-f0Op82XT|P>YI#5%g^mhRjQQ?l*2C5Xc8DC@rX(c?rG9R%ZSci#Clyw+3 z7((+>fF=!|O`zk8jF>T>hN&7l;>)O$oA^lc(3NWhq2-|~*NAV+LszbC>e|%MNkNXG z>t9?(J`R)*!K0Lb6q#14pO$4e>e2*(XYnFqfwYo+4UXM6jbo=sdjiM8?DMMJnY6_! zTbK@>K`cEAoxFuptqc)(W!h+~!w$<&!RyYe7Y&5Z8+0<>ZlD3dRvQpJoWRCbfPo%D zFKmVMB}AR^ry+uXMQ>zlkMO6%zhlgj=}q`EOmBjr;7_$ji~s;D3>rTHvl)jng^t8^ zyawtjnrx%4YB1kelxiD3JIU&W#s(ILaEa+(&{6}(2>f3fr4p1`qg3`dNQ9i@D$_yK ze`Rg>(tO}0iSqcT>dvL=0;jIGa4K_}4KGT1ynHWKMLw|!><+CqMwo%T#2Kv)GFq*S zFov@Y1UyRzs;0j{)799s!G?B$Rx#R&&e1reuVRqR``pVjA;5DBl(JTF;V9NxyW7x6Mm|!O#IInENBdZ$`W;1@TTAh)NGyh?k^X z)U>CsbTZ^aYap*4zY?%Fd*g+j^I%M%UfUU%XL;kDjx#XwpV*|snL2<| zreNB})LTWyTtacV%trr%wgDd5n)&2R#l>7gTC^K%^Bk?SP(x|4PH?&nyFQyB-RYpJ zzI1}HTVR=(t1T0V)Oq0q7?D6IKj(@uG7Q(V6o73M>8G zWGiIwOQveZFPC?XhD=IU8-)LMGU-pWNuny1@s_5H48kK$)z;^Y<>c%#NV*xTpmvaJ zJ_K8CePClXnJ9{3J0R%>W%-fHfedIr4QRImS>T-@r6c-H-W`K!tZ)X?vKi~TT*~^q zhA4P_vPt`-KHox82z@34wLNH31ZEhutsrb?1jjhJS}c>vy3X!Rp9WJ@i{*SlLhn*G z@b%jIs5m9Lzo%^A>NnRlJlHO#+~S&>uykq}P1wMRTjC-Nqe%?RhO$)t>I95^bD6VcgvqhuRa}5L({pfrajaAN#9~^- zcbG64)hcv=2ZhgvA`}gLDX~ zr>c9mbpEfELw$Ssd*kN_x6#o_UzGVL3!L_6yu7hz&s;>NQOKk%K7?Yna$k;~S)}Du zXiKHG&jhx#BJ_KZ0NS!_4oP3llBKP$I%lKJ&E>%?#wH&u9Xyt?whTnE17jDA1|YR8 ze9?A+Wf|PAEC(ciHTCz58QL{_d}r$Km+~`|kyjGK`k$QVvieQXM?)PEM1Hu9+8#B= zB_JV|KG9}IY)S}z+nq_D6_$XmH78G+DaZfKA!r4hRO^Ayv-`CqPwgqgAAAe~4V#;N=HFRgN}r zgr354Sjqc`doi_UbL=%rgoF{+_>d79T`%iwx~iw$rP=jreX3iy?!YOU4bd!6MPH?A zT_4*Yu8Rn3$6sHUvS67*JpqJCYfD17QfFs*xavvJX$*+30=>3eT?aH;F)i2XlW76g7=<2$c~ZzFbn?sW#A|dWO5-xYS~myo zx)WJ9H&WVa)(THseR()(Oj}wn;0!5v>XMvty-hf|(yXRvu(Z+T7TEovDxN-%Vi6;d zl+T87I>3EGH|u1a&CrG^4nN(v`#-Enr@B^8T&pZRc)X|K5xA!l@Q6^+33${OJn9=B z9n@pX9MI9gBdG|m%?>C^RYhLjRgz2PVz>{J5g$RH)f09bvWEE9tRD?W1lZ4vaI^QG z2seSA%ZqRe;8tU4p&}yOY>mE1+N0V@KUbXeQofT7K;DyNrfcHckYP;-qK@>d;@e)C z)4cl#OOf(i?KymDF7N3&pQ`ADEk>lp|6U{3{52#=^FOE?>4Da!*rekx<=D2R6x(Lk zPl|1$qhu6t$aVxz(;MGs3fK~B#k^tK}X zEW{gQrO1ZN)72ET-FORE?8NKNWq+Z(g-a7oJb4RKFj)o#;oa-A41K1^(l|qt?Dp$% zV}`e|+wUcRp}d8YZpj`M*;_d2eJtL>m5GWby@ec@WI3e5o8{$8aM!PfYYdSij*kF$FGiioXYOCzq!acB0CKiJ zAUd)Qqp^uVV3%VDsew4G8e|dK$a1<3NIqKt$>}5@neQ1MLuTXE zH?^5XV$GCYj3(9vWSOdLC}y-1Ym5$CZ0A*Wu+dg@P#irEGQ) zyzm%aN*%e(R=!r93LYR>sO;Rd4!z3CQ{^t)Z{^8qr=triy~=}qrVYuSPjK%{P}`hO z5aAj*24wdDKg4S$?OcmtWXTPLL7NJIENK7!+7pvupM_EU(^~ z`fRf^X=6c3o>=yCT#O8qH?TDr(cNT_)1zS#tbZTEUQ9#RnszoDmGjDj$r8-cf95q#|j$saQ(p9b2c4 zC&!2~U-Pu}#h059s5EB~9 zMDwq`=nSN@1-_l%POg>rqQgWFg`QEBnb%kS0C}+5obL=z^dG#yRS*uysi9Gsyhy;x+jHd>A+1fN~0fXahollce zK%b|yDfhm$Yl~&!-D}tIY)(z3Wcf?Y{%_8=kxAhMR~aC(xmP;+Gb~9B9D60b(N|_w zg?HGTz~{2|qi9-2qLs4|On`ur3{zYI_D_E$N2s^Zad@#plWlP5SLWhayVLo%YGVUP zJ<>iPDZr-@z^WymjSZao*=X>`=}y&=kI@lz<9G~BF*YpJ8|jqws~8(N&oZ)aCAP9? zD}lEs9BY^Tlm{t>=~$G{l4u(nd^)DI;8IM})IcRW85>Y^nvHZp$TN%$|I-6|=DOG# zFf;JX!uS`qPHnLwQuMK=Zb55oVf>F<8b zdarzF4eb-E5ViLesZ8xFGirBsh?R-jd(@uH67AZ_>ctHV3o8?~>+oa;F*EG$D6CS6 z(QK9|E?8e`%n}Pw%+-poz=)lahtRE^%@TBD(B%Ju>a;Ki`50sD2uO_4-f9pUTRrnqxvRhj1Fm1dk2kAGI=osCz7>Nu2#j6e?M0T()y2h^w>6Y|V^8fAylZxW`< zJfy8N5G`UeTgNRz7u9A7;|!oC<0w{p>&K*I_kxp zWrd7&-NdHrx3{m;(1>^0Y+t8GaUF#zuRfJS*W-Fafi9mhitE*C)$s7*}c8@s?-wDHH}VhWt;ZA5-a$6X`M+ zO&Y7^vjotFsMA<2>mkKb zW^`b$ryojbtQIICi7hP?rLl58S-k!*MYx4yeS!tVME;B~!%(h09 zK_Z1;rG}&&W6mw53bAa3tcxKEeg*VuH=sy>NETeF9kUxyq4C*ijord6GmU~69F@(dxtuk#x_6ja$?P|rtXEZ&scc$!55|uszDuw>U7&FNw5fqd}Ayu1A zNZ8vgLkj(=P|>bjtrV)S8Ac9PmC{OwrA;#MuOvIv#o+%}R}B2Bih*<57rzPv=cF|) zmh)U?4P0p1pQPmDZzzzCv3R)v{bzZVrY?Q7y|=1tp?oxtKiS>B)$eg~oKW zOxqJv9m<;2HXU)?CMK_0rlU#8A}P~08@1zE_Clp>xy!<+N{KinOB83UV}WMbj67L{ z9}yBoa({SI+h%m!_PW93o}9{NRK=oHHY1yhwANp%xdyvUKw)&Ogbr{ z-Say6t{|uAQet39RM3eH3$*1g$@$E^I&;D%kVLIBjoJ>k>BMlhF`2@o}L&l~| zz3s>B#TD$pp3$%E8Q42OH!`C%HV$ke8s1{&Y3|s1lFeMXYqq;!7Xfwpol47AjaXo` z@9eCzI5$OMs8K!#>`S?vl2L3sYY^EJYz;!T+8UHMgjLp{*Jq4zlubp>qMa#Y%ur0z zw2}-j#Tt|iFU3aU3s@gkauY@>j?}Wds-K;kQC#MW~&%pPFr*r81>m?cnNWI zI*X%OKnh3GpE=XZdVoLTF%>w7(O-TE`Z_glnzb8i_GdH8O*5aZOe%;WDKZt?befn; zS}QJ@trUC1N-@EAMFchHz06jYc$M8*er%)=n{f*rh;pv6qjbfn1x?WiZb={UhU9T*I zx^By$u2(!u*KHZp^~y4+>$VK)dd1jTjwhB55uHMt57WaOTe7IFC0=! zETDs{hbI@QPB>WF)9dvW0+IjeN>~17WeM;}$ZI_Vw4uZLg)et9AY&}-#!{Jje7H{r z0a9wRWT5@ZoM^R5CgwM^PT5nL|Lpni_}INn4T%UkV~)~GBvL4#qmv2K#WMY!FfIoT zl($VjN5WNvW#0$GGI`Yn6HJO~(i393#2@t)O*1^y|6x9mMt_A5HW9v;4`h}?Y|!-- zVuKRB$_H)>pVt^s8IH8MK_M=EX+mBw7)e5{VdzWX%%VK5S^`oetBh_{MqvkTq`;Xd z5gVZqLucp%lc!=(EW4((Zo&_3ky^qMfN!I zXSs^}x%_dUS=z+FQChGwqip+n!W1V{5o=swCa`Ed(M0Lw&>VP;Ed+7$r3?f zd>IFS=0N&XH5VAVM(iXEwAycfRh2K&FE#dC>HL9L!8I}3%tsh**~$V>u(HY~4)Q7w zNYt#8-S*zn>D>FuAAb5*{`glu^6blmtV9xXbe1I;_Z(xd<1zKCHW`91p5X z>h*lC+su+6T9rh)xrvgJ30Us1YyySKWCBjE{k=>by^oo!Pcm4k#9E8ETANQ=shK%y zahOlm!-fr&iJ@Qo8|vI*qg#`?H0kM&#CZkMJ3?$1dl`cpc8#HI4skp8tr(A|3X-OR zG)Vk$vqvd19xGLj{nZEo`>Wym)=*HCt)Z~6?XS-H-}r4m_v#&;U)TF=`+gGl@kuQl z=}K2gfXT(rX}q8Btp8o*-M%i}6DHZ@HE$#w&ZVr%s%e=gR1=>`m21vX=uRh$fF-Ho z4^gpCiwuLJ_M3kaI&6aC$PV$Gd{v4LT@;tk8h4V5a4OfQxLkUR*x5JaaNR-=4n7Wp zLQI0>Z~LVa zB*_3F`3+K}MJA5qdx#{-gpF!A(j%D=v&tPMS>*;R^4ya&{EN+WYLWyQ&zb}_8Fp>; z=Q$~qCIL<$YR$iH#Qdj?q?&&px4``SxCQ24o_H0lU8O#6;fy(bQ4XK)=bevd67zxw zG^!yYGsy_83)Of&H(80mI`@7MVmQ$a4W8Q#am1}t9o@3*a;T}xNDp~S%EUBNxdcv` zXjFzZ0zs-sZ!yHinOC?3vjeD&wT!FCjZyBJ8Vi4;e7P{h zW)kbO%_%rg@HMfYshz)!2IEoINVRqx%Ut$W)9N7orHTd-&&}b&;fy`qEQ*YwKI?@c zdgR=qvNUShH2Zrj9$YjtVxJwK3V&cxIcRzPVs`uIleA*O@0)h)+7{Aai`^%Iq%2N3kqI~(=t3ZGSg?0OiH%Gge zrm3QUIuKwr!d5t879`+Evj_yhaUIntB+Y>Un!qktZF#&9fdIey)520Iu6QC4U{w!w zcy{`sgaWGs;W-c>QKC>Fsdr-h7g8XAPWhcqR}6Moc#wmb)P08n*wgBha^L`lN0_&B z8$#BicfN(l7=}=LqC+6(CkmQ7vYPVlGJIOEC3zV1pn4{_K$&pBhyMUoqBox9 zfL|uO`ce%+vglZ1iCQ@!csxcXc>h!bil~hSpmy-W4h@Jb!G3^Yu2J6+>U_d2Txvod zJ$g3zonw7eOz2C!CXDc0S|8#-!wg#PUt5%WAK#sF?wXxL5eGSM8qt*kGbp(JskUu$ zVwH%%PJdGXPJdIt`St>RDJ}l`I}TFI2MNY_MZ2-3AN!>~%Mky{Z-Shkw#|au8M5 zfFl`k+j?JZiA5!ny&fHiU6kW_#G$ZZtS#$N<`gm!!sjFfk0Ippk$-&62710GJqlU+ z1ng1i#O$YUjiX8kpFF4pHG)V(rbLAbrF8k4Vi&EV60oQoJBn+4Gqs2_-(>$*I_j3T z#Qs;&sJ;k z^u*kxHQ6N5V%;=Jv`)F8q8C0#k~E4x$yLDEsb1}ScotJd-7U>6!)%XcN=#+2T#IvxfR&IP;`F#^%$99#8?Jb;*~2*gT_oH#%7 z1bwPd&NK8zJvgBr80GB3Eioek(Qb+3?Xo|XMoQ%$kMg&7ODtM(Z@DERY@o!GvzNeX zV|5~rG4f71w$P{9cDk5OkHj(IF?{;xgn7~-$yV%Bf~{v-H~NU8lwj*OTl-#h98aBK z3txk4i6bQ;O=?*kPuG&p;%V1XVi8v-cGphEB39Y8Rw0C>M+}wtv57@o!s~^P)7iCx zDiA!9Ms|8mE4M+(JH;dJVbqD2$RuCIBjyekytPw2B3R!0PRW+EAKrntgF$Nc!{#xW zC`$@<+7GLMT~>-Dke$9vI}&Go4Ulf%UY?>}PwQ)(Q-FtTxlPIoX#XOu1^j_jh=5%Mx{1p5{rbNQ`;AakV zV|5qBJWg1td<>`B+fWIv3xAN?EW_3=c5|{Sv@*JS9NTK;lE{;o{S8qn0vN2*rFDot zSYTNg?Z-eP@x*3pW9K`Rsy$*2glOc&atL?tfel$@Rb)FgyY^oiz05dINdbnZ^Zo78 ztlymNAkEpNiU3rqc9(l=zCWEtt)xR!*u`;P7%~KQtZkS5Y&E&d2sN;~Ot6cr7fZD$ zE!oe2D#w;76b$Dx%4Zy`1hKKsstul(akLU5&(>H;cG|K2Cw8(i%gy;r9sm-@q&(Ui zOP2RGAH{InS18DsQ^SOblrilqW+_LN%52Iw=7S+c(k_HFGkwKE)z2|c{W`PECC=20 zCMo^M?#|R?P<^H*gX;6bnGrj%m=Qa$@_9N(4H1gd>Pce_iMFFXi%yB>jQa)261YHA zAYdD$q@FW?U+eR9wn_$f!iQGNA(}DeB`3LmS}=PjM+oGi;|8rY5!9F58`&{$CDBAg^Os}V!bJD*m*|A<@E5#szb2y!lR_kj^%J3bnb}&7yW+6MLS7gaj zfHItWVr16t{pv|J8|ZSs~X;fYDzMG#Cl1T`jQJ9RkK63+v9XXq_E zxWAm1H|s6^ybpGJz2#z8>!YyWuMov2=6eyEsP&fRdgoN*{)%(&x6@lLw9Ec7WovX) z{)H(2b?Pl30ejB9=JA}{gP!#k-D{HdjC+wW2CFMNMGmLhKV^bdK$Q*=9y4_~OEUWP zHm2*j<0J1=?wQbn2Hgm#nl|S~St+Dyd8#a(8UcQ*!VyIr`;~M)+`0hzW{ocbb1zTd zXoXa*Q|wZx8_9PjikmX+?o!oQS>u$^2oX{-d6c%*5#*~sAD|e_zHeAz_CHexs~0>E z)2je_?tdWfJrOfx8(<)5f%D`KXoK@?Sss&hnA8%Xg8-%#WM&Lbzn zcsv5v$p4!0xUF&=o2PhRhI<0pO58QLmc(31*}GN_e`T90Hjb&#x;jJ2%G#xDH6?0I z`GyLp1RNI|AA4birnmoi2Qx0) z4^6WLKOTIr*^STQX_x)1MXz;a3{m%h3Wdve2FAYuG zhVVBnFg?%$rq;`Mut|rm8B<>j454*o^Mbkb8)s<739vIT-K&_`-2hWtCxtJ+4op|l zF`YAj>5OAC#6zyEq1aZ#KgYl{AER*GLataUK2~Jq@x-u;lysJ^N<6-~fvNJSAX{vx zPrd=int-C?rwzrXf(c#|wAL7k-ymQrOI*uP{H6k?K!{5N(-Up+|4f1wCxVi^GaX;A zqM`N*d=18ZxgN-JHq_2e&(^CjN1SD{0t9_!ZT72sM8ejZj!1Y_J}?0HC5}h{AD?1! z+9T>Z!7{j!iGEh`VE-QzA|UjA>99_a?aJq6dee`C1;4 zaB-DLq^Tnk7!z&kW=OPun-Nhw7z4t?^7s-Drc)O?ajH<$O>KW58Idfwe-5=3v8OVp zZE}}Ka0}b}MZmpBFday6adrCx39Pr(`=5Ov!Jn+=0|~5x9&HollP1b+UGLe7e6)~f zTn{Y?Hz|8HTlyToZ66Q&4F-`0=m>opq_YE3uC~Wf*0NRnNYx({G0eTQ0^a(e|7)w^ zAZ<4Kz1*7|3??U0@O zL;7))r(`=&WPlp!Y|e+9sZoC)P2sYKV@lGFC?Ca0%k9Vi=Nd#rgt9wy1*~lrW2&W^ zmSO(_=9gv8af!{nY9P@P;SyIQdW^A?+{j~(PR%=~hXc}`J3zoKs4^p}KAa#omQnmOX7dxU`Q=;ANrDO#J_ah2X zAq`O*moyaA7q5^aQ9Oat6kcoVwii8hcDTU6xCSkj@kMfZR3hlF#!islJ?iLBG`5hP zA{c`QcrAG*X04rp0(@iH=3vo3t=59WK4YUEzWY3Et>-ru*8N7*)`0z8g^OyL`AAe9 zdr}t6hd9sWa0(aQ?k=s~He58KL@9dq!Kg%{(ism)oX~xNv93(KAIKKo_c!CbFw5qo ztrLZ=&%2Ofb9$fY;~W=Ry+2x8oPI=UY1R54j^d#ZsKjDa87v&0+1}$9sdra$aOO%P z>?S?rqTK#FC;J7XHRhSKG^=uQ{^iK^`(A3d&pX$bcKE5es*@QVAHeUd#KEo%a|bLr zr~35@ii5kXX?F=~jQ8adONk&TBIj?g za+2~lSX`ye&rj>5f^iD_Lnv4nU}kn!1rVTxM0m719}?HLC`5q0tMiNcDYw{$Ty^{~ z3|N@Xyr35S3t^k7<*rl!+pcGE)K@h&0YYc*P%l}A<$#rpcIJ!r9>bC@0lvOtx&-+e zrXxFrVUpK&X>GZV(VUqP!m&7ZO5*R#v}J#1B&rWn+U!@QQ!0uuhm2VgGAovZ%u3`s zuxOuqa6^Zn-PQRW5CUwi7pU=f6<()|P!(qzXU=v{EJmnkw(F{JP`R#DK`s?>I&^IW z-ov$&e3)t^20cNns6GgQtL@9u7A$C#x2obi-xr+cJ#J3yfa#65+aa(Wg($!^7NA9K zVM?>J5vOhcfICZD`Xl5+q_bEb1Hz%GXhU&|_!6LM)a{G6bjkmU$7o}hr-(ZR6DgYO zGuId>6Tcv&*Nq0#D@q60DF@1sPpyOuJsp57v@A{lHZ&(VmSTU(9G!*W)1*g)ws&~b0^zeX>h@Z)-J*CF&C+HR z9+FK;qO)MxlcF<&wL*#Q@j+bNT+smMf6Sy{{%RI>t4Y|c>vB5n8{#4%k5Bt106jLe z`#w|W)4q|0jj$WGC~l;|ysa}d#X&E*x+Lq=0aY2Yj&L3pqU(wWALR52(XtIv#3EFr z{FWw|=UNvIh^$4O_eX@oq?FM#a$3|mu`Z&{juW`QV|n1)v`~XwL|vptas&=7_u*HA z!9cl@_P0;CV$TwuN9G^Y5h|N(glOh%_q+n|qVy=X!mBfEtq85m(T?G`g zgPc-cly!C&mXs*5*h z(8X&60qB*L1X#)vfZZs-{SF;}y%@klJ&gejqMFO%n|7m3On&BO*+*!redIw>m<9uO zh4UcAOsaJbmb6f<&J5loKE*9~ud}$qds}OpU7Z!%-xu%M%)M9rMzSyAp->^2CA(A#U9<6n#0B%9e_;c zXtkncj(#s& ztIx?@d99cY?8;FVTB1@(o3nBu2i?-VHi6$xySdyB?0!SRokpolZnH-MALy;m^M9bmh>)O1 zp1M{~#YHVZo}jM0;SL`KFTJZH8n%%QNJDN=`s&qwOHZp+GU={_IavL}z9F*W$CD!7I||^PTAPKm6#+OFQ(L$KDiu{@?;so920| z`(qn(u~;(&4+jh}r#W{;?4%}eqQ!hBI|&VaN$Zna3Zc}cp$~NLFLHC3l987*)V{PS zv0ai-`x0tckEfLl$))n5vyYd|<9

9<_n5dWyQCq;g3Jjv|KCjTw_?A+Ol+=VEn@ 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�<1Z@f>~~`F5q( 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%0D~nkZL3=ix(<)A;-}&~;-!H=yVD76v(FE}-OmPB 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�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

3#o6ASV7kHAPhh@O9o>k-lAok5*T2B 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∨Cf#aya`e{w?I6+*5&1 z&G3FJGWJ8Si&&n4@;yTR$CZ}e#F2jwZyzqmW5UGz#*|7(MeHm4ht9sDsrk)Tn%Y{h z1xgvh<70~0L$D2NoMfr93H%<_AgJH<+McbJL~PDJN|dnp+kZRzQl{bBoO}(lFFz)~ zXsFVu#-o6B0P0|$`c~u_<<7u+&y8;S0TCWd4ydb)Iv|6Bc#{lB<37NpBs+1N+RVt& zL81(>?*J7!^`)%GZ0~Y77T!|@-OeG&y@|LYD+DfP)b`9~R`0>yBFPu7NdS*ZwN!n> z0Bl3#+z)-23%)3`H(a@LI@?g@V@hM}oj^Y~b#4Uw@gRi82MhXsyy~ z)EkCe$v!a}gMDx)okmV8XF;E4*h6Pgp>$MpMNQ}>QA`y7 zL?y#bNq&1nASdGn%o^T!;>z?F%|fEO{4=#lf=?v{Wb}f^m1BUp2xAU)Rz`<5PCKksxKK>)nu4w1G|!;8Ql9eCJX(?oE=>vPbOl zNNf!pqk{v&{|JyEIkTUlF;S5t-=AI+9WlL@i{oT@eT9Bf13YlqL5jeIYH&(j@@%2y zlz4lYr+StUZ-{|nK$a%*D-oja-ajtl9~I0cP7uA)72zFCH(|)cuzqu{D9DGcCnHEP zxij99~cL z1lU;#aRUDtCVq;HB_XAUq;8hF<2v!w6(ao*xwFatCN519#sOENDc)5*jRENhr|dmw z1N^OZ=rZw|H7<`gGE-XDjC4fOF4I%vwwtM9sRx2*s$^v&l{JY#6iyrFX%+{t1qQwGm!8Hs zVyZ%}rsO2_?V0a;6Jd2gE*I_`JTb}r<>u(3{q=@Ti{rpF`Z_sfu-G-zQZ+z29UQvJ z4d3aLG1+g4N8$81`l8zhOD&B9(@kzsh`Ln1?zp!U2eK4Y_DNz$*!d18mDu#-)6o%} zZTJFIW^Jhh?nrcXx;BU}UJq8i=Ndd_8C^?6`Wpzq?WvgE2LW z*67LdG$Je&j_+EzRJai6ToH1DqbbtR8IgvUe3EV=JFXDxOhOv@`@^Kj8&cV65^5xj=5YYQE7t&egrP`aiAxEjURE7n%TL!z!Hbf3aI-^azQLH zdbxVG5mY5m=Zt@+(y&UXNp^}!|aCrL&6dy?Gs_l zhxi1fa8$p~BQ?l(4)b>SLs(032_VtJ5P~UU8ksFR_HO;%=qf=OE)oiHem;;yK!nKP z#-n5FZE&P|s?MHiw}cUW_SPpj?sP;ec-6ngdMr%%=$x8uBosoRC5f2pMKM9*-QFhi z%ke@kfW@io>TEiZ?34#bBvv9B0%@d4wiOO7X7Vi7kHk-5Sj}jhOek_^0Z??4P;gXy zm?-OYFu*<3R!|-Gr;NYFO^C<*Wb*Ts#YOLr_!79rQHFY-!ZMH+GJgAx4YUO(RZYL& zoA*CUl-p9o917(2C1Jj}FCBvDzXimfYX(vBhT@CC;w2NE3;z`Kn5 zx!a+$FZ<@}+v>()U?2sqIP9ezJqyEii{~KBftcCbawN!Jsb|o`00W}zDJU{HM7O*@ z^s6zELb@`yUNTnXD~^T7)Q`3P`Un+m)u1vavXIOox(27AMPw*mOV{*W;mt)QSSa4dvk-f;qe1N1J34Z-p25i;9k| z0nhjhHNps17Hv04EdvUscVuSFbzr6k0>W3 zIja>zT|suk8s$Y^tBav%+T)6t%s*hy`~yS@!0IVJm*7i`29v-^5_4+zcavToy~Q(P z4-Y!{PZ7*xQ#lQiriyc|@O$cATVAJ<7?*wKY;`VJV*s-EzFXlD&Fv`6qWtHza;H*2 zC?TsG6)cEZQUKW1oSN;AqC`>6_N91})zLZnfA9a`qE5)yh3^d>n56C@LfkDaG;Zqs zZ&^O@J0%$ny0;}ISGaRO6x>0G|73w{XP|r(Wg8 zDgkdx73K=NhZg(7V$ ze~e7yPl}WSM324W1YdLC;ZcdCn0om=OKNz!IK<@PLz7QDpJdchq9I7+!c8R+nuHPk zAb%})utGA+ACo*H$*XLh>s@-m?@$PoNy(YiP&-35L!{nQ%`G>vv zg85--b^V|-sYR9U;q0SAO_f< zusP4Q=CoVwoOKb{DJdurL^(uqFZU;r#UiLmk-qVV@p9p&ieTLBI@7RzkaB(;qp+M` zq$k}qbQDn(z;_Uq;hU#l)izLZNx)KvN7<2V9*7{&O-r?@vIk$U#|LU!Kn-7O>kr(~mz<#{*mLSo4`emM4&C^OuYavVxG$l2ywUCG#?V|-`il9JgJ$ftU!_yeR;Jtst>!sU+;FF7=5mPu$3fvueF?ELM7)yQ3S zdh$7Gc~ph~=;p4$V++c)6QW3P*RlFXw~jI(Pf3mKJE1L_GS2 z>u=i^kgpWO$1^x>Q3H7SgH6ONW21vapzeWrHuUGW=uemaI3v@i39FOJG$8vPnjb5RU#9VebQ~Q zlbEK9UvPN^zoU1$aJc7=tnn_wO{lBfmCH*W86us!af?L`!{@hg-KX-1iW~tam0g** zI7Nm@SAuz<+nwP+Byj$D;bjz$jViLhn1!MXlB(a5jx0&8+lnE+Hn3C-@|A6|c|J3` zhP)Vnqi?)`Tvzt!iB+MustHJ6?u7aB4{|bQl0@6DZq4F^!evxWGwk{|<)*9vOS-{^ zFn&Z$o8YD-ht$aiPAYb0a$b_MfwqujT zjaeRzq;QSBEb}xPB2+`{=&C3Ok$&K_>d)s{OV%JSoDq4kTH=TILgXxJR177X2F%7p`?5=KgSn-gADQ2D7WNoU~W^HzvNkL9ZfmOReBiH-#d8ZMKlG7t<`+f(o2q zjDcY0!NqS7a67Rt7js#l7Va#UINaz%dNq2QEP9&w+dG=BusZ7p%x;iY&@rJkcj?H! z#>bP}{wsH-ujd;bRY?I@J|JWJX;aDnQb~=q4P*%WxD6n0gf83@t6XO?t{^kAKU*7j#y?p!rmv`Sc1j|ERf*#{qg>_Sn z_W5i!DdT^3O9`z^`Z4TEZ%YGW@rwHA7~R@`jib6Xe>tTTK2*H6wRhr)@@0@DGOF6F6-BJ!YgUirnU<; zW~hPuO4bI5i*zr;pl0gF;`S+PsQMb`AJFZ-xibF%cPp(?=B!ss%8&(R&Ml4F-bO6Q zi&x9_d7|YQAo-+L9S@3{R$WqhFf)e2p+vndR9*&Mvy6_$KG}@}_$8aGgMAjz%OS8E zi6fyGm77_&`&NH&FZfO}ZG>;{`G8dSlArb4b2=sJ@b=2a+_!Buog@238Q3<%7BsGj@yQp`7yrC*R6%I+#R@aTYk{rb} zezC4UT};KaJS@djqkV{yU@%Gg(-rrwe_GhMCM_k=Lz8xy6{^ATem?1JLjrOiv`y8J zyZ7p*>Zxa1gzP3z7YZ`$QN;-1LNjPm3@m~%>Y$5G&$0O`#1&QeB5X;!$m=3)sZW9N zBs#2xH24!Ee1Xf8R`os%T;z4FX5@R3b63+#YN4=x3bIM1O4yIvv^@+^RbP(c8uw|m z;#j0&R7e(b7+HJ-=foD2GydqQ%j;d)Eg=~qE`GZjz0;3&lmor$nZ!G(($&o@ct)S& zX=FY^19d!(tw^K`+;B#GdX0uL=p}Lk6k5qwr^6B4QC=o8UaIK(`rd7uDpeQD1PFMd zmJ-=?+tdeHJQcl(4x0-8^9Ack>b8vTJo$j_*5a5hSUsV79#Ded5>pl#Pj8?bdq@e} zmjc|d*mG;|m90zRY<}{s9WOjlyLU%ISlhaYj{;M8Uv`dlK^TbQBFFZq) z+E`UhNBT2h>85CBb)4m|HLefOn78%imlOIE2ryfXgzHr{9ep$1`IF5?N;y*Gr8V58 z=p{E;OE|(Bu2P8n1|#J7_9h&EN6=}5fr6#fGve#}4-i&-=^__bCj6X}7Td~xM=&+$ zsNn@z+uh>h*g|_%>Vyn6at?84t%%zxH*9*N(y`o^rZ51DV2$-``7vlsLmgi z<_@}+lV;JHTc5Ss8g?^l)$;GAYdN;n0NFs14vQulqMk$nMquo(Qjrhp_2_Fl68y9d z?EIPZWBWH{Wp?2@FZ?WC>wzn;9+H4_@;(;u zXpZ(cW+Mq@AtmK1*0V$sdb3eXOAUV`?$d^Cid0Ze@o8t4su(yBX8&A5 z1c+-UFFir8kp*au`ucH#A+$B(zBoVWXVVAvC%A7dV%>YRk@KZ`@tbsZV=qHtlCtWR zZq*VLg-y!^8hVHpe=VLRd!8ZWVs+kgzZI{p6i0$ftK>aU_BL`yG~_*1ep5j}%Hc(J zQvzFx3UO~z^hNtBUbBrU8dGj$?{6@2h#$hQZ!-B7w?YjJ!kNTxf|{3Oa2G?wnpbuJ z^EIP}tBk>W&FjSk_0PXHQ2j&x{PpR97-VcwtLb<^O}TE@edrDQ%f9&KPd_Dd&36HD zvSM{gJ92)@ zaYpjw2xx37rXXqcVy0?s^;$vm+Unhu2yVoJ8^=j!R+Xb+v|{?3#Y;)Y_uB<1PYt_4l6NcApxif$pJvPNFRzx@FP;Q_XI^5~ zbFSB_4#U2JQ=gX%ew6eSKa*oB>aQ56SXE{=wXmQe4$)5AnkH|z8S8!59B_cT}I#W$e7yp0)xU?>f-%G<}cADT0bymm2ke`Px6%p z>ssPvUiVmBLF=9y;YPl#Yor;h>l#=u7DH3lE=`49*GN07Yhb-doDLC{lVnNaO!2m_ zdnH{a?;y)6LR4%KIYA^=vq>w!mX^p_-zTo7T1=;|CDtpgL|NA+1hxb$t)`@T8GKA? zmnHcD&Sw;X{VWBLV%=l75{p=w56r{K>}KXOlxSdR1emVTaEwN2K6H^)u|dP$B#urs zJT(o)2qfLrG*PNu-$cTp6DCBCrFE_9wl!E@O*iSHGKMP(bIFL)yFe9YedQEp za8uJyA?21V&*nHQ9`af}I(+OjT9f{@2AKSye~XmZMI=?UH3zQcEVeQ_eeuK)RW1`n zkzl@jmld8VW%Lc%{B;fUj_r5~;Zeir)Eiib<44N zD7P(cE}uFQ7x@7+p1SE+1Cj%GyP6tSp3r78{xG#hMp$G0WNqfj)dU8?u@?E!!d88+ z5UgsV*iljdiA?`S;yqqGNxo3_*rA4Lt6XBP5KWb3Sj(uZ3D!&d`ick-UcAt!M2zdT zZmZv7w}Rf*XH9R;#-i=a)J37E9OL_U@hhKdT>Ms4PkMM!@`cqtGlpwcGHEiQrZ3kd`m>Wu1=9G!fJ^9WY0`m9holPQj zF1R~5gxj?a*LJWCa=wb!Pa4?z{g?4lQgE&oLS!8yT_DOlBAIHGUh7-r5Yqn3ui45g z9@bqD^b3ickCR2T>-aUnODW!af5_sTD&Lfi>GekvFBhF}<%{GnZ23k;@c5M7VN741 zIF_UM$f*}Ao`&moXSP5r>+TduCPI=Wu1QFRXnr-GUp2x0k}KX9+5QN5^`y4kN>)@v zK5_s0nMyG~YkW7$u4n61?0$>qy8}?MyA+q<7cS91!V?rQp#%|?_j6oDFmv}%sxCX4 zQGO`PD)lNs&J}a?4sh==Z_%Vb{M4V4FXP;2J_|;Wi|oyG2)pL`DvgtCF~z;CzC|`y zGrKP&Bj$aPWOb1oxAWCY;iELA5FN(HJcIEQ_>H5|d`1#tZj>{w`gnF_#k5 zJxI+5x$o|arY2ixxjgraIJCHrQZ0}}BW3MJ?kCNiWFxz(QtpB0b>mh=)>Pd9KOG@F zv`G(AxfcNJX;AE;q|vi87=3DhLtPzvI@2s=6%WOfo%*lJS}WRluvI*kZc;O9O*f*i zkCEm&r`yr=>)0#*{`CKOQR%9yevp;(s2;6uAKmQ{195gdi@X6q(crDu`q!WGkVDvp zt}{owf0-`&qeLkn)$SDU#&fWIyif(Tn?pVU-@utgUW$e__fEs+s=N_LxQ6X#qmkl_ z;I)yybrVvJ2p$@Nrl{SE4ac!6o#VxR!}fIw1hi3JFOZ)7KvV~(l<@X=0u)LWxBSk5QXV6}S362-TACA#KD6Z9f|8!+U#BEu%NPJvCmDMh@L)d0+s z=MoJL>*jh7N+xx?@8{R=a2ub0N))<{8Wnk`EsgzmQoc4E-%;f)4eU>(vcYv8O-|6x zxdci`mol^tJJspjqy}x*Ao{CC7uC^rZ91t8s9V=b;H|}>OtWOfV;MK?Eb6~i>@1J{ zMPKsN4qA3Imq*!tt$SWXb!B&BqqXVM+36~~LE~Nd%wZYkjf5osmCc%U!S!~N9^5Is zNf&ln8bH<3#>krO(3?rSQ7DHsJ<}59q9Ruie)AOVU92nB-YF%BzNb7vamC*ym~2m5iHg{t&wB1%+}s4n0ukIPf>>QX83-O_+;s(`dF0`*U1>bZkf5i#-=9 zfLo;|HdK3qDOOQu%-*E-z4}YUb>aTxt5p<-Z#XO2#CEH46r}P+^|66K)HDbXC_1+B zmc#3*lP40>=XvB2+d$nzI~<@>stHU39>u08Okiyj&s5bma$pe4iWhq-M$DUY)-Y#&_dXSW=6TKwMHiA~eSy@y9FibDN!Lt+a7lGd3*f11T7*=*ZG;SldeRwo)^0aVNA_D^ zh=HNK!BFzXave(=YCLS)^dm0D4)HO`cH(3JMpw6Nk6xTCQh?~^(fXg z^0rfS>2=LQtH1W?LlfLs3Yx`a=G;08Pnj+{d&v%Jyl~<1SQ5QOpGddy2hQZnvgvG8uq$olHKkyHFr&;*^^#8U-h z4P0CjoM7)G-3ZE|{^%V4^{J#st?jOQPP(Kub8>BpXdBMSHSu?Bd@@<1EEuK)B-hA- zf4E|R1yTahW};lffm-uZ@S_y{ai8@T)uwpEK$YcYN)NAn5$6{BUvS%Z zt}FIkNe_ch;IBWym1)<`9a=y8CEF9e>DugD>JqIj)z8HqNUAFd5U_7@%>4`E9j&e9 zP#di)q%)VtlI=wdmike-kyPZXYOQE%U8k`1oSt0myRIMEW`be7qdMVME-H|9E8B?A ziY;6bMLX2{#+I$VAn%j;<#*sejtb={0XjFufNarl&mQeHO`tYf~Kutq65^?Wz|UHhOBsO8GD9jkr(N$T>~c zv~s6ueZzEass3FHwVX-HyomcLVDfi2fELNowe(rj)H9_J_fz?jHckV3Dw`GiPD6Mq z-$+*#LcBkp_bGbxQvST3eN0$iwA}>WODeo9mUXTENkwZif%C6xm2%60JpGE)F0;#E zoXE2X!x(9`pd{!7B&I^yb6?Y0m}$1-Ow~-tr^L=tK&!W$C-}bBwRH5aH~du9*Jb|; z?hn7OlEt#J2?z*EJdRr56&s;;+j^Ryi89n2ft0BXbtn>v6tJsoK;GZ^1wwak1evRtxRBo2fM5&mTuF^u z*-%GYBG6QIBro?A4sw-Mw7NuYSldYFq3E`*CxK~Q8y-q1Qsr!Tw^!SOgTO?_msLG1 z2r`~f)~%+Aun2Ol(RLO#1T=Yr1o*XwXsuWw~i|^JtIzAPBi3U1}fAvf>p9TsBL8%uNTCAU2l%K z*S7J8Lbsu6?xgRnT$fHpme27MqJtlO1xa!=WPL+Br&ZlJOsINnbhhfLkQqg!ss>kF zt*|Hcjf4_LoS%7HZD?a|AQ{ zC{Q)!rs*&(W5hR4<*AAz<%bFqds~QvrbKZ{R1HDa@;`cV5j=Fql;!@Y#wLsOa5?M1 zUSS9+8%sF8jqjD2E}Mx>L|0BYWN*|b$+S(~KT+{dM+tHteTxh7a!&lN6{RXk-D}&Y zEN)$=p+c>$ok+xMM^v5LM;BjLjt~fpiZP$y=nEB|Bj3@z1^cGoz26vWyMU<$5XiR^US=SQnId_j6HMhzU^!!=*2|`#Je@EQw&0 z_Di0*i3smV=7?WWBz$uTy>v9=?w2qhf4Er60eGPEmr$AqI&~t+MP2bgXTK5d6Tbl1+NM{WG3Ts68)wm*h2@_aqs$W1;WMv|F&w z_hibFhT`FH4;hMBX_4LsQZjmm-|_v<;nwBP$7* z!c}kck|i;Xb}77O_QFct&g(fP0W!4&VlP38AJDzLlRvMC_^IzWtClspYVmTq7%Md# zU-59(yG*bb+%|2q6zWL>RP1+Zmfs(!?QSQ;LVNE?N2N?@yY-<8gVc&f_xRyDm?9f%dc zw;In9BM6c~-_7Xbr@KXf!YOgHQfBZrwc!sCMzHUmn(u~e$H?wOf>Wqx*oodCj=Or& zcC#ae0aJIbZ3|0C6`I4!t?b=s z{DnxVp(L}U!1ad<@s|^KxZ5~>1qSyPM^5e6JKjihQNImXru!(hh5A$n7)ZSX$)Aa{ z=zK@E*aFol2%0;FtvM{-25hrXt{pGw3V*DW;hZF&k{#Kr3;QOiC+}ih4Z9Yrj$iYw zP#xzDI8O#Es=DE6cN-`qs}vUbRt783RaG3A?&~&|nqJQdHRnw4~k%&XJ=6RkHr;bbRak5C=RtdKSS8omsD-dgBCs z(P(XTA2aPlVWAsLQZ!h%H^Ee4nq@gqh3kltLKaE%dipb*hUQrKd9@^9A1k9;vnX8&6XT5qzOZehJS>IL>k4n__tw0A- zsnoZTrHCEBdS03V085Jy$I8QD2w2m=BNUN8JxwcK-B*BrH61SJoOD1?)5LNYR1btQ z-A_xnf(!nc)b*z+(+OSz6!<@r=f7rbJs6swZf(;A#e^&!`>>`%J-U5J&yu)^x`sM3 z`(D$RKef-l&ZsA~mkAl1UO)XG&imb4Mb0?4WWb5jI^UDJlv^->#<1SFV;EEN<7{Pm zT(rdZ-Mq8(%DM5hgqR1Ngt>d7;4lApJsni;No=0CFhuG4eg1VmD%au&#^kz|EO8XJ zmbBNbBDjd}8Kh`Z?!djXR9Bje;n0%^=4WcjpMo~8_ZfBfd=~0jurSvSTP+fZD z15T7JFFlRK>XzC_P;tgXPw$CrcqLJUX~KjiO(i~~NxK#k zX*dbjtabvfjqXe@)$56i0??K}XIedwSa()!t%&nCSXQ)(Y)D1R+EJkc4Mt5{tsS*_ z%kk6(PQl@VmqU$ge^9k+88Zx|02t#w=y;T8fD*)dG#hXevp+B#Y0> z=}?RKN|=)3r;COn^+K+=cNi`vc^L{1jl-yXH<*N_dZ@1ARw(-9RwQ9~zDmcY1-892 zOJw@87dCkxfb+(u+N)YqO>ZGEw$WcUyVk(7*=z2MSL~WE)OWu6AoWCv;ms=GMZgj+ z|4cCA!rqk)>zS~`y|XTa)#DF)MFe~ zaK&T#Dw+x;>beR8E9=^Y5q}j!+4K=%Y6nzSH^{A4(OEFBo(h?Dlk+3j>C`=V&3;-t z#efy4nB65Q7(`8A;!EAsa{NI>Z;|VvqGcLSS@k>%la&y5$5&J|7SyQ9?uX(LnvI^W zC((7LuXCbH%o9P(jNPsmb?%P?SY2EZ2%(AT)JD2qdHB#4ce@T3^?-Ih3%BKr(PT0; z1i;_T{__1<%QV)!P@(>!qp#6;vx;^fyt(h{N{zvzGgjBxqs1oyTeuf*?3mtH*v`uFL582Z=z2l32pj`5h*_^vDrFGh2v$R|M;kW z5se0IHc-|2g7Rh|7z+>!VUWp6)G!vg?UR#LY_{2BW!LdSed+V2 zB#M3PY=|4}q^PdtzYr{IIxO!}_;Locoh^7LLu4CQciwio(u4ioqfcavHQQZJ3A7MX zP>pHBbN&uNVkf*zH5mV2tTYKM}u+O z@bJ3_GkLj^%c~`RDU#_<(vN@fAJx9BIz0ERpe}U33K4T3ozBdC!-nD?xPmzDfe|1Q zjJoex6%Y3Vtn1}?&?DJr{)fe9ahkA+x&*%N8;Sk=gLK+GNz~hRnlRga73$slG@IbbFTMaaN4E~gabv4T79twdKlTDj z*u{#JTqODwOTG2sftA_C{1ex^sL1l;O=c*Ns_rhXz?tiID38ydD<%Dy+i_66g zlER6V&E<#l+M6^P+;&DF0XjRgKv%b;0ftHA0fZyhTRhCU{8LF`tXO931N^ zXDdg5e$oqa$RVv~k-sc5k5vBJ;d5)X+>B*I{P ziFeSj=RNyMn8T|Xmduf$c<@vhxUw$SYjpoSRi zVOA7^N8<^CGJw(&q5FW*9cl~)3aSzepMRB!r^=YR7X;~yBJ{L?Pk+KbL{6{p=+n9dSUtz{a)VJX%@=54>w#EYuVHJvxO_)2Pd|XY5lQ*@Gr&6Lmo4Sy{ zythLm{IN#Om9-TEHp8kd4HnqS*PyWtSWz@}t%M+K*!G=?tM;r72=DWX)aB2eCriFf zg%(vJ84r>})WQQR#vG%FHBW4lmG-`ze<0EAbopy1JA`zy!w6>cGh5tzq~Ds<{8JZ=Slh@lPFGKpH+{hcrUc zx{FZtV9-`30S?ycGW;}~N@<2)3@*aMTPx#DY<2i`DkJV1893H93;HTKr?{8p_g8FL z%)dfQP6X}jvXR!Pi0yaT?VLl6f1p=MWyhg=hPK>Z*KzGj>Vgw3N%y~23GO5aTx4a= zZbKx<@i<%DsK1(!EHbFu=lGdiyKk?T^dzF1$vh5xF;%t)Rqp-o5;son#at5`A_v0l zcVApVZU*s5+8(}fih94gY9Ps}?8$!M?72FHUaVVkhR%7kQ;3}{;T40bY<7CiDWozM zX5m}=;97mgHe;u`wwd5kgJx7(_}HLXeEM*r13Vbq#IiOd_{WQGF~(r!o*~RC4KvN9 z{+P1~xn@ql*QUi9z1V8B)`~uiCC}E}NzPMgU8B$~r>3v`jkT`R)XSu%M*&j4pWa-O z8~gO*-L6}PG%S`J_VtF(me&*T#p@2%G|Toy$rW257YD>a6gEE*EhK$qjlw#GFq&Gb z@YnbKbKlB&Ro6C~%{dusxvcx(8uC5aQ^VCaq390n(?g%Xhul-@1c^b=--i`xiu^wn1rqMyeS>58W zvQ|B^fh8oZ;`RNP@$wZk&>)^a*-&n7)Wy&9-^S7auMctPsBM$^I*QEa1WHHwRQS=i zbI)=#s-jIn4>kk-wr7QO|o2#;}E)?a>boss1to}Qf zN_bkd4cfT<(FAt;HH>+@o!w6F=hv?Z$I@nJ$zT!f(r}r2zDNu7`ARs}*wCS?ko2m^ z^V@iN@zZKjc)^j@_HX2jV$A-X1zHxmPw^uO%6eyz(#Kl#M77;)&`WBL+H>JUzt#q^ z)ADvcBm0JT(ulPkr-fhU3OO1f( zcJ&YFE^$nzDwBiZr9p&+DMxN4`lN36r`g;7wFsBdLlT74oF^aT07+Ps3q<7YxAHaZ zAQT0Q8*KV!3KwhH$AA_VALJN3ZJfR2OflMb@x2JOC^m^25lFzO#bpeFF=ZD>m8DhLf=Snr@!o&~f%~|BZ!wr% ziQe%{{(jeA_Q8~LHSS0&yNv%~fHg!G8^T)xvH#l;K-DSk^H=_hxJBcf*3T}gs0!Qj z0kIv6z5qNL^P8gG%PQAoLlqLHzDIebdW~IV#lSvjYtGVddOc;^X*=+7Xz7{Ua^@O%R*4B*?>kS}Y~6m}M8joe~!vbtLlbRKaiWIIX;UqEdKo zb$pmP=C~*7;2C>h1<1#Xeb-RbmS0)lmiS2>CY+4x{#dya?7G(OpW|w8HTApl{r#?E zAl3$e=^O(iTe*I8MDc?9X=c;4+5GkCzTj^#ko`jbtu~gS zyDjhe_g}%9b`!o!PwWk*d$)DPWWs8z$5nFR?NMqkNNtoq;Y8R4B&P&U{ihK=`V6j-3`Rr_9cjdHTX4LCeisC`5Bz zLRgx0FuwY9+{2DS2ihU2)K*fQC)Znig5K44)A==dpXnXC>G>H!Gz-()6Zi#>o$+v; z6|UslA^yRr>g>ja#4wC{dp32NCHcVJdF+Bg7}Ca)-&2XPts>_cY^&*<0Ke1=r36ZS zS(Sz64ly_9eEeTwm6pBXtcbk|eI>$5!9DzPBfmSlnz-bft-B64Hucx@qiAk2tP0Ed zY|;~NH%u<}4YSv0;}^VNoqxyhqAqwag(P0S7s=pb97x5Z{%J2n7_6$1(mzo|H5;6F z6mxD$Vz9A2Bo8BmMxuP>uO@8`P*kmBDb}uEn_P&JXfo*!umy;#PPcF_{WQ=CyZrAtaQe64F`%yh{QX&E7Y+P>uXlMF@QJZ-z1fiv8_gT+zHEq$PC z*~z{df;{*weR#_#?`GWbvh6|LCL}Vylr|(k?+2Q3ERCpc;2ydiq`Z|ils7XZxv8t# zUGC-fuF!){OM1Ial)Rl~6lEXf5ml@}7h=N68w3GySn$UYXWC(yDLN-R7Fw@2iGG}+x}{Cs$FL) zbcR^c!qHbLLFnJKX$sjwmR!3Q;)3MOgHdTE&zUS#VWz6@1F^OE-=iz#Dv z;ZSB8^7vl+(A?J=qU$JDAc~sq!QR!Ma~{E7&UH_Ink_Z-02&~550)3ye-MhKfE35w z(CgHwTKcHQJy>NXaStvXvdkrzeq?|%&3~;?w3@6lYv4StgUMtgPR3->n+x_WF2;mr zJNa8SOnz+_#5-FpZTyI5W2GPTx2w@_I)QA$krj#h;e3YY?&r+OF5hLg65{+WnlboL91*AX(uv+)-P#HR$;blN5b*C$FME~LvR$`Y5HY3I{jYUxdYsG zkBUEMu;-JoD3OSDN#g4gNqRQKDcWN|bs_6d#5tKTT}$?n!mY`8S~aNA$@XLUX$g1K zYN)EEh5ck(?T2#}hSHaBW6YriTx!Z<35v+Ze8;Xia|6Hc2yWl5Mlud2nH0WdxTHlT z@+62^dCY3mjXEV)(X;lQsRr2KX7#Aj70_2XT|=`erV*DnTdKeXyD=GnGPrI&t1Q5C z3$qd;zl}+WaoI>zh3kMl3}Xz%=71sG3vKzj7J7mCdswwHFNggriRRUPg$dhnn!&Wl zAdg5VwM>Zke9ea+vy?U!p?RUArx-1r4|Q};YX{#f9x&E(K|(fYL?+90JYOlix|L$H z)^UYorckSdobh`5!kt&y^*aA@8&vG12!WDOG{}jQ*EE{FN@M0d4;@><9W9vq(4cx3 z3-+hYSh_zZrQ`e1LKTyyDJT09NP!S zh!%DyzrH#XvgYFTgE*a@QSm~TKHjkSGk8EB5=b4JUe#N-JHd>q7s#Ir!?(-M-2w|% z6y6{u0`L6BR1i0kCQ>szE0+9ZZaK2#-<~{Xw);Vo$>$?PLhgAObWUJjbnjN3W5!MMT8 zc@2QWK~s*18_Q=-{yev~BFqbyckyvtF&5tNnOjb14VONlsGvQCx*!o{|r&s6CGe08qw_-wP^yjfwp zJ*NhSZFYM_U5jN8Z_D0fyjVUTO}|#JmMCzgX)@P9eLGc!iDZ^A#TyT68$v7~l89p$ zBZRJBZc~HXvEY9e5Co$uPNQ7u(dFqtv(+}6i~3Gg&ZNo_>E<&r8krMklqUL~^OBH3 zM!ZCILp{NBT%UiZ8C?9!LM>z1q^*?g1hwO{@-cahTJ`-9ot@Ncotf?B30aLoHMa+ z)mMf#di8SL7RVmOxB`PB3Up>r!G@+wqSrO^ihm^i{y| zUX+k=D z+kks;n$=2u)_oyO_jsuRgJs7?uIXqojT9S#SER8~qx9*v$@;yAoq?^Iu9wX9b?{3u zR+jB6ef)`FE5PifEP_F5I{@~+XP%6N0M4;s@j+7_+tHk7;$h)f8A)L7eDS;$!aJ^5 zXKTi4L;VaG_eeyn)S#!R++=xVF^=qfV+kg{si~f8=UZABsmY3W!0T_1RPI*_{#)49 zZJp=55E(mZg>5MgoSjeNh*bOljQ|ko)}rq*OP0;A8){-NqlyW ztGInWZ3h?^0YsB6@f?!ff%oXPspcPVhH}Nr{-(zDjItMdE?y&#co(?m{ps+oh0Jn$ zD0O4@bSH#tqgid;LbAQvvqoyV87&Jrj_(o$o87B{F7#EXw=1~_@s2k|mv!3Jn|o7I zw$ToUVo~+f9)-25$-i}WhH}MAZqw^CKs?UCBgNYwrDb>??h)fwttPk`v5O1Vj^1se zAJ{G0#iyGgdVA)4OEho$6T2z$-G+kVX1KSG>TQC4J0^SE-{wdBlY}}cBISKA>O)pu zyhvYba_(#OB&iy!6|0xNl~JG~Qg2sYjSSdi>3O+uODGre$y=G%O)1{?WQ!Wj+|5v~ zh#i|TdJft8^`sXSJQ+2B-5=(m zPD^w%?xDit_C}=qt4vPZrf`$z<1-)X-C_AQXTR!P`bJn@#jxB^ZYj|7w6{=+Sk3j`jFP8=Wq@h3n_ETkkO$n#yl#r&;eNM)O28*K zV98secs`Mm;YeX})OI69nAVh7kTID|=~h?bOuqz`B_z2|BAOH2mQ{g5mLYPdl2yHT zHR)3yGTMERqwQ^fc|l6nicH3mv?xovT$rRFT$*91{UqvM$Ch1)r~COzYsGyvyq>y3 zV}%iYp33JHO>q5;zx&No$zBtG7No`TCg$c7(ITJav_)s*eVQ-46R{Y?7T`zM+>!uKjOG|6?5R`QzL4r6e|^_yGL{*~!b(k2fA@ zA?n;LSZcg&&CDy`p$Ni!oGhMy6|yE}fli)sM*XE$Ouj6SeV~%}P2nfI$}%cbYF2%p zxdAP$+wZFx*HSN84Ek66m1hfg5R6}3%vKbiCKLE_ zcVQyL&3mc6%UaB)x}3u>EV_`EdnoLfuN4u^csZW3+*~)L_qWq3tZ}2-4b>fIY-lV` zYsf5(#@+6({U6A-_~!Cz!koYj&ba2xt;oyoXv|YZaGfp%Xz|inv&H{?n;=r zX@ByQZL<)c5nmz{CO%0xNWjmEyz@9oyNJZ#pTva*F9S%7p+#M7OlK=zXB1V?oY9G2{kufBthaJMTMQKA5e0 zYU&}1KB}6?Ux3kv`KjbMxJAX}_ zZl>;y3J~SaS}=3LyUKYk`yW%GsOdXikaqKE`r0}O*UnQa-+A0_0asMf#TsXld~cF`N+_A?p_S8YmyfCPDb>25=nI*g z>b4=JVuHDUhD-FJ?oWYARAbl9G&6V4^JUmuy?oE1HWl&yz~Bm0G!3xc1Mcs?t^srZ z)A$2cFzA$~=-C$o^e|C+(kHRNtu6!C72TnJQ9`Pn;Ir zoQqSBGR!I_4CnnZkoZpiJikc~Hb3#$lfk6N+0}op`txDyUQ_ArUH`L4F*UOaygX8& zr>1#U-`fGG$xG&76cCB#FJX=H$GFK$A>D4$UaM}mSV`X8-(-Ypy!o|$W2z*`ud}n* zpI+mYGrfNLKb*^uzlG1R4{;(ZP`SVi2FLv7eMgtO)e$O$&zny@z|Z)EL#Mzf$jd+C z>{PuEEnszrLzf8t^RK<_xj!AF^}3QjTx=t3;&0{i8$RalgECye&+?CJfn}_Nd63ON z%h|;W|M>_0{x-*d!f2(k7doep@Pys&-)6IqV#kM=X1A|4+PtIciHK9cHs-OmpNyvJ zS{fAMlqR&5KWED!?q>ox@6aJ;e_Pd!dlE;NEp;VFan<(9mK{)lPVLN6ba>s}v@ zL-#-_QFP0^g{HZiRC?B9^72$&v^+DHx8tS${5Qw4`>;6Ziu$4b!ImX^w#6mYlD%rQ zgt)2qFMJPXOMmv8BWcZDQ#)w65_g+1ZOVw~?)5@o75kp0JA> zbm8Yd+4$XgatUGG;B}K1+pk)N>xqA?+@~9i>!r!|Bj;K2_U{L1h7*2Oh)eC33(w-D znKo#quT^)99l8B#yxmT$oONBd?|E=Bo8h&N?>dI?-p5Z{?p}%0c4w^SM7;B-j{V=# zr3*PEKCX8GmDn;21R=Hy0tr*vdY5tw^hR6n_G@|iRyM7KeV z9n7FLTI^sBn~<;__*K2I>tX|Oa0=uKA>9F~8YO@HFU`U~0Xip9lyyDV(xu~f~x?#$J5>laDw zp~%}7JV=`Wz}q95`o_AGx0Q(HyM)mXFwYz|weO|J1t+*U*-r3deJ6k3&z@^WCfZ@h zYS2nwZqQDh%PRf1GJ;t>pK#u5%zj1-rmIUl{KP`~wm)Bj8JR`WR@6BGQyoo(k2~V+lWQEj6($|FaC-WVsqAjLGa%+W54KnB6$U8(deQW(8$PMC}*PX;S)4>ER z#3tDY7t757yDHdkLAhRuW#w6|U3t|j6(lQ#j%aqOj$PU)zq#wW+>i-~kJg;}SIc(Q zcTGCxec1JMGC6QJ2Y}xf3w3DVLQsi++nLFO;bGF{>M3gu@H&1Y?Nc`MvT5?f#yzI) zb~nF%(wVNMF=S{J# zNF1@oOu1{&r3hbfVXMSHb1G|dqD2(yoJBpl3E)6a9U zxgjd~K;SztZaqkJtG>sIw6Gbk;L6qPic3hV;Y1mg*x&_U_wucqy;NhHR#ND*^S{3k z7krkeNzAOr!Z7jn>*EJXLo~2^SB+I0B~ThDAMS70M7%h`0(nTpqBHsXU4PlnZML#* zNOuzJBv;yGIaWsQ_cL5+k)H`p{D&|-|1EE2;(GBW-ii>L>Uve+7$$@L(F7?RY4cJp zV!5r)?22D3vHvZ4pT|qGjD47rZ@f3?FC=vj?9gJx*JS!h!WA@Q$BQS9;{2KKwvCe} zy?Ek*DggaTLRnLVLr#u{Hn9PkJ4tjX$znOCB99bO=wI~*<0Tm(d{1tBy!>F;WiA7)NSxi}ZaEpFu^Ej^MU%GlB)pL`Z!xyk{gOo9AG*60;s5<;uO4Z{MICv@XTHAmG60 z#ml`92@(86lSai2xmn>=x1g=OA8Uz8vx7v~7D^wXTr^i_@ui~t)QH-2h?#_SCMuZ& zd8zjGo8-R=vMwS1W_g}S0w^#WPX~CwO9;4R&N4`Q#?cS=iVxcwPu8`|{)LN>mF#ki z{NAWiA*_-HJWWgeE&;B%ocZJHqvpG04iom{DKC%b-Fr zTjgnM20K_qN0SQ*;5buPqzlb->W=qUO;I{tk>re4qON?+zivXs1~(qNbPUah=au)} z$$9n!zlNZw<0F&b%O^N|H)G=F$tU3$Ty~ejG#04}qX>aDufaDYzxU34g1nY*d+zo| zuibO-tiymsJqipiaZLMp&P^O-us3+sEu7cb6;<1dvsf8PlynuapnfKe25mM_#hMp- zTJd3Yr!f#@UcvnHRvfh#AIDd{&*Wy2bz0c~xE1kR002@apgb#+t(+-B$FUbh7ldSj z17R{Z=|cW>=8gXOgj84;$y5aou2H|Yo&mDy6{jt$@-3D93FNvW=0C`#>;{ZQ(4>^8 z8p?rhecQKFr-LmcL)&?PE0hUy_q|-SX@E@1#rcxM%7aK{v2`r1N`KvMqxR8)#0VII z#8<27^?=~o9#%n#v8{IB6@7!qUyDm{qgQyZd~T{c5`{rbwd6@b6V(+nH`8P4dHElR zW!~wbV6`>mS`!4MTj8z2TD(5^=C9Is4`Yu>ax z4G){zq&G`7Id$y(y{cyDuCawg8M$kvs4VeEq(KE3QM^k&;%)RK2Y728aW(erD%i%< zjQJGRPf9CtY^gGNFNggru~Rs_Zv;K-7_NOc9gCp2?Vc;>>~`Rh?_B*ZwhZz72*xHE z1NO^w(H|vhBx-ii@d5`!&Hqn{}Uo zq11U%{n-X265!{U#5KZ6l#$k5j^=F^4*a$PvWb*yQTAekg=iS$CdDu|7%K;~oo!9y z!WkQ^;1f3ehg?qMfiBr+`6~FkZvR-{m;K%OLi0CT6fL4Z)>B0*o)ar+V!Y%0rnb@ST*PcR)PmsiVc&qv3^E46ICNu7c! zfV08i!fw>SXJ_MzgUvWuJm2nS*Y5Ss*K(_vyR+3;aC8k$Ow%*-L;s)G5(Cde zON8v|4poEGrmG+*wK57X7pqr1MM^vQM{_il8KlR6NA}BGhKoKVd4f9X6F%HNK+AT! zM1oy!_O!TZDd}@IZAqdoZF*VWr>sdn{LNA6Elz#i@tzM#xp=8QL9&ZFBZpMY8Qr z?522jD}jf3G?RPA?|pdZ+%V3sK+MwKZsWR42YU>iEc1)uem8Lu^thoLYRAvrHFcqr z$ODp$CCAv7+28vW99d9(=ed*JCjGcyfDj2N^Y`UgfMK^)|?t{r)FzBv>jq|s7obygYhZNq0s5gmyjQt+!(DE0rd@JTG(kRGV zj<>t};Lkkp<509MS(D$rMWbj$WbQ{c^y_~wM6{NLR@p^OqOb9h@Dt4gB`e|=Jq5{4 z#{ak;g&u6oCjR^yvu2wZ$WX5kyB|u_rtME8UOK)iXlNe!Ly@!C*FB5sEKV;ak2On$ z(Hv6A5XS3+ckf68wKM{*%I4@>H*w}Ro0NaU`u{EIf81W*nNz#-N4Uj7$PBxkg|xJK zrZ$+@oB9xwP)X8$0lY;r_sJXXTeTrK$Hm3m34ix?f|L6_L92s&U+1Xt9`|)}m$Oe~ z2$=QsxZKxC_7@~HlEXY+QgI;-cf5DUrPirHm5H@_x^*rEK~<~Te(oTHU7Tn9lWAw2 zcHQwLr4-U}(Ybaf*I`7Y%SRXs4%y=&<)vy@`>W6}) z9udLfa8nFg1m)CobvSeU{kB+dC!p9i7o1~vG+@Z@+|G#A6*_jbL?733n_$fwDQA8h1{!{-I9mY_+^vEu}Wal6oN}JHF?GZU;^^ zC(ZCD<_P)&JuWQ+$?xA@B*PEMuEN!Ga_j@$VDZ;6;&wMI2S)A% z3a-%|Phu@waYxX}vT)fZ6_~6$-MPGJO*D0x^nU*=$!}7BfF_|FnfvqoTZw2c8rZ}Q zH!9T}@y8klOdS5J303RU6u%|C9*SK_rkO!0r>*f4fsI`@>StTA)|#&R-?Z9cqYg^~ ziX$yMg+v^h1)FVg25o>XdX&O}JJ|n2oj6&Jf${Okbt4|?2m5yBGC1w*(8&<1Y@GXe z>>M<9dhT?L$iYkL(IcY95cTnHusVs)-7UFO92H>8|K-9Yg0uUGqA?VGq@_mF-@r;f z2U|cOfB6=flr8ZvDJ{(*>dueGBabQ@Y!rFtz%G)ZoeubTgzxGIKQXE84E7HP!tH){ZgDL^U9*z*j+&+p3)h$ll~sQdbX63`k|}QC1UBM_^S%G* zx-N}sjDKBkZ8Xq9rp@A{u;7oSUhgaYyJk9*q$>Smt8VhXVPC~hM5`Xp$J4%)LrePe z!G)B|3@!!-TMJ;8Y{A9Gy^jf%9Q_&fb-}cUpqtfnEJfM6UH5@-tz{o)E2)iW8c%hV-Y_vNLDL-ICaGUFy!z%t)wo6kozJF(9!_Rj##O7k z3X#leW0%RAd-pE0pg4C|+lc4_#FLA%k2Pf&!)k@MpXMgwu)7@MuUi5)>fQfK@TS&_ z`*AzF4{kft$iRYU(Bob{w7m=>J{<@BxTVA!cvkxU+!sN3#9)&2rz?uT7Z`s}ZpTyN zjIDH_2`G>2c!l1(D|Fpv?p9VQ6_8a7k?SCu?at*^^JQa$ zYvatPv*Vsvhhv?v{8%@o#q%YXSQmN&&lD-@^yIlAE4n zdeT!oO%S|?;{^qouX{!ky4~;WJH%iFB{+D75N@xLf^C!6B!yYK_vD7_kqYs0JRoe? zskO5SlTnX^Q5@`4ZKE$>TsYUC(JU`u+9+sJI{a#2K&MdXAOG0a-Fr4)3?QMNyJXZ5 zQ;IgyfYjzz6*~Rgs`Zx^CL79w50fv=!%1}kLfI+U)M8R%cWL>G46>RIE|S5=WZ3fE zHo>L3B17!+>m?=rOx|f=?$X`vo%aVHTfBo|=eoB^$zGkOzCD`HE^|4cn#}bIfpnM* zz*Zj|)8wt(CbU>(fSz@!CnM#H2>S+J?c(~8Dfy1R-7h2Dty z`;C2ps%qf~fp=@E?7^S8&Ig;kofgZ?!mOg*gcZ*U`i1ON zIw;1T*RpO|53TOGBO&AM@44W$R`;B~H~T2M`eXu9tvdT@kOmi7x0}r8Gw!&za@UdR zK@0Htz1Idt4VLrXygwX&Dcp3Oe`${_X?J7n#l{$KcO3`+dM-WY*Rka>_HSVf_G9Pk zU_aa#WF+(DLvCWqXVR%DKkso_2)DYClR(L|FOCUj-oMG@fkrm@62m78XwC7(8A|a_ zD07sZ;|&H#SxW7*?!MEjL|bJvSB5kmCPH+z?H2LE`#o$QFVdciE+5;&i*$%B0>ryn zY#$(L&$|OiI>hz>l6iG(9U?*3I|E5DMthlAJViF(C4$#l@e=yp_I56HcG>#IWj*g~ z-)>y~)^lpiFJ3h>_JgcpaAe>uqgz;8K5Wa1lT-g@>tsES{`d{D>u0&9eElNVb9hNW1JmI zi*EPj`~xo4)8((7^qOg-(cRBpYopN(UTbwb>3iHx=uZ~ZkTy+l-jz^`bma_7Xc-G- z;fub3u7&A@h$@q3n{;Hfx5fNDt$|z$Kup?bes?_Uf@E>J9VD ze`N(-vSdv5b6r%ERED80l4yxb5O^;5>A_I+{J&>KQ;KD6aC!7IUzZ3$7nx%2Jj`p~ z7__)vo=?PMX(*WVoqqdXzPw43PiYaJKLV(Wm{7~b&#(%YItZMCVQmoUt7ARX4JYyp*S{$UA#fI_w-e_r!8s(PiyU+b->-UeU)+WC{;UyNj{n!kjGrHB}tY+4+ zMw4vRC^zXFtfb+|49R%5orN3KPJi~;@Aj+5RE-LOrb#Pz4s7nq=4|I35fUWikOoxY z)>=v;x`{s!DalkVjmSi!Mt>w)B8n9dC(x=zS7+!{Cvfr_5!N-Ocy)+ioJL)iuezNc zb_b2!k8v+3N+1zek&6abQAjS<@9E?H|1SCDG(0x|x*XZmA7*DKmJza1*6*#(qsXuC z^eo+0s+RkI{hvCF$gb}7`}KGhAJ5{V+uf>Evh(9EH>a218gXll8bwKH?negAE3V=z zZ7RbFr?G>Z^O4=HuX6Cn?%K8R1_h&8X4AuD4>E1UmdJua{5~AoHHtXq>BOL|U!jkO z^6^k27&p{uIT97WUjAr@GBpM6bh%|Qp{&Ue^4GxRatrg!M6MhI;+Yo zrvYADql$SH>@1Vwz2GICF?^?(6(K5R47v|Tz)dvJ6YlH~$h91d)976Nf%TD|zBH1T z8a0aUT<*ubP}S@p#4Pzz%{@FnyTa|Nv17ltlkSq=>q&Neg!r%ZkjU9* z{D=qZo;A}7F zLDR7GaGULkzcpRtOk?~1Vr^}XSbr+k^$Le>bvm&Cf-ab-fduB|jnev?r#GGKflRhB zjAMH8qW5siwNED1Yga$-;tD6phyFnFx2HL9G&Cf)1$z&6Rbwh_gMYn?{^Fv5S6f(A z+)Gi^65GO8>8onTvLp4tH*0qbxtk3V3b(s8H4e#;OT_eC8T&yNtd{hF6STO#JfBT^ zlkrE$_qK5@zD33JlU;?ru7xHt@|;;|T4=4pL%8Nrl+l#@hZkB|G!DR6bH!|SWN&mGRoaV3a%K=U7=T?uWe zNkB=6Cw=tGB+inLS<-CzW>!Jc3z8aYInxI1>K^0_acDw5puK)4f8Nh5sWJLO8OVAS zwQXRyt7uR2@M0lF_!G(WC5g29gYlAd!~7zuY5mZj&-?Z%pJQ7e`eA9`pOVm@a+{=u zA5CVT^|8Q5I$KS_am7X7qYZPJ_S0Xf$T42_M&tRyT21=y!_^G4 z*mybs`u({*Ta5pi^e!ady>u>_;N)+AGX5~_xq=At!{>Sb>S{dw5dOyC+IVoWntojL zk}v&%{XmBGq;DT>D(;Kzwbe`TOVJ*J3LMrWRqS;dnq#fE_$(=@nT0C@D<3UXU$I2K zN|kN-tB|v20{-kbfu>bm&}Op!g(Ym0@1(E_zNwj^P;Eh4nfYN>EW{v>!0350(&2QK z`pHto0c;G=`h!l)9&rLhdv8BWbqB+i>^E_UFaGEbOWNoXwOY`R&ulLf3M)6rcT&L3 zK2MWjHV^yQ>v@w=FNaLp&hK7UQp3-e`seylN;c^FZKozPO7qBf%0vuUR5D2<*C6lD z=EG!8Ne+XFZ?m9W$GSF`9Fh7)tnE`W&_1Oogp6;PLW2C~U&+_xcl%qYqOLO?PoMt> z=ZRom!~g#n%%+R86rL+gzA$^y^F z{8XZK@}rO%`Rj;`d=zBzk4g%g&&$zixBDCa<|$$&1%IvQU+5b^IXUJvA+JX=j$J?U zF}r@`+xG7o>9qh6Db^5yiTylTTo8JuEiP9R?kxR?BLg7UkAN+TZYfIEwhEB4wq1ah zwe37&TBE|w>yPEV*PmIO)f?Cr%yYY~L-@P48G>{U_EH2`Wy$c>h#c|-xpDj(cJtP} zmGU04^K!XKTRx|JMNlmv`w5p!SH3J81&q?mwG=4|17w4(* zP|m#`OD+7hp!hk|n=?yL&6$3A$>(2>gH=iPU1|rEPXNEAbB~?{8YnX)ZyO^dpY$CM z>=#dR7gqLjk;~B;2xB83JWpfYNx541DSMRTLgcyIDLzEXFKKV?uGhx1OSo65#Uc}3 z2$PU~S}{c581{*Qowlb&b~CtI}#cv8ibk(wdrP zA*rcpmQotp)Zc+joSRCfU$~rfMMWA#vj~Z@i9n(FkUOKU_(S%ioKgQ{?u_~$bFaHn z3HjIkkGa?VkKyZSS%KX9*{@*-*{|p0rQn039i4q9CWpUs^3Bu3gKwVhAK6i(4uHQH z5OvKwg^)HB zmrv%1!2R*W;0Q&K-wPB$yDLxx`K?S5w54#Y^1*GbLS27AfbVOTZEEF>FZ+|8tBU!2 zr0*4V~Mdyi$sGpFoKV&A*aTXW_Sq5iJol`OU#kK97O*43j9$N)N$0f06_z!J4q*Lz(s=Hrzmt9@eR#kV>U=%@Rbw&|!!$AaOQB-i$QAWlM#C^eq8PNd|Mi5lo zSLXknbMC!we^tFDjT3)ANq66?m%pEo)uzb<9;2>xzGgpdS2z))mmZWJ4W%rN~tIAq-{k2Tf(FxhP+znv0sq zRK7|u4E~|1aLv0YBwX_@3klb}%dBwaYl79#jh})W;4(;DzF640;)!#M82JeJN~2h+ z;BcEHW5H*_zX-zM{^+jP$0ZKK+DdPEv|bv+(YDVuPhv4p;!#8-Hh<7p1$+w{ZdJ+@J*0>VZb3v+}wj5bC_8!zSC%zd%Ba=2I<;%33!h0>n z4#!a|)QkNLJ^TGz?x`{=L<58R8CG2zsQaQS-44D$tKzUF-Z}|B0+A#fk3kFQIO{AW>ai8|vK+bm|xg z1itRU4I}(-&KDB3gTh!vNK3TiWrL##b%@^uD|g7Ad=&DmaCRciVytY}IY|69>b7QF z#4<W5I35%Dk_)LW@2|`|RHj2aO>9Jjq_q9;xkq?&A+FE#k$;i$XEsj^?UZj2 z`u-}oQeqj)E%d9&Q-r&wekXR{tgp+x&A8HTZYM5sKC^D-agIsW9}l07z{l0*=GHL(~5hnHs&P2%Ih5YfoKWSifS^39C0H(tr4N zW?vo3@tn~2)>Lc5#RjZbb7R?=d`&#fj&n^ma?2!K%KKFB5lbBn@|0vy^7isF&F&aq z@MhP~*a+}onF4)1W4Opah%NNPUE9dE%v$^?8@Pqb^wnnMroup<;XCt6=v#7La97vr zI)eNDG3?`p_Cf44@uhCvv%Vc(bCF9u#oi(0X!OD$(Dd6*WJJqGvTmGV;PHMA#wAy{ zeQb(IxO){igSs(3!nxQh$Kk|osBJCv`D#>P(`!7xfp`*B|2%U_cPE(5u0$n1bGx?%N5o_nLX`LJWY%8JzGiO#eav`!C(fQd6ptrv z_~U0^>}DTku@9TBA^c-Ti{{VWsi08UK#-jDz$Bh=KuRFS3s#dVDQ(1*!qo98q&r<(iuryGCmw9%!f z172(I3>mD`{Uir(&(q>Dr|~~8nY-|GOiUF1NV$NakCczO@p_h5<~HoK_@T}jPu|VU zp@{tCUnlHK0<_3~D_z`}HJvpJFx4h@J$69Tcb(WBCp-ch=U6_kDJXbcvC>!en}df8 z90E;lexW_F$BYY}n6apn!W!q#ZTdR)>5O$^9Hf^qOA(cRXDiYHJyHK=i+r ziLeuW!pWZXpNyQ46SD@`PDo-#l2lvu>H4noz^A6n!nn)i9K)>oZ1d>mIh`-9d z8F|Tsri~5&5u05<2+k@&tZ5d^!Y&wu1js-%+8OJRzT;&_=rDlvgY7TtF{8V(=|J3k z%;<_V9Y$zAcF924atGlIVQ99FOpe36!yz8o?P13QALBQU!|}h{ibx@9l!kp&e z2KEp7gG~wIgdUq0Bv){96f{6hF5{F7`9ZRH`0osY$tNJh!S*TmJ;lC$y+kr)_!`8V znN90xbMj{fI144%(YPQ?p3|Em^Mrq3+KJ?I@GmCrFON=qC=ZK&ns{*h0%3i*4|!JH zWEyu0a~b-`G7UsmF-lqn4G;$d2}n%j7lj|gNZNNmxA7!|i2{@OJ_md`Q_X}7qXnE) zN5qV9c}TcSMq^NjIT{t%EWdDAfZH?WUkfr!?5!4P^4@`{`6NbU6*ggHbVEV0Cnq3u( z{;ot&PH-7IzyzFj%b=O9&Y8amyM+)C+8M2mnm_+3QfPNLFe4n8B{6nSSk{CkPxtP* z%9^XAdW*Gz>QObgFo3|ukE+*tj~aj{KH7660EQ#l{odZrj%CaGdY1XUOFI@G#i#>P z)oO*F(NejA+=wF<9NB*4(na#ca;fLYTK%Y_lUE(tyRdz6zu&Xqh~9zGBiolQqh0dg zj*ewC+E*GYwEOML7?mDfswqhLm&-PAb(X>?{~(Fa@{?cTz^{JFMIES6D3`~E3kdn< z6%HwcFU(80iCmbQbb~8*$*i?6!F-^a1J`xn94Y;QXOBOqmxlZJUz<1=`gtw?ylaNs zzLfK=N+V;P#FJmGl*bGB`BhbT>L}^ZDD|S$5Pu@5QK&=!e-#i1BH{ zZ@rPGXv7 zQmI@W=xFsgg)huKPT>plk5dN(74&+cvx9)73!Xm!EskGz&1&tc2X`#)kR!LSLyp`+ ztPqY|=r<4!1R&J2hre$t)`#&Ajx8v6{9R-i$w}1jhJG{051;E#Yw;7JRE4qjRu?{e zVeZ0*FU()~c3M#z80Fe#C%5mKwO+D|p4+}?7d^P6W8x1M5qpH~%OplM?lQJu*DP7b zk_D_SBvsGKvi1dH>vTZA;m5FC!>@=BB4uDeu3<5QAK(nsits2jE>i4435lrA4E^EA z#S40t`o7;Q?m_Tfp!w17;DaOkIu~{{za81%UR>%g=v-)?(aQnkx$D-QyngOHnWVWWAzDY8@Z9zzJC_{UK6joo zDUiq7vG9lm9Y-u!a`@pyU;Wwv2OKGdI|?JCJ(c3HU;oIH+o+BBf2CX7=(MeEE;C*t zX|2VpI}q6|NufP@#~VmU!pwp~IQ$yimkYU`hI&jdnadPixvkK@N+YIt*jl&~D?k_U z=mkSW!WYo+ZH&Xl;YRs72Uo(Whn`25;3Y;z>w_+&UMTxxzNuH1F{^S0!$2>&{dn;#9=Cyw-v|h1v$2~-%27)1!`ZigNnYsJKmr$QbvB5 z34NzU=u=+^voL;I8*$O-!eF&JL~rhm-_Z0kwPb+Oj&>Kdt4(e)F*u0kOjL}sB1>mFS-e~x{f_Jup>?MKXkOD7fO zWeT1<)&{Sr4xMRAAJE5cBN`qV?xnwN*Ao&12+tX8Oh8^-EvJB=X%j>D*)ip8{gJu=6>;l z9aOrPXmjrfR@N^L(-GKMTBlA&AKOr7Ph^)Zm@xBr1J{`~OP0D*Ej=SP5?SNaFHD3G z%go~tl@{y$*qM+G(aOg;kD~whmfOcmcMx4q1dWTW0(McB{Grn?Y{OXM=vT+3uDNML^Lq)~s=_vq9oxp`?{w1eKaM;p0}OXQ!@sSi_xm1S>k zrA9vl#u|W}D;f=m`obMV$81@@{^fMmHz7W;3qzfz=#1;zOwOuOiwp9a%dJZ6>Jn+x zJzj74!ytfMjma^kqPhOBs-h=d2l0YL1Z4@QiLZ?+$IPs!UD3@g>o%5ORHW<3Ro>IAP0n(4TLgL)iP9{9+$H@Jk}Ci9(mx zVp96?Euqi+52DpvA-x+MjkP#c*swJkyRMB2bpMBNc)1K+k6)1L==7}CBuKVI^5~)K z=g@{Nn>TLRTv)YYy!ErCQ+z17$7Vk9G0rimS2Z3bj5i;U|kj17Dy-ZJ<-2E7-2G`9|@*(*MCZ zS^<-vqC}@csh=0W!99dV>wX_C+1^HD=Y(TLJA4uwEDc$<; zaZtO}?I?in`{4w|u-TuQq?r5=HM$_Y)3@WcSMh7+nA_%Sf5+C*D^FC_cJ)+ z5L?h1D0Zg_4)lpgoF6_ReKAvXzG)^`c~*H6y;;TfXPxQ z*#cRE|5*L1_K;;^^S@H^2hXryGsZk@9^-4Oq*9fpW&jFTDQ2&hzz=_c6Jbn!6xS>C zjY9guVWzRysnsMor}AFxTJpZfmWEn{5J46HK4>S8j()Y86UtN8XY$XHVj(7d)lQMA z-w6u{5l-u}EVK1KTz#v8FXcwSTT8s->nc!)LYS6&=H^Wy`6sw2Z2oP;A@oIed-Unp z0?0Sw1Zr#4U_r&nGiv|`^CYNh5NJWU+0(tb=W+{s*b(}2-ET!KTgSR=N&x@nv%$liphaI~fdh|#0h z!SsdD@P|jxD=Fu+!&!s4fN89EoUY^L(I4+gL6x}7pG<1RTaKYhbsut+E%k(G=F0pn z+<>VP2Ik~b#C7~eN8-w?eFx;@=R@!raEBvT*{NqGL)SCL2;iN*3eQ+jhC-c#r0n2k zc*WnwLWK(W@o-gZW!FUX=t$@rzGpBqVVHIig9+ic4*gO81iv@utAQ^YM}QUoEvz;O zMZJu2hjJrT>j3Ed?Ok2a0Ps#)KRzCP=D*C+GfzVng5Cmb)(Xkpd~Ka&mRy0zpO$om ze5&e~Az4wG8}2R@Z#7E@OSRa!So~ePLn|4uYgZevuZ=kYT3!E zW(?rZ=(Lz<(&kOF-Neq7e5i!5@#rMre-0$mLL$~;hABREJM+>{gzqoo4M}tz^v)<$ zcW+1v0vnq9>BO*9ASh6&o3UMZ}ft}^Vw#bx_ zvVPGsJ-LDLJK#oFj=1ZM63hCyTH|u@r^ssMahzF`p@JZFsGJA%%4+QN(43CQ~wAZWU!I&1M+hCt%ZiVwTulW&(9RF$zUlV zJGp;Fty(T{n_q_0`8v-)*)NaI z{o1R=N6J|?H(Jn`3Z`VB;zXZ)si3P1zWyW;w=qxp(H4A>So9lHN`Kn zF$0{A1u5-$m(!WROaA))HtH5Wz-AP!5yOk#j7XS~#d6<}Sr;`sJ^JvMjT1VG##@Fq zHYEd^R_zHJ5w;M!v}OY}KfO5lX5&tihVW=Tj0r|`?1E3SdC6K+s%8cnn6#k9W~}Vr zv`=^oFJog0c1j_uTHYY7)=4x5ExYVR*@FpLw+lDr1m0KTE*>3rtT~}2P(dlD3^nZP=wCvSId$k!3Os%+$?%Za>gUi6idv@T^1I9eW!e8P6>fAQ* zxezY(=*>V*T8;jvMx!{a5{~|lorCBRJW&+vLkbmL8e)8TbS?swIYi;O38g9~r^kjz z-+cgZ5JJ5*6P>2TzZ6;#!(a4W7`8A5Vb14JPY$@Ojn-CBEw9p`?*Mhn8J|w;uJJao zR;zBp;YE)jL^%u68(4$#5X?1t%h%_CH_)K7el7$&x*s3`7v>A9B;NL>P~;*+u3^$F z;@c}x765nh=w1J=6h3{~R8QE7|I|Nv^qz0d5x!odQKsjBdKqUB1n6J{H^fTiG7Lgv z#ztY&x!a(G-{4S>Dj9myDF8oF2|d1-oH^b-KHS3?!oPkNUm6~f#1SNtK!;08ZE2Ps=PYc&?;^}*6Goeyfl zM%!PBz6gMpVOV+=L#IJegaXTyI?M`mme~g0E(mjm!bC6njyi(c7)i#H+kJ;l0j?0x zR(NgJR=XMgg!K!p^8h^05G8AR1KV`h;n;6X4=eP8{B3|z`in}2N|i>Db7W$L)b$^8 zNL{xB_XWR@X-kDV>>7NJcaTKL=rxb(24*;gy)^KHEsT})YDZT zR-_&0GBalWbkH6-0VznrF*gAhk;yPCtJ}kD#FPdNQG+zgH=joSIs5AS*pJ-Bogh$cuVWd7Wx#3KRF9T_kr4sF7j_zAke9vQ zGUlEKs)yxv&|*jpEGRhR*CoO!p*kB7yQr?~H(2qX95D$pE)w@ghMUVR?2Lt3GVbQl z7|bA!Svsr*YGb_Y(@XY%C@XD8q#adX@TS$#fkDH^R&6j%;@oY>=pLgRjnt?kSja_$ z>E|o38r&m6BJew945u--paIr(p;j6goNgB3D*?MQ%0Bxl{@(Xl;C97Ek$yY}h$lFX zW^E#ZCDJO_LL{>So}p)fcOv;2Qn{!PNvf7JZeAo^JLEUV$=Il%V2QRyaDb!OXUMUs zp{Ncr%lZpG+GMmodovOXxZ}lbz*EMNs#1r@XN-gX6bb=pEQ6kN5E5P;F@+8~mZ4wA z4K~5;$&$J@nZ$xZwNAH&;%#7Bd4!aqc=hFa9J8exTL24PO&KV0YO`ZvB{@e2EQ3C-DO5HEGoG1 z9{t-*EXCQ@&!P|iKcGQTS11gypwKDKV=(h(#=0AfcQEZ8)OEmE1UfU#LK;-EYkYMl{G{cq7xjP^VD`T7XgZmM1 zF2QWhYEdS(vFWB13vOq9#ewv#UJt-O`}qJ!p5nsCAP_wQQkfXKeRS4G6ge@TVC-?S zPpscz{1lJwfukZcC@Im12?7Bj2XOMJ>sp8-F#O?g;)S7N%+(xg#D`3u-+~ON)%>GJ zKJb<>;Gh>XJ`!&6fS3&k-w0f0Jz2)i$20_HgmfP0Xr}r)egfo)jfs;iMI#nMtMMnz zWOGOqU}M_^7y2n&iNMRE`+(rc-5f-w$0Aj-gEvQSMbe>EImt1Dj3J*9LJ?$-gO`IOTfqit(N`-0Xi%K zbnUO$tiV3j9DF#(^c+C1jvz1mTk=3efj5F4J^{mIQoar?e;N>uQoYzy22}b86zCXy z$J7Jr{Z)9HD3BLIjO5yQ<(?5jrJd~!B)D^$ z+BE@@2(*|#UL#l*a&hS<+|5MIa|93LGhJOX#KD2vmfqpc}k38vrRXl2OI646-e53nXIh+U_5f(C9dQ+hh| z?M75TIzN)Jr8}lcm{2duz;~N2Gtb8i5PCw!P3+KYuDbdWrz4sdwJ)7OmO>>Sy&{>D zqQF6B@<+l{S0SGp9dUM5_}&{3f|qJ2=)%>3_!Y`l89U_hVy3u#_wRvimR&A{&c6u0 zd{`+Ovu)LA9ZJNb`W@K4@%#fi8`6dKMNSK2vj;;6S%%PahcRxKeCa|R8h1piy9a8U z&E(x9pT}=izh8koIvVxZBsRmXrs!9gA|n|Co=VtLx$k}(jS_HG-XIU0i6ZY3$8yFe zr~hkY3&gBaDY0cyPmTkok{hSnH^w8XTdXFQoo^+l?$A8ahH!?g1#WAj$xF5PD9FM` z5U!NGn^=jFmZVn37QkBI&MS}O`Vn9$aCOxJI<=x@SOwKW22A2hod~Ht#t7ng(SHJ7 z1|VBQh!jCU)N`X_v7inbGbC$yCR_AoXNxo9NaOCW@o;!zeFD3&6%WJt1UdJ?vw2+I zAs6F`KV$n0Azv=T_vi=N%0xU0ATZhrAQsAsCCl7AV2sbCRPo74`CSvvr}`xvT@Z<= z6T#{zXcfF{Fi4ob?BLV$;bf-98-(huII!EQpeSosH;st)R>8AH@=aahP%hhUUk9XIsVO26({ zHSrmfQg8^+RCBa-W=w(%;ZB!btg>CDhOutPswGsbyYtUPK$bC0bqQ(F-hSL*FycKH zMx9!4!J`i#z+upF+6I6~Ty<7HZ$pt$UQad*M(gyU7;i#0rf7vwR{U5ZWj?A6I1gCB zgO&;fFzSB6O)7YeJ<`NJltHB)21wcpQsYv2A&8?u=CHL2w-9x^eMC$}qy)yTc%|K@ z0N?&#_KV;UFY`=HAPWY7i$i9V%E|(0D6&BY#Ud||pp(FB=^S8Q43E&K=0ZJlkUkS_ zqu*Nwo&@rByQS1YSX=2WLvkVQTjdw>xp2HpF(K6Y|LS2ZDYagd*?rl*!{4zJ6`)Aj zuWw_xhO(ZCUP7~@Y?57)R{dk(p?M2X94m1NTWDQD{5trY38d+0R2d36^{iOas&%In zr|U;o!f!yO0qIKoNo*V;44WN7Al*0!?jn+Dn{<2m1w2M!TJ~#w?`efn>K)nD3Xj#V`SDlXBixsW( z;DEi{&qRT|_s>2MsbkMqU-I@m@8ec|u+MHrGc-1{io>b3D0Y$YG4;U8mn)gl&t%1N zaU2dBojv`Md3PNF7g3yqwVD(+xdoCudJ_0FX;sS|u`*O>&9de{-g>@>8ISlY)+LE& zi+l&g=Tb$U5t!Z56XqcOZZs?;M0xU0w zM(!i^Kz(Sl?=eWYMvMzeYA1CeW?R={pY*I(#<382^(6GsV$FAtUV3>rf1c{yW|8E+ zsawLM1NXO14f@^X=x2}KaJ__#!J!xs#IH{0VXvA3)U3J~t<^;3ocm0C6K1K+=V3em zt~p7EK8p3>u3$_X&CVXV8xCAp7Ul>i4WV*e4S+{;#LfE2v#M=|o49QM-gwp$&q#LO z*(FvIxHX_6bL|~X5qU=t@|F_MO&4u9WFwWv1hVnym#Oh?wY8hzj(X8-gEs;J5{pYa zxbO8lAePX&Qu^33@q!h;M|b}Q!oIGOm@c{ps*H=-7U0Uz;1`V=83qBV1Xvhgq@)bd z0pNLAuyCRdibp^DttBgA1at$~rrdRm)*x*~U6Gw2DDx}=k5&Wc-Q=^QgzQ{pVD^pU z_(`%~5%sUY$3La!NT8xg((!SR-u*`4%}}jS1+W;oZamG)({VG>m*lD&*w91!EQ!pb z_wa~c!$$Dw1^<9Q_#Aq}yGkHyXQnRw2(_S08Jm2r3B;d`Ya?G05jMIO75Y|L(h1#^ z6~+z+EE4tjtaqUDesRtr^j&L6oS(mQPSDQOCSka z1)QBmG)ly#l@^fFtah6*!2&-y;^TzcDyg-IzC{z~`((dSOQf4$rJKrTY7YYOAZ+8P z(26r&W~StXM_*?bl3j(ne~4jN*q;6gHZ@29^b7>25z9>Te{4j09yX3d>tvQ<`{u;p z6t$$ma%S42>mk-S%h5#>rXd>l-F-tAF&oOR7;>ulJ$*a)`@XUDO*!QYL0AoUlFFq| z(Je6KMbgp&q)`LV;LQ zuic&mN2%S0yz1)E@@QjHka&IcKtziA{JHVJY_5&lKMIoI(E>16xU2!I#-9wMU`UX6 zPoEkVrmd7sOnm{3B_lu$;srLJ+~kAM!4UA=g>iLdj7|VGR|vd__`iBI(m7{x4Bg*f zU_EAJzlWH}wwc>z@R-r_;YAsgq3eusgna5!-)OOH&Pj%0XcE%X z%yi6UYTkLoKZ#ug+6a_HltHU5vMVzf6%y$F(29y|64U4O0#TZ3M!s6BHp{W1G@M{xf3u)*h$Fz(G>>xhI8a(m0b%Ycn({V3 z2LEak_*eAA^>aWPK+jJUA*g($72`Mhd<0DgZXw!)G)wpP%On>G(+Niu*4D2mq{$E_4(jyW|x4Sz(qpa zw58tc{)l`C8*uvSzh%r_+Q+Gbu^%>{V!Q+F_ncC6>Ca66G;FlaFbS5c%uZnagm2Vr zCq&lM-ahi7F0x0o6J(43>f~k*Pw)il0#52{&-DHjZ%dHOr(y_LoT7g7u_LDP>vzMM~3Gr-F&iy>TBK@c|C}dSPSlekmykv z-oJ62(182Nw;2by*o!6zC?c&s^0yF(3ClFPw;R27$BLygr(rR!feG<3d&BeyJb9a9 zMhC5f;FeJja35Ln(Jve{Z7$~$bPPWoy4p~c(S8%F1wTe7WQKj1b=H+`%@LF8dUveh z!MdUp))q;L8y&HqGiG)w6G0;hHbB7C+;F*w2d;#YMh0N9UM~$)=;N@wH*I55@Kz>j zN#utf16&xm#524I!@sae$Q_{N7pf9AO+61{X~LsO4k)Nc6w{}YWUW?f@>@tMMk?lL z1%de?0|*IeJD)25UkJHHQ;_u3D_eC-rC#j!g|M0}4D6;+0~&S5>7lGLJaVVjXz>+> zLhH<4jHY$Eq@EKIjbb*rfRfXCz&yGHc36=1E=o3Fm0?JV%)sk#7bV82BbrDQw`msE z3ob^#aKC4CV103f{u^$t$RgmybX%W+FH%=YE@Ri#bg0y!B?F~4PA4_YPR^@IiA6@} z^V>F60v^-yh08p;>WuhivX73%aaRFG@VBEgjZLc8?S@z(F!Y?DIJ|E*gNL~tw{AOd zE&5?W>)u<7p96zL@2Pqdw>9v?Js@-_ixXqhnXtq+O+c|o+PlGRXWPHv8sJeUN{%q( z1&oDLp6xsaV?tCy3;IN30_Kg}OUf~jT@@um%q*vdz6XDl)m~cb$*IuLX+89*^cfN+ zy`FDcjS_a|pe)`&cV{+4Xh|IKteb?HEP3#RJIs3FRjA5kgrzSiy=WQAe3UAjM}ZCk ze?e9e_aWNo*M>__8gSLAeweAI$c20=C?A+ZqQ5c<1_ibj+Q%1RzpvnbjJ3656Xx4i zcSQ@vs}KW_(2AH4LXAJkzT`jY?>F`XzEKYp0^_!(w zwX{jrU#))<1MM35v9yv1`Q)P)Zd`X5~fn> z0+^Eo0}Ch8@!&jqUp!D2P3+kz$9m8AgV0t5iIFjb-tQtXWV^G`bC5C0E?d(Ey_a2N zD=HWZT)F z@=VT01!v*v!tJ4t=h`rZ~WYh~gLS~~Ynxyj_iV0zaM$|&R zgY#!|C(X#&T+P&qqG)t>rvR*cfk zMB)WfF1${aQzRW#n+2O0}P;9t6hCu7BA7rAltPJB|Ts{}eQ=I|-->K7(A%=6yIl#!El;S{U zI=D7yj1<*7h&BbWNrZ`<{X)UvY!zp9*s}+jf%Uo9 zi@r5garU-B@QWH6abnuZ|5WLWGw#uuC@x;}!4ar8I=Em!765(CAe&Jf(iOK~B7!*! z>d|+8iJghN)~e(5GC<}X_lYC{Sjfod5a6srm-nXs!DRUweFppJ+KyDE3s_7sD?_`Lx;4XmqWqe`@DHCClEhZCfp!mMuQG zNZM^zV}oj;JB}+G`FP9w#D_18wbL(vL$k|O1-6m8sXY2``1F!%$bKX@#xOfJgQj8* zVfHCzcbmmc&Or&Lr&YZ63 zuw_qXhDbz*Z$MX07t!b8-A1WCEkL>Si(vOiuD;nmYml*q03BB&1Z#{Ayw|{My3w%y zxiJ`a{TsxyH#g*_lH9W^eN^kJ@5n zLQ|*xu<;pM)g2jxY9>>CVHTkIIWG_jKV%%6FrqaZ;t|j{u(lF|1w8XSNb~jJD~F+E z(N1=o8BTWPT5JPbXafYF`w&%#Y6BMml!?{DV&^&;@<;h{JhgfDPR?%SD4EvhPprQ^s=JTd^rqD3 z9ygD+ndHD+v@sfW()BfgO*n-9_6cZ5w%A5fOo!GwtTE)C*f}2E1pi8tW*}KmpNnn* z3tplmjqwqmK9B$o&3Oq`;0($(CmNV>Ml+nr`Exh8&fgjO*rU_lZ3&yKF`e+)8t#4} zRWu{zw4(wBs+<`sn5e7vhgw6%9ePATau;!WP?>Z4N>?dB%`td5bU2I^c?kXNt~s1~ zjnarTh5(~vbBmCm7sB)G=RWni)=AgX4cG8bv9^%PV*XjvTs_Bt;wD807$)T#CsxM9 zP5JeLTe>@%8@s1MF3&`D`smQD(+l}J>VUyTOQ8Ya&nI6%rz-WWLAsdWOwRP13JYTi z47OuRNH{ExuapU;E|A__s{#5o_}DJ}pANmtX$S=64@NLtjt!c2*67JdzA&VW(S;po zsrM(TK3GF$oNh{5XM*3k!XqB4D8FYiM=!= zY6HO8DvdgI!fq1Uo;7wvD{bYX`!bnRR7-UH=iE^MCE^<g^OjAkySfSmY`{{QO8n*?AVNyxSnl6?&<)rNV}4EhgAQO# z%5*$pQI68VH&2zn*h-s#oLFW6UuVYB&GZ2-bmP$m931(SMqVp{1rT@CHEA*qs zj94~ecQat&$6xhz;OkkOgI#~HII%}2omSjOzyW$~#TjAipwJ zr{|e!x9A&M;X_^4j3Q%tmGz^Fh)!n!o* z+(+PX_tdLp$PxPMRTfW#0&|Q3`u!Jh4U+^Vx$AOJwsFcwxTcZlxvUt}WfLlSoVs&G zprxB2kmbH?^^78Rj~4ax?bksAqZJ6^vhAG+uss=BK!Ha~uecFs z9$gpdo>>xbjB;But?g+IIzFi$xI?;uny4a4IC?SU3bV1Le*+rZXGh(aBExvZ_lM}Y zl|-EsrA=?!9Lai^b&<;X`@?SIP-=l|!|5E&xq_>6tqa+Xbv&C@ItU zY#=pd6quktoTp0KNUI=_v<)S(KnBKtQDy`RK2#Xh01%QL&H2DUDmX3={xH&>(as5> zY+!%&Qg5A>0xuCHK(k0U!vyF(xaSPME64gz*$nv zJCp|}oIC)ay@N$t4@M{(QfS7-lAXW8m!*h>_f!~_jhAG~aE#1p%X>`Zn-*Vl`60{R zX0di2j&4hapPIy@LXa}HEPtU}npm^^x7C{3JJEVBp=Rs~MkIg{Fd{T!jXGgULk^iL zw=D~zSw*^{&%M)5vg4S_ia{}Q6vik<6vYZhWjH?; zaHvNM!G;MJFPoYr7dH-qT{UR{+3fS2aXlUoTkxw;&jQYjC0ss86IQV^u(Lh-%2gPL z&t?{ft(E|Y=ZG!Jk3qGDH=ZpZDhe*LCgClq#-Qv=U9j{7mbCAy%;oCH2s|W&V|Xa( z_w?u!b20d6)lnhX7o@Vg3~HKe6K7%>sbr&Y`|L40TQWz&^i4ePR4JW3dCb{Z0ruzS z-Vv@H!`W5zr{fV{D*OHjJ$O#k?6O&=re9oFS5S^c*ohu3g02qp=OwB);W5$PAAzUA zHUAV3?)iAgaSiV!O$yV!#|auP$ydGG+l(1=~j8~#%myb9} z9UjJKEOO2TCm+1j>TWTR%vq1~=>Bof*&xWBL~8D-p*1)CW1MH0Di}Tb)$7^-bh7Ur zWDzsUU#elU_Wy#xLtBe3VM;Ttc-QB8{#>pN@;k`UT4`Xg!PSEvrAautol+2M zgyn*hD5m$9Hf!b2+qzkm|s&J8IQ+lS?>JH2h<1y*DoIkHn@;(7c*@u7{oD5 z|Fn}6!+|1z5!3P|i6PL3iq<97U?y&d!fnWzx6Wpy@tdKGmHpmoRnx&EC z40lKT5O}NWm_$kc+M5c68sI1FYMH5QA;kmc5O~fD(+{V4()(R)Bai+`;4* zCROmpql;HC3@Le&Gu56ky07S|@3NbP(Wi{f@|6>qy-^#Yd5MsZ`9_Ee@5Bm}QxzDd z7B$Gw-NNT-(`=FaV1v>@`R89Co$f4zLm+cTS@}T4(_inAXh;>5 zVD|q9Z4L+KvveTiaHzsoS`o^s3B3p*NY3&{ftN9p=^*Nu-jP*HK13H;k=y!!ON9uqpINW| zspp6GUI;MfE&vLx^B&A zxtt*+>3Yw(LZ`PgR7E{eq4?Cm2T!WPB(v44u% zi9rOCf3l%XeyWs{$*}8VFNJ`*OlRz4`^3m#?1x#ySo^pSgyLv?4^;-GUYwC?Ob5~u z92)7(@wf5q|1}B^Bn1Sh-;0`dvNpwjOpVzYI(tEe)=ae~D(@HF(#DQx?mZtfF1A&+ z1hM-dCWo@WfDPR8)1%BdkG!>^?%VT%EWpXNhItx5EsjJKU|<%5%$I30FN2ARnb{NM z@#)r^ZP*j+`?E~x9$UjvO89Jp;jaDj%5XIb+}J4RkOXryVNk01*5%FP(Q~co;|f;j zcqHf>vM{takr9A-G5l8RQ_yB4P%wX|Oz*gpSr7x78AT4Hl`LATuw$Df#G;r#7e?Ma z2v!Q!RrYD#H{JHax8Cz3qHY#i^x>(3pRJ#7r=b$m5HmE7HZHI??`Q5 zVC?j3IIzkn$(CktV(kjHx`p#<$Yvaftbzqxk5>iIA=*@Pg>#SYxSoqu zqa_17Z``D~PTxhNF9ZPTbD8Gm3~&_?Lc&V+CR?trTyw{?6r)l>v=F<vWSaG)H(KbAJ{vV zJ7-iT`)i?6qEtjw6>N*;uC~fge~zakJxW&fCdf5o zNZh^_t}mx4b(cnt!*71AeW6D{1!mNah@jR@AUPfBY_k?T+6Sn@IzR}*WvkH=a4?S% zCh2M>l3Hhho;Va1J&GdKwlN&l)fI0IqIx4Pp3pL{N$PQwSMAZOP*fwgPKrHy)0;0$ zdjJz=iO{k&JOgy2DcItxF#Nh-tbwS+wKZFRjTs0AX6t8<-UI~zc%zS7Ttar*aq8Ye zS3%(qTN@;yg3RKy5@zz~oq}K5qB&MOBGm|>0REdUhh}DX8EG8C>RQi6e?tQ6O4t|~ zc#yKqR0hpNLYhZk#1x|!M58oB&w(?j@funS6R|NYGpR+ZvkbmZLZw22_72vdA)yp$ z10Zlqxt9PQ3_slrJawCp9BBf3_&i}j1s7t1jLB-V>_2oS>TeX-zh?qJXZ{D3bj3t1 zK~ry*u9dU}28UAqkoqwGW`!!nFgZkeRH3L0ofy?=uxwEwadt|3Iv&zp0+)2~|FAJs zM#zjYr8@Pa;^7EtcbTA&0!F=ZkIWk<{wKbJi^5h7}v1|JAQPr1XsQVg*8^f0TY{z&b`f+J>oJQ zG%y-*=wNo!+c^5ssM5hOR0Cg6*SLw=&k=w~%7kwesUI5l7E~LW(jmGZr4bJujG-q` z(A2rLbI`hr=+sVRZjH=JeTGMO0$CUun*o@{jG;9^A>6*~GIXnxwl)RKE;~7NE6f+T zMw+r>?kleoBhu3s05OMq*qM_&B{(pdjKa5T0SeX~HsNQ>o=ZT*99#?EFgdEV4jJ}e zz4OZ!@A`(2QGBFXSU^Nn_C>*TN6>jZLqcu;4N^PTJg1+-TAK|71XNL#ChIZM%T&ah z2Tdy=eU1<$lpUUB@2`g>p@AHHHysp=C4r63yTIDM%|+b|*yxiKv-wJ4FW7Uk_N>!G z0x8)%C}F&LwC-ju*awx1+}AWyPSD4z)+!kTQS_%@1L>}Xx~1G$fVzCf8E_oC{Ru#s zY46f@&(B~!pzRsmc~O{j(cWprZ3^oGa1_cdUSX^wDGMxf#HMPKq_U9X&@Clkg`bC# z)h&=3S}`xccpfuW&hk7o+i{WrtR=exq>qyR08`5t_0$nsG+=sSdcSR7{<~~QcoIM; zn}`oP#ZxtKJbDrkMTS;kZxxVkX0!Fs&z=M$os zXj~;H8JUi^hcV-YK7KEJU7`PIdH!G9@Qb7^TX7SS=$pFPjTYB-Blp(Xb&hh=k2yoM=j5<3VW6~i`ayT^b{dakdqybZOuv4>G}Z()Z~u6YCv<+vtyJd<8w4ujq-_)LH#vG51Hn=EI& zvXyeGr<)jIsdJG>pN#Ok#d(pNl1i_7!Pfq=!b_Nc4r|qEVo;qt2uG2`P-0m$y?U z`J+I_d1eJ2r=!9AF#$t*8C-LbGH9e*p=Y0n-?pPhL0_T2hQ6(0@#choIuJC8MAAYm zq$X|wj+IBxhTRQ(UXvpJZ57OXDHE^|851{yeRE8ywi-y03XVwL-54+XbZbO! znA6rmSeOoZacD)SX>)@Kn*b8BgTJsOhQQ>$UY84~Ph^=E3D?SlF zH2049=*>i9Jm(Jo73`G&$4LM~Tj5y-+`Ke`49BchMHx>b+ONo?^Gp%XCfvy50X{JF zP^Yg(fVT;3{a2;iDG>(=4xPU}G~Ox6Sr8AQ6d7)*&0yN#?+()?65-QS?@qW$;f8G$ zA2kEBO`a(z!{+7zZ}3o%)2Y$yZ>kJMJ7FYYA+!(asv#ao_%T1r^Gpg8;ILD8F|!OV ze|K-l9B$PTf@ysl??HUKS7X6Q?9`Iin>*~*dUPFH5rh#kUGNwbhEzD6f-JPH zMTjcxEbdOTbE2${YGrn&n*fT|zHI@Tj8Gx$?IRyre#A}Av|*u(BO=8+0ud0vLY)6B zN3>QSETPXuKxXd7@4+_$p1;qk#uCrCA0A1xXxn!mz?+gJl{` z#=n_Tb&|Am@b_AlWNSejL^wlMmaDNEB=7WG}a+@i@gHJhbDRK_OvFLRmXSs67;Tsiv$WCYa>=&`b+-XzqB&d8S1RKs| z@@S>4fswbf5B>+7`f5Q6oa%Mceejz3T%BAXGge@g4`wC4#~19FnE^&6krPnae_w}(q$-n!)*7#YITT)SHO=$LsU+7Rk-p2RJ2=*J~=B; zON7quZt6s(?o+^{r{2sJVYuNpUHSM6F1Y2QHzvFUvwrG*vP;Kllo=jE#>Yq{h2teH zMFDY))|*uSdG7w8c*NSrq&c)%Yw>+6|6qdZ;ms6&bLJ%&G}$NcI3bQ%>n8iU37^y% z;ET9(mpx2tHVJ$(f$LYJ?n7{{v+w_RJY5q*`RqiaSZ)3^7spBi#RgZBl-NoK>!<|T zGRTFBSz|j#Q+f0-l0FehGHh$QO8^*c&4`?YhF_@m_e0_ewXzKH%Dq<+rl-CBGuhy5 zaDA*)Y(u0^pUo;UG)7I?T02M+D+#61SeS=~O*%r{Pfa4Mg zJ?uF~sKC|-PL3_x0)sQK zprSs_W}4de2^xW`!|`>XE*(_UfK!( zmc@p#JzBwE--bHH2C_jP*)e2qjA1Ees63GwSGMl6BA<1ugPn9sH3_!ceb*{k1JdJi z_-7CeL}y|R5kL~6{>P7%DKy6w^3YCZ_MmyNyp^YS?>cE>Ce0>;emjBuh$wQq2RlQw zU^?`$0MNtt-l+TiMac20H&89aqm#@>a;tE7-od6|GGK2YpKH1W#)S4n$bg_rKuxiS zz}1*ewQa2)n20gF{5?3q=!W9m5)O|sB{l@BiJ0q0b$8u$Ybp{O*f81{8Ew3@1oB@h ztmZy6K5sB*NtBf_vk=$c7{^I4e6XDlbqM?inrSnyac3@Gr;Uc z?{E6&i33U#m>w7m2iaxI3)@(MHPDiH32Vz~orJ)uj)|Ce*&;quCc>s$oXm@w z4@f~+6Vv)i8S6@K+iatZO~uWOxnH}!mP)YTX{W6M6$We%RiHVYM!Z#&kOY*3V!J2% zz4X(6hD01GZmZCjsxX{kw=@P(OD3c;oU*WWwv8r1u?2&0=m$nYv745G9U_7?tPs6f zFBcQh=Oy_(R^YT?^I#fSj?2K=8NmAIlb7u~2hyX20@d6Ug}w^C1jn`F`+arpt;-N_j&ojp zo82=UCed@%!lseFgrE96b|<$%Z=DUBt-f&{t@VyrOO08^u!H!Y(0a843AugZPo13$ z*wPE5g5P@(r*wi=YrnA5*b7F~Fc+7?JRM_xGV;v10TQmPj}P}$%jlVIodN?!B)mtD z`tIQ3LBOX<4SE?YYX&QrAzg7j1DflM8PIURcy6-WltHq3Yv_znub*+8O16-}KD}{p zx(JizxO21@4j&F7W(~E;oOUsf%x#iDcV3N!);xdK7vhQTjk;58E^aF|2F+V*fh#HO zrTBwWtB!H2D1orx83aXV15oP{>+QI|{|wqWv#FT_MnBo967bD#$CQG^V=xOKbCY1dUilW;6LDjT^-)oN~};n5FYtJhArzN<%1xR}iW z*atWv@+h^mLKa!tr|3Q~4}RPVSQ#6cmK*lo$| z!883V=H#6x^28VN(e(4q*X^M?4Yr@86L1wM$tE}zKWyQQ!29kp$^A9j3@?kf#W*d4 z#U(UG_CA5~OGzA^iJA4O>9TMJzm7d5$E@a$;C3@%^fT+v31$2+A(P*Mtf|A5lQjcMH3N8})^L9T)KnSBG1z`o=SohK|U{CjqECz zEz6D0pRB8CM>73!2%MV#t0K%!YAaI^!OdEjG7}x&V02K=rT-oU>66>({@$tIIf{iRtiY|)(^e48ve1Ax*-d}Zw|==0a+4# zKu{d+Kjshz2k6Qp=77l{9ylBi`W<){tP%tAGaDGMflBHvGd!50XXvFjbK@#noE|J> z@f>!AkKvvvW>!J~pcDG7_^^=ff9i`nRjCSlhNl19j^{|d&@D;@Sw3&q39sGsG*}OI zTQ!$ryMDStuH*#dALwbY5FZ3o$9i1OOom5gH@;9oW0X+8G6s<+k^6QIj4+QrMFxH{ z0E&9G&l+&X8aIwo|{ zNrnmOAi(z^X_e>Cw3d;#i~1fWkM5Od_7h@u)y<0326T-ec`e)<|a7`3YCe4b9$DSwN1eVs8PU&nmk$lWg zMNy+<2ERvh5&PLt!$ARyo^A~&FCeWA6ys)x?1RuFg=weAIFA&38p&&5w#~L$ab#t6 zI|3kvJ15^&i#4MM@rl5lk%hy+|MEja!G#%T1I?eyoFY0Nd^Jh4lA)&InB5Zh@#x7Y z@FmAX3zX4bp zONtj0GTj!IDQ~H1Upwe{>*2H@THE8(xd3UmF(dICxsYi~p&veg2X_O(b zVjr{UbF6W*@Q|!FE3jH;&V{J&>_6(>;QFm4&N;NKxY){|9XZ&jymHP!k@&i_TI(xo zw;4qB+)tZ1bF+{^mMi2#m1?{WJ(W0y43LXYkC7G)%{lYAOXz zNlh_3{{yZmq<0@3btRCvP@vLvfm?Q3o}35?RW36ErZl(L3Qi3Bx+O&JBvK7~q0X!u zn8c3PnZ(cnD{0c!lv^*Zx0gCDr{yx4`!hMPkR^i&%f;#!i+e;D6!}51L$^8Qz&^4SU zAB?Ajv2`?Fc_X@Nz;m#?ZIlbU(cRZ5Ud#5S$*V`~_9Za#Q2E)`VmuI*`ADfk|A>F#wguk5 zZr_L!Gn1SG?E;6A%$)(h0&5r^ElveKFki4YQ60l7#$KN|QEm6*MAfR?5}uBQ?ZFl< z0|y8!9k?ax9;7=W^o*pJgSWmBV7+~qbL^uQt3m4z-pIz1-;15dmAd8WMleR@Bel7f zUM(2~fPezuFlPEXiHP>JV!M}9u)5o`d_%p zvQ@ZnpDrE0-K60O`d@H^Oc*<)aZ|NoAo3Es)5^fW>&|GUobOfyuMyNGY?=7wcI}jq zmRaxyq3znF#nxdTk9&iX-L zoa~a+Ga2mq2qKdG1&GjxCI&_tAo7ZLSeYH974fV^N`6Qow-tRzm$Qkzp^5Dl&vhLf zT?}IWrODg1paZ18$pb5-)NaT)O$)$PlHiptjzU-y@I>P` zOq@Q&TRpnakfIXL(GOxMkCAd}xWMnRXE@#%#Ih?|$$I4Q;U7bTp3+MFiJom+~?7=&%oSy|;m3WD6iRT86_Pc2Mq6A%*4x z@|TpHT(CD&;_p^j+=pQ1m2OC~VmIRaC1ezAqUW)6cqZ?GapaC7%{XiE=i7K_s5U@T z$#8Nj0n-o~To~(24wBx6!%_#ol0F4?r*$gq=}oG&6cag_5SztYl4a1}`gVu~0({!luSAPL>GHQjlZ_bn z=q$@WazR}kW9ZCv2etgqRmayV_XrKpqa)D{h?}D^=dMn-EERLbA0BCp(_sMqfiBj1 z2W#Z*59fHaJj8g&%oNSqFY0~K?YA(PF1A{oKES?etf*}YmwCx|!q%_sfKVt&cW+)h z)7#q+y=E>o`|w1-AlHY^s2kb2M|-sa00!yU`p7ef}`i0p9Ar$&Lhe7@$X4R#f5K?upW{agb2RyC+T z)|Lv_yAn^!$ir5A7<%mds0>Aw`mV0HgCvP2fNEe~!Pv1S^KS-{-kKxh(QAR{iHA;~ z|CpT=4AZ(>X2dq&)x}Bl zz-d(nFb)NWBpK`q*zz3Tr#k?$Pa`4tvGovlDERbQND_7bD?pTUHUS#rVYe15O_yBqXeus=oBPRNPdDx zAHe)EX^r*-bA?0xt&ruOsqU}T29R~7vkP%xL^lCoc>w7_704JOV^MV@V?63Xl|+8k zl?cwiyA6JFRd6O=PTH#rHVwBcle3QYuW+>;(T`3o#z$bJOej(qA{%42A^0leu9%=r z$K!4ua5>DEqms&_D<@y#Ll!gLY6u*P7>MHNBu|Xj)oYR1=n9qm9CZzCn=N%3c$$p| z5`5s%B>>GgjPS9fmmv%hC?y#`AE33>ZnlqrzEtsd&^M(-gi7l9$Wq|wQngvJ^~La& z2cZ=$W&%)rC`5BQ#8S;hpOla-()VNgS%Xc<^tlJ^gOGWl78_#d*)AGu8B7gD zI8y(JI@EpfjV3db43cV=ve`i`Y3GCCyY&`PEsajP)D*7)?nk%n$?G7gAN|wblkhxAb)mZB?rR{+4WwI7#K@>sfIyI2f3gdJZyg^72VfSQ$O7ugxi?AR{ebOGd zPD6+(h;hyJP^6ohY`#2L`DD~?dCCyH4bG*igYYDs=wJfC+U&@qp8fS(Xa=Z}VWUoI zKXh3Ub`_kKVsEKoAcfG|bO&nnvX6@0+*caF9)1XJk>zv_kCy4;yA;%>kAMjWUOJ9{ zzJ>gj!{>@4!>nPbN`1&U@4{aW%20sKZQK1 z4ba%##&t-=^1@!dz{W<{<^{<^Ne|W)G&F9H%BL|?lT8~GsyhL&n~UkEDwRN|B%!_3 zF9fJrROwMC#E-bD)_iYnd4j>52X0MaY|Wo7l{e|o>xs}J*cA1l6Zc?v9`4<7aMD=q z7!U2)Fx{nM9)0Zsol!REH~yB9QovN~jNI}sHiE`q3XWU!Xrz)TY5<}5gcSy{aCFei zqrv}(E`5h4N~hVJNKuLJMHy_~H_R8zKaNxS?|(t9PbibRYOn|(zl9)tQa2drZU?aQnX)J!O&;C~J=j;}RIs?+5!bBvDhiLxCziUK(9$At}zI7bDSyu?Ruo-jWhFooy>aCq~h~ zMD)V?KXCLcD7Xqnhs7134;U8^tv1=#x-<-vO*~E~)U$o9XCrhEXBDZB=3-qPiTb5V zLu09^JdB6+R12%}jhjN5J?Nm1AhLggNCUDEgWV@urK?M;a)YV@SP3S#MRT)&+%x`% z?X@wwWdAl~m5Wi0@;gw%Ml}ECNk0?%bv}#7V+PT+lnoW;W~P z>M(e8_F;-~xI9UdS)80`RL4f}AmmG#%{XBeh>SUg*=a8k9jV?hpC1BB0awEvhRKq} z*-AVi{kg3_GvPZZO#Ev9_ zW(GVMZV%$Pdq-F_i-E>I{34*7%GX?ga#fG5gT$;tDQdDEGZ?g~W6qJ-f@1d7A@0sC zuO^;K2%ld8v?vXo=g&7XSx;Oy6z+n|G=|-x9kgd3Vx4|}5eSa9`MwaR6ey84u;?4F z7y+E9YqbHDEW(}cpedYQiee3P`FpLK<-liNknCiT2`F~LJ5Xa>^307yOG&QL_vPpa zFziHv9#_scO`1Gfwm-PQ#WHH0KsByX{t$KiP*fn)IV;aEBaPz(f1IA%#)kf`@2k4D z(p$#<97B%-31FiL>!T92(vGCy?D;jIb3Sc=o2=zx(`_uPiY;5}oe^l%6>KhI%pFM}j`|NjPj=t#M9^6#J=wg#6v%uu(6w$l@Uo|ITb}tv;sNY&m#JEAjQ2 z8(2su;bn6wI(=_V$YC*PTN zj-uDDn|otvi^jJFdevSTaZ1CXTZr3V54IUSIlF74zYhWLK7G6Y? z$eI;U)>oiQ0+a&H$d`gxpzZdoXwE*?cSG>yKfzoGaVfH#-aDb{W=l`#ph9yXSF_-U znatbU_xLshx`1%4Y&!EuRI0%|1l?qan@DcLuh{P^&6ylU&@N;=UX7yhI8~rgETXTw z0G_&CF`q^@MB-3<^o+PWF4u`&lv93HGLW4eR5+KDF9Iv~0s!t>bqIz!2MsQTzCIN_ zJnl(?=o8+>*q~+?kDR5aR6+Gm;6U$;&>-;qtpS7H$g{Hn4H`QK7Wd>j@F$A>cghz&IlT(tEt@(|aBCsWw-Ro#oM2?l+SaN!MFMXYOGYPU|e2 z84#^b-=vv!`Rwvfg1l(mA=X74y+V*wXCpO~#-x-t+bNFBM<;#2Y-X8lL6}#idE%Q#2;h;U5p?>yFIFb%4WY8D3FMD5OVm#aeAprlUavt9}N@2c-;mb zbCvCt)6FMt!y~S$ON}}oj^-ut1wV3?p_f9#ZCr^RFS$^n1`GYgQki}ahmKiEbifCI z=4$6bof8K}K*ps_DQ?13Y7d`Yu7VNYSglR`HZayGOScG(fI1HV&7VE+7%NY<1zipv zdbq$xOq|nm_mm_nRLv`BE6;)`orkZrS{&h-7oZcYJJIwFq!n?0`Z{~I9Oa;~@8Bm0S}DND`7oByk>d~SW@YVk zGD9vJ=g|{EyB+pXrM<6Cs~mK;6bfj+#%;mBTtZO-gqDjZd2k~v2DBpB)9^a+fH4c;W zk|N`TQG$6(A~-qURI}mnK0QreP`99z0hcT#2bY%pF+bUoLDfq#Xfic4&WzGh)jWFP zg{nqUeIO0oM396FZh!(p9ww*T6ax73fX_iS*jfb1L3^~rJV#p#z9nE;GlG9b0zwhA zH3J^W_}HUQOpfg+x-U6qOf*ap8=RQ6$=5l$w-qcdU@Xjr^l>ajcCL#bC@a`y^S2m? z$Al(g?)%iNa2wlap){=rQP>j0a4ps$rAneSweG>vFx_k`HgnikHe}eOlU95PvzZ95 znz5+sE?V z=R|xVX(k33SnM+M=rDn*=6YcSQS^!BvDbmSXv#9oVWnK(M9N9J51 zj#8+Ma!4DwJ161?Ee)TJN^Gt%eTXZr8rSiuaMdSn%)<3FTP;;b1d~1CJgVk~baY)k zdS^>Lgt2OTPP#)C>eoF}%H6OVSoXO@{9ob7YcYkhPLZIX1e}?f2ZLxa%q*5FA~NqbGC$oIS8!I6-iF zB{jVjxnC|jOYa?$1y!7_)s-=iuD+f3xfH{o|5-=KTCVh=oU-8`&_}Uk?2*;zBIIZ@ zg-P+(Kaa*(VY{N$)oW1l%L-4y2UQESJ2zxFiG63kL(x`j% znIN%Kqa?W)?^^*TDU{ecDz>7WbhER-Bt*Mg6X!M>xOl$-XR z2#(*xvu1#Pqrop8kEx>9T#^iswZPAZv5wn3$fW}4-$qO;2YDG9ev;+BECp|*27q4z zm`MCuKGm`c^oJ)Pw--s74lMEI4$XvshNW;hG)hU{JIlqh_P-3OV+>%g}$+@ zXvZ&()d-1k<#e~X-VLE0IGh&H_Nem;yY!AS)WXV3X2!D&MXT&r=+3iq97ju*c`vlM z{LjY-MpTWci9kw~aQg0Ts1+#dP4iRtl`c`O{Gduz` ze%S$Vy-w!^UK_ObD^EfP@optGe0q%vU)jjf79hsvYl550Ubilc604jgsK-LBh4x+A z@q>;o3oCWGtvsD>$Tr1~X3!^fvzBd<9w$~!^K(047;je|a66?FakZp;KnoLQwq7TQ zZAuhMm>|3Y&) z)KCfv1z1ryyD0(-ZFaeOW^ppF)R8b(m~R^#2-Kzselhv?x{0iG*Jm`le=~pz?cY!l z1F1RS9Z2%5D57Ay!jWY|ozo=2Phb-}V^~x2jXc^L)-f+76h6pGFMBGWj-cYKAQU>L zY1=#R+}nE2h?!prN8Fw}0IA=tBHCpeLCPLimwc72a5M4djV?nmF?~29r^THnqxrZ* zgjB%-2jFDCH=C{R(NUmBN(@Dj!*>DKiRMGgYoyK|q6Bd3QRz(Wp9$wEP3mhN{jfKR zR;ziUd<=NSk`1v%80K`+8&urn7zDzfwpF#Kb*nhVW}a>XMf5b#4U8axr2huOA&?XL zXnmLA>17&wv=6rd_q7ut-3VI|Ck9kLCKTv%t!z-skIsc_FSifpOr(Zt=sV5m(1gwohE$AaO^SkDK$Fqp z{ZXJdBeeMG4j_UOD$NX+Xy#H2bQ?^%rr^vCjBOFf3Hwi07i;>$7og{BH8epTz8YJv z3UhDe&1w&FMzZxz^ZFujW~d4p!Thq@C!LRaNn2sCBjc}8rz5e|)dza~xI7-+_dzrT zK#MozNBKT9ZWbQ*JzQrlDL@*F&(@c9@%uKzR8d|LeG|BV$=(+^?^uS2sBm5M4YjQ$ zb}IHk8kmE=xyhYJrvq1WDUs5<_&+y*Q!b-5O@I#RwZbjOkkBaNgnjl6T-w?gA+WUkVxaUr+H2_m1_+AcB!871Rk$%!>D$q*5(n!lu3EDeVic? zM@_+hs@P5^eS}lWLtQ#XK&OnBWKW}jOi5q*=p}gvEzrx_1W?|EPS@x@D^HTV%bTi| zjdI3+>2uLAt4jZs$@LV-FtU|)qkjhz(CY5Gj68Ujj9SmrvPO0uN|7p2QyPK7Nb;k< zn3GXiPa_rth5Yqs6}FaEA&ape2GB#+4g3zeplAgtGXU)If?eVg5;j7?5F17ozXn|tG%OuYaZ z^Mb|y6NXWAlT9D_>vH4&n6R2$>{_wOCq9&>=xky9+)iLiYK#FZK!T%Dd>rywj&0 zhA5}CDgSQTG&tXu;2qf7SSGI99H8J%$0SGC9A%LgfvSYSr`$!=1+w#_pW>g&6zi8> zI>x!)o=n~?IBC#X2Jr&az+Mifxvi2%ev+SA`bfyfa)|-->x<3W#DxdO_6Shm%Wv$_L%|-} z+#SI~PxplGQp}9M)FA6LvD|B`h<3SV(?(D7s}pcQTTQK7rj12Pawqe&bn>u#fh7GQ z#w}n4mgEFR3uJbTjIa|H`ax22nA?~i5Pq8j+xx8T&ueA2D>66Nut0r^p zi_-Etl?}c|uq0okC8vXPW$&~hY??%J?^-^E(hMZ1!LlvMKBzQ>SJC4iC2?}R*>KbV z0_(pvpbW1h$S_N->pH6>=hJ=ih%o=e8W^r*QtpAjPy{nee=|B>RvV~w?Y8q^9Gu2>1 z1E3a>>8f949vuJQWyv&c)m@TXlF>66$B5PF|FZ z$*qH!p^FDYmVkZx-j#+WS*kgIql~<#veyrETqvxVfwPM2I- zx;B>CsgAl^TcNg2L5GYlY5P_91I;?ykHQ8_ z0hQA)B;)0NTh_2%xPa>v&0KG$mY&fpzxv*#!~cyUkRvIyD{NAq!Wg+T1EJ*9%`t|t z#t6w)H-m2=G{|r=3*k!N+*qD>i&ir0d(E<*&K^*gi3A<{7XJ6>X6@B^#OUU&t_>|o z>9gwl4}nw5i%ClkwoW|nGMUP9uc^~W88tfzxklSv5-ipIZMKvDgFovBws$g!eaQ?o z5DkIJk~{<7IN#AhZSijq3bvq%M*fYCqQ_mM?zy)0lUI^n%=0;S3e9LuI^^R_44mvA zlY_>&_z)IrAd*6R(+@xF>0vy~l*XAltxHQHc*6h^p1})+ruTNBW*E@~6kn78S-a8-12mfXffH6njEe zQCt-|WXPlGq;JJLPCvN>qh*YPNK(-4q@qf67g_5Y1t!Ht@tOAxt4dnTy!ew0f*Es{pDaAPc>9Fe~n=19Unx4&FxjF2Sq*YQ0Z; zih4OyNJ7N6(r|L`HXsMN7;H}yMjHl7HZ}A-K_;5QEh$Y&x)GJf&=EQR&7f9Q zFI(b7kbl063X5+`L!>S#rGWqx87s-+(3dq1yw2%{qyR?Fy{mYs0D_7fPYGM|FNnaR2)fK>;bf7?Ig)VPuvw6x#W{p(YbfMcwzx#I^3qhbJF;j4=S|n|fN7@)ec9{6Dp}K*K-o!s(RWazSzW+ybMd)t7Ym!SAg0EWunIPy{S`^Lujwj^K7;A$$6n0 zOVrB52DT8Lfu#k($ZziQrfjU%v>&|vsFhl4sx8UsBn*716K%~}d~6w%P?8Vc3#Nv) zG-xz66jpxl>jO_D`mi-i*shuaa<%@v)*q}fT#IeH@L1(^&1nwSwZZ&N?I?K+9cotA zXuAK?e5reSfKexTZUr<^ozRTg;}_=o05tg?&T=Q$D#=e6Ugn{3`SMX|a#5F9Y z1xpzaw0%o_*EDcSHj8^^B->6$if9-~HWOOY++fmSHLmvmd>Pexa{MY2&E(!UG4h?u zClh4*dTB+^=HHVjKY)oNM}ak%iy1=ko3!4N`&7r64M_s~tMJHN>Wuu5wh89YVpJ-m zKjfx%`uJ2E{cC3MC8(VpWq3>Kxnj`8J>(OQ@8oS`SWub!V!U^=EHt?xa^afr5N!Zx z-?t-dT(3uz@6FBo0z!+9>?EvBROI-BKuJcZa#lOtkW>46lRgx5ovkq!MDqX|{Xu_6 z|4-5;;R9Pfre30=*1T^|K(q;dQs?0@Etk)7! zxjY3%XrlKEI*)m}t4_)X)XguZLafvmpn53aPCC)Dg0My0?8q1Y`R0~Z`=Ne`E zLYhu(*%uHVFnyp z7X1#cs;`+CmpAp!7VG{YPfVH%bSXsfC5();T?nVr-g^m@qZZrD;u?u$$qEbk<=Y(z zsoq?&ziV}&|F~Wk<@<_)TsyiQ?27||cXXd-x+XI@o9R22SLV_NTF48zhoo93`;!p% zc6}1_CajJm;Ke)cz}3&r@hxYPE>c1ZN$UY$*8V=OT+j1T`(xX2Aih>eBl-OeGSF$I z#NgvWoLo||m?GI}7zm>%87h!|Gb2Dvv(u3UyJT>(Lh$AXKTVt{`osO|t?CbDi->I! z-&;VV)rZnfLq_K@^DP^44_3B$UR%*S#5zj{`$MJNm<%!_UAMpwMtLfh-zsB4Z!L10% z3{2EF)CMN3h)NAr$AmJMOOAoaIy3eGERS`KGGO`(T+W)FlMQMMJIY_Cyj~l^Jcm0Q zN+}Oceq(m_lDPyu{Za--Mlm@%g@4%^#L_-6c&F4_i{)B(aL}ELcywe z-7>&Wwb(|EW0iP9vXbp*wz-~!9%+cN$f#es?7<%@b3D^pP+eO!>F3+|N;r3=ZK5ojy0{QjHy|FTm!r zO#oWlk3VxxqXMLFQUcM613m9bpQ|!>+n%{pW_im)d7jFIjbbDBO@&!E7DV9WFFl++ z-l&~`g8$2|CN1z+>ngBj&HXLONgP4q%i~ne;*kv>vqgI6+Th%kqvK3MgbFdp*@l%P zXdJotVfju&H*h%hv1*@9Tnr%F-yRzXXC7eOx_zCzRhyRdkfW6fvEB@W8^T{&(tIx! zTy|g95N3({sCIpXmh?war0eD;lQQJT6DPCH}( zbXujDS$Roby{1@rTFUc-(YT^r`X`d1EvpI62d_=}3+awJufkG&v}LI2bUdC}Bl z$rVp=XX!X+5*m^3KG?k#ovz!x`sgGBCpkEi3DymF*rY13uQ?z7mT=~TN` zMy8sclA|>mq|j?KhU&p{^7}a5#m>{kx|_5iM13ObzqddFZ!SivzYXEx zJ0U%t#xGt@JE`BVkfX3G`hcnk@truu%OA2DWe|p z#S}PcPTpN!NxE4tx!*Mitriz*mgy9>FUNZ+W1B>BS`h&6P3({Rs@&$urs1X?5`x@K zKrd2SW&#jV$EO&Q+q3FYv9HIVU6Zy+YQ<9i z5;uc>Q!;<|R8(mF+L<4>vCk44B|IQPvQb&c3sv2TgfTT!F#s;~SK28g>P~>sy>!2t}K9RWy^X#sW znXMA?bU7LqAT*FuSL7f#oc*>$%;ri%zDYit6N(zzlZ&{4&MMHfBd5U!Y9w#DnEY8h zj^q7>xY&Qr>ZzPS&#uz>VdnE-Vm1BDi+v&n;n0e{+N%aMUBVzJx0-G`6>rAq!MANx zyJ|(yh$ep_#mT0I*V8FxsJ5}Oz@;S5HRnp>f^vr2O2gIi*U8DATh#Vamq=$)%Tgqm zk+KuIe>>Zb#PuyexAsk-G=Q_@x36^8bl@NPSgel98WsvJ+>7>#jVD>=t%**klxk_| zMcv6akfZ(_iNdVl>AaEXqPj0kMLa_N7jDtfX33MWGcauAo+B_`DigxA20tw1Uz`JZDlGD8+-Gmz$<9x7k6UPD$hmC1m6mC{W1Q)Rqf@?Ft)6Oi+;V}OKF!fz zDjXw&0#m!~6-#mfO3jB<3$G$yMeUD`j)5|aO>B@m+15yZ%d2^98ejG7DX`3%F|3SU zpTQt|E1`}|c|vt+rP1A8=60~aRL~RDoyEb((_(uuEKlWhk}k#N>QFtjJn3xv@^?%{ zSh2mQXvz_6fj)5lw;inZAhy!%Y}p->)llK-UGhBM%!zQ_>5X_Hx|{MtD9#a}JjIie zo1}7pMep#p@+(Q7qBD$0jjPAa2|Tm_xaN7utA*rbp2MrC%g6+hIbVu=+zzeJbwh$I zYB2h-%CCinod7`(JOa*c=`kjuM}#Ur3?NPr)k8I{TXc*Nh`Z6#Z)A}U5TTTP?`;dI z&5j1stg~g7)uTaHSo1bQRY5T{btGTtbM#2}ODb5&)*`|dl zekE$7Q=jADIXE+a=I}a`rfMFh!q9PBD_?fz9l${Eol3ZO-~~>{p6`T0RBw+g%Af7b zo0$~RqUV;6P9nipfTi}US~Ga)%Shz_XiACWBXmY$UU{SfpemzSN-8|HHqs#;Z{!_w zVC1*tvBcn&q3~bj3TA2s`C6P(T#_H*)|uNRzlO*f+i2vhzanz)ka_5g>`qQD@n{X= zmx*rhI|9r%-jpSLCr`Pl2=^}AvY1P!Y(PMx!qf46D+|HMFkbx6?-PAIF0^ z!GIn3E~r33Lw7oP9p`LR?NO=`uAs<@tRXC}u)>f zi64+7nl+RIRyhN4MTSY2MA+Y`-$a?8z=TW3cjyQJ88e|7!jpa$pV8yG2; zt|`5I%;EOe20>!Jv%iR=VEF|)!W20~U+br+s!+Ncw=_~sqDBm=X!m(Z_QEUChpfvZ z*kXjATmvVNM!sQ`T!yvgNRtdey*-%>p6LhSYDV9w%vQ%{lXvmmUO7}!UX5UIoNwp1 zKUy@Uw8GGYyV%_bAXD+<)fZCRAE+)9d|5Lw9%K|fk~q7Tee{|uw32*)<4*Cft!9Jb z?RMQr#*0kJ3#F*FwB+QnK)wC;KMHg0W4%LFEN`j z8Ii$2jOhpycNgtzV?IleLII$brJ2)cCpxXJyJPYC!vlE+03dofl^1r)gV2mi#|I~^ z##;{IF`O+Xzu?b2HneR6>Uq(dIxd|-Aq2YR@?f>=q0xmV2W_}rGH!4x&<8>v1+cAT zB+uhqV|-+Ia!Afk*bQ{$F318&Zn(7GgR*xY+b>1@KQAhzuteuQHi;z}5#8&Iwhb~dL)ND@3vCxK+#U>J((<}_R ziC@ycZP@4BTBOT0b3>H8-bABL1z^HJgB)3=cGWcf+AVey+Nh7|y0?GB2we~JlK zXo$K9BEvv6r$A;SnDS)R?C#TKt`-S*D(s8)v$^1#E^XcP{Geu3%5)0asY;?%p5_*7 zOF%=ftziVc?|W1U2(xyi#fbStBAAk_xS99$Q90OJl$&Uduo;LH$jgC*;MMO*k}~w2|KI^HT6kS zf1X_(n`%%ji6rLaBGI%~hjSE)lOEo3KI?WDBS&Q?o-01=nRLVcbnn}sGp8h95lLsf z*-@3wqvJV~{Nd{H29TC-b+ZF17%YPE;Ag2jLS+wejYh$k!Ut(wO!LYb&X|_}aB&uf z?Er^sq`fR4Tawp73fB3U%po0^?(C}^K_p@$fxrnhk|}M`kjZG+!xzIjcu*mY)<{M%Q>JAKG{{?3*JG*-{IRI= zQ3&}ev~nsN?`H<&*PCo+LA)gS%mbpc(P+~N(1mpukirFAioVB0%QW;wy<0a-?jmC{ zkI&+bE;1y84bb8if50l%&{~@Q?~dElV_{C`V-fqy!(K1#U=_MSEmm+3$G{N}j#tJu z&^5*?3GHF8z`${oKpNwbtkXnr$oHc`mjASCF<#CaVjGIrUq$hxFtuC<^*cytF&+Zm zr1>0YaShdAYH-*aw5{_cQ4)V;TAdJB%Oi zfsNLb);rL$Ol2WtT@8?^s;wwaV-7%omdk%>6XZ%)=^lC zp~F?}1k}^Bj`U-XM7H+A+qynaQad9O9_b51{nah_1WB>ZlTVDZBBAIuHPvZF4xK{b zKgOk~Z>)_`2|GxtJ3uXeG`J7xF{M{jM>MxSbvmnTw?qG$$g7o9StZewue~rlOhb?A0i=d%16AgmS6$M(ZMl3F z72r-DK=l8`~h95 zfT0Rf$6U><#A2({QO5LyP!estY)&ApF2Ii^h(%uoXqgPM4h5ZU)luQuLsq0b6I&vV zm}$MoVF!fB6cNT=j%+%{S+JluL_LTm$uP19)`>^0^XH{9Ekv1`e&$Wbi+Ol@%2lSY zOGNJBzuEGuH9N__`0FbE>#N{j)9SVyo>6|lyKcV;ar}fAm^Nu*>Z^G}-Q8F4uNK{{ zrx)CaXhE%7K<;eWjZucAWE;~lJCHB=yz<-l)4rwJNnXpVmAtI2uUXgKL0+r=JC1+T z*zFLna`}-hZwF_E=RlUM#w(P&&FT0$|pIYuNH**bq4#q;*@2{s9sdmH|>6a&<_icodd>>-=XN708+aBT7 zJdo-y@dJND$o}Dcre>yHYxxVzK2}F6jqffXksxXwB;P(vUt2(_yor_+eh8?1c%8+5 z-G$V#G|M+>8|C*VG==^c4+_gLK(tQJ3ptT}*7kvA#Ukb4lN3vEEk*w88V%x+_8 z^;oY@$s^eZ{~T=9_nsbJb#bciVz(lrW6A!`(24D-AaGbFO35HlHQ1QlT?6GLE)qB( zr?S$tVJG&21&K|pttI@G7IP`u>Nos06JKen|1;6nUPPyZv9^54+K2B)8vCqUKKMX| zW9yd{dvcPK*HBB7yOh&?DJZno74w?LQ%_lEU zYyjlfHw$`5IL>uDn{E%ab*ei~_q%77s{76|NVTp{_gBQCb)pH!28XqHnrnF)HG(y& zDMPT}$m9@p{dJ}-Q498H$StlRd`RK57q3-KPsbNwN7VXIjo8$U*p^#av{#c|PI#Zk z`D-giWU4hXV(VIL*@k)jxA*FyOUC<~LyQ0&$5 z(_P0TrX%$asTCC=DX8M?~#A65x^aU$&IA<%w|4D(_EU;g#n zoX2Z%tABEFEA>xFIU~GZv=V(giZa+F^1yfpWC0|n7X}D{d-Xe+GH^w@&;d)8V;U4U)yT>HWj>eTarGmHV zHxh~3jVgkce2-gn!@vleB_;rDI0uT(CG^r-lT`TGI|DQ9asHc-??53z;O~p!^96u$Z~q^SmGn$}ms+_W}9) z4|d0O0g<~gTO1jLqOoTolxaT5Zp(L9tK6gNOB+GBSdFR*nOYFGdJ&<4YdK<-1-?X? z(|rQ=raOuSn3RkC=WhD?^ApKB53b$}SKDtbW@UYC5Y*%fB{ivyrU;B*l2_p685?6N zwbr!HP3VHPKIA~N5#?LQLVr^ueey#fMQ6P>6@oMsbIF5$VcYEaXY)jjcACtBU~Dg~ zm0{>(>-Z}*#!qE`N2=BSx@r?OIh)>?DNEeZEDSjYv1c5ek=i90OtyLmbAe-G1+B;Fu6kf9k(>?XA_CK2AjAf zM?FuUo@RitfoBd_1Vu8Ri?6wyq;R-i!?^n_R3uL&NjPjTp+Ap3k}(bCuWUYTCi{oV zqoc#}eWdaU`dr_s9Xfr<__2A6YPOU*M5 zlZRt}xg{?G+BpU0_74EJzBA#^1$Z^PAdv%Jqjtl$^dL!k?>jjBh6^0Qs$4KhEx8ut z{1Xyq$LXGrBf4u#dXuALvm<@}wQwtUYJHdGY;Ju6N^PTji$9q~YbPn6gFFk}WoKP! z5zZ##l#=|86GJ1c_wEcS1`G;AiK#Y2 z^0I{d5xUP!xJiR^U!uRJ3NQ5M36%33GdW~ZKt>>4>$BQ|KYkB|x)cU4?>aSL?*>xw zn4H@ZI0T<>bfk=fL{Z!^qa!S2$Wr0iHh=X9RO#tiJ3e)s^N_sM+6d_yb;&90nimj= zgr8y*xL2CuJgG_r(yvdBS2cUgZTA0GijyOJ7ewz&%4x_$k44GTkfS(qHgR_lk%4;0 zZf$Yg??|W!xqBH$Xm}_;D9O#Zjm}98eycnI=TFV#s%v1*lT@%Y569^q%6V~t? z62QVQnw5+@Ax~Kos9%$AkK$F5bo+QPN6#kMSLb1hxi}I;kft2S9m%1iH=e-C$w)97 z@ut$Q-Xd;#x_)V919?820mREL7f}%=_WMw3?gm|&#d!$}GY<&^1(Nsep#B5v+Vxe$ zOpx2LfO|O!%MyAlykce-u)K9UuFGK@V1lb^z+xDQM+*Wwlq29JpVH^^aQvfY@p|tW zlbh|NOyQTj47-!{#B~D=2!v(l6$a*0@XunS0jp~;9`A>C6~g%r4Hc z0jfcoqipNuI*UwR&p8>Xm~F3c1eUfebLPEV@mx+Z3E~)~nnjnf%~x|R&wZ$+BQbuX zR47WMHp#W%hvw%iLz+xLIYykh5c%z{fR@`UB7XeF#U_ zo0o{&R(DIjq+*1l!^LVk?Wrr7ed(n_0`V=*+bO^rq2W-D)mIf4ovB>g`Y?z*n}x)7 zz1+qd_kEbjsg86fJ5lGG@EaW^2L;g@$$2!+sMcgoswesr4>sg%`6EU*`+`qT0eM2W zbWgR?TquCF*K!*G{bDqh6AI|`Yt;T2QOto%l)Ah*k`Y+``y&%fF3EmKL-hd?07IU^ z(hGghgs6`*$gQ~?pd0JM6f|)7gS_B4_70ioA1?+yyx7ExJOZl6^Zn_M|A39Wi0ie5WOR8 zt96>yW4;D!t|gGG`<&!HeI4fue82)kaw9)=M~6aqopPC05c&|TlSqx=qBjWK$6FGb z&0ODc#eF71I~NLeFqkK+j^M2u;KYCtajH*-_{~mqyzmDo%q)YZ6jqX7KnQA%$EI4x zAW2ZZAc9^En}+yb0g5zQ=AGj698mMV~8mD#trVA zg@$fP2#|AWMt@f$>cSk;=@8lt9ENvNJu_XN+%D3`d2)Xs@9_hv(z9)Y=n_KRB zJYP@E?y#$V=K@Ufh`q5U90I1e%*Rj+X0IU?jt@$mzn_Zu2_{%OuF5<~N9%n1?A%%79mP04x$W`3Q#`0jq zGDbpfJ;Wly$JVdGGQd zj@@$Ot^M_v_Tp7TF6aBa`I>PIvp7#l_UDog4p+Uh0t!+MFIV8lr^s4?BR|JzZL>>~ z{39nJJe2#zu8)qCT^`M?^=$el2!8W^JUxr|?8@IdzE;u^x0 z7qM~Ld#kA&l%f3#AV>M$v9QQEgUFzmvU`5js2cs7tok?PrtGPRa97V}asdPpye{d7 zmUUPd1JoD}o%OV0rd7QElfCYZ1!b2#h>nr?B+|9QSrtz$u( zeJE^y;{GHEm;8z?vFtUYU!!>2mcQqdgrq|3*AfQgJVf-wIJq#$@fJ(iN2yQqPUR&W z@!0t2>2&D|%Aq6Y;UI|685J#V^YvqpdVO*>d$-1AD?O|SYatFh6~Z}fK?qsBCT`yL zMC5=rWxLZIrc0<&3cBPmxTHFl=f8K?9U7>pe%x&_`)WCKDnsQO|cvCx_0YN40b3dBzw+;J*yHgp1;;^9RR>5ayDLx9ETJ-p6sFDdc#Hr6gDYr z-8IIqoUg!dCfAeQ6$@wa^D;sGspvJD9?rI(gD@I<9 zZ5FmiUd;l0vzy0}xaBY_kM2Ab*0~q+GqEBeP#3$SGwZGyaU^9uo>9Njw;XCxStx#Uf}YZWyr-Qc=4te8A~W=~-?x zuR}lH3)a(5(b9O$wIuo#SBc5etAMs<`X9{zb0wiIOv1qSp477TV&@TsVkb9pZyNnu ze@FjM5>+@2c66q)Ge`qHCr6O|f#}pQA3?fr9BUUX1JE2aW=cxVA=QucC7WfJsq)?fQKdO}Wkv^0$gt;C)oI^N&R>(e25GE3z1kB6ewbSb;h)Hic{z(N}Ev&27{4RdNtLykziBB}4~ ze39r2-^btU*?8rqQpM_ai8L0zpReVw0^Ul=wGT?3Aeqi!2^_MyZ)cuhd-EOL3FXmG(CWn7p zQ;2$cR@gv9Ypk1QdbPZ86t`;tkKOh+TsdsJ=|0tZ(Os93blnq#dWO6I{E1y_L-~A(Ag}J)nCvEDX8S0$$ za{Hs-Pntg2eHW43(-XtlT1=mefKvnK6zekMrVkxFr`EL)9BKfYCPDLJnlLpIqSKBu zpctOFditz56C#ER*I4Jx)HF6)>8&qSA$!6GDAoE^Wl70kqTc#3qZ2EJ$0q1XJuydR zindYb=aUqn4%Dhc{aySsQp0fk+1<0k26wUFtCDZ)m`CaR6pI6VGT3J&9m`_}jeuXE zNL!h;htRxLDm`7R2{Rs(mVG`7*5O7h9C&C-Yp@q5$Cq0AyF8GFRIvI+oLk_Krm){nk5 zOO{TI4%hm6m3^e|hD2O;L6l$KC-DBn-T>LRg_L?16 zclX`wMN{Hy)l}F=xA9=6buYjk@yFW>~;WVs4a7TKwoWoVZ5wTZfX_5BIgV^rUc zS(uF7^L+s~E=u^GsMinAYA~f5RRPMR(IN>DuxcT&Q_al^Hd!MNN3z&#@YLAyqA@i> zre&Qtb(FcJYM8LkPB5n{O{~I1XFHV_tvvloPL#QW$=qtWgXQAAna=9lt?n?yY`Ue} zePLT`a;EBcI-BCD&+oH4Cv8$-wrNhipb`@6qLX`2JobRu$P_n`p@EfsHb6nkY!Nz1frK`)uwoP317Hl0R|>=vU@0 zlCo(I{LO#dscS&dChJVeF!LDU*_u5-Z{le2Gbp3QL+BmSyL5EHMhWS}Oa4)3bSJj? zEnZ49%P`E|pICy2mIO!&0PI}+ze1PH;OfVRa}$_8NJeGT3H&jB{95g{Qj!~f6s({w z#TJi@v8v$onbYZzsy*K5?aR(=ONJoMEy)Ad&Q`}*CSz;=0F&|fSJa9`4OQFAgdGLL zp{c>klFdl?q4}A7YdkGmJ-$nR{cpHFv^$;GZKW9Vx@Gg9lcSgiP2AGHpQ#2tx*qPzoywlpw4(mvL78*2}H}5;fn&G&9^BwbN9wZP{ z`_pJ|uIc$k=h4w6x3j_KccWO}&yZ1Q_qexBw%_DH+gNzSl5HKRCun%gnA4Um%MeTs zb4{*Ryuo>StQlfTC7r_rGq`j|p3ODc7AuQn6H-|>oh@z8Hrv;x!MbQ-K11Vjz#C%Q zvFV;}i3QyWxL=Y3-=JuwM;_GiaA?ErpVm0G&c48oUQgEN8Q-w1CZPYpDfz{QfR}1d zxZ9o_kUMSq_K0)c6YbwWHR54Kk0`nbp8V_Svt>jci7~D@BQ6zaK6)_9{%U~wR)McN zo@j5dv#ak+u@cu`(G4{`4{+k(Wc}yxIrC1zs`dcxdGBa>p7hlr^qY3q31e8=$9<_`yJ%KJ13P4;oJ8zt zQ>~v_g1>lad~>r~l6Jpq(kZsR^z|&sZku`Bq?EXU@@hi}7S?M2`n}H_%S=Ssg7&nf zt{bUW2C5c_TdVDiN^)yGLlyZoRv}G|IV{@MQY?RW zAiJ|^h#NkhGn+hy(?b*2KYp2{j>cw%)yV6CbKkxsaP9(ppaG6XLCYoo!}dRP|T^%LMb^5 zsGE>DS7a6Y9h8lObz@%5>w?iA`t@AU$d@UckIYlu;N;$7niF#HW+a9#Q~F8c@@?? zDAtlFQ8RYh)M`T_COMJ#v|*>S*?SL!XeQUoUO*HCjOAYq0Xip)?1A#&;JTTK-F;;Z ztWq29=c(m#PGD$sbmQche1u`EF3;F4p#g4*!kTw=&DLO_6?Nq&7)xX3*615PCGA&u?2WoFb=5dPsbivwku zA7;Ly`luw=YkUUjR*;|}rw+~%x=I;VyKugIzTy0)FX4))tt3NmqDCxqE`uz;#_dy$ zef?I%qDb}ecazd)xj9n7jp?M;+hRd(6Y^Siz*_?D;I#75C#>jcYxKN`OePXq%ZVsoAN_cF?OJgQ&pqRXs zoBx6Z=GzAZjCRb(NE0A6d}yhN?98RDG26tC^vvBP6Eb&~`HJITtSj`{nE?j)Xc5*jsjZHonZp8JXu1B!opFDL^T{gY{K zE2%-Nh;%wIRsKolxq=98v8~LLxyTArL;kxhZG6Fg*8(C=XKl*V?kCf(!ARd z*_nKd4vZ9>c>{n;@@V8VV1=y0cqE?m-c7SPIuOG>q{URQ6;s(pf+{c}e^#3dn zMwbrZxNuoeB3<(!l#OI&Ro2rzcD!~v{J58bdFnfOO49*k^lM5kg(mXj-tb7>I;~|F7N)ZU%IsT*F2IMgHh(7^7bHb{KU7n* ztvF#hd)+srvsDJBTrS*?-jDX=bYH@fo$hAMY2KXQ$HkAwpjJ!oX`HI1mLxE*Tmyur zX?4_CI$vo?S2x+HT?>J-<{ms}!2b={LRA$Z^DC`}8=Bs6IKYM!hAd?=0LTxb zW?WIbhtUAZ`Y9@j{V5arPoKV($oS~ZP*iPj1ADxoHZUPKa*)B(^k?+1gl`ZTvj1}| z-;wqdvJ(f^682pAqd_v8LV96L(4b;kn%LWfJ=1P?cNu|GtCT?X)2H4g+Yo?H@rGF2G~@ zG)Y$`PMfe=V%=-Zg;Fj5wZNvGAoV}J0M=5oDpZbX-l8iTyAUCAM2)(R{*`0$RTO{& z8y(i@ZpIo+Ka%5v&x~Qe4K3A%l1v@#I#XK3NJ(*>EQBac?IS&BZ22YsH+j>L8av z9`HBy+BRDmdwr6=Ae-fwA13w;uKi~(O!Hz(@+R+t5J>tfA2h8cOR9Otsbs@xrn(|` z?o66q9)wYs4!61n5v*axO_gze0AOt0)8qoexozA^&45YpkAfTB-c3dbFu@(&NW)OO zPboeV^DuU_5O#E!@Lf`)?6RXLi>&cjlXxh%BzL~Y7e0<+xqEsxO|foG?@24ltCk*j z)QaO8)`g+GzlU3*lxh3jN{h?l*8sung)yX@m3Ze(7-ma#3OYG);R2(?PianGqfwu7 zQDV?KZ4MkXjqX?4osV8gEgIm$Z@BVShcda^^nGZs>ANBqTWNx|+SC$0 zwr`?BBP$@XlDzcGFtYF3SQ{E0?3OQIt+=k0bII!;JiA~lN9C9x#kvot zT!GYd3$~+J#yJK^CYJ6c`Im<4lc$T$%~D3z`sNFxw1-g-FD%x+cXVx}T3V&`8(cXyAbYe=A~yQ4$d>l>mg&VB(I8O929X5E~r{_o(BswmU@=5z*oij-VbpmPrfYfKtdg%F@=1T zywo-x?v|QT0UON=<^loY1?ARd*e6g|dc#iSYGAVligth`D%kSqw#Ja#s_q7EUH1jl zc)I0Sw|-4I+S(h*ihRnUr}s{rw)g)#@l+pMokasVcVLS^pPxn8${K-dRO$<)-EFGW zhjG?+zIGa@^tMw#zv^`%ETWTF&-GTUR!kN+W3E-QbyWM(VY6f-&aGUn_8Fu5rZl@q zyU+cJ$4V7io}jmkj}r+j|M5}nk~$CqbSFP#wx2rli3Kg!u8nz0az#U;-t=X3aiU&@ z5`(w{&jO9j&Ry9OuTL^D153gTVlnecfr!mh*;e_#?QS-GdA_xBb324F63eoar=zO<;4HZtb;yak zQHQRkoSJ-cV`IoDe@z`6FI$UGA{ohFtz+zV^#MH|dB$^AH@zd>+!81<4t2+s8qG}b_48hIh zWdp=;kSi8TQAfAH5APWaaNLEYN8h|)fj?IhHk1Ob1J&?W$3!jcr(FPZAc)p2JOdMU zx#iW4j>vhM@?(&teD;Z&GSDv{JT+jp-8!9qRtl}^=-|gi$t>9D_vr5x=CBUx&UecO zg&Tp0&!K}e)d})sz^522>6$AqeXr_g-vKV}2@$)~TPvWH_ohR*;k%K$>kZuIoky5t zfOzp~DRsFsuIa-yN?P8{e^oH6)c3gxs7{Tq15}1iE(W|k<4xWh^7SNPEv-CUy8bOx zN9z2T+d{~5n`H4gzXg4JcP45XZJ4_Ag*_gVbmj;F&@VguA(&FK^CuL zu#YEc;i=%nlB3j)S;OFU^S+2nK2R-JwOyvHpPxxASBifv{;z9O?hR-Aby^HWdim1+ z${5IbNnU$&fE>E#!w!c4TlQD^gkF<$MyKta{3PNZBBO^E*hbpvF)^RQLGn0i&QGtg zBk6OCsR%8}>;=YD6Y?Cg?knRAF_#bL(npF61bSw!g6{Geze z6CucI)QrI{Od^UUWC31q-vk_KovjTrLsN7>dxn&G0ACBUeWEeLmQd&QiK;dnlbgO7 znrE)Vas839d0l(fF}=Xy{qIbg;aW9Vc>}}3PlatT@WRZ=C`(}49EyAorJN=CGn6uDlQbD5N}ft)@*d28yeOu~Lah?s#Hef2E4(EC{HV6qwHan_WT(!kg`Fxu?Gz#O zTB685E6J|Z`L7+HQag|KeU*td)xNrE1NkxlZ>Tnw;|pZ7lgpW_I~~7$TlOY&!{oJN zgOKQ6h>&=H&VmTvlqV27P7w^#VIjYWB+ngY?E45F~rnK$i0625S(-}of@{{2lQT`!t^ruX(wDbhv{;V`$6u-04X z|H5rLqPC8{l%c+G`OKS+Bui4JkVXYl${6MkH1@fdjl|zw6;U*s_+PJcBEbOMl@AWF zZ=XB5;8{UB9)>;MMdE1EuGvrWP*oq+7nF&%!iEaeY;z!|8E*yN@>{-a)}0l=!#Egn z>b?_@zcaa$*&_3ZJTW9jK88bVfGQ^0c-Fn9lvznP26t693V8D_%Pi&yZ@UP0zjDxU#JGg%Rsh2_|XgxgVtG{Ri zfsd=r>ov*c-LxUeXZs72eH89sK8H>n`iwWn<;Ghve=UvY!s7}&P6h&$Dl0B8OMel(4;dk(-0xyF-mx zS#t?qi7>)TAc(&j$s+UMGfFn#6E6Y$Q|94cy(m81B9VNM>oBju}$*()MU5DO7S3E`CW_pgQ!gntUu?LS&mjsDxd9PH1F=c%@>u)vX{B%_YwcRt^Adz z^Kr=T^jL3kX6G-rsf_mhzDn|+wBCua6LU(p#xteOOYj@8v%i(N$wX6s!X`1-K~qpCMTTC(c?}wmZK@m!cP!!kNkxSqdN~xKM^K|%b-M`8r!I?k%*Z|I-nVws=n0jn z&}xkqW=(jjV{9nUU&Fy{7p7^*S?`3V?yH^4!&Z0lj3qe}5>i#YMon0))Bbu^;0Ip| z`QT>lsY(V1g<&A@qzFMyI4`EAEbSS37X^e5*-cGReocC~XE9UWX|TpiNh$~QdpWC3 zXUwN9u91-!eM(kS$1>0LC?J+-HS&0SLz4-E9_K#_B$hbUuU~>*ONw@qZJB4QjVl#>O-sONXZ3bas49 zSs7!4?~bWf`*l*mInAm9R6D28E%uzc2k74NdNqTY(^fznhbAcLP`{^;CUVCdsK|@j z(bQw}s*&k&c^B-WiX!H=1glVI(18{6FwhJMKz6imvoYNZD8J4^HjyJR1CWj8Yr~!;shyH^3tXqLg1iaKM|o8CZJGSNbFnl1yokx=GMtV<5e=1|Y`IcW0EPoYX( zn=WD@hdjd@guE5%i`d+Xv9H&hf!hWX!6^ZZT|C^NT)>PGZN)@^R>ev?XB=H z)C{Q0*||iDgra5E0d%Oh;u`u6R%v8F|Jh+V7JtQ}cHW?nOI6i|o+r|ex#XK(%YTD< zr~9T`el4GB9Wbe_pC3%@s$Okly%W7t3?h%t;FT@Pj3dBXgD{r^wi5x7k9UTVyEC}1 z#q~oOvlg_5lWD2 zi4JLEtJX?BgE_hyqL5eLw~~EZAdm79VpBTYKx4s=x z^Q}ka`9#){_3n6gJ@5*hfLa_@(tSxy;?FKAimbU4|NNJtF$*sB<`FpUOf;`nCfp>I z#j7=V9ul$D3Gb=p7w6L1M?EW8WGp1p9a8XRjV~Qe*=G!tXaFu1#T{w>j=q$!1cLO= zyy?t?@X^c&_B5Q>(IPwgQfAR%xtTXRdy@N2Z|!0Df6w&BdH*Ak2+Qj54xj-84Ko>3 z<2VW46gVL9_N_4zmyIbu8}VHo??#?IAok&N6GBxs-4a?}xW=R^+2kKBR8}I`RD^t- zL<99|U9v&fVXg_G?6yycOuGiYW=G5q3Fps8zx$Nkaz8l_vTs&t*(00g0#=$R$%BCc z^d=q5qE5w^6Cx>M5Tcs)Z-Q|*AdO~ZshFUELdy>=~}6- z`A}NoeX!Pv_+%6(mWC#}@j!ZdoErl4z1;kfeji#q*-7p8iEXDGJcrb(1Lqu4qDR=t zlZ*Xpra6HjyAm+@hAWJyj}9k=5pVP@G2CrPicqbEjD?)s)VmeL57X{4G~d39W?3#fiX0!Z3?egG4#F+8 z^a1%1-aD*s8BOP05i8>c?K3)7t5Wp2%>E5Pd=YAmiSYI|lMMBK;hBqNnhYl64!UVr z^$S*at_NS5KA`l&6c{A*!tTODnpYq}t;WH-j^*n`cDU1_$p9)0T5Sb-HUs!{9uz9N+Lxq?FyaC|>`UiqI)K8{GYrA4Z5wJsa;49kC!HAz=M~(e74F^M z95qBUbu!(u+g!5IS1M+gZTHNnH#d{_NKY?g{g-5q6`^@WH+>oZPB6un=q}T4krT2z zC5z+)ILvN?HX!qTB^9AtjF~~U{RD--rk0$=@X@mjTnq+47AsGh=^YJ78{v#*UtCbs z_6Ios-*dz+pSzRR9GZ@irfA8X=PAfu;W9T?sXv+OyezDotAM_FrNLCiT@Q_fSLZDZ4_N?Ypaj}MBN&ux(-#}`(p?xK&|@Zc=bt$ zsmrkbj&Y+z*O9Dr)mvh>BsR>v-?wIh>0KpxGX}GjS4sV*sGMIm0Ps0*FX-WL-xUoJ z2n(N_f0nzU#@6mUEb+Bz`uNQNG%|iuEB1VF<11$d5#%z%gsK+N3MDW|>p)7qLwRhd zLfdWci035~6OB7}u8#PIgnq^p3tp~6S;;z_umr@q+(80WvYXUmL}N(XiLNadHLe;# ztq9Ut1uY)KZV}zbF<+ZY zHkw4+V>h<_Jt9x5qo7MiUn)Gg%$qJUQ<8&V22^NmL>5iEkhvu9PYTnihYhj$TbNt1 zsj{&ulac>Go`M{?U^W%^L!*82%R|tpO^P0)4yu1*ak1)3jo^-Up`$Nlb|nyb=1sR% z;iG26x+Ac#Gi1|U$~;E92k1?5%=p>;p`V^*L!E_wK@F7TX+J?qxZd9y z|2oUN2i7&<$wWa4s&VAWA!X4g8crPO^8`u2m%VTtR*qk0UZlh;m z(we7hE?n`dW)ZP%>WUOZ#114v6`L?l)Wx917FPWhTc&xhdRl(#46JGg4z{<*WiLtf z!dU)gH^RUxk14%7TMaj}4UD?OaP-5j^%C66!GiUmLg+i_5nV8{&upvtARbdQBRKG$ zvw>5gnWwtxV>$5?X0kUNnNJ6ZYPYy8W{DYDS1T{K6C_7BDjdUfb|o?yy{*(d`6P`V zb#e#h9rOfB?55A`72p;N1a<%YAOh`!n9@@DXM0*vK>(V>3%$I`$WUEMsyg*&T5 zKuop248;-Z*!2^$WR-RpN4RK%@z3&HeVNkiZafnb;l^v#y7?+$S0jdA1_#k~^|nv? z@P%8DmQj^Q2;0v23Qd+OQ@}0#^4@t7@KP|oCZrI#Sunrd0>3knl1_5xJWu~=Nq*d! za|~U4;%Zk<=HvU!0r*F7EEeMKt@&Y`0%W(#6oSjKL~p#F#Is&s#|@brk$$InA{p+3E;uV3jb#=HCoC`C@UN=F%|0NG`Dcq z4!);(gbxfzOG>pFsKqgd_AG0Tv5b*ooF>|30gvwazSo~z_tU_cUET273C|9~ue%H3 zw+Ly{o^rQ&ZbnH)kkGjdks^hWNZKt)4~fgp^7OLx=5q0J(;AOX?6&ZD?N&D}dwJ#; zwzURxD!it%DcP(auRh=qe zMV)(5KH7}TUU8G_v-@VwSb zx~J!u(bdivEXlf~T;xJ4!>`SD4{Aul2M#waD0|b=#@#~)N6-3-UBdXjoHj1JU`Y`D z^FiZ2l-lm}&E6AG+ATP=-O-^MC3!-@4(=cm5<=er&iS8z)zwev&dLeS)R%SS_Y7da zQ(pclf}hzzuJVp$VK2HA(?5@F9kMCa0l?*a#m`ce$xgk`H_LU#b5S#8_em2CT$25$ zuW_}QQGngleQ{f>Yj7_#Yw}!tT}s3~cf=whG1-5IztcYoF{Qahm*n6ujb#PSZhF(q z7ut68w(wX<9z^wrHK+PFfC6T*l~3=I?=GaKA1g_|*}|C!789Ptf8QKZ%*vw!F2}VV z0vF5_OD1OatxG5z%;8bThF9}JH+Db9J6VvdZ#ALL>!60wEoV#K-y|`0Mg&15>{mTA ztP3yb*0{d}NnXjQuN$_&?V#=TOp%J0$ZSh(9cRDX2h4;(_noLmW@SO# zlOsgT;6)0D(vX=9k>DImkaW0J%(7b;Qn+t|_i`HehDKSL#h}x6_aNx%sEIjDkNUb2 zo`R4|Y^1|Cp5=TiZF)DzfJYO;^wg(l3ZcG19`fqgz-Ve3t1U564dbtZ9n#yu=%IH# zCn$q%09d)0SnWx*F?nPt7e{K-aQ}Mx$FL^QiWsX?L380V!tWR2QuP8C!Du6u5xEoi zEMXm3Z@ql|Te(&sF4N#UsXPNnyDAnOIwLT2*tzxUcqhUmc5Z5I(e{*Nty+~Xn17ZW z@koSzg>iaX`?bqMXA7wB;$_+?RfgVNw7lMlYG|+5zz^u|@9w}BM(Dp@l4n0b+qy8X zs4l}noBQ!1GdeFrn=g`!P?9fS8t-L;<>$=4xpdP>5rB^9A@9mJ$yzZ}+?0n!4T8PF z!X81UHZwiPCMT+tP>%NNFjLyLj*o7ZK{N`8SYNG9A)u@+Y6qi;|C5dYJ*D^s z7cWK`@AURS!#dRT49+l2jaU+mJ@EFJX-q1u`=>_cINL7!f#%H?e`e8U_mkXlH2DEL z`qtH9q4R+~hcQLTvmtSV4QBI)v|-gi#b(aThTTZPuTRM=+|~B&Jvt!GlKj6>e;n#@ zT)(YCmf7^CZHvS-h?)3yooM=C6*Sc~UK&mdhMD12ZLM*o%L&gpojoyrbQ|M$p;Zun zI(I0^k~C;}mi*4^*#HhSAbyU`4E;$O5{KbQCHV)KyaI}Cy1Ag*W9rDCxXal>4r$_H zt9CAm8X;QCMl8=22bH(*(k!KK_R13K->!MOuIW*t; z?tU@Rqa}IcqeEp}0ANctEYuhl2zBd3X+z`XRTTo=3D z(SR&j_CW z=;7+bhSC1Iyd(jd*%gHgtW9HgK$^f<6rTTa8-*j^WPXQRETG`B z$AFrt2U9jA!6t^vOCBtev{IAHiTZ#W0-#JxOv%_&eep~0$Ot)UzdS$Ab#gS;zAaXG z3NwNV6QW9TcbhI?KE@a>)dY!JK;Q%WM?Q5#c<8Qfj%fGf=s6B~F?n9rZ$xfB7~boX zx6r&Kp3~Z}&ZODYceKr1o!YCuS}h7`o(PWvC0mut$x&saLan!RN|pZ8D;33wedyrbh#C=Z%=^9QK(Q_ zrU9NTMkimsK4BU{H1o$pwi@i`<(WCn>CCLvmHwsul`;IPlAH*RHa@D|8Z7)KPxjqk z*N=`4mE;(9ZJgj zUAc95CyaqQ6CMErb7O|&jY)hB5N{{)pIkIndcCu+`JKUxWMjgV#VGc2pNyx36Yos+ zKH^<5{h20mM5wevPU`tDYx4QgwUH{HANIQV^H>7-RFN~u7-^^cg z1Ql^%HMtT&XT_SbCz8oc?=p4zQ=;u^w$Xv#_mjG1iO8g8*mhOB4wC`C?sV2-l-80I zGbbu_LTJ$<@50$tFHU<-d2VZv+(|=3YZ&ic6Vs2^lAsa9f`&@1_le11KdLEEdxPYx z4I!aIGEFy`UzYYjUbr8>*^mz&_f;`I@IO$R_Bj)wQ?-uvZ1_FUT9GkKW0}d}unsVL zMl9QFKtgSg)7qEH+a(RKCeT9mwy8~XuZ)x`$>+Wh+^3LhMplyrIKM`QN=I3n3XRUV z=-m!!gyAGQlf3s}^}-k^wF#NEHn1;->s()0Vay=!X28l)n}&D!FT9fOhNqncTI z-#t5)zIh(VQ%~xbtQi}sO{}es57U2bg2oR@;|U=d@tb&GIx@AYGDg(tGf@T<-2GyP znIsh`@;#Ens;9{+;47z#!gFI%%~{KiWa9ldD-6mz z?;LF$>lH^P>-~t@;Joh5^XG=gDg3Y`yQ}`8exp39w*5>7V>$gMaoPh3ltyVHaLhgQ zYew^6z2cv}mWqEo+o;`~Pi$HqZF6I#JVGIU)YQcJ`I!uQw& zU|5J9_463z)8v}ag6fe-6&1Hhlu!CQsZI0lr!P_qsf&%Kg!C6Ax@dFE8OcHH2K}Aa zwE*rqe~+MdpwWkrFkroz<<@}!opdiE9pbwehL>H6x;*bXXsk9acfH#YZKSFjDEDQE z0Np3mGICU=*^q@r_FEnn(50Bo)dy;^Rh|6kLDDm<-}d`k6v-T|?DXvFW^6&5KlK|d zjL54igdg~Bn(1JgAelz)0T?wFtpcw~2R`iKi2_?sHlV%J?(BTiA%K^!>sdAmvmm&F01{CW=Ehg}27ho-hMOlMH_swkNJ^1Kg1dmj6 zv7cf~1!PmM{LJG5VW81hqu=pbi1E~GeRVkqR&#@4YW40|HNal329%tm;n5Lh4=4n* zMsw4@&Az)`?OIGua1~04{R*`XQwz}~JXXN?|4I71 zY}gGGKn<75rV1W}gV-sMUd(;`fJ9Q;@0lfQH;tZ9nOak=05W2HJ?oRRWEmnsp8L#1 z!l3-#uqwRjUVtK6(uffTleKM7h)3L~D&q%{j<}Nuh#h4H_M{;!%S^jdd?Vjoq;# zP;HlDa8Jd8tBp7t?oV)zL-@S?AkV>*ivuWa+-yftX4jkY27aA@k0n@r(^&NpFI9_? z5P(Zy|DX8^(<{q(}zI=uVZAI-i_;_VXeoorI^?JDB>6*cdiK`~D3@)VCf3T8dFG3@T zxu~k-H^&BA=w1XZoc;i8UOuoK$ zOpq0;- z$xsWf#TJac8<5sux0u~&^|B3&RFb(b3nDk&!&aj6w9jczs9_yT{U4Ef1G{}=1{TYE z1YLJjEn_|*OFb-DZX=X^$Ib#t$hU>PW z)y18Z_-o>%9R5vM+@eNc&J`x8tCCv&rWSg?(TNW!OeOgg9RmiaO*B;h?FHr04wlRu zs3TA9Vo=mnp+RiS2(X!WhwQ*F&x;?H5-Cu;wc}IjU6MasnOIZptDCTMm0{03F0q~t z1N5jS=A0QJxwwavfz34tGF$^lo9Nr%Qd0KEzCoF{2YJhQ}tRvLCJ+(Sl$5%G%L2K(8fvh35rFhi%+Wn5QH!KM)hb^$VAy7vKd| zrbcl>jv^R{g}w8qRU8r0!zY}m5z6kfX_9hBo9x6T)}|zR(s&zsLBpE(lO>r0)Kt-Q z5`yJbdFhvfl3_C#$c7>(JHCm=xv%w>e8Jyl35S-TW&hpa%tXRuOD4pJ-ESH%EXnuC zL3GZi`quKGS2nnW%B3Z_#!L7VJ&93(eI85*Lcs+xK;^Fy`VZK*rx7F#**mAmBcg;+ z^?n~l!7?EUwCf;EVD`?16SjvKkuN2gHkx6BG?|byFuroaI2M~8FLY0Btn38FvQF*g z*fD63HTOfCOHy@|I#Y>wbQ`wgXsA|25`j%S(^0o$AFdoZmIMn~@EYQxu6eLo{c!=IK3w85T&6FZ`dFU-^2vH5H%coy#-XP$)PI$1U zp2fB$@nTOXC7Vw6J3K-=2D~4D@vYQa05D-MJK1*%Oc3*Nrp)CQhMm#3Gu?c{}ois00CzXJ`t!BkPzA1sE-9Vc3u%^X$fZ+DXH^0fP$h97?lDR!b z@>thGx%9z8L}0L6zLDf-v5{IPg|8`lA|h3!Zn=Ih$v1Kd*Rds2U`lM6bv8m&qthx;2}{GV-nA>Sm(Lqk34n1evP*VV|%y|A(- z(7K@(gw4y^RFaA&ayWAvNs5#%C_L$Ob|u0C+CrEZMo&z#NlZeYL5hK{+&YkHGFDv{ zBD9IP4A$j_83{O&{@n1iCHXnIB__7zT+K46Yz_wS1AM41g@=4l-KkCa!M8zh*jc$? zt5>J#K|122XnhwZ2`CYRvP3GDt7aY{}zPV=Novh(?t$CsM?&E(c?i76bJrJ`ZW zLKh(q8a8)Q2ceH_GOE*2ul6^l5vW4Lb~IPRq2H;A+r!0}gK z8=p0aPdz=lGmOwdOdc~jatwd?bDpTwH}>@CkYm?Xh&CS_)>r5dK$iKi{D2r|gQXYo z@3a*hayc|+Ey>f5Lb*0f6}1Y6OF$Sps9=cA*g}%!v~7M-10UXBLEFcXyFKeg`YR|I zNGrdS0qJn+aJ$qHYs)fuEKLrzN7O{4>%G zwWo&$#-1-c*B9?k;fL&A8a*`TY^cIev9ZR1u_grTWdn4q#-~~?ET(o%H~@u+t}VBc zmKB;NswZZpL{EHU2RTOG5@3!~N&bFtB(!`PmKRuvPCBN#`ngRMF|Ku40sv)ZDab`P zQEJL)uP0y=yLLd-5>{pL`>ZYksbF(^sf!o|ozbjTbe1o^v;Mqt2M-ZT6DJAtCow~z zLQVhBGfA!SLXXnjy_K!W&+hLcR_#YWw3#DrJFa~Dp|tpNq@s%W3&a`Y@@Dm{PS57C zZb5EnOXN~Vkg9fIId@|iS;TLRL4>mSZwxq5JT<9nljEVxT)Z%H1D3h4V2bhON!F|* zRW;!njp`=$M)dE3E-Q{5rtPZe>h8x6duD7?+e-v@%G=BPY!#kNRCXs+Q<6(b7@^pg zs)EJ7FZ(1Z9h4pR<59_>aA~=$kFTmlTh&KShqCN$xwOKLLn*syhiGxuN4dyUXnl2e$8npjs(>`@5KCTvwPKSd$+z`@($>aowrc5l<&|ID zw8G^v@h0ALswg`VOF=m7aB{arQ7N!Y(x|Zeu>arQdBE9r)%AX#Gna(kL>|wA@fmp_ zaNND*VKik0BMHRZ6r?!rdheKNnUb4JQ9=)d-a9BAq$o)5f+!*#qzEWono^_*yzhUl zz0cXF&CH$Z=kd^+nR90EwbxpEt^fL$-~aaqN%gMZnXp2|Hu?AmTNM_pHv{&-=Vjfk z&CGYK4==PXZJddwIxF}8$_61)t<+GNm9jB|x@p!O`VuwMC10slUFMfrmvGhmQjHM2 zfOLx~CWv+U_0WZuj4>eDXHrZ;d>OYpMMy(h-iw;X`LxqadL1gw*}6bYQL`4^-CVml z&hehNI|av%t^#puU9sAHrkFjk`zAqSmLn;jCwsNF(1si`{iQcB!8Tdut{}4e`1}d_ z8nFMyKA!Fd+a|KcOw6PaAQ+$U8%)&~dy(`RJN1pj>%C*Ascbhr?y;9~x^<`LnZC3Ns({c%%6QuJBj;Tk`d0($p|?5 ztTPGTu2O^L+Pup8T!3TbHKJo_i*t%6c6ZI=$>-JHJ!2!?MBC?$ezY+k+}?F?u-A9< z8Eor&+*0T6TK9Y-)+hR4epHfCnuW803j5w)>4z=I#r!O(Z3E5^L(%$j*u5l{z$e4V z`h&f2+xFGnv!B(-9+9^Als>L1}5Y8RdL0@TqnYKkK3h|!HT%0d?AtX5;wmE+cRH*`>l z$@r)jn0z$3*?OV)sV~`u3)BZjJd#^*Ff=dLXh*^= zi%6N6SuYGQx<=i@Q6IDb*DivakWNt_{$$&ovtuR7>qnkPf}sDNTXP7pCe1`7;!lUHxW;397sGK`SxA3bnK z59>kVz*%%`8f!!CAnt1vGKeOW)cnmljA@JqN5{CVH)Fe|l(2^W=8jGNwWff*H7FRy zZ#2N^Zh*th#MR7bTUmxpt6Mu3O@hJAKGrvmDKv4l-#-`O@cDHC^aD<^a^st7xL%EG zO01|ob4^X~O1E zS?>{weO89#HXog{KJ%`|N#fxoxiQIgqihOy7{h!tt8mIm1xg(_p;X;ng_~hj^Wtd` z#;iUMCP?G2_PID6NLjw#vc&7NMz8lV*hiz;o^IV5y51VMvh@kNbVQLDJ%~3~u>Rk6 ztUSKxSb*B@2G;gs7L4`cr?3}vNfqn4=-M(p#+xq3;V<8(rKFm7&@6t=ucdPZ2{mc? zlj$^3=4uzbNtJA21~-2t`x}Rwt}!-yWNSL_a}UhXQwy$kQtDQ^+zd}E(Q>XDphUkl z^Qz738hHLjBVs!X*YzJZu!&Bj>zj3M+u^!h>DNa7-2GkS8^oFi)lauF@uyoyp4k}2 zTb0tyI@`$qkNGUv#gjiQ2dESQGDy3##r==QE=5p&4KKmuB{`}sZsgjTs>?OK918X{ zN4s?jTDvHUefYxFpn$a_%DQDcyH@M-A0rZF%u(judYucaKXEDR+&-@A_$MrSl+4{~nS&tSGX0r_`;B5`NA7(T!X+)~@|2o*{|LqQfsWI(l{Y}bGWZiHpKp#2Oo8E2kcJJO8 zH$pCTYk37N^JaJ6!yvf4m04=~JiHyvrkS3JZ+!{(C&ruJqoz)VW<9katrrcy_Kn=) zoQAE>!$SWKW)YqpT?WKDBkaEh$nHPUX>pE9S=Yzn^(!x5Pv_akGDoC3QYR+O*hul(1t z&f;I!dK9PR!)8=Pb#9v}W#=rg^M>xl)aBj}a__BYEbH40+N=~-(VhAqcpdlP1C$7GfN_!@U9m3X z^U!Mk0$*sAOhXbRxPc{!K0>PkNqP%^77vzQ6X!__ALJXh0WVlQELz0NDqcN0SFKss z=Qc?OcrO>34)ID}!3QHr)~wUGbe?AF?Cmsu6z9OjVso3MlM;gUe7nC`#ux;eLl$)jg0yx zbj(~7OCc@(cNYJ;)(?N)$g{~~tEC(=Oa?Jgo?(pA%)-r2vc6B+V!|hJABq=*yor11 z>|zEY)BPL#ZCu)ZQpUp_H9dy)Ub+QDO3=Kz5WuR1*ShXH0?zak0rx7tZ6-=&>~GS# z2)u!il8L>4|6bXgvXNz)Z@{&E$tFpdK3}XZQ%_d<%*;2Pd53h4SZQ{AR(>>JTSNEr zmM-KA?dfT*_%=@(ev!Y>zDJIubL1ZJw9T{ab(kQ@Z!kXKGjC+Vp0%(0 zEzKi@Cr3Zyl{e`-rkEoT9j(vOspbT^X}j6kV+?fF`aBi*U@B}jo5pNsJ6xzrk zCY|9*=Qp0w+tL@=5>oZT4D&tL+rq6foZs5YGh{5!Z>H45sh`?R9J%K*Z}oE@hl{-y z-JA6JSCJ(3mDaCs=`QJR$Bb)}xs(3BnHOzVEc^G(ych{~>o@wa=7Ti&UHwflQ}VPMOx>x6t?)3*!scNyX0F} z@?Q0s_ne_eY&dbVjuyOTyq3dD8T4)A8(r&JCvdfI{pQw(;#e|5t<{o>eq1oEBk)1>tb=CgLai_JsH@*yePR0*ut>V0{N9CktLE+Yc&&tJ?Ab1=Ma zIV2B_6p~}JEx?5wd3Yy$s=1=S{f7VkI-ZIeMfC@HZA)hNZ!|CZUD2pzl*PH*pJe?K zlIBYshyC-5DnIoHltodg+REZApNEvikMqR@W${OREz06w@lz{{MpJ|HUE3z_;_DIJ zNsdjU!dUc3G{(1ak?9p0<8%4YXpGl27oh)5K0-d+zY%3ojGi+@$)j*yYjg0$T>mmr zVqU~2d6W0%=de;C3aWIxR!|>0+|G*igpoT|te5eP>A5J2U*ppRW${{!!d%oSi`F}@ znK`tWE|i_8Uo-QZL)OVf2ANq}bgs=WnhBzN9sQMvn;H2lypfBC#9m*LBMl_#4kj;>QXfRER{@oJebyFqxFGmD1}OxbmAG5BT$-y`47 zF0W@0iCp)FWkI1QC#kQz-p!iNndb90_h0{7I^=hQ>s`KHq8{TCn_Il$wbE>9W$i|f z?#$lp&W`QOo_gLzr>>T$KC^$k3fsW3bakQE;|u;{sM&hG!}Lb?_^|%w)OFWBHC@#| z^quwfBbQy0a@XS8sdv2SR43p%(}ba%bE2b8#)LSb=Z9qw%at;DlMqqm}d+ zBg>uS!t~fBWiEZZ=+v`LJwrDZ;>IagP)LMIW_f+}D6QprUIt<2X1U`eVHT>J{K3{* zi|WQ)r&tmaTHUZ9_$VDv%$GDBg<%%?fg49mUIvh>Q_vy;qLKX>4-&`*Oh zu(Kcvqr50eTixuyyA->H@5XTyxIvy&Wv+hyz`K-1c9j%KnWTPNCBCC>emP4siuFnv ze*KW~AMN$lk;V9CdcBLyFM6G9wBN?oipOfry|PNGG|n=|R{!JRXQA*SrwFRtFYGc3 zb9IXY?^5o1LFgBL5C)Z7#D)5w2i~PJD^f4?lRURmr*bOw3kTk%DlW4;aEmkv;wX0_ z^@}1|Lt8IjEv@xQf$xHYLTa2IX|Gq&PI^6%YQ5gsbE{NTJuZvY;|oMumPAEvXGP|_ zp67b0`lX1bogu+0Cr42_wnk}bpFB6Zc@f)gkd$$rM0OCWUk*gt>r36D3^ehDz;vdkx*DbXV#DYnJb=9$Trku{s;=U}&5s#7Ymqlp%MWlZ9Puuqe+D#Jq z6Hl;_!RbkAj) z0V)8&va=!oGYSYpYOig*NP4}IsW}YtU#lr2gLi$mv|XFyvas_q$<(jkod=^gtdt)1 zLJ$=zOUt-0XLZ?OdEoHbU}9IRy&mD$#Wj8^`Kh18%60;#Bk__TfwtBsbnr0^r$xi&hi=(1S5elX2soQQ%A~;1>6@llazMDmk z7pU90%>3|%H18oKwkZlZ(kDk?Cs|&2L75<#)$NTCHDldSh_Yc?#>6BUI(mhOQ0YKz zJHQgXc6_%aqLtP`d;rKdsBpw?Qo>ok(*XdQ7E`Mn9zD1?DyOR zb{SW88B}o;MX^&T`#^h>M*673k|G@i`R5#DZ*nItBHMS|B+ESX0p%WKZ>l&$eTakvb!BbUac1#>l~4nz-AY*r6?w0>u!@ze%nYBu zdZeBPKXEHN#3W5K&v(*Hov~lj;H8;^10*Oywu_spGk+|C)pY_b(ubANz5ya%ll7s; zGTZBksWR&D+(<3oLaS%#C&&b8$FJC3{1a2FzbAUV+1X2=3WV}(aM8G9S~}8PMiY*G zh1>&6#rlF6q=B8}wr59SmE@6EsmoVA&w(#=Y2|pm0P95<;1IzH7NtcL`3c&h+L2A?*?C@tfzSU30lu|!cGMag ze&}G|mZ6UWQ@zH1-H(B0V8 zWJIqZt}Zm2RmsP;dAy-3t3o}&@J3$xF&$0Rxp(D3!X#{66+PKb=Xu>P&T zgdLBl2nZA$X_=A24sM=2%*!%EZ7%Xi{oX1q$HxCQye0V7CI=lagxSv z6_!Qr2e|%Xb?1+o`7)u0DUIyje4Sk`E-jF*qMcN`Ibn8^j+I@<5g`>*EI;Xsvp$V<5irHt++5RajMJ;&X^Q5h}8}=pW5AOkV5yEZoLKjJ}w`nL2GUwk#4x zRFk+&qtHoMl4VjQaiT8XC)LCabHdA2goo29Q_okIT-08`fjzc>H=Pt@k%YBUnvLx= zNL)8pmp-yfv#w`O4mtlOHuK->9rb$VkQDV%6wnJU!6%m&tR_W#gG}yo08m4LOQUG#$@&>`d1!+Y@01KzG0dr)Z*KaVH zWEnHpE62CB?{@eG8}+aMnm4t>NAy4sJ0c~lh)V|PSyn3FCp|C>z*2(xN!coX>P4#9 zrw2P=dPMAGSsoI(%vHHh4^Eso$T{oqwSYu$d{td7E2?jZJ2=QjE%7ZakBww^?ThPg zk=m@w{Gdv4fB>0ufGecx$UaSiUnX`AIw-a6m^fgij_%ikJ(f4lio#3N0@R|K+ouOR z_}$&u4%`Slb(EIskN4@pUK!$St?(0oU`o{$?mJMOve+(&YO#NDJ^Mgp7QSJI z>uxk$asWXNt)iLZgx>KX+>h1_HG5&XJb(Ny8eG1c@7IruAP7@8a6nfQtyhcRGy^u8 z{jiYi_e{Rt+c?rCOKYX!Ox$htDt17sc?f93e#_#85@0JFpR-wYA9E4i-1= zC=hfJ7$>_b{lHht`y?()zp{b!+mRmuIt0{y`93`um{9C`aqik6mjJM}zXo2ujc^kCc1;>-ncX`?&aVXW>| z3~kl%u+J8bh*~A9H57I$LA)Y~9GhT|0|Kp7_ui-B;j<5mSYnj9<2yvP?z0P$=*)ES zvewwb(hV~&0AA;18L#fX;dLk#9GUOl>j9Jyjn_oI*^XT=fr@=OhSa|bj zxvKIs1osyLk4}A(Bp%$Em6lC7b@J$2XK@QFGwlgQ9A-Yi79S`h=)zDvq$6Ou?eu+U z|B)Dl3jwH1L0XXOm+GNAZP!3zGBQ6%bS1_t-jS$MS9k8Y!x^djZQA$42%wD@X257#SqEsZ*lgDOlwlVU28+~}%Dbk-SPJjo^=0GZl(uv^yohM-J@&~p%No{bF5 zbJp1-J32SY94y0H&RHPwd=bgLWJTn#(ovIp@fvm2Qv}6?-6DfM~`5r__@=*K1wzw2klAY99CFMT$xl)7w`X*&KRdf3p?Q7iKC^Sf`eRY*FP_!^0&WuF&Ukj`=h`=DLbS&pLNvj3bA}$VpQ;ahwwe3W79olQL61;hXA3kr#6y20l;&ya=J^g@3+_XNF^Y zNme*jiXH-bNIkc6zPybw0D=<sj?PlU9)@COxdJp8Vx9?% zG!2tVJ?})?6DptK_8dUTj+ckPWL>bEo_c;qr+AF_FMwO}NWUv3vq?hb=y#%a#ZiJ@ z?Zp@#c~GbqbZ)*vq?npbtFuP-VBHFM`-Po5G84WzJw?--Y95u)$BKqmC*8x2LgJ83 zCP`A+9$DZo+HOlJ$xvi~28HXmZk1Q+#hv@or({wHy#ZHiVj4+jr+$OU?-tM_WH;WB?C%|T)m{TZ99*ho1-rVc^Rbvi8AV?+i$BXQ$MoL97Bji^ZWY3#Xps$#r9k$S~$*&>W3$O%dk3?>VS=+P^8s?i(ziK+rE3Izz5 zqzZw^Z*Y74Tw9?Lpt{`oQ-#^I%sELm{Q;~oo0?f>h&RldQ2#Q3TFs_@{J ziXHWuj?R|YNF=QuUtKE~8ew!;f7(zCjcqq43v>JiV32*^wQ>2pw(~7f8p->c5DjX! z{P1(Pp+pY9#L3OJhr|2XO}#Sbjh3AMoP78RyjZ=iQ%C(K#lR+a?|??#7*j2eMawX2 z{>prffN_cfkD^DM#KY`P16RFX+vpw{jn5>z$H~eg!s8)dum^0rD#&X_>-4hJ z2hZ|`?H;(kOI88rljmUWM?t0Dxb2p3czIBGkpCwM=dpUzc3UdY0HPS=Mhb``4kPvE z?H`o;g3Yse?C$Ug(*?wDayF`Qv$t4KlBnVyg*6p_i9wvch0sun+eAO-0+d4y; zu-+u@mOk&1ktMR2a1Ewqf>j9uo^0Htifb)8upLl7o`;obyAoEmqqld;_VIgyE=VEx zA!?byaZ^Iiw!w4W(K)AijxXgFLQ@(hmfs;lUWw1Ge<9WAYXseh9b#ur*6 z`Tzi)xCB9XJH#{Rh3cIHon_;}c#CVo8t9^~GAocv=B{2Ge(ZDGJQK7NK03qUtYW{Ys$k~ItF>gu38ccHHTd&$NuxYBz6Hos(G3 z)Mpjx27%{i%sr6DQoVn#pNm1yl*0mr4M|>;52hz`L-hf@+TuMMFZ`uK8Ox&+oYNIF z5x$>7;S}5IgT~LfXO9k6#EHg}!PWXnf)^lmL)_Jl`j8f#!v;oFzh1{_p2 zGHY?_gPSKEHzpB@ERzqLS(}9D8(Sqbv-t{a=w2@C}*Ulcy06^7k@Jt+JbwhAH33*mc% zvf`7Sr9Bxvgn~E@c_K$*><|`AaJ9px5UWp_MYkm(B|(k3a)d`=(s|Ha$c|5h{kd_B z!=skERT&aK%t8;i;XmtmfoCl12~JPQHG4gYqtQ~NGu-A1MiG#I>cyn{K>ZSyzNbFD zU5h8ku=L}yBsC%it=g;DvY31-v$2?mSqp4|fu*q5l$Vm!tW-t4RjNhuSo3yp9+4 z0bF~yGN4WYpA^B#ng;-(BK4I{#FlgnXT*TQ8TN<~5^16xgfeX?lzsFGKUDu_eB^sb z2kjtA`V3YL36(3xrUPIVkU1p5x%z6YR_z@vwXg*b`eC9LHq^uwl*p2vT|slJzIGtp zK)vO(v7w8=3+Ta%@bv@g2ISfS`c6Vn3*>|P#({JL#95gT5GJvvawCA$-#n0R;6%j3 z8-V}dgomtD{riD*qX0Y>!Q(|1Mg|7IQvY!v-2jc?!>TLh0SU6W`@Xf$-GJCyl#wFw zi-25Nn{Y3%6ZP%R!?ZcJcXGo;iVoz46lq-}a z49w~t{!d6_tD-3ELjCZddV*F2Uu<3lgm-|~CF(~9))VMf{i?(p4x|D*P5swF^&}-B zABt{??!xXC2I|KL)sr&C9YPXh!Xk0m)aoZ1bvDY9Hdg+m!g=Qtv5W9^7o>#MRyypn zPMkzQh~d?9K_GhmPj@-KIpGoa>+V5(bHa13>I(Y04`cGjb1!N?f{~O4<8tvDp;^uU zi8YJJiU9Y8J`BBKNT?CIU=szK@VNVT_b2i<;n5H1?nmTr!h;{!6^mV+^{@l#NCGJu@kMghL1^coULSry9l@e3LNLgJ zw~VSVRo5I;M*^oR@|>iY5HxTRs7D-7M*wyffJh=7o&+{hPd&1$^}%FMca2MJtf68u z%_asC4QLl?F!E0d6c6>N1MLnJNJ5JPhKGDCk_6PF54bx(*Fi72d6JRa9jeD1Xm=>% z1V=R~x{?D&H8u6v?lxiZ;(#MBfN~9)ohG@X9=F|=s60tl0M*@W){hj-d;E4=BCh}v zbwUmW?3Osj)DyPb5?JK4j8j4}g4o1g{KW3Iq4F^`3W)J|0r9koOiT5o?YBiz5vi+g z09ZYYT~Y|1y#2O_%!2yGdMfbD_;3e5rJJ@@za69W0Adq-#T0>Mm=dFLNb%aIb|nBb zP%lp`Q+NtYZ_%h@GrK}$Jls|c&OlO8D3wUik-`vb>6~P#r2)AhqzWN;g}KVD75+(Gd{+0j zH)u96Iw^-s{Ty<9Br8A)!?5gOz{=ILyONMP5kt^NO*hpLTP0LlF|-YXyBSmjnO8+P z4U-VimwHb3GM+cF0PQxOHP=2w`F1F7@YKVK3MKa_s_4SdTJ-!2Bnl zUs_#X0go0H@bc#!(WKeLlu3^(Dvryl2+vu(3xHRj{K@(G z*(H7*G>+e!G+?wPEFVNn)nOsi}1Tv@LAW0T>@ zswd%(I>!=4!iomMqW+>QAodezWYdi$TZ$UHA*JJhFO`LQSy$)e4ktb>fPP##?)WR^ zd`Z62Y_?8Pv843+YrEuvNL;O#`Z*y5j520AiQw z6?%c!Xpu4Fn=inlpHPt(;&4(t*hN>2Jly%}m8OHEv1X~<<=BUtvXv_}WD@R(+|6AO zi$t*SxT(MFN?zceRflX>5F<~IDN0#iIF>2+=|WshaP_bDu?IS66~oID6&Wsf!bN~? z)T{Qd2e?U?10+gWRE|sj4pDF?RPO4a~HIurHR zU0tPa&-&oHgFdWNk)`b`%CeMnIfCuL>mW^1ui3{pqA4t3sfK6Rg%l(JXh^N7*LLr( zgJgSEQq}?8+Po3tJ7ZngK#M5d8lc<5{lLNfx~>VQ?o}@Y z3s=3qs~HzYMU50i(Jn+Ml1e*6&cRyjAnP5X1Y}~u=R?UH^@i?M+AC?GWOQP*3lUw#lx+AL$`Y@?Z&9a9NE+=&V#;(Q=@2!)^8SMtiIix&zP+C)O5Hz!TQ&;EJ zPMB5?kMN+BdOer0o0i~Ev05nwO|4(`=1D5f2z3H3oXqv1st6!+Mi+043DA)w0K|#w zd-8t{v?Fhs)ZCUeCUS+H5WSNmLCVYFZGG$RX-pL7=HwF=2wduvP*-o8I&<;*V!4{9 z%Vqx;wijg5(6q;CQQ45G;gWv))cYOx>_G&(IXqJcsi}PuC4kVO=ML37j1Dy6%?;m= z-)wERX0@VjiWJ2n(LV`b%PG{~Y_$^@Ckz75ASMk>P{ciz1jToD&k!AI(@sR%xG{u1 z87O3!#Bn2l;08VNt`lj4MJfHjvWO|#2=zwFF%ql4?MfEk=KXM-<#Yv|OG7tk2xd_> zLsgRWrlFgKf$R_K=$PzkmO5$3M?J8k`Jp*`2Mhd4HP z1xbGb?oG`g!AFxC^Y>bV-a<>EY3bNek_R;-2;=08Bg=-0c0h_lig&8_bcNku^Va<3 zvb>B2SiWS2F|d#b6vbuLKWyJog%AL}2?(7ICFG2&_i86nn;~j6I@Q?aC#J8KF|Ixj zdRL*P6pi>FyO)c?X)vN=f}bxa)>>YUkD)o34wsit5c>p=$_3d1i~C*HIvqRA4Y; zC3CLcxBZEN4>CnRBGJaK2*JAQ{as0S+3UK`^+-~3d;v1P$&vnmIkFmTKC>`< zaO!C>`h-OE`g5qGbDK|NI|3+3>be^&IWXX5;p3E!!X!~2Y@0O(s4me-iGcQcXX~FQ zwoGiO-l)}?MrG*2SstqobseU87zFRw5~$3N5}RF>{eYT8>UiZd8@UH3@`tzonr%vW zNG?^F=5YTL-2F)R1d;@BZ8;RkAR{9tPlZ&qk9MWRant)cCY;oMIK$sVT9=VB9{8*T z9A5}wX9 zoU!T?+kYX{qPGD7mylA0)HSWtC%50098yINM4fzb3QMNSuHqJ`Mt@ z7O6hd6%w=)PHIXKiy@#~*lF>5kiPQSu5dR_>Vw2qn;z_>67Qa!X%*uB$1h_A5Ob7CfnG9HPa> z5pE#$`R%b8F^~LSA6Bp3TI)*1xlQmE- zg>xcKQ*xIb)K>MC?nA_m?Jr!G^Vmj}y|=Kwrp2h)c+Qf99Vl)KM}4b%7O%2@ zbN`nOTjB5%GlarNZUt{vroOH1tp3gYUnaBy4H3DTOW2cIFO;Jpq~HM7t&7o7Np9?S z^y%Dhr2osL)^Hch&n;dyJD;vV^w~7&N+AIbd}1R|K}M1K?uj%Br)Nn-ak$9@Ce)lc zw|$~4=o9Kc^&04RuK&w~UbFEXd{Ljnh^GqxClJB5h)1`HB$xs zJ2coo=-!6aA*w;Nyt0&2X$ZI?(N?Y{{z8?{6efyDjC*ZSEli4VzjpC+r3S(}EKaAcDC54(H-dAJ9e{eNj&L55|vn(G&wHKfBDzEqPO zJ$rO%Nn7zG`o|D<~Z^Qq=O`DydHrdGY*%uQQY*UYL{ z&Gg2`2CQJMc_tZsgrz8W>HrIkL9pL{<|dlY)eL`q@z~sA@qig&u&7HH>T^mTho;om zgn1f~?PE{?efJQ*O`Bwfs#FC;u2QNT-(>Ep2hIq($H5l_)`wwi0ON{8kU0x$fZ7t7opw;yg0Dw6yRr zy-tNQ7|LU$pKj{mGh!O_#mC^6bRH)1*>w>bZe~-TyF{bGiY!T2x@Jbq;lZ`d!IaFG z6*vtzy0{Bg=p1TbvU$kb#BNlNn0{AEr?`!~VEBRhKgA58zIh5&<0EG#A78F74+Chy z6RV|_*);^^EPJLDz9guEumiF{0Of4_Og(Bw;5g$w4$czSg-B&!9GqF~&k}`&e&7Re z0%%LwsBoMm>d`a)1}*rt4}im?2wf--Y<%s+gVkeZq$tm{2Z#Bb92Y!~O&78EC?mj8 ziPE4RyYY?7&5gK7Vn{4NLj-7_d8{5cBe9EVPsETVzP>Wszn}6g8O1yaHNdn407*T5 zMyRc)-5)g1^{H$u_`|ruz=#rCJz+-h{?qP@7VuFoYdn1HA*M@+A>c=bUo})uoJlsg zGZCrTJQc-{Og3CQR6`(JB~wqD5fgdZQ(e1%^K1%`s6T2Lnu)RC^3MV&sxwbLdFJp2 z?RW&`*fv7$HfUycsWScQD_By{32 z0vA~Lse0-bhOApKUae;8$O@GWK_(=Hy`XtiPn!`K#C{(2x=DT{~%sp5jb)~!JWFrD{93~aRVA1xz z4lX!DX!eC0Q#^V`>!e#ToUowuiRwY*2}_oG(XKQPSDX&{>C$sx)+!%e9ml(R@r=N? zcG&wwiw^>3vhjVKy{Rl-HbYEOxq8XW-FN2$yYQgJwwiKU=+YMw}cw8~~*N z(nT;}21-^BgmQ^QsuPEDFF3YRNBzZ&6kyuvqs*&@5YafNWGw zcIB-sL!sCN8?a`|yetB0qveheV7+{1n<)+uCL9Qr-0yN68dEdQxcXTh_;zs@@H|H;3mT> zf?5l%B2urK5e|K`2tu4bM36#^5q|i~>#IU1OHfDhL?bi<)QzZ6ub$ZzpOxh8`(@@k zqJa^nQ-8hFc8$-93_<)fVTzjoWh?R3Yi4#0Ve5nOBgEy~u>-AVQmWT#`@>9MBn)q` z$3uHRRL-iRuqGs8MAtINo?y;@ojw%IP3FH&OdXg4nlSAkGv+;0?;!^`O(1G63IPA1 zdc8gcM;;e}N=fs%wd1q!Z?050m-Vd_(UN*JD9A!8sopRnIO~yHw+zCePA4v0;slyZ zEzi^&XQbTDW@Cu4({z-d9^uggAp=_)haAOVa`h&yz?mk7m!1=7J!YMR<=OeA)m7nX zECt(14Ti{u+88jbdb3u*%P(wI{D4K|>oCu$G!R<~$*xGgEJy`9l%%CXPDNSt(pFNa`MQ z85oA#kxT}P9O7hxm=A&|l*&xKeMSPyMl?-G6G-}50E@Ps9;AiIqEy{US)_Sc!W$XJte^d4a9yk+eVz+6qp zUqRsVTr4v6cQcY|J~CMbZ7*{h;eX(aMirKNBC+~=z1_z<>6%WO4lV&5S!u@Ukg^s= z0rbO>i>S}kduDQ;7&TOX!e0pZ0#v4;)y4G(gzMbJwG%^mfOp0~sBD>3bVv|PGg&h( z5egoU@Sw{LOxi8K&FjrQ0d*kz2hpMbTo-_;iwngWY#k`sWWj?x3O)5+tpxXHTOLx! znkGI#Z@~?kr~ZQN0@olH0zOCpO*6M@k0H<@J>CkiDxr1EK_J015P?FPk$Sv!5jQg= zws5bf`H(3fDzwP5cg`)Y6rnXP)+UMwtX!8wF&v3Fy9tS__iKy&gyZ-){V_>Ga#@l4 zc!tymwCUJdL?M=Hessn0%}-80oOW6c;?f57kx|43yMO~%eNcPf%#fcHZ6J=+M>Y^cMnkEHA>@gj*#-4~ zLWmqbIp> z0*5FmzzI3YLiJBGg8ww{X@e$WZ7`ZN6)eyU-5|m*<)?T_)W=)Gaf3Ek%~(1nTp(S6 zdKwr6nL;I;@#HIiVrGbnRD_0Zt^R>ztO$MgM>TDQj}^BOP>h#Bn?P!`OVu>>$?d-a z*k@cf2yqCy5!HZv^{MT*Ra8VRDT$8OkH-h6%|B~5fPNRP6AGy=Csd167L))68$g0A zAj`;6pWd$R;#LJ(CrEt?jX1!!)n{fT%oP|OtCrk6W90~$O2i1aJn0-hd0>O*qU9v= zEA`pd{xU3^j>lS9NtXxv3&s;d`tZ_$Xak&Fs(&$NZ$s4F=fQ3Ewk(IDfj&%Diu%=i zhcbB4&g=s#DEHpj;UK{yYO)5H_8-j73PB1LiKkgCsIaYP5WFJ(QGPVA^J&)k0W2{EIa zUFSY}9_eFPXn&15L)yfW|+BqhlIuMWii;HG+g(Fo58L8MCwSU{O{+4a@ecE{jF_~3R2A?j3peYd;?gyW(lLZpQlUW7Z;H+I@%GZO^wagdP6j&%e-MW((vRed#e8Su&? zUma!*tXyiB>fg2TXVx2sYG4pnez9b*Rw(T(S>~KVI-H6G#mRjK0tUI}jN}yb7wXhy z;TjwjK4nv669-5{38MgAkn}o8vcJ_@Byz0RTEEt28yy%RZB>vTiEiq^H}9)&5AUwQ z(}x5RrBVd;>L*av!W8bP?`(3LnN>f{VQ&Y258}b428a6Yuml=BO_*{~f3U5Op|Bs- zF-MFjtRsX7Tp>B(T=k!u-Mvmgtht-b$16pNAlO5mc&@%TZJvoN>1Q)%Lhoe6CqJYB zI4>-My$60JB1JhqPA^d3KaqyqK|>%-7>G*{RE`ajp?`294S9ox$Z>+M1PebR1Vlhs z{jjz6nEBSUqN(a>Ma0T}$CnTOBqePgbZQA;MC;LhouLMHcJk?@#dJ#)l2rpuTTF^6 z3`=R@s{fk#y=DzZWTXiYTjzvnM0Sy`k#dM=TRvKnNGySk#Uh*sDx!noFnxrHhbs#C zMYKLvKOU&aO=HP2{y&54c8QG)K1n{I1JNaBB!O76SbX)9ww}Q|oi?U14GhgQ#Tyn- z(FD(9v45vEC3D=G9!XxptK?EM98nzE>VAi`D_K;PA%i-ZZkNyMPyw(a zJIG7VDRH<_MOj^SNTRb^SPZokO*75wc3e`K0MfFKiEV?LyZ<2p0gSg}8m-Oyf%R-! z@qM&%OrQ{84+Heo0}iE4D{{j0OE2kcKNaFnixvITy zi8z^bfH1fM6HUT`}}q$*DI+bBoQbF{w&fTon%WNs*|jdhnrj zZmqL~je^NS>h<)qd%ga{Cn%c6MbuPZl1~!Bno?JdFk%sldXO<bUGbSS;YfOiP=$& zM?L<8o-la~Lr<_Hn@nSHji~rIzJ2wCLjujIZLF46zM=bcY*# zIXO?f{5sG-Qu$Dls8MV?_{N{K-IhQ^`=G1HECch&{#e7&`ILQTt5D^Lx2_+Kq~sCWXk0D)YZv1?N~ROl_*Aj+3fO?*vl)|xo*cg zxwo<;I;M60bwFGf>pAY!?zQJ}HLv4N>>Rofgr;@<8jM{Qx6h7ut|fTR{Fj|x81 0 { + require.Error(t, err) + actualErrMsg := err.Error() + require.Equal(t, spec.expErrMsg, actualErrMsg) + return + } + require.NoError(t, err) + }) + } +} + +func TestMint(t *testing.T) { + creator := RandomAccountAddress() + tokenz, ctx := SetupCustomApp(t, creator) + + // Fund actor with 100 base denom creation fees + tokenCreationFeeAmt := sdk.NewCoins(sdk.NewCoin(types.DefaultParams().DenomCreationFee[0].Denom, types.DefaultParams().DenomCreationFee[0].Amount.MulRaw(100))) + fundAccount(t, ctx, tokenz, creator, tokenCreationFeeAmt) + + // Create denoms for valid mint tests + validDenom := bindings.CreateDenom{ + Subdenom: "MOON", + } + _, err := wasmbinding.PerformCreateDenom(&tokenz.TokenFactoryKeeper, &tokenz.BankKeeper, ctx, creator, &validDenom) + require.NoError(t, err) + + emptyDenom := bindings.CreateDenom{ + Subdenom: "", + } + _, err = wasmbinding.PerformCreateDenom(&tokenz.TokenFactoryKeeper, &tokenz.BankKeeper, ctx, creator, &emptyDenom) + require.NoError(t, err) + + validDenomStr := fmt.Sprintf("factory/%s/%s", creator.String(), validDenom.Subdenom) + emptyDenomStr := fmt.Sprintf("factory/%s/%s", creator.String(), emptyDenom.Subdenom) + + lucky := RandomAccountAddress() + + // lucky was broke + balances := tokenz.BankKeeper.GetAllBalances(ctx, lucky) + require.Empty(t, balances) + + amount, ok := sdk.NewIntFromString("8080") + require.True(t, ok) + + specs := map[string]struct { + mint *bindings.MintTokens + expErr bool + }{ + "valid mint": { + mint: &bindings.MintTokens{ + Denom: validDenomStr, + Amount: amount, + MintToAddress: lucky.String(), + }, + }, + "empty sub-denom": { + mint: &bindings.MintTokens{ + Denom: emptyDenomStr, + Amount: amount, + MintToAddress: lucky.String(), + }, + expErr: false, + }, + "nonexistent sub-denom": { + mint: &bindings.MintTokens{ + Denom: fmt.Sprintf("factory/%s/%s", creator.String(), "SUN"), + Amount: amount, + MintToAddress: lucky.String(), + }, + expErr: true, + }, + "invalid sub-denom": { + mint: &bindings.MintTokens{ + Denom: "sub-denom_2", + Amount: amount, + MintToAddress: lucky.String(), + }, + expErr: true, + }, + "zero amount": { + mint: &bindings.MintTokens{ + Denom: validDenomStr, + Amount: sdk.ZeroInt(), + MintToAddress: lucky.String(), + }, + expErr: true, + }, + "negative amount": { + mint: &bindings.MintTokens{ + Denom: validDenomStr, + Amount: amount.Neg(), + MintToAddress: lucky.String(), + }, + expErr: true, + }, + "empty recipient": { + mint: &bindings.MintTokens{ + Denom: validDenomStr, + Amount: amount, + MintToAddress: "", + }, + expErr: true, + }, + "invalid recipient": { + mint: &bindings.MintTokens{ + Denom: validDenomStr, + Amount: amount, + MintToAddress: "invalid", + }, + expErr: true, + }, + "null mint": { + mint: nil, + expErr: true, + }, + } + for name, spec := range specs { + t.Run(name, func(t *testing.T) { + // when + gotErr := wasmbinding.PerformMint(&tokenz.TokenFactoryKeeper, &tokenz.BankKeeper, ctx, creator, spec.mint) + // then + if spec.expErr { + require.Error(t, gotErr) + return + } + require.NoError(t, gotErr) + }) + } +} + +func TestBurn(t *testing.T) { + creator := RandomAccountAddress() + tokenz, ctx := SetupCustomApp(t, creator) + + // Fund actor with 100 base denom creation fees + tokenCreationFeeAmt := sdk.NewCoins(sdk.NewCoin(types.DefaultParams().DenomCreationFee[0].Denom, types.DefaultParams().DenomCreationFee[0].Amount.MulRaw(100))) + fundAccount(t, ctx, tokenz, creator, tokenCreationFeeAmt) + + // Create denoms for valid burn tests + validDenom := bindings.CreateDenom{ + Subdenom: "MOON", + } + _, err := wasmbinding.PerformCreateDenom(&tokenz.TokenFactoryKeeper, &tokenz.BankKeeper, ctx, creator, &validDenom) + require.NoError(t, err) + + emptyDenom := bindings.CreateDenom{ + Subdenom: "", + } + _, err = wasmbinding.PerformCreateDenom(&tokenz.TokenFactoryKeeper, &tokenz.BankKeeper, ctx, creator, &emptyDenom) + require.NoError(t, err) + + lucky := RandomAccountAddress() + + // lucky was broke + balances := tokenz.BankKeeper.GetAllBalances(ctx, lucky) + require.Empty(t, balances) + + validDenomStr := fmt.Sprintf("factory/%s/%s", creator.String(), validDenom.Subdenom) + emptyDenomStr := fmt.Sprintf("factory/%s/%s", creator.String(), emptyDenom.Subdenom) + mintAmount, ok := sdk.NewIntFromString("8080") + require.True(t, ok) + + specs := map[string]struct { + burn *bindings.BurnTokens + expErr bool + }{ + "valid burn": { + burn: &bindings.BurnTokens{ + Denom: validDenomStr, + Amount: mintAmount, + BurnFromAddress: creator.String(), + }, + expErr: false, + }, + "non admin address": { + burn: &bindings.BurnTokens{ + Denom: validDenomStr, + Amount: mintAmount, + BurnFromAddress: lucky.String(), + }, + expErr: true, + }, + "empty sub-denom": { + burn: &bindings.BurnTokens{ + Denom: emptyDenomStr, + Amount: mintAmount, + BurnFromAddress: creator.String(), + }, + expErr: false, + }, + "invalid sub-denom": { + burn: &bindings.BurnTokens{ + Denom: "sub-denom_2", + Amount: mintAmount, + BurnFromAddress: creator.String(), + }, + expErr: true, + }, + "non-minted denom": { + burn: &bindings.BurnTokens{ + Denom: fmt.Sprintf("factory/%s/%s", creator.String(), "SUN"), + Amount: mintAmount, + BurnFromAddress: creator.String(), + }, + expErr: true, + }, + "zero amount": { + burn: &bindings.BurnTokens{ + Denom: validDenomStr, + Amount: sdk.ZeroInt(), + BurnFromAddress: creator.String(), + }, + expErr: true, + }, + "negative amount": { + burn: nil, + expErr: true, + }, + "null burn": { + burn: &bindings.BurnTokens{ + Denom: validDenomStr, + Amount: mintAmount.Neg(), + BurnFromAddress: creator.String(), + }, + expErr: true, + }, + } + + for name, spec := range specs { + t.Run(name, func(t *testing.T) { + // Mint valid denom str and empty denom string for burn test + mintBinding := &bindings.MintTokens{ + Denom: validDenomStr, + Amount: mintAmount, + MintToAddress: creator.String(), + } + err := wasmbinding.PerformMint(&tokenz.TokenFactoryKeeper, &tokenz.BankKeeper, ctx, creator, mintBinding) + require.NoError(t, err) + + emptyDenomMintBinding := &bindings.MintTokens{ + Denom: emptyDenomStr, + Amount: mintAmount, + MintToAddress: creator.String(), + } + err = wasmbinding.PerformMint(&tokenz.TokenFactoryKeeper, &tokenz.BankKeeper, ctx, creator, emptyDenomMintBinding) + require.NoError(t, err) + + // when + gotErr := wasmbinding.PerformBurn(&tokenz.TokenFactoryKeeper, ctx, creator, spec.burn) + // then + if spec.expErr { + require.Error(t, gotErr) + return + } + require.NoError(t, gotErr) + }) + } +} diff --git a/x/tokenfactory/bindings/validate_queries_test.go b/x/tokenfactory/bindings/validate_queries_test.go new file mode 100644 index 000000000..78a84b921 --- /dev/null +++ b/x/tokenfactory/bindings/validate_queries_test.go @@ -0,0 +1,115 @@ +package bindings_test + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + sdk "github.com/cosmos/cosmos-sdk/types" + + wasmbinding "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/bindings" +) + +func TestFullDenom(t *testing.T) { + actor := RandomAccountAddress() + + specs := map[string]struct { + addr string + subdenom string + expFullDenom string + expErr bool + }{ + "valid address": { + addr: actor.String(), + subdenom: "subDenom1", + expFullDenom: fmt.Sprintf("factory/%s/subDenom1", actor.String()), + }, + "empty address": { + addr: "", + subdenom: "subDenom1", + expErr: true, + }, + "invalid address": { + addr: "invalid", + subdenom: "subDenom1", + expErr: true, + }, + "empty sub-denom": { + addr: actor.String(), + subdenom: "", + expFullDenom: fmt.Sprintf("factory/%s/", actor.String()), + }, + "invalid sub-denom (contains underscore)": { + addr: actor.String(), + subdenom: "sub_denom", + expErr: true, + }, + } + for name, spec := range specs { + t.Run(name, func(t *testing.T) { + // when + gotFullDenom, gotErr := wasmbinding.GetFullDenom(spec.addr, spec.subdenom) + // then + if spec.expErr { + require.Error(t, gotErr) + return + } + require.NoError(t, gotErr) + assert.Equal(t, spec.expFullDenom, gotFullDenom, "exp %s but got %s", spec.expFullDenom, gotFullDenom) + }) + } +} + +func TestDenomAdmin(t *testing.T) { + addr := RandomAccountAddress() + app, ctx := SetupCustomApp(t, addr) + + // set token creation fee to zero to make testing easier + tfParams := app.TokenFactoryKeeper.GetParams(ctx) + tfParams.DenomCreationFee = sdk.NewCoins() + app.TokenFactoryKeeper.SetParams(ctx, tfParams) + + // create a subdenom via the token factory + admin := sdk.AccAddress([]byte("addr1_______________")) + tfDenom, err := app.TokenFactoryKeeper.CreateDenom(ctx, admin.String(), "subdenom") + require.NoError(t, err) + require.NotEmpty(t, tfDenom) + + queryPlugin := wasmbinding.NewQueryPlugin(&app.BankKeeper, &app.TokenFactoryKeeper) + + testCases := []struct { + name string + denom string + expectErr bool + expectAdmin string + }{ + { + name: "valid token factory denom", + denom: tfDenom, + expectAdmin: admin.String(), + }, + { + name: "invalid token factory denom", + denom: "uosmo", + expectErr: false, + expectAdmin: "", + }, + } + + for _, tc := range testCases { + tc := tc + + t.Run(tc.name, func(t *testing.T) { + resp, err := queryPlugin.GetDenomAdmin(ctx, tc.denom) + if tc.expectErr { + require.Error(t, err) + } else { + require.NoError(t, err) + require.NotNil(t, resp) + require.Equal(t, tc.expectAdmin, resp.Admin) + } + }) + } +} diff --git a/x/tokenfactory/bindings/wasm.go b/x/tokenfactory/bindings/wasm.go new file mode 100644 index 000000000..cb4d86430 --- /dev/null +++ b/x/tokenfactory/bindings/wasm.go @@ -0,0 +1,29 @@ +package bindings + +import ( + "github.com/CosmWasm/wasmd/x/wasm" + + wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" + + tokenfactorykeeper "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/keeper" + bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" +) + +func RegisterCustomPlugins( + bank *bankkeeper.BaseKeeper, + tokenFactory *tokenfactorykeeper.Keeper, +) []wasmkeeper.Option { + wasmQueryPlugin := NewQueryPlugin(bank, tokenFactory) + + queryPluginOpt := wasmkeeper.WithQueryPlugins(&wasmkeeper.QueryPlugins{ + Custom: CustomQuerier(wasmQueryPlugin), + }) + messengerDecoratorOpt := wasmkeeper.WithMessageHandlerDecorator( + CustomMessageDecorator(bank, tokenFactory), + ) + + return []wasm.Option{ + queryPluginOpt, + messengerDecoratorOpt, + } +} diff --git a/x/tokenfactory/client/cli/query.go b/x/tokenfactory/client/cli/query.go new file mode 100644 index 000000000..421a10c74 --- /dev/null +++ b/x/tokenfactory/client/cli/query.go @@ -0,0 +1,122 @@ +package cli + +import ( + "fmt" + + // "strings" + + "github.com/spf13/cobra" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + + // "github.com/cosmos/cosmos-sdk/client/flags" + // sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/types" +) + +// GetQueryCmd returns the cli query commands for this module +func GetQueryCmd() *cobra.Command { + // Group tokenfactory queries under a subcommand + cmd := &cobra.Command{ + Use: types.ModuleName, + Short: fmt.Sprintf("Querying commands for the %s module", types.ModuleName), + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + RunE: client.ValidateCmd, + } + + cmd.AddCommand( + GetParams(), + GetCmdDenomAuthorityMetadata(), + GetCmdDenomsFromCreator(), + ) + + return cmd +} + +// GetParams returns the params for the module +func GetParams() *cobra.Command { + cmd := &cobra.Command{ + Use: "params [flags]", + Short: "Get the params for the x/tokenfactory module", + Args: cobra.ExactArgs(0), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + queryClient := types.NewQueryClient(clientCtx) + + res, err := queryClient.Params(cmd.Context(), &types.QueryParamsRequest{}) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} + +// GetCmdDenomAuthorityMetadata returns the authority metadata for a queried denom +func GetCmdDenomAuthorityMetadata() *cobra.Command { + cmd := &cobra.Command{ + Use: "denom-authority-metadata [denom] [flags]", + Short: "Get the authority metadata for a specific denom", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + queryClient := types.NewQueryClient(clientCtx) + + res, err := queryClient.DenomAuthorityMetadata(cmd.Context(), &types.QueryDenomAuthorityMetadataRequest{ + Denom: args[0], + }) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} + +// GetCmdDenomsFromCreator a command to get a list of all tokens created by a specific creator address +func GetCmdDenomsFromCreator() *cobra.Command { + cmd := &cobra.Command{ + Use: "denoms-from-creator [creator address] [flags]", + Short: "Returns a list of all tokens created by a specific creator address", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + queryClient := types.NewQueryClient(clientCtx) + + res, err := queryClient.DenomsFromCreator(cmd.Context(), &types.QueryDenomsFromCreatorRequest{ + Creator: args[0], + }) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} diff --git a/x/tokenfactory/client/cli/tx.go b/x/tokenfactory/client/cli/tx.go new file mode 100644 index 000000000..5bde09974 --- /dev/null +++ b/x/tokenfactory/client/cli/tx.go @@ -0,0 +1,333 @@ +package cli + +import ( + "fmt" + "strconv" + "strings" + + "github.com/spf13/cobra" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/client/tx" + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/types" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" +) + +// GetTxCmd returns the transaction commands for this module +func GetTxCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: types.ModuleName, + Short: fmt.Sprintf("%s transactions subcommands", types.ModuleName), + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + RunE: client.ValidateCmd, + } + + cmd.AddCommand( + NewCreateDenomCmd(), + NewMintCmd(), + NewMintToCmd(), + NewBurnCmd(), + NewBurnFromCmd(), + NewForceTransferCmd(), + NewChangeAdminCmd(), + NewModifyDenomMetadataCmd(), + ) + + return cmd +} + +// NewCreateDenomCmd broadcast MsgCreateDenom +func NewCreateDenomCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "create-denom [subdenom] [flags]", + Short: "create a new denom from an account", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + txf := tx.NewFactoryCLI(clientCtx, cmd.Flags()).WithTxConfig(clientCtx.TxConfig).WithAccountRetriever(clientCtx.AccountRetriever) + + msg := types.NewMsgCreateDenom( + clientCtx.GetFromAddress().String(), + args[0], + ) + + return tx.GenerateOrBroadcastTxWithFactory(clientCtx, txf, msg) + }, + } + + flags.AddTxFlagsToCmd(cmd) + return cmd +} + +// NewMintCmd broadcast MsgMint +func NewMintCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "mint [amount] [flags]", + Short: "Mint a denom to your address. Must have admin authority to do so.", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + txf := tx.NewFactoryCLI(clientCtx, cmd.Flags()).WithTxConfig(clientCtx.TxConfig).WithAccountRetriever(clientCtx.AccountRetriever) + + amount, err := sdk.ParseCoinNormalized(args[0]) + if err != nil { + return err + } + + msg := types.NewMsgMint( + clientCtx.GetFromAddress().String(), + amount, + ) + + return tx.GenerateOrBroadcastTxWithFactory(clientCtx, txf, msg) + }, + } + + flags.AddTxFlagsToCmd(cmd) + return cmd +} + +// NewMintToCmd broadcast MsgMintTo +func NewMintToCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "mint-to [address] [amount] [flags]", + Short: "Mint a denom to an address. Must have admin authority to do so.", + Args: cobra.ExactArgs(2), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + txf := tx.NewFactoryCLI(clientCtx, cmd.Flags()).WithTxConfig(clientCtx.TxConfig).WithAccountRetriever(clientCtx.AccountRetriever) + + toAddr, err := sdk.AccAddressFromBech32(args[0]) + if err != nil { + return err + } + + amount, err := sdk.ParseCoinNormalized(args[1]) + if err != nil { + return err + } + + msg := types.NewMsgMintTo( + clientCtx.GetFromAddress().String(), + amount, + toAddr.String(), + ) + + return tx.GenerateOrBroadcastTxWithFactory(clientCtx, txf, msg) + }, + } + + flags.AddTxFlagsToCmd(cmd) + return cmd +} + +// NewBurnCmd broadcast MsgBurn +func NewBurnCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "burn [amount] [flags]", + Short: "Burn tokens from an address. Must have admin authority to do so.", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + txf := tx.NewFactoryCLI(clientCtx, cmd.Flags()).WithTxConfig(clientCtx.TxConfig).WithAccountRetriever(clientCtx.AccountRetriever) + + amount, err := sdk.ParseCoinNormalized(args[0]) + if err != nil { + return err + } + + msg := types.NewMsgBurn( + clientCtx.GetFromAddress().String(), + amount, + ) + + return tx.GenerateOrBroadcastTxWithFactory(clientCtx, txf, msg) + }, + } + + flags.AddTxFlagsToCmd(cmd) + return cmd +} + +// NewBurnFromCmd broadcast MsgBurnFrom +func NewBurnFromCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "burn-from [address] [amount] [flags]", + Short: "Burn tokens from an address. Must have admin authority to do so.", + Args: cobra.ExactArgs(2), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + txf := tx.NewFactoryCLI(clientCtx, cmd.Flags()).WithTxConfig(clientCtx.TxConfig).WithAccountRetriever(clientCtx.AccountRetriever) + + fromAddr, err := sdk.AccAddressFromBech32(args[0]) + if err != nil { + return err + } + + amount, err := sdk.ParseCoinNormalized(args[1]) + if err != nil { + return err + } + + msg := types.NewMsgBurnFrom( + clientCtx.GetFromAddress().String(), + amount, + fromAddr.String(), + ) + + return tx.GenerateOrBroadcastTxWithFactory(clientCtx, txf, msg) + }, + } + + flags.AddTxFlagsToCmd(cmd) + return cmd +} + +// NewForceTransferCmd broadcast MsgForceTransfer +func NewForceTransferCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "force-transfer [amount] [transfer-from-address] [transfer-to-address] [flags]", + Short: "Force transfer tokens from one address to another address. Must have admin authority to do so.", + Args: cobra.ExactArgs(3), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + txf := tx.NewFactoryCLI(clientCtx, cmd.Flags()).WithTxConfig(clientCtx.TxConfig).WithAccountRetriever(clientCtx.AccountRetriever) + + amount, err := sdk.ParseCoinNormalized(args[0]) + if err != nil { + return err + } + + msg := types.NewMsgForceTransfer( + clientCtx.GetFromAddress().String(), + amount, + args[1], + args[2], + ) + + return tx.GenerateOrBroadcastTxWithFactory(clientCtx, txf, msg) + }, + } + + flags.AddTxFlagsToCmd(cmd) + return cmd +} + +// NewChangeAdminCmd broadcast MsgChangeAdmin +func NewChangeAdminCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "change-admin [denom] [new-admin-address] [flags]", + Short: "Changes the admin address for a factory-created denom. Must have admin authority to do so.", + Args: cobra.ExactArgs(2), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + txf := tx.NewFactoryCLI(clientCtx, cmd.Flags()).WithTxConfig(clientCtx.TxConfig).WithAccountRetriever(clientCtx.AccountRetriever) + + msg := types.NewMsgChangeAdmin( + clientCtx.GetFromAddress().String(), + args[0], + args[1], + ) + + return tx.GenerateOrBroadcastTxWithFactory(clientCtx, txf, msg) + }, + } + + flags.AddTxFlagsToCmd(cmd) + return cmd +} + +// NewModifyDenomMetadataCmd broadcast a Bank Metadata modification transaction +func NewModifyDenomMetadataCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "modify-metadata [denom] [ticker-symbol] [description] [exponent] [flags]", + Short: "Changes the base data for frontends to query the data of.", + Args: cobra.ExactArgs(4), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + txf := tx.NewFactoryCLI(clientCtx, cmd.Flags()).WithTxConfig(clientCtx.TxConfig).WithAccountRetriever(clientCtx.AccountRetriever) + + fullDenom, ticker, desc := args[0], strings.ToUpper(args[1]), args[2] + + if !strings.HasPrefix(fullDenom, "factory/") { + return fmt.Errorf("denom must start with factory/") + } + + if len(ticker) == 0 { + return fmt.Errorf("ticker cannot be empty") + } + + // Exponent Checks + exponent, err := strconv.ParseUint(args[3], 10, 32) + if err != nil { + return err + } + + bankMetadata := banktypes.Metadata{ + Description: desc, + Display: fullDenom, + Symbol: ticker, + Name: fullDenom, + DenomUnits: []*banktypes.DenomUnit{ + { + Denom: fullDenom, + Exponent: 0, // must be 0 for the base denom + Aliases: []string{ticker}, + }, + { + Denom: ticker, + Exponent: uint32(exponent), + Aliases: []string{fullDenom}, + }, + }, + Base: fullDenom, + } + + msg := types.NewMsgSetDenomMetadata( + clientCtx.GetFromAddress().String(), + bankMetadata, + ) + + return tx.GenerateOrBroadcastTxWithFactory(clientCtx, txf, msg) + }, + } + + flags.AddTxFlagsToCmd(cmd) + return cmd +} diff --git a/x/tokenfactory/keeper/admins.go b/x/tokenfactory/keeper/admins.go new file mode 100644 index 000000000..c1294f536 --- /dev/null +++ b/x/tokenfactory/keeper/admins.go @@ -0,0 +1,49 @@ +package keeper + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/gogo/protobuf/proto" + + "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/types" +) + +// GetAuthorityMetadata returns the authority metadata for a specific denom +func (k Keeper) GetAuthorityMetadata(ctx sdk.Context, denom string) (types.DenomAuthorityMetadata, error) { + bz := k.GetDenomPrefixStore(ctx, denom).Get([]byte(types.DenomAuthorityMetadataKey)) + + metadata := types.DenomAuthorityMetadata{} + err := proto.Unmarshal(bz, &metadata) + if err != nil { + return types.DenomAuthorityMetadata{}, err + } + return metadata, nil +} + +// setAuthorityMetadata stores authority metadata for a specific denom +func (k Keeper) setAuthorityMetadata(ctx sdk.Context, denom string, metadata types.DenomAuthorityMetadata) error { + err := metadata.Validate() + if err != nil { + return err + } + + store := k.GetDenomPrefixStore(ctx, denom) + + bz, err := proto.Marshal(&metadata) + if err != nil { + return err + } + + store.Set([]byte(types.DenomAuthorityMetadataKey), bz) + return nil +} + +func (k Keeper) setAdmin(ctx sdk.Context, denom string, admin string) error { + metadata, err := k.GetAuthorityMetadata(ctx, denom) + if err != nil { + return err + } + + metadata.Admin = admin + + return k.setAuthorityMetadata(ctx, denom, metadata) +} diff --git a/x/tokenfactory/keeper/admins_test.go b/x/tokenfactory/keeper/admins_test.go new file mode 100644 index 000000000..b059c3195 --- /dev/null +++ b/x/tokenfactory/keeper/admins_test.go @@ -0,0 +1,522 @@ +package keeper_test + +import ( + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + + "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/types" +) + +func (suite *KeeperTestSuite) TestAdminMsgs() { + addr0bal := int64(0) + addr1bal := int64(0) + + bankKeeper := suite.App.BankKeeper + + suite.CreateDefaultDenom() + // Make sure that the admin is set correctly + queryRes, err := suite.queryClient.DenomAuthorityMetadata(suite.Ctx.Context(), &types.QueryDenomAuthorityMetadataRequest{ + Denom: suite.defaultDenom, + }) + suite.Require().NoError(err) + suite.Require().Equal(suite.TestAccs[0].String(), queryRes.AuthorityMetadata.Admin) + + // Test minting to admins own account + _, err = suite.msgServer.Mint(sdk.WrapSDKContext(suite.Ctx), types.NewMsgMint(suite.TestAccs[0].String(), sdk.NewInt64Coin(suite.defaultDenom, 10))) + addr0bal += 10 + suite.Require().NoError(err) + suite.Require().True(bankKeeper.GetBalance(suite.Ctx, suite.TestAccs[0], suite.defaultDenom).Amount.Int64() == addr0bal, bankKeeper.GetBalance(suite.Ctx, suite.TestAccs[0], suite.defaultDenom)) + + // Test minting to a different account + _, err = suite.msgServer.Mint(sdk.WrapSDKContext(suite.Ctx), types.NewMsgMintTo(suite.TestAccs[0].String(), sdk.NewInt64Coin(suite.defaultDenom, 10), suite.TestAccs[1].String())) + addr1bal += 10 + suite.Require().NoError(err) + suite.Require().True(suite.App.BankKeeper.GetBalance(suite.Ctx, suite.TestAccs[1], suite.defaultDenom).Amount.Int64() == addr1bal, suite.App.BankKeeper.GetBalance(suite.Ctx, suite.TestAccs[1], suite.defaultDenom)) + + // Test force transferring + _, err = suite.msgServer.ForceTransfer(sdk.WrapSDKContext(suite.Ctx), types.NewMsgForceTransfer(suite.TestAccs[0].String(), sdk.NewInt64Coin(suite.defaultDenom, 5), suite.TestAccs[1].String(), suite.TestAccs[0].String())) + addr1bal -= 5 + addr0bal += 5 + suite.Require().NoError(err) + suite.Require().True(suite.App.BankKeeper.GetBalance(suite.Ctx, suite.TestAccs[0], suite.defaultDenom).Amount.Int64() == addr0bal, suite.App.BankKeeper.GetBalance(suite.Ctx, suite.TestAccs[0], suite.defaultDenom)) + suite.Require().True(suite.App.BankKeeper.GetBalance(suite.Ctx, suite.TestAccs[1], suite.defaultDenom).Amount.Int64() == addr1bal, suite.App.BankKeeper.GetBalance(suite.Ctx, suite.TestAccs[1], suite.defaultDenom)) + + // Test burning from own account + _, err = suite.msgServer.Burn(sdk.WrapSDKContext(suite.Ctx), types.NewMsgBurn(suite.TestAccs[0].String(), sdk.NewInt64Coin(suite.defaultDenom, 5))) + suite.Require().NoError(err) + suite.Require().True(bankKeeper.GetBalance(suite.Ctx, suite.TestAccs[1], suite.defaultDenom).Amount.Int64() == addr1bal) + + // Test Change Admin + _, err = suite.msgServer.ChangeAdmin(sdk.WrapSDKContext(suite.Ctx), types.NewMsgChangeAdmin(suite.TestAccs[0].String(), suite.defaultDenom, suite.TestAccs[1].String())) + suite.Require().NoError(err) + queryRes, err = suite.queryClient.DenomAuthorityMetadata(suite.Ctx.Context(), &types.QueryDenomAuthorityMetadataRequest{ + Denom: suite.defaultDenom, + }) + suite.Require().NoError(err) + suite.Require().Equal(suite.TestAccs[1].String(), queryRes.AuthorityMetadata.Admin) + + // Make sure old admin can no longer do actions + _, err = suite.msgServer.Burn(sdk.WrapSDKContext(suite.Ctx), types.NewMsgBurn(suite.TestAccs[0].String(), sdk.NewInt64Coin(suite.defaultDenom, 5))) + suite.Require().Error(err) + + // Make sure the new admin works + _, err = suite.msgServer.Mint(sdk.WrapSDKContext(suite.Ctx), types.NewMsgMint(suite.TestAccs[1].String(), sdk.NewInt64Coin(suite.defaultDenom, 5))) + addr1bal += 5 + suite.Require().NoError(err) + suite.Require().True(bankKeeper.GetBalance(suite.Ctx, suite.TestAccs[1], suite.defaultDenom).Amount.Int64() == addr1bal) + + // Try setting admin to empty + _, err = suite.msgServer.ChangeAdmin(sdk.WrapSDKContext(suite.Ctx), types.NewMsgChangeAdmin(suite.TestAccs[1].String(), suite.defaultDenom, "")) + suite.Require().NoError(err) + queryRes, err = suite.queryClient.DenomAuthorityMetadata(suite.Ctx.Context(), &types.QueryDenomAuthorityMetadataRequest{ + Denom: suite.defaultDenom, + }) + suite.Require().NoError(err) + suite.Require().Equal("", queryRes.AuthorityMetadata.Admin) +} + +// TestMintDenom ensures the following properties of the MintMessage: +// * Noone can mint tokens for a denom that doesn't exist +// * Only the admin of a denom can mint tokens for it +// * The admin of a denom can mint tokens for it +func (suite *KeeperTestSuite) TestMintDenom() { + balances := make(map[string]int64) + for _, acc := range suite.TestAccs { + balances[acc.String()] = 0 + } + + // Create a denom + suite.CreateDefaultDenom() + + for _, tc := range []struct { + desc string + mintMsg types.MsgMint + expectPass bool + }{ + { + desc: "denom does not exist", + mintMsg: *types.NewMsgMint( + suite.TestAccs[0].String(), + sdk.NewInt64Coin("factory/osmo1t7egva48prqmzl59x5ngv4zx0dtrwewc9m7z44/evmos", 10), + ), + expectPass: false, + }, + { + desc: "mint is not by the admin", + mintMsg: *types.NewMsgMintTo( + suite.TestAccs[1].String(), + sdk.NewInt64Coin(suite.defaultDenom, 10), + suite.TestAccs[0].String(), + ), + expectPass: false, + }, + { + desc: "success case - mint to self", + mintMsg: *types.NewMsgMint( + suite.TestAccs[0].String(), + sdk.NewInt64Coin(suite.defaultDenom, 10), + ), + expectPass: true, + }, + { + desc: "success case - mint to another address", + mintMsg: *types.NewMsgMintTo( + suite.TestAccs[0].String(), + sdk.NewInt64Coin(suite.defaultDenom, 10), + suite.TestAccs[1].String(), + ), + expectPass: true, + }, + } { + suite.Run(fmt.Sprintf("Case %s", tc.desc), func() { + _, err := suite.msgServer.Mint(sdk.WrapSDKContext(suite.Ctx), &tc.mintMsg) + if tc.expectPass { + suite.Require().NoError(err) + balances[tc.mintMsg.MintToAddress] += tc.mintMsg.Amount.Amount.Int64() + } else { + suite.Require().Error(err) + } + + mintToAddr, _ := sdk.AccAddressFromBech32(tc.mintMsg.MintToAddress) + bal := suite.App.BankKeeper.GetBalance(suite.Ctx, mintToAddr, suite.defaultDenom).Amount + suite.Require().Equal(bal.Int64(), balances[tc.mintMsg.MintToAddress]) + }) + } +} + +func (suite *KeeperTestSuite) TestBurnDenom() { + // Create a denom. + suite.CreateDefaultDenom() + + // mint 1000 default token for all testAccs + balances := make(map[string]int64) + for _, acc := range suite.TestAccs { + _, err := suite.msgServer.Mint(sdk.WrapSDKContext(suite.Ctx), types.NewMsgMintTo(suite.TestAccs[0].String(), sdk.NewInt64Coin(suite.defaultDenom, 1000), acc.String())) + suite.Require().NoError(err) + balances[acc.String()] = 1000 + } + + for _, tc := range []struct { + desc string + burnMsg types.MsgBurn + expectPass bool + }{ + { + desc: "denom does not exist", + burnMsg: *types.NewMsgBurn( + suite.TestAccs[0].String(), + sdk.NewInt64Coin("factory/osmo1t7egva48prqmzl59x5ngv4zx0dtrwewc9m7z44/evmos", 10), + ), + expectPass: false, + }, + { + desc: "burn is not by the admin", + burnMsg: *types.NewMsgBurnFrom( + suite.TestAccs[1].String(), + sdk.NewInt64Coin(suite.defaultDenom, 10), + suite.TestAccs[0].String(), + ), + expectPass: false, + }, + { + desc: "burn more than balance", + burnMsg: *types.NewMsgBurn( + suite.TestAccs[0].String(), + sdk.NewInt64Coin(suite.defaultDenom, 10000), + ), + expectPass: false, + }, + { + desc: "success case - burn from self", + burnMsg: *types.NewMsgBurn( + suite.TestAccs[0].String(), + sdk.NewInt64Coin(suite.defaultDenom, 10), + ), + expectPass: true, + }, + { + desc: "success case - burn from another address", + burnMsg: *types.NewMsgBurnFrom( + suite.TestAccs[0].String(), + sdk.NewInt64Coin(suite.defaultDenom, 10), + suite.TestAccs[1].String(), + ), + expectPass: true, + }, + } { + suite.Run(fmt.Sprintf("Case %s", tc.desc), func() { + _, err := suite.msgServer.Burn(sdk.WrapSDKContext(suite.Ctx), &tc.burnMsg) + if tc.expectPass { + suite.Require().NoError(err) + balances[tc.burnMsg.BurnFromAddress] -= tc.burnMsg.Amount.Amount.Int64() + } else { + suite.Require().Error(err) + } + + burnFromAddr, _ := sdk.AccAddressFromBech32(tc.burnMsg.BurnFromAddress) + bal := suite.App.BankKeeper.GetBalance(suite.Ctx, burnFromAddr, suite.defaultDenom).Amount + suite.Require().Equal(bal.Int64(), balances[tc.burnMsg.BurnFromAddress]) + }) + } +} + +func (suite *KeeperTestSuite) TestForceTransferDenom() { + // Create a denom. + suite.CreateDefaultDenom() + + // mint 1000 default token for all testAccs + balances := make(map[string]int64) + for _, acc := range suite.TestAccs { + _, err := suite.msgServer.Mint(sdk.WrapSDKContext(suite.Ctx), types.NewMsgMintTo(suite.TestAccs[0].String(), sdk.NewInt64Coin(suite.defaultDenom, 1000), acc.String())) + suite.Require().NoError(err) + balances[acc.String()] = 1000 + } + + for _, tc := range []struct { + desc string + forceTransferMsg types.MsgForceTransfer + expectPass bool + }{ + { + desc: "valid force transfer", + forceTransferMsg: *types.NewMsgForceTransfer( + suite.TestAccs[0].String(), + sdk.NewInt64Coin(suite.defaultDenom, 10), + suite.TestAccs[1].String(), + suite.TestAccs[2].String(), + ), + expectPass: true, + }, + { + desc: "denom does not exist", + forceTransferMsg: *types.NewMsgForceTransfer( + suite.TestAccs[0].String(), + sdk.NewInt64Coin("factory/osmo1t7egva48prqmzl59x5ngv4zx0dtrwewc9m7z44/evmos", 10), + suite.TestAccs[1].String(), + suite.TestAccs[2].String(), + ), + expectPass: false, + }, + { + desc: "forceTransfer is not by the admin", + forceTransferMsg: *types.NewMsgForceTransfer( + suite.TestAccs[1].String(), + sdk.NewInt64Coin(suite.defaultDenom, 10), + suite.TestAccs[1].String(), + suite.TestAccs[2].String(), + ), + expectPass: false, + }, + { + desc: "forceTransfer is greater than the balance of", + forceTransferMsg: *types.NewMsgForceTransfer( + suite.TestAccs[0].String(), + sdk.NewInt64Coin(suite.defaultDenom, 10000), + suite.TestAccs[1].String(), + suite.TestAccs[2].String(), + ), + expectPass: false, + }, + } { + suite.Run(fmt.Sprintf("Case %s", tc.desc), func() { + _, err := suite.msgServer.ForceTransfer(sdk.WrapSDKContext(suite.Ctx), &tc.forceTransferMsg) + if tc.expectPass { + suite.Require().NoError(err) + + balances[tc.forceTransferMsg.TransferFromAddress] -= tc.forceTransferMsg.Amount.Amount.Int64() + balances[tc.forceTransferMsg.TransferToAddress] += tc.forceTransferMsg.Amount.Amount.Int64() + } else { + suite.Require().Error(err) + } + + fromAddr, err := sdk.AccAddressFromBech32(tc.forceTransferMsg.TransferFromAddress) + suite.Require().NoError(err) + fromBal := suite.App.BankKeeper.GetBalance(suite.Ctx, fromAddr, suite.defaultDenom).Amount + suite.Require().True(fromBal.Int64() == balances[tc.forceTransferMsg.TransferFromAddress]) + + toAddr, err := sdk.AccAddressFromBech32(tc.forceTransferMsg.TransferToAddress) + suite.Require().NoError(err) + toBal := suite.App.BankKeeper.GetBalance(suite.Ctx, toAddr, suite.defaultDenom).Amount + suite.Require().True(toBal.Int64() == balances[tc.forceTransferMsg.TransferToAddress]) + }) + } +} + +func (suite *KeeperTestSuite) TestChangeAdminDenom() { + for _, tc := range []struct { + desc string + msgChangeAdmin func(denom string) *types.MsgChangeAdmin + expectedChangeAdminPass bool + expectedAdminIndex int + msgMint func(denom string) *types.MsgMint + expectedMintPass bool + }{ + { + desc: "creator admin can't mint after setting to '' ", + msgChangeAdmin: func(denom string) *types.MsgChangeAdmin { + return types.NewMsgChangeAdmin(suite.TestAccs[0].String(), denom, "") + }, + expectedChangeAdminPass: true, + expectedAdminIndex: -1, + msgMint: func(denom string) *types.MsgMint { + return types.NewMsgMint(suite.TestAccs[0].String(), sdk.NewInt64Coin(denom, 5)) + }, + expectedMintPass: false, + }, + { + desc: "non-admins can't change the existing admin", + msgChangeAdmin: func(denom string) *types.MsgChangeAdmin { + return types.NewMsgChangeAdmin(suite.TestAccs[1].String(), denom, suite.TestAccs[2].String()) + }, + expectedChangeAdminPass: false, + expectedAdminIndex: 0, + }, + { + desc: "success change admin", + msgChangeAdmin: func(denom string) *types.MsgChangeAdmin { + return types.NewMsgChangeAdmin(suite.TestAccs[0].String(), denom, suite.TestAccs[1].String()) + }, + expectedAdminIndex: 1, + expectedChangeAdminPass: true, + msgMint: func(denom string) *types.MsgMint { + return types.NewMsgMint(suite.TestAccs[1].String(), sdk.NewInt64Coin(denom, 5)) + }, + expectedMintPass: true, + }, + } { + suite.Run(fmt.Sprintf("Case %s", tc.desc), func() { + // setup test + suite.SetupTest() + + // Create a denom and mint + res, err := suite.msgServer.CreateDenom(sdk.WrapSDKContext(suite.Ctx), types.NewMsgCreateDenom(suite.TestAccs[0].String(), "bitcoin")) + suite.Require().NoError(err) + + testDenom := res.GetNewTokenDenom() + + _, err = suite.msgServer.Mint(sdk.WrapSDKContext(suite.Ctx), types.NewMsgMint(suite.TestAccs[0].String(), sdk.NewInt64Coin(testDenom, 10))) + suite.Require().NoError(err) + + _, err = suite.msgServer.ChangeAdmin(sdk.WrapSDKContext(suite.Ctx), tc.msgChangeAdmin(testDenom)) + if tc.expectedChangeAdminPass { + suite.Require().NoError(err) + } else { + suite.Require().Error(err) + } + + queryRes, err := suite.queryClient.DenomAuthorityMetadata(suite.Ctx.Context(), &types.QueryDenomAuthorityMetadataRequest{ + Denom: testDenom, + }) + suite.Require().NoError(err) + + // expectedAdminIndex with negative value is assumed as admin with value of "" + const emptyStringAdminIndexFlag = -1 + if tc.expectedAdminIndex == emptyStringAdminIndexFlag { + suite.Require().Equal("", queryRes.AuthorityMetadata.Admin) + } else { + suite.Require().Equal(suite.TestAccs[tc.expectedAdminIndex].String(), queryRes.AuthorityMetadata.Admin) + } + + // we test mint to test if admin authority is performed properly after admin change. + if tc.msgMint != nil { + _, err := suite.msgServer.Mint(sdk.WrapSDKContext(suite.Ctx), tc.msgMint(testDenom)) + if tc.expectedMintPass { + suite.Require().NoError(err) + } else { + suite.Require().Error(err) + } + } + }) + } +} + +func (suite *KeeperTestSuite) TestSetDenomMetaData() { + // setup test + suite.SetupTest() + suite.CreateDefaultDenom() + + for _, tc := range []struct { + desc string + msgSetDenomMetadata types.MsgSetDenomMetadata + expectedPass bool + }{ + { + desc: "successful set denom metadata", + msgSetDenomMetadata: *types.NewMsgSetDenomMetadata(suite.TestAccs[0].String(), banktypes.Metadata{ + Description: "yeehaw", + DenomUnits: []*banktypes.DenomUnit{ + { + Denom: suite.defaultDenom, + Exponent: 0, + }, + { + Denom: "uosmo", + Exponent: 6, + }, + }, + Base: suite.defaultDenom, + Display: "uosmo", + Name: "OSMO", + Symbol: "OSMO", + }), + expectedPass: true, + }, + { + desc: "non existent factory denom name", + msgSetDenomMetadata: *types.NewMsgSetDenomMetadata(suite.TestAccs[0].String(), banktypes.Metadata{ + Description: "yeehaw", + DenomUnits: []*banktypes.DenomUnit{ + { + Denom: fmt.Sprintf("factory/%s/litecoin", suite.TestAccs[0].String()), + Exponent: 0, + }, + { + Denom: "uosmo", + Exponent: 6, + }, + }, + Base: fmt.Sprintf("factory/%s/litecoin", suite.TestAccs[0].String()), + Display: "uosmo", + Name: "OSMO", + Symbol: "OSMO", + }), + expectedPass: false, + }, + { + desc: "non-factory denom", + msgSetDenomMetadata: *types.NewMsgSetDenomMetadata(suite.TestAccs[0].String(), banktypes.Metadata{ + Description: "yeehaw", + DenomUnits: []*banktypes.DenomUnit{ + { + Denom: "uosmo", + Exponent: 0, + }, + { + Denom: "uosmoo", + Exponent: 6, + }, + }, + Base: "uosmo", + Display: "uosmoo", + Name: "OSMO", + Symbol: "OSMO", + }), + expectedPass: false, + }, + { + desc: "wrong admin", + msgSetDenomMetadata: *types.NewMsgSetDenomMetadata(suite.TestAccs[1].String(), banktypes.Metadata{ + Description: "yeehaw", + DenomUnits: []*banktypes.DenomUnit{ + { + Denom: suite.defaultDenom, + Exponent: 0, + }, + { + Denom: "uosmo", + Exponent: 6, + }, + }, + Base: suite.defaultDenom, + Display: "uosmo", + Name: "OSMO", + Symbol: "OSMO", + }), + expectedPass: false, + }, + { + desc: "invalid metadata (missing display denom unit)", + msgSetDenomMetadata: *types.NewMsgSetDenomMetadata(suite.TestAccs[0].String(), banktypes.Metadata{ + Description: "yeehaw", + DenomUnits: []*banktypes.DenomUnit{ + { + Denom: suite.defaultDenom, + Exponent: 0, + }, + }, + Base: suite.defaultDenom, + Display: "uosmo", + Name: "OSMO", + Symbol: "OSMO", + }), + expectedPass: false, + }, + } { + suite.Run(fmt.Sprintf("Case %s", tc.desc), func() { + bankKeeper := suite.App.BankKeeper + res, err := suite.msgServer.SetDenomMetadata(sdk.WrapSDKContext(suite.Ctx), &tc.msgSetDenomMetadata) + if tc.expectedPass { + suite.Require().NoError(err) + suite.Require().NotNil(res) + + md, found := bankKeeper.GetDenomMetaData(suite.Ctx, suite.defaultDenom) + suite.Require().True(found) + suite.Require().Equal(tc.msgSetDenomMetadata.Metadata.Name, md.Name) + } else { + suite.Require().Error(err) + } + }) + } +} diff --git a/x/tokenfactory/keeper/bankactions.go b/x/tokenfactory/keeper/bankactions.go new file mode 100644 index 000000000..dff42306d --- /dev/null +++ b/x/tokenfactory/keeper/bankactions.go @@ -0,0 +1,86 @@ +package keeper + +import ( + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/types" +) + +func (k Keeper) mintTo(ctx sdk.Context, amount sdk.Coin, mintTo string) error { + // verify that denom is an x/tokenfactory denom + _, _, err := types.DeconstructDenom(amount.Denom) + if err != nil { + return err + } + + err = k.bankKeeper.MintCoins(ctx, types.ModuleName, sdk.NewCoins(amount)) + if err != nil { + return err + } + + addr, err := sdk.AccAddressFromBech32(mintTo) + if err != nil { + return err + } + + if k.bankKeeper.BlockedAddr(addr) { + return fmt.Errorf("failed to mint to blocked address: %s", addr) + } + + return k.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, + addr, + sdk.NewCoins(amount)) +} + +func (k Keeper) burnFrom(ctx sdk.Context, amount sdk.Coin, burnFrom string) error { + // verify that denom is an x/tokenfactory denom + _, _, err := types.DeconstructDenom(amount.Denom) + if err != nil { + return err + } + + addr, err := sdk.AccAddressFromBech32(burnFrom) + if err != nil { + return err + } + + if k.bankKeeper.BlockedAddr(addr) { + return fmt.Errorf("failed to burn from blocked address: %s", addr) + } + + err = k.bankKeeper.SendCoinsFromAccountToModule(ctx, + addr, + types.ModuleName, + sdk.NewCoins(amount)) + if err != nil { + return err + } + + return k.bankKeeper.BurnCoins(ctx, types.ModuleName, sdk.NewCoins(amount)) +} + +func (k Keeper) forceTransfer(ctx sdk.Context, amount sdk.Coin, fromAddr string, toAddr string) error { + // verify that denom is an x/tokenfactory denom + _, _, err := types.DeconstructDenom(amount.Denom) + if err != nil { + return err + } + + fromSdkAddr, err := sdk.AccAddressFromBech32(fromAddr) + if err != nil { + return err + } + + toSdkAddr, err := sdk.AccAddressFromBech32(toAddr) + if err != nil { + return err + } + + if k.bankKeeper.BlockedAddr(toSdkAddr) { + return fmt.Errorf("failed to force transfer to blocked address: %s", toSdkAddr) + } + + return k.bankKeeper.SendCoins(ctx, fromSdkAddr, toSdkAddr, sdk.NewCoins(amount)) +} diff --git a/x/tokenfactory/keeper/createdenom.go b/x/tokenfactory/keeper/createdenom.go new file mode 100644 index 000000000..6658e55a6 --- /dev/null +++ b/x/tokenfactory/keeper/createdenom.go @@ -0,0 +1,95 @@ +package keeper + +import ( + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + + "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/types" +) + +// ConvertToBaseToken converts a fee amount in a whitelisted fee token to the base fee token amount +func (k Keeper) CreateDenom(ctx sdk.Context, creatorAddr string, subdenom string) (newTokenDenom string, err error) { + denom, err := k.validateCreateDenom(ctx, creatorAddr, subdenom) + if err != nil { + return "", err + } + + err = k.chargeForCreateDenom(ctx, creatorAddr, subdenom) + if err != nil { + return "", err + } + + err = k.createDenomAfterValidation(ctx, creatorAddr, denom) + return denom, err +} + +// Runs CreateDenom logic after the charge and all denom validation has been handled. +// Made into a second function for genesis initialization. +func (k Keeper) createDenomAfterValidation(ctx sdk.Context, creatorAddr string, denom string) (err error) { + denomMetaData := banktypes.Metadata{ + DenomUnits: []*banktypes.DenomUnit{{ + Denom: denom, + Exponent: 0, + }}, + Base: denom, + } + + k.bankKeeper.SetDenomMetaData(ctx, denomMetaData) + + authorityMetadata := types.DenomAuthorityMetadata{ + Admin: creatorAddr, + } + err = k.setAuthorityMetadata(ctx, denom, authorityMetadata) + if err != nil { + return err + } + + k.addDenomFromCreator(ctx, creatorAddr, denom) + return nil +} + +func (k Keeper) validateCreateDenom(ctx sdk.Context, creatorAddr string, subdenom string) (newTokenDenom string, err error) { + // Temporary check until IBC bug is sorted out + if k.bankKeeper.HasSupply(ctx, subdenom) { + return "", fmt.Errorf("temporary error until IBC bug is sorted out, " + + "can't create subdenoms that are the same as a native denom") + } + + denom, err := types.GetTokenDenom(creatorAddr, subdenom) + if err != nil { + return "", err + } + + _, found := k.bankKeeper.GetDenomMetaData(ctx, denom) + if found { + return "", types.ErrDenomExists + } + + return denom, nil +} + +func (k Keeper) chargeForCreateDenom(ctx sdk.Context, creatorAddr string, _ string) (err error) { + params := k.GetParams(ctx) + + // if DenomCreationFee is non-zero, transfer the tokens from the creator + // account to community pool + if params.DenomCreationFee != nil { + accAddr, err := sdk.AccAddressFromBech32(creatorAddr) + if err != nil { + return err + } + + if err := k.communityPoolKeeper.FundCommunityPool(ctx, params.DenomCreationFee, accAddr); err != nil { + return err + } + } + + // if DenomCreationGasConsume is non-zero, consume the gas + if params.DenomCreationGasConsume != 0 { + ctx.GasMeter().ConsumeGas(params.DenomCreationGasConsume, "consume denom creation gas") + } + + return nil +} diff --git a/x/tokenfactory/keeper/createdenom_test.go b/x/tokenfactory/keeper/createdenom_test.go new file mode 100644 index 000000000..889758da5 --- /dev/null +++ b/x/tokenfactory/keeper/createdenom_test.go @@ -0,0 +1,163 @@ +package keeper_test + +import ( + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/testhelpers" + "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/types" +) + +func (suite *KeeperTestSuite) TestMsgCreateDenom() { + var ( + tokenFactoryKeeper = suite.App.TokenFactoryKeeper + bankKeeper = suite.App.BankKeeper + denomCreationFee = tokenFactoryKeeper.GetParams(suite.Ctx).DenomCreationFee + ) + + // Get balance of acc 0 before creating a denom + preCreateBalance := bankKeeper.GetBalance(suite.Ctx, suite.TestAccs[0], denomCreationFee[0].Denom) + + // Creating a denom should work + res, err := suite.msgServer.CreateDenom(sdk.WrapSDKContext(suite.Ctx), types.NewMsgCreateDenom(suite.TestAccs[0].String(), "bitcoin")) + suite.Require().NoError(err) + suite.Require().NotEmpty(res.GetNewTokenDenom()) + + // Make sure that the admin is set correctly + queryRes, err := suite.queryClient.DenomAuthorityMetadata(suite.Ctx.Context(), &types.QueryDenomAuthorityMetadataRequest{ + Denom: res.GetNewTokenDenom(), + }) + suite.Require().NoError(err) + suite.Require().Equal(suite.TestAccs[0].String(), queryRes.AuthorityMetadata.Admin) + + // Make sure that creation fee was deducted + postCreateBalance := bankKeeper.GetBalance(suite.Ctx, suite.TestAccs[0], tokenFactoryKeeper.GetParams(suite.Ctx).DenomCreationFee[0].Denom) + suite.Require().True(preCreateBalance.Sub(postCreateBalance).IsEqual(denomCreationFee[0])) + + // Make sure that a second version of the same denom can't be recreated + _, err = suite.msgServer.CreateDenom(sdk.WrapSDKContext(suite.Ctx), types.NewMsgCreateDenom(suite.TestAccs[0].String(), "bitcoin")) + suite.Require().Error(err) + + // Creating a second denom should work + res, err = suite.msgServer.CreateDenom(sdk.WrapSDKContext(suite.Ctx), types.NewMsgCreateDenom(suite.TestAccs[0].String(), "litecoin")) + suite.Require().NoError(err) + suite.Require().NotEmpty(res.GetNewTokenDenom()) + + // Try querying all the denoms created by suite.TestAccs[0] + queryRes2, err := suite.queryClient.DenomsFromCreator(suite.Ctx.Context(), &types.QueryDenomsFromCreatorRequest{ + Creator: suite.TestAccs[0].String(), + }) + suite.Require().NoError(err) + suite.Require().Len(queryRes2.Denoms, 2) + + // Make sure that a second account can create a denom with the same subdenom + res, err = suite.msgServer.CreateDenom(sdk.WrapSDKContext(suite.Ctx), types.NewMsgCreateDenom(suite.TestAccs[1].String(), "bitcoin")) + suite.Require().NoError(err) + suite.Require().NotEmpty(res.GetNewTokenDenom()) + + // Make sure that an address with a "/" in it can't create denoms + _, err = suite.msgServer.CreateDenom(sdk.WrapSDKContext(suite.Ctx), types.NewMsgCreateDenom("osmosis.eth/creator", "bitcoin")) + suite.Require().Error(err) +} + +func (suite *KeeperTestSuite) TestCreateDenom() { + var ( + primaryDenom = types.DefaultParams().DenomCreationFee[0].Denom + secondaryDenom = testhelpers.SecondaryDenom + defaultDenomCreationFee = types.Params{DenomCreationFee: sdk.NewCoins(sdk.NewCoin(primaryDenom, sdk.NewInt(50000000)))} + twoDenomCreationFee = types.Params{DenomCreationFee: sdk.NewCoins(sdk.NewCoin(primaryDenom, sdk.NewInt(50000000)), sdk.NewCoin(secondaryDenom, sdk.NewInt(50000000)))} + nilCreationFee = types.Params{DenomCreationFee: nil} + largeCreationFee = types.Params{DenomCreationFee: sdk.NewCoins(sdk.NewCoin(primaryDenom, sdk.NewInt(5000000000)))} + ) + + for _, tc := range []struct { + desc string + denomCreationFee types.Params + setup func() + subdenom string + valid bool + }{ + { + desc: "subdenom too long", + denomCreationFee: defaultDenomCreationFee, + subdenom: "assadsadsadasdasdsadsadsadsadsadsadsklkadaskkkdasdasedskhanhassyeunganassfnlksdflksafjlkasd", + valid: false, + }, + { + desc: "subdenom and creator pair already exists", + denomCreationFee: defaultDenomCreationFee, + setup: func() { + _, err := suite.msgServer.CreateDenom(sdk.WrapSDKContext(suite.Ctx), types.NewMsgCreateDenom(suite.TestAccs[0].String(), "bitcoin")) + suite.Require().NoError(err) + }, + subdenom: "bitcoin", + valid: false, + }, + { + desc: "success case: defaultDenomCreationFee", + denomCreationFee: defaultDenomCreationFee, + subdenom: "evmos", + valid: true, + }, + { + desc: "success case: twoDenomCreationFee", + denomCreationFee: twoDenomCreationFee, + subdenom: "catcoin", + valid: true, + }, + { + desc: "success case: nilCreationFee", + denomCreationFee: nilCreationFee, + subdenom: "czcoin", + valid: true, + }, + { + desc: "account doesn't have enough to pay for denom creation fee", + denomCreationFee: largeCreationFee, + subdenom: "tooexpensive", + valid: false, + }, + { + desc: "subdenom having invalid characters", + denomCreationFee: defaultDenomCreationFee, + subdenom: "bit/***///&&&/coin", + valid: false, + }, + } { + suite.SetupTest() + suite.Run(fmt.Sprintf("Case %s", tc.desc), func() { + if tc.setup != nil { + tc.setup() + } + tokenFactoryKeeper := suite.App.TokenFactoryKeeper + bankKeeper := suite.App.BankKeeper + // Set denom creation fee in params + tokenFactoryKeeper.SetParams(suite.Ctx, tc.denomCreationFee) + denomCreationFee := tokenFactoryKeeper.GetParams(suite.Ctx).DenomCreationFee + suite.Require().Equal(tc.denomCreationFee.DenomCreationFee, denomCreationFee) + + // note balance, create a tokenfactory denom, then note balance again + preCreateBalance := bankKeeper.GetAllBalances(suite.Ctx, suite.TestAccs[0]) + res, err := suite.msgServer.CreateDenom(sdk.WrapSDKContext(suite.Ctx), types.NewMsgCreateDenom(suite.TestAccs[0].String(), tc.subdenom)) + postCreateBalance := bankKeeper.GetAllBalances(suite.Ctx, suite.TestAccs[0]) + if tc.valid { + suite.Require().NoError(err) + suite.Require().True(preCreateBalance.Sub(postCreateBalance).IsEqual(denomCreationFee)) + + // Make sure that the admin is set correctly + queryRes, err := suite.queryClient.DenomAuthorityMetadata(suite.Ctx.Context(), &types.QueryDenomAuthorityMetadataRequest{ + Denom: res.GetNewTokenDenom(), + }) + + suite.Require().NoError(err) + suite.Require().Equal(suite.TestAccs[0].String(), queryRes.AuthorityMetadata.Admin) + + } else { + suite.Require().Error(err) + // Ensure we don't charge if we expect an error + suite.Require().True(preCreateBalance.IsEqual(postCreateBalance)) + } + }) + } +} diff --git a/x/tokenfactory/keeper/creators.go b/x/tokenfactory/keeper/creators.go new file mode 100644 index 000000000..d200c0603 --- /dev/null +++ b/x/tokenfactory/keeper/creators.go @@ -0,0 +1,29 @@ +package keeper + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" +) + +func (k Keeper) addDenomFromCreator(ctx sdk.Context, creator, denom string) { + store := k.GetCreatorPrefixStore(ctx, creator) + store.Set([]byte(denom), []byte(denom)) +} + +func (k Keeper) GetDenomsFromCreator(ctx sdk.Context, creator string) []string { + store := k.GetCreatorPrefixStore(ctx, creator) + + iterator := store.Iterator(nil, nil) + defer iterator.Close() + + denoms := []string{} + for ; iterator.Valid(); iterator.Next() { + denoms = append(denoms, string(iterator.Key())) + } + return denoms +} + +func (k Keeper) GetAllDenomsIterator(ctx sdk.Context) sdk.Iterator { + return k.GetCreatorsPrefixStore(ctx).Iterator(nil, nil) +} + +// TODO: Get all denoms a user is the admin of currently diff --git a/x/tokenfactory/keeper/genesis.go b/x/tokenfactory/keeper/genesis.go new file mode 100644 index 000000000..bd8c82de5 --- /dev/null +++ b/x/tokenfactory/keeper/genesis.go @@ -0,0 +1,58 @@ +package keeper + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/types" +) + +// InitGenesis initializes the tokenfactory module's state from a provided genesis +// state. +func (k Keeper) InitGenesis(ctx sdk.Context, genState types.GenesisState) { + k.CreateModuleAccount(ctx) + + if genState.Params.DenomCreationFee == nil { + genState.Params.DenomCreationFee = sdk.NewCoins() + } + k.SetParams(ctx, genState.Params) + + for _, genDenom := range genState.GetFactoryDenoms() { + creator, _, err := types.DeconstructDenom(genDenom.GetDenom()) + if err != nil { + panic(err) + } + err = k.createDenomAfterValidation(ctx, creator, genDenom.GetDenom()) + if err != nil { + panic(err) + } + err = k.setAuthorityMetadata(ctx, genDenom.GetDenom(), genDenom.GetAuthorityMetadata()) + if err != nil { + panic(err) + } + } +} + +// ExportGenesis returns the tokenfactory module's exported genesis. +func (k Keeper) ExportGenesis(ctx sdk.Context) *types.GenesisState { + genDenoms := []types.GenesisDenom{} + iterator := k.GetAllDenomsIterator(ctx) + defer iterator.Close() + for ; iterator.Valid(); iterator.Next() { + denom := string(iterator.Value()) + + authorityMetadata, err := k.GetAuthorityMetadata(ctx, denom) + if err != nil { + panic(err) + } + + genDenoms = append(genDenoms, types.GenesisDenom{ + Denom: denom, + AuthorityMetadata: authorityMetadata, + }) + } + + return &types.GenesisState{ + FactoryDenoms: genDenoms, + Params: k.GetParams(ctx), + } +} diff --git a/x/tokenfactory/keeper/genesis_test.go b/x/tokenfactory/keeper/genesis_test.go new file mode 100644 index 000000000..862cbbdd8 --- /dev/null +++ b/x/tokenfactory/keeper/genesis_test.go @@ -0,0 +1,59 @@ +package keeper_test + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + + "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/types" +) + +func (suite *KeeperTestSuite) TestGenesis() { + genesisState := types.GenesisState{ + FactoryDenoms: []types.GenesisDenom{ + { + Denom: "factory/cosmos1t7egva48prqmzl59x5ngv4zx0dtrwewcdqdjr8/bitcoin", + AuthorityMetadata: types.DenomAuthorityMetadata{ + Admin: "cosmos1t7egva48prqmzl59x5ngv4zx0dtrwewcdqdjr8", + }, + }, + { + Denom: "factory/cosmos1t7egva48prqmzl59x5ngv4zx0dtrwewcdqdjr8/diff-admin", + AuthorityMetadata: types.DenomAuthorityMetadata{ + Admin: "cosmos15czt5nhlnvayqq37xun9s9yus0d6y26dx74r5p", + }, + }, + { + Denom: "factory/cosmos1t7egva48prqmzl59x5ngv4zx0dtrwewcdqdjr8/litecoin", + AuthorityMetadata: types.DenomAuthorityMetadata{ + Admin: "cosmos1t7egva48prqmzl59x5ngv4zx0dtrwewcdqdjr8", + }, + }, + }, + } + + suite.SetupTestForInitGenesis() + app := suite.App + + // Test both with bank denom metadata set, and not set. + for i, denom := range genesisState.FactoryDenoms { + // hacky, sets bank metadata to exist if i != 0, to cover both cases. + if i != 0 { + app.BankKeeper.SetDenomMetaData(suite.Ctx, banktypes.Metadata{Base: denom.GetDenom()}) + } + } + + // check before initGenesis that the module account is nil + tokenfactoryModuleAccount := app.AccountKeeper.GetAccount(suite.Ctx, app.AccountKeeper.GetModuleAddress(types.ModuleName)) + suite.Require().Nil(tokenfactoryModuleAccount) + + app.TokenFactoryKeeper.SetParams(suite.Ctx, types.Params{DenomCreationFee: sdk.Coins{sdk.NewInt64Coin("uosmo", 100)}}) + app.TokenFactoryKeeper.InitGenesis(suite.Ctx, genesisState) + + // check that the module account is now initialized + tokenfactoryModuleAccount = app.AccountKeeper.GetAccount(suite.Ctx, app.AccountKeeper.GetModuleAddress(types.ModuleName)) + suite.Require().NotNil(tokenfactoryModuleAccount) + + exportedGenesis := app.TokenFactoryKeeper.ExportGenesis(suite.Ctx) + suite.Require().NotNil(exportedGenesis) + suite.Require().Equal(genesisState, *exportedGenesis) +} diff --git a/x/tokenfactory/keeper/grpc_query.go b/x/tokenfactory/keeper/grpc_query.go new file mode 100644 index 000000000..3ed6e27c9 --- /dev/null +++ b/x/tokenfactory/keeper/grpc_query.go @@ -0,0 +1,35 @@ +package keeper + +import ( + "context" + + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/types" +) + +var _ types.QueryServer = Keeper{} + +func (k Keeper) Params(ctx context.Context, _ *types.QueryParamsRequest) (*types.QueryParamsResponse, error) { + sdkCtx := sdk.UnwrapSDKContext(ctx) + params := k.GetParams(sdkCtx) + + return &types.QueryParamsResponse{Params: params}, nil +} + +func (k Keeper) DenomAuthorityMetadata(ctx context.Context, req *types.QueryDenomAuthorityMetadataRequest) (*types.QueryDenomAuthorityMetadataResponse, error) { + sdkCtx := sdk.UnwrapSDKContext(ctx) + + authorityMetadata, err := k.GetAuthorityMetadata(sdkCtx, req.GetDenom()) + if err != nil { + return nil, err + } + + return &types.QueryDenomAuthorityMetadataResponse{AuthorityMetadata: authorityMetadata}, nil +} + +func (k Keeper) DenomsFromCreator(ctx context.Context, req *types.QueryDenomsFromCreatorRequest) (*types.QueryDenomsFromCreatorResponse, error) { + sdkCtx := sdk.UnwrapSDKContext(ctx) + denoms := k.GetDenomsFromCreator(sdkCtx, req.GetCreator()) + return &types.QueryDenomsFromCreatorResponse{Denoms: denoms}, nil +} diff --git a/x/tokenfactory/keeper/keeper.go b/x/tokenfactory/keeper/keeper.go new file mode 100644 index 000000000..0f30be034 --- /dev/null +++ b/x/tokenfactory/keeper/keeper.go @@ -0,0 +1,87 @@ +package keeper + +import ( + "fmt" + + "github.com/tendermint/tendermint/libs/log" + + "github.com/cosmos/cosmos-sdk/store/prefix" + storetypes "github.com/cosmos/cosmos-sdk/store/types" + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/types" + + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" +) + +type ( + Keeper struct { + storeKey storetypes.StoreKey + + paramSpace paramtypes.Subspace + + accountKeeper types.AccountKeeper + bankKeeper types.BankKeeper + communityPoolKeeper types.CommunityPoolKeeper + + enabledCapabilities []string + } +) + +// NewKeeper returns a new instance of the x/tokenfactory keeper +func NewKeeper( + storeKey storetypes.StoreKey, + paramSpace paramtypes.Subspace, + accountKeeper types.AccountKeeper, + bankKeeper types.BankKeeper, + communityPoolKeeper types.CommunityPoolKeeper, + enabledCapabilities []string, +) Keeper { + if !paramSpace.HasKeyTable() { + paramSpace = paramSpace.WithKeyTable(types.ParamKeyTable()) + } + + return Keeper{ + storeKey: storeKey, + paramSpace: paramSpace, + + accountKeeper: accountKeeper, + bankKeeper: bankKeeper, + communityPoolKeeper: communityPoolKeeper, + + enabledCapabilities: enabledCapabilities, + } +} + +// Logger returns a logger for the x/tokenfactory module +func (k Keeper) Logger(ctx sdk.Context) log.Logger { + return ctx.Logger().With("module", fmt.Sprintf("x/%s", types.ModuleName)) +} + +// GetDenomPrefixStore returns the substore for a specific denom +func (k Keeper) GetDenomPrefixStore(ctx sdk.Context, denom string) sdk.KVStore { + store := ctx.KVStore(k.storeKey) + return prefix.NewStore(store, types.GetDenomPrefixStore(denom)) +} + +// GetCreatorPrefixStore returns the substore for a specific creator address +func (k Keeper) GetCreatorPrefixStore(ctx sdk.Context, creator string) sdk.KVStore { + store := ctx.KVStore(k.storeKey) + return prefix.NewStore(store, types.GetCreatorPrefix(creator)) +} + +// GetCreatorsPrefixStore returns the substore that contains a list of creators +func (k Keeper) GetCreatorsPrefixStore(ctx sdk.Context) sdk.KVStore { + store := ctx.KVStore(k.storeKey) + return prefix.NewStore(store, types.GetCreatorsPrefix()) +} + +// CreateModuleAccount creates a module account with minting and burning capabilities +// This account isn't intended to store any coins, +// it purely mints and burns them on behalf of the admin of respective denoms, +// and sends to the relevant address. +func (k Keeper) CreateModuleAccount(ctx sdk.Context) { + moduleAcc := authtypes.NewEmptyModuleAccount(types.ModuleName, authtypes.Minter, authtypes.Burner) + k.accountKeeper.SetModuleAccount(ctx, moduleAcc) +} diff --git a/x/tokenfactory/keeper/keeper_test.go b/x/tokenfactory/keeper/keeper_test.go new file mode 100644 index 000000000..da8589008 --- /dev/null +++ b/x/tokenfactory/keeper/keeper_test.go @@ -0,0 +1,64 @@ +package keeper_test + +import ( + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/suite" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + + "github.com/CosmosTokenFactory/token-factory/app/apptesting" + "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/keeper" + "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/testhelpers" + "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/types" +) + +type KeeperTestSuite struct { + apptesting.KeeperTestHelper + + queryClient types.QueryClient + msgServer types.MsgServer + // defaultDenom is on the suite, as it depends on the creator test address. + defaultDenom string +} + +func TestKeeperTestSuite(t *testing.T) { + suite.Run(t, new(KeeperTestSuite)) +} + +func (suite *KeeperTestSuite) SetupTest() { + suite.Setup() + // Fund every TestAcc with two denoms, one of which is the denom creation fee + fundAccsAmount := sdk.NewCoins(sdk.NewCoin(types.DefaultParams().DenomCreationFee[0].Denom, types.DefaultParams().DenomCreationFee[0].Amount.MulRaw(100)), sdk.NewCoin(testhelpers.SecondaryDenom, testhelpers.SecondaryAmount)) + for _, acc := range suite.TestAccs { + suite.FundAcc(acc, fundAccsAmount) + } + + suite.queryClient = types.NewQueryClient(suite.QueryHelper) + suite.msgServer = keeper.NewMsgServerImpl(suite.App.TokenFactoryKeeper) +} + +func (suite *KeeperTestSuite) CreateDefaultDenom() { + res, _ := suite.msgServer.CreateDenom(sdk.WrapSDKContext(suite.Ctx), types.NewMsgCreateDenom(suite.TestAccs[0].String(), "bitcoin")) + suite.defaultDenom = res.GetNewTokenDenom() +} + +func (suite *KeeperTestSuite) TestCreateModuleAccount() { + app := suite.App + + // remove module account + tokenfactoryModuleAccount := app.AccountKeeper.GetAccount(suite.Ctx, app.AccountKeeper.GetModuleAddress(types.ModuleName)) + app.AccountKeeper.RemoveAccount(suite.Ctx, tokenfactoryModuleAccount) + + // ensure module account was removed + suite.Ctx = app.BaseApp.NewContext(false, tmproto.Header{}) + tokenfactoryModuleAccount = app.AccountKeeper.GetAccount(suite.Ctx, app.AccountKeeper.GetModuleAddress(types.ModuleName)) + suite.Require().Nil(tokenfactoryModuleAccount) + + // create module account + app.TokenFactoryKeeper.CreateModuleAccount(suite.Ctx) + + // check that the module account is now initialized + tokenfactoryModuleAccount = app.AccountKeeper.GetAccount(suite.Ctx, app.AccountKeeper.GetModuleAddress(types.ModuleName)) + suite.Require().NotNil(tokenfactoryModuleAccount) +} diff --git a/x/tokenfactory/keeper/msg_server.go b/x/tokenfactory/keeper/msg_server.go new file mode 100644 index 000000000..6a4e09be3 --- /dev/null +++ b/x/tokenfactory/keeper/msg_server.go @@ -0,0 +1,209 @@ +package keeper + +import ( + "context" + + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/types" +) + +type msgServer struct { + Keeper +} + +// NewMsgServerImpl returns an implementation of the MsgServer interface +// for the provided Keeper. +func NewMsgServerImpl(keeper Keeper) types.MsgServer { + return &msgServer{Keeper: keeper} +} + +var _ types.MsgServer = msgServer{} + +func (server msgServer) CreateDenom(goCtx context.Context, msg *types.MsgCreateDenom) (*types.MsgCreateDenomResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + + denom, err := server.Keeper.CreateDenom(ctx, msg.Sender, msg.Subdenom) + if err != nil { + return nil, err + } + + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + types.TypeMsgCreateDenom, + sdk.NewAttribute(types.AttributeCreator, msg.Sender), + sdk.NewAttribute(types.AttributeNewTokenDenom, denom), + ), + }) + + return &types.MsgCreateDenomResponse{ + NewTokenDenom: denom, + }, nil +} + +func (server msgServer) Mint(goCtx context.Context, msg *types.MsgMint) (*types.MsgMintResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + + // pay some extra gas cost to give a better error here. + _, denomExists := server.bankKeeper.GetDenomMetaData(ctx, msg.Amount.Denom) + if !denomExists { + return nil, types.ErrDenomDoesNotExist.Wrapf("denom: %s", msg.Amount.Denom) + } + + authorityMetadata, err := server.Keeper.GetAuthorityMetadata(ctx, msg.Amount.GetDenom()) + if err != nil { + return nil, err + } + + if msg.Sender != authorityMetadata.GetAdmin() { + return nil, types.ErrUnauthorized + } + + if msg.MintToAddress == "" { + msg.MintToAddress = msg.Sender + } + + err = server.Keeper.mintTo(ctx, msg.Amount, msg.MintToAddress) + if err != nil { + return nil, err + } + + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + types.TypeMsgMint, + sdk.NewAttribute(types.AttributeMintToAddress, msg.Sender), + sdk.NewAttribute(types.AttributeAmount, msg.Amount.String()), + ), + }) + + return &types.MsgMintResponse{}, nil +} + +func (server msgServer) Burn(goCtx context.Context, msg *types.MsgBurn) (*types.MsgBurnResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + + authorityMetadata, err := server.Keeper.GetAuthorityMetadata(ctx, msg.Amount.GetDenom()) + if err != nil { + return nil, err + } + + if msg.Sender != authorityMetadata.GetAdmin() { + return nil, types.ErrUnauthorized + } + + if msg.BurnFromAddress == "" { + msg.BurnFromAddress = msg.Sender + } else if !types.IsCapabilityEnabled(server.Keeper.enabledCapabilities, types.EnableBurnFrom) { + return nil, types.ErrCapabilityNotEnabled + } + + err = server.Keeper.burnFrom(ctx, msg.Amount, msg.BurnFromAddress) + if err != nil { + return nil, err + } + + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + types.TypeMsgBurn, + sdk.NewAttribute(types.AttributeBurnFromAddress, msg.Sender), + sdk.NewAttribute(types.AttributeAmount, msg.Amount.String()), + ), + }) + + return &types.MsgBurnResponse{}, nil +} + +func (server msgServer) ForceTransfer(goCtx context.Context, msg *types.MsgForceTransfer) (*types.MsgForceTransferResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + + if !types.IsCapabilityEnabled(server.Keeper.enabledCapabilities, types.EnableForceTransfer) { + return nil, types.ErrCapabilityNotEnabled + } + + authorityMetadata, err := server.Keeper.GetAuthorityMetadata(ctx, msg.Amount.GetDenom()) + if err != nil { + return nil, err + } + + if msg.Sender != authorityMetadata.GetAdmin() { + return nil, types.ErrUnauthorized + } + + err = server.Keeper.forceTransfer(ctx, msg.Amount, msg.TransferFromAddress, msg.TransferToAddress) + if err != nil { + return nil, err + } + + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + types.TypeMsgForceTransfer, + sdk.NewAttribute(types.AttributeTransferFromAddress, msg.TransferFromAddress), + sdk.NewAttribute(types.AttributeTransferToAddress, msg.TransferToAddress), + sdk.NewAttribute(types.AttributeAmount, msg.Amount.String()), + ), + }) + + return &types.MsgForceTransferResponse{}, nil +} + +func (server msgServer) ChangeAdmin(goCtx context.Context, msg *types.MsgChangeAdmin) (*types.MsgChangeAdminResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + + authorityMetadata, err := server.Keeper.GetAuthorityMetadata(ctx, msg.Denom) + if err != nil { + return nil, err + } + + if msg.Sender != authorityMetadata.GetAdmin() { + return nil, types.ErrUnauthorized + } + + err = server.Keeper.setAdmin(ctx, msg.Denom, msg.NewAdmin) + if err != nil { + return nil, err + } + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + types.TypeMsgChangeAdmin, + sdk.NewAttribute(types.AttributeDenom, msg.GetDenom()), + sdk.NewAttribute(types.AttributeNewAdmin, msg.NewAdmin), + ), + }) + + return &types.MsgChangeAdminResponse{}, nil +} + +func (server msgServer) SetDenomMetadata(goCtx context.Context, msg *types.MsgSetDenomMetadata) (*types.MsgSetDenomMetadataResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + + if !types.IsCapabilityEnabled(server.Keeper.enabledCapabilities, types.EnableSetMetadata) { + return nil, types.ErrCapabilityNotEnabled + } + + // Defense in depth validation of metadata + err := msg.Metadata.Validate() + if err != nil { + return nil, err + } + + authorityMetadata, err := server.Keeper.GetAuthorityMetadata(ctx, msg.Metadata.Base) + if err != nil { + return nil, err + } + + if msg.Sender != authorityMetadata.GetAdmin() { + return nil, types.ErrUnauthorized + } + + server.Keeper.bankKeeper.SetDenomMetaData(ctx, msg.Metadata) + + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + types.TypeMsgSetDenomMetadata, + sdk.NewAttribute(types.AttributeDenom, msg.Metadata.Base), + sdk.NewAttribute(types.AttributeDenomMetadata, msg.Metadata.String()), + ), + }) + + return &types.MsgSetDenomMetadataResponse{}, nil +} diff --git a/x/tokenfactory/keeper/msg_server_test.go b/x/tokenfactory/keeper/msg_server_test.go new file mode 100644 index 000000000..14e497177 --- /dev/null +++ b/x/tokenfactory/keeper/msg_server_test.go @@ -0,0 +1,247 @@ +package keeper_test + +import ( + "fmt" + + "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/types" + + sdk "github.com/cosmos/cosmos-sdk/types" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" +) + +// TestMintDenomMsg tests TypeMsgMint message is emitted on a successful mint +func (suite *KeeperTestSuite) TestMintDenomMsg() { + // Create a denom + suite.CreateDefaultDenom() + + for _, tc := range []struct { + desc string + amount int64 + mintDenom string + admin string + valid bool + expectedMessageEvents int + }{ + { + desc: "denom does not exist", + amount: 10, + mintDenom: "factory/osmo1t7egva48prqmzl59x5ngv4zx0dtrwewc9m7z44/evmos", + admin: suite.TestAccs[0].String(), + valid: false, + }, + { + desc: "success case", + amount: 10, + mintDenom: suite.defaultDenom, + admin: suite.TestAccs[0].String(), + valid: true, + expectedMessageEvents: 1, + }, + } { + suite.Run(fmt.Sprintf("Case %s", tc.desc), func() { + ctx := suite.Ctx.WithEventManager(sdk.NewEventManager()) + suite.Require().Equal(0, len(ctx.EventManager().Events())) + // Test mint message + suite.msgServer.Mint(sdk.WrapSDKContext(ctx), types.NewMsgMint(tc.admin, sdk.NewInt64Coin(tc.mintDenom, 10))) //nolint:errcheck + // Ensure current number and type of event is emitted + suite.AssertEventEmitted(ctx, types.TypeMsgMint, tc.expectedMessageEvents) + }) + } +} + +// TestBurnDenomMsg tests TypeMsgBurn message is emitted on a successful burn +func (suite *KeeperTestSuite) TestBurnDenomMsg() { + // Create a denom. + suite.CreateDefaultDenom() + // mint 10 default token for testAcc[0] + suite.msgServer.Mint(sdk.WrapSDKContext(suite.Ctx), types.NewMsgMint(suite.TestAccs[0].String(), sdk.NewInt64Coin(suite.defaultDenom, 10))) //nolint:errcheck + + for _, tc := range []struct { + desc string + amount int64 + burnDenom string + admin string + valid bool + expectedMessageEvents int + }{ + { + desc: "denom does not exist", + burnDenom: "factory/osmo1t7egva48prqmzl59x5ngv4zx0dtrwewc9m7z44/evmos", + admin: suite.TestAccs[0].String(), + valid: false, + }, + { + desc: "success case", + burnDenom: suite.defaultDenom, + admin: suite.TestAccs[0].String(), + valid: true, + expectedMessageEvents: 1, + }, + } { + suite.Run(fmt.Sprintf("Case %s", tc.desc), func() { + ctx := suite.Ctx.WithEventManager(sdk.NewEventManager()) + suite.Require().Equal(0, len(ctx.EventManager().Events())) + // Test burn message + suite.msgServer.Burn(sdk.WrapSDKContext(ctx), types.NewMsgBurn(tc.admin, sdk.NewInt64Coin(tc.burnDenom, 10))) //nolint:errcheck + // Ensure current number and type of event is emitted + suite.AssertEventEmitted(ctx, types.TypeMsgBurn, tc.expectedMessageEvents) + }) + } +} + +// TestCreateDenomMsg tests TypeMsgCreateDenom message is emitted on a successful denom creation +func (suite *KeeperTestSuite) TestCreateDenomMsg() { + defaultDenomCreationFee := types.Params{DenomCreationFee: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(50000000)))} + for _, tc := range []struct { + desc string + denomCreationFee types.Params + subdenom string + valid bool + expectedMessageEvents int + }{ + { + desc: "subdenom too long", + denomCreationFee: defaultDenomCreationFee, + subdenom: "assadsadsadasdasdsadsadsadsadsadsadsklkadaskkkdasdasedskhanhassyeunganassfnlksdflksafjlkasd", + valid: false, + }, + { + desc: "success case: defaultDenomCreationFee", + denomCreationFee: defaultDenomCreationFee, + subdenom: "evmos", + valid: true, + expectedMessageEvents: 1, + }, + } { + suite.SetupTest() + suite.Run(fmt.Sprintf("Case %s", tc.desc), func() { + tokenFactoryKeeper := suite.App.TokenFactoryKeeper + ctx := suite.Ctx.WithEventManager(sdk.NewEventManager()) + suite.Require().Equal(0, len(ctx.EventManager().Events())) + // Set denom creation fee in params + tokenFactoryKeeper.SetParams(suite.Ctx, tc.denomCreationFee) + // Test create denom message + suite.msgServer.CreateDenom(sdk.WrapSDKContext(ctx), types.NewMsgCreateDenom(suite.TestAccs[0].String(), tc.subdenom)) //nolint:errcheck + // Ensure current number and type of event is emitted + suite.AssertEventEmitted(ctx, types.TypeMsgCreateDenom, tc.expectedMessageEvents) + }) + } +} + +// TestChangeAdminDenomMsg tests TypeMsgChangeAdmin message is emitted on a successful admin change +func (suite *KeeperTestSuite) TestChangeAdminDenomMsg() { + for _, tc := range []struct { + desc string + msgChangeAdmin func(denom string) *types.MsgChangeAdmin + expectedChangeAdminPass bool + expectedAdminIndex int + msgMint func(denom string) *types.MsgMint + expectedMintPass bool + expectedMessageEvents int + }{ + { + desc: "non-admins can't change the existing admin", + msgChangeAdmin: func(denom string) *types.MsgChangeAdmin { + return types.NewMsgChangeAdmin(suite.TestAccs[1].String(), denom, suite.TestAccs[2].String()) + }, + expectedChangeAdminPass: false, + expectedAdminIndex: 0, + }, + { + desc: "success change admin", + msgChangeAdmin: func(denom string) *types.MsgChangeAdmin { + return types.NewMsgChangeAdmin(suite.TestAccs[0].String(), denom, suite.TestAccs[1].String()) + }, + expectedAdminIndex: 1, + expectedChangeAdminPass: true, + expectedMessageEvents: 1, + msgMint: func(denom string) *types.MsgMint { + return types.NewMsgMint(suite.TestAccs[1].String(), sdk.NewInt64Coin(denom, 5)) + }, + expectedMintPass: true, + }, + } { + suite.Run(fmt.Sprintf("Case %s", tc.desc), func() { + // setup test + suite.SetupTest() + ctx := suite.Ctx.WithEventManager(sdk.NewEventManager()) + suite.Require().Equal(0, len(ctx.EventManager().Events())) + // Create a denom and mint + res, err := suite.msgServer.CreateDenom(sdk.WrapSDKContext(ctx), types.NewMsgCreateDenom(suite.TestAccs[0].String(), "bitcoin")) + suite.Require().NoError(err) + testDenom := res.GetNewTokenDenom() + suite.msgServer.Mint(sdk.WrapSDKContext(ctx), types.NewMsgMint(suite.TestAccs[0].String(), sdk.NewInt64Coin(testDenom, 10))) //nolint:errcheck + // Test change admin message + suite.msgServer.ChangeAdmin(sdk.WrapSDKContext(ctx), tc.msgChangeAdmin(testDenom)) //nolint:errcheck + // Ensure current number and type of event is emitted + suite.AssertEventEmitted(ctx, types.TypeMsgChangeAdmin, tc.expectedMessageEvents) + }) + } +} + +// TestSetDenomMetaDataMsg tests TypeMsgSetDenomMetadata message is emitted on a successful denom metadata change +func (suite *KeeperTestSuite) TestSetDenomMetaDataMsg() { + // setup test + suite.SetupTest() + suite.CreateDefaultDenom() + + for _, tc := range []struct { + desc string + msgSetDenomMetadata types.MsgSetDenomMetadata + expectedPass bool + expectedMessageEvents int + }{ + { + desc: "successful set denom metadata", + msgSetDenomMetadata: *types.NewMsgSetDenomMetadata(suite.TestAccs[0].String(), banktypes.Metadata{ + Description: "yeehaw", + DenomUnits: []*banktypes.DenomUnit{ + { + Denom: suite.defaultDenom, + Exponent: 0, + }, + { + Denom: "uosmo", + Exponent: 6, + }, + }, + Base: suite.defaultDenom, + Display: "uosmo", + Name: "OSMO", + Symbol: "OSMO", + }), + expectedPass: true, + expectedMessageEvents: 1, + }, + { + desc: "non existent factory denom name", + msgSetDenomMetadata: *types.NewMsgSetDenomMetadata(suite.TestAccs[0].String(), banktypes.Metadata{ + Description: "yeehaw", + DenomUnits: []*banktypes.DenomUnit{ + { + Denom: fmt.Sprintf("factory/%s/litecoin", suite.TestAccs[0].String()), + Exponent: 0, + }, + { + Denom: "uosmo", + Exponent: 6, + }, + }, + Base: fmt.Sprintf("factory/%s/litecoin", suite.TestAccs[0].String()), + Display: "uosmo", + Name: "OSMO", + Symbol: "OSMO", + }), + expectedPass: false, + }, + } { + suite.Run(fmt.Sprintf("Case %s", tc.desc), func() { + ctx := suite.Ctx.WithEventManager(sdk.NewEventManager()) + suite.Require().Equal(0, len(ctx.EventManager().Events())) + // Test set denom metadata message + suite.msgServer.SetDenomMetadata(sdk.WrapSDKContext(ctx), &tc.msgSetDenomMetadata) //nolint:errcheck + // Ensure current number and type of event is emitted + suite.AssertEventEmitted(ctx, types.TypeMsgSetDenomMetadata, tc.expectedMessageEvents) + }) + } +} diff --git a/x/tokenfactory/keeper/params.go b/x/tokenfactory/keeper/params.go new file mode 100644 index 000000000..07b37d8e7 --- /dev/null +++ b/x/tokenfactory/keeper/params.go @@ -0,0 +1,18 @@ +package keeper + +import ( + "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/types" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// GetParams returns the total set params. +func (k Keeper) GetParams(ctx sdk.Context) (params types.Params) { + k.paramSpace.GetParamSet(ctx, ¶ms) + return params +} + +// SetParams sets the total set of params. +func (k Keeper) SetParams(ctx sdk.Context, params types.Params) { + k.paramSpace.SetParamSet(ctx, ¶ms) +} diff --git a/x/tokenfactory/module.go b/x/tokenfactory/module.go new file mode 100644 index 000000000..936f1bf3f --- /dev/null +++ b/x/tokenfactory/module.go @@ -0,0 +1,229 @@ +/* +The tokenfactory module allows any account to create a new token with +the name `factory/{creator address}/{subdenom}`. + +- Mint and burn user denom to and form any account +- Create a transfer of their denom between any two accounts +- Change the admin. In the future, more admin capabilities may be added. +*/ +package tokenfactory + +import ( + "context" + "encoding/json" + "fmt" + "math/rand" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/codec" + cdctypes "github.com/cosmos/cosmos-sdk/codec/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/module" + "github.com/gorilla/mux" + "github.com/grpc-ecosystem/grpc-gateway/runtime" + "github.com/spf13/cobra" + abci "github.com/tendermint/tendermint/abci/types" + + simulation "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/simulation" + simtypes "github.com/cosmos/cosmos-sdk/types/simulation" + + "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/client/cli" + "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/keeper" + "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/types" +) + +var ( + _ module.AppModule = AppModule{} + _ module.AppModuleBasic = AppModuleBasic{} +) + +// ---------------------------------------------------------------------------- +// AppModuleBasic +// ---------------------------------------------------------------------------- + +// AppModuleBasic implements the AppModuleBasic interface for the capability module. +type AppModuleBasic struct{} + +func NewAppModuleBasic() AppModuleBasic { + return AppModuleBasic{} +} + +// Name returns the x/tokenfactory module's name. +func (AppModuleBasic) Name() string { + return types.ModuleName +} + +func (AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { + types.RegisterCodec(cdc) +} + +// RegisterInterfaces registers the module's interface types +func (a AppModuleBasic) RegisterInterfaces(reg cdctypes.InterfaceRegistry) { + types.RegisterInterfaces(reg) +} + +// DefaultGenesis returns the x/tokenfactory module's default genesis state. +func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage { + return cdc.MustMarshalJSON(types.DefaultGenesis()) +} + +// ValidateGenesis performs genesis state validation for the x/tokenfactory module. +func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, _ client.TxEncodingConfig, bz json.RawMessage) error { + var genState types.GenesisState + if err := cdc.UnmarshalJSON(bz, &genState); err != nil { + return fmt.Errorf("failed to unmarshal %s genesis state: %w", types.ModuleName, err) + } + + return genState.Validate() +} + +// RegisterRESTRoutes registers the capability module's REST service handlers. +func (AppModuleBasic) RegisterRESTRoutes(_ client.Context, _ *mux.Router) { +} + +// RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the module. +func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) { + types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(clientCtx)) //nolint:errcheck +} + +// GetTxCmd returns the x/tokenfactory module's root tx command. +func (a AppModuleBasic) GetTxCmd() *cobra.Command { + return cli.GetTxCmd() +} + +// GetQueryCmd returns the x/tokenfactory module's root query command. +func (AppModuleBasic) GetQueryCmd() *cobra.Command { + return cli.GetQueryCmd() +} + +// ---------------------------------------------------------------------------- +// AppModule +// ---------------------------------------------------------------------------- + +// AppModule implements the AppModule interface for the capability module. +type AppModule struct { + AppModuleBasic + + keeper keeper.Keeper + accountKeeper types.AccountKeeper + bankKeeper types.BankKeeper +} + +func NewAppModule( + keeper keeper.Keeper, + accountKeeper types.AccountKeeper, + bankKeeper types.BankKeeper, +) AppModule { + return AppModule{ + AppModuleBasic: NewAppModuleBasic(), + keeper: keeper, + accountKeeper: accountKeeper, + bankKeeper: bankKeeper, + } +} + +// Name returns the x/tokenfactory module's name. +func (am AppModule) Name() string { + return am.AppModuleBasic.Name() +} + +// Route returns the x/tokenfactory module's message routing key. +func (am AppModule) Route() sdk.Route { + return sdk.Route{} +} + +// QuerierRoute returns the x/tokenfactory module's query routing key. +func (AppModule) QuerierRoute() string { return types.QuerierRoute } + +// LegacyQuerierHandler returns the x/tokenfactory module's Querier. +func (am AppModule) LegacyQuerierHandler(_ *codec.LegacyAmino) sdk.Querier { + return nil +} + +// RegisterServices registers a GRPC query service to respond to the +// module-specific GRPC queries. +func (am AppModule) RegisterServices(cfg module.Configurator) { + types.RegisterMsgServer(cfg.MsgServer(), keeper.NewMsgServerImpl(am.keeper)) + types.RegisterQueryServer(cfg.QueryServer(), am.keeper) +} + +// RegisterInvariants registers the x/tokenfactory module's invariants. +func (am AppModule) RegisterInvariants(_ sdk.InvariantRegistry) {} + +// InitGenesis performs the x/tokenfactory module's genesis initialization. It +// returns no validator updates. +func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, gs json.RawMessage) []abci.ValidatorUpdate { + var genState types.GenesisState + cdc.MustUnmarshalJSON(gs, &genState) + + am.keeper.InitGenesis(ctx, genState) + + return []abci.ValidatorUpdate{} +} + +// ExportGenesis returns the x/tokenfactory module's exported genesis state as raw +// JSON bytes. +func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.RawMessage { + genState := am.keeper.ExportGenesis(ctx) + return cdc.MustMarshalJSON(genState) +} + +// ConsensusVersion implements ConsensusVersion. +func (AppModule) ConsensusVersion() uint64 { return 1 } + +// BeginBlock executes all ABCI BeginBlock logic respective to the tokenfactory module. +func (am AppModule) BeginBlock(_ sdk.Context, _ abci.RequestBeginBlock) {} + +// EndBlock executes all ABCI EndBlock logic respective to the tokenfactory module. It +// returns no validator updates. +func (am AppModule) EndBlock(_ sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate { + return []abci.ValidatorUpdate{} +} + +// ___________________________________________________________________________ + +// AppModuleSimulationV2 functions + +// // GenerateGenesisState creates a randomized GenState of the tokenfactory module. +// func (am AppModule) SimulatorGenesisState(simState *module.SimulationState, s *simtypes.SimCtx) { +// tfDefaultGen := types.DefaultGenesis() +// tfDefaultGen.Params.DenomCreationFee = sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(10000000))) +// tfDefaultGenJson := simState.Cdc.MustMarshalJSON(tfDefaultGen) +// simState.GenState[types.ModuleName] = tfDefaultGenJson +// } + +// // WeightedOperations returns the all the lockup module operations with their respective weights. +// func (am AppModule) Actions() []simtypes.Action { +// return []simtypes.Action{ +// simtypes.NewMsgBasedAction("create token factory token", am.keeper, simulation.RandomMsgCreateDenom), +// simtypes.NewMsgBasedAction("mint token factory token", am.keeper, simulation.RandomMsgMintDenom), +// simtypes.NewMsgBasedAction("burn token factory token", am.keeper, simulation.RandomMsgBurnDenom), +// simtypes.NewMsgBasedAction("change admin token factory token", am.keeper, simulation.RandomMsgChangeAdmin), +// } +// } + +// ____________________________________________________________________________ + +// AppModuleSimulation functions +func (AppModule) GenerateGenesisState(simState *module.SimulationState) { + simulation.RandomizedGenState(simState) +} + +// GenerateGenesisState creates a randomized GenState of the bank module. +func (am AppModule) ProposalContents(_ module.SimulationState) []simtypes.WeightedProposalContent { + return nil +} + +// RandomizedParams creates randomized bank param changes for the simulator. +func (am AppModule) RandomizedParams(r *rand.Rand) []simtypes.ParamChange { + return simulation.ParamChanges(r) +} + +// RegisterStoreDecoder registers a decoder for supply module's types +func (am AppModule) RegisterStoreDecoder(_ sdk.StoreDecoderRegistry) { +} + +// WeightedOperations returns the all the gov module operations with their respective weights. +func (am AppModule) WeightedOperations(simState module.SimulationState) []simtypes.WeightedOperation { + return simulation.WeightedOperations(&simState, am.keeper, am.accountKeeper, am.bankKeeper) +} diff --git a/x/tokenfactory/simulation/genesis.go b/x/tokenfactory/simulation/genesis.go new file mode 100644 index 000000000..d839fad40 --- /dev/null +++ b/x/tokenfactory/simulation/genesis.go @@ -0,0 +1,25 @@ +package simulation + +import ( + "math/rand" + + "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/module" +) + +func RandDenomCreationFeeParam(r *rand.Rand) sdk.Coins { + amount := r.Int63n(10_000_000) + return sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(amount))) +} + +func RandomizedGenState(simstate *module.SimulationState) { + tfGenesis := types.DefaultGenesis() + + _, err := simstate.Cdc.MarshalJSON(tfGenesis) + if err != nil { + panic(err) + } + + simstate.GenState[types.ModuleName] = simstate.Cdc.MustMarshalJSON(tfGenesis) +} diff --git a/x/tokenfactory/simulation/operations.go b/x/tokenfactory/simulation/operations.go new file mode 100644 index 000000000..87e70653b --- /dev/null +++ b/x/tokenfactory/simulation/operations.go @@ -0,0 +1,411 @@ +package simulation + +import ( + "math/rand" + + "github.com/CosmosTokenFactory/token-factory/app/params" + "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/types" + "github.com/cosmos/cosmos-sdk/baseapp" + simappparams "github.com/cosmos/cosmos-sdk/simapp/params" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/module" + simtypes "github.com/cosmos/cosmos-sdk/types/simulation" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + "github.com/cosmos/cosmos-sdk/x/simulation" +) + +// Simulation operation weights constants +// +//nolint:gosec +const ( + OpWeightMsgCreateDenom = "op_weight_msg_create_denom" + OpWeightMsgMint = "op_weight_msg_mint" + OpWeightMsgBurn = "op_weight_msg_burn" + OpWeightMsgChangeAdmin = "op_weight_msg_change_admin" + OpWeightMsgSetDenomMetadata = "op_weight_msg_set_denom_metadata" + OpWeightMsgForceTransfer = "op_weight_msg_force_transfer" +) + +type TokenfactoryKeeper interface { + GetParams(ctx sdk.Context) (params types.Params) + GetAuthorityMetadata(ctx sdk.Context, denom string) (types.DenomAuthorityMetadata, error) + GetAllDenomsIterator(ctx sdk.Context) sdk.Iterator + GetDenomsFromCreator(ctx sdk.Context, creator string) []string +} + +type BankKeeper interface { + simulation.BankKeeper + GetAllBalances(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins + GetBalance(ctx sdk.Context, addr sdk.AccAddress, denom string) sdk.Coin +} + +func WeightedOperations( + simstate *module.SimulationState, + tfKeeper TokenfactoryKeeper, + ak types.AccountKeeper, + bk BankKeeper, +) simulation.WeightedOperations { + var ( + weightMsgCreateDenom int + weightMsgMint int + weightMsgBurn int + weightMsgChangeAdmin int + weightMsgSetDenomMetadata int + weightMsgForceTransfer int + ) + + simstate.AppParams.GetOrGenerate(simstate.Cdc, OpWeightMsgCreateDenom, &weightMsgCreateDenom, nil, + func(_ *rand.Rand) { + weightMsgCreateDenom = params.DefaultWeightMsgCreateDenom + }, + ) + simstate.AppParams.GetOrGenerate(simstate.Cdc, OpWeightMsgMint, &weightMsgMint, nil, + func(_ *rand.Rand) { + weightMsgMint = params.DefaultWeightMsgMint + }, + ) + simstate.AppParams.GetOrGenerate(simstate.Cdc, OpWeightMsgBurn, &weightMsgBurn, nil, + func(_ *rand.Rand) { + weightMsgBurn = params.DefaultWeightMsgBurn + }, + ) + simstate.AppParams.GetOrGenerate(simstate.Cdc, OpWeightMsgChangeAdmin, &weightMsgChangeAdmin, nil, + func(_ *rand.Rand) { + weightMsgChangeAdmin = params.DefaultWeightMsgChangeAdmin + }, + ) + simstate.AppParams.GetOrGenerate(simstate.Cdc, OpWeightMsgSetDenomMetadata, &weightMsgSetDenomMetadata, nil, + func(_ *rand.Rand) { + weightMsgSetDenomMetadata = params.DefaultWeightMsgSetDenomMetadata + }, + ) + simstate.AppParams.GetOrGenerate(simstate.Cdc, OpWeightMsgForceTransfer, &weightMsgForceTransfer, nil, + func(_ *rand.Rand) { + weightMsgForceTransfer = params.DefaultWeightMsgForceTransfer + }, + ) + + return simulation.WeightedOperations{ + simulation.NewWeightedOperation( + weightMsgCreateDenom, + SimulateMsgCreateDenom( + tfKeeper, + ak, + bk, + ), + ), + simulation.NewWeightedOperation( + weightMsgMint, + SimulateMsgMint( + tfKeeper, + ak, + bk, + DefaultSimulationDenomSelector, + ), + ), + simulation.NewWeightedOperation( + weightMsgBurn, + SimulateMsgBurn( + tfKeeper, + ak, + bk, + DefaultSimulationDenomSelector, + ), + ), + simulation.NewWeightedOperation( + weightMsgChangeAdmin, + SimulateMsgChangeAdmin( + tfKeeper, + ak, + bk, + DefaultSimulationDenomSelector, + ), + ), + simulation.NewWeightedOperation( + weightMsgSetDenomMetadata, + SimulateMsgSetDenomMetadata( + tfKeeper, + ak, + bk, + DefaultSimulationDenomSelector, + ), + ), + } +} + +type DenomSelector = func(*rand.Rand, sdk.Context, TokenfactoryKeeper, string) (string, bool) + +func DefaultSimulationDenomSelector(r *rand.Rand, ctx sdk.Context, tfKeeper TokenfactoryKeeper, creator string) (string, bool) { + denoms := tfKeeper.GetDenomsFromCreator(ctx, creator) + if len(denoms) == 0 { + return "", false + } + randPos := r.Intn(len(denoms)) + + return denoms[randPos], true +} + +func SimulateMsgSetDenomMetadata( + tfKeeper TokenfactoryKeeper, + ak types.AccountKeeper, + bk BankKeeper, + denomSelector DenomSelector, +) simtypes.Operation { + return func( + r *rand.Rand, + app *baseapp.BaseApp, + ctx sdk.Context, + accs []simtypes.Account, + chainID string, + ) (simtypes.OperationMsg, []simtypes.FutureOperation, error) { + // Get create denom account + createdDenomAccount, _ := simtypes.RandomAcc(r, accs) + + // Get demon + denom, hasDenom := denomSelector(r, ctx, tfKeeper, createdDenomAccount.Address.String()) + if !hasDenom { + return simtypes.NoOpMsg(types.ModuleName, types.MsgSetDenomMetadata{}.Type(), "sim account have no denom created"), nil, nil + } + + // Get admin of the denom + authData, err := tfKeeper.GetAuthorityMetadata(ctx, denom) + if err != nil { + return simtypes.NoOpMsg(types.ModuleName, types.MsgSetDenomMetadata{}.Type(), "err authority metadata"), nil, err + } + adminAccount, found := simtypes.FindAccount(accs, sdk.MustAccAddressFromBech32(authData.Admin)) + if !found { + return simtypes.NoOpMsg(types.ModuleName, types.MsgSetDenomMetadata{}.Type(), "admin account not found"), nil, nil + } + + metadata := banktypes.Metadata{ + Description: simtypes.RandStringOfLength(r, 10), + DenomUnits: []*banktypes.DenomUnit{{ + Denom: denom, + Exponent: 0, + }}, + Base: denom, + Display: denom, + Name: simtypes.RandStringOfLength(r, 10), + Symbol: simtypes.RandStringOfLength(r, 10), + } + + msg := types.MsgSetDenomMetadata{ + Sender: adminAccount.Address.String(), + Metadata: metadata, + } + + txCtx := BuildOperationInput(r, app, ctx, &msg, adminAccount, ak, bk, nil) + return simulation.GenAndDeliverTxWithRandFees(txCtx) + } +} + +func SimulateMsgChangeAdmin( + tfKeeper TokenfactoryKeeper, + ak types.AccountKeeper, + bk BankKeeper, + denomSelector DenomSelector, +) simtypes.Operation { + return func( + r *rand.Rand, + app *baseapp.BaseApp, + ctx sdk.Context, + accs []simtypes.Account, + chainID string, + ) (simtypes.OperationMsg, []simtypes.FutureOperation, error) { + // Get create denom account + createdDenomAccount, _ := simtypes.RandomAcc(r, accs) + + // Get demon + denom, hasDenom := denomSelector(r, ctx, tfKeeper, createdDenomAccount.Address.String()) + if !hasDenom { + return simtypes.NoOpMsg(types.ModuleName, types.MsgChangeAdmin{}.Type(), "sim account have no denom created"), nil, nil + } + + // Get admin of the denom + authData, err := tfKeeper.GetAuthorityMetadata(ctx, denom) + if err != nil { + return simtypes.NoOpMsg(types.ModuleName, types.MsgChangeAdmin{}.Type(), "err authority metadata"), nil, err + } + curAdminAccount, found := simtypes.FindAccount(accs, sdk.MustAccAddressFromBech32(authData.Admin)) + if !found { + return simtypes.NoOpMsg(types.ModuleName, types.MsgChangeAdmin{}.Type(), "admin account not found"), nil, nil + } + + // Rand new admin account + newAdmin, _ := simtypes.RandomAcc(r, accs) + if newAdmin.Address.String() == curAdminAccount.Address.String() { + return simtypes.NoOpMsg(types.ModuleName, types.MsgChangeAdmin{}.Type(), "new admin cannot be the same as current admin"), nil, nil + } + + // Create msg + msg := types.MsgChangeAdmin{ + Sender: curAdminAccount.Address.String(), + Denom: denom, + NewAdmin: newAdmin.Address.String(), + } + + txCtx := BuildOperationInput(r, app, ctx, &msg, curAdminAccount, ak, bk, nil) + return simulation.GenAndDeliverTxWithRandFees(txCtx) + } +} + +func SimulateMsgBurn( + tfKeeper TokenfactoryKeeper, + ak types.AccountKeeper, + bk BankKeeper, + denomSelector DenomSelector, +) simtypes.Operation { + return func( + r *rand.Rand, + app *baseapp.BaseApp, + ctx sdk.Context, + accs []simtypes.Account, + chainID string, + ) (simtypes.OperationMsg, []simtypes.FutureOperation, error) { + // Get create denom account + createdDenomAccount, _ := simtypes.RandomAcc(r, accs) + + // Get demon + denom, hasDenom := denomSelector(r, ctx, tfKeeper, createdDenomAccount.Address.String()) + if !hasDenom { + return simtypes.NoOpMsg(types.ModuleName, types.MsgBurn{}.Type(), "sim account have no denom created"), nil, nil + } + + // Get admin of the denom + authData, err := tfKeeper.GetAuthorityMetadata(ctx, denom) + if err != nil { + return simtypes.NoOpMsg(types.ModuleName, types.MsgBurn{}.Type(), "err authority metadata"), nil, err + } + adminAccount, found := simtypes.FindAccount(accs, sdk.MustAccAddressFromBech32(authData.Admin)) + if !found { + return simtypes.NoOpMsg(types.ModuleName, types.MsgBurn{}.Type(), "admin account not found"), nil, nil + } + + // Check if admin account balance = 0 + accountBalance := bk.GetBalance(ctx, adminAccount.Address, denom) + if accountBalance.Amount.LTE(sdk.ZeroInt()) { + return simtypes.NoOpMsg(types.ModuleName, types.MsgBurn{}.Type(), "sim account have no balance"), nil, nil + } + + // Rand burn amount + amount, _ := simtypes.RandPositiveInt(r, accountBalance.Amount) + burnAmount := sdk.NewCoin(denom, amount) + + // Create msg + msg := types.MsgBurn{ + Sender: adminAccount.Address.String(), + Amount: burnAmount, + } + + txCtx := BuildOperationInput(r, app, ctx, &msg, adminAccount, ak, bk, sdk.NewCoins(burnAmount)) + return simulation.GenAndDeliverTxWithRandFees(txCtx) + } +} + +// Simulate msg mint denom +func SimulateMsgMint( + tfKeeper TokenfactoryKeeper, + ak types.AccountKeeper, + bk BankKeeper, + denomSelector DenomSelector, +) simtypes.Operation { + return func( + r *rand.Rand, + app *baseapp.BaseApp, + ctx sdk.Context, + accs []simtypes.Account, + chainID string, + ) (simtypes.OperationMsg, []simtypes.FutureOperation, error) { + // Get create denom account + createdDenomAccount, _ := simtypes.RandomAcc(r, accs) + + // Get demon + denom, hasDenom := denomSelector(r, ctx, tfKeeper, createdDenomAccount.Address.String()) + if !hasDenom { + return simtypes.NoOpMsg(types.ModuleName, types.MsgMint{}.Type(), "sim account have no denom created"), nil, nil + } + + // Get admin of the denom + authData, err := tfKeeper.GetAuthorityMetadata(ctx, denom) + if err != nil { + return simtypes.NoOpMsg(types.ModuleName, types.MsgMint{}.Type(), "err authority metadata"), nil, err + } + adminAccount, found := simtypes.FindAccount(accs, sdk.MustAccAddressFromBech32(authData.Admin)) + if !found { + return simtypes.NoOpMsg(types.ModuleName, types.MsgMint{}.Type(), "admin account not found"), nil, nil + } + + // Rand mint amount + mintAmount, _ := simtypes.RandPositiveInt(r, sdk.NewIntFromUint64(100_000_000)) + + // Create msg mint + msg := types.MsgMint{ + Sender: adminAccount.Address.String(), + Amount: sdk.NewCoin(denom, mintAmount), + } + + txCtx := BuildOperationInput(r, app, ctx, &msg, adminAccount, ak, bk, nil) + return simulation.GenAndDeliverTxWithRandFees(txCtx) + } +} + +// Simulate msg create denom +func SimulateMsgCreateDenom(tfKeeper TokenfactoryKeeper, ak types.AccountKeeper, bk BankKeeper) simtypes.Operation { + return func( + r *rand.Rand, + app *baseapp.BaseApp, + ctx sdk.Context, + accs []simtypes.Account, + chainID string, + ) (simtypes.OperationMsg, []simtypes.FutureOperation, error) { + // Get sims account + simAccount, _ := simtypes.RandomAcc(r, accs) + + // Check if sims account enough create fee + createFee := tfKeeper.GetParams(ctx).DenomCreationFee + balances := bk.GetAllBalances(ctx, simAccount.Address) + _, hasNeg := balances.SafeSub(createFee) + if hasNeg { + return simtypes.NoOpMsg(types.ModuleName, types.MsgCreateDenom{}.Type(), "Creator not enough creation fee"), nil, nil + } + + // Create msg create denom + msg := types.MsgCreateDenom{ + Sender: simAccount.Address.String(), + Subdenom: simtypes.RandStringOfLength(r, 10), + } + + txCtx := BuildOperationInput(r, app, ctx, &msg, simAccount, ak, bk, createFee) + return simulation.GenAndDeliverTxWithRandFees(txCtx) + } +} + +// BuildOperationInput helper to build object +func BuildOperationInput( + r *rand.Rand, + app *baseapp.BaseApp, + ctx sdk.Context, + msg interface { + sdk.Msg + Type() string + }, + simAccount simtypes.Account, + ak types.AccountKeeper, + bk BankKeeper, + deposit sdk.Coins, +) simulation.OperationInput { + return simulation.OperationInput{ + R: r, + App: app, + TxGen: simappparams.MakeTestEncodingConfig().TxConfig, + Cdc: nil, + Msg: msg, + MsgType: msg.Type(), + Context: ctx, + SimAccount: simAccount, + AccountKeeper: ak, + Bankkeeper: bk, + ModuleName: types.ModuleName, + CoinsSpentInMsg: deposit, + } +} diff --git a/x/tokenfactory/simulation/params.go b/x/tokenfactory/simulation/params.go new file mode 100644 index 000000000..001a55c09 --- /dev/null +++ b/x/tokenfactory/simulation/params.go @@ -0,0 +1,23 @@ +package simulation + +import ( + "fmt" + "math/rand" + + "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/types" + simtypes "github.com/cosmos/cosmos-sdk/types/simulation" + "github.com/cosmos/cosmos-sdk/x/simulation" +) + +func ParamChanges(_ *rand.Rand) []simtypes.ParamChange { + return []simtypes.ParamChange{ + simulation.NewSimParamChange( + types.ModuleName, + string(types.KeyDenomCreationFee), + func(r *rand.Rand) string { + amount := RandDenomCreationFeeParam(r) + return fmt.Sprintf("[{\"denom\":\"%v\",\"amount\":\"%v\"}]", amount[0].Denom, amount[0].Amount) + }, + ), + } +} diff --git a/x/tokenfactory/testhelpers/consts.go b/x/tokenfactory/testhelpers/consts.go new file mode 100644 index 000000000..d7804a372 --- /dev/null +++ b/x/tokenfactory/testhelpers/consts.go @@ -0,0 +1,8 @@ +package testhelpers + +import sdk "github.com/cosmos/cosmos-sdk/types" + +var ( + SecondaryDenom = "uion" + SecondaryAmount = sdk.NewInt(100000000) +) diff --git a/x/tokenfactory/testhelpers/suite.go b/x/tokenfactory/testhelpers/suite.go new file mode 100644 index 000000000..7df45ad15 --- /dev/null +++ b/x/tokenfactory/testhelpers/suite.go @@ -0,0 +1,66 @@ +package testhelpers + +import ( + "encoding/json" + "testing" + "time" + + "github.com/cosmos/cosmos-sdk/x/authz" + "github.com/stretchr/testify/require" + + "github.com/cosmos/cosmos-sdk/codec" + cdctypes "github.com/cosmos/cosmos-sdk/codec/types" + cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +var ( + Amino = codec.NewLegacyAmino() + AuthzModuleCdc = codec.NewAminoCodec(Amino) +) + +func init() { + cryptocodec.RegisterCrypto(Amino) + codec.RegisterEvidences(Amino) + sdk.RegisterLegacyAminoCodec(Amino) +} + +func TestMessageAuthzSerialization(t *testing.T, msg sdk.Msg) { + someDate := time.Date(1, 1, 1, 1, 1, 1, 1, time.UTC) + const ( + mockGranter string = "cosmos1abc" + mockGrantee string = "cosmos1xyz" + ) + + var ( + mockMsgGrant authz.MsgGrant + mockMsgRevoke authz.MsgRevoke + mockMsgExec authz.MsgExec + ) + + // Authz: Grant Msg + typeURL := sdk.MsgTypeURL(msg) + later := someDate.Add(time.Hour) + grant, err := authz.NewGrant(authz.NewGenericAuthorization(typeURL), later) + require.NoError(t, err) + + msgGrant := authz.MsgGrant{Granter: mockGranter, Grantee: mockGrantee, Grant: grant} + msgGrantBytes := json.RawMessage(sdk.MustSortJSON(AuthzModuleCdc.MustMarshalJSON(&msgGrant))) + err = AuthzModuleCdc.UnmarshalJSON(msgGrantBytes, &mockMsgGrant) + require.NoError(t, err) + + // Authz: Revoke Msg + msgRevoke := authz.MsgRevoke{Granter: mockGranter, Grantee: mockGrantee, MsgTypeUrl: typeURL} + msgRevokeByte := json.RawMessage(sdk.MustSortJSON(AuthzModuleCdc.MustMarshalJSON(&msgRevoke))) + err = AuthzModuleCdc.UnmarshalJSON(msgRevokeByte, &mockMsgRevoke) + require.NoError(t, err) + + // Authz: Exec Msg + msgAny, err := cdctypes.NewAnyWithValue(msg) + require.NoError(t, err) + msgExec := authz.MsgExec{Grantee: mockGrantee, Msgs: []*cdctypes.Any{msgAny}} + execMsgByte := json.RawMessage(sdk.MustSortJSON(AuthzModuleCdc.MustMarshalJSON(&msgExec))) + err = AuthzModuleCdc.UnmarshalJSON(execMsgByte, &mockMsgExec) + require.NoError(t, err) + require.Equal(t, msgExec.Msgs[0].Value, mockMsgExec.Msgs[0].Value) +} diff --git a/x/tokenfactory/types/authorityMetadata.go b/x/tokenfactory/types/authorityMetadata.go new file mode 100644 index 000000000..b45bffcab --- /dev/null +++ b/x/tokenfactory/types/authorityMetadata.go @@ -0,0 +1,15 @@ +package types + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" +) + +func (metadata DenomAuthorityMetadata) Validate() error { + if metadata.Admin != "" { + _, err := sdk.AccAddressFromBech32(metadata.Admin) + if err != nil { + return err + } + } + return nil +} diff --git a/x/tokenfactory/types/authorityMetadata.pb.go b/x/tokenfactory/types/authorityMetadata.pb.go new file mode 100644 index 000000000..d8df78772 --- /dev/null +++ b/x/tokenfactory/types/authorityMetadata.pb.go @@ -0,0 +1,351 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: osmosis/tokenfactory/v1beta1/authorityMetadata.proto + +package types + +import ( + fmt "fmt" + _ "github.com/cosmos/cosmos-sdk/types" + _ "github.com/cosmos/gogoproto/gogoproto" + proto "github.com/gogo/protobuf/proto" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = 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 + +// DenomAuthorityMetadata specifies metadata for addresses that have specific +// capabilities over a token factory denom. Right now there is only one Admin +// permission, but is planned to be extended to the future. +type DenomAuthorityMetadata struct { + // Can be empty for no admin, or a valid osmosis address + Admin string `protobuf:"bytes,1,opt,name=admin,proto3" json:"admin,omitempty" yaml:"admin"` +} + +func (m *DenomAuthorityMetadata) Reset() { *m = DenomAuthorityMetadata{} } +func (m *DenomAuthorityMetadata) String() string { return proto.CompactTextString(m) } +func (*DenomAuthorityMetadata) ProtoMessage() {} +func (*DenomAuthorityMetadata) Descriptor() ([]byte, []int) { + return fileDescriptor_99435de88ae175f7, []int{0} +} +func (m *DenomAuthorityMetadata) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *DenomAuthorityMetadata) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_DenomAuthorityMetadata.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 *DenomAuthorityMetadata) XXX_Merge(src proto.Message) { + xxx_messageInfo_DenomAuthorityMetadata.Merge(m, src) +} +func (m *DenomAuthorityMetadata) XXX_Size() int { + return m.Size() +} +func (m *DenomAuthorityMetadata) XXX_DiscardUnknown() { + xxx_messageInfo_DenomAuthorityMetadata.DiscardUnknown(m) +} + +var xxx_messageInfo_DenomAuthorityMetadata proto.InternalMessageInfo + +func (m *DenomAuthorityMetadata) GetAdmin() string { + if m != nil { + return m.Admin + } + return "" +} + +func init() { + proto.RegisterType((*DenomAuthorityMetadata)(nil), "osmosis.tokenfactory.v1beta1.DenomAuthorityMetadata") +} + +func init() { + proto.RegisterFile("osmosis/tokenfactory/v1beta1/authorityMetadata.proto", fileDescriptor_99435de88ae175f7) +} + +var fileDescriptor_99435de88ae175f7 = []byte{ + // 240 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x32, 0xc9, 0x2f, 0xce, 0xcd, + 0x2f, 0xce, 0x2c, 0xd6, 0x2f, 0xc9, 0xcf, 0x4e, 0xcd, 0x4b, 0x4b, 0x4c, 0x2e, 0xc9, 0x2f, 0xaa, + 0xd4, 0x2f, 0x33, 0x4c, 0x4a, 0x2d, 0x49, 0x34, 0xd4, 0x4f, 0x2c, 0x2d, 0xc9, 0xc8, 0x2f, 0xca, + 0x2c, 0xa9, 0xf4, 0x4d, 0x2d, 0x49, 0x4c, 0x49, 0x2c, 0x49, 0xd4, 0x2b, 0x28, 0xca, 0x2f, 0xc9, + 0x17, 0x92, 0x81, 0xea, 0xd2, 0x43, 0xd6, 0xa5, 0x07, 0xd5, 0x25, 0x25, 0x92, 0x9e, 0x9f, 0x9e, + 0x0f, 0x56, 0xa8, 0x0f, 0x62, 0x41, 0xf4, 0x48, 0xc9, 0x25, 0x83, 0x35, 0xe9, 0x27, 0x25, 0x16, + 0xa7, 0xc2, 0x2d, 0x48, 0xce, 0xcf, 0xcc, 0x83, 0xc8, 0x2b, 0xb9, 0x71, 0x89, 0xb9, 0xa4, 0xe6, + 0xe5, 0xe7, 0x3a, 0xa2, 0xdb, 0x29, 0xa4, 0xc6, 0xc5, 0x9a, 0x98, 0x92, 0x9b, 0x99, 0x27, 0xc1, + 0xa8, 0xc0, 0xa8, 0xc1, 0xe9, 0x24, 0xf0, 0xe9, 0x9e, 0x3c, 0x4f, 0x65, 0x62, 0x6e, 0x8e, 0x95, + 0x12, 0x58, 0x58, 0x29, 0x08, 0x22, 0x6d, 0xc5, 0xf2, 0x62, 0x81, 0x3c, 0xa3, 0x53, 0xd4, 0x89, + 0x47, 0x72, 0x8c, 0x17, 0x1e, 0xc9, 0x31, 0x3e, 0x78, 0x24, 0xc7, 0x38, 0xe1, 0xb1, 0x1c, 0xc3, + 0x85, 0xc7, 0x72, 0x0c, 0x37, 0x1e, 0xcb, 0x31, 0x44, 0x39, 0xa4, 0x67, 0x96, 0x64, 0x94, 0x26, + 0xe9, 0x25, 0xe7, 0xe7, 0xea, 0x3b, 0x83, 0x1d, 0x13, 0x02, 0x72, 0xbe, 0x1b, 0xd4, 0xd3, 0x60, + 0xbf, 0xe8, 0xc2, 0x82, 0xa0, 0x02, 0x35, 0x44, 0x4a, 0x2a, 0x0b, 0x52, 0x8b, 0x93, 0xd8, 0xc0, + 0x4e, 0x35, 0x06, 0x04, 0x00, 0x00, 0xff, 0xff, 0x5d, 0xdc, 0xc5, 0x01, 0x36, 0x01, 0x00, 0x00, +} + +func (this *DenomAuthorityMetadata) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*DenomAuthorityMetadata) + if !ok { + that2, ok := that.(DenomAuthorityMetadata) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if this.Admin != that1.Admin { + return false + } + return true +} +func (m *DenomAuthorityMetadata) 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 *DenomAuthorityMetadata) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *DenomAuthorityMetadata) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Admin) > 0 { + i -= len(m.Admin) + copy(dAtA[i:], m.Admin) + i = encodeVarintAuthorityMetadata(dAtA, i, uint64(len(m.Admin))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func encodeVarintAuthorityMetadata(dAtA []byte, offset int, v uint64) int { + offset -= sovAuthorityMetadata(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *DenomAuthorityMetadata) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Admin) + if l > 0 { + n += 1 + l + sovAuthorityMetadata(uint64(l)) + } + return n +} + +func sovAuthorityMetadata(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozAuthorityMetadata(x uint64) (n int) { + return sovAuthorityMetadata(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *DenomAuthorityMetadata) 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 ErrIntOverflowAuthorityMetadata + } + 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: DenomAuthorityMetadata: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: DenomAuthorityMetadata: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + 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 ErrIntOverflowAuthorityMetadata + } + 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 ErrInvalidLengthAuthorityMetadata + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthAuthorityMetadata + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Admin = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipAuthorityMetadata(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthAuthorityMetadata + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipAuthorityMetadata(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, ErrIntOverflowAuthorityMetadata + } + 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, ErrIntOverflowAuthorityMetadata + } + 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, ErrIntOverflowAuthorityMetadata + } + 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, ErrInvalidLengthAuthorityMetadata + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupAuthorityMetadata + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthAuthorityMetadata + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthAuthorityMetadata = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowAuthorityMetadata = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupAuthorityMetadata = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/tokenfactory/types/authzcodec/codec.go b/x/tokenfactory/types/authzcodec/codec.go new file mode 100644 index 000000000..366e337a1 --- /dev/null +++ b/x/tokenfactory/types/authzcodec/codec.go @@ -0,0 +1,24 @@ +package authzcodec + +// Note: this file is a copy from authz/codec in 0.46 so we can be compatible with 0.45 + +import ( + "github.com/cosmos/cosmos-sdk/codec" + cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +var ( + Amino = codec.NewLegacyAmino() + ModuleCdc = codec.NewAminoCodec(Amino) +) + +func init() { + // Register all Amino interfaces and concrete types on the authz Amino codec so that this can later be + // used to properly serialize MsgGrant and MsgExec instances + sdk.RegisterLegacyAminoCodec(Amino) + cryptocodec.RegisterCrypto(Amino) + codec.RegisterEvidences(Amino) + + Amino.Seal() +} diff --git a/x/tokenfactory/types/capabilities.go b/x/tokenfactory/types/capabilities.go new file mode 100644 index 000000000..bda91c950 --- /dev/null +++ b/x/tokenfactory/types/capabilities.go @@ -0,0 +1,21 @@ +package types + +const ( + EnableSetMetadata = "enable_metadata" + EnableForceTransfer = "enable_force_transfer" + EnableBurnFrom = "enable_burn_from" +) + +func IsCapabilityEnabled(enabledCapabilities []string, capability string) bool { + if len(enabledCapabilities) == 0 { + return true + } + + for _, v := range enabledCapabilities { + if v == capability { + return true + } + } + + return false +} diff --git a/x/tokenfactory/types/codec.go b/x/tokenfactory/types/codec.go new file mode 100644 index 000000000..8984dd89e --- /dev/null +++ b/x/tokenfactory/types/codec.go @@ -0,0 +1,48 @@ +package types + +import ( + "github.com/cosmos/cosmos-sdk/codec" + cdctypes "github.com/cosmos/cosmos-sdk/codec/types" + cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + + // this line is used by starport scaffolding # 1 + "github.com/cosmos/cosmos-sdk/types/msgservice" +) + +func RegisterCodec(cdc *codec.LegacyAmino) { + cdc.RegisterConcrete(&MsgCreateDenom{}, "osmosis/tokenfactory/create-denom", nil) + cdc.RegisterConcrete(&MsgMint{}, "osmosis/tokenfactory/mint", nil) + cdc.RegisterConcrete(&MsgBurn{}, "osmosis/tokenfactory/burn", nil) + cdc.RegisterConcrete(&MsgForceTransfer{}, "osmosis/tokenfactory/force-transfer", nil) + cdc.RegisterConcrete(&MsgChangeAdmin{}, "osmosis/tokenfactory/change-admin", nil) +} + +func RegisterInterfaces(registry cdctypes.InterfaceRegistry) { + registry.RegisterImplementations( + (*sdk.Msg)(nil), + &MsgCreateDenom{}, + &MsgMint{}, + &MsgBurn{}, + // &MsgForceTransfer{}, + &MsgChangeAdmin{}, + ) + msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc) +} + +var ( + amino = codec.NewLegacyAmino() + ModuleCdc = codec.NewProtoCodec(cdctypes.NewInterfaceRegistry()) +) + +func init() { + RegisterCodec(amino) + // Register all Amino interfaces and concrete types on the authz Amino codec so that this can later be + // used to properly serialize MsgGrant and MsgExec instances + // Note: these 3 are inlines from authz/codec in 0.46 so we can be compatible with 0.45 + sdk.RegisterLegacyAminoCodec(amino) + cryptocodec.RegisterCrypto(amino) + codec.RegisterEvidences(amino) + + amino.Seal() +} diff --git a/x/tokenfactory/types/denoms.go b/x/tokenfactory/types/denoms.go new file mode 100644 index 000000000..7a9f2f9e9 --- /dev/null +++ b/x/tokenfactory/types/denoms.go @@ -0,0 +1,68 @@ +package types + +import ( + "strings" + + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" +) + +const ( + ModuleDenomPrefix = "factory" + // See the TokenFactory readme for a derivation of these. + // TL;DR, MaxSubdenomLength + MaxHrpLength = 60 comes from SDK max denom length = 128 + // and the structure of tokenfactory denoms. + MaxSubdenomLength = 44 + MaxHrpLength = 16 + // MaxCreatorLength = 59 + MaxHrpLength + MaxCreatorLength = 59 + MaxHrpLength +) + +// GetTokenDenom constructs a denom string for tokens created by tokenfactory +// based on an input creator address and a subdenom +// The denom constructed is factory/{creator}/{subdenom} +func GetTokenDenom(creator, subdenom string) (string, error) { + if len(subdenom) > MaxSubdenomLength { + return "", ErrSubdenomTooLong + } + if len(creator) > MaxCreatorLength { + return "", ErrCreatorTooLong + } + if strings.Contains(creator, "/") { + return "", ErrInvalidCreator + } + denom := strings.Join([]string{ModuleDenomPrefix, creator, subdenom}, "/") + return denom, sdk.ValidateDenom(denom) +} + +// DeconstructDenom takes a token denom string and verifies that it is a valid +// denom of the tokenfactory module, and is of the form `factory/{creator}/{subdenom}` +// If valid, it returns the creator address and subdenom +func DeconstructDenom(denom string) (creator string, subdenom string, err error) { + err = sdk.ValidateDenom(denom) + if err != nil { + return "", "", err + } + + strParts := strings.Split(denom, "/") + if len(strParts) < 3 { + return "", "", sdkerrors.Wrapf(ErrInvalidDenom, "not enough parts of denom %s", denom) + } + + if strParts[0] != ModuleDenomPrefix { + return "", "", sdkerrors.Wrapf(ErrInvalidDenom, "denom prefix is incorrect. Is: %s. Should be: %s", strParts[0], ModuleDenomPrefix) + } + + creator = strParts[1] + creatorAddr, err := sdk.AccAddressFromBech32(creator) + if err != nil { + return "", "", sdkerrors.Wrapf(ErrInvalidDenom, "Invalid creator address (%s)", err) + } + + // Handle the case where a denom has a slash in its subdenom. For example, + // when we did the split, we'd turn factory/accaddr/atomderivative/sikka into ["factory", "accaddr", "atomderivative", "sikka"] + // So we have to join [2:] with a "/" as the delimiter to get back the correct subdenom which should be "atomderivative/sikka" + subdenom = strings.Join(strParts[2:], "/") + + return creatorAddr.String(), subdenom, nil +} diff --git a/x/tokenfactory/types/denoms_test.go b/x/tokenfactory/types/denoms_test.go new file mode 100644 index 000000000..a4395f59a --- /dev/null +++ b/x/tokenfactory/types/denoms_test.go @@ -0,0 +1,132 @@ +package types_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/types" +) + +func TestDeconstructDenom(t *testing.T) { + // Note: this seems to be used in osmosis to add some more checks (only 20 or 32 byte addresses), + // which is good, but not required for these tests as they make code less reuable + // appparams.SetAddressPrefixes() + + for _, tc := range []struct { + desc string + denom string + expectedSubdenom string + err error + }{ + { + desc: "empty is invalid", + denom: "", + err: types.ErrInvalidDenom, + }, + { + desc: "normal", + denom: "factory/cosmos1t7egva48prqmzl59x5ngv4zx0dtrwewcdqdjr8/bitcoin", + expectedSubdenom: "bitcoin", + }, + { + desc: "multiple slashes in subdenom", + denom: "factory/cosmos1t7egva48prqmzl59x5ngv4zx0dtrwewcdqdjr8/bitcoin/1", + expectedSubdenom: "bitcoin/1", + }, + { + desc: "no subdenom", + denom: "factory/cosmos1t7egva48prqmzl59x5ngv4zx0dtrwewcdqdjr8/", + expectedSubdenom: "", + }, + { + desc: "incorrect prefix", + denom: "ibc/cosmos1t7egva48prqmzl59x5ngv4zx0dtrwewcdqdjr8/bitcoin", + err: types.ErrInvalidDenom, + }, + { + desc: "subdenom of only slashes", + denom: "factory/cosmos1t7egva48prqmzl59x5ngv4zx0dtrwewcdqdjr8/////", + expectedSubdenom: "////", + }, + { + desc: "too long name", + denom: "factory/cosmos1t7egva48prqmzl59x5ngv4zx0dtrwewcdqdjr8/adsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsf", + err: types.ErrInvalidDenom, + }, + } { + t.Run(tc.desc, func(t *testing.T) { + expectedCreator := "cosmos1t7egva48prqmzl59x5ngv4zx0dtrwewcdqdjr8" + creator, subdenom, err := types.DeconstructDenom(tc.denom) + if tc.err != nil { + require.ErrorContains(t, err, tc.err.Error()) + } else { + require.NoError(t, err) + require.Equal(t, expectedCreator, creator) + require.Equal(t, tc.expectedSubdenom, subdenom) + } + }) + } +} + +func TestGetTokenDenom(t *testing.T) { + // appparams.SetAddressPrefixes() + for _, tc := range []struct { + desc string + creator string + subdenom string + valid bool + }{ + { + desc: "normal", + creator: "cosmos1t7egva48prqmzl59x5ngv4zx0dtrwewcdqdjr8", + subdenom: "bitcoin", + valid: true, + }, + { + desc: "multiple slashes in subdenom", + creator: "cosmos1t7egva48prqmzl59x5ngv4zx0dtrwewcdqdjr8", + subdenom: "bitcoin/1", + valid: true, + }, + { + desc: "no subdenom", + creator: "cosmos1t7egva48prqmzl59x5ngv4zx0dtrwewcdqdjr8", + subdenom: "", + valid: true, + }, + { + desc: "subdenom of only slashes", + creator: "cosmos1t7egva48prqmzl59x5ngv4zx0dtrwewcdqdjr8", + subdenom: "/////", + valid: true, + }, + { + desc: "too long name", + creator: "cosmos1t7egva48prqmzl59x5ngv4zx0dtrwewcdqdjr8", + subdenom: "adsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsf", + valid: false, + }, + { + desc: "subdenom is exactly max length", + creator: "cosmos1t7egva48prqmzl59x5ngv4zx0dtrwewcdqdjr8", + subdenom: "bitcoinfsadfsdfeadfsafwefsefsefsdfsdafasefsf", + valid: true, + }, + { + desc: "creator is exactly max length", + creator: "cosmos1t7egva48prqmzl59x5ngv4zx0dtrwewcdqdjr8jhgjhgkhjklhkjhkjhgjhgjgjghelu", + subdenom: "bitcoin", + valid: true, + }, + } { + t.Run(tc.desc, func(t *testing.T) { + _, err := types.GetTokenDenom(tc.creator, tc.subdenom) + if tc.valid { + require.NoError(t, err) + } else { + require.Error(t, err) + } + }) + } +} diff --git a/x/tokenfactory/types/errors.go b/x/tokenfactory/types/errors.go new file mode 100644 index 000000000..d5e09de19 --- /dev/null +++ b/x/tokenfactory/types/errors.go @@ -0,0 +1,23 @@ +package types + +// DONTCOVER + +import ( + fmt "fmt" + + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" +) + +// x/tokenfactory module sentinel errors +var ( + ErrDenomExists = sdkerrors.Register(ModuleName, 2, "attempting to create a denom that already exists (has bank metadata)") + ErrUnauthorized = sdkerrors.Register(ModuleName, 3, "unauthorized account") + ErrInvalidDenom = sdkerrors.Register(ModuleName, 4, "invalid denom") + ErrInvalidCreator = sdkerrors.Register(ModuleName, 5, "invalid creator") + ErrInvalidAuthorityMetadata = sdkerrors.Register(ModuleName, 6, "invalid authority metadata") + ErrInvalidGenesis = sdkerrors.Register(ModuleName, 7, "invalid genesis") + ErrSubdenomTooLong = sdkerrors.Register(ModuleName, 8, fmt.Sprintf("subdenom too long, max length is %d bytes", MaxSubdenomLength)) + ErrCreatorTooLong = sdkerrors.Register(ModuleName, 9, fmt.Sprintf("creator too long, max length is %d bytes", MaxCreatorLength)) + ErrDenomDoesNotExist = sdkerrors.Register(ModuleName, 10, "denom does not exist") + ErrCapabilityNotEnabled = sdkerrors.Register(ModuleName, 11, "this capability is not enabled on chain") +) diff --git a/x/tokenfactory/types/events.go b/x/tokenfactory/types/events.go new file mode 100644 index 000000000..602e06fab --- /dev/null +++ b/x/tokenfactory/types/events.go @@ -0,0 +1,18 @@ +package types + +// event types +// +//nolint:gosec +const ( + AttributeAmount = "amount" + AttributeCreator = "creator" + AttributeSubdenom = "subdenom" + AttributeNewTokenDenom = "new_token_denom" + AttributeMintToAddress = "mint_to_address" + AttributeBurnFromAddress = "burn_from_address" + AttributeTransferFromAddress = "transfer_from_address" + AttributeTransferToAddress = "transfer_to_address" + AttributeDenom = "denom" + AttributeNewAdmin = "new_admin" + AttributeDenomMetadata = "denom_metadata" +) diff --git a/x/tokenfactory/types/expected_keepers.go b/x/tokenfactory/types/expected_keepers.go new file mode 100644 index 000000000..5500dab76 --- /dev/null +++ b/x/tokenfactory/types/expected_keepers.go @@ -0,0 +1,38 @@ +package types + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" +) + +type BankKeeper interface { + // Methods imported from bank should be defined here + GetDenomMetaData(ctx sdk.Context, denom string) (banktypes.Metadata, bool) + SetDenomMetaData(ctx sdk.Context, denomMetaData banktypes.Metadata) + + HasSupply(ctx sdk.Context, denom string) bool + + SendCoinsFromModuleToAccount(ctx sdk.Context, senderModule string, recipientAddr sdk.AccAddress, amt sdk.Coins) error + SendCoinsFromAccountToModule(ctx sdk.Context, senderAddr sdk.AccAddress, recipientModule string, amt sdk.Coins) error + MintCoins(ctx sdk.Context, moduleName string, amt sdk.Coins) error + BurnCoins(ctx sdk.Context, moduleName string, amt sdk.Coins) error + + SendCoins(ctx sdk.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins) error + HasBalance(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coin) bool + GetAllBalances(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins + SpendableCoins(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins + GetBalance(ctx sdk.Context, addr sdk.AccAddress, denom string) sdk.Coin + + BlockedAddr(addr sdk.AccAddress) bool +} + +type AccountKeeper interface { + SetModuleAccount(ctx sdk.Context, macc authtypes.ModuleAccountI) + GetAccount(ctx sdk.Context, addr sdk.AccAddress) authtypes.AccountI +} + +// CommunityPoolKeeper defines the contract needed to be fulfilled for community pool interactions. +type CommunityPoolKeeper interface { + FundCommunityPool(ctx sdk.Context, amount sdk.Coins, sender sdk.AccAddress) error +} diff --git a/x/tokenfactory/types/genesis.go b/x/tokenfactory/types/genesis.go new file mode 100644 index 000000000..b1ba181fa --- /dev/null +++ b/x/tokenfactory/types/genesis.go @@ -0,0 +1,51 @@ +package types + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" +) + +// this line is used by starport scaffolding # genesis/types/import + +// DefaultIndex is the default capability global index +const DefaultIndex uint64 = 1 + +// DefaultGenesis returns the default Capability genesis state +func DefaultGenesis() *GenesisState { + return &GenesisState{ + Params: DefaultParams(), + FactoryDenoms: []GenesisDenom{}, + } +} + +// Validate performs basic genesis state validation returning an error upon any +// failure. +func (gs GenesisState) Validate() error { + err := gs.Params.Validate() + if err != nil { + return err + } + + seenDenoms := map[string]bool{} + + for _, denom := range gs.GetFactoryDenoms() { + if seenDenoms[denom.GetDenom()] { + return sdkerrors.Wrapf(ErrInvalidGenesis, "duplicate denom: %s", denom.GetDenom()) + } + seenDenoms[denom.GetDenom()] = true + + _, _, err := DeconstructDenom(denom.GetDenom()) + if err != nil { + return err + } + + if denom.AuthorityMetadata.Admin != "" { + _, err = sdk.AccAddressFromBech32(denom.AuthorityMetadata.Admin) + if err != nil { + return sdkerrors.Wrapf(ErrInvalidAuthorityMetadata, "Invalid admin address (%s)", err) + } + } + } + + return nil +} diff --git a/x/tokenfactory/types/genesis.pb.go b/x/tokenfactory/types/genesis.pb.go new file mode 100644 index 000000000..594a86ea9 --- /dev/null +++ b/x/tokenfactory/types/genesis.pb.go @@ -0,0 +1,649 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: osmosis/tokenfactory/v1beta1/genesis.proto + +package types + +import ( + fmt "fmt" + _ "github.com/cosmos/gogoproto/gogoproto" + proto "github.com/gogo/protobuf/proto" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = 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 + +// GenesisState defines the tokenfactory module's genesis state. +type GenesisState struct { + // params defines the paramaters of the module. + Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` + FactoryDenoms []GenesisDenom `protobuf:"bytes,2,rep,name=factory_denoms,json=factoryDenoms,proto3" json:"factory_denoms" yaml:"factory_denoms"` +} + +func (m *GenesisState) Reset() { *m = GenesisState{} } +func (m *GenesisState) String() string { return proto.CompactTextString(m) } +func (*GenesisState) ProtoMessage() {} +func (*GenesisState) Descriptor() ([]byte, []int) { + return fileDescriptor_5749c3f71850298b, []int{0} +} +func (m *GenesisState) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *GenesisState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_GenesisState.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) XXX_Merge(src proto.Message) { + xxx_messageInfo_GenesisState.Merge(m, src) +} +func (m *GenesisState) XXX_Size() int { + return m.Size() +} +func (m *GenesisState) XXX_DiscardUnknown() { + xxx_messageInfo_GenesisState.DiscardUnknown(m) +} + +var xxx_messageInfo_GenesisState proto.InternalMessageInfo + +func (m *GenesisState) GetParams() Params { + if m != nil { + return m.Params + } + return Params{} +} + +func (m *GenesisState) GetFactoryDenoms() []GenesisDenom { + if m != nil { + return m.FactoryDenoms + } + return nil +} + +// GenesisDenom defines a tokenfactory denom that is defined within genesis +// state. The structure contains DenomAuthorityMetadata which defines the +// denom's admin. +type GenesisDenom struct { + Denom string `protobuf:"bytes,1,opt,name=denom,proto3" json:"denom,omitempty" yaml:"denom"` + AuthorityMetadata DenomAuthorityMetadata `protobuf:"bytes,2,opt,name=authority_metadata,json=authorityMetadata,proto3" json:"authority_metadata" yaml:"authority_metadata"` +} + +func (m *GenesisDenom) Reset() { *m = GenesisDenom{} } +func (m *GenesisDenom) String() string { return proto.CompactTextString(m) } +func (*GenesisDenom) ProtoMessage() {} +func (*GenesisDenom) Descriptor() ([]byte, []int) { + return fileDescriptor_5749c3f71850298b, []int{1} +} +func (m *GenesisDenom) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *GenesisDenom) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_GenesisDenom.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 *GenesisDenom) XXX_Merge(src proto.Message) { + xxx_messageInfo_GenesisDenom.Merge(m, src) +} +func (m *GenesisDenom) XXX_Size() int { + return m.Size() +} +func (m *GenesisDenom) XXX_DiscardUnknown() { + xxx_messageInfo_GenesisDenom.DiscardUnknown(m) +} + +var xxx_messageInfo_GenesisDenom proto.InternalMessageInfo + +func (m *GenesisDenom) GetDenom() string { + if m != nil { + return m.Denom + } + return "" +} + +func (m *GenesisDenom) GetAuthorityMetadata() DenomAuthorityMetadata { + if m != nil { + return m.AuthorityMetadata + } + return DenomAuthorityMetadata{} +} + +func init() { + proto.RegisterType((*GenesisState)(nil), "osmosis.tokenfactory.v1beta1.GenesisState") + proto.RegisterType((*GenesisDenom)(nil), "osmosis.tokenfactory.v1beta1.GenesisDenom") +} + +func init() { + proto.RegisterFile("osmosis/tokenfactory/v1beta1/genesis.proto", fileDescriptor_5749c3f71850298b) +} + +var fileDescriptor_5749c3f71850298b = []byte{ + // 367 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xd2, 0xca, 0x2f, 0xce, 0xcd, + 0x2f, 0xce, 0x2c, 0xd6, 0x2f, 0xc9, 0xcf, 0x4e, 0xcd, 0x4b, 0x4b, 0x4c, 0x2e, 0xc9, 0x2f, 0xaa, + 0xd4, 0x2f, 0x33, 0x4c, 0x4a, 0x2d, 0x49, 0x34, 0xd4, 0x4f, 0x4f, 0xcd, 0x4b, 0x2d, 0xce, 0x2c, + 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x92, 0x81, 0xaa, 0xd5, 0x43, 0x56, 0xab, 0x07, 0x55, + 0x2b, 0x25, 0x92, 0x9e, 0x9f, 0x9e, 0x0f, 0x56, 0xa8, 0x0f, 0x62, 0x41, 0xf4, 0x48, 0x99, 0xe0, + 0x35, 0x3f, 0xb1, 0xb4, 0x24, 0x23, 0xbf, 0x28, 0xb3, 0xa4, 0xd2, 0x37, 0xb5, 0x24, 0x31, 0x25, + 0xb1, 0x24, 0x11, 0xaa, 0x4b, 0x13, 0xaf, 0xae, 0x82, 0xc4, 0xa2, 0xc4, 0x5c, 0xa8, 0xa3, 0x94, + 0x8e, 0x30, 0x72, 0xf1, 0xb8, 0x43, 0x9c, 0x19, 0x5c, 0x92, 0x58, 0x92, 0x2a, 0xe4, 0xc4, 0xc5, + 0x06, 0x51, 0x20, 0xc1, 0xa8, 0xc0, 0xa8, 0xc1, 0x6d, 0xa4, 0xa2, 0x87, 0xcf, 0xd9, 0x7a, 0x01, + 0x60, 0xb5, 0x4e, 0x2c, 0x27, 0xee, 0xc9, 0x33, 0x04, 0x41, 0x75, 0x0a, 0x15, 0x70, 0xf1, 0x41, + 0xd5, 0xc5, 0xa7, 0xa4, 0xe6, 0xe5, 0xe7, 0x16, 0x4b, 0x30, 0x29, 0x30, 0x6b, 0x70, 0x1b, 0x69, + 0xe1, 0x37, 0x0b, 0xea, 0x0e, 0x17, 0x90, 0x16, 0x27, 0x59, 0x90, 0x89, 0x9f, 0xee, 0xc9, 0x8b, + 0x56, 0x26, 0xe6, 0xe6, 0x58, 0x29, 0xa1, 0x9a, 0xa7, 0x14, 0xc4, 0x0b, 0x15, 0x70, 0x81, 0xf0, + 0x8f, 0x22, 0xbc, 0x01, 0x16, 0x11, 0x52, 0xe3, 0x62, 0x05, 0x2b, 0x05, 0xfb, 0x82, 0xd3, 0x49, + 0xe0, 0xd3, 0x3d, 0x79, 0x1e, 0x88, 0x49, 0x60, 0x61, 0xa5, 0x20, 0x88, 0xb4, 0x50, 0x1b, 0x23, + 0x97, 0x10, 0x3c, 0x18, 0xe3, 0x73, 0xa1, 0xe1, 0x28, 0xc1, 0x04, 0xf6, 0xbb, 0x09, 0x7e, 0xf7, + 0x82, 0x6d, 0x72, 0x44, 0x8f, 0x03, 0x27, 0x45, 0xa8, 0xcb, 0x25, 0x21, 0xf6, 0x61, 0x9a, 0xae, + 0x14, 0x24, 0x88, 0x11, 0x73, 0x56, 0x2c, 0x2f, 0x16, 0xc8, 0x33, 0x3a, 0x45, 0x9d, 0x78, 0x24, + 0xc7, 0x78, 0xe1, 0x91, 0x1c, 0xe3, 0x83, 0x47, 0x72, 0x8c, 0x13, 0x1e, 0xcb, 0x31, 0x5c, 0x78, + 0x2c, 0xc7, 0x70, 0xe3, 0xb1, 0x1c, 0x43, 0x94, 0x43, 0x7a, 0x66, 0x49, 0x46, 0x69, 0x92, 0x5e, + 0x72, 0x7e, 0xae, 0xbe, 0x33, 0xd8, 0x59, 0x21, 0x20, 0x37, 0xb9, 0x41, 0x23, 0x17, 0xec, 0x40, + 0x5d, 0x58, 0x54, 0x57, 0xa0, 0xc6, 0x7c, 0x49, 0x65, 0x41, 0x6a, 0x71, 0x12, 0x1b, 0x38, 0xc6, + 0x8d, 0x01, 0x01, 0x00, 0x00, 0xff, 0xff, 0xb3, 0x39, 0x70, 0x15, 0xb4, 0x02, 0x00, 0x00, +} + +func (this *GenesisDenom) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*GenesisDenom) + if !ok { + that2, ok := that.(GenesisDenom) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if this.Denom != that1.Denom { + return false + } + if !this.AuthorityMetadata.Equal(&that1.AuthorityMetadata) { + return false + } + return true +} +func (m *GenesisState) 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) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.FactoryDenoms) > 0 { + for iNdEx := len(m.FactoryDenoms) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.FactoryDenoms[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + { + size, err := m.Params.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 *GenesisDenom) 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 *GenesisDenom) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *GenesisDenom) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.AuthorityMetadata.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + if len(m.Denom) > 0 { + i -= len(m.Denom) + copy(dAtA[i:], m.Denom) + i = encodeVarintGenesis(dAtA, i, uint64(len(m.Denom))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func encodeVarintGenesis(dAtA []byte, offset int, v uint64) int { + offset -= sovGenesis(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *GenesisState) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Params.Size() + n += 1 + l + sovGenesis(uint64(l)) + if len(m.FactoryDenoms) > 0 { + for _, e := range m.FactoryDenoms { + l = e.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + } + return n +} + +func (m *GenesisDenom) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Denom) + if l > 0 { + n += 1 + l + sovGenesis(uint64(l)) + } + l = m.AuthorityMetadata.Size() + n += 1 + l + sovGenesis(uint64(l)) + return n +} + +func sovGenesis(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozGenesis(x uint64) (n int) { + return sovGenesis(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *GenesisState) 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: GenesisState: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GenesisState: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Params", 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 + } + if err := m.Params.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field FactoryDenoms", 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.FactoryDenoms = append(m.FactoryDenoms, GenesisDenom{}) + if err := m.FactoryDenoms[len(m.FactoryDenoms)-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 *GenesisDenom) 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: GenesisDenom: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GenesisDenom: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Denom", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Denom = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AuthorityMetadata", 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 + } + if err := m.AuthorityMetadata.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 skipGenesis(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, ErrIntOverflowGenesis + } + 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, ErrIntOverflowGenesis + } + 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, ErrIntOverflowGenesis + } + 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, ErrInvalidLengthGenesis + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupGenesis + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthGenesis + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthGenesis = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowGenesis = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupGenesis = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/tokenfactory/types/genesis_test.go b/x/tokenfactory/types/genesis_test.go new file mode 100644 index 000000000..7289c62fc --- /dev/null +++ b/x/tokenfactory/types/genesis_test.go @@ -0,0 +1,139 @@ +package types_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/types" +) + +func TestGenesisState_Validate(t *testing.T) { + for _, tc := range []struct { + desc string + genState *types.GenesisState + valid bool + }{ + { + desc: "default is valid", + genState: types.DefaultGenesis(), + valid: true, + }, + { + desc: "valid genesis state", + genState: &types.GenesisState{ + FactoryDenoms: []types.GenesisDenom{ + { + Denom: "factory/cosmos1t7egva48prqmzl59x5ngv4zx0dtrwewcdqdjr8/bitcoin", + AuthorityMetadata: types.DenomAuthorityMetadata{ + Admin: "cosmos1t7egva48prqmzl59x5ngv4zx0dtrwewcdqdjr8", + }, + }, + }, + }, + valid: true, + }, + { + desc: "different admin from creator", + genState: &types.GenesisState{ + FactoryDenoms: []types.GenesisDenom{ + { + Denom: "factory/cosmos1t7egva48prqmzl59x5ngv4zx0dtrwewcdqdjr8/bitcoin", + AuthorityMetadata: types.DenomAuthorityMetadata{ + Admin: "cosmos1ft6e5esdtdegnvcr3djd3ftk4kwpcr6jta8eyh", + }, + }, + }, + }, + valid: true, + }, + { + desc: "empty admin", + genState: &types.GenesisState{ + FactoryDenoms: []types.GenesisDenom{ + { + Denom: "factory/cosmos1t7egva48prqmzl59x5ngv4zx0dtrwewcdqdjr8/bitcoin", + AuthorityMetadata: types.DenomAuthorityMetadata{ + Admin: "", + }, + }, + }, + }, + valid: true, + }, + { + desc: "no admin", + genState: &types.GenesisState{ + FactoryDenoms: []types.GenesisDenom{ + { + Denom: "factory/cosmos1t7egva48prqmzl59x5ngv4zx0dtrwewcdqdjr8/bitcoin", + }, + }, + }, + valid: true, + }, + { + desc: "invalid admin", + genState: &types.GenesisState{ + FactoryDenoms: []types.GenesisDenom{ + { + Denom: "factory/cosmos1t7egva48prqmzl59x5ngv4zx0dtrwewcdqdjr8/bitcoin", + AuthorityMetadata: types.DenomAuthorityMetadata{ + Admin: "moose", + }, + }, + }, + }, + valid: false, + }, + { + desc: "multiple denoms", + genState: &types.GenesisState{ + FactoryDenoms: []types.GenesisDenom{ + { + Denom: "factory/cosmos1t7egva48prqmzl59x5ngv4zx0dtrwewcdqdjr8/bitcoin", + AuthorityMetadata: types.DenomAuthorityMetadata{ + Admin: "", + }, + }, + { + Denom: "factory/cosmos1t7egva48prqmzl59x5ngv4zx0dtrwewcdqdjr8/litecoin", + AuthorityMetadata: types.DenomAuthorityMetadata{ + Admin: "", + }, + }, + }, + }, + valid: true, + }, + { + desc: "duplicate denoms", + genState: &types.GenesisState{ + FactoryDenoms: []types.GenesisDenom{ + { + Denom: "factory/cosmos1t7egva48prqmzl59x5ngv4zx0dtrwewcdqdjr8/bitcoin", + AuthorityMetadata: types.DenomAuthorityMetadata{ + Admin: "", + }, + }, + { + Denom: "factory/cosmos1t7egva48prqmzl59x5ngv4zx0dtrwewcdqdjr8/bitcoin", + AuthorityMetadata: types.DenomAuthorityMetadata{ + Admin: "", + }, + }, + }, + }, + valid: false, + }, + } { + t.Run(tc.desc, func(t *testing.T) { + err := tc.genState.Validate() + if tc.valid { + require.NoError(t, err) + } else { + require.Error(t, err) + } + }) + } +} diff --git a/x/tokenfactory/types/keys.go b/x/tokenfactory/types/keys.go new file mode 100644 index 000000000..fac4a6e39 --- /dev/null +++ b/x/tokenfactory/types/keys.go @@ -0,0 +1,49 @@ +package types + +import ( + "strings" +) + +const ( + // ModuleName defines the module name + ModuleName = "tokenfactory" + + // StoreKey defines the primary module store key + StoreKey = ModuleName + + // RouterKey is the message route for slashing + RouterKey = ModuleName + + // QuerierRoute defines the module's query routing key + QuerierRoute = ModuleName + + // MemStoreKey defines the in-memory store key + MemStoreKey = "mem_tokenfactory" +) + +// KeySeparator is used to combine parts of the keys in the store +const KeySeparator = "|" + +var ( + DenomAuthorityMetadataKey = "authoritymetadata" + DenomsPrefixKey = "denoms" + CreatorPrefixKey = "creator" + AdminPrefixKey = "admin" +) + +// GetDenomPrefixStore returns the store prefix where all the data associated with a specific denom +// is stored +func GetDenomPrefixStore(denom string) []byte { + return []byte(strings.Join([]string{DenomsPrefixKey, denom, ""}, KeySeparator)) +} + +// GetCreatorsPrefix returns the store prefix where the list of the denoms created by a specific +// creator are stored +func GetCreatorPrefix(creator string) []byte { + return []byte(strings.Join([]string{CreatorPrefixKey, creator, ""}, KeySeparator)) +} + +// GetCreatorsPrefix returns the store prefix where a list of all creator addresses are stored +func GetCreatorsPrefix() []byte { + return []byte(strings.Join([]string{CreatorPrefixKey, ""}, KeySeparator)) +} diff --git a/x/tokenfactory/types/msgs.go b/x/tokenfactory/types/msgs.go new file mode 100644 index 000000000..be5e8a716 --- /dev/null +++ b/x/tokenfactory/types/msgs.go @@ -0,0 +1,277 @@ +package types + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" +) + +// constants +const ( + TypeMsgCreateDenom = "create_denom" + TypeMsgMint = "tf_mint" + TypeMsgBurn = "tf_burn" + TypeMsgForceTransfer = "force_transfer" + TypeMsgChangeAdmin = "change_admin" + TypeMsgSetDenomMetadata = "set_denom_metadata" +) + +var _ sdk.Msg = &MsgCreateDenom{} + +// NewMsgCreateDenom creates a msg to create a new denom +func NewMsgCreateDenom(sender, subdenom string) *MsgCreateDenom { + return &MsgCreateDenom{ + Sender: sender, + Subdenom: subdenom, + } +} + +func (m MsgCreateDenom) Route() string { return RouterKey } +func (m MsgCreateDenom) Type() string { return TypeMsgCreateDenom } +func (m MsgCreateDenom) ValidateBasic() error { + _, err := sdk.AccAddressFromBech32(m.Sender) + if err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "Invalid sender address (%s)", err) + } + + _, err = GetTokenDenom(m.Sender, m.Subdenom) + if err != nil { + return sdkerrors.Wrap(ErrInvalidDenom, err.Error()) + } + + return nil +} + +func (m MsgCreateDenom) GetSignBytes() []byte { + return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&m)) +} + +func (m MsgCreateDenom) GetSigners() []sdk.AccAddress { + sender, _ := sdk.AccAddressFromBech32(m.Sender) + return []sdk.AccAddress{sender} +} + +var _ sdk.Msg = &MsgMint{} + +// NewMsgMint creates a message to mint tokens +func NewMsgMint(sender string, amount sdk.Coin) *MsgMint { + return &MsgMint{ + Sender: sender, + Amount: amount, + } +} + +func NewMsgMintTo(sender string, amount sdk.Coin, mintToAddress string) *MsgMint { + return &MsgMint{ + Sender: sender, + Amount: amount, + MintToAddress: mintToAddress, + } +} + +func (m MsgMint) Route() string { return RouterKey } +func (m MsgMint) Type() string { return TypeMsgMint } +func (m MsgMint) ValidateBasic() error { + _, err := sdk.AccAddressFromBech32(m.Sender) + if err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "Invalid sender address (%s)", err) + } + + if m.MintToAddress != "" { + _, err = sdk.AccAddressFromBech32(m.MintToAddress) + if err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "Invalid mint to address (%s)", err) + } + } + + if !m.Amount.IsValid() || m.Amount.Amount.Equal(sdk.ZeroInt()) { + return sdkerrors.Wrap(sdkerrors.ErrInvalidCoins, m.Amount.String()) + } + + return nil +} + +func (m MsgMint) GetSignBytes() []byte { + return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&m)) +} + +func (m MsgMint) GetSigners() []sdk.AccAddress { + sender, _ := sdk.AccAddressFromBech32(m.Sender) + return []sdk.AccAddress{sender} +} + +var _ sdk.Msg = &MsgBurn{} + +// NewMsgBurn creates a message to burn tokens +func NewMsgBurn(sender string, amount sdk.Coin) *MsgBurn { + return &MsgBurn{ + Sender: sender, + Amount: amount, + } +} + +// NewMsgBurn creates a message to burn tokens +func NewMsgBurnFrom(sender string, amount sdk.Coin, burnFromAddress string) *MsgBurn { + return &MsgBurn{ + Sender: sender, + Amount: amount, + BurnFromAddress: burnFromAddress, + } +} + +func (m MsgBurn) Route() string { return RouterKey } +func (m MsgBurn) Type() string { return TypeMsgBurn } +func (m MsgBurn) ValidateBasic() error { + _, err := sdk.AccAddressFromBech32(m.Sender) + if err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "Invalid sender address (%s)", err) + } + + if !m.Amount.IsValid() || m.Amount.Amount.Equal(sdk.ZeroInt()) { + return sdkerrors.Wrap(sdkerrors.ErrInvalidCoins, m.Amount.String()) + } + + if m.BurnFromAddress != "" { + _, err = sdk.AccAddressFromBech32(m.BurnFromAddress) + if err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "Invalid burn from address (%s)", err) + } + } + + return nil +} + +func (m MsgBurn) GetSignBytes() []byte { + return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&m)) +} + +func (m MsgBurn) GetSigners() []sdk.AccAddress { + sender, _ := sdk.AccAddressFromBech32(m.Sender) + return []sdk.AccAddress{sender} +} + +var _ sdk.Msg = &MsgForceTransfer{} + +// NewMsgForceTransfer creates a transfer funds from one account to another +func NewMsgForceTransfer(sender string, amount sdk.Coin, fromAddr, toAddr string) *MsgForceTransfer { + return &MsgForceTransfer{ + Sender: sender, + Amount: amount, + TransferFromAddress: fromAddr, + TransferToAddress: toAddr, + } +} + +func (m MsgForceTransfer) Route() string { return RouterKey } +func (m MsgForceTransfer) Type() string { return TypeMsgForceTransfer } +func (m MsgForceTransfer) ValidateBasic() error { + _, err := sdk.AccAddressFromBech32(m.Sender) + if err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "Invalid sender address (%s)", err) + } + + _, err = sdk.AccAddressFromBech32(m.TransferFromAddress) + if err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "Invalid from address (%s)", err) + } + _, err = sdk.AccAddressFromBech32(m.TransferToAddress) + if err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "Invalid to address (%s)", err) + } + + if !m.Amount.IsValid() { + return sdkerrors.Wrap(sdkerrors.ErrInvalidCoins, m.Amount.String()) + } + + return nil +} + +func (m MsgForceTransfer) GetSignBytes() []byte { + return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&m)) +} + +func (m MsgForceTransfer) GetSigners() []sdk.AccAddress { + sender, _ := sdk.AccAddressFromBech32(m.Sender) + return []sdk.AccAddress{sender} +} + +var _ sdk.Msg = &MsgChangeAdmin{} + +// NewMsgChangeAdmin creates a message to burn tokens +func NewMsgChangeAdmin(sender, denom, newAdmin string) *MsgChangeAdmin { + return &MsgChangeAdmin{ + Sender: sender, + Denom: denom, + NewAdmin: newAdmin, + } +} + +func (m MsgChangeAdmin) Route() string { return RouterKey } +func (m MsgChangeAdmin) Type() string { return TypeMsgChangeAdmin } +func (m MsgChangeAdmin) ValidateBasic() error { + _, err := sdk.AccAddressFromBech32(m.Sender) + if err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "Invalid sender address (%s)", err) + } + + _, err = sdk.AccAddressFromBech32(m.NewAdmin) + if err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "Invalid address (%s)", err) + } + + _, _, err = DeconstructDenom(m.Denom) + if err != nil { + return err + } + + return nil +} + +func (m MsgChangeAdmin) GetSignBytes() []byte { + return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&m)) +} + +func (m MsgChangeAdmin) GetSigners() []sdk.AccAddress { + sender, _ := sdk.AccAddressFromBech32(m.Sender) + return []sdk.AccAddress{sender} +} + +var _ sdk.Msg = &MsgSetDenomMetadata{} + +// NewMsgChangeAdmin creates a message to burn tokens +func NewMsgSetDenomMetadata(sender string, metadata banktypes.Metadata) *MsgSetDenomMetadata { + return &MsgSetDenomMetadata{ + Sender: sender, + Metadata: metadata, + } +} + +func (m MsgSetDenomMetadata) Route() string { return RouterKey } +func (m MsgSetDenomMetadata) Type() string { return TypeMsgSetDenomMetadata } +func (m MsgSetDenomMetadata) ValidateBasic() error { + _, err := sdk.AccAddressFromBech32(m.Sender) + if err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "Invalid sender address (%s)", err) + } + + err = m.Metadata.Validate() + if err != nil { + return err + } + + _, _, err = DeconstructDenom(m.Metadata.Base) + if err != nil { + return err + } + + return nil +} + +func (m MsgSetDenomMetadata) GetSignBytes() []byte { + return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&m)) +} + +func (m MsgSetDenomMetadata) GetSigners() []sdk.AccAddress { + sender, _ := sdk.AccAddressFromBech32(m.Sender) + return []sdk.AccAddress{sender} +} diff --git a/x/tokenfactory/types/msgs_test.go b/x/tokenfactory/types/msgs_test.go new file mode 100644 index 000000000..d713e1ecf --- /dev/null +++ b/x/tokenfactory/types/msgs_test.go @@ -0,0 +1,451 @@ +package types_test + +import ( + fmt "fmt" + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/require" + + "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/testhelpers" + "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/types" + + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + "github.com/tendermint/tendermint/crypto/ed25519" +) + +// // Test authz serialize and de-serializes for tokenfactory msg. +func TestAuthzMsg(t *testing.T) { + t.Skip("TODO: figure out how to register authz interfaces for tests") + pk1 := ed25519.GenPrivKey().PubKey() + addr1 := sdk.AccAddress(pk1.Address()).String() + coin := sdk.NewCoin("denom", sdk.NewInt(1)) + + testCases := []struct { + name string + msg sdk.Msg + }{ + { + name: "MsgCreateDenom", + msg: &types.MsgCreateDenom{ + Sender: addr1, + Subdenom: "valoper1xyz", + }, + }, + { + name: "MsgBurn", + msg: &types.MsgBurn{ + Sender: addr1, + Amount: coin, + }, + }, + { + name: "MsgMint", + msg: &types.MsgMint{ + Sender: addr1, + Amount: coin, + }, + }, + { + name: "MsgChangeAdmin", + msg: &types.MsgChangeAdmin{ + Sender: addr1, + Denom: "denom", + NewAdmin: "osmo1q8tq5qhrhw6t970egemuuwywhlhpnmdmts6xnu", + }, + }, + } + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + testhelpers.TestMessageAuthzSerialization(t, tc.msg) + }) + } +} + +// TestMsgCreateDenom tests if valid/invalid create denom messages are properly validated/invalidated +func TestMsgCreateDenom(t *testing.T) { + // generate a private/public key pair and get the respective address + pk1 := ed25519.GenPrivKey().PubKey() + addr1 := sdk.AccAddress(pk1.Address()) + + // make a proper createDenom message + createMsg := func(after func(msg types.MsgCreateDenom) types.MsgCreateDenom) types.MsgCreateDenom { + properMsg := *types.NewMsgCreateDenom( + addr1.String(), + "bitcoin", + ) + + return after(properMsg) + } + + // validate createDenom message was created as intended + msg := createMsg(func(msg types.MsgCreateDenom) types.MsgCreateDenom { + return msg + }) + require.Equal(t, msg.Route(), types.RouterKey) + require.Equal(t, msg.Type(), "create_denom") + signers := msg.GetSigners() + require.Equal(t, len(signers), 1) + require.Equal(t, signers[0].String(), addr1.String()) + + tests := []struct { + name string + msg types.MsgCreateDenom + expectPass bool + }{ + { + name: "proper msg", + msg: createMsg(func(msg types.MsgCreateDenom) types.MsgCreateDenom { + return msg + }), + expectPass: true, + }, + { + name: "empty sender", + msg: createMsg(func(msg types.MsgCreateDenom) types.MsgCreateDenom { + msg.Sender = "" + return msg + }), + expectPass: false, + }, + { + name: "invalid subdenom", + msg: createMsg(func(msg types.MsgCreateDenom) types.MsgCreateDenom { + msg.Subdenom = "thissubdenomismuchtoolongasdkfjaasdfdsafsdlkfnmlksadmflksmdlfmlsakmfdsafasdfasdf" + return msg + }), + expectPass: false, + }, + } + + for _, test := range tests { + if test.expectPass { + require.NoError(t, test.msg.ValidateBasic(), "test: %v", test.name) + } else { + require.Error(t, test.msg.ValidateBasic(), "test: %v", test.name) + } + } +} + +// TestMsgMint tests if valid/invalid create denom messages are properly validated/invalidated +func TestMsgMint(t *testing.T) { + // generate a private/public key pair and get the respective address + pk1 := ed25519.GenPrivKey().PubKey() + addr1 := sdk.AccAddress(pk1.Address()) + + // make a proper mint message + createMsg := func(after func(msg types.MsgMint) types.MsgMint) types.MsgMint { + properMsg := *types.NewMsgMint( + addr1.String(), + sdk.NewCoin("bitcoin", sdk.NewInt(500000000)), + ) + + return after(properMsg) + } + + // validate mint message was created as intended + msg := createMsg(func(msg types.MsgMint) types.MsgMint { + return msg + }) + require.Equal(t, msg.Route(), types.RouterKey) + require.Equal(t, msg.Type(), "tf_mint") + signers := msg.GetSigners() + require.Equal(t, len(signers), 1) + require.Equal(t, signers[0].String(), addr1.String()) + + tests := []struct { + name string + msg types.MsgMint + expectPass bool + }{ + { + name: "proper msg", + msg: createMsg(func(msg types.MsgMint) types.MsgMint { + return msg + }), + expectPass: true, + }, + { + name: "empty sender", + msg: createMsg(func(msg types.MsgMint) types.MsgMint { + msg.Sender = "" + return msg + }), + expectPass: false, + }, + { + name: "zero amount", + msg: createMsg(func(msg types.MsgMint) types.MsgMint { + msg.Amount = sdk.NewCoin("bitcoin", sdk.ZeroInt()) + return msg + }), + expectPass: false, + }, + { + name: "negative amount", + msg: createMsg(func(msg types.MsgMint) types.MsgMint { + msg.Amount.Amount = sdk.NewInt(-10000000) + return msg + }), + expectPass: false, + }, + } + + for _, test := range tests { + if test.expectPass { + require.NoError(t, test.msg.ValidateBasic(), "test: %v", test.name) + } else { + require.Error(t, test.msg.ValidateBasic(), "test: %v", test.name) + } + } +} + +// TestMsgBurn tests if valid/invalid create denom messages are properly validated/invalidated +func TestMsgBurn(t *testing.T) { + // generate a private/public key pair and get the respective address + pk1 := ed25519.GenPrivKey().PubKey() + addr1 := sdk.AccAddress(pk1.Address()) + + // make a proper burn message + baseMsg := types.NewMsgBurn( + addr1.String(), + sdk.NewCoin("bitcoin", sdk.NewInt(500000000)), + ) + + // validate burn message was created as intended + require.Equal(t, baseMsg.Route(), types.RouterKey) + require.Equal(t, baseMsg.Type(), "tf_burn") + signers := baseMsg.GetSigners() + require.Equal(t, len(signers), 1) + require.Equal(t, signers[0].String(), addr1.String()) + + tests := []struct { + name string + msg func() *types.MsgBurn + expectPass bool + }{ + { + name: "proper msg", + msg: func() *types.MsgBurn { + msg := baseMsg + return msg + }, + expectPass: true, + }, + { + name: "empty sender", + msg: func() *types.MsgBurn { + msg := baseMsg + msg.Sender = "" + return msg + }, + expectPass: false, + }, + { + name: "zero amount", + msg: func() *types.MsgBurn { + msg := baseMsg + msg.Amount.Amount = sdk.ZeroInt() + return msg + }, + expectPass: false, + }, + { + name: "negative amount", + msg: func() *types.MsgBurn { + msg := baseMsg + msg.Amount.Amount = sdk.NewInt(-10000000) + return msg + }, + expectPass: false, + }, + } + + for _, test := range tests { + if test.expectPass { + require.NoError(t, test.msg().ValidateBasic(), "test: %v", test.name) + } else { + require.Error(t, test.msg().ValidateBasic(), "test: %v", test.name) + } + } +} + +// TestMsgChangeAdmin tests if valid/invalid create denom messages are properly validated/invalidated +func TestMsgChangeAdmin(t *testing.T) { + // generate a private/public key pair and get the respective address + pk1 := ed25519.GenPrivKey().PubKey() + addr1 := sdk.AccAddress(pk1.Address()) + pk2 := ed25519.GenPrivKey().PubKey() + addr2 := sdk.AccAddress(pk2.Address()) + tokenFactoryDenom := fmt.Sprintf("factory/%s/bitcoin", addr1.String()) + + // make a proper changeAdmin message + baseMsg := types.NewMsgChangeAdmin( + addr1.String(), + tokenFactoryDenom, + addr2.String(), + ) + + // validate changeAdmin message was created as intended + require.Equal(t, baseMsg.Route(), types.RouterKey) + require.Equal(t, baseMsg.Type(), "change_admin") + signers := baseMsg.GetSigners() + require.Equal(t, len(signers), 1) + require.Equal(t, signers[0].String(), addr1.String()) + + tests := []struct { + name string + msg func() *types.MsgChangeAdmin + expectPass bool + }{ + { + name: "proper msg", + msg: func() *types.MsgChangeAdmin { + msg := baseMsg + return msg + }, + expectPass: true, + }, + { + name: "empty sender", + msg: func() *types.MsgChangeAdmin { + msg := baseMsg + msg.Sender = "" + return msg + }, + expectPass: false, + }, + { + name: "empty newAdmin", + msg: func() *types.MsgChangeAdmin { + msg := baseMsg + msg.NewAdmin = "" + return msg + }, + expectPass: false, + }, + { + name: "invalid denom", + msg: func() *types.MsgChangeAdmin { + msg := baseMsg + msg.Denom = "bitcoin" + return msg + }, + expectPass: false, + }, + } + + for _, test := range tests { + if test.expectPass { + require.NoError(t, test.msg().ValidateBasic(), "test: %v", test.name) + } else { + require.Error(t, test.msg().ValidateBasic(), "test: %v", test.name) + } + } +} + +// TestMsgSetDenomMetadata tests if valid/invalid create denom messages are properly validated/invalidated +func TestMsgSetDenomMetadata(t *testing.T) { + // generate a private/public key pair and get the respective address + pk1 := ed25519.GenPrivKey().PubKey() + addr1 := sdk.AccAddress(pk1.Address()) + tokenFactoryDenom := fmt.Sprintf("factory/%s/bitcoin", addr1.String()) + denomMetadata := banktypes.Metadata{ + Description: "nakamoto", + DenomUnits: []*banktypes.DenomUnit{ + { + Denom: tokenFactoryDenom, + Exponent: 0, + }, + { + Denom: "sats", + Exponent: 6, + }, + }, + Display: "sats", + Base: tokenFactoryDenom, + Name: "bitcoin", + Symbol: "BTC", + } + invalidDenomMetadata := banktypes.Metadata{ + Description: "nakamoto", + DenomUnits: []*banktypes.DenomUnit{ + { + Denom: "bitcoin", + Exponent: 0, + }, + { + Denom: "sats", + Exponent: 6, + }, + }, + Display: "sats", + Base: "bitcoin", + Name: "bitcoin", + Symbol: "BTC", + } + + // make a proper setDenomMetadata message + baseMsg := types.NewMsgSetDenomMetadata( + addr1.String(), + denomMetadata, + ) + + // validate setDenomMetadata message was created as intended + require.Equal(t, baseMsg.Route(), types.RouterKey) + require.Equal(t, baseMsg.Type(), "set_denom_metadata") + signers := baseMsg.GetSigners() + require.Equal(t, len(signers), 1) + require.Equal(t, signers[0].String(), addr1.String()) + + tests := []struct { + name string + msg func() *types.MsgSetDenomMetadata + expectPass bool + }{ + { + name: "proper msg", + msg: func() *types.MsgSetDenomMetadata { + msg := baseMsg + return msg + }, + expectPass: true, + }, + { + name: "empty sender", + msg: func() *types.MsgSetDenomMetadata { + msg := baseMsg + msg.Sender = "" + return msg + }, + expectPass: false, + }, + { + name: "invalid metadata", + msg: func() *types.MsgSetDenomMetadata { + msg := baseMsg + msg.Metadata.Name = "" + return msg + }, + + expectPass: false, + }, + { + name: "invalid base", + msg: func() *types.MsgSetDenomMetadata { + msg := baseMsg + msg.Metadata = invalidDenomMetadata + return msg + }, + expectPass: false, + }, + } + + for _, test := range tests { + if test.expectPass { + require.NoError(t, test.msg().ValidateBasic(), "test: %v", test.name) + } else { + require.Error(t, test.msg().ValidateBasic(), "test: %v", test.name) + } + } +} diff --git a/x/tokenfactory/types/params.go b/x/tokenfactory/types/params.go new file mode 100644 index 000000000..cf481ba84 --- /dev/null +++ b/x/tokenfactory/types/params.go @@ -0,0 +1,70 @@ +package types + +import ( + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" +) + +// Parameter store keys. +var ( + KeyDenomCreationFee = []byte("DenomCreationFee") + KeyDenomCreationGasConsume = []byte("DenomCreationGasConsume") +) + +// ParamTable for tokenfactory module. +func ParamKeyTable() paramtypes.KeyTable { + return paramtypes.NewKeyTable().RegisterParamSet(&Params{}) +} + +func NewParams(denomCreationFee sdk.Coins) Params { + return Params{ + DenomCreationFee: denomCreationFee, + } +} + +// default tokenfactory module parameters. +func DefaultParams() Params { + return Params{ + DenomCreationFee: sdk.NewCoins(sdk.NewInt64Coin(sdk.DefaultBondDenom, 10_000_000)), + DenomCreationGasConsume: 2_000_000, + } +} + +// validate params. +func (p Params) Validate() error { + err := validateDenomCreationFee(p.DenomCreationFee) + + return err +} + +// Implements params.ParamSet. +func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs { + return paramtypes.ParamSetPairs{ + paramtypes.NewParamSetPair(KeyDenomCreationFee, &p.DenomCreationFee, validateDenomCreationFee), + paramtypes.NewParamSetPair(KeyDenomCreationGasConsume, &p.DenomCreationGasConsume, validateDenomCreationFeeGasConsume), + } +} + +func validateDenomCreationFee(i interface{}) error { + v, ok := i.(sdk.Coins) + if !ok { + return fmt.Errorf("invalid parameter type: %T", i) + } + + if v.Validate() != nil { + return fmt.Errorf("invalid denom creation fee: %+v", i) + } + + return nil +} + +func validateDenomCreationFeeGasConsume(i interface{}) error { + _, ok := i.(uint64) + if !ok { + return fmt.Errorf("invalid parameter type: %T", i) + } + + return nil +} diff --git a/x/tokenfactory/types/params.pb.go b/x/tokenfactory/types/params.pb.go new file mode 100644 index 000000000..63cb9f459 --- /dev/null +++ b/x/tokenfactory/types/params.pb.go @@ -0,0 +1,383 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: osmosis/tokenfactory/v1beta1/params.proto + +package types + +import ( + fmt "fmt" + _ "github.com/cosmos/cosmos-proto" + github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types" + types "github.com/cosmos/cosmos-sdk/types" + _ "github.com/cosmos/gogoproto/gogoproto" + proto "github.com/gogo/protobuf/proto" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = 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 + +// Params defines the parameters for the tokenfactory module. +type Params struct { + DenomCreationFee github_com_cosmos_cosmos_sdk_types.Coins `protobuf:"bytes,1,rep,name=denom_creation_fee,json=denomCreationFee,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.Coins" json:"denom_creation_fee" yaml:"denom_creation_fee"` + // if denom_creation_fee is an empty array, then this field is used to add more gas consumption + // to the base cost. + // https://github.com/CosmWasm/token-factory/issues/11 + DenomCreationGasConsume uint64 `protobuf:"varint,2,opt,name=denom_creation_gas_consume,json=denomCreationGasConsume,proto3" json:"denom_creation_gas_consume,omitempty" yaml:"denom_creation_gas_consume"` +} + +func (m *Params) Reset() { *m = Params{} } +func (m *Params) String() string { return proto.CompactTextString(m) } +func (*Params) ProtoMessage() {} +func (*Params) Descriptor() ([]byte, []int) { + return fileDescriptor_cc8299d306f3ff47, []int{0} +} +func (m *Params) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Params) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Params.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 *Params) XXX_Merge(src proto.Message) { + xxx_messageInfo_Params.Merge(m, src) +} +func (m *Params) XXX_Size() int { + return m.Size() +} +func (m *Params) XXX_DiscardUnknown() { + xxx_messageInfo_Params.DiscardUnknown(m) +} + +var xxx_messageInfo_Params proto.InternalMessageInfo + +func (m *Params) GetDenomCreationFee() github_com_cosmos_cosmos_sdk_types.Coins { + if m != nil { + return m.DenomCreationFee + } + return nil +} + +func (m *Params) GetDenomCreationGasConsume() uint64 { + if m != nil { + return m.DenomCreationGasConsume + } + return 0 +} + +func init() { + proto.RegisterType((*Params)(nil), "osmosis.tokenfactory.v1beta1.Params") +} + +func init() { + proto.RegisterFile("osmosis/tokenfactory/v1beta1/params.proto", fileDescriptor_cc8299d306f3ff47) +} + +var fileDescriptor_cc8299d306f3ff47 = []byte{ + // 355 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x91, 0xb1, 0x4e, 0xc2, 0x50, + 0x14, 0x86, 0x7b, 0xd1, 0x30, 0xd4, 0xc5, 0x34, 0x26, 0x02, 0x31, 0xb7, 0xd8, 0x09, 0x06, 0xda, + 0xa0, 0x4e, 0x4e, 0x86, 0x26, 0x38, 0x91, 0x18, 0xe2, 0xc4, 0xd2, 0x9c, 0x96, 0x4b, 0x69, 0xb0, + 0x3d, 0xa4, 0xf7, 0x62, 0xec, 0x23, 0xb8, 0x39, 0xf9, 0x10, 0x3e, 0x09, 0x23, 0xa3, 0x53, 0x35, + 0xf0, 0x06, 0x3c, 0x81, 0xe1, 0xf6, 0x62, 0x40, 0x8d, 0x53, 0x7b, 0x72, 0xfe, 0xff, 0xeb, 0x7f, + 0xfa, 0xeb, 0x4d, 0xe4, 0x31, 0xf2, 0x88, 0x3b, 0x02, 0x27, 0x2c, 0x19, 0x41, 0x20, 0x30, 0xcd, + 0x9c, 0xc7, 0xb6, 0xcf, 0x04, 0xb4, 0x9d, 0x29, 0xa4, 0x10, 0x73, 0x7b, 0x9a, 0xa2, 0x40, 0xe3, + 0x4c, 0x49, 0xed, 0x5d, 0xa9, 0xad, 0xa4, 0xb5, 0x93, 0x10, 0x43, 0x94, 0x42, 0x67, 0xf3, 0x56, + 0x78, 0x6a, 0x57, 0xff, 0xe2, 0x61, 0x26, 0xc6, 0x98, 0x46, 0x22, 0xeb, 0x31, 0x01, 0x43, 0x10, + 0xa0, 0x5c, 0xd5, 0x40, 0xda, 0xbc, 0x02, 0x57, 0x0c, 0x6a, 0x45, 0x8b, 0xc9, 0xf1, 0x81, 0xb3, + 0x6f, 0x4e, 0x80, 0x51, 0x52, 0xec, 0xad, 0xe7, 0x92, 0x5e, 0xbe, 0x93, 0xa9, 0x8d, 0x57, 0xa2, + 0x1b, 0x43, 0x96, 0x60, 0xec, 0x05, 0x29, 0x03, 0x11, 0x61, 0xe2, 0x8d, 0x18, 0xab, 0x90, 0xfa, + 0x41, 0xe3, 0xe8, 0xa2, 0x6a, 0x2b, 0xec, 0x06, 0xb4, 0x3d, 0xc2, 0x76, 0x31, 0x4a, 0x3a, 0xbd, + 0x79, 0x6e, 0x6a, 0xeb, 0xdc, 0xac, 0x66, 0x10, 0x3f, 0x5c, 0x5b, 0xbf, 0x11, 0xd6, 0xdb, 0x87, + 0xd9, 0x08, 0x23, 0x31, 0x9e, 0xf9, 0x76, 0x80, 0xb1, 0x0a, 0xa8, 0x1e, 0x2d, 0x3e, 0x9c, 0x38, + 0x22, 0x9b, 0x32, 0x2e, 0x69, 0xbc, 0x7f, 0x2c, 0x01, 0xae, 0xf2, 0x77, 0x19, 0x33, 0x46, 0x7a, + 0xed, 0x07, 0x34, 0x04, 0xee, 0x05, 0x98, 0xf0, 0x59, 0xcc, 0x2a, 0xa5, 0x3a, 0x69, 0x1c, 0x76, + 0x9a, 0xf3, 0xdc, 0x24, 0xeb, 0xdc, 0x3c, 0xff, 0x33, 0xc4, 0x8e, 0xde, 0xea, 0x9f, 0xee, 0x7d, + 0xe0, 0x16, 0xb8, 0x5b, 0x6c, 0x3a, 0x83, 0xf9, 0x92, 0x92, 0xc5, 0x92, 0x92, 0xcf, 0x25, 0x25, + 0x2f, 0x2b, 0xaa, 0x2d, 0x56, 0x54, 0x7b, 0x5f, 0x51, 0x6d, 0x70, 0xb3, 0x93, 0xde, 0x95, 0xb1, + 0xef, 0x37, 0xfd, 0x74, 0x55, 0x3f, 0xb2, 0xac, 0xd6, 0xb6, 0xad, 0xa7, 0xfd, 0xf2, 0xe4, 0x6d, + 0x7e, 0x59, 0xfe, 0xee, 0xcb, 0xaf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x17, 0xac, 0x28, 0xc6, 0x40, + 0x02, 0x00, 0x00, +} + +func (m *Params) 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 *Params) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.DenomCreationGasConsume != 0 { + i = encodeVarintParams(dAtA, i, uint64(m.DenomCreationGasConsume)) + i-- + dAtA[i] = 0x10 + } + if len(m.DenomCreationFee) > 0 { + for iNdEx := len(m.DenomCreationFee) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.DenomCreationFee[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintParams(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func encodeVarintParams(dAtA []byte, offset int, v uint64) int { + offset -= sovParams(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *Params) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.DenomCreationFee) > 0 { + for _, e := range m.DenomCreationFee { + l = e.Size() + n += 1 + l + sovParams(uint64(l)) + } + } + if m.DenomCreationGasConsume != 0 { + n += 1 + sovParams(uint64(m.DenomCreationGasConsume)) + } + return n +} + +func sovParams(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozParams(x uint64) (n int) { + return sovParams(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *Params) 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 ErrIntOverflowParams + } + 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: Params: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Params: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DenomCreationFee", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthParams + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthParams + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.DenomCreationFee = append(m.DenomCreationFee, types.Coin{}) + if err := m.DenomCreationFee[len(m.DenomCreationFee)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field DenomCreationGasConsume", wireType) + } + m.DenomCreationGasConsume = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.DenomCreationGasConsume |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipParams(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthParams + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipParams(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, ErrIntOverflowParams + } + 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, ErrIntOverflowParams + } + 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, ErrIntOverflowParams + } + 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, ErrInvalidLengthParams + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupParams + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthParams + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthParams = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowParams = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupParams = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/tokenfactory/types/query.pb.go b/x/tokenfactory/types/query.pb.go new file mode 100644 index 000000000..1e201985d --- /dev/null +++ b/x/tokenfactory/types/query.pb.go @@ -0,0 +1,1332 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: osmosis/tokenfactory/v1beta1/query.proto + +package types + +import ( + context "context" + fmt "fmt" + _ "github.com/cosmos/cosmos-sdk/types/query" + _ "github.com/cosmos/gogoproto/gogoproto" + grpc1 "github.com/gogo/protobuf/grpc" + proto "github.com/gogo/protobuf/proto" + _ "google.golang.org/genproto/googleapis/api/annotations" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = 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 + +// QueryParamsRequest is the request type for the Query/Params RPC method. +type QueryParamsRequest struct { +} + +func (m *QueryParamsRequest) Reset() { *m = QueryParamsRequest{} } +func (m *QueryParamsRequest) String() string { return proto.CompactTextString(m) } +func (*QueryParamsRequest) ProtoMessage() {} +func (*QueryParamsRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_6f22013ad0f72e3f, []int{0} +} +func (m *QueryParamsRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryParamsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryParamsRequest.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 *QueryParamsRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryParamsRequest.Merge(m, src) +} +func (m *QueryParamsRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryParamsRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryParamsRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryParamsRequest proto.InternalMessageInfo + +// QueryParamsResponse is the response type for the Query/Params RPC method. +type QueryParamsResponse struct { + // params defines the parameters of the module. + Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` +} + +func (m *QueryParamsResponse) Reset() { *m = QueryParamsResponse{} } +func (m *QueryParamsResponse) String() string { return proto.CompactTextString(m) } +func (*QueryParamsResponse) ProtoMessage() {} +func (*QueryParamsResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_6f22013ad0f72e3f, []int{1} +} +func (m *QueryParamsResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryParamsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryParamsResponse.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 *QueryParamsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryParamsResponse.Merge(m, src) +} +func (m *QueryParamsResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryParamsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryParamsResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryParamsResponse proto.InternalMessageInfo + +func (m *QueryParamsResponse) GetParams() Params { + if m != nil { + return m.Params + } + return Params{} +} + +// QueryDenomAuthorityMetadataRequest defines the request structure for the +// DenomAuthorityMetadata gRPC query. +type QueryDenomAuthorityMetadataRequest struct { + Denom string `protobuf:"bytes,1,opt,name=denom,proto3" json:"denom,omitempty" yaml:"denom"` +} + +func (m *QueryDenomAuthorityMetadataRequest) Reset() { *m = QueryDenomAuthorityMetadataRequest{} } +func (m *QueryDenomAuthorityMetadataRequest) String() string { return proto.CompactTextString(m) } +func (*QueryDenomAuthorityMetadataRequest) ProtoMessage() {} +func (*QueryDenomAuthorityMetadataRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_6f22013ad0f72e3f, []int{2} +} +func (m *QueryDenomAuthorityMetadataRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryDenomAuthorityMetadataRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryDenomAuthorityMetadataRequest.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 *QueryDenomAuthorityMetadataRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryDenomAuthorityMetadataRequest.Merge(m, src) +} +func (m *QueryDenomAuthorityMetadataRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryDenomAuthorityMetadataRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryDenomAuthorityMetadataRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryDenomAuthorityMetadataRequest proto.InternalMessageInfo + +func (m *QueryDenomAuthorityMetadataRequest) GetDenom() string { + if m != nil { + return m.Denom + } + return "" +} + +// QueryDenomAuthorityMetadataResponse defines the response structure for the +// DenomAuthorityMetadata gRPC query. +type QueryDenomAuthorityMetadataResponse struct { + AuthorityMetadata DenomAuthorityMetadata `protobuf:"bytes,1,opt,name=authority_metadata,json=authorityMetadata,proto3" json:"authority_metadata" yaml:"authority_metadata"` +} + +func (m *QueryDenomAuthorityMetadataResponse) Reset() { *m = QueryDenomAuthorityMetadataResponse{} } +func (m *QueryDenomAuthorityMetadataResponse) String() string { return proto.CompactTextString(m) } +func (*QueryDenomAuthorityMetadataResponse) ProtoMessage() {} +func (*QueryDenomAuthorityMetadataResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_6f22013ad0f72e3f, []int{3} +} +func (m *QueryDenomAuthorityMetadataResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryDenomAuthorityMetadataResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryDenomAuthorityMetadataResponse.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 *QueryDenomAuthorityMetadataResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryDenomAuthorityMetadataResponse.Merge(m, src) +} +func (m *QueryDenomAuthorityMetadataResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryDenomAuthorityMetadataResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryDenomAuthorityMetadataResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryDenomAuthorityMetadataResponse proto.InternalMessageInfo + +func (m *QueryDenomAuthorityMetadataResponse) GetAuthorityMetadata() DenomAuthorityMetadata { + if m != nil { + return m.AuthorityMetadata + } + return DenomAuthorityMetadata{} +} + +// QueryDenomsFromCreatorRequest defines the request structure for the +// DenomsFromCreator gRPC query. +type QueryDenomsFromCreatorRequest struct { + Creator string `protobuf:"bytes,1,opt,name=creator,proto3" json:"creator,omitempty" yaml:"creator"` +} + +func (m *QueryDenomsFromCreatorRequest) Reset() { *m = QueryDenomsFromCreatorRequest{} } +func (m *QueryDenomsFromCreatorRequest) String() string { return proto.CompactTextString(m) } +func (*QueryDenomsFromCreatorRequest) ProtoMessage() {} +func (*QueryDenomsFromCreatorRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_6f22013ad0f72e3f, []int{4} +} +func (m *QueryDenomsFromCreatorRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryDenomsFromCreatorRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryDenomsFromCreatorRequest.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 *QueryDenomsFromCreatorRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryDenomsFromCreatorRequest.Merge(m, src) +} +func (m *QueryDenomsFromCreatorRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryDenomsFromCreatorRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryDenomsFromCreatorRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryDenomsFromCreatorRequest proto.InternalMessageInfo + +func (m *QueryDenomsFromCreatorRequest) GetCreator() string { + if m != nil { + return m.Creator + } + return "" +} + +// QueryDenomsFromCreatorRequest defines the response structure for the +// DenomsFromCreator gRPC query. +type QueryDenomsFromCreatorResponse struct { + Denoms []string `protobuf:"bytes,1,rep,name=denoms,proto3" json:"denoms,omitempty" yaml:"denoms"` +} + +func (m *QueryDenomsFromCreatorResponse) Reset() { *m = QueryDenomsFromCreatorResponse{} } +func (m *QueryDenomsFromCreatorResponse) String() string { return proto.CompactTextString(m) } +func (*QueryDenomsFromCreatorResponse) ProtoMessage() {} +func (*QueryDenomsFromCreatorResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_6f22013ad0f72e3f, []int{5} +} +func (m *QueryDenomsFromCreatorResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryDenomsFromCreatorResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryDenomsFromCreatorResponse.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 *QueryDenomsFromCreatorResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryDenomsFromCreatorResponse.Merge(m, src) +} +func (m *QueryDenomsFromCreatorResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryDenomsFromCreatorResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryDenomsFromCreatorResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryDenomsFromCreatorResponse proto.InternalMessageInfo + +func (m *QueryDenomsFromCreatorResponse) GetDenoms() []string { + if m != nil { + return m.Denoms + } + return nil +} + +func init() { + proto.RegisterType((*QueryParamsRequest)(nil), "osmosis.tokenfactory.v1beta1.QueryParamsRequest") + proto.RegisterType((*QueryParamsResponse)(nil), "osmosis.tokenfactory.v1beta1.QueryParamsResponse") + proto.RegisterType((*QueryDenomAuthorityMetadataRequest)(nil), "osmosis.tokenfactory.v1beta1.QueryDenomAuthorityMetadataRequest") + proto.RegisterType((*QueryDenomAuthorityMetadataResponse)(nil), "osmosis.tokenfactory.v1beta1.QueryDenomAuthorityMetadataResponse") + proto.RegisterType((*QueryDenomsFromCreatorRequest)(nil), "osmosis.tokenfactory.v1beta1.QueryDenomsFromCreatorRequest") + proto.RegisterType((*QueryDenomsFromCreatorResponse)(nil), "osmosis.tokenfactory.v1beta1.QueryDenomsFromCreatorResponse") +} + +func init() { + proto.RegisterFile("osmosis/tokenfactory/v1beta1/query.proto", fileDescriptor_6f22013ad0f72e3f) +} + +var fileDescriptor_6f22013ad0f72e3f = []byte{ + // 574 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x54, 0x4f, 0x4f, 0x13, 0x41, + 0x14, 0xef, 0x2a, 0xd4, 0x30, 0xfe, 0x89, 0x1d, 0x89, 0xd1, 0x06, 0xb7, 0x3a, 0x12, 0x52, 0x0c, + 0xee, 0x58, 0xe4, 0x24, 0x1a, 0xe9, 0xd6, 0xe0, 0x41, 0x49, 0x74, 0xe3, 0x45, 0x2e, 0xcd, 0xb4, + 0x0c, 0xcb, 0x46, 0x76, 0x67, 0xd9, 0x99, 0x1a, 0x1b, 0xc2, 0xc5, 0x83, 0x67, 0x13, 0x8f, 0x7e, + 0x07, 0x3f, 0x07, 0x47, 0x12, 0x2e, 0x9e, 0x1a, 0xd3, 0x12, 0x3f, 0x40, 0x3f, 0x81, 0xd9, 0x99, + 0x57, 0x04, 0x5b, 0x37, 0x55, 0x4e, 0xdd, 0xcc, 0xfb, 0xbd, 0xdf, 0x9f, 0xf7, 0x5e, 0x8a, 0xca, + 0x42, 0x86, 0x42, 0x06, 0x92, 0x2a, 0xf1, 0x8e, 0x47, 0x9b, 0xac, 0xa9, 0x44, 0xd2, 0xa6, 0xef, + 0x2b, 0x0d, 0xae, 0x58, 0x85, 0xee, 0xb4, 0x78, 0xd2, 0x76, 0xe2, 0x44, 0x28, 0x81, 0x67, 0x00, + 0xe9, 0x9c, 0x44, 0x3a, 0x80, 0x2c, 0x4e, 0xfb, 0xc2, 0x17, 0x1a, 0x48, 0xd3, 0x2f, 0xd3, 0x53, + 0x9c, 0xf1, 0x85, 0xf0, 0xb7, 0x39, 0x65, 0x71, 0x40, 0x59, 0x14, 0x09, 0xc5, 0x54, 0x20, 0x22, + 0x09, 0xd5, 0x7b, 0x4d, 0x4d, 0x49, 0x1b, 0x4c, 0x72, 0x23, 0x75, 0x2c, 0x1c, 0x33, 0x3f, 0x88, + 0x34, 0x18, 0xb0, 0x4b, 0x99, 0x3e, 0x59, 0x4b, 0x6d, 0x89, 0x24, 0x50, 0xed, 0x35, 0xae, 0xd8, + 0x06, 0x53, 0x0c, 0xba, 0xe6, 0x33, 0xbb, 0x62, 0x96, 0xb0, 0x10, 0xcc, 0x90, 0x69, 0x84, 0x5f, + 0xa7, 0x16, 0x5e, 0xe9, 0x47, 0x8f, 0xef, 0xb4, 0xb8, 0x54, 0xe4, 0x2d, 0xba, 0x76, 0xea, 0x55, + 0xc6, 0x22, 0x92, 0x1c, 0xbb, 0x28, 0x6f, 0x9a, 0x6f, 0x58, 0xb7, 0xad, 0xf2, 0xc5, 0xc5, 0x59, + 0x27, 0x6b, 0x38, 0x8e, 0xe9, 0x76, 0x27, 0xf6, 0x3b, 0xa5, 0x9c, 0x07, 0x9d, 0xe4, 0x25, 0x22, + 0x9a, 0xfa, 0x19, 0x8f, 0x44, 0x58, 0xfd, 0x33, 0x00, 0x18, 0xc0, 0x73, 0x68, 0x72, 0x23, 0x05, + 0x68, 0xa1, 0x29, 0xf7, 0x6a, 0xbf, 0x53, 0xba, 0xd4, 0x66, 0xe1, 0xf6, 0x23, 0xa2, 0x9f, 0x89, + 0x67, 0xca, 0xe4, 0x9b, 0x85, 0xee, 0x66, 0xd2, 0x81, 0xf3, 0x4f, 0x16, 0xc2, 0xc7, 0xd3, 0xaa, + 0x87, 0x50, 0x86, 0x18, 0x4b, 0xd9, 0x31, 0x46, 0x53, 0xbb, 0x77, 0xd2, 0x58, 0xfd, 0x4e, 0xe9, + 0xa6, 0xf1, 0x35, 0xcc, 0x4e, 0xbc, 0xc2, 0xd0, 0x82, 0xc8, 0x1a, 0xba, 0xf5, 0xdb, 0xaf, 0x5c, + 0x4d, 0x44, 0x58, 0x4b, 0x38, 0x53, 0x22, 0x19, 0x24, 0x5f, 0x40, 0x17, 0x9a, 0xe6, 0x05, 0xb2, + 0xe3, 0x7e, 0xa7, 0x74, 0xc5, 0x68, 0x40, 0x81, 0x78, 0x03, 0x08, 0x79, 0x81, 0xec, 0xbf, 0xd1, + 0x41, 0xf2, 0x79, 0x94, 0xd7, 0xa3, 0x4a, 0x77, 0x76, 0xbe, 0x3c, 0xe5, 0x16, 0xfa, 0x9d, 0xd2, + 0xe5, 0x13, 0xa3, 0x94, 0xc4, 0x03, 0xc0, 0xe2, 0xd1, 0x04, 0x9a, 0xd4, 0x6c, 0xf8, 0xab, 0x85, + 0xf2, 0x66, 0x7b, 0xf8, 0x41, 0xf6, 0x70, 0x86, 0x8f, 0xa7, 0x58, 0xf9, 0x87, 0x0e, 0x63, 0x92, + 0x2c, 0x7c, 0x3c, 0x3c, 0xfa, 0x72, 0x6e, 0x0e, 0xcf, 0xd2, 0x31, 0x2e, 0x17, 0xff, 0xb4, 0xd0, + 0xf5, 0xd1, 0x4b, 0xc1, 0x2b, 0x63, 0x68, 0x67, 0x5e, 0x5e, 0xb1, 0x7a, 0x06, 0x06, 0x48, 0xf3, + 0x5c, 0xa7, 0xa9, 0xe2, 0xa7, 0xd9, 0x69, 0xcc, 0xd4, 0xe9, 0xae, 0xfe, 0xdd, 0xa3, 0xc3, 0x07, + 0x84, 0x0f, 0x2d, 0x54, 0x18, 0xda, 0x2c, 0x5e, 0x1e, 0xd7, 0xe1, 0x88, 0xf3, 0x2a, 0x3e, 0xfe, + 0xbf, 0x66, 0x48, 0x56, 0xd3, 0xc9, 0x9e, 0xe0, 0xe5, 0x71, 0x92, 0xd5, 0x37, 0x13, 0x11, 0xd6, + 0xe1, 0x52, 0xe9, 0x2e, 0x7c, 0xec, 0xb9, 0xeb, 0xfb, 0x5d, 0xdb, 0x3a, 0xe8, 0xda, 0xd6, 0x8f, + 0xae, 0x6d, 0x7d, 0xee, 0xd9, 0xb9, 0x83, 0x9e, 0x9d, 0xfb, 0xde, 0xb3, 0x73, 0xeb, 0x2b, 0x7e, + 0xa0, 0xb6, 0x5a, 0x0d, 0xa7, 0x29, 0x42, 0x5a, 0xd3, 0x0a, 0x6f, 0x52, 0xfa, 0x55, 0xa0, 0xd7, + 0x5a, 0xf7, 0x07, 0x62, 0x1f, 0x4e, 0x6b, 0xab, 0x76, 0xcc, 0x65, 0x23, 0xaf, 0xff, 0xd5, 0x1e, + 0xfe, 0x0a, 0x00, 0x00, 0xff, 0xff, 0x27, 0x80, 0x49, 0x9f, 0xe0, 0x05, 0x00, 0x00, +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ 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. +const _ = grpc.SupportPackageIsVersion4 + +// QueryClient is the client API for Query service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type QueryClient interface { + // Params defines a gRPC query method that returns the tokenfactory module's + // parameters. + Params(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) + // DenomAuthorityMetadata defines a gRPC query method for fetching + // DenomAuthorityMetadata for a particular denom. + DenomAuthorityMetadata(ctx context.Context, in *QueryDenomAuthorityMetadataRequest, opts ...grpc.CallOption) (*QueryDenomAuthorityMetadataResponse, error) + // DenomsFromCreator defines a gRPC query method for fetching all + // denominations created by a specific admin/creator. + DenomsFromCreator(ctx context.Context, in *QueryDenomsFromCreatorRequest, opts ...grpc.CallOption) (*QueryDenomsFromCreatorResponse, error) +} + +type queryClient struct { + cc grpc1.ClientConn +} + +func NewQueryClient(cc grpc1.ClientConn) QueryClient { + return &queryClient{cc} +} + +func (c *queryClient) Params(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) { + out := new(QueryParamsResponse) + err := c.cc.Invoke(ctx, "/osmosis.tokenfactory.v1beta1.Query/Params", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) DenomAuthorityMetadata(ctx context.Context, in *QueryDenomAuthorityMetadataRequest, opts ...grpc.CallOption) (*QueryDenomAuthorityMetadataResponse, error) { + out := new(QueryDenomAuthorityMetadataResponse) + err := c.cc.Invoke(ctx, "/osmosis.tokenfactory.v1beta1.Query/DenomAuthorityMetadata", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) DenomsFromCreator(ctx context.Context, in *QueryDenomsFromCreatorRequest, opts ...grpc.CallOption) (*QueryDenomsFromCreatorResponse, error) { + out := new(QueryDenomsFromCreatorResponse) + err := c.cc.Invoke(ctx, "/osmosis.tokenfactory.v1beta1.Query/DenomsFromCreator", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// QueryServer is the server API for Query service. +type QueryServer interface { + // Params defines a gRPC query method that returns the tokenfactory module's + // parameters. + Params(context.Context, *QueryParamsRequest) (*QueryParamsResponse, error) + // DenomAuthorityMetadata defines a gRPC query method for fetching + // DenomAuthorityMetadata for a particular denom. + DenomAuthorityMetadata(context.Context, *QueryDenomAuthorityMetadataRequest) (*QueryDenomAuthorityMetadataResponse, error) + // DenomsFromCreator defines a gRPC query method for fetching all + // denominations created by a specific admin/creator. + DenomsFromCreator(context.Context, *QueryDenomsFromCreatorRequest) (*QueryDenomsFromCreatorResponse, error) +} + +// UnimplementedQueryServer can be embedded to have forward compatible implementations. +type UnimplementedQueryServer struct { +} + +func (*UnimplementedQueryServer) Params(ctx context.Context, req *QueryParamsRequest) (*QueryParamsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Params not implemented") +} +func (*UnimplementedQueryServer) DenomAuthorityMetadata(ctx context.Context, req *QueryDenomAuthorityMetadataRequest) (*QueryDenomAuthorityMetadataResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method DenomAuthorityMetadata not implemented") +} +func (*UnimplementedQueryServer) DenomsFromCreator(ctx context.Context, req *QueryDenomsFromCreatorRequest) (*QueryDenomsFromCreatorResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method DenomsFromCreator not implemented") +} + +func RegisterQueryServer(s grpc1.Server, srv QueryServer) { + s.RegisterService(&_Query_serviceDesc, srv) +} + +func _Query_Params_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryParamsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).Params(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/osmosis.tokenfactory.v1beta1.Query/Params", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).Params(ctx, req.(*QueryParamsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_DenomAuthorityMetadata_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryDenomAuthorityMetadataRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).DenomAuthorityMetadata(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/osmosis.tokenfactory.v1beta1.Query/DenomAuthorityMetadata", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).DenomAuthorityMetadata(ctx, req.(*QueryDenomAuthorityMetadataRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_DenomsFromCreator_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryDenomsFromCreatorRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).DenomsFromCreator(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/osmosis.tokenfactory.v1beta1.Query/DenomsFromCreator", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).DenomsFromCreator(ctx, req.(*QueryDenomsFromCreatorRequest)) + } + return interceptor(ctx, in, info, handler) +} + +var _Query_serviceDesc = grpc.ServiceDesc{ + ServiceName: "osmosis.tokenfactory.v1beta1.Query", + HandlerType: (*QueryServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Params", + Handler: _Query_Params_Handler, + }, + { + MethodName: "DenomAuthorityMetadata", + Handler: _Query_DenomAuthorityMetadata_Handler, + }, + { + MethodName: "DenomsFromCreator", + Handler: _Query_DenomsFromCreator_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "osmosis/tokenfactory/v1beta1/query.proto", +} + +func (m *QueryParamsRequest) 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 *QueryParamsRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryParamsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *QueryParamsResponse) 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 *QueryParamsResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryParamsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Params.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *QueryDenomAuthorityMetadataRequest) 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 *QueryDenomAuthorityMetadataRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryDenomAuthorityMetadataRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Denom) > 0 { + i -= len(m.Denom) + copy(dAtA[i:], m.Denom) + i = encodeVarintQuery(dAtA, i, uint64(len(m.Denom))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryDenomAuthorityMetadataResponse) 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 *QueryDenomAuthorityMetadataResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryDenomAuthorityMetadataResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.AuthorityMetadata.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *QueryDenomsFromCreatorRequest) 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 *QueryDenomsFromCreatorRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryDenomsFromCreatorRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Creator) > 0 { + i -= len(m.Creator) + copy(dAtA[i:], m.Creator) + i = encodeVarintQuery(dAtA, i, uint64(len(m.Creator))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryDenomsFromCreatorResponse) 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 *QueryDenomsFromCreatorResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryDenomsFromCreatorResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Denoms) > 0 { + for iNdEx := len(m.Denoms) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Denoms[iNdEx]) + copy(dAtA[i:], m.Denoms[iNdEx]) + i = encodeVarintQuery(dAtA, i, uint64(len(m.Denoms[iNdEx]))) + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func encodeVarintQuery(dAtA []byte, offset int, v uint64) int { + offset -= sovQuery(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *QueryParamsRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *QueryParamsResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Params.Size() + n += 1 + l + sovQuery(uint64(l)) + return n +} + +func (m *QueryDenomAuthorityMetadataRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Denom) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryDenomAuthorityMetadataResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.AuthorityMetadata.Size() + n += 1 + l + sovQuery(uint64(l)) + return n +} + +func (m *QueryDenomsFromCreatorRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Creator) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryDenomsFromCreatorResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Denoms) > 0 { + for _, s := range m.Denoms { + l = len(s) + n += 1 + l + sovQuery(uint64(l)) + } + } + return n +} + +func sovQuery(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozQuery(x uint64) (n int) { + return sovQuery(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *QueryParamsRequest) 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: QueryParamsRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryParamsRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + 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 *QueryParamsResponse) 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: QueryParamsResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryParamsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Params", 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 err := m.Params.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 *QueryDenomAuthorityMetadataRequest) 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: QueryDenomAuthorityMetadataRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryDenomAuthorityMetadataRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Denom", 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.Denom = string(dAtA[iNdEx:postIndex]) + 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 *QueryDenomAuthorityMetadataResponse) 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: QueryDenomAuthorityMetadataResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryDenomAuthorityMetadataResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AuthorityMetadata", 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 err := m.AuthorityMetadata.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 *QueryDenomsFromCreatorRequest) 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: QueryDenomsFromCreatorRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryDenomsFromCreatorRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Creator", 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.Creator = string(dAtA[iNdEx:postIndex]) + 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 *QueryDenomsFromCreatorResponse) 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: QueryDenomsFromCreatorResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryDenomsFromCreatorResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Denoms", 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.Denoms = append(m.Denoms, string(dAtA[iNdEx:postIndex])) + 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 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowQuery + } + 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, ErrIntOverflowQuery + } + 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, ErrIntOverflowQuery + } + 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, ErrInvalidLengthQuery + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupQuery + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthQuery + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthQuery = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowQuery = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupQuery = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/tokenfactory/types/query.pb.gw.go b/x/tokenfactory/types/query.pb.gw.go new file mode 100644 index 000000000..0b895e706 --- /dev/null +++ b/x/tokenfactory/types/query.pb.gw.go @@ -0,0 +1,355 @@ +// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. +// source: osmosis/tokenfactory/v1beta1/query.proto + +/* +Package types is a reverse proxy. + +It translates gRPC into RESTful JSON APIs. +*/ +package types + +import ( + "context" + "io" + "net/http" + + "github.com/golang/protobuf/descriptor" + "github.com/golang/protobuf/proto" + "github.com/grpc-ecosystem/grpc-gateway/runtime" + "github.com/grpc-ecosystem/grpc-gateway/utilities" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/metadata" + "google.golang.org/grpc/status" +) + +// Suppress "imported and not used" errors +var _ codes.Code +var _ io.Reader +var _ status.Status +var _ = runtime.String +var _ = utilities.NewDoubleArray +var _ = descriptor.ForMessage +var _ = metadata.Join + +func request_Query_Params_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryParamsRequest + var metadata runtime.ServerMetadata + + msg, err := client.Params(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_Params_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryParamsRequest + var metadata runtime.ServerMetadata + + msg, err := server.Params(ctx, &protoReq) + return msg, metadata, err + +} + +func request_Query_DenomAuthorityMetadata_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryDenomAuthorityMetadataRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["denom"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "denom") + } + + protoReq.Denom, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "denom", err) + } + + msg, err := client.DenomAuthorityMetadata(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_DenomAuthorityMetadata_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryDenomAuthorityMetadataRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["denom"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "denom") + } + + protoReq.Denom, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "denom", err) + } + + msg, err := server.DenomAuthorityMetadata(ctx, &protoReq) + return msg, metadata, err + +} + +func request_Query_DenomsFromCreator_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryDenomsFromCreatorRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["creator"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "creator") + } + + protoReq.Creator, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "creator", err) + } + + msg, err := client.DenomsFromCreator(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_DenomsFromCreator_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryDenomsFromCreatorRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["creator"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "creator") + } + + protoReq.Creator, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "creator", err) + } + + msg, err := server.DenomsFromCreator(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. +// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterQueryHandlerFromEndpoint instead. +func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, server QueryServer) error { + + mux.Handle("GET", pattern_Query_Params_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 { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_Params_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) + return + } + + forward_Query_Params_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_DenomAuthorityMetadata_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 { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_DenomAuthorityMetadata_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) + return + } + + forward_Query_DenomAuthorityMetadata_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_DenomsFromCreator_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 { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_DenomsFromCreator_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) + return + } + + forward_Query_DenomsFromCreator_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +// RegisterQueryHandlerFromEndpoint is same as RegisterQueryHandler but +// automatically dials to "endpoint" and closes the connection when "ctx" gets done. +func RegisterQueryHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { + conn, err := grpc.Dial(endpoint, opts...) + if err != nil { + return err + } + defer func() { + if err != nil { + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + return + } + go func() { + <-ctx.Done() + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + }() + }() + + return RegisterQueryHandler(ctx, mux, conn) +} + +// RegisterQueryHandler registers the http handlers for service Query to "mux". +// The handlers forward requests to the grpc endpoint over "conn". +func RegisterQueryHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { + return RegisterQueryHandlerClient(ctx, mux, NewQueryClient(conn)) +} + +// RegisterQueryHandlerClient registers the http handlers for service Query +// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "QueryClient". +// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "QueryClient" +// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in +// "QueryClient" to call the correct interceptors. +func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, client QueryClient) error { + + mux.Handle("GET", pattern_Query_Params_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_Params_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_Params_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_DenomAuthorityMetadata_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_DenomAuthorityMetadata_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_DenomAuthorityMetadata_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_DenomsFromCreator_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_DenomsFromCreator_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_DenomsFromCreator_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +var ( + pattern_Query_Params_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"osmosis", "tokenfactory", "v1beta1", "params"}, "", runtime.AssumeColonVerbOpt(false))) + + pattern_Query_DenomAuthorityMetadata_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4, 2, 5}, []string{"osmosis", "tokenfactory", "v1beta1", "denoms", "denom", "authority_metadata"}, "", runtime.AssumeColonVerbOpt(false))) + + pattern_Query_DenomsFromCreator_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"osmosis", "tokenfactory", "v1beta1", "denoms_from_creator", "creator"}, "", runtime.AssumeColonVerbOpt(false))) +) + +var ( + forward_Query_Params_0 = runtime.ForwardResponseMessage + + forward_Query_DenomAuthorityMetadata_0 = runtime.ForwardResponseMessage + + forward_Query_DenomsFromCreator_0 = runtime.ForwardResponseMessage +) diff --git a/x/tokenfactory/types/tx.pb.go b/x/tokenfactory/types/tx.pb.go new file mode 100644 index 000000000..6b44d792a --- /dev/null +++ b/x/tokenfactory/types/tx.pb.go @@ -0,0 +1,2829 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: osmosis/tokenfactory/v1beta1/tx.proto + +package types + +import ( + context "context" + fmt "fmt" + types "github.com/cosmos/cosmos-sdk/types" + types1 "github.com/cosmos/cosmos-sdk/x/bank/types" + _ "github.com/cosmos/gogoproto/gogoproto" + grpc1 "github.com/gogo/protobuf/grpc" + proto "github.com/gogo/protobuf/proto" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = 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 + +// MsgCreateDenom defines the message structure for the CreateDenom gRPC service +// method. It allows an account to create a new denom. It requires a sender +// address and a sub denomination. The (sender_address, sub_denomination) tuple +// must be unique and cannot be re-used. +// +// The resulting denom created is defined as +// . The resulting denom's admin is +// originally set to be the creator, but this can be changed later. The token +// denom does not indicate the current admin. +type MsgCreateDenom struct { + Sender string `protobuf:"bytes,1,opt,name=sender,proto3" json:"sender,omitempty" yaml:"sender"` + // subdenom can be up to 44 "alphanumeric" characters long. + Subdenom string `protobuf:"bytes,2,opt,name=subdenom,proto3" json:"subdenom,omitempty" yaml:"subdenom"` +} + +func (m *MsgCreateDenom) Reset() { *m = MsgCreateDenom{} } +func (m *MsgCreateDenom) String() string { return proto.CompactTextString(m) } +func (*MsgCreateDenom) ProtoMessage() {} +func (*MsgCreateDenom) Descriptor() ([]byte, []int) { + return fileDescriptor_283b6c9a90a846b4, []int{0} +} +func (m *MsgCreateDenom) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgCreateDenom) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgCreateDenom.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 *MsgCreateDenom) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgCreateDenom.Merge(m, src) +} +func (m *MsgCreateDenom) XXX_Size() int { + return m.Size() +} +func (m *MsgCreateDenom) XXX_DiscardUnknown() { + xxx_messageInfo_MsgCreateDenom.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgCreateDenom proto.InternalMessageInfo + +func (m *MsgCreateDenom) GetSender() string { + if m != nil { + return m.Sender + } + return "" +} + +func (m *MsgCreateDenom) GetSubdenom() string { + if m != nil { + return m.Subdenom + } + return "" +} + +// MsgCreateDenomResponse is the return value of MsgCreateDenom +// It returns the full string of the newly created denom +type MsgCreateDenomResponse struct { + NewTokenDenom string `protobuf:"bytes,1,opt,name=new_token_denom,json=newTokenDenom,proto3" json:"new_token_denom,omitempty" yaml:"new_token_denom"` +} + +func (m *MsgCreateDenomResponse) Reset() { *m = MsgCreateDenomResponse{} } +func (m *MsgCreateDenomResponse) String() string { return proto.CompactTextString(m) } +func (*MsgCreateDenomResponse) ProtoMessage() {} +func (*MsgCreateDenomResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_283b6c9a90a846b4, []int{1} +} +func (m *MsgCreateDenomResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgCreateDenomResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgCreateDenomResponse.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 *MsgCreateDenomResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgCreateDenomResponse.Merge(m, src) +} +func (m *MsgCreateDenomResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgCreateDenomResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgCreateDenomResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgCreateDenomResponse proto.InternalMessageInfo + +func (m *MsgCreateDenomResponse) GetNewTokenDenom() string { + if m != nil { + return m.NewTokenDenom + } + return "" +} + +// MsgMint is the sdk.Msg type for allowing an admin account to mint +// more of a token. For now, we only support minting to the sender account +type MsgMint struct { + Sender string `protobuf:"bytes,1,opt,name=sender,proto3" json:"sender,omitempty" yaml:"sender"` + Amount types.Coin `protobuf:"bytes,2,opt,name=amount,proto3" json:"amount" yaml:"amount"` + MintToAddress string `protobuf:"bytes,3,opt,name=mintToAddress,proto3" json:"mintToAddress,omitempty" yaml:"mint_to_address"` +} + +func (m *MsgMint) Reset() { *m = MsgMint{} } +func (m *MsgMint) String() string { return proto.CompactTextString(m) } +func (*MsgMint) ProtoMessage() {} +func (*MsgMint) Descriptor() ([]byte, []int) { + return fileDescriptor_283b6c9a90a846b4, []int{2} +} +func (m *MsgMint) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgMint) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgMint.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 *MsgMint) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgMint.Merge(m, src) +} +func (m *MsgMint) XXX_Size() int { + return m.Size() +} +func (m *MsgMint) XXX_DiscardUnknown() { + xxx_messageInfo_MsgMint.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgMint proto.InternalMessageInfo + +func (m *MsgMint) GetSender() string { + if m != nil { + return m.Sender + } + return "" +} + +func (m *MsgMint) GetAmount() types.Coin { + if m != nil { + return m.Amount + } + return types.Coin{} +} + +func (m *MsgMint) GetMintToAddress() string { + if m != nil { + return m.MintToAddress + } + return "" +} + +type MsgMintResponse struct { +} + +func (m *MsgMintResponse) Reset() { *m = MsgMintResponse{} } +func (m *MsgMintResponse) String() string { return proto.CompactTextString(m) } +func (*MsgMintResponse) ProtoMessage() {} +func (*MsgMintResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_283b6c9a90a846b4, []int{3} +} +func (m *MsgMintResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgMintResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgMintResponse.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 *MsgMintResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgMintResponse.Merge(m, src) +} +func (m *MsgMintResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgMintResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgMintResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgMintResponse proto.InternalMessageInfo + +// MsgBurn is the sdk.Msg type for allowing an admin account to burn +// a token. For now, we only support burning from the sender account. +type MsgBurn struct { + Sender string `protobuf:"bytes,1,opt,name=sender,proto3" json:"sender,omitempty" yaml:"sender"` + Amount types.Coin `protobuf:"bytes,2,opt,name=amount,proto3" json:"amount" yaml:"amount"` + BurnFromAddress string `protobuf:"bytes,3,opt,name=burnFromAddress,proto3" json:"burnFromAddress,omitempty" yaml:"burn_from_address"` +} + +func (m *MsgBurn) Reset() { *m = MsgBurn{} } +func (m *MsgBurn) String() string { return proto.CompactTextString(m) } +func (*MsgBurn) ProtoMessage() {} +func (*MsgBurn) Descriptor() ([]byte, []int) { + return fileDescriptor_283b6c9a90a846b4, []int{4} +} +func (m *MsgBurn) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgBurn) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgBurn.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 *MsgBurn) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgBurn.Merge(m, src) +} +func (m *MsgBurn) XXX_Size() int { + return m.Size() +} +func (m *MsgBurn) XXX_DiscardUnknown() { + xxx_messageInfo_MsgBurn.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgBurn proto.InternalMessageInfo + +func (m *MsgBurn) GetSender() string { + if m != nil { + return m.Sender + } + return "" +} + +func (m *MsgBurn) GetAmount() types.Coin { + if m != nil { + return m.Amount + } + return types.Coin{} +} + +func (m *MsgBurn) GetBurnFromAddress() string { + if m != nil { + return m.BurnFromAddress + } + return "" +} + +type MsgBurnResponse struct { +} + +func (m *MsgBurnResponse) Reset() { *m = MsgBurnResponse{} } +func (m *MsgBurnResponse) String() string { return proto.CompactTextString(m) } +func (*MsgBurnResponse) ProtoMessage() {} +func (*MsgBurnResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_283b6c9a90a846b4, []int{5} +} +func (m *MsgBurnResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgBurnResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgBurnResponse.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 *MsgBurnResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgBurnResponse.Merge(m, src) +} +func (m *MsgBurnResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgBurnResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgBurnResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgBurnResponse proto.InternalMessageInfo + +// MsgChangeAdmin is the sdk.Msg type for allowing an admin account to reassign +// adminship of a denom to a new account +type MsgChangeAdmin struct { + Sender string `protobuf:"bytes,1,opt,name=sender,proto3" json:"sender,omitempty" yaml:"sender"` + Denom string `protobuf:"bytes,2,opt,name=denom,proto3" json:"denom,omitempty" yaml:"denom"` + NewAdmin string `protobuf:"bytes,3,opt,name=new_admin,json=newAdmin,proto3" json:"new_admin,omitempty" yaml:"new_admin"` +} + +func (m *MsgChangeAdmin) Reset() { *m = MsgChangeAdmin{} } +func (m *MsgChangeAdmin) String() string { return proto.CompactTextString(m) } +func (*MsgChangeAdmin) ProtoMessage() {} +func (*MsgChangeAdmin) Descriptor() ([]byte, []int) { + return fileDescriptor_283b6c9a90a846b4, []int{6} +} +func (m *MsgChangeAdmin) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgChangeAdmin) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgChangeAdmin.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 *MsgChangeAdmin) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgChangeAdmin.Merge(m, src) +} +func (m *MsgChangeAdmin) XXX_Size() int { + return m.Size() +} +func (m *MsgChangeAdmin) XXX_DiscardUnknown() { + xxx_messageInfo_MsgChangeAdmin.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgChangeAdmin proto.InternalMessageInfo + +func (m *MsgChangeAdmin) GetSender() string { + if m != nil { + return m.Sender + } + return "" +} + +func (m *MsgChangeAdmin) GetDenom() string { + if m != nil { + return m.Denom + } + return "" +} + +func (m *MsgChangeAdmin) GetNewAdmin() string { + if m != nil { + return m.NewAdmin + } + return "" +} + +// MsgChangeAdminResponse defines the response structure for an executed +// MsgChangeAdmin message. +type MsgChangeAdminResponse struct { +} + +func (m *MsgChangeAdminResponse) Reset() { *m = MsgChangeAdminResponse{} } +func (m *MsgChangeAdminResponse) String() string { return proto.CompactTextString(m) } +func (*MsgChangeAdminResponse) ProtoMessage() {} +func (*MsgChangeAdminResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_283b6c9a90a846b4, []int{7} +} +func (m *MsgChangeAdminResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgChangeAdminResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgChangeAdminResponse.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 *MsgChangeAdminResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgChangeAdminResponse.Merge(m, src) +} +func (m *MsgChangeAdminResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgChangeAdminResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgChangeAdminResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgChangeAdminResponse proto.InternalMessageInfo + +// MsgSetDenomMetadata is the sdk.Msg type for allowing an admin account to set +// the denom's bank metadata +type MsgSetDenomMetadata struct { + Sender string `protobuf:"bytes,1,opt,name=sender,proto3" json:"sender,omitempty" yaml:"sender"` + Metadata types1.Metadata `protobuf:"bytes,2,opt,name=metadata,proto3" json:"metadata" yaml:"metadata"` +} + +func (m *MsgSetDenomMetadata) Reset() { *m = MsgSetDenomMetadata{} } +func (m *MsgSetDenomMetadata) String() string { return proto.CompactTextString(m) } +func (*MsgSetDenomMetadata) ProtoMessage() {} +func (*MsgSetDenomMetadata) Descriptor() ([]byte, []int) { + return fileDescriptor_283b6c9a90a846b4, []int{8} +} +func (m *MsgSetDenomMetadata) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgSetDenomMetadata) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgSetDenomMetadata.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 *MsgSetDenomMetadata) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgSetDenomMetadata.Merge(m, src) +} +func (m *MsgSetDenomMetadata) XXX_Size() int { + return m.Size() +} +func (m *MsgSetDenomMetadata) XXX_DiscardUnknown() { + xxx_messageInfo_MsgSetDenomMetadata.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgSetDenomMetadata proto.InternalMessageInfo + +func (m *MsgSetDenomMetadata) GetSender() string { + if m != nil { + return m.Sender + } + return "" +} + +func (m *MsgSetDenomMetadata) GetMetadata() types1.Metadata { + if m != nil { + return m.Metadata + } + return types1.Metadata{} +} + +// MsgSetDenomMetadataResponse defines the response structure for an executed +// MsgSetDenomMetadata message. +type MsgSetDenomMetadataResponse struct { +} + +func (m *MsgSetDenomMetadataResponse) Reset() { *m = MsgSetDenomMetadataResponse{} } +func (m *MsgSetDenomMetadataResponse) String() string { return proto.CompactTextString(m) } +func (*MsgSetDenomMetadataResponse) ProtoMessage() {} +func (*MsgSetDenomMetadataResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_283b6c9a90a846b4, []int{9} +} +func (m *MsgSetDenomMetadataResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgSetDenomMetadataResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgSetDenomMetadataResponse.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 *MsgSetDenomMetadataResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgSetDenomMetadataResponse.Merge(m, src) +} +func (m *MsgSetDenomMetadataResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgSetDenomMetadataResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgSetDenomMetadataResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgSetDenomMetadataResponse proto.InternalMessageInfo + +type MsgForceTransfer struct { + Sender string `protobuf:"bytes,1,opt,name=sender,proto3" json:"sender,omitempty" yaml:"sender"` + Amount types.Coin `protobuf:"bytes,2,opt,name=amount,proto3" json:"amount" yaml:"amount"` + TransferFromAddress string `protobuf:"bytes,3,opt,name=transferFromAddress,proto3" json:"transferFromAddress,omitempty" yaml:"transfer_from_address"` + TransferToAddress string `protobuf:"bytes,4,opt,name=transferToAddress,proto3" json:"transferToAddress,omitempty" yaml:"transfer_to_address"` +} + +func (m *MsgForceTransfer) Reset() { *m = MsgForceTransfer{} } +func (m *MsgForceTransfer) String() string { return proto.CompactTextString(m) } +func (*MsgForceTransfer) ProtoMessage() {} +func (*MsgForceTransfer) Descriptor() ([]byte, []int) { + return fileDescriptor_283b6c9a90a846b4, []int{10} +} +func (m *MsgForceTransfer) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgForceTransfer) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgForceTransfer.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 *MsgForceTransfer) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgForceTransfer.Merge(m, src) +} +func (m *MsgForceTransfer) XXX_Size() int { + return m.Size() +} +func (m *MsgForceTransfer) XXX_DiscardUnknown() { + xxx_messageInfo_MsgForceTransfer.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgForceTransfer proto.InternalMessageInfo + +func (m *MsgForceTransfer) GetSender() string { + if m != nil { + return m.Sender + } + return "" +} + +func (m *MsgForceTransfer) GetAmount() types.Coin { + if m != nil { + return m.Amount + } + return types.Coin{} +} + +func (m *MsgForceTransfer) GetTransferFromAddress() string { + if m != nil { + return m.TransferFromAddress + } + return "" +} + +func (m *MsgForceTransfer) GetTransferToAddress() string { + if m != nil { + return m.TransferToAddress + } + return "" +} + +type MsgForceTransferResponse struct { +} + +func (m *MsgForceTransferResponse) Reset() { *m = MsgForceTransferResponse{} } +func (m *MsgForceTransferResponse) String() string { return proto.CompactTextString(m) } +func (*MsgForceTransferResponse) ProtoMessage() {} +func (*MsgForceTransferResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_283b6c9a90a846b4, []int{11} +} +func (m *MsgForceTransferResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgForceTransferResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgForceTransferResponse.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 *MsgForceTransferResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgForceTransferResponse.Merge(m, src) +} +func (m *MsgForceTransferResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgForceTransferResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgForceTransferResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgForceTransferResponse proto.InternalMessageInfo + +func init() { + proto.RegisterType((*MsgCreateDenom)(nil), "osmosis.tokenfactory.v1beta1.MsgCreateDenom") + proto.RegisterType((*MsgCreateDenomResponse)(nil), "osmosis.tokenfactory.v1beta1.MsgCreateDenomResponse") + proto.RegisterType((*MsgMint)(nil), "osmosis.tokenfactory.v1beta1.MsgMint") + proto.RegisterType((*MsgMintResponse)(nil), "osmosis.tokenfactory.v1beta1.MsgMintResponse") + proto.RegisterType((*MsgBurn)(nil), "osmosis.tokenfactory.v1beta1.MsgBurn") + proto.RegisterType((*MsgBurnResponse)(nil), "osmosis.tokenfactory.v1beta1.MsgBurnResponse") + proto.RegisterType((*MsgChangeAdmin)(nil), "osmosis.tokenfactory.v1beta1.MsgChangeAdmin") + proto.RegisterType((*MsgChangeAdminResponse)(nil), "osmosis.tokenfactory.v1beta1.MsgChangeAdminResponse") + proto.RegisterType((*MsgSetDenomMetadata)(nil), "osmosis.tokenfactory.v1beta1.MsgSetDenomMetadata") + proto.RegisterType((*MsgSetDenomMetadataResponse)(nil), "osmosis.tokenfactory.v1beta1.MsgSetDenomMetadataResponse") + proto.RegisterType((*MsgForceTransfer)(nil), "osmosis.tokenfactory.v1beta1.MsgForceTransfer") + proto.RegisterType((*MsgForceTransferResponse)(nil), "osmosis.tokenfactory.v1beta1.MsgForceTransferResponse") +} + +func init() { + proto.RegisterFile("osmosis/tokenfactory/v1beta1/tx.proto", fileDescriptor_283b6c9a90a846b4) +} + +var fileDescriptor_283b6c9a90a846b4 = []byte{ + // 742 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x56, 0x4f, 0x4f, 0x13, 0x41, + 0x14, 0xef, 0xf2, 0x4f, 0x18, 0xac, 0x2d, 0x0b, 0x62, 0x5d, 0x61, 0x97, 0x4c, 0x82, 0xd1, 0x44, + 0xb6, 0x29, 0x1a, 0x13, 0x3d, 0x41, 0x31, 0x8d, 0x07, 0x7b, 0x59, 0x39, 0x11, 0x92, 0x66, 0xdb, + 0x0e, 0x4b, 0x03, 0x3b, 0x83, 0x3b, 0x53, 0x0b, 0x37, 0x3f, 0x82, 0x07, 0xe3, 0x17, 0xf0, 0xe4, + 0xb7, 0xf0, 0x64, 0x38, 0x72, 0xf4, 0xb4, 0x31, 0xf0, 0x0d, 0xf6, 0x13, 0x98, 0x9d, 0x99, 0xfd, + 0x5b, 0x62, 0xdb, 0x13, 0x37, 0xd8, 0xf7, 0xfb, 0xfd, 0xe6, 0xfd, 0xde, 0xbc, 0xf7, 0x3a, 0x60, + 0x93, 0x50, 0x97, 0xd0, 0x1e, 0xad, 0x32, 0x72, 0x82, 0xf0, 0x91, 0xdd, 0x61, 0xc4, 0xbb, 0xa8, + 0x7e, 0xae, 0xb5, 0x11, 0xb3, 0x6b, 0x55, 0x76, 0x6e, 0x9e, 0x79, 0x84, 0x11, 0x75, 0x4d, 0xc2, + 0xcc, 0x34, 0xcc, 0x94, 0x30, 0x6d, 0xc5, 0x21, 0x0e, 0xe1, 0xc0, 0x6a, 0xf8, 0x97, 0xe0, 0x68, + 0x7a, 0x87, 0x93, 0xaa, 0x6d, 0x9b, 0xa2, 0x58, 0xb1, 0x43, 0x7a, 0x78, 0x28, 0x8e, 0x4f, 0xe2, + 0x78, 0xf8, 0x8f, 0x88, 0xc3, 0x53, 0xf0, 0xa0, 0x49, 0x9d, 0x3d, 0x0f, 0xd9, 0x0c, 0xbd, 0x43, + 0x98, 0xb8, 0xea, 0x73, 0x30, 0x47, 0x11, 0xee, 0x22, 0xaf, 0xa2, 0x6c, 0x28, 0xcf, 0x16, 0xea, + 0x4b, 0x81, 0x6f, 0x14, 0x2f, 0x6c, 0xf7, 0xf4, 0x2d, 0x14, 0xdf, 0xa1, 0x25, 0x01, 0x6a, 0x15, + 0xcc, 0xd3, 0x7e, 0xbb, 0x1b, 0xd2, 0x2a, 0x53, 0x1c, 0xbc, 0x1c, 0xf8, 0x46, 0x49, 0x82, 0x65, + 0x04, 0x5a, 0x31, 0x08, 0x1e, 0x82, 0xd5, 0xec, 0x69, 0x16, 0xa2, 0x67, 0x04, 0x53, 0xa4, 0xd6, + 0x41, 0x09, 0xa3, 0x41, 0x8b, 0x3b, 0x6f, 0x09, 0x45, 0x71, 0xbc, 0x16, 0xf8, 0xc6, 0xaa, 0x50, + 0xcc, 0x01, 0xa0, 0x55, 0xc4, 0x68, 0xb0, 0x1f, 0x7e, 0xe0, 0x5a, 0xf0, 0x97, 0x02, 0xee, 0x35, + 0xa9, 0xd3, 0xec, 0x61, 0x36, 0x89, 0x8b, 0xf7, 0x60, 0xce, 0x76, 0x49, 0x1f, 0x33, 0xee, 0x61, + 0x71, 0xfb, 0xb1, 0x29, 0x6a, 0x66, 0x86, 0x35, 0x8d, 0xca, 0x6f, 0xee, 0x91, 0x1e, 0xae, 0x3f, + 0xbc, 0xf4, 0x8d, 0x42, 0xa2, 0x24, 0x68, 0xd0, 0x92, 0x7c, 0x75, 0x07, 0x14, 0xdd, 0x1e, 0x66, + 0xfb, 0x64, 0xb7, 0xdb, 0xf5, 0x10, 0xa5, 0x95, 0xe9, 0xbc, 0x85, 0x30, 0xdc, 0x62, 0xa4, 0x65, + 0x0b, 0x00, 0xb4, 0xb2, 0x04, 0xb8, 0x04, 0x4a, 0xd2, 0x41, 0x54, 0x19, 0xf8, 0x5b, 0xb8, 0xaa, + 0xf7, 0x3d, 0x7c, 0x37, 0xae, 0x1a, 0xa0, 0xd4, 0xee, 0x7b, 0xb8, 0xe1, 0x11, 0x37, 0xeb, 0x6b, + 0x2d, 0xf0, 0x8d, 0x8a, 0xe0, 0x84, 0x80, 0xd6, 0x91, 0x47, 0xdc, 0xc4, 0x59, 0x9e, 0x24, 0xbd, + 0x85, 0x3e, 0x62, 0x6f, 0xdf, 0x15, 0xd1, 0x7e, 0xc7, 0x36, 0x76, 0xd0, 0x6e, 0xd7, 0xed, 0x4d, + 0x64, 0xf1, 0x29, 0x98, 0x4d, 0xf7, 0x5e, 0x39, 0xf0, 0x8d, 0xfb, 0x02, 0x29, 0xfb, 0x43, 0x84, + 0xd5, 0x1a, 0x58, 0x08, 0x5b, 0xc7, 0x0e, 0xf5, 0x65, 0xea, 0x2b, 0x81, 0x6f, 0x94, 0x93, 0xae, + 0xe2, 0x21, 0x68, 0xcd, 0x63, 0x34, 0xe0, 0x59, 0xc0, 0x8a, 0x68, 0xd4, 0x24, 0xaf, 0x38, 0xe5, + 0x6f, 0x0a, 0x58, 0x6e, 0x52, 0xe7, 0x23, 0x62, 0xbc, 0xe9, 0x9a, 0x88, 0xd9, 0x5d, 0x9b, 0xd9, + 0x93, 0xe4, 0x6d, 0x81, 0x79, 0x57, 0xd2, 0xe4, 0xe5, 0xac, 0x27, 0x97, 0x83, 0x4f, 0xe2, 0xcb, + 0x89, 0xb4, 0xeb, 0x8f, 0xe4, 0x05, 0xc9, 0xc9, 0x8a, 0xc8, 0xd0, 0x8a, 0x75, 0xe0, 0x3a, 0x78, + 0x72, 0x4b, 0x56, 0x71, 0xd6, 0x3f, 0xa7, 0x40, 0xb9, 0x49, 0x9d, 0x06, 0xf1, 0x3a, 0x68, 0xdf, + 0xb3, 0x31, 0x3d, 0x42, 0xde, 0xdd, 0x74, 0x93, 0x05, 0x96, 0x99, 0x4c, 0x60, 0xb8, 0xa3, 0x36, + 0x02, 0xdf, 0x58, 0x13, 0xbc, 0x08, 0x94, 0xeb, 0xaa, 0xdb, 0xc8, 0xea, 0x07, 0xb0, 0x14, 0x7d, + 0x4e, 0x66, 0x6f, 0x86, 0x2b, 0xea, 0x81, 0x6f, 0x68, 0x39, 0xc5, 0xf4, 0xfc, 0x0d, 0x13, 0xa1, + 0x06, 0x2a, 0xf9, 0x52, 0x45, 0x75, 0xdc, 0xfe, 0x31, 0x0b, 0xa6, 0x9b, 0xd4, 0x51, 0x3f, 0x81, + 0xc5, 0xf4, 0xce, 0x7c, 0x61, 0xfe, 0x6f, 0x75, 0x9b, 0xd9, 0x9d, 0xa7, 0xbd, 0x9a, 0x04, 0x1d, + 0x6f, 0xc8, 0x43, 0x30, 0xc3, 0x37, 0xdb, 0xe6, 0x48, 0x76, 0x08, 0xd3, 0xb6, 0xc6, 0x82, 0xa5, + 0xd5, 0xf9, 0x86, 0x19, 0xad, 0x1e, 0xc2, 0xc6, 0x50, 0x4f, 0xcf, 0x39, 0x2f, 0x57, 0x6a, 0xc6, + 0xc7, 0x28, 0x57, 0x82, 0x1e, 0xa7, 0x5c, 0xc3, 0x73, 0xaa, 0x7e, 0x51, 0x40, 0x79, 0x68, 0x48, + 0x6b, 0x23, 0xa5, 0xf2, 0x14, 0xed, 0xcd, 0xc4, 0x94, 0x38, 0x85, 0x01, 0x28, 0x66, 0x07, 0xce, + 0x1c, 0xa9, 0x95, 0xc1, 0x6b, 0xaf, 0x27, 0xc3, 0x47, 0x07, 0xd7, 0x0f, 0x2e, 0xaf, 0x75, 0xe5, + 0xea, 0x5a, 0x57, 0xfe, 0x5e, 0xeb, 0xca, 0xd7, 0x1b, 0xbd, 0x70, 0x75, 0xa3, 0x17, 0xfe, 0xdc, + 0xe8, 0x85, 0x83, 0x1d, 0xa7, 0xc7, 0x8e, 0xfb, 0x6d, 0xb3, 0x43, 0xdc, 0xea, 0x1e, 0x17, 0xe7, + 0xbf, 0x9f, 0x0d, 0xf9, 0x24, 0xe1, 0xc7, 0x6c, 0x45, 0x0f, 0x94, 0xf3, 0xec, 0x7b, 0x85, 0x5d, + 0x9c, 0x21, 0xda, 0x9e, 0xe3, 0xef, 0x86, 0x97, 0xff, 0x02, 0x00, 0x00, 0xff, 0xff, 0x27, 0x3b, + 0x54, 0x9e, 0xd4, 0x08, 0x00, 0x00, +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ 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. +const _ = grpc.SupportPackageIsVersion4 + +// MsgClient is the client API for Msg service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type MsgClient interface { + CreateDenom(ctx context.Context, in *MsgCreateDenom, opts ...grpc.CallOption) (*MsgCreateDenomResponse, error) + Mint(ctx context.Context, in *MsgMint, opts ...grpc.CallOption) (*MsgMintResponse, error) + Burn(ctx context.Context, in *MsgBurn, opts ...grpc.CallOption) (*MsgBurnResponse, error) + ChangeAdmin(ctx context.Context, in *MsgChangeAdmin, opts ...grpc.CallOption) (*MsgChangeAdminResponse, error) + SetDenomMetadata(ctx context.Context, in *MsgSetDenomMetadata, opts ...grpc.CallOption) (*MsgSetDenomMetadataResponse, error) + ForceTransfer(ctx context.Context, in *MsgForceTransfer, opts ...grpc.CallOption) (*MsgForceTransferResponse, error) +} + +type msgClient struct { + cc grpc1.ClientConn +} + +func NewMsgClient(cc grpc1.ClientConn) MsgClient { + return &msgClient{cc} +} + +func (c *msgClient) CreateDenom(ctx context.Context, in *MsgCreateDenom, opts ...grpc.CallOption) (*MsgCreateDenomResponse, error) { + out := new(MsgCreateDenomResponse) + err := c.cc.Invoke(ctx, "/osmosis.tokenfactory.v1beta1.Msg/CreateDenom", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *msgClient) Mint(ctx context.Context, in *MsgMint, opts ...grpc.CallOption) (*MsgMintResponse, error) { + out := new(MsgMintResponse) + err := c.cc.Invoke(ctx, "/osmosis.tokenfactory.v1beta1.Msg/Mint", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *msgClient) Burn(ctx context.Context, in *MsgBurn, opts ...grpc.CallOption) (*MsgBurnResponse, error) { + out := new(MsgBurnResponse) + err := c.cc.Invoke(ctx, "/osmosis.tokenfactory.v1beta1.Msg/Burn", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *msgClient) ChangeAdmin(ctx context.Context, in *MsgChangeAdmin, opts ...grpc.CallOption) (*MsgChangeAdminResponse, error) { + out := new(MsgChangeAdminResponse) + err := c.cc.Invoke(ctx, "/osmosis.tokenfactory.v1beta1.Msg/ChangeAdmin", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *msgClient) SetDenomMetadata(ctx context.Context, in *MsgSetDenomMetadata, opts ...grpc.CallOption) (*MsgSetDenomMetadataResponse, error) { + out := new(MsgSetDenomMetadataResponse) + err := c.cc.Invoke(ctx, "/osmosis.tokenfactory.v1beta1.Msg/SetDenomMetadata", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *msgClient) ForceTransfer(ctx context.Context, in *MsgForceTransfer, opts ...grpc.CallOption) (*MsgForceTransferResponse, error) { + out := new(MsgForceTransferResponse) + err := c.cc.Invoke(ctx, "/osmosis.tokenfactory.v1beta1.Msg/ForceTransfer", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// MsgServer is the server API for Msg service. +type MsgServer interface { + CreateDenom(context.Context, *MsgCreateDenom) (*MsgCreateDenomResponse, error) + Mint(context.Context, *MsgMint) (*MsgMintResponse, error) + Burn(context.Context, *MsgBurn) (*MsgBurnResponse, error) + ChangeAdmin(context.Context, *MsgChangeAdmin) (*MsgChangeAdminResponse, error) + SetDenomMetadata(context.Context, *MsgSetDenomMetadata) (*MsgSetDenomMetadataResponse, error) + ForceTransfer(context.Context, *MsgForceTransfer) (*MsgForceTransferResponse, error) +} + +// UnimplementedMsgServer can be embedded to have forward compatible implementations. +type UnimplementedMsgServer struct { +} + +func (*UnimplementedMsgServer) CreateDenom(ctx context.Context, req *MsgCreateDenom) (*MsgCreateDenomResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreateDenom not implemented") +} +func (*UnimplementedMsgServer) Mint(ctx context.Context, req *MsgMint) (*MsgMintResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Mint not implemented") +} +func (*UnimplementedMsgServer) Burn(ctx context.Context, req *MsgBurn) (*MsgBurnResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Burn not implemented") +} +func (*UnimplementedMsgServer) ChangeAdmin(ctx context.Context, req *MsgChangeAdmin) (*MsgChangeAdminResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ChangeAdmin not implemented") +} +func (*UnimplementedMsgServer) SetDenomMetadata(ctx context.Context, req *MsgSetDenomMetadata) (*MsgSetDenomMetadataResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method SetDenomMetadata not implemented") +} +func (*UnimplementedMsgServer) ForceTransfer(ctx context.Context, req *MsgForceTransfer) (*MsgForceTransferResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ForceTransfer not implemented") +} + +func RegisterMsgServer(s grpc1.Server, srv MsgServer) { + s.RegisterService(&_Msg_serviceDesc, srv) +} + +func _Msg_CreateDenom_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgCreateDenom) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).CreateDenom(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/osmosis.tokenfactory.v1beta1.Msg/CreateDenom", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).CreateDenom(ctx, req.(*MsgCreateDenom)) + } + return interceptor(ctx, in, info, handler) +} + +func _Msg_Mint_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgMint) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).Mint(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/osmosis.tokenfactory.v1beta1.Msg/Mint", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).Mint(ctx, req.(*MsgMint)) + } + return interceptor(ctx, in, info, handler) +} + +func _Msg_Burn_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgBurn) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).Burn(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/osmosis.tokenfactory.v1beta1.Msg/Burn", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).Burn(ctx, req.(*MsgBurn)) + } + return interceptor(ctx, in, info, handler) +} + +func _Msg_ChangeAdmin_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgChangeAdmin) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).ChangeAdmin(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/osmosis.tokenfactory.v1beta1.Msg/ChangeAdmin", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).ChangeAdmin(ctx, req.(*MsgChangeAdmin)) + } + return interceptor(ctx, in, info, handler) +} + +func _Msg_SetDenomMetadata_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgSetDenomMetadata) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).SetDenomMetadata(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/osmosis.tokenfactory.v1beta1.Msg/SetDenomMetadata", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).SetDenomMetadata(ctx, req.(*MsgSetDenomMetadata)) + } + return interceptor(ctx, in, info, handler) +} + +func _Msg_ForceTransfer_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgForceTransfer) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).ForceTransfer(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/osmosis.tokenfactory.v1beta1.Msg/ForceTransfer", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).ForceTransfer(ctx, req.(*MsgForceTransfer)) + } + return interceptor(ctx, in, info, handler) +} + +var _Msg_serviceDesc = grpc.ServiceDesc{ + ServiceName: "osmosis.tokenfactory.v1beta1.Msg", + HandlerType: (*MsgServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "CreateDenom", + Handler: _Msg_CreateDenom_Handler, + }, + { + MethodName: "Mint", + Handler: _Msg_Mint_Handler, + }, + { + MethodName: "Burn", + Handler: _Msg_Burn_Handler, + }, + { + MethodName: "ChangeAdmin", + Handler: _Msg_ChangeAdmin_Handler, + }, + { + MethodName: "SetDenomMetadata", + Handler: _Msg_SetDenomMetadata_Handler, + }, + { + MethodName: "ForceTransfer", + Handler: _Msg_ForceTransfer_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "osmosis/tokenfactory/v1beta1/tx.proto", +} + +func (m *MsgCreateDenom) 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 *MsgCreateDenom) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgCreateDenom) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Subdenom) > 0 { + i -= len(m.Subdenom) + copy(dAtA[i:], m.Subdenom) + i = encodeVarintTx(dAtA, i, uint64(len(m.Subdenom))) + i-- + dAtA[i] = 0x12 + } + 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 *MsgCreateDenomResponse) 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 *MsgCreateDenomResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgCreateDenomResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.NewTokenDenom) > 0 { + i -= len(m.NewTokenDenom) + copy(dAtA[i:], m.NewTokenDenom) + i = encodeVarintTx(dAtA, i, uint64(len(m.NewTokenDenom))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgMint) 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 *MsgMint) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgMint) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.MintToAddress) > 0 { + i -= len(m.MintToAddress) + copy(dAtA[i:], m.MintToAddress) + i = encodeVarintTx(dAtA, i, uint64(len(m.MintToAddress))) + i-- + dAtA[i] = 0x1a + } + { + size, err := m.Amount.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + 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 *MsgMintResponse) 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 *MsgMintResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgMintResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *MsgBurn) 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 *MsgBurn) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgBurn) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.BurnFromAddress) > 0 { + i -= len(m.BurnFromAddress) + copy(dAtA[i:], m.BurnFromAddress) + i = encodeVarintTx(dAtA, i, uint64(len(m.BurnFromAddress))) + i-- + dAtA[i] = 0x1a + } + { + size, err := m.Amount.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + 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 *MsgBurnResponse) 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 *MsgBurnResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgBurnResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *MsgChangeAdmin) 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 *MsgChangeAdmin) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgChangeAdmin) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.NewAdmin) > 0 { + i -= len(m.NewAdmin) + copy(dAtA[i:], m.NewAdmin) + i = encodeVarintTx(dAtA, i, uint64(len(m.NewAdmin))) + i-- + dAtA[i] = 0x1a + } + if len(m.Denom) > 0 { + i -= len(m.Denom) + copy(dAtA[i:], m.Denom) + i = encodeVarintTx(dAtA, i, uint64(len(m.Denom))) + i-- + dAtA[i] = 0x12 + } + 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 *MsgChangeAdminResponse) 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 *MsgChangeAdminResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgChangeAdminResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *MsgSetDenomMetadata) 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 *MsgSetDenomMetadata) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgSetDenomMetadata) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Metadata.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + 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 *MsgSetDenomMetadataResponse) 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 *MsgSetDenomMetadataResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgSetDenomMetadataResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *MsgForceTransfer) 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 *MsgForceTransfer) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgForceTransfer) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.TransferToAddress) > 0 { + i -= len(m.TransferToAddress) + copy(dAtA[i:], m.TransferToAddress) + i = encodeVarintTx(dAtA, i, uint64(len(m.TransferToAddress))) + i-- + dAtA[i] = 0x22 + } + if len(m.TransferFromAddress) > 0 { + i -= len(m.TransferFromAddress) + copy(dAtA[i:], m.TransferFromAddress) + i = encodeVarintTx(dAtA, i, uint64(len(m.TransferFromAddress))) + i-- + dAtA[i] = 0x1a + } + { + size, err := m.Amount.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + 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 *MsgForceTransferResponse) 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 *MsgForceTransferResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgForceTransferResponse) 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 + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *MsgCreateDenom) 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)) + } + l = len(m.Subdenom) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgCreateDenomResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.NewTokenDenom) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgMint) 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)) + } + l = m.Amount.Size() + n += 1 + l + sovTx(uint64(l)) + l = len(m.MintToAddress) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgMintResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *MsgBurn) 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)) + } + l = m.Amount.Size() + n += 1 + l + sovTx(uint64(l)) + l = len(m.BurnFromAddress) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgBurnResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *MsgChangeAdmin) 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)) + } + l = len(m.Denom) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.NewAdmin) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgChangeAdminResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *MsgSetDenomMetadata) 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)) + } + l = m.Metadata.Size() + n += 1 + l + sovTx(uint64(l)) + return n +} + +func (m *MsgSetDenomMetadataResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *MsgForceTransfer) 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)) + } + l = m.Amount.Size() + n += 1 + l + sovTx(uint64(l)) + l = len(m.TransferFromAddress) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.TransferToAddress) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgForceTransferResponse) 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 +} +func sozTx(x uint64) (n int) { + return sovTx(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *MsgCreateDenom) 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: MsgCreateDenom: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgCreateDenom: 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 != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Subdenom", 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.Subdenom = string(dAtA[iNdEx:postIndex]) + 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 *MsgCreateDenomResponse) 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: MsgCreateDenomResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgCreateDenomResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NewTokenDenom", 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.NewTokenDenom = string(dAtA[iNdEx:postIndex]) + 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 *MsgMint) 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: MsgMint: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgMint: 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 != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Amount", 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 err := m.Amount.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MintToAddress", 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.MintToAddress = string(dAtA[iNdEx:postIndex]) + 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 *MsgMintResponse) 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: MsgMintResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgMintResponse: 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 (m *MsgBurn) 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: MsgBurn: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgBurn: 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 != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Amount", 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 err := m.Amount.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field BurnFromAddress", 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.BurnFromAddress = string(dAtA[iNdEx:postIndex]) + 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 *MsgBurnResponse) 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: MsgBurnResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgBurnResponse: 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 (m *MsgChangeAdmin) 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: MsgChangeAdmin: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgChangeAdmin: 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 != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Denom", 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.Denom = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NewAdmin", 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.NewAdmin = string(dAtA[iNdEx:postIndex]) + 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 *MsgChangeAdminResponse) 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: MsgChangeAdminResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgChangeAdminResponse: 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 (m *MsgSetDenomMetadata) 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: MsgSetDenomMetadata: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgSetDenomMetadata: 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 != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Metadata", 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 err := m.Metadata.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 *MsgSetDenomMetadataResponse) 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: MsgSetDenomMetadataResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgSetDenomMetadataResponse: 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 (m *MsgForceTransfer) 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: MsgForceTransfer: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgForceTransfer: 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 != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Amount", 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 err := m.Amount.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TransferFromAddress", 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.TransferFromAddress = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TransferToAddress", 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.TransferToAddress = string(dAtA[iNdEx:postIndex]) + 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 *MsgForceTransferResponse) 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: MsgForceTransferResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgForceTransferResponse: 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 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowTx + } + 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, ErrIntOverflowTx + } + 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, ErrIntOverflowTx + } + 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, ErrInvalidLengthTx + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupTx + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthTx + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthTx = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowTx = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupTx = fmt.Errorf("proto: unexpected end of group") +) From 0268fa734e59024d1057c35a04b894595a14dc5d Mon Sep 17 00:00:00 2001 From: Jacob Gadikian Date: Mon, 24 Apr 2023 11:41:49 +0700 Subject: [PATCH 006/131] add token factory --- Makefile | 2 +- app/ante.go | 4 +- app/app.go | 20 ++--- app/decorators/msg_filter.go | 2 +- app/export.go | 2 +- app/helpers/mock.go | 6 +- app/keepers/keepers.go | 38 +++++----- app/keepers/keys.go | 10 +-- app/keepers/querier.go | 2 +- app/modules.go | 16 ++-- app/sim_test.go | 6 +- app/test_helpers.go | 14 ++-- app/upgrades/types.go | 2 +- app/upgrades/v10/constants.go | 4 +- app/upgrades/v10/upgrades.go | 4 +- app/upgrades/v11/constants.go | 4 +- app/upgrades/v11/upgrades.go | 4 +- app/upgrades/v13/constants.go | 4 +- app/upgrades/v13/upgrades.go | 8 +- cmd/junod/cmd/balances_from_state_export.go | 4 +- cmd/junod/cmd/config.go | 2 +- cmd/junod/cmd/forceprune.go | 4 +- cmd/junod/cmd/genica.go | 6 +- cmd/junod/cmd/resets.go | 2 +- cmd/junod/cmd/root.go | 6 +- cmd/junod/cmd/server_configs.go | 2 +- go.mod | 82 +++++++++------------ go.sum | 61 +++++++++++++++ tests/interchaintest/ibc_transfer_test.go | 2 +- tests/interchaintest/setup.go | 2 +- 30 files changed, 188 insertions(+), 137 deletions(-) diff --git a/Makefile b/Makefile index 7938bc8e9..e18cea320 100644 --- a/Makefile +++ b/Makefile @@ -159,7 +159,7 @@ endif ### Proto ### ############################################################################### -protoVer=v0.7 +protoVer=v0.12.1 protoImageName=tendermintdev/sdk-proto-gen:$(protoVer) containerProtoGen=juno-proto-gen-$(protoVer) containerProtoGenAny=juno-proto-gen-any-$(protoVer) diff --git a/app/ante.go b/app/ante.go index b72341f43..d83e024d2 100644 --- a/app/ante.go +++ b/app/ante.go @@ -5,8 +5,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/v4/modules/core/ante" - ibckeeper "github.com/cosmos/ibc-go/v4/modules/core/keeper" + ibcante "github.com/cosmos/ibc-go/v7/modules/core/ante" + ibckeeper "github.com/cosmos/ibc-go/v7/modules/core/keeper" paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" diff --git a/app/app.go b/app/app.go index 52b1c0757..b5b5df66e 100644 --- a/app/app.go +++ b/app/app.go @@ -7,8 +7,14 @@ import ( "strconv" "strings" + "cosmossdk.io/simapp" "github.com/CosmosContracts/juno/v15/app/openapiconsole" "github.com/CosmosContracts/juno/v15/docs" + dbm "github.com/cometbft/cometbft-db" + abci "github.com/cometbft/cometbft/abci/types" + tmjson "github.com/cometbft/cometbft/libs/json" + "github.com/cometbft/cometbft/libs/log" + tmos "github.com/cometbft/cometbft/libs/os" "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/grpc/tmservice" @@ -18,7 +24,6 @@ import ( "github.com/cosmos/cosmos-sdk/server/api" "github.com/cosmos/cosmos-sdk/server/config" servertypes "github.com/cosmos/cosmos-sdk/server/types" - "github.com/cosmos/cosmos-sdk/simapp" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/address" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" @@ -36,16 +41,11 @@ import ( stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" upgradeclient "github.com/cosmos/cosmos-sdk/x/upgrade/client" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" - ibctransfertypes "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types" - ibcclientclient "github.com/cosmos/ibc-go/v4/modules/core/02-client/client" - ibcclienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - ibcchanneltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" + ibctransfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" + ibcclientclient "github.com/cosmos/ibc-go/v7/modules/core/02-client/client" + ibcclienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + ibcchanneltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" "github.com/spf13/cast" - abci "github.com/tendermint/tendermint/abci/types" - tmjson "github.com/tendermint/tendermint/libs/json" - "github.com/tendermint/tendermint/libs/log" - tmos "github.com/tendermint/tendermint/libs/os" - dbm "github.com/tendermint/tm-db" "github.com/CosmWasm/wasmd/x/wasm" wasmclient "github.com/CosmWasm/wasmd/x/wasm/client" diff --git a/app/decorators/msg_filter.go b/app/decorators/msg_filter.go index ea3767634..186a74b63 100644 --- a/app/decorators/msg_filter.go +++ b/app/decorators/msg_filter.go @@ -4,7 +4,7 @@ import ( "fmt" sdk "github.com/cosmos/cosmos-sdk/types" - ibcchanneltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" + ibcchanneltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" ) // MsgFilterDecorator defines an AnteHandler decorator for the v9 upgrade that diff --git a/app/export.go b/app/export.go index 2bc0901f4..cfd94eb62 100644 --- a/app/export.go +++ b/app/export.go @@ -4,7 +4,7 @@ import ( "encoding/json" "log" - tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + tmproto "github.com/cometbft/cometbft/proto/tendermint/types" servertypes "github.com/cosmos/cosmos-sdk/server/types" sdk "github.com/cosmos/cosmos-sdk/types" diff --git a/app/helpers/mock.go b/app/helpers/mock.go index 0e2ca9521..ffbfc82fb 100644 --- a/app/helpers/mock.go +++ b/app/helpers/mock.go @@ -1,9 +1,9 @@ package helpers import ( - "github.com/tendermint/tendermint/crypto" - tmproto "github.com/tendermint/tendermint/proto/tendermint/types" - tmtypes "github.com/tendermint/tendermint/types" + "github.com/cometbft/cometbft/crypto" + tmproto "github.com/cometbft/cometbft/proto/tendermint/types" + tmtypes "github.com/cometbft/cometbft/types" cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" diff --git a/app/keepers/keepers.go b/app/keepers/keepers.go index 04d006212..218820e0a 100644 --- a/app/keepers/keepers.go +++ b/app/keepers/keepers.go @@ -42,18 +42,18 @@ import ( "github.com/cosmos/cosmos-sdk/x/upgrade" upgradekeeper "github.com/cosmos/cosmos-sdk/x/upgrade/keeper" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/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" - ibcclient "github.com/cosmos/ibc-go/v4/modules/core/02-client" - ibcclienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - ibcconnectiontypes "github.com/cosmos/ibc-go/v4/modules/core/03-connection/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" + ibcfee "github.com/cosmos/ibc-go/v7/modules/apps/29-fee" + ibcfeekeeper "github.com/cosmos/ibc-go/v7/modules/apps/29-fee/keeper" + ibcfeetypes "github.com/cosmos/ibc-go/v7/modules/apps/29-fee/types" + transfer "github.com/cosmos/ibc-go/v7/modules/apps/transfer" + ibctransferkeeper "github.com/cosmos/ibc-go/v7/modules/apps/transfer/keeper" + ibctransfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" + ibcclient "github.com/cosmos/ibc-go/v7/modules/core/02-client" + ibcclienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + ibcconnectiontypes "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" + porttypes "github.com/cosmos/ibc-go/v7/modules/core/05-port/types" + ibchost "github.com/cosmos/ibc-go/v7/modules/core/24-host" + ibckeeper "github.com/cosmos/ibc-go/v7/modules/core/keeper" ibchooks "github.com/osmosis-labs/osmosis/x/ibc-hooks" ibchookskeeper "github.com/osmosis-labs/osmosis/x/ibc-hooks/keeper" @@ -65,9 +65,9 @@ import ( tokenfactorykeeper "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/keeper" tokenfactorytypes "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/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" + icahost "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/host" + icahostkeeper "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/host/keeper" + icahosttypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/host/types" feesharekeeper "github.com/CosmosContracts/juno/v15/x/feeshare/keeper" feesharetypes "github.com/CosmosContracts/juno/v15/x/feeshare/types" @@ -76,10 +76,10 @@ import ( icqkeeper "github.com/strangelove-ventures/async-icq/v4/keeper" icqtypes "github.com/strangelove-ventures/async-icq/v4/types" - // 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" + // ica "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts" + icacontroller "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller" + icacontrollerkeeper "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/keeper" + icacontrollertypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/types" "github.com/cosmos/gaia/v9/x/globalfee" ) diff --git a/app/keepers/keys.go b/app/keepers/keys.go index 024141f9c..556919793 100644 --- a/app/keepers/keys.go +++ b/app/keepers/keys.go @@ -19,11 +19,11 @@ import ( slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" - icacontrollertypes "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/controller/types" - icahosttypes "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/host/types" - ibcfeetypes "github.com/cosmos/ibc-go/v4/modules/apps/29-fee/types" - ibctransfertypes "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types" - ibchost "github.com/cosmos/ibc-go/v4/modules/core/24-host" + icacontrollertypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/types" + icahosttypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/host/types" + ibcfeetypes "github.com/cosmos/ibc-go/v7/modules/apps/29-fee/types" + ibctransfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" + ibchost "github.com/cosmos/ibc-go/v7/modules/core/24-host" ibchookstypes "github.com/osmosis-labs/osmosis/x/ibc-hooks/types" icqtypes "github.com/strangelove-ventures/async-icq/v4/types" packetforwardtypes "github.com/strangelove-ventures/packet-forward-middleware/v4/router/types" diff --git a/app/keepers/querier.go b/app/keepers/querier.go index 692d99325..b31142f21 100644 --- a/app/keepers/querier.go +++ b/app/keepers/querier.go @@ -4,8 +4,8 @@ package keepers import ( + abci "github.com/cometbft/cometbft/abci/types" sdk "github.com/cosmos/cosmos-sdk/types" - abci "github.com/tendermint/tendermint/abci/types" ) // QuerierWrapper is a local wrapper around BaseApp that exports only the Queryable interface. diff --git a/app/modules.go b/app/modules.go index ab49ed534..ace5074d7 100644 --- a/app/modules.go +++ b/app/modules.go @@ -42,14 +42,14 @@ import ( "github.com/cosmos/cosmos-sdk/x/upgrade" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" "github.com/cosmos/gaia/v9/x/globalfee" - ica "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts" - icatypes "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/types" - ibcfee "github.com/cosmos/ibc-go/v4/modules/apps/29-fee" - ibcfeetypes "github.com/cosmos/ibc-go/v4/modules/apps/29-fee/types" - transfer "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" + ica "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts" + icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" + ibcfee "github.com/cosmos/ibc-go/v7/modules/apps/29-fee" + ibcfeetypes "github.com/cosmos/ibc-go/v7/modules/apps/29-fee/types" + transfer "github.com/cosmos/ibc-go/v7/modules/apps/transfer" + ibctransfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" + ibc "github.com/cosmos/ibc-go/v7/modules/core" + ibchost "github.com/cosmos/ibc-go/v7/modules/core/24-host" ibchooks "github.com/osmosis-labs/osmosis/x/ibc-hooks" ibchookstypes "github.com/osmosis-labs/osmosis/x/ibc-hooks/types" icq "github.com/strangelove-ventures/async-icq/v4" diff --git a/app/sim_test.go b/app/sim_test.go index a66ee5d9c..47406feb7 100644 --- a/app/sim_test.go +++ b/app/sim_test.go @@ -8,18 +8,18 @@ import ( "time" "github.com/CosmWasm/wasmd/x/wasm" + "github.com/cometbft/cometbft/libs/log" "github.com/stretchr/testify/require" - "github.com/tendermint/tendermint/libs/log" + "cosmossdk.io/simapp" + dbm "github.com/cometbft/cometbft-db" "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/codec" - "github.com/cosmos/cosmos-sdk/simapp" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/kv" "github.com/cosmos/cosmos-sdk/types/module" simtypes "github.com/cosmos/cosmos-sdk/types/simulation" "github.com/cosmos/cosmos-sdk/x/simulation" - dbm "github.com/tendermint/tm-db" ) // Get flags every time the simulator is run diff --git a/app/test_helpers.go b/app/test_helpers.go index 71e39f57c..576871fc5 100644 --- a/app/test_helpers.go +++ b/app/test_helpers.go @@ -9,6 +9,13 @@ import ( "github.com/CosmWasm/wasmd/x/wasm/keeper" apphelpers "github.com/CosmosContracts/juno/v15/app/helpers" appparams "github.com/CosmosContracts/juno/v15/app/params" + dbm "github.com/cometbft/cometbft-db" + abci "github.com/cometbft/cometbft/abci/types" + "github.com/cometbft/cometbft/crypto" + "github.com/cometbft/cometbft/crypto/ed25519" + "github.com/cometbft/cometbft/libs/log" + tmproto "github.com/cometbft/cometbft/proto/tendermint/types" + tmtypes "github.com/cometbft/cometbft/types" codectypes "github.com/cosmos/cosmos-sdk/codec/types" cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" @@ -17,13 +24,6 @@ import ( banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/stretchr/testify/require" - abci "github.com/tendermint/tendermint/abci/types" - "github.com/tendermint/tendermint/crypto" - "github.com/tendermint/tendermint/crypto/ed25519" - "github.com/tendermint/tendermint/libs/log" - tmproto "github.com/tendermint/tendermint/proto/tendermint/types" - tmtypes "github.com/tendermint/tendermint/types" - dbm "github.com/tendermint/tm-db" ) // SimAppChainID hardcoded chainID for simulation diff --git a/app/upgrades/types.go b/app/upgrades/types.go index d833795a5..f16387cf3 100644 --- a/app/upgrades/types.go +++ b/app/upgrades/types.go @@ -4,11 +4,11 @@ import ( "strings" "github.com/CosmosContracts/juno/v15/app/keepers" + abci "github.com/cometbft/cometbft/abci/types" store "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" - abci "github.com/tendermint/tendermint/abci/types" ) // BaseAppParamManager defines an interrace that BaseApp is expected to fullfil diff --git a/app/upgrades/v10/constants.go b/app/upgrades/v10/constants.go index b21c62b2d..dd47a63ab 100644 --- a/app/upgrades/v10/constants.go +++ b/app/upgrades/v10/constants.go @@ -3,8 +3,8 @@ package v10 import ( "github.com/CosmosContracts/juno/v15/app/upgrades" store "github.com/cosmos/cosmos-sdk/store/types" - icacontrollertypes "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/controller/types" - icahosttypes "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/host/types" + icacontrollertypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/types" + icahosttypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/host/types" ) // UpgradeName defines the on-chain upgrade name for the Juno v10 upgrade. diff --git a/app/upgrades/v10/upgrades.go b/app/upgrades/v10/upgrades.go index a96e920c3..2b30d6f35 100644 --- a/app/upgrades/v10/upgrades.go +++ b/app/upgrades/v10/upgrades.go @@ -11,8 +11,8 @@ import ( govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" - icahosttypes "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/host/types" - ibctransfertypes "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types" + icahosttypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/host/types" + ibctransfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" ) // CreateV10UpgradeHandler makes an upgrade handler for v10 of Juno diff --git a/app/upgrades/v11/constants.go b/app/upgrades/v11/constants.go index f05fff308..feb14f793 100644 --- a/app/upgrades/v11/constants.go +++ b/app/upgrades/v11/constants.go @@ -3,8 +3,8 @@ package v11 import ( "github.com/CosmosContracts/juno/v15/app/upgrades" store "github.com/cosmos/cosmos-sdk/store/types" - icacontrollertypes "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/controller/types" - icahosttypes "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/host/types" + icacontrollertypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/types" + icahosttypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/host/types" ) // UpgradeName defines the on-chain upgrade name for the Juno v11 upgrade. diff --git a/app/upgrades/v11/upgrades.go b/app/upgrades/v11/upgrades.go index 5ab901559..0e05d3cf4 100644 --- a/app/upgrades/v11/upgrades.go +++ b/app/upgrades/v11/upgrades.go @@ -11,8 +11,8 @@ import ( govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" - icahosttypes "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/host/types" - ibctransfertypes "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types" + icahosttypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/host/types" + ibctransfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" ) // CreateV11UpgradeHandler makes an upgrade handler for v11 of Juno diff --git a/app/upgrades/v13/constants.go b/app/upgrades/v13/constants.go index af275e58a..4781e1138 100644 --- a/app/upgrades/v13/constants.go +++ b/app/upgrades/v13/constants.go @@ -5,8 +5,8 @@ import ( feesharetypes "github.com/CosmosContracts/juno/v15/x/feeshare/types" tokenfactorytypes "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/types" store "github.com/cosmos/cosmos-sdk/store/types" - icacontrollertypes "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/controller/types" - ibcfeetypes "github.com/cosmos/ibc-go/v4/modules/apps/29-fee/types" + icacontrollertypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/types" + ibcfeetypes "github.com/cosmos/ibc-go/v7/modules/apps/29-fee/types" ibchookstypes "github.com/osmosis-labs/osmosis/x/ibc-hooks/types" packetforwardtypes "github.com/strangelove-ventures/packet-forward-middleware/v4/router/types" ) diff --git a/app/upgrades/v13/upgrades.go b/app/upgrades/v13/upgrades.go index dfe6b0f42..5b11d82f9 100644 --- a/app/upgrades/v13/upgrades.go +++ b/app/upgrades/v13/upgrades.go @@ -10,15 +10,15 @@ import ( "github.com/cosmos/cosmos-sdk/types/module" // ICA - icacontrollertypes "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/controller/types" - 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" + icacontrollertypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/types" + icahosttypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/host/types" + icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" // types feesharetypes "github.com/CosmosContracts/juno/v15/x/feeshare/types" tokenfactorytypes "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/types" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" - ibcfeetypes "github.com/cosmos/ibc-go/v4/modules/apps/29-fee/types" + ibcfeetypes "github.com/cosmos/ibc-go/v7/modules/apps/29-fee/types" packetforwardtypes "github.com/strangelove-ventures/packet-forward-middleware/v4/router/types" ) diff --git a/cmd/junod/cmd/balances_from_state_export.go b/cmd/junod/cmd/balances_from_state_export.go index 225ca72dc..4e9722afe 100644 --- a/cmd/junod/cmd/balances_from_state_export.go +++ b/cmd/junod/cmd/balances_from_state_export.go @@ -11,9 +11,9 @@ import ( "os" "path/filepath" + tmjson "github.com/cometbft/cometbft/libs/json" + tmtypes "github.com/cometbft/cometbft/types" "github.com/spf13/cobra" - tmjson "github.com/tendermint/tendermint/libs/json" - tmtypes "github.com/tendermint/tendermint/types" appparams "github.com/CosmosContracts/juno/v15/app/params" "github.com/cosmos/cosmos-sdk/client" diff --git a/cmd/junod/cmd/config.go b/cmd/junod/cmd/config.go index 1be0ff9d5..b2eb0c151 100644 --- a/cmd/junod/cmd/config.go +++ b/cmd/junod/cmd/config.go @@ -8,7 +8,7 @@ import ( "path/filepath" "text/template" - tmcli "github.com/tendermint/tendermint/libs/cli" + tmcli "github.com/cometbft/cometbft/libs/cli" "github.com/spf13/cobra" diff --git a/cmd/junod/cmd/forceprune.go b/cmd/junod/cmd/forceprune.go index 93435cd33..a585f9691 100644 --- a/cmd/junod/cmd/forceprune.go +++ b/cmd/junod/cmd/forceprune.go @@ -13,13 +13,13 @@ import ( "github.com/spf13/cobra" tmdb "github.com/cometbft/cometbft-db" + tmstore "github.com/cometbft/cometbft/store" "github.com/syndtr/goleveldb/leveldb" "github.com/syndtr/goleveldb/leveldb/opt" "github.com/syndtr/goleveldb/leveldb/util" - tmstore "github.com/tendermint/tendermint/store" + "github.com/cometbft/cometbft/config" "github.com/cosmos/cosmos-sdk/client" - "github.com/tendermint/tendermint/config" ) const ( diff --git a/cmd/junod/cmd/genica.go b/cmd/junod/cmd/genica.go index d001e4c6d..84c58cf7a 100644 --- a/cmd/junod/cmd/genica.go +++ b/cmd/junod/cmd/genica.go @@ -6,9 +6,9 @@ import ( "github.com/spf13/cobra" - icacontrollertypes "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/controller/types" - 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" + icacontrollertypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/types" + icahosttypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/host/types" + icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" diff --git a/cmd/junod/cmd/resets.go b/cmd/junod/cmd/resets.go index 0c3d68ad6..510c29654 100644 --- a/cmd/junod/cmd/resets.go +++ b/cmd/junod/cmd/resets.go @@ -7,9 +7,9 @@ import ( "github.com/spf13/cobra" + tmos "github.com/cometbft/cometbft/libs/os" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/server" - tmos "github.com/tendermint/tendermint/libs/os" ) // Cmd creates a main CLI command diff --git a/cmd/junod/cmd/root.go b/cmd/junod/cmd/root.go index 8a04d9465..fcd38414d 100644 --- a/cmd/junod/cmd/root.go +++ b/cmd/junod/cmd/root.go @@ -11,6 +11,9 @@ import ( "github.com/cosmos/cosmos-sdk/client" serverconfig "github.com/cosmos/cosmos-sdk/server/config" + dbm "github.com/cometbft/cometbft-db" + tmcli "github.com/cometbft/cometbft/libs/cli" + "github.com/cometbft/cometbft/libs/log" "github.com/cosmos/cosmos-sdk/client/config" "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/client/keys" @@ -30,9 +33,6 @@ import ( "github.com/prometheus/client_golang/prometheus" "github.com/spf13/cast" "github.com/spf13/cobra" - tmcli "github.com/tendermint/tendermint/libs/cli" - "github.com/tendermint/tendermint/libs/log" - dbm "github.com/tendermint/tm-db" "github.com/CosmWasm/wasmd/x/wasm" wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" diff --git a/cmd/junod/cmd/server_configs.go b/cmd/junod/cmd/server_configs.go index dd3747aef..200935be7 100644 --- a/cmd/junod/cmd/server_configs.go +++ b/cmd/junod/cmd/server_configs.go @@ -9,11 +9,11 @@ import ( "strings" "time" + tmcfg "github.com/cometbft/cometbft/config" "github.com/rs/zerolog" "github.com/spf13/cobra" "github.com/spf13/pflag" "github.com/spf13/viper" - tmcfg "github.com/tendermint/tendermint/config" "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/server/config" diff --git a/go.mod b/go.mod index 5483f8104..4475af153 100644 --- a/go.mod +++ b/go.mod @@ -3,35 +3,30 @@ module github.com/CosmosContracts/juno/v15 go 1.19 require ( - github.com/CosmWasm/wasmd v0.31.0 github.com/CosmosTokenFactory/token-factory v0.0.0-20230422130917-82986c5b3ec0 github.com/cometbft/cometbft-db v0.7.0 - github.com/cosmos/cosmos-sdk v0.45.15 github.com/cosmos/gaia/v9 v9.0.2 - github.com/cosmos/ibc-go/v4 v4.3.0 - github.com/gogo/protobuf v1.3.3 github.com/golang/protobuf v1.5.3 github.com/gorilla/mux v1.8.0 github.com/grpc-ecosystem/grpc-gateway v1.16.0 github.com/osmosis-labs/osmosis/x/ibc-hooks v0.0.0-20230201151635-ef43e092d196 - github.com/prometheus/client_golang v1.14.0 + github.com/prometheus/client_golang v1.15.0 github.com/spf13/cast v1.5.0 github.com/spf13/cobra v1.7.0 - github.com/strangelove-ventures/async-icq/v4 v4.0.0-rc0 - github.com/strangelove-ventures/packet-forward-middleware/v4 v4.0.5 github.com/stretchr/testify v1.8.2 - github.com/tendermint/tendermint v0.34.27 github.com/tendermint/tm-db v0.6.8-0.20220506192307-f628bb5dc95b - google.golang.org/genproto v0.0.0-20230125152338-dcaf20b6aeaa - google.golang.org/grpc v1.53.0 + google.golang.org/genproto v0.0.0-20230216225411-c8e22ba71e44 + google.golang.org/grpc v1.54.0 gopkg.in/yaml.v2 v2.4.0 ) +require github.com/CosmWasm/wasmd v0.40.0-rc.1.0.20230422061626-b85abcf1d7b8 // indirect + require ( - cosmossdk.io/api v0.2.6 // indirect + cosmossdk.io/api v0.3.1 // indirect cosmossdk.io/core v0.5.1 // indirect cosmossdk.io/depinject v1.0.0-alpha.3 // indirect - filippo.io/edwards25519 v1.0.0-rc.1 // indirect + filippo.io/edwards25519 v1.0.0 // 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 @@ -45,7 +40,7 @@ require ( github.com/btcsuite/btcd/btcec/v2 v2.3.2 // 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/cespare/xxhash/v2 v2.2.0 // indirect github.com/cockroachdb/errors v1.9.1 // indirect github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect github.com/cockroachdb/pebble v0.0.0-20220817183557-09c6e030a677 // indirect @@ -56,31 +51,31 @@ require ( github.com/cosmos/cosmos-db v0.0.0-20221226095112-f3c38ecb5e32 // indirect github.com/cosmos/cosmos-proto v1.0.0-beta.2 // indirect github.com/cosmos/go-bip39 v1.0.0 // indirect - github.com/cosmos/gogoproto v1.4.7 + github.com/cosmos/gogoproto v1.4.8 github.com/cosmos/gorocksdb v1.2.0 // indirect - github.com/cosmos/iavl v0.19.5 // indirect + github.com/cosmos/iavl v0.20.0 // indirect github.com/cosmos/ledger-cosmos-go v0.12.2 // indirect - github.com/creachadair/taskgroup v0.3.2 // indirect + github.com/creachadair/taskgroup v0.4.2 // indirect github.com/danieljoos/wincred v1.1.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect github.com/dgraph-io/badger/v2 v2.2007.4 // indirect github.com/dgraph-io/badger/v3 v3.2103.2 // indirect - github.com/dgraph-io/ristretto v0.1.0 // indirect + github.com/dgraph-io/ristretto v0.1.1 // indirect github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect github.com/docker/distribution v2.8.1+incompatible // indirect - github.com/dustin/go-humanize v1.0.1-0.20200219035652-afde56e7acac // indirect + github.com/dustin/go-humanize v1.0.1 // indirect github.com/dvsekhvalnov/jose2go v1.5.0 // indirect github.com/felixge/httpsnoop v1.0.2 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/getsentry/sentry-go v0.17.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/go-logfmt/logfmt v0.6.0 // 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/glog v1.1.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 @@ -97,21 +92,21 @@ require ( github.com/hashicorp/go-immutable-radix v1.3.1 // 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-20220222234857-c00d1f31bab3 // indirect + github.com/hdevalence/ed25519consensus v0.1.0 // indirect github.com/iancoleman/orderedmap v0.2.0 // indirect github.com/improbable-eng/grpc-web v0.15.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jmhodges/levigo v1.0.0 // indirect - github.com/klauspost/compress v1.15.11 // indirect + github.com/klauspost/compress v1.16.3 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect - github.com/lib/pq v1.10.6 // indirect + github.com/lib/pq v1.10.7 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/linxGnu/grocksdb v1.7.10 // indirect github.com/magiconair/properties v1.8.7 // 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/mattn/go-isatty v0.0.17 // indirect + github.com/matttproud/golang_protobuf_extensions v1.0.4 // 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 @@ -119,17 +114,17 @@ require ( github.com/opencontainers/go-digest v1.0.0 // indirect github.com/osmosis-labs/osmosis/osmoutils v0.0.3-rc0 // indirect github.com/pelletier/go-toml/v2 v2.0.6 // indirect - github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 // indirect + github.com/petermattis/goid v0.0.0-20221215004737-a150e88a970d // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.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/prometheus/common v0.42.0 // indirect + github.com/prometheus/procfs v0.9.0 // indirect github.com/rakyll/statik v0.1.7 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/regen-network/cosmos-proto v0.3.1 // indirect github.com/rogpeppe/go-internal v1.9.0 // indirect - github.com/rs/cors v1.8.2 // indirect + github.com/rs/cors v1.8.3 // indirect github.com/rs/zerolog v1.27.0 github.com/sasha-s/go-deadlock v0.3.1 // indirect github.com/spf13/afero v1.9.3 // indirect @@ -137,21 +132,21 @@ require ( github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.15.0 github.com/subosito/gotenv v1.4.2 // indirect - github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 + github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c // indirect github.com/tendermint/go-amino v0.16.0 // indirect - github.com/tidwall/btree v1.5.0 // indirect + github.com/tidwall/btree v1.6.0 // indirect github.com/zondax/hid v0.9.1 // indirect github.com/zondax/ledger-go v0.14.1 // indirect - go.etcd.io/bbolt v1.3.6 // indirect + go.etcd.io/bbolt v1.3.7 // indirect go.opencensus.io v0.24.0 // indirect - golang.org/x/crypto v0.5.0 // indirect - golang.org/x/exp v0.0.0-20230131160201-f062dba9d201 // indirect - golang.org/x/net v0.8.0 // indirect - golang.org/x/sys v0.6.0 // indirect - golang.org/x/term v0.6.0 // indirect - golang.org/x/text v0.8.0 // indirect - google.golang.org/protobuf v1.29.1 // indirect + golang.org/x/crypto v0.7.0 // indirect + golang.org/x/exp v0.0.0-20230321023759-10a507213a29 // indirect + golang.org/x/net v0.9.0 // indirect + golang.org/x/sys v0.7.0 // indirect + golang.org/x/term v0.7.0 // indirect + golang.org/x/text v0.9.0 // indirect + google.golang.org/protobuf v1.30.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect nhooyr.io/websocket v1.8.7 // indirect @@ -168,10 +163,5 @@ replace ( // Fix upstream GHSA-h395-qcrw-5vmq vulnerability. // TODO Remove it: https://github.com/cosmos/cosmos-sdk/issues/10409 github.com/gin-gonic/gin => github.com/gin-gonic/gin v1.8.1 - // use cosmos-flavored protocol buffers - github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 - // cometbft - github.com/tendermint/tendermint => github.com/skip-mev/mev-cometbft v0.34.27-mev.18 - // use grpc version that's compatible with cosmos-flavored protocol buffers - google.golang.org/grpc => google.golang.org/grpc v1.33.2 + ) diff --git a/go.sum b/go.sum index 67df08c16..7d5df035b 100644 --- a/go.sum +++ b/go.sum @@ -40,6 +40,7 @@ cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3f collectd.org v0.3.0/go.mod h1:A/8DzQBkF6abtvrT2j/AU/4tiBgJWYyh0y/oB/4MlWE= cosmossdk.io/api v0.2.6 h1:AoNwaLLapcLsphhMK6+o0kZl+D6MMUaHVqSdwinASGU= cosmossdk.io/api v0.2.6/go.mod h1:u/d+GAxil0nWpl1XnQL8nkziQDIWuBDhv8VnDm/s6dI= +cosmossdk.io/api v0.3.1/go.mod h1:DfHfMkiNA2Uhy8fj0JJlOCYOBp4eWUUJ1te5zBGNyIw= cosmossdk.io/core v0.5.1 h1:vQVtFrIYOQJDV3f7rw4pjjVqc1id4+mE0L9hHP66pyI= cosmossdk.io/core v0.5.1/go.mod h1:KZtwHCLjcFuo0nmDc24Xy6CRNEL9Vl/MeimQ2aC7NLE= cosmossdk.io/depinject v1.0.0-alpha.3 h1:6evFIgj//Y3w09bqOUOzEpFj5tsxBqdc5CfkO7z+zfw= @@ -47,6 +48,7 @@ cosmossdk.io/depinject v1.0.0-alpha.3/go.mod h1:eRbcdQ7MRpIPEM5YUJh8k97nxHpYbc3s 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= +filippo.io/edwards25519 v1.0.0/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= @@ -66,6 +68,8 @@ github.com/CloudyKit/jet v2.1.3-0.20180809161101-62edd43e4f88+incompatible/go.mo github.com/CloudyKit/jet/v3 v3.0.0/go.mod h1:HKQPgSJmdK8hdoAbKUUWajkHyHo4RaU5rMdUywE7VMo= github.com/CosmWasm/wasmd v0.31.0 h1:xACf6A/SkCeGWQWrKGsR4X9PQb5G4XYuNfnrl+HQ1mE= github.com/CosmWasm/wasmd v0.31.0/go.mod h1:VcyDGk/ISVlMUeW+1GGL0zdHWBS2FPwLEV2qZ86l7l8= +github.com/CosmWasm/wasmd v0.40.0-rc.1.0.20230422061626-b85abcf1d7b8 h1:daJIcrTcYkpDtn1DXqbGhnQkCPSD93El6mXfv15VJRA= +github.com/CosmWasm/wasmd v0.40.0-rc.1.0.20230422061626-b85abcf1d7b8/go.mod h1:uacdue6EGn9JA1TqBNHB3iCe4PCIChuFT23AzIl2VME= github.com/CosmWasm/wasmvm v1.2.3 h1:OKYlobwmVGbl0eSn0mXoAAjE5hIuXnQCLPjbNd91sVY= github.com/CosmWasm/wasmvm v1.2.3/go.mod h1:vW/E3h8j9xBQs9bCoijDuawKo9kCtxOaS8N8J7KFtkc= github.com/CosmosTokenFactory/token-factory v0.0.0-20230422130917-82986c5b3ec0 h1:H7RtDJcx8WFK7q9BlJeWog+XLwoaVDozlo70Wvl5B40= @@ -173,6 +177,7 @@ 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/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= 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= @@ -234,10 +239,12 @@ 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.7 h1:RzYKVnsEC7UIkDnhTIkqEB7LnIQbsySvmNEqPCiPevk= github.com/cosmos/gogoproto v1.4.7/go.mod h1:gxGePp9qedovvl/StQL2BIJ6qlIBn1+9YxR0IulGBKA= +github.com/cosmos/gogoproto v1.4.8/go.mod h1:hnb0DIEWTv+wdNzNcqus5xCQXq5+CXauq1FJuurRfVY= 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.5 h1:rGA3hOrgNxgRM5wYcSCxgQBap7fW82WZgY78V9po/iY= github.com/cosmos/iavl v0.19.5/go.mod h1:X9PKD3J0iFxdmgNLa7b2LYWdsGd90ToV5cAONApkEPw= +github.com/cosmos/iavl v0.20.0/go.mod h1:WO7FyvaZJoH65+HFOsDir7xU9FWk2w9cHXNW1XHcl7A= github.com/cosmos/ibc-go/v4 v4.3.0 h1:yOzVsyZzsv4XPBux8gq+D0LhZn45yGWKjvT+6Vyo5no= github.com/cosmos/ibc-go/v4 v4.3.0/go.mod h1:CcLvIoi9NNtIbNsxs4KjBGjYhlwqtsmXy1AKARKiMzQ= github.com/cosmos/interchain-accounts v0.2.6 h1:TV2M2g1/Rb9MCNw1YePdBKE0rcEczNj1RGHT+2iRYas= @@ -250,6 +257,7 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:ma github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= 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/creachadair/taskgroup v0.4.2/go.mod h1:qiXUOSrbwAY3u0JPGTzObbE3yf9hcXHDKBZ2ZjpCbgM= 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/cucumber/common/gherkin/go/v22 v22.0.0 h1:4K8NqptbvdOrjL9DEea6HFjSpbdT9+Q5kgLpmmsHYl0= @@ -267,6 +275,7 @@ github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 h1:YLtO71vCjJRCBcrPMtQ9nqBsqpA1m5sE92cU+pd5Mcc= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0/go.mod h1:DZGJHZMqrU4JJqFAWUS2UO1+lbSKsdiOoYi9Zzey7Fc= 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= @@ -281,6 +290,7 @@ github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de/go.mod h1:KP github.com/dgraph-io/ristretto v0.0.3/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= 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/dgraph-io/ristretto v0.1.1/go.mod h1:S1GPSBCYCIhmVNfcth17y2zZtQT6wzkzgwUve0VDWWA= 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= @@ -300,6 +310,7 @@ github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:Htrtb github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.1-0.20200219035652-afde56e7acac h1:opbrjaN/L8gg6Xh5D04Tem+8xVcz6ajZlGCs49mQgyg= github.com/dustin/go-humanize v1.0.1-0.20200219035652-afde56e7acac/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= 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/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= @@ -331,6 +342,7 @@ 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/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/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= @@ -369,6 +381,7 @@ github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= 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-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= 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= @@ -384,6 +397,7 @@ github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5Nq 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/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= 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= github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8= @@ -401,6 +415,11 @@ 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/gogo/googleapis v0.0.0-20180223154316-0cd9801be74a/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/googleapis v1.4.1/go.mod h1:2lpHqI5OcWCtVElxXnPt+s8oJvMpySlOyM6xDCrzib4= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/gogo/status v1.1.0/go.mod h1:BFv9nrluPLmrS0EmGVvLaPNmRosr9KapBYd5/hpY1WM= github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang-jwt/jwt/v4 v4.3.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= @@ -410,6 +429,7 @@ github.com/golang/geo v0.0.0-20190916061304-5b978397cfec/go.mod h1:QZ0nwyI2jOfgR 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= +github.com/golang/glog v1.1.0/go.mod h1:pfYeQZ3JWZoXTV5sFc986z3HTpwQs9At6P4ImfuP3NQ= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= 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= @@ -489,6 +509,7 @@ 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-20210407192527-94a9f03dee38/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= @@ -561,6 +582,7 @@ github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2p 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/hdevalence/ed25519consensus v0.1.0/go.mod h1:w3BHWjwJbFU29IRHL1Iqkw3sus+7FctEyM4RqDxYNzo= 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= @@ -639,6 +661,8 @@ github.com/kataras/neffos v0.0.14/go.mod h1:8lqADm8PnbeFfL7CLXh1WHw53dG27MC3pgi2 github.com/kataras/pio v0.0.0-20190103105442-ea782b38602d/go.mod h1:NV88laa9UiiDuX9AhMbDPkGYSPugBOV6yTZB1l2K9Z0= github.com/kataras/pio v0.0.2/go.mod h1:hAoW0t9UmXi4R5Oyq5Z4irTbaTsOemSrDGUtaTl7Dro= github.com/kataras/sitemap v0.0.5/go.mod h1:KY2eugMKiPwsJgx7+U103YZehfvNGOXURubcGyk0Bz8= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= 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= @@ -651,6 +675,7 @@ github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYs github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.15.11 h1:Lcadnb3RKGin4FYM/orgq0qde+nc15E5Cbqg4B9Sx9c= github.com/klauspost/compress v1.15.11/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= +github.com/klauspost/compress v1.16.3/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/klauspost/cpuid v0.0.0-20170728055534-ae7887de9fa5/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/crc32 v0.0.0-20161016154125-cb6bfca970f6/go.mod h1:+ZoRqAPRLkC4NPOvfYeR5KNOrY6TD+/sAC3HXPZgDYg= @@ -679,6 +704,7 @@ github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ic 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/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= @@ -709,6 +735,7 @@ github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Ky 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-isatty v0.0.17/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.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= @@ -718,6 +745,7 @@ github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpe 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= +github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/mediocregopher/mediocre-go-lib v0.0.0-20181029021733-cb65787f37ed/go.mod h1:dSsfyI2zABAdhcbvkXqgxOxrCsbYeHCPgrZkku60dSg= github.com/mediocregopher/radix/v3 v3.3.0/go.mod h1:EmfVyvspXz1uZEyPBMyGK+kjWiKQGvsUt6O3Pj+LDCQ= github.com/mediocregopher/radix/v3 v3.4.2/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i4n7wVopoX3x7Bv8= @@ -772,6 +800,7 @@ github.com/neilotoole/errgroup v0.1.6/go.mod h1:Q2nLGf+594h0CLBs/Mbg6qOr7GtqDK7C 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= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= 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= @@ -784,10 +813,15 @@ github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108 github.com/onsi/ginkgo v1.13.0/go.mod h1:+REjRxOmWfHCjfv9TTWB1jD1Frx4XydAD3zm1lskyM0= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= +github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= +github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= +github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= github.com/onsi/gomega v1.20.0 h1:8W0cWlwFkflGPLltQvLRB7ZVD5HuP6ng320w2IS245Q= 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= @@ -824,6 +858,7 @@ github.com/peterh/liner v1.0.1-0.20180619022028-8c1271fcf47f/go.mod h1:xIteQHvHu 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/petermattis/goid v0.0.0-20221215004737-a150e88a970d/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= 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= @@ -851,6 +886,7 @@ github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqr github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= 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_golang v1.15.0/go.mod h1:e9yaBhRPU2pPNsZwE+JdQl0KEt1N9XgF6zxWmaC0xOk= 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= @@ -871,6 +907,7 @@ github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9 github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE= github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= +github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= @@ -881,6 +918,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/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= 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= @@ -905,6 +943,7 @@ github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/f 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/cors v1.8.3/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= 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= @@ -981,6 +1020,7 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5 github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= @@ -989,6 +1029,7 @@ github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8 github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= github.com/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.20220721030215-126854af5e6d/go.mod h1:RRCYJbIwD5jmqPI9XoAFR0OcDxqUctll6zUj/+B4S48= github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c h1:g+WoO5jjkqGAzHWCjJB1zZfXPIAaDpzXIEJ0eS6B5Ok= github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c/go.mod h1:ahpPrc7HpcfEWDQRZEmnXMzHY03mLDYMCxeDzy46i+8= github.com/tendermint/go-amino v0.16.0 h1:GyhmgQKvqF82e2oZeuMSp9JTN0N09emoSZlb2lyGa2E= @@ -997,6 +1038,7 @@ github.com/tendermint/tm-db v0.6.8-0.20220506192307-f628bb5dc95b h1:Y3ZPG6gdDCAV github.com/tendermint/tm-db v0.6.8-0.20220506192307-f628bb5dc95b/go.mod h1:ADqbS9NOSnBRK9R2RtYC61CdsHmVMD/yXAzcMuPexbU= github.com/tidwall/btree v1.5.0 h1:iV0yVY/frd7r6qGBXfEYs7DH0gTDgrKTrDjS7xt/IyQ= github.com/tidwall/btree v1.5.0/go.mod h1:LGm8L/DZjPLmeWGjv5kFrY8dL4uVhMmzmmLYmsObdKE= +github.com/tidwall/btree v1.6.0/go.mod h1:twD9XRA5jj9VUQGELzDO4HPQTNJsoWWfYEL+EUQ2cKY= 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= @@ -1053,6 +1095,7 @@ github.com/zondax/ledger-go v0.14.1/go.mod h1:fZ3Dqg6qcdXWSOJFKMG8GCTnD7slO/RL2f 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= +go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= @@ -1098,6 +1141,7 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.5.0 h1:U/0M97KRkSFvyD/3FSmdP5W5swImpNgle/EHFhOsQPE= golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU= +golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= 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= @@ -1115,6 +1159,7 @@ golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8H golang.org/x/exp v0.0.0-20200513190911-00229845015e/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= golang.org/x/exp v0.0.0-20230131160201-f062dba9d201 h1:BEABXpNXLEz0WxtA+6CQIz2xkg80e+1zrhWyMcq8VzE= golang.org/x/exp v0.0.0-20230131160201-f062dba9d201/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= +golang.org/x/exp v0.0.0-20230321023759-10a507213a29/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= 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= @@ -1190,6 +1235,7 @@ golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v 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-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= 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-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= @@ -1197,8 +1243,10 @@ golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qx 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-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= 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= @@ -1280,6 +1328,7 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210112080510-489259a85091/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-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1305,15 +1354,20 @@ golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/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-20220209214540-3681064d5158/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-20220520151302-bc2c85ada10a/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/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.7.0/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.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= +golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= 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= @@ -1325,14 +1379,17 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= 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-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 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-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181221001348-537d06c36207/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= @@ -1385,6 +1442,7 @@ golang.org/x/tools v0.0.0-20201022035929-9cf592e881e9/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= 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= @@ -1396,6 +1454,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/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= @@ -1479,6 +1538,7 @@ google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= google.golang.org/genproto v0.0.0-20230125152338-dcaf20b6aeaa h1:qQPhfbPO23fwm/9lQr91L1u62Zo6cm+zI+slZT+uf+o= google.golang.org/genproto v0.0.0-20230125152338-dcaf20b6aeaa/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230216225411-c8e22ba71e44/go.mod h1:8B0gmkoRebU8ukX6HP+4wrVQUY1+6PkQ44BSyIlflHA= 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= @@ -1496,6 +1556,7 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.29.1 h1:7QBf+IK2gx70Ap/hDsOmam3GE0v9HicjfEdAxE62UoM= google.golang.org/protobuf v1.29.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.30.0/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= diff --git a/tests/interchaintest/ibc_transfer_test.go b/tests/interchaintest/ibc_transfer_test.go index 6e6d6c5ab..696e51839 100644 --- a/tests/interchaintest/ibc_transfer_test.go +++ b/tests/interchaintest/ibc_transfer_test.go @@ -5,7 +5,7 @@ import ( "fmt" "testing" - transfertypes "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types" + transfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" "github.com/strangelove-ventures/interchaintest/v4" "github.com/strangelove-ventures/interchaintest/v4/chain/cosmos" "github.com/strangelove-ventures/interchaintest/v4/ibc" diff --git a/tests/interchaintest/setup.go b/tests/interchaintest/setup.go index 78647e53b..aa8726faa 100644 --- a/tests/interchaintest/setup.go +++ b/tests/interchaintest/setup.go @@ -1,8 +1,8 @@ package interchaintest import ( + simappparams "cosmossdk.io/simapp/params" feesharetypes "github.com/CosmosContracts/juno/v13/x/feeshare/types" - simappparams "github.com/cosmos/cosmos-sdk/simapp/params" "github.com/strangelove-ventures/interchaintest/v4/chain/cosmos" "github.com/strangelove-ventures/interchaintest/v4/ibc" ) From dd92574cc23af50317cc2f9c836c1b145edec6ed Mon Sep 17 00:00:00 2001 From: Jacob Gadikian Date: Mon, 24 Apr 2023 12:04:32 +0700 Subject: [PATCH 007/131] add global fee module to juno's repository directly --- app/keepers/keepers.go | 6 +- app/keepers/keys.go | 2 +- app/modules.go | 4 +- app/upgrades/v13/constants.go | 2 +- app/upgrades/v13/upgrades.go | 2 +- app/upgrades/v15/upgrades.go | 2 +- proto/gaia/globalfee/v1beta1/genesis.proto | 31 + proto/gaia/globalfee/v1beta1/query.proto | 32 + x/globalfee/README.md | 5 + x/globalfee/alias.go | 9 + x/globalfee/ante/antetest/fee_test.go | 748 ++++++++++++++++++ x/globalfee/ante/antetest/fee_test_setup.go | 128 +++ x/globalfee/ante/fee.go | 224 ++++++ x/globalfee/ante/fee_utils.go | 110 +++ x/globalfee/ante/fee_utils_test.go | 298 +++++++ x/globalfee/client/cli/query.go | 48 ++ x/globalfee/genesis_test.go | 129 +++ x/globalfee/module.go | 138 ++++ x/globalfee/querier.go | 37 + x/globalfee/querier_test.go | 56 ++ x/globalfee/types/genesis.go | 40 + x/globalfee/types/genesis.pb.go | 521 ++++++++++++ x/globalfee/types/keys.go | 8 + x/globalfee/types/params.go | 81 ++ x/globalfee/types/params_test.go | 73 ++ x/globalfee/types/query.pb.go | 553 +++++++++++++ x/globalfee/types/query.pb.gw.go | 153 ++++ x/tokenfactory/bindings/custom_msg_test.go | 6 +- x/tokenfactory/bindings/custom_query_test.go | 4 +- x/tokenfactory/bindings/helpers_test.go | 2 +- x/tokenfactory/bindings/message_plugin.go | 6 +- x/tokenfactory/bindings/queries.go | 4 +- x/tokenfactory/bindings/query_plugin.go | 2 +- x/tokenfactory/bindings/validate_msg_test.go | 6 +- .../bindings/validate_queries_test.go | 2 +- x/tokenfactory/bindings/wasm.go | 2 +- x/tokenfactory/client/cli/query.go | 2 +- x/tokenfactory/client/cli/tx.go | 2 +- x/tokenfactory/keeper/admins.go | 2 +- x/tokenfactory/keeper/admins_test.go | 2 +- x/tokenfactory/keeper/bankactions.go | 2 +- x/tokenfactory/keeper/createdenom.go | 2 +- x/tokenfactory/keeper/createdenom_test.go | 4 +- x/tokenfactory/keeper/genesis.go | 2 +- x/tokenfactory/keeper/genesis_test.go | 2 +- x/tokenfactory/keeper/grpc_query.go | 2 +- x/tokenfactory/keeper/keeper.go | 2 +- x/tokenfactory/keeper/keeper_test.go | 8 +- x/tokenfactory/keeper/msg_server.go | 2 +- x/tokenfactory/keeper/msg_server_test.go | 2 +- x/tokenfactory/keeper/params.go | 2 +- x/tokenfactory/module.go | 8 +- x/tokenfactory/simulation/genesis.go | 2 +- x/tokenfactory/simulation/operations.go | 4 +- x/tokenfactory/simulation/params.go | 2 +- x/tokenfactory/types/denoms_test.go | 2 +- x/tokenfactory/types/genesis_test.go | 2 +- x/tokenfactory/types/msgs_test.go | 4 +- 58 files changed, 3479 insertions(+), 57 deletions(-) create mode 100644 proto/gaia/globalfee/v1beta1/genesis.proto create mode 100644 proto/gaia/globalfee/v1beta1/query.proto create mode 100644 x/globalfee/README.md create mode 100644 x/globalfee/alias.go create mode 100644 x/globalfee/ante/antetest/fee_test.go create mode 100644 x/globalfee/ante/antetest/fee_test_setup.go create mode 100644 x/globalfee/ante/fee.go create mode 100644 x/globalfee/ante/fee_utils.go create mode 100644 x/globalfee/ante/fee_utils_test.go create mode 100644 x/globalfee/client/cli/query.go create mode 100644 x/globalfee/genesis_test.go create mode 100644 x/globalfee/module.go create mode 100644 x/globalfee/querier.go create mode 100644 x/globalfee/querier_test.go create mode 100644 x/globalfee/types/genesis.go create mode 100644 x/globalfee/types/genesis.pb.go create mode 100644 x/globalfee/types/keys.go create mode 100644 x/globalfee/types/params.go create mode 100644 x/globalfee/types/params_test.go create mode 100644 x/globalfee/types/query.pb.go create mode 100644 x/globalfee/types/query.pb.gw.go diff --git a/app/keepers/keepers.go b/app/keepers/keepers.go index 218820e0a..f654e4e46 100644 --- a/app/keepers/keepers.go +++ b/app/keepers/keepers.go @@ -61,9 +61,9 @@ import ( packetforwardkeeper "github.com/strangelove-ventures/packet-forward-middleware/v4/router/keeper" packetforwardtypes "github.com/strangelove-ventures/packet-forward-middleware/v4/router/types" - "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/bindings" - tokenfactorykeeper "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/keeper" - tokenfactorytypes "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/types" + "github.com/CosmosContracts/juno/x/tokenfactory/bindings" + tokenfactorykeeper "github.com/CosmosContracts/juno/x/tokenfactory/keeper" + tokenfactorytypes "github.com/CosmosContracts/juno/x/tokenfactory/types" icahost "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/host" icahostkeeper "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/host/keeper" diff --git a/app/keepers/keys.go b/app/keepers/keys.go index 556919793..aa19ea4b0 100644 --- a/app/keepers/keys.go +++ b/app/keepers/keys.go @@ -4,7 +4,7 @@ import ( "github.com/CosmWasm/wasmd/x/wasm" feesharetypes "github.com/CosmosContracts/juno/v15/x/feeshare/types" minttypes "github.com/CosmosContracts/juno/v15/x/mint/types" - tokenfactorytypes "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/types" + tokenfactorytypes "github.com/CosmosContracts/juno/x/tokenfactory/types" storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" diff --git a/app/modules.go b/app/modules.go index ace5074d7..629c36d13 100644 --- a/app/modules.go +++ b/app/modules.go @@ -7,8 +7,8 @@ import ( feesharetypes "github.com/CosmosContracts/juno/v15/x/feeshare/types" "github.com/CosmosContracts/juno/v15/x/mint" minttypes "github.com/CosmosContracts/juno/v15/x/mint/types" - "github.com/CosmosTokenFactory/token-factory/x/tokenfactory" - tokenfactorytypes "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/types" + "github.com/CosmosContracts/juno/x/tokenfactory" + tokenfactorytypes "github.com/CosmosContracts/juno/x/tokenfactory/types" "github.com/cosmos/cosmos-sdk/types/module" "github.com/cosmos/cosmos-sdk/x/auth" authsims "github.com/cosmos/cosmos-sdk/x/auth/simulation" diff --git a/app/upgrades/v13/constants.go b/app/upgrades/v13/constants.go index 4781e1138..6b1a845d8 100644 --- a/app/upgrades/v13/constants.go +++ b/app/upgrades/v13/constants.go @@ -3,7 +3,7 @@ package v13 import ( "github.com/CosmosContracts/juno/v15/app/upgrades" feesharetypes "github.com/CosmosContracts/juno/v15/x/feeshare/types" - tokenfactorytypes "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/types" + tokenfactorytypes "github.com/CosmosContracts/juno/x/tokenfactory/types" store "github.com/cosmos/cosmos-sdk/store/types" icacontrollertypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/types" ibcfeetypes "github.com/cosmos/ibc-go/v7/modules/apps/29-fee/types" diff --git a/app/upgrades/v13/upgrades.go b/app/upgrades/v13/upgrades.go index 5b11d82f9..b98802938 100644 --- a/app/upgrades/v13/upgrades.go +++ b/app/upgrades/v13/upgrades.go @@ -16,7 +16,7 @@ import ( // types feesharetypes "github.com/CosmosContracts/juno/v15/x/feeshare/types" - tokenfactorytypes "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/types" + tokenfactorytypes "github.com/CosmosContracts/juno/x/tokenfactory/types" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" ibcfeetypes "github.com/cosmos/ibc-go/v7/modules/apps/29-fee/types" diff --git a/app/upgrades/v15/upgrades.go b/app/upgrades/v15/upgrades.go index 1ada5a400..060978dfe 100644 --- a/app/upgrades/v15/upgrades.go +++ b/app/upgrades/v15/upgrades.go @@ -9,7 +9,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" - tokenfactorytypes "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/types" + tokenfactorytypes "github.com/CosmosContracts/juno/x/tokenfactory/types" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" ) diff --git a/proto/gaia/globalfee/v1beta1/genesis.proto b/proto/gaia/globalfee/v1beta1/genesis.proto new file mode 100644 index 000000000..39493b0c6 --- /dev/null +++ b/proto/gaia/globalfee/v1beta1/genesis.proto @@ -0,0 +1,31 @@ +syntax = "proto3"; +package gaia.globalfee.v1beta1; + +import "gogoproto/gogo.proto"; +import "cosmos/base/v1beta1/coin.proto"; + +option go_package = "github.com/cosmos/gaia/x/globalfee/types"; + +// GenesisState - initial state of module +message GenesisState { + // Params of this module + Params params = 1 [ + (gogoproto.nullable) = false, + (gogoproto.jsontag) = "params,omitempty" + ]; +} + +// Params defines the set of module parameters. +message Params { + // Minimum stores the minimum gas price(s) for all TX on the chain. + // When multiple coins are defined then they are accepted alternatively. + // The list must be sorted by denoms asc. No duplicate denoms or zero amount + // values allowed. For more information see + // https://docs.cosmos.network/main/modules/auth#concepts + repeated cosmos.base.v1beta1.DecCoin minimum_gas_prices = 1 [ + (gogoproto.nullable) = false, + (gogoproto.jsontag) = "minimum_gas_prices,omitempty", + (gogoproto.moretags) = "yaml:\"minimum_gas_prices\"", + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.DecCoins" + ]; +} diff --git a/proto/gaia/globalfee/v1beta1/query.proto b/proto/gaia/globalfee/v1beta1/query.proto new file mode 100644 index 000000000..81f587c5b --- /dev/null +++ b/proto/gaia/globalfee/v1beta1/query.proto @@ -0,0 +1,32 @@ +syntax = "proto3"; +package gaia.globalfee.v1beta1; + +import "gogoproto/gogo.proto"; +import "google/api/annotations.proto"; +import "cosmos/base/v1beta1/coin.proto"; + +option go_package = "github.com/cosmos/gaia/x/globalfee/types"; + +// Query defines the gRPC querier service. +service Query { + rpc MinimumGasPrices(QueryMinimumGasPricesRequest) + returns (QueryMinimumGasPricesResponse) { + option (google.api.http).get = + "/gaia/globalfee/v1beta1/minimum_gas_prices"; + } +} + +// QueryMinimumGasPricesRequest is the request type for the +// Query/MinimumGasPrices RPC method. +message QueryMinimumGasPricesRequest {} + +// QueryMinimumGasPricesResponse is the response type for the +// Query/MinimumGasPrices RPC method. +message QueryMinimumGasPricesResponse { + repeated cosmos.base.v1beta1.DecCoin minimum_gas_prices = 1 [ + (gogoproto.nullable) = false, + (gogoproto.jsontag) = "minimum_gas_prices,omitempty", + (gogoproto.moretags) = "yaml:\"minimum_gas_prices\"", + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.DecCoins" + ]; +} diff --git a/x/globalfee/README.md b/x/globalfee/README.md new file mode 100644 index 000000000..746d5c142 --- /dev/null +++ b/x/globalfee/README.md @@ -0,0 +1,5 @@ +# Global fee module + +The Global fee module was supplied by the great folks at [TGrade](https://github.com/confio/tgrade) 👋, with minor modifications. All credits and big thanks go to the original authors. + +More information about Cosmoshub fee system please check [here](../../docs/modules/globalfee.md). diff --git a/x/globalfee/alias.go b/x/globalfee/alias.go new file mode 100644 index 000000000..74e59e386 --- /dev/null +++ b/x/globalfee/alias.go @@ -0,0 +1,9 @@ +package globalfee + +import ( + "github.com/cosmos/gaia/v9/x/globalfee/types" +) + +const ( + ModuleName = types.ModuleName +) diff --git a/x/globalfee/ante/antetest/fee_test.go b/x/globalfee/ante/antetest/fee_test.go new file mode 100644 index 000000000..cf144b1f6 --- /dev/null +++ b/x/globalfee/ante/antetest/fee_test.go @@ -0,0 +1,748 @@ +package antetest + +import ( + "testing" + + cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" + "github.com/cosmos/cosmos-sdk/testutil/testdata" + sdk "github.com/cosmos/cosmos-sdk/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + ibcclienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" + ibcchanneltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" + "github.com/stretchr/testify/suite" + + gaiafeeante "github.com/cosmos/gaia/v9/x/globalfee/ante" + globfeetypes "github.com/cosmos/gaia/v9/x/globalfee/types" +) + +var testGasLimit uint64 = 200_000 + +func TestIntegrationTestSuite(t *testing.T) { + suite.Run(t, new(IntegrationTestSuite)) +} + +func (s *IntegrationTestSuite) TestGetDefaultGlobalFees() { + // set globalfees and min gas price + feeDecorator, _ := s.SetupTestGlobalFeeStoreAndMinGasPrice([]sdk.DecCoin{}, &globfeetypes.Params{}) + + defaultGlobalFees, err := feeDecorator.DefaultZeroGlobalFee(s.ctx) + s.Require().NoError(err) + s.Require().Greater(len(defaultGlobalFees), 0) + + if defaultGlobalFees[0].Denom != testBondDenom { + s.T().Fatalf("bond denom: %s, default global fee denom: %s", testBondDenom, defaultGlobalFees[0].Denom) + } +} + +// Test global fees and min_gas_price with bypass msg types. +// Please note even globalfee=0, min_gas_price=0, we do not let fee=0random_denom pass. +// Paid fees are already sanitized by removing zero coins(through feeFlag parsing), so use sdk.NewCoins() to create it. +func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { + s.txBuilder = s.clientCtx.TxConfig.NewTxBuilder() + priv1, _, addr1 := testdata.KeyTestPubAddr() + privs, accNums, accSeqs := []cryptotypes.PrivKey{priv1}, []uint64{0}, []uint64{0} + + denominator := int64(100000) + high := sdk.NewDec(400).Quo(sdk.NewDec(denominator)) // 0.004 + med := sdk.NewDec(200).Quo(sdk.NewDec(denominator)) // 0.002 + low := sdk.NewDec(100).Quo(sdk.NewDec(denominator)) // 0.001 + + highFeeAmt := sdk.NewInt(high.MulInt64(int64(2) * denominator).RoundInt64()) + medFeeAmt := sdk.NewInt(med.MulInt64(int64(2) * denominator).RoundInt64()) + lowFeeAmt := sdk.NewInt(low.MulInt64(int64(2) * denominator).RoundInt64()) + + globalfeeParamsEmpty := &globfeetypes.Params{MinimumGasPrices: []sdk.DecCoin{}} + minGasPriceEmpty := []sdk.DecCoin{} + globalfeeParams0 := &globfeetypes.Params{MinimumGasPrices: []sdk.DecCoin{ + sdk.NewDecCoinFromDec("photon", sdk.NewDec(0)), + sdk.NewDecCoinFromDec("uatom", sdk.NewDec(0)), + }} + globalfeeParamsContain0 := &globfeetypes.Params{MinimumGasPrices: []sdk.DecCoin{ + sdk.NewDecCoinFromDec("photon", med), + sdk.NewDecCoinFromDec("uatom", sdk.NewDec(0)), + }} + minGasPrice0 := []sdk.DecCoin{ + sdk.NewDecCoinFromDec("stake", sdk.NewDec(0)), + sdk.NewDecCoinFromDec("uatom", sdk.NewDec(0)), + } + globalfeeParamsHigh := &globfeetypes.Params{ + MinimumGasPrices: []sdk.DecCoin{ + sdk.NewDecCoinFromDec("uatom", high), + }, + } + minGasPrice := []sdk.DecCoin{ + sdk.NewDecCoinFromDec("uatom", med), + sdk.NewDecCoinFromDec("stake", med), + } + globalfeeParamsLow := &globfeetypes.Params{ + MinimumGasPrices: []sdk.DecCoin{ + sdk.NewDecCoinFromDec("uatom", low), + }, + } + // global fee must be sorted in denom + globalfeeParamsNewDenom := &globfeetypes.Params{ + MinimumGasPrices: []sdk.DecCoin{ + sdk.NewDecCoinFromDec("photon", high), + sdk.NewDecCoinFromDec("quark", high), + }, + } + testCases := map[string]struct { + minGasPrice []sdk.DecCoin + globalFeeParams *globfeetypes.Params + gasPrice sdk.Coins + gasLimit sdk.Gas + txMsg sdk.Msg + txCheck bool + expErr bool + }{ + // test fees + // empty min_gas_price or empty global fee + "empty min_gas_price, nonempty global fee, fee higher/equal than global_fee": { + minGasPrice: minGasPriceEmpty, + globalFeeParams: globalfeeParamsHigh, + gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", highFeeAmt)), + gasLimit: testdata.NewTestGasLimit(), + txMsg: testdata.NewTestMsg(addr1), + txCheck: true, + expErr: false, + }, + "empty min_gas_price, nonempty global fee, fee lower than global_fee": { + minGasPrice: minGasPriceEmpty, + globalFeeParams: globalfeeParamsHigh, + gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", lowFeeAmt)), + gasLimit: testdata.NewTestGasLimit(), + txMsg: testdata.NewTestMsg(addr1), + txCheck: true, + expErr: true, + }, + "nonempty min_gas_price with defaultGlobalFee denom, empty global fee, fee higher/equal than min_gas_price": { + minGasPrice: minGasPrice, + globalFeeParams: globalfeeParamsEmpty, // default 0uatom + gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", medFeeAmt)), + gasLimit: testdata.NewTestGasLimit(), + txMsg: testdata.NewTestMsg(addr1), + txCheck: true, + expErr: false, + }, + "nonempty min_gas_price with defaultGlobalFee denom, empty global fee, fee lower than min_gas_price": { + minGasPrice: minGasPrice, + globalFeeParams: globalfeeParamsEmpty, + gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", lowFeeAmt)), + gasLimit: testdata.NewTestGasLimit(), + txMsg: testdata.NewTestMsg(addr1), + txCheck: true, + expErr: true, + }, + "empty min_gas_price, empty global fee, empty fee": { + minGasPrice: minGasPriceEmpty, + globalFeeParams: globalfeeParamsEmpty, + gasPrice: sdk.Coins{}, + gasLimit: testdata.NewTestGasLimit(), + txMsg: testdata.NewTestMsg(addr1), + txCheck: true, + expErr: false, + }, + // zero min_gas_price or zero global fee + "zero min_gas_price, zero global fee, zero fee in global fee denom": { + minGasPrice: minGasPrice0, + globalFeeParams: globalfeeParams0, + gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", sdk.ZeroInt()), sdk.NewCoin("photon", sdk.ZeroInt())), + gasLimit: testdata.NewTestGasLimit(), + txMsg: testdata.NewTestMsg(addr1), + txCheck: true, + expErr: false, + }, + "zero min_gas_price, zero global fee, empty fee": { + minGasPrice: minGasPrice0, + globalFeeParams: globalfeeParams0, + gasPrice: sdk.Coins{}, + gasLimit: testdata.NewTestGasLimit(), + txMsg: testdata.NewTestMsg(addr1), + txCheck: true, + expErr: false, + }, + // zero global fee + "zero min_gas_price, zero global fee, zero fee not in globalfee denom": { + minGasPrice: minGasPrice0, + globalFeeParams: globalfeeParams0, + gasPrice: sdk.NewCoins(sdk.NewCoin("stake", sdk.ZeroInt())), + gasLimit: testdata.NewTestGasLimit(), + txMsg: testdata.NewTestMsg(addr1), + txCheck: true, + expErr: false, + }, + "zero min_gas_price, zero global fee, zero fees one in, one not in globalfee denom": { + minGasPrice: minGasPrice0, + globalFeeParams: globalfeeParams0, + gasPrice: sdk.NewCoins( + sdk.NewCoin("stake", sdk.ZeroInt()), + sdk.NewCoin("uatom", sdk.ZeroInt())), + gasLimit: testdata.NewTestGasLimit(), + txMsg: testdata.NewTestMsg(addr1), + txCheck: true, + expErr: false, + }, + // zero min_gas_price and empty global fee + "zero min_gas_price, empty global fee, zero fee in min_gas_price_denom": { + minGasPrice: minGasPrice0, + globalFeeParams: globalfeeParamsEmpty, + gasPrice: sdk.NewCoins(sdk.NewCoin("stake", sdk.ZeroInt())), + gasLimit: testdata.NewTestGasLimit(), + txMsg: testdata.NewTestMsg(addr1), + txCheck: true, + expErr: false, + }, + "zero min_gas_price, empty global fee, zero fee not in min_gas_price denom, not in defaultZeroGlobalFee denom": { + minGasPrice: minGasPrice0, + globalFeeParams: globalfeeParamsEmpty, + gasPrice: sdk.NewCoins(sdk.NewCoin("quark", sdk.ZeroInt())), + gasLimit: testdata.NewTestGasLimit(), + txMsg: testdata.NewTestMsg(addr1), + txCheck: true, + expErr: false, + }, + "zero min_gas_price, empty global fee, zero fee in defaultZeroGlobalFee denom": { + minGasPrice: minGasPrice0, + globalFeeParams: globalfeeParamsEmpty, + gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", sdk.ZeroInt())), + gasLimit: testGasLimit, + txMsg: testdata.NewTestMsg(addr1), + txCheck: true, + expErr: false, + }, + "zero min_gas_price, empty global fee, nonzero fee in defaultZeroGlobalFee denom": { + minGasPrice: minGasPrice0, + globalFeeParams: globalfeeParamsEmpty, + gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", lowFeeAmt)), + gasLimit: testGasLimit, + txMsg: testdata.NewTestMsg(addr1), + txCheck: true, + expErr: false, + }, + "zero min_gas_price, empty global fee, nonzero fee not in defaultZeroGlobalFee denom": { + minGasPrice: minGasPrice0, + globalFeeParams: globalfeeParamsEmpty, + gasPrice: sdk.NewCoins(sdk.NewCoin("quark", highFeeAmt)), + gasLimit: testGasLimit, + txMsg: testdata.NewTestMsg(addr1), + txCheck: true, + expErr: true, + }, + // empty min_gas_price, zero global fee + "empty min_gas_price, zero global fee, zero fee in global fee denom": { + minGasPrice: minGasPriceEmpty, + globalFeeParams: globalfeeParams0, + gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", sdk.ZeroInt())), + gasLimit: testGasLimit, + txMsg: testdata.NewTestMsg(addr1), + txCheck: true, + expErr: false, + }, + "empty min_gas_price, zero global fee, zero fee not in global fee denom": { + minGasPrice: minGasPriceEmpty, + globalFeeParams: globalfeeParams0, + gasPrice: sdk.NewCoins(sdk.NewCoin("stake", sdk.ZeroInt())), + gasLimit: testGasLimit, + txMsg: testdata.NewTestMsg(addr1), + txCheck: true, + expErr: false, + }, + "empty min_gas_price, zero global fee, nonzero fee in global fee denom": { + minGasPrice: minGasPriceEmpty, + globalFeeParams: globalfeeParams0, + gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", lowFeeAmt)), + gasLimit: testGasLimit, + txMsg: testdata.NewTestMsg(addr1), + txCheck: true, + expErr: false, + }, + "empty min_gas_price, zero global fee, nonzero fee not in global fee denom": { + minGasPrice: minGasPriceEmpty, + globalFeeParams: globalfeeParams0, + gasPrice: sdk.NewCoins(sdk.NewCoin("stake", highFeeAmt)), + gasLimit: testGasLimit, + txMsg: testdata.NewTestMsg(addr1), + txCheck: true, + expErr: true, + }, + // zero min_gas_price, nonzero global fee + "zero min_gas_price, nonzero global fee, fee is higher than global fee": { + minGasPrice: minGasPrice0, + globalFeeParams: globalfeeParamsLow, + gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", lowFeeAmt)), + gasLimit: testGasLimit, + txMsg: testdata.NewTestMsg(addr1), + txCheck: true, + expErr: false, + }, + // nonzero min_gas_price, nonzero global fee + "fee higher/equal than globalfee and min_gas_price": { + minGasPrice: minGasPrice, + globalFeeParams: globalfeeParamsHigh, + gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", highFeeAmt)), + gasLimit: testGasLimit, + txMsg: testdata.NewTestMsg(addr1), + txCheck: true, + expErr: false, + }, + "fee lower than globalfee and min_gas_price": { + minGasPrice: minGasPrice, + globalFeeParams: globalfeeParamsHigh, + gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", lowFeeAmt)), + gasLimit: testGasLimit, + txMsg: testdata.NewTestMsg(addr1), + txCheck: true, + expErr: true, + }, + "fee with one denom higher/equal, one denom lower than globalfee and min_gas_price": { + minGasPrice: minGasPrice, + globalFeeParams: globalfeeParamsNewDenom, + gasPrice: sdk.NewCoins( + sdk.NewCoin("photon", lowFeeAmt), + sdk.NewCoin("quark", highFeeAmt)), + gasLimit: testGasLimit, + txMsg: testdata.NewTestMsg(addr1), + txCheck: true, + expErr: false, + }, + "globalfee > min_gas_price, fee higher/equal than min_gas_price, lower than globalfee": { + minGasPrice: minGasPrice, + globalFeeParams: globalfeeParamsHigh, + gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", medFeeAmt)), + gasLimit: testGasLimit, + txMsg: testdata.NewTestMsg(addr1), + txCheck: true, + expErr: true, + }, + "globalfee < min_gas_price, fee higher/equal than globalfee and lower than min_gas_price": { + minGasPrice: minGasPrice, + globalFeeParams: globalfeeParamsLow, + gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", lowFeeAmt)), + gasLimit: testGasLimit, + txMsg: testdata.NewTestMsg(addr1), + txCheck: true, + expErr: true, + }, + // nonzero min_gas_price, zero global fee + "nonzero min_gas_price, zero global fee, fee is in global fee denom and lower than min_gas_price": { + minGasPrice: minGasPrice, + globalFeeParams: globalfeeParams0, + gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", lowFeeAmt)), + gasLimit: testGasLimit, + txMsg: testdata.NewTestMsg(addr1), + txCheck: true, + expErr: true, + }, + "nonzero min_gas_price, zero global fee, fee is in global fee denom and higher/equal than min_gas_price": { + minGasPrice: minGasPrice, + globalFeeParams: globalfeeParams0, + gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", medFeeAmt)), + gasLimit: testGasLimit, + txMsg: testdata.NewTestMsg(addr1), + txCheck: true, + expErr: false, + }, + "nonzero min_gas_price, zero global fee, fee is in min_gas_price denom which is not in global fee default, but higher/equal than min_gas_price": { + minGasPrice: minGasPrice, + globalFeeParams: globalfeeParams0, + gasPrice: sdk.NewCoins(sdk.NewCoin("stake", highFeeAmt)), + gasLimit: testGasLimit, + txMsg: testdata.NewTestMsg(addr1), + txCheck: true, + expErr: true, + }, + // fee denom tests + "min_gas_price denom is not subset of global fee denom , fee paying in global fee denom": { + minGasPrice: minGasPrice, + globalFeeParams: globalfeeParamsNewDenom, + gasPrice: sdk.NewCoins(sdk.NewCoin("photon", highFeeAmt)), + gasLimit: testGasLimit, + txMsg: testdata.NewTestMsg(addr1), + txCheck: true, + expErr: false, + }, + "min_gas_price denom is not subset of global fee denom, fee paying in min_gas_price denom": { + minGasPrice: minGasPrice, + globalFeeParams: globalfeeParamsNewDenom, + gasPrice: sdk.NewCoins(sdk.NewCoin("stake", highFeeAmt)), + gasLimit: testGasLimit, + txMsg: testdata.NewTestMsg(addr1), + txCheck: true, + expErr: true, + }, + "fees contain denom not in globalfee": { + minGasPrice: minGasPrice, + globalFeeParams: globalfeeParamsLow, + gasPrice: sdk.NewCoins( + sdk.NewCoin("uatom", highFeeAmt), + sdk.NewCoin("quark", highFeeAmt)), + gasLimit: testGasLimit, + txMsg: testdata.NewTestMsg(addr1), + txCheck: true, + expErr: true, + }, + "fees contain denom not in globalfee with zero amount": { + minGasPrice: minGasPrice, + globalFeeParams: globalfeeParamsLow, + gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", highFeeAmt), + sdk.NewCoin("quark", sdk.ZeroInt())), + gasLimit: testGasLimit, + txMsg: testdata.NewTestMsg(addr1), + txCheck: true, + expErr: false, + }, + // cases from https://github.com/cosmos/gaia/pull/1570#issuecomment-1190524402 + // note: this is kind of a silly scenario but technically correct + // if there is a zero coin in the globalfee, the user could pay 0fees + // if the user includes any fee at all in the non-zero denom, it must be higher than that non-zero fee + // unlikely we will ever see zero and non-zero together but technically possible + "globalfee contains zero coin and non-zero coin, fee is lower than the nonzero coin": { + minGasPrice: minGasPrice0, + globalFeeParams: globalfeeParamsContain0, + gasPrice: sdk.NewCoins(sdk.NewCoin("photon", lowFeeAmt)), + gasLimit: testGasLimit, + txMsg: testdata.NewTestMsg(addr1), + txCheck: true, + expErr: true, + }, + "globalfee contains zero coin, fee contains zero coins of the same denom and a lower fee of the other denom in global fee": { + minGasPrice: minGasPrice0, + globalFeeParams: globalfeeParamsContain0, + gasPrice: sdk.NewCoins( + sdk.NewCoin("photon", lowFeeAmt), + sdk.NewCoin("uatom", sdk.ZeroInt())), + gasLimit: testGasLimit, + txMsg: testdata.NewTestMsg(addr1), + txCheck: true, + expErr: true, + }, + "globalfee contains zero coin, fee is empty": { + minGasPrice: minGasPrice0, + globalFeeParams: globalfeeParamsContain0, + gasPrice: sdk.Coins{}, + gasLimit: testGasLimit, + txMsg: testdata.NewTestMsg(addr1), + txCheck: true, + expErr: false, + }, + "globalfee contains zero coin, fee contains lower fee of zero coins's denom, globalfee also contains nonzero coin,fee contains higher fee of nonzero coins's denom, ": { + minGasPrice: minGasPrice0, + globalFeeParams: globalfeeParamsContain0, + gasPrice: sdk.NewCoins( + sdk.NewCoin("photon", lowFeeAmt), + sdk.NewCoin("uatom", highFeeAmt)), + gasLimit: testGasLimit, + txMsg: testdata.NewTestMsg(addr1), + txCheck: true, + expErr: false, + }, + "globalfee contains zero coin, fee is all zero coins but in global fee's denom": { + minGasPrice: minGasPrice0, + globalFeeParams: globalfeeParamsContain0, + gasPrice: sdk.NewCoins( + sdk.NewCoin("photon", sdk.ZeroInt()), + sdk.NewCoin("uatom", sdk.ZeroInt()), + ), + gasLimit: testGasLimit, + txMsg: testdata.NewTestMsg(addr1), + txCheck: true, + expErr: false, + }, + "globalfee contains zero coin, fee is higher than the nonzero coin": { + minGasPrice: minGasPrice0, + globalFeeParams: globalfeeParamsContain0, + gasPrice: sdk.NewCoins(sdk.NewCoin("photon", highFeeAmt)), + gasLimit: testGasLimit, + txMsg: testdata.NewTestMsg(addr1), + txCheck: true, + expErr: false, + }, + "bypass msg type: ibc.core.channel.v1.MsgRecvPacket": { + minGasPrice: minGasPrice, + globalFeeParams: globalfeeParamsLow, + gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", sdk.ZeroInt())), + gasLimit: testGasLimit, + txMsg: ibcchanneltypes.NewMsgRecvPacket( + ibcchanneltypes.Packet{}, nil, ibcclienttypes.Height{}, ""), + txCheck: true, + expErr: false, + }, + "bypass msg type: ibc.core.channel.v1.MsgTimeout": { + minGasPrice: minGasPrice, + globalFeeParams: globalfeeParamsLow, + gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", sdk.ZeroInt())), + gasLimit: testGasLimit, + txMsg: ibcchanneltypes.NewMsgTimeout( + ibcchanneltypes.Packet{}, 1, nil, ibcclienttypes.Height{}, ""), + txCheck: true, + expErr: false, + }, + "bypass msg type: ibc.core.channel.v1.MsgTimeoutOnClose": { + minGasPrice: minGasPrice, + globalFeeParams: globalfeeParamsLow, + gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", sdk.ZeroInt())), + gasLimit: testGasLimit, + txMsg: ibcchanneltypes.NewMsgTimeout( + ibcchanneltypes.Packet{}, 2, nil, ibcclienttypes.Height{}, ""), + txCheck: true, + expErr: false, + }, + "bypass msg gas usage exceeds maxTotalBypassMinFeeMsgGasUsage": { + minGasPrice: minGasPrice, + globalFeeParams: globalfeeParamsLow, + gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", sdk.ZeroInt())), + gasLimit: 2 * testMaxTotalBypassMinFeeMsgGasUsage, + txMsg: ibcchanneltypes.NewMsgTimeout( + ibcchanneltypes.Packet{}, 2, nil, ibcclienttypes.Height{}, ""), + txCheck: true, + expErr: true, + }, + "bypass msg gas usage equals to maxTotalBypassMinFeeMsgGasUsage": { + minGasPrice: minGasPrice, + globalFeeParams: globalfeeParamsLow, + gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", sdk.ZeroInt())), + gasLimit: testGasLimit, + txMsg: ibcchanneltypes.NewMsgTimeout( + ibcchanneltypes.Packet{}, 3, nil, ibcclienttypes.Height{}, ""), + txCheck: true, + expErr: false, + }, + "msg type ibc, zero fee not in globalfee denom": { + minGasPrice: minGasPrice, + globalFeeParams: globalfeeParamsLow, + gasPrice: sdk.NewCoins(sdk.NewCoin("photon", sdk.ZeroInt())), + gasLimit: testGasLimit, + txMsg: ibcchanneltypes.NewMsgRecvPacket( + ibcchanneltypes.Packet{}, nil, ibcclienttypes.Height{}, ""), + txCheck: true, + expErr: false, + }, + "msg type ibc, nonzero fee in globalfee denom": { + minGasPrice: minGasPrice, + globalFeeParams: globalfeeParamsLow, + gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", highFeeAmt)), + gasLimit: testGasLimit, + txMsg: ibcchanneltypes.NewMsgRecvPacket( + ibcchanneltypes.Packet{}, nil, ibcclienttypes.Height{}, ""), + txCheck: true, + expErr: false, + }, + "msg type ibc, nonzero fee not in globalfee denom": { + minGasPrice: minGasPrice, + globalFeeParams: globalfeeParamsLow, + gasPrice: sdk.NewCoins(sdk.NewCoin("photon", highFeeAmt)), + gasLimit: testGasLimit, + txMsg: ibcchanneltypes.NewMsgRecvPacket( + ibcchanneltypes.Packet{}, nil, ibcclienttypes.Height{}, ""), + txCheck: true, + expErr: true, + }, + "msg type ibc, empty fee": { + minGasPrice: minGasPrice, + globalFeeParams: globalfeeParamsLow, + gasPrice: sdk.Coins{}, + gasLimit: testGasLimit, + txMsg: ibcchanneltypes.NewMsgRecvPacket( + ibcchanneltypes.Packet{}, nil, ibcclienttypes.Height{}, ""), + txCheck: true, + expErr: false, + }, + "msg type non-ibc, nonzero fee in globalfee denom": { + minGasPrice: minGasPrice, + globalFeeParams: globalfeeParamsLow, + gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", highFeeAmt)), + gasLimit: testGasLimit, + txMsg: testdata.NewTestMsg(addr1), + txCheck: true, + expErr: false, + }, + "msg type non-ibc, empty fee": { + minGasPrice: minGasPrice, + globalFeeParams: globalfeeParamsLow, + gasPrice: sdk.Coins{}, + gasLimit: testGasLimit, + txMsg: testdata.NewTestMsg(addr1), + txCheck: true, + expErr: true, + }, + "msg type non-ibc, nonzero fee not in globalfee denom": { + minGasPrice: minGasPrice, + globalFeeParams: globalfeeParamsLow, + gasPrice: sdk.NewCoins(sdk.NewCoin("photon", highFeeAmt)), + gasLimit: testGasLimit, + txMsg: testdata.NewTestMsg(addr1), + txCheck: true, + expErr: true, + }, + "disable checkTx: no fee check. min_gas_price is low, global fee is low, tx fee is zero": { + minGasPrice: minGasPrice, + globalFeeParams: globalfeeParamsLow, + gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", sdk.ZeroInt())), + gasLimit: testGasLimit, + txMsg: testdata.NewTestMsg(addr1), + txCheck: false, + expErr: false, + }, + "disable checkTx: no fee check. min_gas_price is low, global fee is low, tx fee's denom is not in global fees denoms set": { + minGasPrice: minGasPrice, + globalFeeParams: globalfeeParamsLow, + gasPrice: sdk.NewCoins(sdk.NewCoin("quark", sdk.ZeroInt())), + gasLimit: testGasLimit, + txMsg: testdata.NewTestMsg(addr1), + txCheck: false, + expErr: false, + }, + } + for name, tc := range testCases { + s.Run(name, func() { + // set globalfees and min gas price + _, antehandler := s.SetupTestGlobalFeeStoreAndMinGasPrice(tc.minGasPrice, tc.globalFeeParams) + + // set fee decorator to ante handler + + s.Require().NoError(s.txBuilder.SetMsgs(tc.txMsg)) + s.txBuilder.SetFeeAmount(tc.gasPrice) + s.txBuilder.SetGasLimit(tc.gasLimit) + tx, err := s.CreateTestTx(privs, accNums, accSeqs, s.ctx.ChainID()) + s.Require().NoError(err) + + s.ctx = s.ctx.WithIsCheckTx(tc.txCheck) + _, err = antehandler(s.ctx, tx, false) + if !tc.expErr { + s.Require().NoError(err) + } else { + s.Require().Error(err) + } + }) + } +} + +// Test how the operator fees are determined using various min gas prices. +// +// Note that in a real Gaia deployment all zero coins can be removed from minGasPrice. +// This sanitizing happens when the minGasPrice is set into the context. +// (see baseapp.SetMinGasPrices in gaia/cmd/root.go line 221) +func (s *IntegrationTestSuite) TestGetMinGasPrice() { + expCoins := sdk.Coins{ + sdk.NewCoin("photon", sdk.NewInt(2000)), + sdk.NewCoin("uatom", sdk.NewInt(3000)), + } + + testCases := []struct { + name string + minGasPrice []sdk.DecCoin + feeTxGasLimit uint64 + expCoins sdk.Coins + }{ + { + "empty min gas price should return empty coins", + []sdk.DecCoin{}, + uint64(1000), + sdk.Coins{}, + }, + { + "zero coins min gas price should return empty coins", + []sdk.DecCoin{ + sdk.NewDecCoinFromDec("stake", sdk.NewDec(0)), + sdk.NewDecCoinFromDec("uatom", sdk.NewDec(0)), + }, + uint64(1000), + sdk.Coins{}, + }, + { + "zero coins, non-zero coins mix should return zero coin and non-zero coins", + []sdk.DecCoin{ + sdk.NewDecCoinFromDec("stake", sdk.NewDec(0)), + sdk.NewDecCoinFromDec("uatom", sdk.NewDec(1)), + }, + uint64(1000), + sdk.Coins{ + sdk.NewCoin("stake", sdk.NewInt(0)), + sdk.NewCoin("uatom", sdk.NewInt(1000)), + }, + }, + + { + "unsorted min gas price should return sorted coins", + []sdk.DecCoin{ + sdk.NewDecCoinFromDec("uatom", sdk.NewDec(3)), + sdk.NewDecCoinFromDec("photon", sdk.NewDec(2)), + }, + uint64(1000), + expCoins, + }, + { + "sorted min gas price should return same conins", + []sdk.DecCoin{ + sdk.NewDecCoinFromDec("photon", sdk.NewDec(2)), + sdk.NewDecCoinFromDec("uatom", sdk.NewDec(3)), + }, + uint64(1000), + expCoins, + }, + } + + for _, tc := range testCases { + s.Run(tc.name, func() { + s.SetupTestGlobalFeeStoreAndMinGasPrice(tc.minGasPrice, &globfeetypes.Params{}) + + fees := gaiafeeante.GetMinGasPrice(s.ctx, int64(tc.feeTxGasLimit)) + s.Require().True(tc.expCoins.Sort().IsEqual(fees)) + }) + } +} + +func (s *IntegrationTestSuite) TestContainsOnlyBypassMinFeeMsgs() { + // set globalfees and min gas price + feeDecorator, _ := s.SetupTestGlobalFeeStoreAndMinGasPrice([]sdk.DecCoin{}, &globfeetypes.Params{}) + + testCases := []struct { + name string + msgs []sdk.Msg + expPass bool + }{ + { + "expect empty msgs to pass", + []sdk.Msg{}, + true, + }, + { + "expect default bypass msg to pass", + []sdk.Msg{ + ibcchanneltypes.NewMsgRecvPacket(ibcchanneltypes.Packet{}, nil, ibcclienttypes.Height{}, ""), + ibcchanneltypes.NewMsgAcknowledgement(ibcchanneltypes.Packet{}, []byte{1}, []byte{1}, ibcclienttypes.Height{}, ""), + }, + true, + }, + { + "expect default bypass msgs to pass", + []sdk.Msg{ + ibcchanneltypes.NewMsgRecvPacket(ibcchanneltypes.Packet{}, nil, ibcclienttypes.Height{}, ""), + ibcchanneltypes.NewMsgAcknowledgement(ibcchanneltypes.Packet{}, []byte{1}, []byte{1}, ibcclienttypes.Height{}, ""), + }, + true, + }, + { + "msgs contain non-bypass msg - should not pass", + []sdk.Msg{ + ibcchanneltypes.NewMsgRecvPacket(ibcchanneltypes.Packet{}, nil, ibcclienttypes.Height{}, ""), + stakingtypes.NewMsgDelegate(sdk.AccAddress{}, sdk.ValAddress{}, sdk.Coin{}), + }, + false, + }, + { + "msgs contain only non-bypass msgs - should not pass", + []sdk.Msg{ + stakingtypes.NewMsgDelegate(sdk.AccAddress{}, sdk.ValAddress{}, sdk.Coin{}), + }, + false, + }, + } + + for _, tc := range testCases { + s.Run(tc.name, func() { + res := feeDecorator.ContainsOnlyBypassMinFeeMsgs(tc.msgs) + s.Require().True(tc.expPass == res) + }) + } +} diff --git a/x/globalfee/ante/antetest/fee_test_setup.go b/x/globalfee/ante/antetest/fee_test_setup.go new file mode 100644 index 000000000..c1508126a --- /dev/null +++ b/x/globalfee/ante/antetest/fee_test_setup.go @@ -0,0 +1,128 @@ +package antetest + +import ( + "fmt" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/tx" + cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" + "github.com/cosmos/cosmos-sdk/testutil/testdata" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/tx/signing" + xauthsigning "github.com/cosmos/cosmos-sdk/x/auth/signing" + "github.com/cosmos/cosmos-sdk/x/params/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + "github.com/stretchr/testify/suite" + tmrand "github.com/tendermint/tendermint/libs/rand" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + + gaiahelpers "github.com/cosmos/gaia/v9/app/helpers" + gaiafeeante "github.com/cosmos/gaia/v9/x/globalfee/ante" + + gaiaapp "github.com/cosmos/gaia/v9/app" + "github.com/cosmos/gaia/v9/x/globalfee" + globfeetypes "github.com/cosmos/gaia/v9/x/globalfee/types" +) + +type IntegrationTestSuite struct { + suite.Suite + + app *gaiaapp.GaiaApp + ctx sdk.Context + clientCtx client.Context + txBuilder client.TxBuilder +} + +var ( + testBondDenom = "uatom" + testMaxTotalBypassMinFeeMsgGasUsage uint64 = 1_000_000 +) + +func (s *IntegrationTestSuite) SetupTest() { + app := gaiahelpers.Setup(s.T()) + ctx := app.BaseApp.NewContext(false, tmproto.Header{ + ChainID: fmt.Sprintf("test-chain-%s", tmrand.Str(4)), + Height: 1, + }) + + encodingConfig := gaiaapp.MakeTestEncodingConfig() + encodingConfig.Amino.RegisterConcrete(&testdata.TestMsg{}, "testdata.TestMsg", nil) + testdata.RegisterInterfaces(encodingConfig.InterfaceRegistry) + + s.app = app + s.ctx = ctx + s.clientCtx = client.Context{}.WithTxConfig(encodingConfig.TxConfig) +} + +func (s *IntegrationTestSuite) SetupTestGlobalFeeStoreAndMinGasPrice(minGasPrice []sdk.DecCoin, globalFeeParams *globfeetypes.Params) (gaiafeeante.FeeDecorator, sdk.AnteHandler) { + subspace := s.app.GetSubspace(globalfee.ModuleName) + subspace.SetParamSet(s.ctx, globalFeeParams) + s.ctx = s.ctx.WithMinGasPrices(minGasPrice).WithIsCheckTx(true) + + // set staking params + stakingParam := stakingtypes.DefaultParams() + stakingParam.BondDenom = testBondDenom + stakingSubspace := s.SetupTestStakingSubspace(stakingParam) + + // build fee decorator + feeDecorator := gaiafeeante.NewFeeDecorator(gaiaapp.GetDefaultBypassFeeMessages(), subspace, stakingSubspace, uint64(1_000_000)) + + // chain fee decorator to antehandler + antehandler := sdk.ChainAnteDecorators(feeDecorator) + + return feeDecorator, antehandler +} + +// SetupTestStakingSubspace sets uatom as bond denom for the fee tests. +func (s *IntegrationTestSuite) SetupTestStakingSubspace(params stakingtypes.Params) types.Subspace { + s.app.GetSubspace(stakingtypes.ModuleName).SetParamSet(s.ctx, ¶ms) + return s.app.GetSubspace(stakingtypes.ModuleName) +} + +func (s *IntegrationTestSuite) CreateTestTx(privs []cryptotypes.PrivKey, accNums []uint64, accSeqs []uint64, chainID string) (xauthsigning.Tx, error) { + var sigsV2 []signing.SignatureV2 + for i, priv := range privs { + sigV2 := signing.SignatureV2{ + PubKey: priv.PubKey(), + Data: &signing.SingleSignatureData{ + SignMode: s.clientCtx.TxConfig.SignModeHandler().DefaultMode(), + Signature: nil, + }, + Sequence: accSeqs[i], + } + + sigsV2 = append(sigsV2, sigV2) + } + + if err := s.txBuilder.SetSignatures(sigsV2...); err != nil { + return nil, err + } + + sigsV2 = []signing.SignatureV2{} + for i, priv := range privs { + signerData := xauthsigning.SignerData{ + ChainID: chainID, + AccountNumber: accNums[i], + Sequence: accSeqs[i], + } + sigV2, err := tx.SignWithPrivKey( + s.clientCtx.TxConfig.SignModeHandler().DefaultMode(), + signerData, + s.txBuilder, + priv, + s.clientCtx.TxConfig, + accSeqs[i], + ) + if err != nil { + return nil, err + } + + sigsV2 = append(sigsV2, sigV2) + } + + if err := s.txBuilder.SetSignatures(sigsV2...); err != nil { + return nil, err + } + + return s.txBuilder.GetTx(), nil +} diff --git a/x/globalfee/ante/fee.go b/x/globalfee/ante/fee.go new file mode 100644 index 000000000..909fac4a7 --- /dev/null +++ b/x/globalfee/ante/fee.go @@ -0,0 +1,224 @@ +package ante + +import ( + "errors" + + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + tmstrings "github.com/tendermint/tendermint/libs/strings" + + "github.com/cosmos/gaia/v9/x/globalfee" + "github.com/cosmos/gaia/v9/x/globalfee/types" +) + +// FeeWithBypassDecorator checks if the transaction's fee is at least as large +// as the local validator's minimum gasFee (defined in validator config) and global fee, and the fee denom should be in the global fees' denoms. +// +// If fee is too low, decorator returns error and tx is rejected from mempool. +// Note this only applies when ctx.CheckTx = true. If fee is high enough or not +// CheckTx, then call next AnteHandler. +// +// CONTRACT: Tx must implement FeeTx to use FeeDecorator +// If the tx msg type is one of the bypass msg types, the tx is valid even if the min fee is lower than normally required. +// If the bypass tx still carries fees, the fee denom should be the same as global fee required. + +var _ sdk.AnteDecorator = FeeDecorator{} + +type FeeDecorator struct { + BypassMinFeeMsgTypes []string + GlobalMinFee globalfee.ParamSource + StakingSubspace paramtypes.Subspace + MaxTotalBypassMinFeeMsgGasUsage uint64 +} + +func NewFeeDecorator(bypassMsgTypes []string, globalfeeSubspace, stakingSubspace paramtypes.Subspace, maxTotalBypassMinFeeMsgGasUsage uint64) FeeDecorator { + if !globalfeeSubspace.HasKeyTable() { + panic("global fee paramspace was not set up via module") + } + + if !stakingSubspace.HasKeyTable() { + panic("staking paramspace was not set up via module") + } + + return FeeDecorator{ + BypassMinFeeMsgTypes: bypassMsgTypes, + GlobalMinFee: globalfeeSubspace, + StakingSubspace: stakingSubspace, + MaxTotalBypassMinFeeMsgGasUsage: maxTotalBypassMinFeeMsgGasUsage, + } +} + +// AnteHandle implements the AnteDecorator interface +func (mfd FeeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) { + feeTx, ok := tx.(sdk.FeeTx) + if !ok { + return ctx, sdkerrors.Wrap(sdkerrors.ErrTxDecode, "Tx must implement the sdk.FeeTx interface") + } + + // Only check for minimum fees and global fee if the execution mode is CheckTx + if !ctx.IsCheckTx() || simulate { + return next(ctx, tx, simulate) + } + + // Sort fee tx's coins, zero coins in feeCoins are already removed + feeCoins := feeTx.GetFee().Sort() + gas := feeTx.GetGas() + msgs := feeTx.GetMsgs() + + // Get required Global Fee + requiredGlobalFees, err := mfd.GetGlobalFee(ctx, feeTx) + if err != nil { + return ctx, err + } + + // Get local minimum-gas-prices + localFees := GetMinGasPrice(ctx, int64(feeTx.GetGas())) + + // CombinedFeeRequirement should never be empty since + // global fee is set to its default value, i.e. 0uatom, if empty + combinedFeeRequirement := CombinedFeeRequirement(requiredGlobalFees, localFees) + if len(combinedFeeRequirement) == 0 { + return ctx, sdkerrors.Wrapf(sdkerrors.ErrNotFound, "required fees are not setup.") + } + + nonZeroCoinFeesReq, zeroCoinFeesDenomReq := getNonZeroFees(combinedFeeRequirement) + + // feeCoinsNonZeroDenom contains non-zero denominations from the combinedFeeRequirement + // + // feeCoinsNoZeroDenom is used to check if the fees meets the requirement imposed by nonZeroCoinFeesReq + // when feeCoins does not contain zero coins' denoms in combinedFeeRequirement + feeCoinsNonZeroDenom, feeCoinsZeroDenom := splitCoinsByDenoms(feeCoins, zeroCoinFeesDenomReq) + + // Check that the fees are in expected denominations. + // if feeCoinsNoZeroDenom=[], DenomsSubsetOf returns true + // if feeCoinsNoZeroDenom is not empty, but nonZeroCoinFeesReq empty, return false + if !feeCoinsNonZeroDenom.DenomsSubsetOf(nonZeroCoinFeesReq) { + return ctx, sdkerrors.Wrapf(sdkerrors.ErrInsufficientFee, "fee is not a subset of required fees; got %s, required: %s", feeCoins, combinedFeeRequirement) + } + + // Accept zero fee transactions only if both of the following statements are true: + // + // - the tx contains only message types that can bypass the minimum fee, + // see BypassMinFeeMsgTypes; + // - the total gas limit per message does not exceed MaxTotalBypassMinFeeMsgGasUsage, + // i.e., totalGas <= MaxTotalBypassMinFeeMsgGasUsage + // + // Otherwise, minimum fees and global fees are checked to prevent spam. + doesNotExceedMaxGasUsage := gas <= mfd.MaxTotalBypassMinFeeMsgGasUsage + allowedToBypassMinFee := mfd.ContainsOnlyBypassMinFeeMsgs(msgs) && doesNotExceedMaxGasUsage + + // Either the transaction contains at least one message of a type + // that cannot bypass the minimum fee or the total gas limit exceeds + // the imposed threshold. As a result, besides check the fees are in + // expected denominations, check the amounts are greater or equal than + // the expected amounts. + + // only check feeCoinsNoZeroDenom has coins IsAnyGTE than nonZeroCoinFeesReq + // when feeCoins does not contain denoms of zero denoms in combinedFeeRequirement + if !allowedToBypassMinFee && len(feeCoinsZeroDenom) == 0 { + // special case: when feeCoins=[] and there is zero coin in fee requirement + if len(feeCoins) == 0 && len(zeroCoinFeesDenomReq) != 0 { + return next(ctx, tx, simulate) + } + + // Check that the amounts of the fees are greater or equal than + // the expected amounts, i.e., at least one feeCoin amount must + // be greater or equal to one of the combined required fees. + + // if feeCoinsNoZeroDenom=[], return false + // if nonZeroCoinFeesReq=[], return false (this situation should not happen + // because when nonZeroCoinFeesReq empty, and DenomsSubsetOf check passed, + // the tx should already passed before) + if !feeCoinsNonZeroDenom.IsAnyGTE(nonZeroCoinFeesReq) { + return ctx, sdkerrors.Wrapf(sdkerrors.ErrInsufficientFee, "insufficient fees; got: %s required: %s", feeCoins, combinedFeeRequirement) + } + } + + return next(ctx, tx, simulate) +} + +// GetGlobalFee returns the global fees for a given fee tx's gas +// (might also return 0denom if globalMinGasPrice is 0) +// sorted in ascending order. +// Note that ParamStoreKeyMinGasPrices type requires coins sorted. +func (mfd FeeDecorator) GetGlobalFee(ctx sdk.Context, feeTx sdk.FeeTx) (sdk.Coins, error) { + var ( + globalMinGasPrices sdk.DecCoins + err error + ) + + if mfd.GlobalMinFee.Has(ctx, types.ParamStoreKeyMinGasPrices) { + mfd.GlobalMinFee.Get(ctx, types.ParamStoreKeyMinGasPrices, &globalMinGasPrices) + } + // global fee is empty set, set global fee to 0uatom + if len(globalMinGasPrices) == 0 { + globalMinGasPrices, err = mfd.DefaultZeroGlobalFee(ctx) + if err != nil { + return sdk.Coins{}, err + } + } + requiredGlobalFees := make(sdk.Coins, len(globalMinGasPrices)) + // Determine the required fees by multiplying each required minimum gas + // price by the gas limit, where fee = ceil(minGasPrice * gasLimit). + glDec := sdk.NewDec(int64(feeTx.GetGas())) + for i, gp := range globalMinGasPrices { + fee := gp.Amount.Mul(glDec) + requiredGlobalFees[i] = sdk.NewCoin(gp.Denom, fee.Ceil().RoundInt()) + } + + return requiredGlobalFees.Sort(), nil +} + +func (mfd FeeDecorator) DefaultZeroGlobalFee(ctx sdk.Context) ([]sdk.DecCoin, error) { + bondDenom := mfd.getBondDenom(ctx) + if bondDenom == "" { + return nil, errors.New("empty staking bond denomination") + } + + return []sdk.DecCoin{sdk.NewDecCoinFromDec(bondDenom, sdk.NewDec(0))}, nil +} + +func (mfd FeeDecorator) getBondDenom(ctx sdk.Context) string { + var bondDenom string + if mfd.StakingSubspace.Has(ctx, stakingtypes.KeyBondDenom) { + mfd.StakingSubspace.Get(ctx, stakingtypes.KeyBondDenom, &bondDenom) + } + + return bondDenom +} + +// ContainsOnlyBypassMinFeeMsgs returns true if all the given msgs type are listed +// in the BypassMinFeeMsgTypes of the FeeDecorator. +func (mfd FeeDecorator) ContainsOnlyBypassMinFeeMsgs(msgs []sdk.Msg) bool { + for _, msg := range msgs { + if tmstrings.StringInSlice(sdk.MsgTypeURL(msg), mfd.BypassMinFeeMsgTypes) { + continue + } + return false + } + + return true +} + +// GetMinGasPrice returns the validator's minimum gas prices +// fees given a gas limit +func GetMinGasPrice(ctx sdk.Context, gasLimit int64) sdk.Coins { + minGasPrices := ctx.MinGasPrices() + // special case: if minGasPrices=[], requiredFees=[] + if minGasPrices.IsZero() { + return sdk.Coins{} + } + + requiredFees := make(sdk.Coins, len(minGasPrices)) + // Determine the required fees by multiplying each required minimum gas + // price by the gas limit, where fee = ceil(minGasPrice * gasLimit). + glDec := sdk.NewDec(gasLimit) + for i, gp := range minGasPrices { + fee := gp.Amount.Mul(glDec) + requiredFees[i] = sdk.NewCoin(gp.Denom, fee.Ceil().RoundInt()) + } + + return requiredFees.Sort() +} diff --git a/x/globalfee/ante/fee_utils.go b/x/globalfee/ante/fee_utils.go new file mode 100644 index 000000000..b3d5e2c8e --- /dev/null +++ b/x/globalfee/ante/fee_utils.go @@ -0,0 +1,110 @@ +package ante + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// ContainZeroCoins returns true if the given coins are empty or contain zero coins, +// Note that the coins denoms must be validated, see sdk.ValidateDenom +func ContainZeroCoins(coins sdk.Coins) bool { + if len(coins) == 0 { + return true + } + for _, coin := range coins { + if coin.IsZero() { + return true + } + } + + return false +} + +// CombinedFeeRequirement returns the global fee and min_gas_price combined and sorted. +// Both globalFees and minGasPrices must be valid, but CombinedFeeRequirement +// does not validate them, so it may return 0denom. +// if globalfee is empty, CombinedFeeRequirement return sdk.Coins{} +func CombinedFeeRequirement(globalFees, minGasPrices sdk.Coins) sdk.Coins { + // empty min_gas_price + if len(minGasPrices) == 0 { + return globalFees + } + // empty global fee is not possible if we set default global fee + if len(globalFees) == 0 && len(minGasPrices) != 0 { + return sdk.Coins{} + } + + // if min_gas_price denom is in globalfee, and the amount is higher than globalfee, add min_gas_price to allFees + var allFees sdk.Coins + for _, fee := range globalFees { + // min_gas_price denom in global fee + ok, c := Find(minGasPrices, fee.Denom) + if ok && c.Amount.GT(fee.Amount) { + allFees = append(allFees, c) + } else { + allFees = append(allFees, fee) + } + } + + return allFees.Sort() +} + +// Find replaces the functionality of Coins.Find from SDK v0.46.x +func Find(coins sdk.Coins, denom string) (bool, sdk.Coin) { + switch len(coins) { + case 0: + return false, sdk.Coin{} + + case 1: + coin := coins[0] + if coin.Denom == denom { + return true, coin + } + return false, sdk.Coin{} + + default: + midIdx := len(coins) / 2 // 2:1, 3:1, 4:2 + coin := coins[midIdx] + switch { + case denom < coin.Denom: + return Find(coins[:midIdx], denom) + case denom == coin.Denom: + return true, coin + default: + return Find(coins[midIdx+1:], denom) + } + } +} + +// splitCoinsByDenoms returns the given coins split in two whether +// their demon is or isn't found in the given denom map. +func splitCoinsByDenoms(feeCoins sdk.Coins, denomMap map[string]bool) (sdk.Coins, sdk.Coins) { + feeCoinsNonZeroDenom, feeCoinsZeroDenom := sdk.Coins{}, sdk.Coins{} + + for _, fc := range feeCoins { + _, found := denomMap[fc.Denom] + if found { + feeCoinsZeroDenom = append(feeCoinsZeroDenom, fc) + } else { + feeCoinsNonZeroDenom = append(feeCoinsNonZeroDenom, fc) + } + } + + return feeCoinsNonZeroDenom.Sort(), feeCoinsZeroDenom.Sort() +} + +// getNonZeroFees returns the given fees nonzero coins +// and a map storing the zero coins's denoms +func getNonZeroFees(fees sdk.Coins) (sdk.Coins, map[string]bool) { + requiredFeesNonZero := sdk.Coins{} + requiredFeesZeroDenom := map[string]bool{} + + for _, gf := range fees { + if gf.IsZero() { + requiredFeesZeroDenom[gf.Denom] = true + } else { + requiredFeesNonZero = append(requiredFeesNonZero, gf) + } + } + + return requiredFeesNonZero.Sort(), requiredFeesZeroDenom +} diff --git a/x/globalfee/ante/fee_utils_test.go b/x/globalfee/ante/fee_utils_test.go new file mode 100644 index 000000000..9a702c52e --- /dev/null +++ b/x/globalfee/ante/fee_utils_test.go @@ -0,0 +1,298 @@ +package ante + +import ( + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/require" +) + +func TestContainZeroCoins(t *testing.T) { + zeroCoin1 := sdk.NewCoin("photon", sdk.ZeroInt()) + zeroCoin2 := sdk.NewCoin("stake", sdk.ZeroInt()) + coin1 := sdk.NewCoin("photon", sdk.NewInt(1)) + coin2 := sdk.NewCoin("stake", sdk.NewInt(2)) + coin3 := sdk.NewCoin("quark", sdk.NewInt(3)) + // coins must be valid !!! + coinsEmpty := sdk.Coins{} + coinsNonEmpty := sdk.Coins{coin1, coin2} + coinsCointainZero := sdk.Coins{coin1, zeroCoin2} + coinsCointainTwoZero := sdk.Coins{zeroCoin1, zeroCoin2, coin3} + coinsAllZero := sdk.Coins{zeroCoin1, zeroCoin2} + + tests := []struct { + c sdk.Coins + ok bool + }{ + { + coinsEmpty, + true, + }, + { + coinsNonEmpty, + false, + }, + { + coinsCointainZero, + true, + }, + { + coinsCointainTwoZero, + true, + }, + { + coinsAllZero, + true, + }, + } + + for _, test := range tests { + ok := ContainZeroCoins(test.c) + require.Equal(t, test.ok, ok) + } +} + +// Note that in a real Gaia deployment all zero coins can be removed from minGasPrice. +// This sanitizing happens when the minGasPrice is set into the context. +// (see baseapp.SetMinGasPrices in gaia/cmd/root.go line 221) +func TestCombinedFeeRequirement(t *testing.T) { + zeroCoin1 := sdk.NewCoin("photon", sdk.ZeroInt()) + zeroCoin2 := sdk.NewCoin("stake", sdk.ZeroInt()) + zeroCoin3 := sdk.NewCoin("quark", sdk.ZeroInt()) + coin1 := sdk.NewCoin("photon", sdk.NewInt(1)) + coin2 := sdk.NewCoin("stake", sdk.NewInt(2)) + coin1High := sdk.NewCoin("photon", sdk.NewInt(10)) + coin2High := sdk.NewCoin("stake", sdk.NewInt(20)) + coinNewDenom1 := sdk.NewCoin("Newphoton", sdk.NewInt(1)) + coinNewDenom2 := sdk.NewCoin("Newstake", sdk.NewInt(1)) + // coins must be valid !!! and sorted!!! + coinsEmpty := sdk.Coins{} + coinsNonEmpty := sdk.Coins{coin1, coin2}.Sort() + coinsNonEmptyHigh := sdk.Coins{coin1High, coin2High}.Sort() + coinsNonEmptyOneHigh := sdk.Coins{coin1High, coin2}.Sort() + coinsNewDenom := sdk.Coins{coinNewDenom1, coinNewDenom2}.Sort() + coinsNewOldDenom := sdk.Coins{coin1, coinNewDenom1}.Sort() + coinsNewOldDenomHigh := sdk.Coins{coin1High, coinNewDenom1}.Sort() + coinsCointainZero := sdk.Coins{coin1, zeroCoin2}.Sort() + coinsCointainZeroNewDenom := sdk.Coins{coin1, zeroCoin3}.Sort() + coinsAllZero := sdk.Coins{zeroCoin1, zeroCoin2}.Sort() + tests := map[string]struct { + cGlobal sdk.Coins + c sdk.Coins + combined sdk.Coins + }{ + "global fee empty, min fee empty, combined fee empty": { + cGlobal: coinsEmpty, + c: coinsEmpty, + combined: coinsEmpty, + }, + "global fee empty, min fee nonempty, combined fee empty": { + cGlobal: coinsEmpty, + c: coinsNonEmpty, + combined: coinsEmpty, + }, + "global fee nonempty, min fee empty, combined fee = global fee": { + cGlobal: coinsNonEmpty, + c: coinsNonEmpty, + combined: coinsNonEmpty, + }, + "global fee and min fee have overlapping denom, min fees amounts are all higher": { + cGlobal: coinsNonEmpty, + c: coinsNonEmptyHigh, + combined: coinsNonEmptyHigh, + }, + "global fee and min fee have overlapping denom, one of min fees amounts is higher": { + cGlobal: coinsNonEmpty, + c: coinsNonEmptyOneHigh, + combined: coinsNonEmptyOneHigh, + }, + "global fee and min fee have no overlapping denom, combined fee = global fee": { + cGlobal: coinsNonEmpty, + c: coinsNewDenom, + combined: coinsNonEmpty, + }, + "global fees and min fees have partial overlapping denom, min fee amount <= global fee amount, combined fees = global fees": { + cGlobal: coinsNonEmpty, + c: coinsNewOldDenom, + combined: coinsNonEmpty, + }, + "global fees and min fees have partial overlapping denom, one min fee amount > global fee amount, combined fee = overlapping highest": { + cGlobal: coinsNonEmpty, + c: coinsNewOldDenomHigh, + combined: sdk.Coins{coin1High, coin2}, + }, + "global fees have zero fees, min fees have overlapping non-zero fees, combined fees = overlapping highest": { + cGlobal: coinsCointainZero, + c: coinsNonEmpty, + combined: sdk.Coins{coin1, coin2}, + }, + "global fees have zero fees, min fees have overlapping zero fees": { + cGlobal: coinsCointainZero, + c: coinsCointainZero, + combined: coinsCointainZero, + }, + "global fees have zero fees, min fees have non-overlapping zero fees": { + cGlobal: coinsCointainZero, + c: coinsCointainZeroNewDenom, + combined: coinsCointainZero, + }, + "global fees are all zero fees, min fees have overlapping zero fees": { + cGlobal: coinsAllZero, + c: coinsAllZero, + combined: coinsAllZero, + }, + "global fees are all zero fees, min fees have overlapping non-zero fees, combined fee = overlapping highest": { + cGlobal: coinsAllZero, + c: coinsCointainZeroNewDenom, + combined: sdk.Coins{coin1, zeroCoin2}, + }, + "global fees are all zero fees, fees have one overlapping non-zero fee": { + cGlobal: coinsAllZero, + c: coinsCointainZero, + combined: coinsCointainZero, + }, + } + + for name, test := range tests { + t.Run(name, func(t *testing.T) { + allFees := CombinedFeeRequirement(test.cGlobal, test.c) + require.Equal(t, test.combined, allFees) + }) + } +} + +func TestSplitCoinsByDenoms(t *testing.T) { + zeroGlobalFeesDenom0 := map[string]bool{} + zeroGlobalFeesDenom1 := map[string]bool{ + "uatom": true, + "photon": true, + } + zeroGlobalFeesDenom2 := map[string]bool{ + "uatom": true, + } + zeroGlobalFeesDenom3 := map[string]bool{ + "stake": true, + } + + photon := sdk.NewCoin("photon", sdk.OneInt()) + uatom := sdk.NewCoin("uatom", sdk.OneInt()) + feeCoins := sdk.NewCoins(photon, uatom) + + tests := map[string]struct { + feeCoins sdk.Coins + zeroGlobalFeesDenom map[string]bool + expectedNonZeroCoins sdk.Coins + expectedZeroCoins sdk.Coins + }{ + "no zero coins in global fees": { + feeCoins: feeCoins, + zeroGlobalFeesDenom: zeroGlobalFeesDenom0, + expectedNonZeroCoins: feeCoins, + expectedZeroCoins: sdk.Coins{}, + }, + "no split of fee coins": { + feeCoins: feeCoins, + zeroGlobalFeesDenom: zeroGlobalFeesDenom3, + expectedNonZeroCoins: feeCoins, + expectedZeroCoins: sdk.Coins{}, + }, + "split the fee coins": { + feeCoins: feeCoins, + zeroGlobalFeesDenom: zeroGlobalFeesDenom2, + expectedNonZeroCoins: sdk.NewCoins(photon), + expectedZeroCoins: sdk.NewCoins(uatom), + }, + "remove all of the fee coins": { + feeCoins: feeCoins, + zeroGlobalFeesDenom: zeroGlobalFeesDenom1, + expectedNonZeroCoins: sdk.Coins{}, + expectedZeroCoins: feeCoins, + }, + "fee coins are empty": { + feeCoins: sdk.Coins{}, + zeroGlobalFeesDenom: zeroGlobalFeesDenom1, + expectedNonZeroCoins: sdk.Coins{}, + expectedZeroCoins: sdk.Coins{}, + }, + } + + for name, test := range tests { + t.Run(name, func(t *testing.T) { + feeCoinsNoZeroDenoms, feeCoinsZeroDenoms := splitCoinsByDenoms(test.feeCoins, test.zeroGlobalFeesDenom) + require.Equal(t, test.expectedNonZeroCoins, feeCoinsNoZeroDenoms) + require.Equal(t, test.expectedZeroCoins, feeCoinsZeroDenoms) + }) + } +} + +func TestSplitGlobalFees(t *testing.T) { + photon0 := sdk.NewCoin("photon", sdk.ZeroInt()) + uatom0 := sdk.NewCoin("uatom", sdk.ZeroInt()) + photon1 := sdk.NewCoin("photon", sdk.OneInt()) + uatom1 := sdk.NewCoin("uatom", sdk.OneInt()) + + globalFeesEmpty := sdk.Coins{} + globalFees := sdk.Coins{photon1, uatom1}.Sort() + globalFeesZeroCoins := sdk.Coins{photon0, uatom0}.Sort() + globalFeesMix := sdk.Coins{photon0, uatom1}.Sort() + + tests := map[string]struct { + globalfees sdk.Coins + zeroGlobalFeesDenom map[string]bool + globalfeesNonZero sdk.Coins + }{ + "empty global fees": { + globalfees: globalFeesEmpty, + zeroGlobalFeesDenom: map[string]bool{}, + globalfeesNonZero: sdk.Coins{}, + }, + "nonzero coins global fees": { + globalfees: globalFees, + zeroGlobalFeesDenom: map[string]bool{}, + globalfeesNonZero: globalFees, + }, + "zero coins global fees": { + globalfees: globalFeesZeroCoins, + zeroGlobalFeesDenom: map[string]bool{ + "photon": true, + "uatom": true, + }, + globalfeesNonZero: sdk.Coins{}, + }, + "mix zero, nonzero coins global fees": { + globalfees: globalFeesMix, + zeroGlobalFeesDenom: map[string]bool{ + "photon": true, + }, + globalfeesNonZero: sdk.NewCoins(uatom1), + }, + } + + for name, test := range tests { + t.Run(name, func(t *testing.T) { + nonZeroCoins, zeroCoinsMap := getNonZeroFees(test.globalfees) + require.True(t, nonZeroCoins.IsEqual(test.globalfeesNonZero)) + require.True(t, equalMap(zeroCoinsMap, test.zeroGlobalFeesDenom)) + }) + } +} + +func equalMap(a, b map[string]bool) bool { + if len(a) != len(b) { + return false + } + if len(a) == 0 && len(b) == 0 { + return true + } + if len(a) == 0 { + return false + } + + for k := range a { + if _, ok := b[k]; !ok { + return false + } + } + + return true +} diff --git a/x/globalfee/client/cli/query.go b/x/globalfee/client/cli/query.go new file mode 100644 index 000000000..be6894a9d --- /dev/null +++ b/x/globalfee/client/cli/query.go @@ -0,0 +1,48 @@ +package cli + +import ( + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/spf13/cobra" + + "github.com/cosmos/gaia/v9/x/globalfee/types" +) + +func GetQueryCmd() *cobra.Command { + queryCmd := &cobra.Command{ + Use: types.ModuleName, + Short: "Querying commands for the global fee module", + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + RunE: client.ValidateCmd, + } + queryCmd.AddCommand( + GetCmdShowMinimumGasPrices(), + ) + return queryCmd +} + +func GetCmdShowMinimumGasPrices() *cobra.Command { + cmd := &cobra.Command{ + Use: "minimum-gas-prices", + Short: "Show minimum gas prices", + Long: "Show all minimum gas prices", + Aliases: []string{"min"}, + Args: cobra.ExactArgs(0), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + + queryClient := types.NewQueryClient(clientCtx) + res, err := queryClient.MinimumGasPrices(cmd.Context(), &types.QueryMinimumGasPricesRequest{}) + if err != nil { + return err + } + return clientCtx.PrintProto(res) + }, + } + flags.AddQueryFlagsToCmd(cmd) + return cmd +} diff --git a/x/globalfee/genesis_test.go b/x/globalfee/genesis_test.go new file mode 100644 index 000000000..02f90ce53 --- /dev/null +++ b/x/globalfee/genesis_test.go @@ -0,0 +1,129 @@ +package globalfee + +import ( + "testing" + "time" + + "github.com/cosmos/cosmos-sdk/simapp" + simappparams "github.com/cosmos/cosmos-sdk/simapp/params" + "github.com/cosmos/cosmos-sdk/store" + storetypes "github.com/cosmos/cosmos-sdk/store/types" + sdk "github.com/cosmos/cosmos-sdk/types" + paramskeeper "github.com/cosmos/cosmos-sdk/x/params/keeper" + paramstypes "github.com/cosmos/cosmos-sdk/x/params/types" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/tendermint/tendermint/libs/log" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + dbm "github.com/tendermint/tm-db" + + "github.com/cosmos/gaia/v9/x/globalfee/types" +) + +func TestDefaultGenesis(t *testing.T) { + encCfg := simapp.MakeTestEncodingConfig() + gotJSON := AppModuleBasic{}.DefaultGenesis(encCfg.Marshaler) + assert.JSONEq(t, `{"params":{"minimum_gas_prices":[]}}`, string(gotJSON), string(gotJSON)) +} + +func TestValidateGenesis(t *testing.T) { + encCfg := simapp.MakeTestEncodingConfig() + specs := map[string]struct { + src string + expErr bool + }{ + "all good": { + src: `{"params":{"minimum_gas_prices":[{"denom":"ALX", "amount":"1"}]}}`, + }, + "empty minimum": { + src: `{"params":{"minimum_gas_prices":[]}}`, + }, + "minimum not set": { + src: `{"params":{}}`, + }, + "zero amount allowed": { + src: `{"params":{"minimum_gas_prices":[{"denom":"ALX", "amount":"0"}]}}`, + expErr: false, + }, + "duplicate denoms not allowed": { + src: `{"params":{"minimum_gas_prices":[{"denom":"ALX", "amount":"1"},{"denom":"ALX", "amount":"2"}]}}`, + expErr: true, + }, + "negative amounts not allowed": { + src: `{"params":{"minimum_gas_prices":[{"denom":"ALX", "amount":"-1"}]}}`, + expErr: true, + }, + "denom must be sorted": { + src: `{"params":{"minimum_gas_prices":[{"denom":"ZLX", "amount":"1"},{"denom":"ALX", "amount":"2"}]}}`, + expErr: true, + }, + "sorted denoms is allowed": { + src: `{"params":{"minimum_gas_prices":[{"denom":"ALX", "amount":"1"},{"denom":"ZLX", "amount":"2"}]}}`, + expErr: false, + }, + } + for name, spec := range specs { + t.Run(name, func(t *testing.T) { + gotErr := AppModuleBasic{}.ValidateGenesis(encCfg.Marshaler, nil, []byte(spec.src)) + if spec.expErr { + require.Error(t, gotErr) + return + } + require.NoError(t, gotErr) + }) + } +} + +func TestInitExportGenesis(t *testing.T) { + specs := map[string]struct { + src string + exp types.GenesisState + }{ + "single fee": { + src: `{"params":{"minimum_gas_prices":[{"denom":"ALX", "amount":"1"}]}}`, + exp: types.GenesisState{Params: types.Params{MinimumGasPrices: sdk.NewDecCoins(sdk.NewDecCoin("ALX", sdk.NewInt(1)))}}, + }, + "multiple fee options": { + src: `{"params":{"minimum_gas_prices":[{"denom":"ALX", "amount":"1"}, {"denom":"BLX", "amount":"0.001"}]}}`, + exp: types.GenesisState{Params: types.Params{MinimumGasPrices: sdk.NewDecCoins(sdk.NewDecCoin("ALX", sdk.NewInt(1)), + sdk.NewDecCoinFromDec("BLX", sdk.NewDecWithPrec(1, 3)))}}, + }, + "no fee set": { + src: `{"params":{}}`, + exp: types.GenesisState{Params: types.Params{MinimumGasPrices: sdk.DecCoins{}}}, + }, + } + for name, spec := range specs { + t.Run(name, func(t *testing.T) { + ctx, encCfg, subspace := setupTestStore(t) + m := NewAppModule(subspace) + m.InitGenesis(ctx, encCfg.Marshaler, []byte(spec.src)) + gotJSON := m.ExportGenesis(ctx, encCfg.Marshaler) + var got types.GenesisState + require.NoError(t, encCfg.Marshaler.UnmarshalJSON(gotJSON, &got)) + assert.Equal(t, spec.exp, got, string(gotJSON)) + }) + } +} + +func setupTestStore(t *testing.T) (sdk.Context, simappparams.EncodingConfig, paramstypes.Subspace) { + t.Helper() + db := dbm.NewMemDB() + ms := store.NewCommitMultiStore(db) + encCfg := simapp.MakeTestEncodingConfig() + keyParams := sdk.NewKVStoreKey(paramstypes.StoreKey) + tkeyParams := sdk.NewTransientStoreKey(paramstypes.TStoreKey) + ms.MountStoreWithDB(keyParams, storetypes.StoreTypeIAVL, db) + ms.MountStoreWithDB(tkeyParams, storetypes.StoreTypeTransient, db) + require.NoError(t, ms.LoadLatestVersion()) + + paramsKeeper := paramskeeper.NewKeeper(encCfg.Marshaler, encCfg.Amino, keyParams, tkeyParams) + + ctx := sdk.NewContext(ms, tmproto.Header{ + Height: 1234567, + Time: time.Date(2020, time.April, 22, 12, 0, 0, 0, time.UTC), + }, false, log.NewNopLogger()) + + subspace := paramsKeeper.Subspace(ModuleName).WithKeyTable(types.ParamKeyTable()) + return ctx, encCfg, subspace +} diff --git a/x/globalfee/module.go b/x/globalfee/module.go new file mode 100644 index 000000000..d2cf91c0f --- /dev/null +++ b/x/globalfee/module.go @@ -0,0 +1,138 @@ +package globalfee + +import ( + "context" + "encoding/json" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/codec" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/cosmos-sdk/types/module" + paramstypes "github.com/cosmos/cosmos-sdk/x/params/types" + "github.com/gorilla/mux" + "github.com/grpc-ecosystem/grpc-gateway/runtime" + "github.com/spf13/cobra" + abci "github.com/tendermint/tendermint/abci/types" + + "github.com/cosmos/gaia/v9/x/globalfee/client/cli" + "github.com/cosmos/gaia/v9/x/globalfee/types" +) + +var ( + _ module.AppModuleBasic = AppModuleBasic{} + _ module.AppModuleGenesis = AppModule{} + _ module.AppModule = AppModule{} +) + +// AppModuleBasic defines the basic application module used by the wasm module. +type AppModuleBasic struct{} + +func (a AppModuleBasic) Name() string { + return types.ModuleName +} + +func (a AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage { + return cdc.MustMarshalJSON(&types.GenesisState{ + Params: types.DefaultParams(), + }) +} + +func (a AppModuleBasic) ValidateGenesis(marshaler codec.JSONCodec, _ client.TxEncodingConfig, message json.RawMessage) error { + var data types.GenesisState + err := marshaler.UnmarshalJSON(message, &data) + if err != nil { + return err + } + if err := data.Params.ValidateBasic(); err != nil { + return sdkerrors.Wrap(err, "params") + } + return nil +} + +func (a AppModuleBasic) RegisterInterfaces(_ codectypes.InterfaceRegistry) { +} + +func (a AppModuleBasic) RegisterRESTRoutes(_ client.Context, _ *mux.Router) { +} + +func (a AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) { + err := types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(clientCtx)) + if err != nil { + // same behavior as in cosmos-sdk + panic(err) + } +} + +func (a AppModuleBasic) GetTxCmd() *cobra.Command { + return nil +} + +func (a AppModuleBasic) GetQueryCmd() *cobra.Command { + return cli.GetQueryCmd() +} + +func (a AppModuleBasic) RegisterLegacyAminoCodec(_ *codec.LegacyAmino) { +} + +type AppModule struct { + AppModuleBasic + paramSpace paramstypes.Subspace +} + +// NewAppModule constructor +func NewAppModule(paramSpace paramstypes.Subspace) *AppModule { + if !paramSpace.HasKeyTable() { + paramSpace = paramSpace.WithKeyTable(types.ParamKeyTable()) + } + + return &AppModule{paramSpace: paramSpace} +} + +func (a AppModule) InitGenesis(ctx sdk.Context, marshaler codec.JSONCodec, message json.RawMessage) []abci.ValidatorUpdate { + var genesisState types.GenesisState + marshaler.MustUnmarshalJSON(message, &genesisState) + a.paramSpace.SetParamSet(ctx, &genesisState.Params) + return nil +} + +func (a AppModule) ExportGenesis(ctx sdk.Context, marshaler codec.JSONCodec) json.RawMessage { + var genState types.GenesisState + a.paramSpace.GetParamSet(ctx, &genState.Params) + return marshaler.MustMarshalJSON(&genState) +} + +func (a AppModule) RegisterInvariants(_ sdk.InvariantRegistry) { +} + +func (a AppModule) Route() sdk.Route { + return sdk.Route{} +} + +func (a AppModule) QuerierRoute() string { + return types.QuerierRoute +} + +func (a AppModule) LegacyQuerierHandler(_ *codec.LegacyAmino) sdk.Querier { + return nil +} + +func (a AppModule) RegisterServices(cfg module.Configurator) { + types.RegisterQueryServer(cfg.QueryServer(), NewGrpcQuerier(a.paramSpace)) +} + +func (a AppModule) BeginBlock(_ sdk.Context, _ abci.RequestBeginBlock) { +} + +func (a AppModule) EndBlock(_ sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate { + return nil +} + +// ConsensusVersion is a sequence number for state-breaking change of the +// 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 (a AppModule) ConsensusVersion() uint64 { + return 1 +} diff --git a/x/globalfee/querier.go b/x/globalfee/querier.go new file mode 100644 index 000000000..23a06c286 --- /dev/null +++ b/x/globalfee/querier.go @@ -0,0 +1,37 @@ +package globalfee + +import ( + "context" + + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/cosmos/gaia/v9/x/globalfee/types" +) + +var _ types.QueryServer = &GrpcQuerier{} + +// ParamSource is a read only subset of paramtypes.Subspace +type ParamSource interface { + Get(ctx sdk.Context, key []byte, ptr interface{}) + Has(ctx sdk.Context, key []byte) bool +} + +type GrpcQuerier struct { + paramSource ParamSource +} + +func NewGrpcQuerier(paramSource ParamSource) GrpcQuerier { + return GrpcQuerier{paramSource: paramSource} +} + +// MinimumGasPrices return minimum gas prices +func (g GrpcQuerier) MinimumGasPrices(stdCtx context.Context, _ *types.QueryMinimumGasPricesRequest) (*types.QueryMinimumGasPricesResponse, error) { + var minGasPrices sdk.DecCoins + ctx := sdk.UnwrapSDKContext(stdCtx) + if g.paramSource.Has(ctx, types.ParamStoreKeyMinGasPrices) { + g.paramSource.Get(ctx, types.ParamStoreKeyMinGasPrices, &minGasPrices) + } + return &types.QueryMinimumGasPricesResponse{ + MinimumGasPrices: minGasPrices, + }, nil +} diff --git a/x/globalfee/querier_test.go b/x/globalfee/querier_test.go new file mode 100644 index 000000000..bed110300 --- /dev/null +++ b/x/globalfee/querier_test.go @@ -0,0 +1,56 @@ +package globalfee + +import ( + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/cosmos/gaia/v9/x/globalfee/types" +) + +func TestQueryMinimumGasPrices(t *testing.T) { + specs := map[string]struct { + setupStore func(ctx sdk.Context, s paramtypes.Subspace) + expMin sdk.DecCoins + }{ + "one coin": { + setupStore: func(ctx sdk.Context, s paramtypes.Subspace) { + s.SetParamSet(ctx, &types.Params{ + MinimumGasPrices: sdk.NewDecCoins(sdk.NewDecCoin("ALX", sdk.OneInt())), + }) + }, + expMin: sdk.NewDecCoins(sdk.NewDecCoin("ALX", sdk.OneInt())), + }, + "multiple coins": { + setupStore: func(ctx sdk.Context, s paramtypes.Subspace) { + s.SetParamSet(ctx, &types.Params{ + MinimumGasPrices: sdk.NewDecCoins(sdk.NewDecCoin("ALX", sdk.OneInt()), sdk.NewDecCoin("BLX", sdk.NewInt(2))), + }) + }, + expMin: sdk.NewDecCoins(sdk.NewDecCoin("ALX", sdk.OneInt()), sdk.NewDecCoin("BLX", sdk.NewInt(2))), + }, + "no min gas price set": { + setupStore: func(ctx sdk.Context, s paramtypes.Subspace) { + s.SetParamSet(ctx, &types.Params{}) + }, + }, + "no param set": { + setupStore: func(ctx sdk.Context, s paramtypes.Subspace) { + }, + }, + } + for name, spec := range specs { + t.Run(name, func(t *testing.T) { + ctx, _, subspace := setupTestStore(t) + spec.setupStore(ctx, subspace) + q := NewGrpcQuerier(subspace) + gotResp, gotErr := q.MinimumGasPrices(sdk.WrapSDKContext(ctx), nil) + require.NoError(t, gotErr) + require.NotNil(t, gotResp) + assert.Equal(t, spec.expMin, gotResp.MinimumGasPrices) + }) + } +} diff --git a/x/globalfee/types/genesis.go b/x/globalfee/types/genesis.go new file mode 100644 index 000000000..a87d8d989 --- /dev/null +++ b/x/globalfee/types/genesis.go @@ -0,0 +1,40 @@ +package types + +import ( + "encoding/json" + + "github.com/cosmos/cosmos-sdk/codec" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" +) + +// NewGenesisState - Create a new genesis state +func NewGenesisState(params Params) *GenesisState { + return &GenesisState{ + Params: params, + } +} + +// DefaultGenesisState - Return a default genesis state +func DefaultGenesisState() *GenesisState { + return NewGenesisState(DefaultParams()) +} + +// GetGenesisStateFromAppState returns x/auth GenesisState given raw application +// genesis state. +func GetGenesisStateFromAppState(cdc codec.Codec, appState map[string]json.RawMessage) *GenesisState { + var genesisState GenesisState + + if appState[ModuleName] != nil { + cdc.MustUnmarshalJSON(appState[ModuleName], &genesisState) + } + + return &genesisState +} + +func ValidateGenesis(data GenesisState) error { + if err := data.Params.ValidateBasic(); err != nil { + return sdkerrors.Wrap(err, "globalfee params") + } + + return nil +} diff --git a/x/globalfee/types/genesis.pb.go b/x/globalfee/types/genesis.pb.go new file mode 100644 index 000000000..bde069af6 --- /dev/null +++ b/x/globalfee/types/genesis.pb.go @@ -0,0 +1,521 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: gaia/globalfee/v1beta1/genesis.proto + +package types + +import ( + fmt "fmt" + github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types" + types "github.com/cosmos/cosmos-sdk/types" + _ "github.com/gogo/protobuf/gogoproto" + proto "github.com/gogo/protobuf/proto" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = 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 + +// GenesisState - initial state of module +type GenesisState struct { + // Params of this module + Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params,omitempty"` +} + +func (m *GenesisState) Reset() { *m = GenesisState{} } +func (m *GenesisState) String() string { return proto.CompactTextString(m) } +func (*GenesisState) ProtoMessage() {} +func (*GenesisState) Descriptor() ([]byte, []int) { + return fileDescriptor_015b3e8b7a7c65c5, []int{0} +} +func (m *GenesisState) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *GenesisState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_GenesisState.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) XXX_Merge(src proto.Message) { + xxx_messageInfo_GenesisState.Merge(m, src) +} +func (m *GenesisState) XXX_Size() int { + return m.Size() +} +func (m *GenesisState) XXX_DiscardUnknown() { + xxx_messageInfo_GenesisState.DiscardUnknown(m) +} + +var xxx_messageInfo_GenesisState proto.InternalMessageInfo + +func (m *GenesisState) GetParams() Params { + if m != nil { + return m.Params + } + return Params{} +} + +// Params defines the set of module parameters. +type Params struct { + // Minimum stores the minimum gas price(s) for all TX on the chain. + // When multiple coins are defined then they are accepted alternatively. + // The list must be sorted by denoms asc. No duplicate denoms or zero amount + // values allowed. For more information see + // https://docs.cosmos.network/main/modules/auth#concepts + MinimumGasPrices github_com_cosmos_cosmos_sdk_types.DecCoins `protobuf:"bytes,1,rep,name=minimum_gas_prices,json=minimumGasPrices,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.DecCoins" json:"minimum_gas_prices,omitempty" yaml:"minimum_gas_prices"` +} + +func (m *Params) Reset() { *m = Params{} } +func (m *Params) String() string { return proto.CompactTextString(m) } +func (*Params) ProtoMessage() {} +func (*Params) Descriptor() ([]byte, []int) { + return fileDescriptor_015b3e8b7a7c65c5, []int{1} +} +func (m *Params) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Params) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Params.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 *Params) XXX_Merge(src proto.Message) { + xxx_messageInfo_Params.Merge(m, src) +} +func (m *Params) XXX_Size() int { + return m.Size() +} +func (m *Params) XXX_DiscardUnknown() { + xxx_messageInfo_Params.DiscardUnknown(m) +} + +var xxx_messageInfo_Params proto.InternalMessageInfo + +func (m *Params) GetMinimumGasPrices() github_com_cosmos_cosmos_sdk_types.DecCoins { + if m != nil { + return m.MinimumGasPrices + } + return nil +} + +func init() { + proto.RegisterType((*GenesisState)(nil), "gaia.globalfee.v1beta1.GenesisState") + proto.RegisterType((*Params)(nil), "gaia.globalfee.v1beta1.Params") +} + +func init() { + proto.RegisterFile("gaia/globalfee/v1beta1/genesis.proto", fileDescriptor_015b3e8b7a7c65c5) +} + +var fileDescriptor_015b3e8b7a7c65c5 = []byte{ + // 325 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x91, 0x31, 0x4b, 0x03, 0x31, + 0x14, 0xc7, 0x2f, 0x08, 0x1d, 0xae, 0x0e, 0xe5, 0x10, 0xa9, 0xa5, 0xe4, 0xe4, 0x70, 0x28, 0xa8, + 0x09, 0xad, 0x9b, 0xe3, 0x29, 0x74, 0x2d, 0x75, 0x73, 0xa9, 0xb9, 0x33, 0xc6, 0x60, 0x73, 0x09, + 0x4d, 0x2a, 0xf6, 0x5b, 0xf8, 0x39, 0xfc, 0x0c, 0xee, 0x76, 0xec, 0xe8, 0x54, 0xe5, 0x6e, 0x73, + 0xf4, 0x13, 0xc8, 0x25, 0x67, 0x2b, 0x9c, 0x53, 0x02, 0xef, 0xf7, 0x7e, 0xff, 0xc7, 0x7b, 0xfe, + 0x11, 0x23, 0x9c, 0x60, 0x36, 0x95, 0x09, 0x99, 0xde, 0x51, 0x8a, 0x1f, 0xfb, 0x09, 0x35, 0xa4, + 0x8f, 0x19, 0xcd, 0xa8, 0xe6, 0x1a, 0xa9, 0x99, 0x34, 0x32, 0xd8, 0x2f, 0x29, 0xb4, 0xa1, 0x50, + 0x45, 0x75, 0xf6, 0x98, 0x64, 0xd2, 0x22, 0xb8, 0xfc, 0x39, 0xba, 0x03, 0x53, 0xa9, 0x85, 0xd4, + 0x38, 0x21, 0x7a, 0x2b, 0x4c, 0x25, 0xcf, 0x5c, 0x3d, 0xba, 0xf1, 0x77, 0x87, 0x4e, 0x7f, 0x65, + 0x88, 0xa1, 0xc1, 0xc8, 0x6f, 0x28, 0x32, 0x23, 0x42, 0xb7, 0xc1, 0x21, 0xe8, 0x35, 0x07, 0x10, + 0xfd, 0x1f, 0x87, 0x46, 0x96, 0x8a, 0xdb, 0xcb, 0x75, 0xe8, 0x7d, 0xad, 0xc3, 0x96, 0xeb, 0x3a, + 0x91, 0x82, 0x1b, 0x2a, 0x94, 0x59, 0x8c, 0x2b, 0x4f, 0xf4, 0x06, 0xfc, 0x86, 0x83, 0x83, 0x57, + 0xe0, 0x07, 0x82, 0x67, 0x5c, 0xcc, 0xc5, 0x84, 0x11, 0x3d, 0x51, 0x33, 0x9e, 0xd2, 0x32, 0x69, + 0xa7, 0xd7, 0x1c, 0x74, 0x91, 0x1b, 0x15, 0x95, 0xa3, 0x6e, 0x62, 0x2e, 0x69, 0x7a, 0x21, 0x79, + 0x16, 0xab, 0x2a, 0xa7, 0x5b, 0xef, 0xdf, 0x66, 0x7e, 0xaf, 0xc3, 0x83, 0x05, 0x11, 0xd3, 0xf3, + 0xa8, 0x4e, 0x45, 0x2f, 0x1f, 0xe1, 0x31, 0xe3, 0xe6, 0x7e, 0x9e, 0xa0, 0x54, 0x0a, 0x5c, 0xed, + 0xc5, 0x3d, 0xa7, 0xfa, 0xf6, 0x01, 0x9b, 0x85, 0xa2, 0xfa, 0x37, 0x50, 0x8f, 0x5b, 0x95, 0x63, + 0x48, 0xf4, 0xc8, 0x1a, 0xe2, 0x78, 0x99, 0x43, 0xb0, 0xca, 0x21, 0xf8, 0xcc, 0x21, 0x78, 0x2e, + 0xa0, 0xb7, 0x2a, 0xa0, 0xf7, 0x5e, 0x40, 0xef, 0xba, 0x57, 0x17, 0xdb, 0x5b, 0x3e, 0xfd, 0xb9, + 0xa6, 0xd5, 0x27, 0x0d, 0xbb, 0xf6, 0xb3, 0x9f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x48, 0x6d, 0x01, + 0xcd, 0xec, 0x01, 0x00, 0x00, +} + +func (m *GenesisState) 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) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Params.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 *Params) 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 *Params) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.MinimumGasPrices) > 0 { + for iNdEx := len(m.MinimumGasPrices) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.MinimumGasPrices[iNdEx].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 encodeVarintGenesis(dAtA []byte, offset int, v uint64) int { + offset -= sovGenesis(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *GenesisState) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Params.Size() + n += 1 + l + sovGenesis(uint64(l)) + return n +} + +func (m *Params) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.MinimumGasPrices) > 0 { + for _, e := range m.MinimumGasPrices { + l = e.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + } + return n +} + +func sovGenesis(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozGenesis(x uint64) (n int) { + return sovGenesis(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *GenesisState) 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: GenesisState: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GenesisState: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Params", 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 + } + if err := m.Params.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 *Params) 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: Params: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Params: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MinimumGasPrices", 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.MinimumGasPrices = append(m.MinimumGasPrices, types.DecCoin{}) + if err := m.MinimumGasPrices[len(m.MinimumGasPrices)-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 skipGenesis(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, ErrIntOverflowGenesis + } + 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, ErrIntOverflowGenesis + } + 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, ErrIntOverflowGenesis + } + 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, ErrInvalidLengthGenesis + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupGenesis + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthGenesis + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthGenesis = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowGenesis = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupGenesis = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/globalfee/types/keys.go b/x/globalfee/types/keys.go new file mode 100644 index 000000000..71b43267d --- /dev/null +++ b/x/globalfee/types/keys.go @@ -0,0 +1,8 @@ +package types + +const ( + // ModuleName is the name of the this module + ModuleName = "globalfee" + + QuerierRoute = ModuleName +) diff --git a/x/globalfee/types/params.go b/x/globalfee/types/params.go new file mode 100644 index 000000000..7161b2c3e --- /dev/null +++ b/x/globalfee/types/params.go @@ -0,0 +1,81 @@ +package types + +import ( + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" +) + +// ParamStoreKeyMinGasPrices store key +var ParamStoreKeyMinGasPrices = []byte("MinimumGasPricesParam") + +// DefaultParams returns default parameters +func DefaultParams() Params { + return Params{MinimumGasPrices: sdk.DecCoins{}} +} + +func ParamKeyTable() paramtypes.KeyTable { + return paramtypes.NewKeyTable().RegisterParamSet(&Params{}) +} + +// ValidateBasic performs basic validation. +func (p Params) ValidateBasic() error { + return validateMinimumGasPrices(p.MinimumGasPrices) +} + +// ParamSetPairs returns the parameter set pairs. +func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs { + return paramtypes.ParamSetPairs{ + paramtypes.NewParamSetPair( + ParamStoreKeyMinGasPrices, &p.MinimumGasPrices, validateMinimumGasPrices, + ), + } +} + +// this requires the fee non-negative +func validateMinimumGasPrices(i interface{}) error { + v, ok := i.(sdk.DecCoins) + if !ok { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidType, "type: %T, expected sdk.DecCoins", i) + } + + dec := DecCoins(v) + return dec.Validate() +} + +type DecCoins sdk.DecCoins + +// Validate checks that the DecCoins are sorted, have nonnegtive amount, with a valid and unique +// denomination (i.e no duplicates). Otherwise, it returns an error. +func (coins DecCoins) Validate() error { + if len(coins) == 0 { + return nil + } + + lowDenom := "" + seenDenoms := make(map[string]bool) + + for i, coin := range coins { + if seenDenoms[coin.Denom] { + return fmt.Errorf("duplicate denomination %s", coin.Denom) + } + if err := sdk.ValidateDenom(coin.Denom); err != nil { + return err + } + // skip the denom order check for the first denom in the coins list + if i != 0 && coin.Denom <= lowDenom { + return fmt.Errorf("denomination %s is not sorted", coin.Denom) + } + if coin.IsNegative() { + return fmt.Errorf("coin %s amount is negative", coin.Amount) + } + + // we compare each coin against the last denom + lowDenom = coin.Denom + seenDenoms[coin.Denom] = true + } + + return nil +} diff --git a/x/globalfee/types/params_test.go b/x/globalfee/types/params_test.go new file mode 100644 index 000000000..ba53a7f1f --- /dev/null +++ b/x/globalfee/types/params_test.go @@ -0,0 +1,73 @@ +package types + +import ( + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/require" +) + +func TestDefaultParams(t *testing.T) { + p := DefaultParams() + require.EqualValues(t, p.MinimumGasPrices, sdk.DecCoins{}) +} + +func Test_validateParams(t *testing.T) { + tests := map[string]struct { + coins interface{} // not sdk.DeCoins, but Decoins defined in glboalfee + expectErr bool + }{ + "DefaultParams, pass": { + DefaultParams().MinimumGasPrices, + false, + }, + "DecCoins conversion fails, fail": { + sdk.Coins{sdk.NewCoin("photon", sdk.OneInt())}, + true, + }, + "coins amounts are zero, pass": { + sdk.DecCoins{ + sdk.NewDecCoin("atom", sdk.ZeroInt()), + sdk.NewDecCoin("photon", sdk.ZeroInt()), + }, + false, + }, + "duplicate coins denoms, fail": { + sdk.DecCoins{ + sdk.NewDecCoin("photon", sdk.OneInt()), + sdk.NewDecCoin("photon", sdk.OneInt()), + }, + true, + }, + "coins are not sorted by denom alphabetically, fail": { + sdk.DecCoins{ + sdk.NewDecCoin("photon", sdk.OneInt()), + sdk.NewDecCoin("atom", sdk.OneInt()), + }, + true, + }, + "negative amount, fail": { + sdk.DecCoins{ + sdk.DecCoin{Denom: "photon", Amount: sdk.OneDec().Neg()}, + }, + true, + }, + "invalid denom, fail": { + sdk.DecCoins{ + sdk.DecCoin{Denom: "photon!", Amount: sdk.OneDec().Neg()}, + }, + true, + }, + } + + for name, test := range tests { + t.Run(name, func(t *testing.T) { + err := validateMinimumGasPrices(test.coins) + if test.expectErr { + require.Error(t, err) + return + } + require.NoError(t, err) + }) + } +} diff --git a/x/globalfee/types/query.pb.go b/x/globalfee/types/query.pb.go new file mode 100644 index 000000000..569b6975b --- /dev/null +++ b/x/globalfee/types/query.pb.go @@ -0,0 +1,553 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: gaia/globalfee/v1beta1/query.proto + +package types + +import ( + context "context" + fmt "fmt" + github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types" + types "github.com/cosmos/cosmos-sdk/types" + _ "github.com/gogo/protobuf/gogoproto" + grpc1 "github.com/gogo/protobuf/grpc" + proto "github.com/gogo/protobuf/proto" + _ "google.golang.org/genproto/googleapis/api/annotations" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = 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 + +// QueryMinimumGasPricesRequest is the request type for the +// Query/MinimumGasPrices RPC method. +type QueryMinimumGasPricesRequest struct { +} + +func (m *QueryMinimumGasPricesRequest) Reset() { *m = QueryMinimumGasPricesRequest{} } +func (m *QueryMinimumGasPricesRequest) String() string { return proto.CompactTextString(m) } +func (*QueryMinimumGasPricesRequest) ProtoMessage() {} +func (*QueryMinimumGasPricesRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_12a736cede25d10a, []int{0} +} +func (m *QueryMinimumGasPricesRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryMinimumGasPricesRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryMinimumGasPricesRequest.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 *QueryMinimumGasPricesRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryMinimumGasPricesRequest.Merge(m, src) +} +func (m *QueryMinimumGasPricesRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryMinimumGasPricesRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryMinimumGasPricesRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryMinimumGasPricesRequest proto.InternalMessageInfo + +// QueryMinimumGasPricesResponse is the response type for the +// Query/MinimumGasPrices RPC method. +type QueryMinimumGasPricesResponse struct { + MinimumGasPrices github_com_cosmos_cosmos_sdk_types.DecCoins `protobuf:"bytes,1,rep,name=minimum_gas_prices,json=minimumGasPrices,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.DecCoins" json:"minimum_gas_prices,omitempty" yaml:"minimum_gas_prices"` +} + +func (m *QueryMinimumGasPricesResponse) Reset() { *m = QueryMinimumGasPricesResponse{} } +func (m *QueryMinimumGasPricesResponse) String() string { return proto.CompactTextString(m) } +func (*QueryMinimumGasPricesResponse) ProtoMessage() {} +func (*QueryMinimumGasPricesResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_12a736cede25d10a, []int{1} +} +func (m *QueryMinimumGasPricesResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryMinimumGasPricesResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryMinimumGasPricesResponse.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 *QueryMinimumGasPricesResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryMinimumGasPricesResponse.Merge(m, src) +} +func (m *QueryMinimumGasPricesResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryMinimumGasPricesResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryMinimumGasPricesResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryMinimumGasPricesResponse proto.InternalMessageInfo + +func (m *QueryMinimumGasPricesResponse) GetMinimumGasPrices() github_com_cosmos_cosmos_sdk_types.DecCoins { + if m != nil { + return m.MinimumGasPrices + } + return nil +} + +func init() { + proto.RegisterType((*QueryMinimumGasPricesRequest)(nil), "gaia.globalfee.v1beta1.QueryMinimumGasPricesRequest") + proto.RegisterType((*QueryMinimumGasPricesResponse)(nil), "gaia.globalfee.v1beta1.QueryMinimumGasPricesResponse") +} + +func init() { + proto.RegisterFile("gaia/globalfee/v1beta1/query.proto", fileDescriptor_12a736cede25d10a) +} + +var fileDescriptor_12a736cede25d10a = []byte{ + // 377 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x92, 0xb1, 0x4f, 0xdb, 0x40, + 0x14, 0xc6, 0x7d, 0xad, 0xda, 0xc1, 0x5d, 0x22, 0xab, 0xaa, 0xda, 0xc8, 0x3d, 0x57, 0x9e, 0xa2, + 0x36, 0xbd, 0x53, 0xd2, 0x76, 0xe9, 0x98, 0x56, 0x62, 0x42, 0x82, 0x8c, 0x2c, 0xd1, 0xd9, 0x1c, + 0xc7, 0x09, 0x9f, 0x9f, 0x93, 0x3b, 0x23, 0xbc, 0xf2, 0x17, 0x20, 0xf1, 0x5f, 0xb0, 0xb2, 0xc2, + 0x9e, 0x31, 0x12, 0x0b, 0x93, 0x41, 0x09, 0x13, 0x23, 0x7f, 0x01, 0xb2, 0x9d, 0x00, 0x8a, 0x09, + 0x12, 0x93, 0x2d, 0x7d, 0xbf, 0xf7, 0x3e, 0x7d, 0xdf, 0x3d, 0xdb, 0x17, 0x4c, 0x32, 0x2a, 0x22, + 0x08, 0x58, 0xb4, 0xc3, 0x39, 0xdd, 0xef, 0x04, 0xdc, 0xb0, 0x0e, 0x1d, 0xa6, 0x7c, 0x94, 0x91, + 0x64, 0x04, 0x06, 0x9c, 0x4f, 0x05, 0x43, 0x1e, 0x18, 0x32, 0x67, 0x9a, 0x1f, 0x05, 0x08, 0x28, + 0x11, 0x5a, 0xfc, 0x55, 0x74, 0xd3, 0x15, 0x00, 0x22, 0xe2, 0x94, 0x25, 0x92, 0xb2, 0x38, 0x06, + 0xc3, 0x8c, 0x84, 0x58, 0xcf, 0x55, 0x1c, 0x82, 0x56, 0xa0, 0x69, 0xc0, 0xf4, 0xa3, 0x59, 0x08, + 0x32, 0xae, 0x74, 0x1f, 0xdb, 0xee, 0x66, 0x61, 0xbd, 0x2e, 0x63, 0xa9, 0x52, 0xb5, 0xc6, 0xf4, + 0xc6, 0x48, 0x86, 0x5c, 0xf7, 0xf9, 0x30, 0xe5, 0xda, 0xf8, 0x39, 0xb2, 0xbf, 0xae, 0x00, 0x74, + 0x02, 0xb1, 0xe6, 0xce, 0x19, 0xb2, 0x1d, 0x55, 0x89, 0x03, 0xc1, 0xf4, 0x20, 0x29, 0xe5, 0xcf, + 0xe8, 0xdb, 0xdb, 0xd6, 0x87, 0xae, 0x4b, 0x2a, 0x7f, 0x52, 0xf8, 0x2f, 0x82, 0x90, 0xff, 0x3c, + 0xfc, 0x07, 0x32, 0xee, 0x25, 0xe3, 0xdc, 0xb3, 0x6e, 0x73, 0xcf, 0xad, 0xcf, 0xb7, 0x41, 0x49, + 0xc3, 0x55, 0x62, 0xb2, 0xbb, 0xdc, 0xfb, 0x92, 0x31, 0x15, 0xfd, 0xf5, 0xeb, 0x94, 0x7f, 0x72, + 0xe5, 0xfd, 0x10, 0xd2, 0xec, 0xa6, 0x01, 0x09, 0x41, 0xd1, 0x79, 0xd8, 0xea, 0xf3, 0x53, 0x6f, + 0xef, 0x51, 0x93, 0x25, 0x5c, 0x2f, 0x0c, 0x75, 0xbf, 0xa1, 0x96, 0x62, 0x74, 0xcf, 0x91, 0xfd, + 0xae, 0x0c, 0xe8, 0x9c, 0x22, 0xbb, 0xb1, 0x9c, 0xd2, 0xf9, 0x4d, 0x9e, 0x7f, 0x0c, 0xf2, 0x52, + 0x6b, 0xcd, 0x3f, 0xaf, 0x9c, 0xaa, 0xaa, 0xf4, 0xbb, 0x87, 0x17, 0x37, 0xc7, 0x6f, 0xda, 0xce, + 0x77, 0xba, 0xe2, 0x4a, 0xea, 0x0d, 0xf4, 0x7a, 0xe3, 0x29, 0x46, 0x93, 0x29, 0x46, 0xd7, 0x53, + 0x8c, 0x8e, 0x66, 0xd8, 0x9a, 0xcc, 0xb0, 0x75, 0x39, 0xc3, 0xd6, 0x56, 0xab, 0x5e, 0x4c, 0xb9, + 0xf6, 0xe0, 0xc9, 0xe2, 0xb2, 0x9e, 0xe0, 0x7d, 0x79, 0x0b, 0xbf, 0xee, 0x03, 0x00, 0x00, 0xff, + 0xff, 0x73, 0x0d, 0xf8, 0x43, 0x9d, 0x02, 0x00, 0x00, +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ 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. +const _ = grpc.SupportPackageIsVersion4 + +// QueryClient is the client API for Query service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type QueryClient interface { + MinimumGasPrices(ctx context.Context, in *QueryMinimumGasPricesRequest, opts ...grpc.CallOption) (*QueryMinimumGasPricesResponse, error) +} + +type queryClient struct { + cc grpc1.ClientConn +} + +func NewQueryClient(cc grpc1.ClientConn) QueryClient { + return &queryClient{cc} +} + +func (c *queryClient) MinimumGasPrices(ctx context.Context, in *QueryMinimumGasPricesRequest, opts ...grpc.CallOption) (*QueryMinimumGasPricesResponse, error) { + out := new(QueryMinimumGasPricesResponse) + err := c.cc.Invoke(ctx, "/gaia.globalfee.v1beta1.Query/MinimumGasPrices", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// QueryServer is the server API for Query service. +type QueryServer interface { + MinimumGasPrices(context.Context, *QueryMinimumGasPricesRequest) (*QueryMinimumGasPricesResponse, error) +} + +// UnimplementedQueryServer can be embedded to have forward compatible implementations. +type UnimplementedQueryServer struct { +} + +func (*UnimplementedQueryServer) MinimumGasPrices(ctx context.Context, req *QueryMinimumGasPricesRequest) (*QueryMinimumGasPricesResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method MinimumGasPrices not implemented") +} + +func RegisterQueryServer(s grpc1.Server, srv QueryServer) { + s.RegisterService(&_Query_serviceDesc, srv) +} + +func _Query_MinimumGasPrices_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryMinimumGasPricesRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).MinimumGasPrices(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/gaia.globalfee.v1beta1.Query/MinimumGasPrices", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).MinimumGasPrices(ctx, req.(*QueryMinimumGasPricesRequest)) + } + return interceptor(ctx, in, info, handler) +} + +var _Query_serviceDesc = grpc.ServiceDesc{ + ServiceName: "gaia.globalfee.v1beta1.Query", + HandlerType: (*QueryServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "MinimumGasPrices", + Handler: _Query_MinimumGasPrices_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "gaia/globalfee/v1beta1/query.proto", +} + +func (m *QueryMinimumGasPricesRequest) 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 *QueryMinimumGasPricesRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryMinimumGasPricesRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *QueryMinimumGasPricesResponse) 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 *QueryMinimumGasPricesResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryMinimumGasPricesResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.MinimumGasPrices) > 0 { + for iNdEx := len(m.MinimumGasPrices) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.MinimumGasPrices[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func encodeVarintQuery(dAtA []byte, offset int, v uint64) int { + offset -= sovQuery(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *QueryMinimumGasPricesRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *QueryMinimumGasPricesResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.MinimumGasPrices) > 0 { + for _, e := range m.MinimumGasPrices { + l = e.Size() + n += 1 + l + sovQuery(uint64(l)) + } + } + return n +} + +func sovQuery(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozQuery(x uint64) (n int) { + return sovQuery(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *QueryMinimumGasPricesRequest) 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: QueryMinimumGasPricesRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryMinimumGasPricesRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + 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 *QueryMinimumGasPricesResponse) 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: QueryMinimumGasPricesResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryMinimumGasPricesResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MinimumGasPrices", 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 + } + m.MinimumGasPrices = append(m.MinimumGasPrices, types.DecCoin{}) + if err := m.MinimumGasPrices[len(m.MinimumGasPrices)-1].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 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowQuery + } + 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, ErrIntOverflowQuery + } + 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, ErrIntOverflowQuery + } + 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, ErrInvalidLengthQuery + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupQuery + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthQuery + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthQuery = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowQuery = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupQuery = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/globalfee/types/query.pb.gw.go b/x/globalfee/types/query.pb.gw.go new file mode 100644 index 000000000..0e33d9df1 --- /dev/null +++ b/x/globalfee/types/query.pb.gw.go @@ -0,0 +1,153 @@ +// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. +// source: gaia/globalfee/v1beta1/query.proto + +/* +Package types is a reverse proxy. + +It translates gRPC into RESTful JSON APIs. +*/ +package types + +import ( + "context" + "io" + "net/http" + + "github.com/golang/protobuf/descriptor" + "github.com/golang/protobuf/proto" + "github.com/grpc-ecosystem/grpc-gateway/runtime" + "github.com/grpc-ecosystem/grpc-gateway/utilities" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/metadata" + "google.golang.org/grpc/status" +) + +// Suppress "imported and not used" errors +var _ codes.Code +var _ io.Reader +var _ status.Status +var _ = runtime.String +var _ = utilities.NewDoubleArray +var _ = descriptor.ForMessage +var _ = metadata.Join + +func request_Query_MinimumGasPrices_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryMinimumGasPricesRequest + var metadata runtime.ServerMetadata + + msg, err := client.MinimumGasPrices(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_MinimumGasPrices_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryMinimumGasPricesRequest + var metadata runtime.ServerMetadata + + msg, err := server.MinimumGasPrices(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. +// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterQueryHandlerFromEndpoint instead. +func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, server QueryServer) error { + + mux.Handle("GET", pattern_Query_MinimumGasPrices_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 { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_MinimumGasPrices_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) + return + } + + forward_Query_MinimumGasPrices_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +// RegisterQueryHandlerFromEndpoint is same as RegisterQueryHandler but +// automatically dials to "endpoint" and closes the connection when "ctx" gets done. +func RegisterQueryHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { + conn, err := grpc.Dial(endpoint, opts...) + if err != nil { + return err + } + defer func() { + if err != nil { + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + return + } + go func() { + <-ctx.Done() + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + }() + }() + + return RegisterQueryHandler(ctx, mux, conn) +} + +// RegisterQueryHandler registers the http handlers for service Query to "mux". +// The handlers forward requests to the grpc endpoint over "conn". +func RegisterQueryHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { + return RegisterQueryHandlerClient(ctx, mux, NewQueryClient(conn)) +} + +// RegisterQueryHandlerClient registers the http handlers for service Query +// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "QueryClient". +// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "QueryClient" +// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in +// "QueryClient" to call the correct interceptors. +func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, client QueryClient) error { + + mux.Handle("GET", pattern_Query_MinimumGasPrices_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_MinimumGasPrices_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_MinimumGasPrices_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +var ( + pattern_Query_MinimumGasPrices_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"gaia", "globalfee", "v1beta1", "minimum_gas_prices"}, "", runtime.AssumeColonVerbOpt(true))) +) + +var ( + forward_Query_MinimumGasPrices_0 = runtime.ForwardResponseMessage +) diff --git a/x/tokenfactory/bindings/custom_msg_test.go b/x/tokenfactory/bindings/custom_msg_test.go index ba411ce1f..ca083a6e1 100644 --- a/x/tokenfactory/bindings/custom_msg_test.go +++ b/x/tokenfactory/bindings/custom_msg_test.go @@ -11,9 +11,9 @@ import ( wasmvmtypes "github.com/CosmWasm/wasmvm/types" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/CosmosTokenFactory/token-factory/app" - bindings "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/bindings/types" - "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/types" + "github.com/CosmosContracts/juno/app" + bindings "github.com/CosmosContracts/juno/x/tokenfactory/bindings/types" + "github.com/CosmosContracts/juno/x/tokenfactory/types" ) func TestCreateDenomMsg(t *testing.T) { diff --git a/x/tokenfactory/bindings/custom_query_test.go b/x/tokenfactory/bindings/custom_query_test.go index 278c60352..db018ca0a 100644 --- a/x/tokenfactory/bindings/custom_query_test.go +++ b/x/tokenfactory/bindings/custom_query_test.go @@ -10,8 +10,8 @@ import ( wasmvmtypes "github.com/CosmWasm/wasmvm/types" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/CosmosTokenFactory/token-factory/app" - bindings "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/bindings/types" + "github.com/CosmosContracts/juno/app" + bindings "github.com/CosmosContracts/juno/x/tokenfactory/bindings/types" ) func TestQueryFullDenom(t *testing.T) { diff --git a/x/tokenfactory/bindings/helpers_test.go b/x/tokenfactory/bindings/helpers_test.go index 41d14131a..496e6481e 100644 --- a/x/tokenfactory/bindings/helpers_test.go +++ b/x/tokenfactory/bindings/helpers_test.go @@ -15,7 +15,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/CosmWasm/wasmd/x/wasm/keeper" - "github.com/CosmosTokenFactory/token-factory/app" + "github.com/CosmosContracts/juno/app" ) func CreateTestInput() (*app.TokenApp, sdk.Context) { diff --git a/x/tokenfactory/bindings/message_plugin.go b/x/tokenfactory/bindings/message_plugin.go index b6acde281..e7810cf8e 100644 --- a/x/tokenfactory/bindings/message_plugin.go +++ b/x/tokenfactory/bindings/message_plugin.go @@ -10,9 +10,9 @@ import ( bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" - bindingstypes "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/bindings/types" - tokenfactorykeeper "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/keeper" - tokenfactorytypes "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/types" + bindingstypes "github.com/CosmosContracts/juno/x/tokenfactory/bindings/types" + tokenfactorykeeper "github.com/CosmosContracts/juno/x/tokenfactory/keeper" + tokenfactorytypes "github.com/CosmosContracts/juno/x/tokenfactory/types" ) // CustomMessageDecorator returns decorator for custom CosmWasm bindings messages diff --git a/x/tokenfactory/bindings/queries.go b/x/tokenfactory/bindings/queries.go index b648b6468..be414c8e2 100644 --- a/x/tokenfactory/bindings/queries.go +++ b/x/tokenfactory/bindings/queries.go @@ -6,8 +6,8 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" - bindingstypes "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/bindings/types" - tokenfactorykeeper "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/keeper" + bindingstypes "github.com/CosmosContracts/juno/x/tokenfactory/bindings/types" + tokenfactorykeeper "github.com/CosmosContracts/juno/x/tokenfactory/keeper" ) type QueryPlugin struct { diff --git a/x/tokenfactory/bindings/query_plugin.go b/x/tokenfactory/bindings/query_plugin.go index cbef51ac7..f77c4540d 100644 --- a/x/tokenfactory/bindings/query_plugin.go +++ b/x/tokenfactory/bindings/query_plugin.go @@ -8,7 +8,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - bindingstypes "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/bindings/types" + bindingstypes "github.com/CosmosContracts/juno/x/tokenfactory/bindings/types" ) // CustomQuerier dispatches custom CosmWasm bindings queries. diff --git a/x/tokenfactory/bindings/validate_msg_test.go b/x/tokenfactory/bindings/validate_msg_test.go index dbc124dd5..6e6c5e5ca 100644 --- a/x/tokenfactory/bindings/validate_msg_test.go +++ b/x/tokenfactory/bindings/validate_msg_test.go @@ -6,9 +6,9 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" - wasmbinding "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/bindings" - bindings "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/bindings/types" - "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/types" + wasmbinding "github.com/CosmosContracts/juno/x/tokenfactory/bindings" + bindings "github.com/CosmosContracts/juno/x/tokenfactory/bindings/types" + "github.com/CosmosContracts/juno/x/tokenfactory/types" "github.com/stretchr/testify/require" ) diff --git a/x/tokenfactory/bindings/validate_queries_test.go b/x/tokenfactory/bindings/validate_queries_test.go index 78a84b921..a35ecb24a 100644 --- a/x/tokenfactory/bindings/validate_queries_test.go +++ b/x/tokenfactory/bindings/validate_queries_test.go @@ -9,7 +9,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" - wasmbinding "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/bindings" + wasmbinding "github.com/CosmosContracts/juno/x/tokenfactory/bindings" ) func TestFullDenom(t *testing.T) { diff --git a/x/tokenfactory/bindings/wasm.go b/x/tokenfactory/bindings/wasm.go index cb4d86430..2c7f3c3da 100644 --- a/x/tokenfactory/bindings/wasm.go +++ b/x/tokenfactory/bindings/wasm.go @@ -5,7 +5,7 @@ import ( wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" - tokenfactorykeeper "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/keeper" + tokenfactorykeeper "github.com/CosmosContracts/juno/x/tokenfactory/keeper" bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" ) diff --git a/x/tokenfactory/client/cli/query.go b/x/tokenfactory/client/cli/query.go index 421a10c74..8cf9dd331 100644 --- a/x/tokenfactory/client/cli/query.go +++ b/x/tokenfactory/client/cli/query.go @@ -13,7 +13,7 @@ import ( // "github.com/cosmos/cosmos-sdk/client/flags" // sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/types" + "github.com/CosmosContracts/juno/x/tokenfactory/types" ) // GetQueryCmd returns the cli query commands for this module diff --git a/x/tokenfactory/client/cli/tx.go b/x/tokenfactory/client/cli/tx.go index 5bde09974..a666ce57a 100644 --- a/x/tokenfactory/client/cli/tx.go +++ b/x/tokenfactory/client/cli/tx.go @@ -12,7 +12,7 @@ import ( "github.com/cosmos/cosmos-sdk/client/tx" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/types" + "github.com/CosmosContracts/juno/x/tokenfactory/types" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" ) diff --git a/x/tokenfactory/keeper/admins.go b/x/tokenfactory/keeper/admins.go index c1294f536..52ace9802 100644 --- a/x/tokenfactory/keeper/admins.go +++ b/x/tokenfactory/keeper/admins.go @@ -4,7 +4,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/gogo/protobuf/proto" - "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/types" + "github.com/CosmosContracts/juno/x/tokenfactory/types" ) // GetAuthorityMetadata returns the authority metadata for a specific denom diff --git a/x/tokenfactory/keeper/admins_test.go b/x/tokenfactory/keeper/admins_test.go index b059c3195..2f7c5f7de 100644 --- a/x/tokenfactory/keeper/admins_test.go +++ b/x/tokenfactory/keeper/admins_test.go @@ -6,7 +6,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" - "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/types" + "github.com/CosmosContracts/juno/x/tokenfactory/types" ) func (suite *KeeperTestSuite) TestAdminMsgs() { diff --git a/x/tokenfactory/keeper/bankactions.go b/x/tokenfactory/keeper/bankactions.go index dff42306d..2eae19887 100644 --- a/x/tokenfactory/keeper/bankactions.go +++ b/x/tokenfactory/keeper/bankactions.go @@ -5,7 +5,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/types" + "github.com/CosmosContracts/juno/x/tokenfactory/types" ) func (k Keeper) mintTo(ctx sdk.Context, amount sdk.Coin, mintTo string) error { diff --git a/x/tokenfactory/keeper/createdenom.go b/x/tokenfactory/keeper/createdenom.go index 6658e55a6..6c50340d7 100644 --- a/x/tokenfactory/keeper/createdenom.go +++ b/x/tokenfactory/keeper/createdenom.go @@ -6,7 +6,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" - "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/types" + "github.com/CosmosContracts/juno/x/tokenfactory/types" ) // ConvertToBaseToken converts a fee amount in a whitelisted fee token to the base fee token amount diff --git a/x/tokenfactory/keeper/createdenom_test.go b/x/tokenfactory/keeper/createdenom_test.go index 889758da5..d9f5747f3 100644 --- a/x/tokenfactory/keeper/createdenom_test.go +++ b/x/tokenfactory/keeper/createdenom_test.go @@ -5,8 +5,8 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/testhelpers" - "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/types" + "github.com/CosmosContracts/juno/x/tokenfactory/testhelpers" + "github.com/CosmosContracts/juno/x/tokenfactory/types" ) func (suite *KeeperTestSuite) TestMsgCreateDenom() { diff --git a/x/tokenfactory/keeper/genesis.go b/x/tokenfactory/keeper/genesis.go index bd8c82de5..a0b36f0b2 100644 --- a/x/tokenfactory/keeper/genesis.go +++ b/x/tokenfactory/keeper/genesis.go @@ -3,7 +3,7 @@ package keeper import ( sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/types" + "github.com/CosmosContracts/juno/x/tokenfactory/types" ) // InitGenesis initializes the tokenfactory module's state from a provided genesis diff --git a/x/tokenfactory/keeper/genesis_test.go b/x/tokenfactory/keeper/genesis_test.go index 862cbbdd8..6f2ce0988 100644 --- a/x/tokenfactory/keeper/genesis_test.go +++ b/x/tokenfactory/keeper/genesis_test.go @@ -4,7 +4,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" - "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/types" + "github.com/CosmosContracts/juno/x/tokenfactory/types" ) func (suite *KeeperTestSuite) TestGenesis() { diff --git a/x/tokenfactory/keeper/grpc_query.go b/x/tokenfactory/keeper/grpc_query.go index 3ed6e27c9..1ef143a40 100644 --- a/x/tokenfactory/keeper/grpc_query.go +++ b/x/tokenfactory/keeper/grpc_query.go @@ -5,7 +5,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/types" + "github.com/CosmosContracts/juno/x/tokenfactory/types" ) var _ types.QueryServer = Keeper{} diff --git a/x/tokenfactory/keeper/keeper.go b/x/tokenfactory/keeper/keeper.go index 0f30be034..00cd09006 100644 --- a/x/tokenfactory/keeper/keeper.go +++ b/x/tokenfactory/keeper/keeper.go @@ -9,7 +9,7 @@ import ( storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/types" + "github.com/CosmosContracts/juno/x/tokenfactory/types" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" diff --git a/x/tokenfactory/keeper/keeper_test.go b/x/tokenfactory/keeper/keeper_test.go index da8589008..fa2668e16 100644 --- a/x/tokenfactory/keeper/keeper_test.go +++ b/x/tokenfactory/keeper/keeper_test.go @@ -7,10 +7,10 @@ import ( "github.com/stretchr/testify/suite" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" - "github.com/CosmosTokenFactory/token-factory/app/apptesting" - "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/keeper" - "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/testhelpers" - "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/types" + "github.com/CosmosContracts/juno/app/apptesting" + "github.com/CosmosContracts/juno/x/tokenfactory/keeper" + "github.com/CosmosContracts/juno/x/tokenfactory/testhelpers" + "github.com/CosmosContracts/juno/x/tokenfactory/types" ) type KeeperTestSuite struct { diff --git a/x/tokenfactory/keeper/msg_server.go b/x/tokenfactory/keeper/msg_server.go index 6a4e09be3..d7fc495a9 100644 --- a/x/tokenfactory/keeper/msg_server.go +++ b/x/tokenfactory/keeper/msg_server.go @@ -5,7 +5,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/types" + "github.com/CosmosContracts/juno/x/tokenfactory/types" ) type msgServer struct { diff --git a/x/tokenfactory/keeper/msg_server_test.go b/x/tokenfactory/keeper/msg_server_test.go index 14e497177..bb12542ee 100644 --- a/x/tokenfactory/keeper/msg_server_test.go +++ b/x/tokenfactory/keeper/msg_server_test.go @@ -3,7 +3,7 @@ package keeper_test import ( "fmt" - "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/types" + "github.com/CosmosContracts/juno/x/tokenfactory/types" sdk "github.com/cosmos/cosmos-sdk/types" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" diff --git a/x/tokenfactory/keeper/params.go b/x/tokenfactory/keeper/params.go index 07b37d8e7..a02ba6367 100644 --- a/x/tokenfactory/keeper/params.go +++ b/x/tokenfactory/keeper/params.go @@ -1,7 +1,7 @@ package keeper import ( - "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/types" + "github.com/CosmosContracts/juno/x/tokenfactory/types" sdk "github.com/cosmos/cosmos-sdk/types" ) diff --git a/x/tokenfactory/module.go b/x/tokenfactory/module.go index 936f1bf3f..ba3dd6be5 100644 --- a/x/tokenfactory/module.go +++ b/x/tokenfactory/module.go @@ -24,12 +24,12 @@ import ( "github.com/spf13/cobra" abci "github.com/tendermint/tendermint/abci/types" - simulation "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/simulation" + simulation "github.com/CosmosContracts/juno/x/tokenfactory/simulation" simtypes "github.com/cosmos/cosmos-sdk/types/simulation" - "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/client/cli" - "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/keeper" - "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/types" + "github.com/CosmosContracts/juno/x/tokenfactory/client/cli" + "github.com/CosmosContracts/juno/x/tokenfactory/keeper" + "github.com/CosmosContracts/juno/x/tokenfactory/types" ) var ( diff --git a/x/tokenfactory/simulation/genesis.go b/x/tokenfactory/simulation/genesis.go index d839fad40..d5e0bfa0c 100644 --- a/x/tokenfactory/simulation/genesis.go +++ b/x/tokenfactory/simulation/genesis.go @@ -3,7 +3,7 @@ package simulation import ( "math/rand" - "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/types" + "github.com/CosmosContracts/juno/x/tokenfactory/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" ) diff --git a/x/tokenfactory/simulation/operations.go b/x/tokenfactory/simulation/operations.go index 87e70653b..7e0adf368 100644 --- a/x/tokenfactory/simulation/operations.go +++ b/x/tokenfactory/simulation/operations.go @@ -3,8 +3,8 @@ package simulation import ( "math/rand" - "github.com/CosmosTokenFactory/token-factory/app/params" - "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/types" + "github.com/CosmosContracts/juno/app/params" + "github.com/CosmosContracts/juno/x/tokenfactory/types" "github.com/cosmos/cosmos-sdk/baseapp" simappparams "github.com/cosmos/cosmos-sdk/simapp/params" sdk "github.com/cosmos/cosmos-sdk/types" diff --git a/x/tokenfactory/simulation/params.go b/x/tokenfactory/simulation/params.go index 001a55c09..0983b56a7 100644 --- a/x/tokenfactory/simulation/params.go +++ b/x/tokenfactory/simulation/params.go @@ -4,7 +4,7 @@ import ( "fmt" "math/rand" - "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/types" + "github.com/CosmosContracts/juno/x/tokenfactory/types" simtypes "github.com/cosmos/cosmos-sdk/types/simulation" "github.com/cosmos/cosmos-sdk/x/simulation" ) diff --git a/x/tokenfactory/types/denoms_test.go b/x/tokenfactory/types/denoms_test.go index a4395f59a..b1a52ca7b 100644 --- a/x/tokenfactory/types/denoms_test.go +++ b/x/tokenfactory/types/denoms_test.go @@ -5,7 +5,7 @@ import ( "github.com/stretchr/testify/require" - "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/types" + "github.com/CosmosContracts/juno/x/tokenfactory/types" ) func TestDeconstructDenom(t *testing.T) { diff --git a/x/tokenfactory/types/genesis_test.go b/x/tokenfactory/types/genesis_test.go index 7289c62fc..0bebec724 100644 --- a/x/tokenfactory/types/genesis_test.go +++ b/x/tokenfactory/types/genesis_test.go @@ -5,7 +5,7 @@ import ( "github.com/stretchr/testify/require" - "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/types" + "github.com/CosmosContracts/juno/x/tokenfactory/types" ) func TestGenesisState_Validate(t *testing.T) { diff --git a/x/tokenfactory/types/msgs_test.go b/x/tokenfactory/types/msgs_test.go index d713e1ecf..0740aebd0 100644 --- a/x/tokenfactory/types/msgs_test.go +++ b/x/tokenfactory/types/msgs_test.go @@ -7,8 +7,8 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" - "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/testhelpers" - "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/types" + "github.com/CosmosContracts/juno/x/tokenfactory/testhelpers" + "github.com/CosmosContracts/juno/x/tokenfactory/types" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" "github.com/tendermint/tendermint/crypto/ed25519" From c5d4aa76cc2fa24d076e4e7946132b2d27e0fe3f Mon Sep 17 00:00:00 2001 From: Jacob Gadikian Date: Mon, 24 Apr 2023 12:21:35 +0700 Subject: [PATCH 008/131] add modules --- app/ante.go | 2 +- app/app.go | 8 +- app/keepers/keepers.go | 14 +- app/keepers/keys.go | 4 +- app/modules.go | 10 +- app/upgrades/v13/constants.go | 2 +- app/upgrades/v13/upgrades.go | 2 +- app/upgrades/v14/constants.go | 2 +- app/upgrades/v14/upgrades.go | 2 +- go.mod | 8 +- go.sum | 1619 ----------------- .../v1beta1/authorityMetadata.proto | 2 +- .../tokenfactory/v1beta1/genesis.proto | 2 +- .../osmosis/tokenfactory/v1beta1/params.proto | 2 +- .../osmosis/tokenfactory/v1beta1/query.proto | 2 +- proto/osmosis/tokenfactory/v1beta1/tx.proto | 2 +- scripts/protoc_swagger_openapi_gen.sh | 2 +- tests/interchaintest/chain_start_test.go | 6 +- tests/interchaintest/chain_upgrade_test.go | 8 +- tests/interchaintest/ibc_transfer_test.go | 10 +- tests/interchaintest/setup.go | 4 +- x/globalfee/alias.go | 2 +- x/globalfee/ante/antetest/fee_test.go | 8 +- x/globalfee/ante/antetest/fee_test_setup.go | 14 +- x/globalfee/ante/fee.go | 6 +- x/globalfee/client/cli/query.go | 2 +- x/globalfee/genesis_test.go | 14 +- x/globalfee/module.go | 6 +- x/globalfee/querier.go | 2 +- x/globalfee/querier_test.go | 2 +- x/globalfee/types/genesis.pb.go | 4 +- x/globalfee/types/query.pb.go | 6 +- x/tokenfactory/bindings/custom_msg_test.go | 6 +- x/tokenfactory/bindings/custom_query_test.go | 4 +- x/tokenfactory/bindings/helpers_test.go | 10 +- x/tokenfactory/bindings/message_plugin.go | 6 +- x/tokenfactory/bindings/queries.go | 4 +- x/tokenfactory/bindings/query_plugin.go | 2 +- x/tokenfactory/bindings/validate_msg_test.go | 6 +- .../bindings/validate_queries_test.go | 2 +- x/tokenfactory/bindings/wasm.go | 2 +- x/tokenfactory/client/cli/query.go | 2 +- x/tokenfactory/client/cli/tx.go | 2 +- x/tokenfactory/keeper/admins.go | 4 +- x/tokenfactory/keeper/admins_test.go | 2 +- x/tokenfactory/keeper/bankactions.go | 2 +- x/tokenfactory/keeper/createdenom.go | 2 +- x/tokenfactory/keeper/createdenom_test.go | 4 +- x/tokenfactory/keeper/genesis.go | 2 +- x/tokenfactory/keeper/genesis_test.go | 2 +- x/tokenfactory/keeper/grpc_query.go | 2 +- x/tokenfactory/keeper/keeper.go | 4 +- x/tokenfactory/keeper/keeper_test.go | 10 +- x/tokenfactory/keeper/msg_server.go | 2 +- x/tokenfactory/keeper/msg_server_test.go | 2 +- x/tokenfactory/keeper/params.go | 2 +- x/tokenfactory/module.go | 10 +- x/tokenfactory/simulation/genesis.go | 2 +- x/tokenfactory/simulation/operations.go | 5 +- x/tokenfactory/simulation/params.go | 2 +- x/tokenfactory/types/authorityMetadata.pb.go | 2 +- x/tokenfactory/types/denoms_test.go | 2 +- x/tokenfactory/types/genesis.pb.go | 2 +- x/tokenfactory/types/genesis_test.go | 2 +- x/tokenfactory/types/msgs_test.go | 6 +- x/tokenfactory/types/params.pb.go | 2 +- x/tokenfactory/types/query.pb.go | 4 +- x/tokenfactory/types/tx.pb.go | 4 +- 68 files changed, 143 insertions(+), 1765 deletions(-) delete mode 100644 go.sum diff --git a/app/ante.go b/app/ante.go index d83e024d2..6adbe4035 100644 --- a/app/ante.go +++ b/app/ante.go @@ -19,7 +19,7 @@ import ( feeshareante "github.com/CosmosContracts/juno/v15/x/feeshare/ante" feesharekeeper "github.com/CosmosContracts/juno/v15/x/feeshare/keeper" - gaiafeeante "github.com/cosmos/gaia/v9/x/globalfee/ante" + gaiafeeante "github.com/CosmosContracts/juno/v15/x/globalfee/ante" ) const maxBypassMinFeeMsgGasUsage = 1_000_000 diff --git a/app/app.go b/app/app.go index b5b5df66e..5bf458aa8 100644 --- a/app/app.go +++ b/app/app.go @@ -34,7 +34,6 @@ import ( authtx "github.com/cosmos/cosmos-sdk/x/auth/tx" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" "github.com/cosmos/cosmos-sdk/x/crisis" - distrclient "github.com/cosmos/cosmos-sdk/x/distribution/client" govclient "github.com/cosmos/cosmos-sdk/x/gov/client" paramsclient "github.com/cosmos/cosmos-sdk/x/params/client" paramstypes "github.com/cosmos/cosmos-sdk/x/params/types" @@ -53,7 +52,7 @@ import ( wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" "github.com/prometheus/client_golang/prometheus" - "github.com/cosmos/gaia/v9/x/globalfee" + "github.com/CosmosContracts/juno/v15/x/globalfee" "github.com/CosmosContracts/juno/v15/app/keepers" encparams "github.com/CosmosContracts/juno/v15/app/params" @@ -173,9 +172,8 @@ func getGovProposalHandlers() []govclient.ProposalHandler { govProposalHandlers = append(govProposalHandlers, paramsclient.ProposalHandler, - distrclient.ProposalHandler, - upgradeclient.ProposalHandler, - upgradeclient.CancelProposalHandler, + upgradeclient.LegacyProposalHandler, + upgradeclient.LegacyCancelProposalHandler, ibcclientclient.UpdateClientProposalHandler, ibcclientclient.UpgradeProposalHandler, ) diff --git a/app/keepers/keepers.go b/app/keepers/keepers.go index f654e4e46..1e3659f98 100644 --- a/app/keepers/keepers.go +++ b/app/keepers/keepers.go @@ -57,9 +57,9 @@ import ( ibchooks "github.com/osmosis-labs/osmosis/x/ibc-hooks" ibchookskeeper "github.com/osmosis-labs/osmosis/x/ibc-hooks/keeper" - packetforward "github.com/strangelove-ventures/packet-forward-middleware/v4/router" - packetforwardkeeper "github.com/strangelove-ventures/packet-forward-middleware/v4/router/keeper" - packetforwardtypes "github.com/strangelove-ventures/packet-forward-middleware/v4/router/types" + packetforward "github.com/strangelove-ventures/packet-forward-middleware/v7/router" + packetforwardkeeper "github.com/strangelove-ventures/packet-forward-middleware/v7/router/keeper" + packetforwardtypes "github.com/strangelove-ventures/packet-forward-middleware/v7/router/types" "github.com/CosmosContracts/juno/x/tokenfactory/bindings" tokenfactorykeeper "github.com/CosmosContracts/juno/x/tokenfactory/keeper" @@ -72,16 +72,16 @@ import ( feesharekeeper "github.com/CosmosContracts/juno/v15/x/feeshare/keeper" feesharetypes "github.com/CosmosContracts/juno/v15/x/feeshare/types" - icq "github.com/strangelove-ventures/async-icq/v4" - icqkeeper "github.com/strangelove-ventures/async-icq/v4/keeper" - icqtypes "github.com/strangelove-ventures/async-icq/v4/types" + icq "github.com/strangelove-ventures/async-icq/v7" + icqkeeper "github.com/strangelove-ventures/async-icq/v7/keeper" + icqtypes "github.com/strangelove-ventures/async-icq/v7/types" // ica "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts" icacontroller "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller" icacontrollerkeeper "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/keeper" icacontrollertypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/types" - "github.com/cosmos/gaia/v9/x/globalfee" + "github.com/CosmosContracts/juno/v15/x/globalfee" ) var ( diff --git a/app/keepers/keys.go b/app/keepers/keys.go index aa19ea4b0..024d39eb6 100644 --- a/app/keepers/keys.go +++ b/app/keepers/keys.go @@ -25,8 +25,8 @@ import ( ibctransfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" ibchost "github.com/cosmos/ibc-go/v7/modules/core/24-host" ibchookstypes "github.com/osmosis-labs/osmosis/x/ibc-hooks/types" - icqtypes "github.com/strangelove-ventures/async-icq/v4/types" - packetforwardtypes "github.com/strangelove-ventures/packet-forward-middleware/v4/router/types" + icqtypes "github.com/strangelove-ventures/async-icq/v7/types" + packetforwardtypes "github.com/strangelove-ventures/packet-forward-middleware/v7/router/types" ) func (appKeepers *AppKeepers) GenerateKeys() { diff --git a/app/modules.go b/app/modules.go index 629c36d13..49a53b544 100644 --- a/app/modules.go +++ b/app/modules.go @@ -5,6 +5,7 @@ import ( encparams "github.com/CosmosContracts/juno/v15/app/params" feeshare "github.com/CosmosContracts/juno/v15/x/feeshare" feesharetypes "github.com/CosmosContracts/juno/v15/x/feeshare/types" + "github.com/CosmosContracts/juno/v15/x/globalfee" "github.com/CosmosContracts/juno/v15/x/mint" minttypes "github.com/CosmosContracts/juno/v15/x/mint/types" "github.com/CosmosContracts/juno/x/tokenfactory" @@ -41,7 +42,6 @@ import ( stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/cosmos/cosmos-sdk/x/upgrade" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" - "github.com/cosmos/gaia/v9/x/globalfee" ica "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts" icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" ibcfee "github.com/cosmos/ibc-go/v7/modules/apps/29-fee" @@ -52,10 +52,10 @@ import ( ibchost "github.com/cosmos/ibc-go/v7/modules/core/24-host" ibchooks "github.com/osmosis-labs/osmosis/x/ibc-hooks" ibchookstypes "github.com/osmosis-labs/osmosis/x/ibc-hooks/types" - icq "github.com/strangelove-ventures/async-icq/v4" - icqtypes "github.com/strangelove-ventures/async-icq/v4/types" - packetforward "github.com/strangelove-ventures/packet-forward-middleware/v4/router" - packetforwardtypes "github.com/strangelove-ventures/packet-forward-middleware/v4/router/types" + icq "github.com/strangelove-ventures/async-icq/v7" + icqtypes "github.com/strangelove-ventures/async-icq/v7/types" + packetforward "github.com/strangelove-ventures/packet-forward-middleware/v7/router" + packetforwardtypes "github.com/strangelove-ventures/packet-forward-middleware/v7/router/types" ) // module account permissions diff --git a/app/upgrades/v13/constants.go b/app/upgrades/v13/constants.go index 6b1a845d8..85778505f 100644 --- a/app/upgrades/v13/constants.go +++ b/app/upgrades/v13/constants.go @@ -8,7 +8,7 @@ import ( icacontrollertypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/types" ibcfeetypes "github.com/cosmos/ibc-go/v7/modules/apps/29-fee/types" ibchookstypes "github.com/osmosis-labs/osmosis/x/ibc-hooks/types" - packetforwardtypes "github.com/strangelove-ventures/packet-forward-middleware/v4/router/types" + packetforwardtypes "github.com/strangelove-ventures/packet-forward-middleware/v7/router/types" ) // UpgradeName defines the on-chain upgrade name for the upgrade. diff --git a/app/upgrades/v13/upgrades.go b/app/upgrades/v13/upgrades.go index b98802938..64fcf671a 100644 --- a/app/upgrades/v13/upgrades.go +++ b/app/upgrades/v13/upgrades.go @@ -20,7 +20,7 @@ import ( upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" ibcfeetypes "github.com/cosmos/ibc-go/v7/modules/apps/29-fee/types" - packetforwardtypes "github.com/strangelove-ventures/packet-forward-middleware/v4/router/types" + packetforwardtypes "github.com/strangelove-ventures/packet-forward-middleware/v7/router/types" ) func CreateV13UpgradeHandler( diff --git a/app/upgrades/v14/constants.go b/app/upgrades/v14/constants.go index a40ee4812..eadd0e971 100644 --- a/app/upgrades/v14/constants.go +++ b/app/upgrades/v14/constants.go @@ -2,8 +2,8 @@ package v14 import ( "github.com/CosmosContracts/juno/v15/app/upgrades" + "github.com/CosmosContracts/juno/v15/x/globalfee" store "github.com/cosmos/cosmos-sdk/store/types" - "github.com/cosmos/gaia/v9/x/globalfee" ibchookstypes "github.com/osmosis-labs/osmosis/x/ibc-hooks/types" ) diff --git a/app/upgrades/v14/upgrades.go b/app/upgrades/v14/upgrades.go index 7209f594a..a95566e3a 100644 --- a/app/upgrades/v14/upgrades.go +++ b/app/upgrades/v14/upgrades.go @@ -11,7 +11,7 @@ import ( upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" - globalfeetypes "github.com/cosmos/gaia/v9/x/globalfee/types" + globalfeetypes "github.com/CosmosContracts/juno/v15/x/globalfee/types" ) func CreateV14UpgradeHandler( diff --git a/go.mod b/go.mod index 4475af153..d20480ef7 100644 --- a/go.mod +++ b/go.mod @@ -3,9 +3,7 @@ module github.com/CosmosContracts/juno/v15 go 1.19 require ( - github.com/CosmosTokenFactory/token-factory v0.0.0-20230422130917-82986c5b3ec0 github.com/cometbft/cometbft-db v0.7.0 - github.com/cosmos/gaia/v9 v9.0.2 github.com/golang/protobuf v1.5.3 github.com/gorilla/mux v1.8.0 github.com/grpc-ecosystem/grpc-gateway v1.16.0 @@ -14,13 +12,15 @@ require ( github.com/spf13/cast v1.5.0 github.com/spf13/cobra v1.7.0 github.com/stretchr/testify v1.8.2 - github.com/tendermint/tm-db v0.6.8-0.20220506192307-f628bb5dc95b google.golang.org/genproto v0.0.0-20230216225411-c8e22ba71e44 google.golang.org/grpc v1.54.0 gopkg.in/yaml.v2 v2.4.0 ) -require github.com/CosmWasm/wasmd v0.40.0-rc.1.0.20230422061626-b85abcf1d7b8 // indirect +require ( + github.com/CosmWasm/wasmd v0.40.0-rc.1.0.20230422061626-b85abcf1d7b8 // indirect + github.com/cosmos/cosmos-sdk v0.47.1 // indirect +) require ( cosmossdk.io/api v0.3.1 // indirect diff --git a/go.sum b/go.sum deleted file mode 100644 index 7d5df035b..000000000 --- a/go.sum +++ /dev/null @@ -1,1619 +0,0 @@ -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= -cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= -cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= -cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= -cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= -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/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/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/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= -cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= -cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= -cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= -cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= -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= -collectd.org v0.3.0/go.mod h1:A/8DzQBkF6abtvrT2j/AU/4tiBgJWYyh0y/oB/4MlWE= -cosmossdk.io/api v0.2.6 h1:AoNwaLLapcLsphhMK6+o0kZl+D6MMUaHVqSdwinASGU= -cosmossdk.io/api v0.2.6/go.mod h1:u/d+GAxil0nWpl1XnQL8nkziQDIWuBDhv8VnDm/s6dI= -cosmossdk.io/api v0.3.1/go.mod h1:DfHfMkiNA2Uhy8fj0JJlOCYOBp4eWUUJ1te5zBGNyIw= -cosmossdk.io/core v0.5.1 h1:vQVtFrIYOQJDV3f7rw4pjjVqc1id4+mE0L9hHP66pyI= -cosmossdk.io/core v0.5.1/go.mod h1:KZtwHCLjcFuo0nmDc24Xy6CRNEL9Vl/MeimQ2aC7NLE= -cosmossdk.io/depinject v1.0.0-alpha.3 h1:6evFIgj//Y3w09bqOUOzEpFj5tsxBqdc5CfkO7z+zfw= -cosmossdk.io/depinject v1.0.0-alpha.3/go.mod h1:eRbcdQ7MRpIPEM5YUJh8k97nxHpYbc3sMUnEtt8HPWU= -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= -filippo.io/edwards25519 v1.0.0/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/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= -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/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/CloudyKit/fastprinter v0.0.0-20170127035650-74b38d55f37a/go.mod h1:EFZQ978U7x8IRnstaskI3IysnWY5Ao3QgZUKOXlsAdw= -github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno= -github.com/CloudyKit/jet v2.1.3-0.20180809161101-62edd43e4f88+incompatible/go.mod h1:HPYO+50pSWkPoj9Q/eq0aRGByCL6ScRlUmiEX5Zgm+w= -github.com/CloudyKit/jet/v3 v3.0.0/go.mod h1:HKQPgSJmdK8hdoAbKUUWajkHyHo4RaU5rMdUywE7VMo= -github.com/CosmWasm/wasmd v0.31.0 h1:xACf6A/SkCeGWQWrKGsR4X9PQb5G4XYuNfnrl+HQ1mE= -github.com/CosmWasm/wasmd v0.31.0/go.mod h1:VcyDGk/ISVlMUeW+1GGL0zdHWBS2FPwLEV2qZ86l7l8= -github.com/CosmWasm/wasmd v0.40.0-rc.1.0.20230422061626-b85abcf1d7b8 h1:daJIcrTcYkpDtn1DXqbGhnQkCPSD93El6mXfv15VJRA= -github.com/CosmWasm/wasmd v0.40.0-rc.1.0.20230422061626-b85abcf1d7b8/go.mod h1:uacdue6EGn9JA1TqBNHB3iCe4PCIChuFT23AzIl2VME= -github.com/CosmWasm/wasmvm v1.2.3 h1:OKYlobwmVGbl0eSn0mXoAAjE5hIuXnQCLPjbNd91sVY= -github.com/CosmWasm/wasmvm v1.2.3/go.mod h1:vW/E3h8j9xBQs9bCoijDuawKo9kCtxOaS8N8J7KFtkc= -github.com/CosmosTokenFactory/token-factory v0.0.0-20230422130917-82986c5b3ec0 h1:H7RtDJcx8WFK7q9BlJeWog+XLwoaVDozlo70Wvl5B40= -github.com/CosmosTokenFactory/token-factory v0.0.0-20230422130917-82986c5b3ec0/go.mod h1:jgHStegz3SBIbARUc3n63xRP0cmsrJ0NHzfvuxZ3WXI= -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.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= -github.com/DataDog/zstd v1.5.0 h1:+K/VEwIAaPcHiMtQvpLD4lqW7f0Gk3xdYZmI1hD+CXo= -github.com/DataDog/zstd v1.5.0/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= -github.com/HdrHistogram/hdrhistogram-go v1.1.2 h1:5IcZpTvzydCQeHzK4Ef/D5rrSqwxob0t8PQPMybUNFM= -github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo= -github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= -github.com/Joker/jade v1.0.1-0.20190614124447-d475f43051e7/go.mod h1:6E6s8o2AE4KhCrqr6GRJjdC/gNfTdxkIXvuGZZda2VM= -github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= -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= -github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= -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/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= -github.com/Workiva/go-datastructures v1.0.53/go.mod h1:1yZL+zfsztete+ePzZz/Zb1/t5BnDuE2Ya2MMGhzP6A= -github.com/Zilliqa/gozilliqa-sdk v1.2.1-0.20201201074141-dd0ecada1be6/go.mod h1:eSYp2T6f0apnuW8TzhV3f6Aff2SE8Dwio++U4ha4yEM= -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/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= -github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= -github.com/alecthomas/participle/v2 v2.0.0-alpha7 h1:cK4vjj0VSgb3lN1nuKA5F7dw+1s1pWBe5bx7nNCnN+c= -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/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= -github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA= -github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4= -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.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -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/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= -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/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816 h1:41iFGWnSlI2gVpmOtVTJZNodLdLQLn/KsJqFvXwnd/s= -github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816/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.22.2 h1:vBZ+lGGd1XubpOWO67ITJpAEsICWhA0YzqkcpkgNBfo= -github.com/btcsuite/btcd v0.22.2/go.mod h1:wqgTSL29+50LRkmOVknEdmt8ZojIzhuWvgu/iptuN7Y= -github.com/btcsuite/btcd/btcec/v2 v2.1.2/go.mod h1:ctjw4H1kknNJmRN4iP1R7bTQ+v3GJkZBd6mui8ZsAZE= -github.com/btcsuite/btcd/btcec/v2 v2.3.2 h1:5n0X6hX0Zk+6omWcihdYvdAlGf2DfasC0GMf7DClJ3U= -github.com/btcsuite/btcd/btcec/v2 v2.3.2/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= -github.com/btcsuite/btcd/btcutil v1.1.2 h1:XLMbX8JQEiwMcYft2EGi8zPUkoa0abKIU6/BJSRsjzQ= -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-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/go.mod h1:0DVlHczLPewLcPGEIeUEzfOJhqGPQ0mJJRDBtD307+o= -github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= -github.com/btcsuite/goleveldb v1.0.0/go.mod h1:QiK9vBlgftBg6rWQIj6wFzbPfRjiykIEhBH4obrXJ/I= -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= -github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= -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/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -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/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cockroachdb/apd/v3 v3.1.0 h1:MK3Ow7LH0W8zkd5GMKA1PvS9qG3bWFI95WaVNfyZJ/w= -github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= -github.com/cockroachdb/datadriven v1.0.0/go.mod h1:5Ib8Meh+jk1RlHIXej6Pzevx/NLlNvQB9pmSBZErGA4= -github.com/cockroachdb/datadriven v1.0.2/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= -github.com/cockroachdb/errors v1.6.1/go.mod h1:tm6FTP5G81vwJ5lC0SizQo374JNCOPrHyXGitRJoDqM= -github.com/cockroachdb/errors v1.8.1/go.mod h1:qGwQn6JmZ+oMjuLwjWzUNqblqk0xl4CVV3SQbGwK7Ac= -github.com/cockroachdb/errors v1.9.1 h1:yFVvsI0VxmRShfawbt/laCIDy/mtTqqnvoNgiy5bEV8= -github.com/cockroachdb/errors v1.9.1/go.mod h1:2sxOtL2WIc096WSZqZ5h8fa17rdDq9HZOZLBCor4mBk= -github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI= -github.com/cockroachdb/logtags v0.0.0-20211118104740-dabe8e521a4f/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= -github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE= -github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= -github.com/cockroachdb/pebble v0.0.0-20220817183557-09c6e030a677 h1:qbb/AE938DFhOajUYh9+OXELpSF9KZw2ZivtmW6eX1Q= -github.com/cockroachdb/pebble v0.0.0-20220817183557-09c6e030a677/go.mod h1:890yq1fUb9b6dGNwssgeUO5vQV9qfXnCPxAJhBQfXw0= -github.com/cockroachdb/redact v1.0.8/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= -github.com/cockroachdb/redact v1.1.3 h1:AKZds10rFSIj7qADf0g46UixK8NNLwWTNdCIGS5wfSQ= -github.com/cockroachdb/redact v1.1.3/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= -github.com/cockroachdb/sentry-go v0.6.1-cockroachdb.2/go.mod h1:8BT+cPK6xvFOcRlk0R8eg+OTkcqI6baNH4xAkpiYVvQ= -github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= -github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= -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/cometbft/cometbft-db v0.7.0 h1:uBjbrBx4QzU0zOEnU8KxoDl18dMNgDh+zZRUE0ucsbo= -github.com/cometbft/cometbft-db v0.7.0/go.mod h1:yiKJIm2WKrt6x8Cyxtq9YTEcIMPcEe4XPxhgX59Fzf0= -github.com/confio/ics23/go v0.9.0 h1:cWs+wdbS2KRPZezoaaj+qBleXgUk5WOQFMP3CQFGTr4= -github.com/confio/ics23/go v0.9.0/go.mod h1:4LPZ2NYqnYIVRklaozjNR1FScgDJ2s5Xrp+e/mYVRak= -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= -github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= -github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= -github.com/cosmos/btcutil v1.0.5 h1:t+ZFcX77LpKtDBhjucvnOH8C2l2ioGsBNEQ3jef8xFk= -github.com/cosmos/btcutil v1.0.5/go.mod h1:IyB7iuqZMJlthe2tkIFL33xPyzbFYP0XVdS8P5lUPis= -github.com/cosmos/cosmos-db v0.0.0-20221226095112-f3c38ecb5e32 h1:zlCp9n3uwQieELltZWHRmwPmPaZ8+XoL2Sj+A2YJlr8= -github.com/cosmos/cosmos-db v0.0.0-20221226095112-f3c38ecb5e32/go.mod h1:kwMlEC4wWvB48zAShGKVqboJL6w4zCLesaNQ3YLU2BQ= -github.com/cosmos/cosmos-proto v1.0.0-beta.2 h1:X3OKvWgK9Gsejo0F1qs5l8Qn6xJV/AzgIWR2wZ8Nua8= -github.com/cosmos/cosmos-proto v1.0.0-beta.2/go.mod h1:+XRCLJ14pr5HFEHIUcn51IKXD1Fy3rkEQqt4WqmN4V0= -github.com/cosmos/cosmos-sdk v0.45.15 h1:yyLZ9PylnR1DADf9FYGxnn8t3+Y5K2mMUXNUN38MI5A= -github.com/cosmos/cosmos-sdk v0.45.15/go.mod h1:bScuNwWAP0TZJpUf+SHXRU3xGoUPp+X9nAzfeIXts40= -github.com/cosmos/gaia/v9 v9.0.2 h1:RAxt+oZdWsjXFkiwxhK/VgxvV+2LEJLPJJOvwcUVEAo= -github.com/cosmos/gaia/v9 v9.0.2/go.mod h1:eaWmm8GUAkCe6b89+fHdyc7T3QGE4e/vw9GeZakS78c= -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.7 h1:RzYKVnsEC7UIkDnhTIkqEB7LnIQbsySvmNEqPCiPevk= -github.com/cosmos/gogoproto v1.4.7/go.mod h1:gxGePp9qedovvl/StQL2BIJ6qlIBn1+9YxR0IulGBKA= -github.com/cosmos/gogoproto v1.4.8/go.mod h1:hnb0DIEWTv+wdNzNcqus5xCQXq5+CXauq1FJuurRfVY= -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.5 h1:rGA3hOrgNxgRM5wYcSCxgQBap7fW82WZgY78V9po/iY= -github.com/cosmos/iavl v0.19.5/go.mod h1:X9PKD3J0iFxdmgNLa7b2LYWdsGd90ToV5cAONApkEPw= -github.com/cosmos/iavl v0.20.0/go.mod h1:WO7FyvaZJoH65+HFOsDir7xU9FWk2w9cHXNW1XHcl7A= -github.com/cosmos/ibc-go/v4 v4.3.0 h1:yOzVsyZzsv4XPBux8gq+D0LhZn45yGWKjvT+6Vyo5no= -github.com/cosmos/ibc-go/v4 v4.3.0/go.mod h1:CcLvIoi9NNtIbNsxs4KjBGjYhlwqtsmXy1AKARKiMzQ= -github.com/cosmos/interchain-accounts v0.2.6 h1:TV2M2g1/Rb9MCNw1YePdBKE0rcEczNj1RGHT+2iRYas= -github.com/cosmos/keyring v1.2.0 h1:8C1lBP9xhImmIabyXW4c3vFjjLiBdGCmfLUfeZlV1Yo= -github.com/cosmos/keyring v1.2.0/go.mod h1:fc+wB5KTk9wQ9sDx0kFXB3A0MaeGHM9AwRStKOQ5vOA= -github.com/cosmos/ledger-cosmos-go v0.12.2 h1:/XYaBlE2BJxtvpkHiBm97gFGSGmYGKunKyF3nNqAXZA= -github.com/cosmos/ledger-cosmos-go v0.12.2/go.mod h1:ZcqYgnfNJ6lAXe4HPtWgarNEY+B74i+2/8MhZw4ziiI= -github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= -github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -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/creachadair/taskgroup v0.4.2/go.mod h1:qiXUOSrbwAY3u0JPGTzObbE3yf9hcXHDKBZ2ZjpCbgM= -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/cucumber/common/gherkin/go/v22 v22.0.0 h1:4K8NqptbvdOrjL9DEea6HFjSpbdT9+Q5kgLpmmsHYl0= -github.com/cucumber/common/messages/go/v17 v17.1.1 h1:RNqopvIFyLWnKv0LfATh34SWBhXeoFTJnSrgm9cT/Ts= -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 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= -github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 h1:YLtO71vCjJRCBcrPMtQ9nqBsqpA1m5sE92cU+pd5Mcc= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0/go.mod h1:DZGJHZMqrU4JJqFAWUS2UO1+lbSKsdiOoYi9Zzey7Fc= -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 v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= -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/badger/v3 v3.2103.2 h1:dpyM5eCJAtQCBcMCZcT4UBZchuTJgCywerHHgmxfxM8= -github.com/dgraph-io/badger/v3 v3.2103.2/go.mod h1:RHo4/GmYcKKh5Lxu63wLEMHJ70Pac2JqZRYGhlyAo2M= -github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= -github.com/dgraph-io/ristretto v0.0.3/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= -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/dgraph-io/ristretto v0.1.1/go.mod h1:S1GPSBCYCIhmVNfcth17y2zZtQT6wzkzgwUve0VDWWA= -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/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= -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/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/dustin/go-humanize v1.0.1-0.20200219035652-afde56e7acac h1:opbrjaN/L8gg6Xh5D04Tem+8xVcz6ajZlGCs49mQgyg= -github.com/dustin/go-humanize v1.0.1-0.20200219035652-afde56e7acac/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= -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/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 v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= -github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= -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/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw= -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/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= -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/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= -github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/felixge/httpsnoop v1.0.2 h1:+nS9g82KMXccJ/wp0zyRW9ZBHFETmMGtkk+2CTTrW4o= -github.com/felixge/httpsnoop v1.0.2/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= -github.com/flosch/pongo2 v0.0.0-20190707114632-bbf5a6c351f4/go.mod h1:T9YF2M40nIgbVgp3rreNmTged+9HrbNTIQf1PsaIiTA= -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/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/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= -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/getsentry/sentry-go v0.12.0/go.mod h1:NSap0JBYWzHND8oMbyi0+XZhUalc1TBdRL1M71JZW2c= -github.com/getsentry/sentry-go v0.17.0 h1:UustVWnOoDFHBS7IJUB2QK/nB5pap748ZEp0swnQJak= -github.com/getsentry/sentry-go v0.17.0/go.mod h1:B82dxtBvxG0KaPD8/hfSV+VcHD+Lg/xUS4JuQn1P4cM= -github.com/ghemawat/stream v0.0.0-20171120220530-696b145b53b9/go.mod h1:106OIgooyS7OzLDOpUGgm9fA3bQENb/cFSyyBmMoJDs= -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.8.1 h1:4+fr/el88TOO3ewCmQr8cx/CtZ/umlIRIs5M4NTNjf8= -github.com/gin-gonic/gin v1.8.1/go.mod h1:ji8BvRH1azfM+SYow9zQ6SZMvR8qOMZHmsCuWR9tTTk= -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-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= -github.com/go-chi/chi/v5 v5.0.0/go.mod h1:BBug9lr0cqtdAhsu6R4AAdvufI0/XBzAQSsUqJpoZOs= -github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= -github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= -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= -github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= -github.com/go-kit/kit v0.12.0 h1:e4o3o3IsBfAKQh5Qbbiqyfu97Ku7jrO/JbohvztANh4= -github.com/go-kit/kit v0.12.0/go.mod h1:lHd+EkCZPIwYItmGDDRdhinkzX2A1sj+M9biaEaizzs= -github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= -github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= -github.com/go-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU= -github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= -github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= -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-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= -github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= -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.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU= -github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs= -github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho= -github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA= -github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos= -github.com/go-playground/validator/v10 v10.11.1 h1:prmOlTVv+YjZjmRmNSF3VmspqJIxJWXmqUsHwfTRRkQ= -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/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= -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= -github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8= -github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= -github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo= -github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= -github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= -github.com/goccy/go-json v0.9.11 h1:/pAaQDLHEoCq/5FFmSKBswWmK6H0e8g4159Kc/X/nqk= -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/gofrs/uuid v4.3.0+incompatible h1:CaSVZxm5B+7o45rtab4jC2G37WGYX1zQfuU2i6DSvnc= -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/gogo/googleapis v0.0.0-20180223154316-0cd9801be74a/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= -github.com/gogo/googleapis v1.4.1/go.mod h1:2lpHqI5OcWCtVElxXnPt+s8oJvMpySlOyM6xDCrzib4= -github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= -github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= -github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/gogo/status v1.1.0/go.mod h1:BFv9nrluPLmrS0EmGVvLaPNmRosr9KapBYd5/hpY1WM= -github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= -github.com/golang-jwt/jwt/v4 v4.3.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= -github.com/golang-jwt/jwt/v4 v4.4.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= -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= -github.com/golang/glog v1.1.0/go.mod h1:pfYeQZ3JWZoXTV5sFc986z3HTpwQs9At6P4ImfuP3NQ= -github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -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.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= -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= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= -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.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= -github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.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/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= -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/flatbuffers v1.12.1 h1:MVlul7pQNoDzWRLTw5imwYsl+usrS1TXG2H4jg6ImGw= -github.com/google/flatbuffers v1.12.1/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= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -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.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= -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/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/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= -github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -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-20210407192527-94a9f03dee38/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/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/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= -github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4= -github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q= -github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= -github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= -github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/gorilla/websocket v1.4.1/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/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= -github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= -github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= -github.com/grpc-ecosystem/grpc-gateway v1.8.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= -github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c h1:6rhixN/i8ZofjG1Y75iExal34USq5p+wiN1tpie8IrU= -github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c/go.mod h1:NMPJylDgVpX0MLRlPy15sqSwOFv/U1GZ2m21JhFfek0= -github.com/gtank/merlin v0.1.1-0.20191105220539-8318aed1a79f/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/bIQ+s= -github.com/gtank/merlin v0.1.1 h1:eQ90iG7K9pOhtereWsmyRJ6RAwcP4tHTDBHXNg+u5is= -github.com/gtank/merlin v0.1.1/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/bIQ+s= -github.com/gtank/ristretto255 v0.1.2 h1:JEqUCPA1NvLq5DwYtuzigd7ss8fwbYay9fi4/5uMzcc= -github.com/gtank/ristretto255 v0.1.2/go.mod h1:Ph5OpO6c7xKUGROZfWVLiJf9icMDwUeIvY4OmlYW69o= -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-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= -github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= -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-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/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE= -github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -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/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/hdevalence/ed25519consensus v0.1.0/go.mod h1:w3BHWjwJbFU29IRHL1Iqkw3sus+7FctEyM4RqDxYNzo= -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.3-0.20220313090229-ca81a64b4204/go.mod h1:ZxNlw5WqJj6wSsRK5+YfflQGXYfccj5VgQsMNixHM7Y= -github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= -github.com/hydrogen18/memlistener v0.0.0-20141126152155-54553eb933fb/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= -github.com/hydrogen18/memlistener v0.0.0-20200120041712-dcc25e7acd91/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= -github.com/iancoleman/orderedmap v0.2.0 h1:sq1N/TFpYH++aViPcaKjys3bDClUEU7s5B+z6jq8pNA= -github.com/iancoleman/orderedmap v0.2.0/go.mod h1:N0Wam8K1arqPXNWjMo21EXnBPOPp36vB07FNRdD2geA= -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/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= -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.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= -github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/influxdata/flux v0.65.1/go.mod h1:J754/zds0vvpfwuq7Gc2wRdVwEodfpCFM7mYlOw2LqY= -github.com/influxdata/influxdb v1.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/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/iris-contrib/blackfriday v2.0.0+incompatible/go.mod h1:UzZ2bDEoaSGPbkg6SAB4att1aAwTmVIx/5gCVqeyUdI= -github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/+fafWORmlnuysV2EMP8MW+qe0= -github.com/iris-contrib/i18n v0.0.0-20171121225848-987a633949d0/go.mod h1:pMCz62A0xJL6I+umB2YTlFRwWXaDFA0jy+5HzGiJjqI= -github.com/iris-contrib/jade v1.1.3/go.mod h1:H/geBymxJhShH5kecoiOCSssPX7QWYH7UaeZTSWddIk= -github.com/iris-contrib/pongo2 v0.0.1/go.mod h1:Ssh+00+3GAZqSQb30AvBRNxBx7rf0GqwkjqxNd0u65g= -github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw= -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 v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/jhump/protoreflect v1.13.1-0.20220928232736-101791cb1b4c h1:XImQJfpJLmGEEd8ll5yPVyL/aEvmgGHW4WYTyNseLOM= -github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= -github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= -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= -github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= -github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= -github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= -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/juju/errors v0.0.0-20181118221551-089d3ea4e4d5/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q= -github.com/juju/loggo v0.0.0-20180524022052-584905176618/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U= -github.com/juju/testing v0.0.0-20180920084828-472a3e8b2073/go.mod h1:63prj8cnj0tU0S9OHjGJn+b1h0ZghCndfnbQolrYTwA= -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/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= -github.com/karalabe/usb v0.0.2/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU= -github.com/kataras/golog v0.0.9/go.mod h1:12HJgwBIZFNGL0EJnMRhmvGA0PQGx8VFwrZtM4CqbAk= -github.com/kataras/golog v0.0.10/go.mod h1:yJ8YKCmyL+nWjERB90Qwn+bdyBZsaQwU3bTVFgkFIp8= -github.com/kataras/iris/v12 v12.0.1/go.mod h1:udK4vLQKkdDqMGJJVd/msuMtN6hpYJhg/lSzuxjhO+U= -github.com/kataras/iris/v12 v12.1.8/go.mod h1:LMYy4VlP67TQ3Zgriz8RE2h2kMZV2SgMYbq3UhfoFmE= -github.com/kataras/neffos v0.0.10/go.mod h1:ZYmJC07hQPW67eKuzlfY7SO3bC0mw83A3j6im82hfqw= -github.com/kataras/neffos v0.0.14/go.mod h1:8lqADm8PnbeFfL7CLXh1WHw53dG27MC3pgi2R1rmoTE= -github.com/kataras/pio v0.0.0-20190103105442-ea782b38602d/go.mod h1:NV88laa9UiiDuX9AhMbDPkGYSPugBOV6yTZB1l2K9Z0= -github.com/kataras/pio v0.0.2/go.mod h1:hAoW0t9UmXi4R5Oyq5Z4irTbaTsOemSrDGUtaTl7Dro= -github.com/kataras/sitemap v0.0.5/go.mod h1:KY2eugMKiPwsJgx7+U103YZehfvNGOXURubcGyk0Bz8= -github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= -github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= -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.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/compress v1.9.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/compress v1.9.7/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -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.11 h1:Lcadnb3RKGin4FYM/orgq0qde+nc15E5Cbqg4B9Sx9c= -github.com/klauspost/compress v1.15.11/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= -github.com/klauspost/compress v1.16.3/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= -github.com/klauspost/cpuid v0.0.0-20170728055534-ae7887de9fa5/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= -github.com/klauspost/cpuid v1.2.1/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.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -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.1.11/go.mod h1:i541M3Fj6f76NZtHSj7TXnyM8n2gaodfvfxNnFqi74g= -github.com/labstack/echo/v4 v4.2.1/go.mod h1:AA49e0DZ8kk5jTOOCKNuPR6oTnBS0dYiM4FW1e6jwpg= -github.com/labstack/echo/v4 v4.5.0/go.mod h1:czIriw4a0C1dFun+ObrXp7ok03xON0N1awStJ6ArI7Y= -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.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= -github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= -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/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= -github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= -github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= -github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= -github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= -github.com/linxGnu/grocksdb v1.7.10 h1:dz7RY7GnFUA+GJO6jodyxgkUeGMEkPp3ikt9hAcNGEw= -github.com/linxGnu/grocksdb v1.7.10/go.mod h1:0hTf+iA+GOr0jDX4CgIYyJZxqOH9XlBh6KVj8+zmF34= -github.com/lucasjones/reggen v0.0.0-20180717132126-cdb49ff09d77/go.mod h1:5ELEyG+X8f+meRWHuqUOewBOhvHkl7M76pdGEansxW4= -github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= -github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= -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.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.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= -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-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.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= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.17/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.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/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= -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= -github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= -github.com/mediocregopher/mediocre-go-lib v0.0.0-20181029021733-cb65787f37ed/go.mod h1:dSsfyI2zABAdhcbvkXqgxOxrCsbYeHCPgrZkku60dSg= -github.com/mediocregopher/radix/v3 v3.3.0/go.mod h1:EmfVyvspXz1uZEyPBMyGK+kjWiKQGvsUt6O3Pj+LDCQ= -github.com/mediocregopher/radix/v3 v3.4.2/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i4n7wVopoX3x7Bv8= -github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= -github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -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= -github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -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.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= -github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -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/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ= -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= -github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU= -github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/mwitkow/grpc-proxy v0.0.0-20181017164139-0f1106ef9c76/go.mod h1:x5OoJHDHqxHS801UIuhqGl6QdSAEJvtausosHSdazIo= -github.com/naoina/go-stringutil v0.1.0/go.mod h1:XJ2SJL9jCtBh+P9q5btrd/Ylo8XwT/h1USek5+NqSA0= -github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416/go.mod h1:NBIhNtsFMo3G2szEBne+bO4gS192HuIYRqfvOWb4i1E= -github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= -github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= -github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k= -github.com/nats-io/nats.go v1.8.1/go.mod h1:BrFz9vVn0fU3AcH9Vn4Kd7W0NpJ651tD5omQ3M8LwxM= -github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= -github.com/nats-io/nkeys v0.0.2/go.mod h1:dab7URMsZm6Z/jp9Z5UGa87Uutgc2mVpXLC4B7TDb/4= -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/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= -github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= -github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= -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/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo v1.13.0/go.mod h1:+REjRxOmWfHCjfv9TTWB1jD1Frx4XydAD3zm1lskyM0= -github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= -github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= -github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= -github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= -github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= -github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= -github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= -github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= -github.com/onsi/gomega v1.20.0 h1:8W0cWlwFkflGPLltQvLRB7ZVD5HuP6ng320w2IS245Q= -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= -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/osmosis-labs/osmosis/osmoutils v0.0.3-rc0 h1:u91mXL0DbbQdLy95gCkLrM6cxya9b53fuiNkLO04KOE= -github.com/osmosis-labs/osmosis/osmoutils v0.0.3-rc0/go.mod h1:rO4YKI0ZQkS3o4UDhFuQFy+j4eM/as8GLvuBDNBStkQ= -github.com/osmosis-labs/osmosis/x/ibc-hooks v0.0.0-20230201151635-ef43e092d196 h1:V8OgwzvHwvGt2yEHRFsiWUPC647qez2LNgcvLzXgw8U= -github.com/osmosis-labs/osmosis/x/ibc-hooks v0.0.0-20230201151635-ef43e092d196/go.mod h1:eoSRNkeqi3ufOmvY8XcW8y0NgbbaPyBTEn7DTxq8XY4= -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 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/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo= -github.com/pelletier/go-toml/v2 v2.0.6 h1:nrzqCb7j9cDFj2coyLNLaZuJTLjWjlaz6nvTvIwycIU= -github.com/pelletier/go-toml/v2 v2.0.6/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek= -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/petermattis/goid v0.0.0-20221215004737-a150e88a970d/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= -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= -github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= -github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= -github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= -github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -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= -github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= -github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= -github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= -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.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw= -github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= -github.com/prometheus/client_golang v1.15.0/go.mod h1:e9yaBhRPU2pPNsZwE+JdQl0KEt1N9XgF6zxWmaC0xOk= -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/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= -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= -github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= -github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= -github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= -github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE= -github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= -github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc= -github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= -github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.3.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -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/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= -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= -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/gocuke v0.6.2 h1:pHviZ0kKAq2U2hN2q3smKNxct6hS0mGByFMHGnWA97M= -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/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= -github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= -github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o= -github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= -github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= -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/cors v1.8.3/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= -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= -github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= -github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -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/ryanuber/columnize v2.1.0+incompatible/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.3.1 h1:sqv7fDNShgjcaxkO0JNcOAlr8B9+cV5Ey/OB71efZx0= -github.com/sasha-s/go-deadlock v0.3.1/go.mod h1:F73l+cr82YSh10GxyRI6qZiCgK64VaZjwesgfQ1/iLM= -github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g= -github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw= -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/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= -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= -github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= -github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= -github.com/skip-mev/mev-cometbft v0.34.27-mev.18 h1:xoZRzzW4u4Rr4jjXUz7y05AoDZu8W5dGvgeg7jxrt0U= -github.com/skip-mev/mev-cometbft v0.34.27-mev.18/go.mod h1:BcCbhKv7ieM0KEddnYXvQZR+pZykTKReJJYf7YC7qhw= -github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= -github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= -github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -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.3 h1:41FoI0fD7OR7mGcKE/aOiLkGreyf8ifIOQmJANWogMk= -github.com/spf13/afero v1.9.3/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= -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.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= -github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= -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= -github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -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.15.0 h1:js3yy885G8xwJa6iOISGFwd+qlUo5AvyXb7CiihdtiU= -github.com/spf13/viper v1.15.0/go.mod h1:fFcTBJxvhhzSJiZy8n+PeW6t8l+KeT/uTARa0jHOQLA= -github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4/go.mod h1:RZLeN1LMWmRsyYjvAu+I6Dm9QmlDaIIt+Y+4Kd7Tp+Q= -github.com/strangelove-ventures/async-icq/v4 v4.0.0-rc0 h1:foE/5O2/XiqGsdTKx3R0BTfKgW9KnUYyQLZt0WFSesE= -github.com/strangelove-ventures/async-icq/v4 v4.0.0-rc0/go.mod h1:thzXHoaK1MgPDCjN7Rp9A/VcHA4cmjQpKCtVNt2O2xk= -github.com/strangelove-ventures/packet-forward-middleware/v4 v4.0.5 h1:KKUqeGhVBK38+1LwThC8IeIcsJZ6COX5kvhiJroFqCM= -github.com/strangelove-ventures/packet-forward-middleware/v4 v4.0.5/go.mod h1:4zAtg449/JISRmf+sbmqolqSLP+QJBh+EtWkWtt/AKE= -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/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= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= -github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= -github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= -github.com/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.20220721030215-126854af5e6d/go.mod h1:RRCYJbIwD5jmqPI9XoAFR0OcDxqUctll6zUj/+B4S48= -github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c h1:g+WoO5jjkqGAzHWCjJB1zZfXPIAaDpzXIEJ0eS6B5Ok= -github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c/go.mod h1:ahpPrc7HpcfEWDQRZEmnXMzHY03mLDYMCxeDzy46i+8= -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/tm-db v0.6.8-0.20220506192307-f628bb5dc95b h1:Y3ZPG6gdDCAV2sdGkD759ji/09GzaNu1X3qKTmZIbTo= -github.com/tendermint/tm-db v0.6.8-0.20220506192307-f628bb5dc95b/go.mod h1:ADqbS9NOSnBRK9R2RtYC61CdsHmVMD/yXAzcMuPexbU= -github.com/tidwall/btree v1.5.0 h1:iV0yVY/frd7r6qGBXfEYs7DH0gTDgrKTrDjS7xt/IyQ= -github.com/tidwall/btree v1.5.0/go.mod h1:LGm8L/DZjPLmeWGjv5kFrY8dL4uVhMmzmmLYmsObdKE= -github.com/tidwall/btree v1.6.0/go.mod h1:twD9XRA5jj9VUQGELzDO4HPQTNJsoWWfYEL+EUQ2cKY= -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= -github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs= -github.com/tyler-smith/go-bip39 v1.0.2/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs= -github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= -github.com/ugorji/go v1.2.7 h1:qYhyWUUd6WbiM+C6JZAUkIJt/1WrjzNHY9+KCIjVqTo= -github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M= -github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= -github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= -github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= -github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= -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/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= -github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= -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/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= -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/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= -github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= -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/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= -github.com/ybbus/jsonrpc v2.1.2+incompatible/go.mod h1:XJrh1eMSzdIYFbM08flv0wp5G35eRniyeGut1z+LSiE= -github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= -github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= -github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc= -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.1 h1:gQe66rtmyZ8VeGFcOpbuH3r7erYtNEAezCAYu8LdkJo= -github.com/zondax/hid v0.9.1/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= -github.com/zondax/ledger-go v0.14.1 h1:Pip65OOl4iJ84WTpA4BKChvOufMhhbxED3BaihoZN4c= -github.com/zondax/ledger-go v0.14.1/go.mod h1:fZ3Dqg6qcdXWSOJFKMG8GCTnD7slO/RL2feOQv8K320= -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= -go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= -go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= -go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= -go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= -go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= -go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= -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.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= -go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -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-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190909091759-094676da4a83/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -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-20210921155107-089bfa567519/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.5.0 h1:U/0M97KRkSFvyD/3FSmdP5W5swImpNgle/EHFhOsQPE= -golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU= -golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= -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-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= -golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= -golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= -golang.org/x/exp v0.0.0-20200513190911-00229845015e/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= -golang.org/x/exp v0.0.0-20230131160201-f062dba9d201 h1:BEABXpNXLEz0WxtA+6CQIz2xkg80e+1zrhWyMcq8VzE= -golang.org/x/exp v0.0.0-20230131160201-f062dba9d201/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= -golang.org/x/exp v0.0.0-20230321023759-10a507213a29/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= -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= -golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= -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/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.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8= -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-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= -golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200421231249-e086a090c8fd/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -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-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-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -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-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211008194852-3b03d305991f/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-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= -golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= -golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= -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= -golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -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-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -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= -golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -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.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= -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= -golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -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= -golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -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= -golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -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= -golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -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-20200905004654-be1d3432aa8f/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= -golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210112080510-489259a85091/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-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210316164454-77fc1eacc6aa/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-20210403161142-5e06dd20ab57/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-20210603081109-ebe580a85c40/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-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-20210909193231-528a39cd75f3/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-20211007075335-d3039528d8ac/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-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-20220209214540-3681064d5158/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-20220520151302-bc2c85ada10a/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/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.7.0/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.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw= -golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= -golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= -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= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -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/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= -golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -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-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -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-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181221001348-537d06c36207/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= -golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190327201419-c70d86f8b7cf/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200108203644-89082a384178/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-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= -golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= -golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= -golang.org/x/tools v0.0.0-20201022035929-9cf592e881e9/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -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.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= -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/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/gonum v0.8.2 h1:CCXrcPKiGGotvnN6jfUsKk4rRqm7q09/YbKb5xCEvtM= -gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0= -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= -google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= -google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= -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/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/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/genproto v0.0.0-20180518175338-11a468237815/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -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= -google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -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= -google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -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= -google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200324203455-a04cca1dde73/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= -google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= -google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -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-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= -google.golang.org/genproto v0.0.0-20230125152338-dcaf20b6aeaa h1:qQPhfbPO23fwm/9lQr91L1u62Zo6cm+zI+slZT+uf+o= -google.golang.org/genproto v0.0.0-20230125152338-dcaf20b6aeaa/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= -google.golang.org/genproto v0.0.0-20230216225411-c8e22ba71e44/go.mod h1:8B0gmkoRebU8ukX6HP+4wrVQUY1+6PkQ44BSyIlflHA= -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= -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= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= -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.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.29.1 h1:7QBf+IK2gx70Ap/hDsOmam3GE0v9HicjfEdAxE62UoM= -google.golang.org/protobuf v1.29.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.30.0/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-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -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/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= -gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= -gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= -gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c= -gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200619000410-60c24ae608a6/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns= -gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/urfave/cli.v1 v1.20.0/go.mod h1:vuBzUtMdQeixQj8LVd+/98pzhxNGQoyuPBlsXHOQNO0= -gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= -gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20191120175047-4206685974f2/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= -gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= -gotest.tools/v3 v3.4.0 h1:ZazjZUfuVeZGLAmlKKuyv3IKP5orXcwtOwDQH6YVr6o= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -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/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= -nhooyr.io/websocket v1.8.7 h1:usjR2uOr/zjjkVMy0lW+PPohFok7PCow5sDjLgX4P4g= -nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= -pgregory.net/rapid v0.5.5 h1:jkgx1TjbQPD/feRoK+S/mXw9e1uj6WilpHrXJowi6oA= -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= -sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= diff --git a/proto/osmosis/tokenfactory/v1beta1/authorityMetadata.proto b/proto/osmosis/tokenfactory/v1beta1/authorityMetadata.proto index b0c2fe756..a9a370253 100755 --- a/proto/osmosis/tokenfactory/v1beta1/authorityMetadata.proto +++ b/proto/osmosis/tokenfactory/v1beta1/authorityMetadata.proto @@ -4,7 +4,7 @@ package osmosis.tokenfactory.v1beta1; import "gogoproto/gogo.proto"; import "cosmos/base/v1beta1/coin.proto"; -option go_package = "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/types"; +option go_package = "github.com/CosmosContracts/juno/v15/x/tokenfactory/types"; // DenomAuthorityMetadata specifies metadata for addresses that have specific // capabilities over a token factory denom. Right now there is only one Admin diff --git a/proto/osmosis/tokenfactory/v1beta1/genesis.proto b/proto/osmosis/tokenfactory/v1beta1/genesis.proto index a14f0336b..c930a8ade 100755 --- a/proto/osmosis/tokenfactory/v1beta1/genesis.proto +++ b/proto/osmosis/tokenfactory/v1beta1/genesis.proto @@ -5,7 +5,7 @@ import "gogoproto/gogo.proto"; import "osmosis/tokenfactory/v1beta1/authorityMetadata.proto"; import "osmosis/tokenfactory/v1beta1/params.proto"; -option go_package = "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/types"; +option go_package = "github.com/CosmosContracts/juno/v15/x/tokenfactory/types"; // GenesisState defines the tokenfactory module's genesis state. message GenesisState { diff --git a/proto/osmosis/tokenfactory/v1beta1/params.proto b/proto/osmosis/tokenfactory/v1beta1/params.proto index 36ffafa82..9a6c0982d 100755 --- a/proto/osmosis/tokenfactory/v1beta1/params.proto +++ b/proto/osmosis/tokenfactory/v1beta1/params.proto @@ -6,7 +6,7 @@ import "osmosis/tokenfactory/v1beta1/authorityMetadata.proto"; import "cosmos_proto/cosmos.proto"; import "cosmos/base/v1beta1/coin.proto"; -option go_package = "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/types"; +option go_package = "github.com/CosmosContracts/juno/v15/x/tokenfactory/types"; // Params defines the parameters for the tokenfactory module. message Params { diff --git a/proto/osmosis/tokenfactory/v1beta1/query.proto b/proto/osmosis/tokenfactory/v1beta1/query.proto index 0d5795ce8..9ed1f04a9 100755 --- a/proto/osmosis/tokenfactory/v1beta1/query.proto +++ b/proto/osmosis/tokenfactory/v1beta1/query.proto @@ -7,7 +7,7 @@ import "cosmos/base/query/v1beta1/pagination.proto"; import "osmosis/tokenfactory/v1beta1/authorityMetadata.proto"; import "osmosis/tokenfactory/v1beta1/params.proto"; -option go_package = "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/types"; +option go_package = "github.com/CosmosContracts/juno/v15/x/tokenfactory/types"; // Query defines the gRPC querier service. service Query { diff --git a/proto/osmosis/tokenfactory/v1beta1/tx.proto b/proto/osmosis/tokenfactory/v1beta1/tx.proto index 5a95b7047..22a12a7b6 100755 --- a/proto/osmosis/tokenfactory/v1beta1/tx.proto +++ b/proto/osmosis/tokenfactory/v1beta1/tx.proto @@ -5,7 +5,7 @@ import "gogoproto/gogo.proto"; import "cosmos/base/v1beta1/coin.proto"; import "cosmos/bank/v1beta1/bank.proto"; -option go_package = "github.com/CosmosTokenFactory/token-factory/x/tokenfactory/types"; +option go_package = "github.com/CosmosContracts/juno/v15/x/tokenfactory/types"; // Msg defines the tokefactory module's gRPC message service. service Msg { diff --git a/scripts/protoc_swagger_openapi_gen.sh b/scripts/protoc_swagger_openapi_gen.sh index 981042ae8..458942a52 100644 --- a/scripts/protoc_swagger_openapi_gen.sh +++ b/scripts/protoc_swagger_openapi_gen.sh @@ -17,7 +17,7 @@ mkdir -p ./tmp-swagger-gen # Get the paths used repos from go/pkg/mod cosmos_sdk_dir=$(go list -f '{{ .Dir }}' -m github.com/cosmos/cosmos-sdk) wasmd=$(go list -f '{{ .Dir }}' -m github.com/CosmWasm/wasmd) -token_factory=$(go list -f '{{ .Dir }}' -m github.com/CosmosTokenFactory/token-factory) +token_factory=$(go list -f '{{ .Dir }}' -m github.com/CosmosContracts/juno/v15) gaia=$(go list -f '{{ .Dir }}' -m github.com/cosmos/gaia/v9) ica=$(go list -f '{{ .Dir }}' -m github.com/cosmos/interchain-accounts) pfm=$(go list -f '{{ .Dir }}' -m github.com/strangelove-ventures/packet-forward-middleware/v4) diff --git a/tests/interchaintest/chain_start_test.go b/tests/interchaintest/chain_start_test.go index 7a6148545..cda463dd4 100644 --- a/tests/interchaintest/chain_start_test.go +++ b/tests/interchaintest/chain_start_test.go @@ -4,9 +4,9 @@ import ( "context" "testing" - "github.com/strangelove-ventures/interchaintest/v4" - "github.com/strangelove-ventures/interchaintest/v4/chain/cosmos" - "github.com/strangelove-ventures/interchaintest/v4/testreporter" + "github.com/strangelove-ventures/interchaintest/v7" + "github.com/strangelove-ventures/interchaintest/v7/chain/cosmos" + "github.com/strangelove-ventures/interchaintest/v7/testreporter" "github.com/stretchr/testify/require" "go.uber.org/zap/zaptest" ) diff --git a/tests/interchaintest/chain_upgrade_test.go b/tests/interchaintest/chain_upgrade_test.go index e320c8c1f..2c0a640bd 100644 --- a/tests/interchaintest/chain_upgrade_test.go +++ b/tests/interchaintest/chain_upgrade_test.go @@ -5,10 +5,10 @@ import ( "testing" "time" - "github.com/strangelove-ventures/interchaintest/v4" - "github.com/strangelove-ventures/interchaintest/v4/chain/cosmos" - "github.com/strangelove-ventures/interchaintest/v4/ibc" - "github.com/strangelove-ventures/interchaintest/v4/testutil" + "github.com/strangelove-ventures/interchaintest/v7" + "github.com/strangelove-ventures/interchaintest/v7/chain/cosmos" + "github.com/strangelove-ventures/interchaintest/v7/ibc" + "github.com/strangelove-ventures/interchaintest/v7/testutil" "github.com/stretchr/testify/require" "go.uber.org/zap/zaptest" ) diff --git a/tests/interchaintest/ibc_transfer_test.go b/tests/interchaintest/ibc_transfer_test.go index 696e51839..c96bbc203 100644 --- a/tests/interchaintest/ibc_transfer_test.go +++ b/tests/interchaintest/ibc_transfer_test.go @@ -6,11 +6,11 @@ import ( "testing" transfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" - "github.com/strangelove-ventures/interchaintest/v4" - "github.com/strangelove-ventures/interchaintest/v4/chain/cosmos" - "github.com/strangelove-ventures/interchaintest/v4/ibc" - "github.com/strangelove-ventures/interchaintest/v4/testreporter" - "github.com/strangelove-ventures/interchaintest/v4/testutil" + "github.com/strangelove-ventures/interchaintest/v7" + "github.com/strangelove-ventures/interchaintest/v7/chain/cosmos" + "github.com/strangelove-ventures/interchaintest/v7/ibc" + "github.com/strangelove-ventures/interchaintest/v7/testreporter" + "github.com/strangelove-ventures/interchaintest/v7/testutil" "github.com/stretchr/testify/require" "go.uber.org/zap/zaptest" ) diff --git a/tests/interchaintest/setup.go b/tests/interchaintest/setup.go index aa8726faa..d7335ab52 100644 --- a/tests/interchaintest/setup.go +++ b/tests/interchaintest/setup.go @@ -3,8 +3,8 @@ package interchaintest import ( simappparams "cosmossdk.io/simapp/params" feesharetypes "github.com/CosmosContracts/juno/v13/x/feeshare/types" - "github.com/strangelove-ventures/interchaintest/v4/chain/cosmos" - "github.com/strangelove-ventures/interchaintest/v4/ibc" + "github.com/strangelove-ventures/interchaintest/v7/chain/cosmos" + "github.com/strangelove-ventures/interchaintest/v7/ibc" ) var ( diff --git a/x/globalfee/alias.go b/x/globalfee/alias.go index 74e59e386..76a56032e 100644 --- a/x/globalfee/alias.go +++ b/x/globalfee/alias.go @@ -1,7 +1,7 @@ package globalfee import ( - "github.com/cosmos/gaia/v9/x/globalfee/types" + "github.com/CosmosContracts/juno/v15/x/globalfee/types" ) const ( diff --git a/x/globalfee/ante/antetest/fee_test.go b/x/globalfee/ante/antetest/fee_test.go index cf144b1f6..1c156213e 100644 --- a/x/globalfee/ante/antetest/fee_test.go +++ b/x/globalfee/ante/antetest/fee_test.go @@ -7,12 +7,12 @@ import ( "github.com/cosmos/cosmos-sdk/testutil/testdata" sdk "github.com/cosmos/cosmos-sdk/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - ibcclienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - ibcchanneltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" + ibcclienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + ibcchanneltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" "github.com/stretchr/testify/suite" - gaiafeeante "github.com/cosmos/gaia/v9/x/globalfee/ante" - globfeetypes "github.com/cosmos/gaia/v9/x/globalfee/types" + gaiafeeante "github.com/CosmosContracts/juno/v15/x/globalfee/ante" + globfeetypes "github.com/CosmosContracts/juno/v15/x/globalfee/types" ) var testGasLimit uint64 = 200_000 diff --git a/x/globalfee/ante/antetest/fee_test_setup.go b/x/globalfee/ante/antetest/fee_test_setup.go index c1508126a..f21c02a26 100644 --- a/x/globalfee/ante/antetest/fee_test_setup.go +++ b/x/globalfee/ante/antetest/fee_test_setup.go @@ -3,6 +3,8 @@ package antetest import ( "fmt" + tmrand "github.com/cometbft/cometbft/libs/rand" + tmproto "github.com/cometbft/cometbft/proto/tendermint/types" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/tx" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" @@ -13,15 +15,13 @@ import ( "github.com/cosmos/cosmos-sdk/x/params/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/stretchr/testify/suite" - tmrand "github.com/tendermint/tendermint/libs/rand" - tmproto "github.com/tendermint/tendermint/proto/tendermint/types" - gaiahelpers "github.com/cosmos/gaia/v9/app/helpers" - gaiafeeante "github.com/cosmos/gaia/v9/x/globalfee/ante" + gaiahelpers "github.com/CosmosContracts/juno/v15/app/helpers" + gaiafeeante "github.com/CosmosContracts/juno/v15/x/globalfee/ante" - gaiaapp "github.com/cosmos/gaia/v9/app" - "github.com/cosmos/gaia/v9/x/globalfee" - globfeetypes "github.com/cosmos/gaia/v9/x/globalfee/types" + gaiaapp "github.com/CosmosContracts/juno/v15/app" + "github.com/CosmosContracts/juno/v15/x/globalfee" + globfeetypes "github.com/CosmosContracts/juno/v15/x/globalfee/types" ) type IntegrationTestSuite struct { diff --git a/x/globalfee/ante/fee.go b/x/globalfee/ante/fee.go index 909fac4a7..b2fea43be 100644 --- a/x/globalfee/ante/fee.go +++ b/x/globalfee/ante/fee.go @@ -3,14 +3,14 @@ package ante import ( "errors" + tmstrings "github.com/cometbft/cometbft/libs/strings" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - tmstrings "github.com/tendermint/tendermint/libs/strings" - "github.com/cosmos/gaia/v9/x/globalfee" - "github.com/cosmos/gaia/v9/x/globalfee/types" + "github.com/CosmosContracts/juno/v15/x/globalfee" + "github.com/CosmosContracts/juno/v15/x/globalfee/types" ) // FeeWithBypassDecorator checks if the transaction's fee is at least as large diff --git a/x/globalfee/client/cli/query.go b/x/globalfee/client/cli/query.go index be6894a9d..31276612e 100644 --- a/x/globalfee/client/cli/query.go +++ b/x/globalfee/client/cli/query.go @@ -5,7 +5,7 @@ import ( "github.com/cosmos/cosmos-sdk/client/flags" "github.com/spf13/cobra" - "github.com/cosmos/gaia/v9/x/globalfee/types" + "github.com/CosmosContracts/juno/v15/x/globalfee/types" ) func GetQueryCmd() *cobra.Command { diff --git a/x/globalfee/genesis_test.go b/x/globalfee/genesis_test.go index 02f90ce53..03102c34b 100644 --- a/x/globalfee/genesis_test.go +++ b/x/globalfee/genesis_test.go @@ -4,8 +4,11 @@ import ( "testing" "time" - "github.com/cosmos/cosmos-sdk/simapp" - simappparams "github.com/cosmos/cosmos-sdk/simapp/params" + "cosmossdk.io/simapp" + appparams "github.com/CosmosContracts/juno/app/params" + dbm "github.com/cometbft/cometbft-db" + "github.com/cometbft/cometbft/libs/log" + tmproto "github.com/cometbft/cometbft/proto/tendermint/types" "github.com/cosmos/cosmos-sdk/store" storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" @@ -13,11 +16,8 @@ import ( paramstypes "github.com/cosmos/cosmos-sdk/x/params/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/tendermint/tendermint/libs/log" - tmproto "github.com/tendermint/tendermint/proto/tendermint/types" - dbm "github.com/tendermint/tm-db" - "github.com/cosmos/gaia/v9/x/globalfee/types" + "github.com/CosmosContracts/juno/v15/x/globalfee/types" ) func TestDefaultGenesis(t *testing.T) { @@ -106,7 +106,7 @@ func TestInitExportGenesis(t *testing.T) { } } -func setupTestStore(t *testing.T) (sdk.Context, simappparams.EncodingConfig, paramstypes.Subspace) { +func setupTestStore(t *testing.T) (sdk.Context, appparams.EncodingConfig, paramstypes.Subspace) { t.Helper() db := dbm.NewMemDB() ms := store.NewCommitMultiStore(db) diff --git a/x/globalfee/module.go b/x/globalfee/module.go index d2cf91c0f..91072ce0b 100644 --- a/x/globalfee/module.go +++ b/x/globalfee/module.go @@ -4,6 +4,7 @@ import ( "context" "encoding/json" + abci "github.com/cometbft/cometbft/abci/types" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" codectypes "github.com/cosmos/cosmos-sdk/codec/types" @@ -14,10 +15,9 @@ import ( "github.com/gorilla/mux" "github.com/grpc-ecosystem/grpc-gateway/runtime" "github.com/spf13/cobra" - abci "github.com/tendermint/tendermint/abci/types" - "github.com/cosmos/gaia/v9/x/globalfee/client/cli" - "github.com/cosmos/gaia/v9/x/globalfee/types" + "github.com/CosmosContracts/juno/v15/x/globalfee/client/cli" + "github.com/CosmosContracts/juno/v15/x/globalfee/types" ) var ( diff --git a/x/globalfee/querier.go b/x/globalfee/querier.go index 23a06c286..f28cddcfa 100644 --- a/x/globalfee/querier.go +++ b/x/globalfee/querier.go @@ -5,7 +5,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/gaia/v9/x/globalfee/types" + "github.com/CosmosContracts/juno/v15/x/globalfee/types" ) var _ types.QueryServer = &GrpcQuerier{} diff --git a/x/globalfee/querier_test.go b/x/globalfee/querier_test.go index bed110300..9db4914ae 100644 --- a/x/globalfee/querier_test.go +++ b/x/globalfee/querier_test.go @@ -8,7 +8,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/cosmos/gaia/v9/x/globalfee/types" + "github.com/CosmosContracts/juno/v15/x/globalfee/types" ) func TestQueryMinimumGasPrices(t *testing.T) { diff --git a/x/globalfee/types/genesis.pb.go b/x/globalfee/types/genesis.pb.go index bde069af6..9c91da832 100644 --- a/x/globalfee/types/genesis.pb.go +++ b/x/globalfee/types/genesis.pb.go @@ -7,8 +7,8 @@ import ( fmt "fmt" github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types" types "github.com/cosmos/cosmos-sdk/types" - _ "github.com/gogo/protobuf/gogoproto" - proto "github.com/gogo/protobuf/proto" + _ "github.com/cosmos/gogoproto/gogoproto" + proto "github.com/cosmos/gogoproto/proto" io "io" math "math" math_bits "math/bits" diff --git a/x/globalfee/types/query.pb.go b/x/globalfee/types/query.pb.go index 569b6975b..d57e528cb 100644 --- a/x/globalfee/types/query.pb.go +++ b/x/globalfee/types/query.pb.go @@ -8,9 +8,9 @@ import ( fmt "fmt" github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types" types "github.com/cosmos/cosmos-sdk/types" - _ "github.com/gogo/protobuf/gogoproto" - grpc1 "github.com/gogo/protobuf/grpc" - proto "github.com/gogo/protobuf/proto" + _ "github.com/cosmos/gogoproto/gogoproto" + grpc1 "github.com/cosmos/gogoproto/grpc" + proto "github.com/cosmos/gogoproto/proto" _ "google.golang.org/genproto/googleapis/api/annotations" grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" diff --git a/x/tokenfactory/bindings/custom_msg_test.go b/x/tokenfactory/bindings/custom_msg_test.go index ca083a6e1..afcf0a646 100644 --- a/x/tokenfactory/bindings/custom_msg_test.go +++ b/x/tokenfactory/bindings/custom_msg_test.go @@ -11,9 +11,9 @@ import ( wasmvmtypes "github.com/CosmWasm/wasmvm/types" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/CosmosContracts/juno/app" - bindings "github.com/CosmosContracts/juno/x/tokenfactory/bindings/types" - "github.com/CosmosContracts/juno/x/tokenfactory/types" + "github.com/CosmosContracts/juno/v15/app" + bindings "github.com/CosmosContracts/juno/v15/x/tokenfactory/bindings/types" + "github.com/CosmosContracts/juno/v15/x/tokenfactory/types" ) func TestCreateDenomMsg(t *testing.T) { diff --git a/x/tokenfactory/bindings/custom_query_test.go b/x/tokenfactory/bindings/custom_query_test.go index db018ca0a..56a0cbc0f 100644 --- a/x/tokenfactory/bindings/custom_query_test.go +++ b/x/tokenfactory/bindings/custom_query_test.go @@ -10,8 +10,8 @@ import ( wasmvmtypes "github.com/CosmWasm/wasmvm/types" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/CosmosContracts/juno/app" - bindings "github.com/CosmosContracts/juno/x/tokenfactory/bindings/types" + "github.com/CosmosContracts/juno/v15/app" + bindings "github.com/CosmosContracts/juno/v15/x/tokenfactory/bindings/types" ) func TestQueryFullDenom(t *testing.T) { diff --git a/x/tokenfactory/bindings/helpers_test.go b/x/tokenfactory/bindings/helpers_test.go index 496e6481e..969516642 100644 --- a/x/tokenfactory/bindings/helpers_test.go +++ b/x/tokenfactory/bindings/helpers_test.go @@ -7,15 +7,15 @@ import ( "github.com/stretchr/testify/require" - "github.com/tendermint/tendermint/crypto" - "github.com/tendermint/tendermint/crypto/ed25519" - tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + "github.com/cometbft/cometbft/crypto" + "github.com/cometbft/cometbft/crypto/ed25519" + tmproto "github.com/cometbft/cometbft/proto/tendermint/types" - "github.com/cosmos/cosmos-sdk/simapp" + "cosmossdk.io/simapp" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/CosmWasm/wasmd/x/wasm/keeper" - "github.com/CosmosContracts/juno/app" + "github.com/CosmosContracts/juno/v15/app" ) func CreateTestInput() (*app.TokenApp, sdk.Context) { diff --git a/x/tokenfactory/bindings/message_plugin.go b/x/tokenfactory/bindings/message_plugin.go index e7810cf8e..8431b0473 100644 --- a/x/tokenfactory/bindings/message_plugin.go +++ b/x/tokenfactory/bindings/message_plugin.go @@ -10,9 +10,9 @@ import ( bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" - bindingstypes "github.com/CosmosContracts/juno/x/tokenfactory/bindings/types" - tokenfactorykeeper "github.com/CosmosContracts/juno/x/tokenfactory/keeper" - tokenfactorytypes "github.com/CosmosContracts/juno/x/tokenfactory/types" + bindingstypes "github.com/CosmosContracts/juno/v15/x/tokenfactory/bindings/types" + tokenfactorykeeper "github.com/CosmosContracts/juno/v15/x/tokenfactory/keeper" + tokenfactorytypes "github.com/CosmosContracts/juno/v15/x/tokenfactory/types" ) // CustomMessageDecorator returns decorator for custom CosmWasm bindings messages diff --git a/x/tokenfactory/bindings/queries.go b/x/tokenfactory/bindings/queries.go index be414c8e2..5523c140d 100644 --- a/x/tokenfactory/bindings/queries.go +++ b/x/tokenfactory/bindings/queries.go @@ -6,8 +6,8 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" - bindingstypes "github.com/CosmosContracts/juno/x/tokenfactory/bindings/types" - tokenfactorykeeper "github.com/CosmosContracts/juno/x/tokenfactory/keeper" + bindingstypes "github.com/CosmosContracts/juno/v15/x/tokenfactory/bindings/types" + tokenfactorykeeper "github.com/CosmosContracts/juno/v15/x/tokenfactory/keeper" ) type QueryPlugin struct { diff --git a/x/tokenfactory/bindings/query_plugin.go b/x/tokenfactory/bindings/query_plugin.go index f77c4540d..706fc07e9 100644 --- a/x/tokenfactory/bindings/query_plugin.go +++ b/x/tokenfactory/bindings/query_plugin.go @@ -8,7 +8,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - bindingstypes "github.com/CosmosContracts/juno/x/tokenfactory/bindings/types" + bindingstypes "github.com/CosmosContracts/juno/v15/x/tokenfactory/bindings/types" ) // CustomQuerier dispatches custom CosmWasm bindings queries. diff --git a/x/tokenfactory/bindings/validate_msg_test.go b/x/tokenfactory/bindings/validate_msg_test.go index 6e6c5e5ca..430dc9da6 100644 --- a/x/tokenfactory/bindings/validate_msg_test.go +++ b/x/tokenfactory/bindings/validate_msg_test.go @@ -6,9 +6,9 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" - wasmbinding "github.com/CosmosContracts/juno/x/tokenfactory/bindings" - bindings "github.com/CosmosContracts/juno/x/tokenfactory/bindings/types" - "github.com/CosmosContracts/juno/x/tokenfactory/types" + wasmbinding "github.com/CosmosContracts/juno/v15/x/tokenfactory/bindings" + bindings "github.com/CosmosContracts/juno/v15/x/tokenfactory/bindings/types" + "github.com/CosmosContracts/juno/v15/x/tokenfactory/types" "github.com/stretchr/testify/require" ) diff --git a/x/tokenfactory/bindings/validate_queries_test.go b/x/tokenfactory/bindings/validate_queries_test.go index a35ecb24a..5f0a4d9c2 100644 --- a/x/tokenfactory/bindings/validate_queries_test.go +++ b/x/tokenfactory/bindings/validate_queries_test.go @@ -9,7 +9,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" - wasmbinding "github.com/CosmosContracts/juno/x/tokenfactory/bindings" + wasmbinding "github.com/CosmosContracts/juno/v15/x/tokenfactory/bindings" ) func TestFullDenom(t *testing.T) { diff --git a/x/tokenfactory/bindings/wasm.go b/x/tokenfactory/bindings/wasm.go index 2c7f3c3da..7a8db2c1d 100644 --- a/x/tokenfactory/bindings/wasm.go +++ b/x/tokenfactory/bindings/wasm.go @@ -5,7 +5,7 @@ import ( wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" - tokenfactorykeeper "github.com/CosmosContracts/juno/x/tokenfactory/keeper" + tokenfactorykeeper "github.com/CosmosContracts/juno/v15/x/tokenfactory/keeper" bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" ) diff --git a/x/tokenfactory/client/cli/query.go b/x/tokenfactory/client/cli/query.go index 8cf9dd331..099d9c074 100644 --- a/x/tokenfactory/client/cli/query.go +++ b/x/tokenfactory/client/cli/query.go @@ -13,7 +13,7 @@ import ( // "github.com/cosmos/cosmos-sdk/client/flags" // sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/CosmosContracts/juno/x/tokenfactory/types" + "github.com/CosmosContracts/juno/v15/x/tokenfactory/types" ) // GetQueryCmd returns the cli query commands for this module diff --git a/x/tokenfactory/client/cli/tx.go b/x/tokenfactory/client/cli/tx.go index a666ce57a..10acf32e5 100644 --- a/x/tokenfactory/client/cli/tx.go +++ b/x/tokenfactory/client/cli/tx.go @@ -12,7 +12,7 @@ import ( "github.com/cosmos/cosmos-sdk/client/tx" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/CosmosContracts/juno/x/tokenfactory/types" + "github.com/CosmosContracts/juno/v15/x/tokenfactory/types" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" ) diff --git a/x/tokenfactory/keeper/admins.go b/x/tokenfactory/keeper/admins.go index 52ace9802..0c1dfb774 100644 --- a/x/tokenfactory/keeper/admins.go +++ b/x/tokenfactory/keeper/admins.go @@ -2,9 +2,9 @@ package keeper import ( sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/gogo/protobuf/proto" + "github.com/cosmos/gogoproto/proto" - "github.com/CosmosContracts/juno/x/tokenfactory/types" + "github.com/CosmosContracts/juno/v15/x/tokenfactory/types" ) // GetAuthorityMetadata returns the authority metadata for a specific denom diff --git a/x/tokenfactory/keeper/admins_test.go b/x/tokenfactory/keeper/admins_test.go index 2f7c5f7de..b5436bf32 100644 --- a/x/tokenfactory/keeper/admins_test.go +++ b/x/tokenfactory/keeper/admins_test.go @@ -6,7 +6,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" - "github.com/CosmosContracts/juno/x/tokenfactory/types" + "github.com/CosmosContracts/juno/v15/x/tokenfactory/types" ) func (suite *KeeperTestSuite) TestAdminMsgs() { diff --git a/x/tokenfactory/keeper/bankactions.go b/x/tokenfactory/keeper/bankactions.go index 2eae19887..9d7155fc4 100644 --- a/x/tokenfactory/keeper/bankactions.go +++ b/x/tokenfactory/keeper/bankactions.go @@ -5,7 +5,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/CosmosContracts/juno/x/tokenfactory/types" + "github.com/CosmosContracts/juno/v15/x/tokenfactory/types" ) func (k Keeper) mintTo(ctx sdk.Context, amount sdk.Coin, mintTo string) error { diff --git a/x/tokenfactory/keeper/createdenom.go b/x/tokenfactory/keeper/createdenom.go index 6c50340d7..08881e7f1 100644 --- a/x/tokenfactory/keeper/createdenom.go +++ b/x/tokenfactory/keeper/createdenom.go @@ -6,7 +6,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" - "github.com/CosmosContracts/juno/x/tokenfactory/types" + "github.com/CosmosContracts/juno/v15/x/tokenfactory/types" ) // ConvertToBaseToken converts a fee amount in a whitelisted fee token to the base fee token amount diff --git a/x/tokenfactory/keeper/createdenom_test.go b/x/tokenfactory/keeper/createdenom_test.go index d9f5747f3..f23c5b11f 100644 --- a/x/tokenfactory/keeper/createdenom_test.go +++ b/x/tokenfactory/keeper/createdenom_test.go @@ -5,8 +5,8 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/CosmosContracts/juno/x/tokenfactory/testhelpers" - "github.com/CosmosContracts/juno/x/tokenfactory/types" + "github.com/CosmosContracts/juno/v15/x/tokenfactory/testhelpers" + "github.com/CosmosContracts/juno/v15/x/tokenfactory/types" ) func (suite *KeeperTestSuite) TestMsgCreateDenom() { diff --git a/x/tokenfactory/keeper/genesis.go b/x/tokenfactory/keeper/genesis.go index a0b36f0b2..2d29cb192 100644 --- a/x/tokenfactory/keeper/genesis.go +++ b/x/tokenfactory/keeper/genesis.go @@ -3,7 +3,7 @@ package keeper import ( sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/CosmosContracts/juno/x/tokenfactory/types" + "github.com/CosmosContracts/juno/v15/x/tokenfactory/types" ) // InitGenesis initializes the tokenfactory module's state from a provided genesis diff --git a/x/tokenfactory/keeper/genesis_test.go b/x/tokenfactory/keeper/genesis_test.go index 6f2ce0988..6569999ae 100644 --- a/x/tokenfactory/keeper/genesis_test.go +++ b/x/tokenfactory/keeper/genesis_test.go @@ -4,7 +4,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" - "github.com/CosmosContracts/juno/x/tokenfactory/types" + "github.com/CosmosContracts/juno/v15/x/tokenfactory/types" ) func (suite *KeeperTestSuite) TestGenesis() { diff --git a/x/tokenfactory/keeper/grpc_query.go b/x/tokenfactory/keeper/grpc_query.go index 1ef143a40..98f64bc66 100644 --- a/x/tokenfactory/keeper/grpc_query.go +++ b/x/tokenfactory/keeper/grpc_query.go @@ -5,7 +5,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/CosmosContracts/juno/x/tokenfactory/types" + "github.com/CosmosContracts/juno/v15/x/tokenfactory/types" ) var _ types.QueryServer = Keeper{} diff --git a/x/tokenfactory/keeper/keeper.go b/x/tokenfactory/keeper/keeper.go index 00cd09006..5ac68a67e 100644 --- a/x/tokenfactory/keeper/keeper.go +++ b/x/tokenfactory/keeper/keeper.go @@ -3,13 +3,13 @@ package keeper import ( "fmt" - "github.com/tendermint/tendermint/libs/log" + "github.com/cometbft/cometbft/libs/log" "github.com/cosmos/cosmos-sdk/store/prefix" storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/CosmosContracts/juno/x/tokenfactory/types" + "github.com/CosmosContracts/juno/v15/x/tokenfactory/types" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" diff --git a/x/tokenfactory/keeper/keeper_test.go b/x/tokenfactory/keeper/keeper_test.go index fa2668e16..5703d2767 100644 --- a/x/tokenfactory/keeper/keeper_test.go +++ b/x/tokenfactory/keeper/keeper_test.go @@ -3,14 +3,14 @@ package keeper_test import ( "testing" + tmproto "github.com/cometbft/cometbft/proto/tendermint/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/suite" - tmproto "github.com/tendermint/tendermint/proto/tendermint/types" - "github.com/CosmosContracts/juno/app/apptesting" - "github.com/CosmosContracts/juno/x/tokenfactory/keeper" - "github.com/CosmosContracts/juno/x/tokenfactory/testhelpers" - "github.com/CosmosContracts/juno/x/tokenfactory/types" + "github.com/CosmosContracts/juno/v15/app/apptesting" + "github.com/CosmosContracts/juno/v15/x/tokenfactory/keeper" + "github.com/CosmosContracts/juno/v15/x/tokenfactory/testhelpers" + "github.com/CosmosContracts/juno/v15/x/tokenfactory/types" ) type KeeperTestSuite struct { diff --git a/x/tokenfactory/keeper/msg_server.go b/x/tokenfactory/keeper/msg_server.go index d7fc495a9..fdb84e70f 100644 --- a/x/tokenfactory/keeper/msg_server.go +++ b/x/tokenfactory/keeper/msg_server.go @@ -5,7 +5,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/CosmosContracts/juno/x/tokenfactory/types" + "github.com/CosmosContracts/juno/v15/x/tokenfactory/types" ) type msgServer struct { diff --git a/x/tokenfactory/keeper/msg_server_test.go b/x/tokenfactory/keeper/msg_server_test.go index bb12542ee..749a140d3 100644 --- a/x/tokenfactory/keeper/msg_server_test.go +++ b/x/tokenfactory/keeper/msg_server_test.go @@ -3,7 +3,7 @@ package keeper_test import ( "fmt" - "github.com/CosmosContracts/juno/x/tokenfactory/types" + "github.com/CosmosContracts/juno/v15/x/tokenfactory/types" sdk "github.com/cosmos/cosmos-sdk/types" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" diff --git a/x/tokenfactory/keeper/params.go b/x/tokenfactory/keeper/params.go index a02ba6367..663976d2c 100644 --- a/x/tokenfactory/keeper/params.go +++ b/x/tokenfactory/keeper/params.go @@ -1,7 +1,7 @@ package keeper import ( - "github.com/CosmosContracts/juno/x/tokenfactory/types" + "github.com/CosmosContracts/juno/v15/x/tokenfactory/types" sdk "github.com/cosmos/cosmos-sdk/types" ) diff --git a/x/tokenfactory/module.go b/x/tokenfactory/module.go index ba3dd6be5..e2a4f5e32 100644 --- a/x/tokenfactory/module.go +++ b/x/tokenfactory/module.go @@ -14,6 +14,7 @@ import ( "fmt" "math/rand" + abci "github.com/cometbft/cometbft/abci/types" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" cdctypes "github.com/cosmos/cosmos-sdk/codec/types" @@ -22,14 +23,13 @@ import ( "github.com/gorilla/mux" "github.com/grpc-ecosystem/grpc-gateway/runtime" "github.com/spf13/cobra" - abci "github.com/tendermint/tendermint/abci/types" - simulation "github.com/CosmosContracts/juno/x/tokenfactory/simulation" + simulation "github.com/CosmosContracts/juno/v15/x/tokenfactory/simulation" simtypes "github.com/cosmos/cosmos-sdk/types/simulation" - "github.com/CosmosContracts/juno/x/tokenfactory/client/cli" - "github.com/CosmosContracts/juno/x/tokenfactory/keeper" - "github.com/CosmosContracts/juno/x/tokenfactory/types" + "github.com/CosmosContracts/juno/v15/x/tokenfactory/client/cli" + "github.com/CosmosContracts/juno/v15/x/tokenfactory/keeper" + "github.com/CosmosContracts/juno/v15/x/tokenfactory/types" ) var ( diff --git a/x/tokenfactory/simulation/genesis.go b/x/tokenfactory/simulation/genesis.go index d5e0bfa0c..03abe07a8 100644 --- a/x/tokenfactory/simulation/genesis.go +++ b/x/tokenfactory/simulation/genesis.go @@ -3,7 +3,7 @@ package simulation import ( "math/rand" - "github.com/CosmosContracts/juno/x/tokenfactory/types" + "github.com/CosmosContracts/juno/v15/x/tokenfactory/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" ) diff --git a/x/tokenfactory/simulation/operations.go b/x/tokenfactory/simulation/operations.go index 7e0adf368..74244cf67 100644 --- a/x/tokenfactory/simulation/operations.go +++ b/x/tokenfactory/simulation/operations.go @@ -3,10 +3,9 @@ package simulation import ( "math/rand" - "github.com/CosmosContracts/juno/app/params" - "github.com/CosmosContracts/juno/x/tokenfactory/types" + "github.com/CosmosContracts/juno/v15/app/params" + "github.com/CosmosContracts/juno/v15/x/tokenfactory/types" "github.com/cosmos/cosmos-sdk/baseapp" - simappparams "github.com/cosmos/cosmos-sdk/simapp/params" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" simtypes "github.com/cosmos/cosmos-sdk/types/simulation" diff --git a/x/tokenfactory/simulation/params.go b/x/tokenfactory/simulation/params.go index 0983b56a7..f25901d8c 100644 --- a/x/tokenfactory/simulation/params.go +++ b/x/tokenfactory/simulation/params.go @@ -4,7 +4,7 @@ import ( "fmt" "math/rand" - "github.com/CosmosContracts/juno/x/tokenfactory/types" + "github.com/CosmosContracts/juno/v15/x/tokenfactory/types" simtypes "github.com/cosmos/cosmos-sdk/types/simulation" "github.com/cosmos/cosmos-sdk/x/simulation" ) diff --git a/x/tokenfactory/types/authorityMetadata.pb.go b/x/tokenfactory/types/authorityMetadata.pb.go index d8df78772..c0b05a436 100644 --- a/x/tokenfactory/types/authorityMetadata.pb.go +++ b/x/tokenfactory/types/authorityMetadata.pb.go @@ -7,7 +7,7 @@ import ( fmt "fmt" _ "github.com/cosmos/cosmos-sdk/types" _ "github.com/cosmos/gogoproto/gogoproto" - proto "github.com/gogo/protobuf/proto" + proto "github.com/cosmos/gogoproto/proto" io "io" math "math" math_bits "math/bits" diff --git a/x/tokenfactory/types/denoms_test.go b/x/tokenfactory/types/denoms_test.go index b1a52ca7b..038c732c2 100644 --- a/x/tokenfactory/types/denoms_test.go +++ b/x/tokenfactory/types/denoms_test.go @@ -5,7 +5,7 @@ import ( "github.com/stretchr/testify/require" - "github.com/CosmosContracts/juno/x/tokenfactory/types" + "github.com/CosmosContracts/juno/v15/x/tokenfactory/types" ) func TestDeconstructDenom(t *testing.T) { diff --git a/x/tokenfactory/types/genesis.pb.go b/x/tokenfactory/types/genesis.pb.go index 594a86ea9..cfd70aba8 100644 --- a/x/tokenfactory/types/genesis.pb.go +++ b/x/tokenfactory/types/genesis.pb.go @@ -6,7 +6,7 @@ package types import ( fmt "fmt" _ "github.com/cosmos/gogoproto/gogoproto" - proto "github.com/gogo/protobuf/proto" + proto "github.com/cosmos/gogoproto/proto" io "io" math "math" math_bits "math/bits" diff --git a/x/tokenfactory/types/genesis_test.go b/x/tokenfactory/types/genesis_test.go index 0bebec724..c9d64cdca 100644 --- a/x/tokenfactory/types/genesis_test.go +++ b/x/tokenfactory/types/genesis_test.go @@ -5,7 +5,7 @@ import ( "github.com/stretchr/testify/require" - "github.com/CosmosContracts/juno/x/tokenfactory/types" + "github.com/CosmosContracts/juno/v15/x/tokenfactory/types" ) func TestGenesisState_Validate(t *testing.T) { diff --git a/x/tokenfactory/types/msgs_test.go b/x/tokenfactory/types/msgs_test.go index 0740aebd0..efcca3777 100644 --- a/x/tokenfactory/types/msgs_test.go +++ b/x/tokenfactory/types/msgs_test.go @@ -7,11 +7,11 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" - "github.com/CosmosContracts/juno/x/tokenfactory/testhelpers" - "github.com/CosmosContracts/juno/x/tokenfactory/types" + "github.com/CosmosContracts/juno/v15/x/tokenfactory/testhelpers" + "github.com/CosmosContracts/juno/v15/x/tokenfactory/types" + "github.com/cometbft/cometbft/crypto/ed25519" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" - "github.com/tendermint/tendermint/crypto/ed25519" ) // // Test authz serialize and de-serializes for tokenfactory msg. diff --git a/x/tokenfactory/types/params.pb.go b/x/tokenfactory/types/params.pb.go index 63cb9f459..155cd2de6 100644 --- a/x/tokenfactory/types/params.pb.go +++ b/x/tokenfactory/types/params.pb.go @@ -9,7 +9,7 @@ import ( github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types" types "github.com/cosmos/cosmos-sdk/types" _ "github.com/cosmos/gogoproto/gogoproto" - proto "github.com/gogo/protobuf/proto" + proto "github.com/cosmos/gogoproto/proto" io "io" math "math" math_bits "math/bits" diff --git a/x/tokenfactory/types/query.pb.go b/x/tokenfactory/types/query.pb.go index 1e201985d..1400afd87 100644 --- a/x/tokenfactory/types/query.pb.go +++ b/x/tokenfactory/types/query.pb.go @@ -8,8 +8,8 @@ import ( fmt "fmt" _ "github.com/cosmos/cosmos-sdk/types/query" _ "github.com/cosmos/gogoproto/gogoproto" - grpc1 "github.com/gogo/protobuf/grpc" - proto "github.com/gogo/protobuf/proto" + grpc1 "github.com/cosmos/gogoproto/grpc" + proto "github.com/cosmos/gogoproto/proto" _ "google.golang.org/genproto/googleapis/api/annotations" grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" diff --git a/x/tokenfactory/types/tx.pb.go b/x/tokenfactory/types/tx.pb.go index 6b44d792a..d3b7f8c12 100644 --- a/x/tokenfactory/types/tx.pb.go +++ b/x/tokenfactory/types/tx.pb.go @@ -9,8 +9,8 @@ import ( types "github.com/cosmos/cosmos-sdk/types" types1 "github.com/cosmos/cosmos-sdk/x/bank/types" _ "github.com/cosmos/gogoproto/gogoproto" - grpc1 "github.com/gogo/protobuf/grpc" - proto "github.com/gogo/protobuf/proto" + grpc1 "github.com/cosmos/gogoproto/grpc" + proto "github.com/cosmos/gogoproto/proto" grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" From ab9580ccb487260204ee9733168320f56a5b54ee Mon Sep 17 00:00:00 2001 From: Jacob Gadikian Date: Mon, 24 Apr 2023 12:42:17 +0700 Subject: [PATCH 009/131] add ibc hooks --- x/ibc-hooks/.cargo/config | 2 + x/ibc-hooks/README.md | 185 +++++++++++++++ x/ibc-hooks/client/cli/query.go | 76 +++++++ x/ibc-hooks/hooks.go | 144 ++++++++++++ x/ibc-hooks/ibc_module.go | 257 +++++++++++++++++++++ x/ibc-hooks/ics4_middleware.go | 77 +++++++ x/ibc-hooks/keeper/keeper.go | 62 +++++ x/ibc-hooks/sdkmodule.go | 138 ++++++++++++ x/ibc-hooks/types/errors.go | 15 ++ x/ibc-hooks/types/keys.go | 8 + x/ibc-hooks/wasm_hook.go | 386 ++++++++++++++++++++++++++++++++ 11 files changed, 1350 insertions(+) create mode 100644 x/ibc-hooks/.cargo/config create mode 100644 x/ibc-hooks/README.md create mode 100644 x/ibc-hooks/client/cli/query.go create mode 100644 x/ibc-hooks/hooks.go create mode 100644 x/ibc-hooks/ibc_module.go create mode 100644 x/ibc-hooks/ics4_middleware.go create mode 100644 x/ibc-hooks/keeper/keeper.go create mode 100644 x/ibc-hooks/sdkmodule.go create mode 100644 x/ibc-hooks/types/errors.go create mode 100644 x/ibc-hooks/types/keys.go create mode 100644 x/ibc-hooks/wasm_hook.go diff --git a/x/ibc-hooks/.cargo/config b/x/ibc-hooks/.cargo/config new file mode 100644 index 000000000..946af0fab --- /dev/null +++ b/x/ibc-hooks/.cargo/config @@ -0,0 +1,2 @@ +[alias] +wasm = "build --release --lib --target wasm32-unknown-unknown" diff --git a/x/ibc-hooks/README.md b/x/ibc-hooks/README.md new file mode 100644 index 000000000..1955c925d --- /dev/null +++ b/x/ibc-hooks/README.md @@ -0,0 +1,185 @@ +# IBC-hooks + +## Wasm Hooks + +The wasm hook is an IBC middleware which is used to allow ICS-20 token transfers to initiate contract calls. +This allows cross-chain contract calls, that involve token movement. +This is useful for a variety of usecases. +One of primary importance is cross-chain swaps, which is an extremely powerful primitive. + +The mechanism enabling this is a `memo` field on every ICS20 transfer packet as of [IBC v3.4.0](https://medium.com/the-interchain-foundation/moving-beyond-simple-token-transfers-d42b2b1dc29b). +Wasm hooks is an IBC middleware that parses an ICS20 transfer, and if the `memo` field is of a particular form, executes a wasm contract call. We now detail the `memo` format for `wasm` contract calls, and the execution guarantees provided. + +### Cosmwasm Contract Execution Format + +Before we dive into the IBC metadata format, we show the cosmwasm execute message format, so the reader has a sense of what are the fields we need to be setting in. +The cosmwasm `MsgExecuteContract` is defined [here](https://github.com/CosmWasm/wasmd/blob/4fe2fbc8f322efdaf187e2e5c99ce32fd1df06f0/x/wasm/types/tx.pb.go#L340-L349 +) as the following type: + +```go +type MsgExecuteContract struct { + // Sender is the that actor that signed the messages + Sender string + // Contract is the address of the smart contract + Contract string + // Msg json encoded message to be passed to the contract + Msg RawContractMessage + // Funds coins that are transferred to the contract on execution + Funds sdk.Coins +} +``` + +So we detail where we want to get each of these fields from: + +* Sender: We cannot trust the sender of an IBC packet, the counterparty chain has full ability to lie about it. +We cannot risk this sender being confused for a particular user or module address on Osmosis. +So we replace the sender with an account to represent the sender prefixed by the channel and a wasm module prefix. +This is done by setting the sender to `Bech32(Hash("ibc-wasm-hook-intermediary" || channelID || sender))`, where the channelId is the channel id on the local chain. +* Contract: This field should be directly obtained from the ICS-20 packet metadata +* Msg: This field should be directly obtained from the ICS-20 packet metadata. +* Funds: This field is set to the amount of funds being sent over in the ICS 20 packet. One detail is that the denom in the packet is the counterparty chains representation of the denom, so we have to translate it to Osmosis' representation. + +So our constructed cosmwasm message that we execute will look like: + +```go +msg := MsgExecuteContract{ + // Sender is the that actor that signed the messages + Sender: "osmo1-hash-of-channel-and-sender", + // Contract is the address of the smart contract + Contract: packet.data.memo["wasm"]["ContractAddress"], + // Msg json encoded message to be passed to the contract + Msg: packet.data.memo["wasm"]["Msg"], + // Funds coins that are transferred to the contract on execution + Funds: sdk.NewCoin{Denom: ibc.ConvertSenderDenomToLocalDenom(packet.data.Denom), Amount: packet.data.Amount} +``` + +### ICS20 packet structure + +So given the details above, we propogate the implied ICS20 packet data structure. +ICS20 is JSON native, so we use JSON for the memo format. + +```json +{ + //... other ibc fields that we don't care about + "data":{ + "denom": "denom on counterparty chain (e.g. uatom)", // will be transformed to the local denom (ibc/...) + "amount": "1000", + "sender": "addr on counterparty chain", // will be transformed + "receiver": "contract addr or blank", + "memo": { + "wasm": { + "contract": "osmo1contractAddr", + "msg": { + "raw_message_fields": "raw_message_data", + } + } + } + } +} +``` + +An ICS20 packet is formatted correctly for wasmhooks iff the following all hold: + +* `memo` is not blank +* `memo` is valid JSON +* `memo` has at least one key, with value `"wasm"` +* `memo["wasm"]` has exactly two entries, `"contract"` and `"msg"` +* `memo["wasm"]["msg"]` is a valid JSON object +* `receiver == "" || receiver == memo["wasm"]["contract"]` + +We consider an ICS20 packet as directed towards wasmhooks iff all of the following hold: + +* `memo` is not blank +* `memo` is valid JSON +* `memo` has at least one key, with name `"wasm"` + +If an ICS20 packet is not directed towards wasmhooks, wasmhooks doesn't do anything. +If an ICS20 packet is directed towards wasmhooks, and is formated incorrectly, then wasmhooks returns an error. + +### Execution flow + +Pre wasm hooks: + +* Ensure the incoming IBC packet is cryptogaphically valid +* Ensure the incoming IBC packet is not timed out. + +In Wasm hooks, pre packet execution: + +* Ensure the packet is correctly formatted (as defined above) +* Edit the receiver to be the hardcoded IBC module account + +In wasm hooks, post packet execution: + +* Construct wasm message as defined before +* Execute wasm message +* if wasm message has error, return ErrAck +* otherwise continue through middleware + +## Ack callbacks + +A contract that sends an IBC transfer, may need to listen for the ACK from that packet. To allow +contracts to listen on the ack of specific packets, we provide Ack callbacks. + +### Design + +The sender of an IBC transfer packet may specify a callback for when the ack of that packet is received in the memo +field of the transfer packet. + +Crucially, _only_ the IBC packet sender can set the callback. + +### Use case + +The crosschain swaps implementation sends an IBC transfer. If the transfer were to fail, we want to allow the sender +to be able to retrieve their funds (which would otherwise be stuck in the contract). To do this, we allow users to +retrieve the funds after the timeout has passed, but without the ack information, we cannot guarantee that the send +hasn't failed (i.e.: returned an error ack notifying that the receiving change didn't accept it) + +### Implementation + +#### Callback information in memo + +For the callback to be processed, the transfer packet's memo should contain the following in its JSON: + +`{"ibc_callback": "osmo1contractAddr"}` + +The wasm hooks will keep the mapping from the packet's channel and sequence to the contract in storage. When an ack is +received, it will notify the specified contract via a sudo message. + +#### Interface for receiving the Acks and Timeouts + +The contract that awaits the callback should implement the following interface for a sudo message: + +```rust +#[cw_serde] +pub enum IBCLifecycleComplete { + #[serde(rename = "ibc_ack")] + IBCAck { + /// The source channel (osmosis side) of the IBC packet + channel: String, + /// The sequence number that the packet was sent with + sequence: u64, + /// String encoded version of the ack as seen by OnAcknowledgementPacket(..) + ack: String, + /// Weather an ack is a success of failure according to the transfer spec + success: bool, + }, + #[serde(rename = "ibc_timeout")] + IBCTimeout { + /// The source channel (osmosis side) of the IBC packet + channel: String, + /// The sequence number that the packet was sent with + sequence: u64, + }, +} + +/// Message type for `sudo` entry_point +#[cw_serde] +pub enum SudoMsg { + #[serde(rename = "ibc_lifecycle_complete")] + IBCLifecycleComplete(IBCLifecycleComplete), +} +``` + +# Testing strategy + +See go tests. \ No newline at end of file diff --git a/x/ibc-hooks/client/cli/query.go b/x/ibc-hooks/client/cli/query.go new file mode 100644 index 000000000..82f58282a --- /dev/null +++ b/x/ibc-hooks/client/cli/query.go @@ -0,0 +1,76 @@ +package cli + +import ( + "fmt" + "strings" + + "github.com/CosmosContracts/juno/v15/x/ibc-hooks/keeper" + "github.com/cosmos/cosmos-sdk/client/flags" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/version" + "github.com/spf13/cobra" + + "github.com/CosmosContracts/juno/v15/x/ibc-hooks/types" +) + +func indexRunCmd(cmd *cobra.Command, args []string) error { + usageTemplate := `Usage:{{if .HasAvailableSubCommands}} + {{.CommandPath}} [command]{{end}} + +{{if .HasAvailableSubCommands}}Available Commands:{{range .Commands}}{{if .IsAvailableCommand}} + {{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}} + +Use "{{.CommandPath}} [command] --help" for more information about a command.{{end}} +` + cmd.SetUsageTemplate(usageTemplate) + return cmd.Help() +} + +// GetQueryCmd returns the cli query commands for this module. +func GetQueryCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: types.ModuleName, + Short: fmt.Sprintf("Querying commands for the %s module", types.ModuleName), + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + RunE: indexRunCmd, + } + + cmd.AddCommand( + GetCmdWasmSender(), + ) + return cmd +} + +// GetCmdPoolParams return pool params. +func GetCmdWasmSender() *cobra.Command { + cmd := &cobra.Command{ + Use: "wasm-sender ", + Short: "Generate the local address for a wasm hooks sender", + Long: strings.TrimSpace( + fmt.Sprintf(`Generate the local address for a wasm hooks sender. +Example: +$ %s query ibc-hooks wasm-hooks-sender channel-42 juno12smx2wdlyttvyzvzg54y2vnqwq2qjatezqwqxu +`, + version.AppName, + ), + ), + Args: cobra.ExactArgs(2), + RunE: func(cmd *cobra.Command, args []string) error { + channelID := args[0] + originalSender := args[1] + // ToDo: Make this flexible as an arg + prefix := sdk.GetConfig().GetBech32AccountAddrPrefix() + senderBech32, err := keeper.DeriveIntermediateSender(channelID, originalSender, prefix) + if err != nil { + return err + } + fmt.Println(senderBech32) + return nil + }, + } + + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} diff --git a/x/ibc-hooks/hooks.go b/x/ibc-hooks/hooks.go new file mode 100644 index 000000000..1735a5af8 --- /dev/null +++ b/x/ibc-hooks/hooks.go @@ -0,0 +1,144 @@ +package ibc_hooks + +import ( + // external libraries + sdk "github.com/cosmos/cosmos-sdk/types" + capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" + + // ibc-go + channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" + ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" +) + +type Hooks interface{} + +type OnChanOpenInitOverrideHooks interface { + OnChanOpenInitOverride(im IBCMiddleware, ctx sdk.Context, order channeltypes.Order, connectionHops []string, portID string, channelID string, channelCap *capabilitytypes.Capability, counterparty channeltypes.Counterparty, version string) (string, error) +} +type OnChanOpenInitBeforeHooks interface { + OnChanOpenInitBeforeHook(ctx sdk.Context, order channeltypes.Order, connectionHops []string, portID string, channelID string, channelCap *capabilitytypes.Capability, counterparty channeltypes.Counterparty, version string) +} +type OnChanOpenInitAfterHooks interface { + OnChanOpenInitAfterHook(ctx sdk.Context, order channeltypes.Order, connectionHops []string, portID string, channelID string, channelCap *capabilitytypes.Capability, counterparty channeltypes.Counterparty, version string, finalVersion string, err error) +} + +// OnChanOpenTry Hooks +type OnChanOpenTryOverrideHooks interface { + OnChanOpenTryOverride(im IBCMiddleware, ctx sdk.Context, order channeltypes.Order, connectionHops []string, portID, channelID string, channelCap *capabilitytypes.Capability, counterparty channeltypes.Counterparty, counterpartyVersion string) (string, error) +} +type OnChanOpenTryBeforeHooks interface { + OnChanOpenTryBeforeHook(ctx sdk.Context, order channeltypes.Order, connectionHops []string, portID, channelID string, channelCap *capabilitytypes.Capability, counterparty channeltypes.Counterparty, counterpartyVersion string) +} +type OnChanOpenTryAfterHooks interface { + OnChanOpenTryAfterHook(ctx sdk.Context, order channeltypes.Order, connectionHops []string, portID, channelID string, channelCap *capabilitytypes.Capability, counterparty channeltypes.Counterparty, counterpartyVersion string, version string, err error) +} + +// OnChanOpenAck Hooks +type OnChanOpenAckOverrideHooks interface { + OnChanOpenAckOverride(im IBCMiddleware, ctx sdk.Context, portID, channelID string, counterpartyChannelID string, counterpartyVersion string) error +} +type OnChanOpenAckBeforeHooks interface { + OnChanOpenAckBeforeHook(ctx sdk.Context, portID, channelID string, counterpartyChannelID string, counterpartyVersion string) +} +type OnChanOpenAckAfterHooks interface { + OnChanOpenAckAfterHook(ctx sdk.Context, portID, channelID string, counterpartyChannelID string, counterpartyVersion string, err error) +} + +// OnChanOpenConfirm Hooks +type OnChanOpenConfirmOverrideHooks interface { + OnChanOpenConfirmOverride(im IBCMiddleware, ctx sdk.Context, portID, channelID string) error +} +type OnChanOpenConfirmBeforeHooks interface { + OnChanOpenConfirmBeforeHook(ctx sdk.Context, portID, channelID string) +} +type OnChanOpenConfirmAfterHooks interface { + OnChanOpenConfirmAfterHook(ctx sdk.Context, portID, channelID string, err error) +} + +// OnChanCloseInit Hooks +type OnChanCloseInitOverrideHooks interface { + OnChanCloseInitOverride(im IBCMiddleware, ctx sdk.Context, portID, channelID string) error +} +type OnChanCloseInitBeforeHooks interface { + OnChanCloseInitBeforeHook(ctx sdk.Context, portID, channelID string) +} +type OnChanCloseInitAfterHooks interface { + OnChanCloseInitAfterHook(ctx sdk.Context, portID, channelID string, err error) +} + +// OnChanCloseConfirm Hooks +type OnChanCloseConfirmOverrideHooks interface { + OnChanCloseConfirmOverride(im IBCMiddleware, ctx sdk.Context, portID, channelID string) error +} +type OnChanCloseConfirmBeforeHooks interface { + OnChanCloseConfirmBeforeHook(ctx sdk.Context, portID, channelID string) +} +type OnChanCloseConfirmAfterHooks interface { + OnChanCloseConfirmAfterHook(ctx sdk.Context, portID, channelID string, err error) +} + +// OnRecvPacket Hooks +type OnRecvPacketOverrideHooks interface { + OnRecvPacketOverride(im IBCMiddleware, ctx sdk.Context, packet channeltypes.Packet, relayer sdk.AccAddress) ibcexported.Acknowledgement +} +type OnRecvPacketBeforeHooks interface { + OnRecvPacketBeforeHook(ctx sdk.Context, packet channeltypes.Packet, relayer sdk.AccAddress) +} +type OnRecvPacketAfterHooks interface { + OnRecvPacketAfterHook(ctx sdk.Context, packet channeltypes.Packet, relayer sdk.AccAddress, ack ibcexported.Acknowledgement) +} + +// OnAcknowledgementPacket Hooks +type OnAcknowledgementPacketOverrideHooks interface { + OnAcknowledgementPacketOverride(im IBCMiddleware, ctx sdk.Context, packet channeltypes.Packet, acknowledgement []byte, relayer sdk.AccAddress) error +} +type OnAcknowledgementPacketBeforeHooks interface { + OnAcknowledgementPacketBeforeHook(ctx sdk.Context, packet channeltypes.Packet, acknowledgement []byte, relayer sdk.AccAddress) +} +type OnAcknowledgementPacketAfterHooks interface { + OnAcknowledgementPacketAfterHook(ctx sdk.Context, packet channeltypes.Packet, acknowledgement []byte, relayer sdk.AccAddress, err error) +} + +// OnTimeoutPacket Hooks +type OnTimeoutPacketOverrideHooks interface { + OnTimeoutPacketOverride(im IBCMiddleware, ctx sdk.Context, packet channeltypes.Packet, relayer sdk.AccAddress) error +} +type OnTimeoutPacketBeforeHooks interface { + OnTimeoutPacketBeforeHook(ctx sdk.Context, packet channeltypes.Packet, relayer sdk.AccAddress) +} +type OnTimeoutPacketAfterHooks interface { + OnTimeoutPacketAfterHook(ctx sdk.Context, packet channeltypes.Packet, relayer sdk.AccAddress, err error) +} + +// SendPacket Hooks +type SendPacketOverrideHooks interface { + SendPacketOverride(i ICS4Middleware, ctx sdk.Context, chanCap *capabilitytypes.Capability, packet ibcexported.PacketI) error +} +type SendPacketBeforeHooks interface { + SendPacketBeforeHook(ctx sdk.Context, chanCap *capabilitytypes.Capability, packet ibcexported.PacketI) +} +type SendPacketAfterHooks interface { + SendPacketAfterHook(ctx sdk.Context, chanCap *capabilitytypes.Capability, packet ibcexported.PacketI, err error) +} + +// WriteAcknowledgement Hooks +type WriteAcknowledgementOverrideHooks interface { + WriteAcknowledgementOverride(i ICS4Middleware, ctx sdk.Context, chanCap *capabilitytypes.Capability, packet ibcexported.PacketI, ack ibcexported.Acknowledgement) error +} +type WriteAcknowledgementBeforeHooks interface { + WriteAcknowledgementBeforeHook(ctx sdk.Context, chanCap *capabilitytypes.Capability, packet ibcexported.PacketI, ack ibcexported.Acknowledgement) +} +type WriteAcknowledgementAfterHooks interface { + WriteAcknowledgementAfterHook(ctx sdk.Context, chanCap *capabilitytypes.Capability, packet ibcexported.PacketI, ack ibcexported.Acknowledgement, err error) +} + +// GetAppVersion Hooks +type GetAppVersionOverrideHooks interface { + GetAppVersionOverride(i ICS4Middleware, ctx sdk.Context, portID, channelID string) (string, bool) +} +type GetAppVersionBeforeHooks interface { + GetAppVersionBeforeHook(ctx sdk.Context, portID, channelID string) +} +type GetAppVersionAfterHooks interface { + GetAppVersionAfterHook(ctx sdk.Context, portID, channelID string, result string, success bool) +} diff --git a/x/ibc-hooks/ibc_module.go b/x/ibc-hooks/ibc_module.go new file mode 100644 index 000000000..94e542ae0 --- /dev/null +++ b/x/ibc-hooks/ibc_module.go @@ -0,0 +1,257 @@ +package ibc_hooks + +import ( + // external libraries + sdk "github.com/cosmos/cosmos-sdk/types" + capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" + + // ibc-go + channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" + porttypes "github.com/cosmos/ibc-go/v7/modules/core/05-port/types" + ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" +) + +var _ porttypes.Middleware = &IBCMiddleware{} + +type IBCMiddleware struct { + App porttypes.IBCModule + ICS4Middleware *ICS4Middleware +} + +func NewIBCMiddleware(app porttypes.IBCModule, ics4 *ICS4Middleware) IBCMiddleware { + return IBCMiddleware{ + App: app, + ICS4Middleware: ics4, + } +} + +// OnChanOpenInit implements the IBCMiddleware interface +func (im IBCMiddleware) OnChanOpenInit( + ctx sdk.Context, + order channeltypes.Order, + connectionHops []string, + portID string, + channelID string, + channelCap *capabilitytypes.Capability, + counterparty channeltypes.Counterparty, + version string, +) (string, error) { + if hook, ok := im.ICS4Middleware.Hooks.(OnChanOpenInitOverrideHooks); ok { + return hook.OnChanOpenInitOverride(im, ctx, order, connectionHops, portID, channelID, channelCap, counterparty, version) + } + + if hook, ok := im.ICS4Middleware.Hooks.(OnChanOpenInitBeforeHooks); ok { + hook.OnChanOpenInitBeforeHook(ctx, order, connectionHops, portID, channelID, channelCap, counterparty, version) + } + + finalVersion, err := im.App.OnChanOpenInit(ctx, order, connectionHops, portID, channelID, channelCap, counterparty, version) + + if hook, ok := im.ICS4Middleware.Hooks.(OnChanOpenInitAfterHooks); ok { + hook.OnChanOpenInitAfterHook(ctx, order, connectionHops, portID, channelID, channelCap, counterparty, version, finalVersion, err) + } + return version, err +} + +// OnChanOpenTry implements the IBCMiddleware interface +func (im IBCMiddleware) OnChanOpenTry( + ctx sdk.Context, + order channeltypes.Order, + connectionHops []string, + portID, + channelID string, + channelCap *capabilitytypes.Capability, + counterparty channeltypes.Counterparty, + counterpartyVersion string, +) (string, error) { + if hook, ok := im.ICS4Middleware.Hooks.(OnChanOpenTryOverrideHooks); ok { + return hook.OnChanOpenTryOverride(im, ctx, order, connectionHops, portID, channelID, channelCap, counterparty, counterpartyVersion) + } + + if hook, ok := im.ICS4Middleware.Hooks.(OnChanOpenTryBeforeHooks); ok { + hook.OnChanOpenTryBeforeHook(ctx, order, connectionHops, portID, channelID, channelCap, counterparty, counterpartyVersion) + } + + version, err := im.App.OnChanOpenTry(ctx, order, connectionHops, portID, channelID, channelCap, counterparty, counterpartyVersion) + + if hook, ok := im.ICS4Middleware.Hooks.(OnChanOpenTryAfterHooks); ok { + hook.OnChanOpenTryAfterHook(ctx, order, connectionHops, portID, channelID, channelCap, counterparty, counterpartyVersion, version, err) + } + return version, err +} + +// OnChanOpenAck implements the IBCMiddleware interface +func (im IBCMiddleware) OnChanOpenAck( + ctx sdk.Context, + portID, + channelID string, + counterpartyChannelID string, + counterpartyVersion string, +) error { + if hook, ok := im.ICS4Middleware.Hooks.(OnChanOpenAckOverrideHooks); ok { + return hook.OnChanOpenAckOverride(im, ctx, portID, channelID, counterpartyChannelID, counterpartyVersion) + } + + if hook, ok := im.ICS4Middleware.Hooks.(OnChanOpenAckBeforeHooks); ok { + hook.OnChanOpenAckBeforeHook(ctx, portID, channelID, counterpartyChannelID, counterpartyVersion) + } + err := im.App.OnChanOpenAck(ctx, portID, channelID, counterpartyChannelID, counterpartyVersion) + if hook, ok := im.ICS4Middleware.Hooks.(OnChanOpenAckAfterHooks); ok { + hook.OnChanOpenAckAfterHook(ctx, portID, channelID, counterpartyChannelID, counterpartyVersion, err) + } + + return err +} + +// OnChanOpenConfirm implements the IBCMiddleware interface +func (im IBCMiddleware) OnChanOpenConfirm( + ctx sdk.Context, + portID, + channelID string, +) error { + if hook, ok := im.ICS4Middleware.Hooks.(OnChanOpenConfirmOverrideHooks); ok { + return hook.OnChanOpenConfirmOverride(im, ctx, portID, channelID) + } + + if hook, ok := im.ICS4Middleware.Hooks.(OnChanOpenConfirmBeforeHooks); ok { + hook.OnChanOpenConfirmBeforeHook(ctx, portID, channelID) + } + err := im.App.OnChanOpenConfirm(ctx, portID, channelID) + if hook, ok := im.ICS4Middleware.Hooks.(OnChanOpenConfirmAfterHooks); ok { + hook.OnChanOpenConfirmAfterHook(ctx, portID, channelID, err) + } + return err +} + +// OnChanCloseInit implements the IBCMiddleware interface +func (im IBCMiddleware) OnChanCloseInit( + ctx sdk.Context, + portID, + channelID string, +) error { + // Here we can remove the limits when a new channel is closed. For now, they can remove them manually on the contract + if hook, ok := im.ICS4Middleware.Hooks.(OnChanCloseInitOverrideHooks); ok { + return hook.OnChanCloseInitOverride(im, ctx, portID, channelID) + } + + if hook, ok := im.ICS4Middleware.Hooks.(OnChanCloseInitBeforeHooks); ok { + hook.OnChanCloseInitBeforeHook(ctx, portID, channelID) + } + err := im.App.OnChanCloseInit(ctx, portID, channelID) + if hook, ok := im.ICS4Middleware.Hooks.(OnChanCloseInitAfterHooks); ok { + hook.OnChanCloseInitAfterHook(ctx, portID, channelID, err) + } + + return err +} + +// OnChanCloseConfirm implements the IBCMiddleware interface +func (im IBCMiddleware) OnChanCloseConfirm( + ctx sdk.Context, + portID, + channelID string, +) error { + // Here we can remove the limits when a new channel is closed. For now, they can remove them manually on the contract + if hook, ok := im.ICS4Middleware.Hooks.(OnChanCloseConfirmOverrideHooks); ok { + return hook.OnChanCloseConfirmOverride(im, ctx, portID, channelID) + } + + if hook, ok := im.ICS4Middleware.Hooks.(OnChanCloseConfirmBeforeHooks); ok { + hook.OnChanCloseConfirmBeforeHook(ctx, portID, channelID) + } + err := im.App.OnChanCloseConfirm(ctx, portID, channelID) + if hook, ok := im.ICS4Middleware.Hooks.(OnChanCloseConfirmAfterHooks); ok { + hook.OnChanCloseConfirmAfterHook(ctx, portID, channelID, err) + } + + return err +} + +// OnRecvPacket implements the IBCMiddleware interface +func (im IBCMiddleware) OnRecvPacket( + ctx sdk.Context, + packet channeltypes.Packet, + relayer sdk.AccAddress, +) ibcexported.Acknowledgement { + if hook, ok := im.ICS4Middleware.Hooks.(OnRecvPacketOverrideHooks); ok { + return hook.OnRecvPacketOverride(im, ctx, packet, relayer) + } + + if hook, ok := im.ICS4Middleware.Hooks.(OnRecvPacketBeforeHooks); ok { + hook.OnRecvPacketBeforeHook(ctx, packet, relayer) + } + + ack := im.App.OnRecvPacket(ctx, packet, relayer) + + if hook, ok := im.ICS4Middleware.Hooks.(OnRecvPacketAfterHooks); ok { + hook.OnRecvPacketAfterHook(ctx, packet, relayer, ack) + } + + return ack +} + +// OnAcknowledgementPacket implements the IBCMiddleware interface +func (im IBCMiddleware) OnAcknowledgementPacket( + ctx sdk.Context, + packet channeltypes.Packet, + acknowledgement []byte, + relayer sdk.AccAddress, +) error { + if hook, ok := im.ICS4Middleware.Hooks.(OnAcknowledgementPacketOverrideHooks); ok { + return hook.OnAcknowledgementPacketOverride(im, ctx, packet, acknowledgement, relayer) + } + if hook, ok := im.ICS4Middleware.Hooks.(OnAcknowledgementPacketBeforeHooks); ok { + hook.OnAcknowledgementPacketBeforeHook(ctx, packet, acknowledgement, relayer) + } + + err := im.App.OnAcknowledgementPacket(ctx, packet, acknowledgement, relayer) + + if hook, ok := im.ICS4Middleware.Hooks.(OnAcknowledgementPacketAfterHooks); ok { + hook.OnAcknowledgementPacketAfterHook(ctx, packet, acknowledgement, relayer, err) + } + + return err +} + +// OnTimeoutPacket implements the IBCMiddleware interface +func (im IBCMiddleware) OnTimeoutPacket( + ctx sdk.Context, + packet channeltypes.Packet, + relayer sdk.AccAddress, +) error { + if hook, ok := im.ICS4Middleware.Hooks.(OnTimeoutPacketOverrideHooks); ok { + return hook.OnTimeoutPacketOverride(im, ctx, packet, relayer) + } + + if hook, ok := im.ICS4Middleware.Hooks.(OnTimeoutPacketBeforeHooks); ok { + hook.OnTimeoutPacketBeforeHook(ctx, packet, relayer) + } + err := im.App.OnTimeoutPacket(ctx, packet, relayer) + if hook, ok := im.ICS4Middleware.Hooks.(OnTimeoutPacketAfterHooks); ok { + hook.OnTimeoutPacketAfterHook(ctx, packet, relayer, err) + } + + return err +} + +// SendPacket implements the ICS4 Wrapper interface +func (im IBCMiddleware) SendPacket( + ctx sdk.Context, + chanCap *capabilitytypes.Capability, + packet ibcexported.PacketI, +) error { + return im.ICS4Middleware.SendPacket(ctx, chanCap, packet) +} + +// WriteAcknowledgement implements the ICS4 Wrapper interface +func (im IBCMiddleware) WriteAcknowledgement( + ctx sdk.Context, + chanCap *capabilitytypes.Capability, + packet ibcexported.PacketI, + ack ibcexported.Acknowledgement, +) error { + return im.ICS4Middleware.WriteAcknowledgement(ctx, chanCap, packet, ack) +} + +func (im IBCMiddleware) GetAppVersion(ctx sdk.Context, portID, channelID string) (string, bool) { + return im.ICS4Middleware.GetAppVersion(ctx, portID, channelID) +} diff --git a/x/ibc-hooks/ics4_middleware.go b/x/ibc-hooks/ics4_middleware.go new file mode 100644 index 000000000..8e4f7307c --- /dev/null +++ b/x/ibc-hooks/ics4_middleware.go @@ -0,0 +1,77 @@ +package ibc_hooks + +import ( + // external libraries + sdk "github.com/cosmos/cosmos-sdk/types" + capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" + + // ibc-go + porttypes "github.com/cosmos/ibc-go/v7/modules/core/05-port/types" + ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" +) + +var _ porttypes.ICS4Wrapper = &ICS4Middleware{} + +type ICS4Middleware struct { + channel porttypes.ICS4Wrapper + + // Hooks + Hooks Hooks +} + +func NewICS4Middleware(channel porttypes.ICS4Wrapper, hooks Hooks) ICS4Middleware { + return ICS4Middleware{ + channel: channel, + Hooks: hooks, + } +} + +func (i ICS4Middleware) SendPacket(ctx sdk.Context, channelCap *capabilitytypes.Capability, packet ibcexported.PacketI) error { + if hook, ok := i.Hooks.(SendPacketOverrideHooks); ok { + return hook.SendPacketOverride(i, ctx, channelCap, packet) + } + + if hook, ok := i.Hooks.(SendPacketBeforeHooks); ok { + hook.SendPacketBeforeHook(ctx, channelCap, packet) + } + + err := i.channel.SendPacket(ctx, channelCap, packet) + + if hook, ok := i.Hooks.(SendPacketAfterHooks); ok { + hook.SendPacketAfterHook(ctx, channelCap, packet, err) + } + + return err +} + +func (i ICS4Middleware) WriteAcknowledgement(ctx sdk.Context, chanCap *capabilitytypes.Capability, packet ibcexported.PacketI, ack ibcexported.Acknowledgement) error { + if hook, ok := i.Hooks.(WriteAcknowledgementOverrideHooks); ok { + return hook.WriteAcknowledgementOverride(i, ctx, chanCap, packet, ack) + } + + if hook, ok := i.Hooks.(WriteAcknowledgementBeforeHooks); ok { + hook.WriteAcknowledgementBeforeHook(ctx, chanCap, packet, ack) + } + err := i.channel.WriteAcknowledgement(ctx, chanCap, packet, ack) + if hook, ok := i.Hooks.(WriteAcknowledgementAfterHooks); ok { + hook.WriteAcknowledgementAfterHook(ctx, chanCap, packet, ack, err) + } + + return err +} + +func (i ICS4Middleware) GetAppVersion(ctx sdk.Context, portID, channelID string) (string, bool) { + if hook, ok := i.Hooks.(GetAppVersionOverrideHooks); ok { + return hook.GetAppVersionOverride(i, ctx, portID, channelID) + } + + if hook, ok := i.Hooks.(GetAppVersionBeforeHooks); ok { + hook.GetAppVersionBeforeHook(ctx, portID, channelID) + } + version, err := i.channel.GetAppVersion(ctx, portID, channelID) + if hook, ok := i.Hooks.(GetAppVersionAfterHooks); ok { + hook.GetAppVersionAfterHook(ctx, portID, channelID, version, err) + } + + return version, err +} diff --git a/x/ibc-hooks/keeper/keeper.go b/x/ibc-hooks/keeper/keeper.go new file mode 100644 index 000000000..44ad330f5 --- /dev/null +++ b/x/ibc-hooks/keeper/keeper.go @@ -0,0 +1,62 @@ +package keeper + +import ( + "fmt" + + "github.com/cosmos/cosmos-sdk/types/address" + + "github.com/tendermint/tendermint/libs/log" + + "github.com/CosmosContracts/juno/v15/x/ibc-hooks/types" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +type ( + Keeper struct { + storeKey sdk.StoreKey + } +) + +// NewKeeper returns a new instance of the x/ibchooks keeper +func NewKeeper( + storeKey sdk.StoreKey, +) Keeper { + return Keeper{ + storeKey: storeKey, + } +} + +// Logger returns a logger for the x/tokenfactory module +func (k Keeper) Logger(ctx sdk.Context) log.Logger { + return ctx.Logger().With("module", fmt.Sprintf("x/%s", types.ModuleName)) +} + +func GetPacketKey(channel string, packetSequence uint64) []byte { + return []byte(fmt.Sprintf("%s::%d", channel, packetSequence)) +} + +// StorePacketCallback stores which contract will be listening for the ack or timeout of a packet +func (k Keeper) StorePacketCallback(ctx sdk.Context, channel string, packetSequence uint64, contract string) { + store := ctx.KVStore(k.storeKey) + store.Set(GetPacketKey(channel, packetSequence), []byte(contract)) +} + +// GetPacketCallback returns the bech32 addr of the contract that is expecting a callback from a packet +func (k Keeper) GetPacketCallback(ctx sdk.Context, channel string, packetSequence uint64) string { + store := ctx.KVStore(k.storeKey) + return string(store.Get(GetPacketKey(channel, packetSequence))) +} + +// DeletePacketCallback deletes the callback from storage once it has been processed +func (k Keeper) DeletePacketCallback(ctx sdk.Context, channel string, packetSequence uint64) { + store := ctx.KVStore(k.storeKey) + store.Delete(GetPacketKey(channel, packetSequence)) +} + +func DeriveIntermediateSender(channel, originalSender, bech32Prefix string) (string, error) { + senderStr := fmt.Sprintf("%s/%s", channel, originalSender) + senderHash32 := address.Hash(types.SenderPrefix, []byte(senderStr)) + sender := sdk.AccAddress(senderHash32[:]) + return sdk.Bech32ifyAddressBytes(bech32Prefix, sender) +} diff --git a/x/ibc-hooks/sdkmodule.go b/x/ibc-hooks/sdkmodule.go new file mode 100644 index 000000000..5c4ea5ad9 --- /dev/null +++ b/x/ibc-hooks/sdkmodule.go @@ -0,0 +1,138 @@ +package ibc_hooks + +import ( + "encoding/json" + "fmt" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/types/module" + "github.com/gorilla/mux" + "github.com/grpc-ecosystem/grpc-gateway/runtime" + "github.com/spf13/cobra" + + "github.com/CosmosContracts/juno/v15/x/ibc-hooks/client/cli" + "github.com/CosmosContracts/juno/v15/x/ibc-hooks/types" + + cdctypes "github.com/cosmos/cosmos-sdk/codec/types" + + "github.com/CosmosContracts/juno/v15/osmoutils" + + sdk "github.com/cosmos/cosmos-sdk/types" + abci "github.com/tendermint/tendermint/abci/types" +) + +var ( + _ module.AppModule = AppModule{} + _ module.AppModuleBasic = AppModuleBasic{} +) + +// AppModuleBasic defines the basic application module used by the ibc-hooks module. +type AppModuleBasic struct{} + +var _ module.AppModuleBasic = AppModuleBasic{} + +// Name returns the ibc-hooks module's name. +func (AppModuleBasic) Name() string { + return types.ModuleName +} + +// RegisterLegacyAminoCodec registers the ibc-hooks module's types on the given LegacyAmino codec. +func (AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) {} + +// RegisterInterfaces registers the module's interface types. +func (b AppModuleBasic) RegisterInterfaces(_ cdctypes.InterfaceRegistry) {} + +// DefaultGenesis returns default genesis state as raw bytes for the +// module. +func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage { + emptyString := "{}" + return []byte(emptyString) +} + +// ValidateGenesis performs genesis state validation for the ibc-hooks module. +func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, config client.TxEncodingConfig, bz json.RawMessage) error { + return nil +} + +// RegisterRESTRoutes registers the REST routes for the ibc-hooks module. +func (AppModuleBasic) RegisterRESTRoutes(clientCtx client.Context, rtr *mux.Router) {} + +// RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the ibc-hooks module. +func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) {} + +// GetTxCmd returns no root tx command for the ibc-hooks module. +func (AppModuleBasic) GetTxCmd() *cobra.Command { return nil } + +// GetQueryCmd returns the root query command for the ibc-hooks module. +func (AppModuleBasic) GetQueryCmd() *cobra.Command { + return cli.GetQueryCmd() +} + +// ___________________________________________________________________________ + +// AppModule implements an application module for the ibc-hooks module. +type AppModule struct { + AppModuleBasic + + authKeeper osmoutils.AccountKeeper +} + +// NewAppModule creates a new AppModule object. +func NewAppModule(ak osmoutils.AccountKeeper) AppModule { + return AppModule{ + AppModuleBasic: AppModuleBasic{}, + authKeeper: ak, + } +} + +// Name returns the ibc-hooks module's name. +func (AppModule) Name() string { + return types.ModuleName +} + +// RegisterInvariants registers the ibc-hooks module invariants. +func (am AppModule) RegisterInvariants(_ sdk.InvariantRegistry) {} + +// Route returns the message routing key for the ibc-hooks module. +func (AppModule) Route() sdk.Route { return sdk.Route{} } + +// QuerierRoute returns the module's querier route name. +func (AppModule) QuerierRoute() string { + return "" +} + +// LegacyQuerierHandler returns the x/ibc-hooks module's sdk.Querier. +func (am AppModule) LegacyQuerierHandler(legacyQuerierCdc *codec.LegacyAmino) sdk.Querier { + return func(sdk.Context, []string, abci.RequestQuery) ([]byte, error) { + return nil, fmt.Errorf("legacy querier not supported for the x/%s module", types.ModuleName) + } +} + +// RegisterServices registers a gRPC query service to respond to the +// module-specific gRPC queries. +func (am AppModule) RegisterServices(cfg module.Configurator) { +} + +// InitGenesis performs genesis initialization for the ibc-hooks module. It returns +// no validator updates. +func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, data json.RawMessage) []abci.ValidatorUpdate { + return []abci.ValidatorUpdate{} +} + +func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.RawMessage { + return json.RawMessage([]byte("{}")) +} + +// BeginBlock returns the begin blocker for the ibc-hooks module. +func (am AppModule) BeginBlock(ctx sdk.Context, _ abci.RequestBeginBlock) { +} + +// EndBlock returns the end blocker for the ibc-hooks module. It returns no validator +// updates. +func (AppModule) EndBlock(_ sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate { + return []abci.ValidatorUpdate{} +} + +// ConsensusVersion implements AppModule/ConsensusVersion. +func (AppModule) ConsensusVersion() uint64 { return 1 } diff --git a/x/ibc-hooks/types/errors.go b/x/ibc-hooks/types/errors.go new file mode 100644 index 000000000..9683d397f --- /dev/null +++ b/x/ibc-hooks/types/errors.go @@ -0,0 +1,15 @@ +package types + +import sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + +var ( + ErrBadMetadataFormatMsg = "wasm metadata not properly formatted for: '%v'. %s" + ErrBadExecutionMsg = "cannot execute contract: %v" + + ErrMsgValidation = sdkerrors.Register("wasm-hooks", 2, "error in wasmhook message validation") + ErrMarshaling = sdkerrors.Register("wasm-hooks", 3, "cannot marshal the ICS20 packet") + ErrInvalidPacket = sdkerrors.Register("wasm-hooks", 4, "invalid packet data") + ErrBadResponse = sdkerrors.Register("wasm-hooks", 5, "cannot create response") + ErrWasmError = sdkerrors.Register("wasm-hooks", 6, "wasm error") + ErrBadSender = sdkerrors.Register("wasm-hooks", 7, "bad sender") +) diff --git a/x/ibc-hooks/types/keys.go b/x/ibc-hooks/types/keys.go new file mode 100644 index 000000000..9a3e7ded1 --- /dev/null +++ b/x/ibc-hooks/types/keys.go @@ -0,0 +1,8 @@ +package types + +const ( + ModuleName = "ibchooks" + StoreKey = "hooks-for-ibc" // not using the module name because of collisions with key "ibc" + IBCCallbackKey = "ibc_callback" + SenderPrefix = "ibc-wasm-hook-intermediary" +) diff --git a/x/ibc-hooks/wasm_hook.go b/x/ibc-hooks/wasm_hook.go new file mode 100644 index 000000000..e941f7808 --- /dev/null +++ b/x/ibc-hooks/wasm_hook.go @@ -0,0 +1,386 @@ +package ibc_hooks + +import ( + "encoding/json" + "fmt" + + wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" + "github.com/CosmosContracts/juno/v15/x/ibc-hooks/keeper" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" + + wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" + + "github.com/CosmosContracts/juno/v15/osmoutils" + + sdk "github.com/cosmos/cosmos-sdk/types" + transfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" + channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" + ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" + + "github.com/CosmosContracts/juno/v15/x/ibc-hooks/types" +) + +type ContractAck struct { + ContractResult []byte `json:"contract_result"` + IbcAck []byte `json:"ibc_ack"` +} + +type WasmHooks struct { + ContractKeeper *wasmkeeper.PermissionedKeeper + ibcHooksKeeper *keeper.Keeper + bech32PrefixAccAddr string +} + +func NewWasmHooks(ibcHooksKeeper *keeper.Keeper, contractKeeper *wasmkeeper.PermissionedKeeper, bech32PrefixAccAddr string) WasmHooks { + return WasmHooks{ + ContractKeeper: contractKeeper, + ibcHooksKeeper: ibcHooksKeeper, + bech32PrefixAccAddr: bech32PrefixAccAddr, + } +} + +func (h WasmHooks) ProperlyConfigured() bool { + return h.ContractKeeper != nil && h.ibcHooksKeeper != nil +} + +func (h WasmHooks) OnRecvPacketOverride(im IBCMiddleware, ctx sdk.Context, packet channeltypes.Packet, relayer sdk.AccAddress) ibcexported.Acknowledgement { + if !h.ProperlyConfigured() { + // Not configured + return im.App.OnRecvPacket(ctx, packet, relayer) + } + isIcs20, data := isIcs20Packet(packet) + if !isIcs20 { + return im.App.OnRecvPacket(ctx, packet, relayer) + } + + // Validate the memo + isWasmRouted, contractAddr, msgBytes, err := ValidateAndParseMemo(data.GetMemo(), data.Receiver) + if !isWasmRouted { + return im.App.OnRecvPacket(ctx, packet, relayer) + } + if err != nil { + return osmoutils.NewEmitErrorAcknowledgement(ctx, types.ErrMsgValidation, err.Error()) + } + if msgBytes == nil || contractAddr == nil { // This should never happen + return osmoutils.NewEmitErrorAcknowledgement(ctx, types.ErrMsgValidation) + } + + // Calculate the receiver / contract caller based on the packet's channel and sender + channel := packet.GetDestChannel() + sender := data.GetSender() + senderBech32, err := keeper.DeriveIntermediateSender(channel, sender, h.bech32PrefixAccAddr) + if err != nil { + return osmoutils.NewEmitErrorAcknowledgement(ctx, types.ErrBadSender, fmt.Sprintf("cannot convert sender address %s/%s to bech32: %s", channel, sender, err.Error())) + } + + // The funds sent on this packet need to be transferred to the intermediary account for the sender. + // For this, we override the ICS20 packet's Receiver (essentially hijacking the funds to this new address) + // and execute the underlying OnRecvPacket() call (which should eventually land on the transfer app's + // relay.go and send the sunds to the intermediary account. + // + // If that succeeds, we make the contract call + data.Receiver = senderBech32 + bz, err := json.Marshal(data) + if err != nil { + return osmoutils.NewEmitErrorAcknowledgement(ctx, types.ErrMarshaling, err.Error()) + } + packet.Data = bz + + // Execute the receive + ack := im.App.OnRecvPacket(ctx, packet, relayer) + if !ack.Success() { + return ack + } + + amount, ok := sdk.NewIntFromString(data.GetAmount()) + if !ok { + // This should never happen, as it should've been caught in the underlaying call to OnRecvPacket, + // but returning here for completeness + return osmoutils.NewEmitErrorAcknowledgement(ctx, types.ErrInvalidPacket, "Amount is not an int") + } + + // The packet's denom is the denom in the sender chain. This needs to be converted to the local denom. + denom := osmoutils.MustExtractDenomFromPacketOnRecv(packet) + funds := sdk.NewCoins(sdk.NewCoin(denom, amount)) + + // Execute the contract + execMsg := wasmtypes.MsgExecuteContract{ + Sender: senderBech32, + Contract: contractAddr.String(), + Msg: msgBytes, + Funds: funds, + } + response, err := h.execWasmMsg(ctx, &execMsg) + if err != nil { + return osmoutils.NewEmitErrorAcknowledgement(ctx, types.ErrWasmError, err.Error()) + } + + fullAck := ContractAck{ContractResult: response.Data, IbcAck: ack.Acknowledgement()} + bz, err = json.Marshal(fullAck) + if err != nil { + return osmoutils.NewEmitErrorAcknowledgement(ctx, types.ErrBadResponse, err.Error()) + } + + return channeltypes.NewResultAcknowledgement(bz) +} + +func (h WasmHooks) execWasmMsg(ctx sdk.Context, execMsg *wasmtypes.MsgExecuteContract) (*wasmtypes.MsgExecuteContractResponse, error) { + if err := execMsg.ValidateBasic(); err != nil { + return nil, fmt.Errorf(types.ErrBadExecutionMsg, err.Error()) + } + wasmMsgServer := wasmkeeper.NewMsgServerImpl(h.ContractKeeper) + return wasmMsgServer.ExecuteContract(sdk.WrapSDKContext(ctx), execMsg) +} + +func isIcs20Packet(packet channeltypes.Packet) (isIcs20 bool, ics20data transfertypes.FungibleTokenPacketData) { + var data transfertypes.FungibleTokenPacketData + if err := json.Unmarshal(packet.GetData(), &data); err != nil { + return false, data + } + return true, data +} + +// jsonStringHasKey parses the memo as a json object and checks if it contains the key. +func jsonStringHasKey(memo, key string) (found bool, jsonObject map[string]interface{}) { + jsonObject = make(map[string]interface{}) + + // If there is no memo, the packet was either sent with an earlier version of IBC, or the memo was + // intentionally left blank. Nothing to do here. Ignore the packet and pass it down the stack. + if len(memo) == 0 { + return false, jsonObject + } + + // the jsonObject must be a valid JSON object + err := json.Unmarshal([]byte(memo), &jsonObject) + if err != nil { + return false, jsonObject + } + + // If the key doesn't exist, there's nothing to do on this hook. Continue by passing the packet + // down the stack + _, ok := jsonObject[key] + if !ok { + return false, jsonObject + } + + return true, jsonObject +} + +func ValidateAndParseMemo(memo string, receiver string) (isWasmRouted bool, contractAddr sdk.AccAddress, msgBytes []byte, err error) { + isWasmRouted, metadata := jsonStringHasKey(memo, "wasm") + if !isWasmRouted { + return isWasmRouted, sdk.AccAddress{}, nil, nil + } + + wasmRaw := metadata["wasm"] + + // Make sure the wasm key is a map. If it isn't, ignore this packet + wasm, ok := wasmRaw.(map[string]interface{}) + if !ok { + return isWasmRouted, sdk.AccAddress{}, nil, + fmt.Errorf(types.ErrBadMetadataFormatMsg, memo, "wasm metadata is not a valid JSON map object") + } + + // Get the contract + contract, ok := wasm["contract"].(string) + if !ok { + // The tokens will be returned + return isWasmRouted, sdk.AccAddress{}, nil, + fmt.Errorf(types.ErrBadMetadataFormatMsg, memo, `Could not find key wasm["contract"]`) + } + + contractAddr, err = sdk.AccAddressFromBech32(contract) + if err != nil { + return isWasmRouted, sdk.AccAddress{}, nil, + fmt.Errorf(types.ErrBadMetadataFormatMsg, memo, `wasm["contract"] is not a valid bech32 address`) + } + + // The contract and the receiver should be the same for the packet to be valid + if contract != receiver { + return isWasmRouted, sdk.AccAddress{}, nil, + fmt.Errorf(types.ErrBadMetadataFormatMsg, memo, `wasm["contract"] should be the same as the receiver of the packet`) + } + + // Ensure the message key is provided + if wasm["msg"] == nil { + return isWasmRouted, sdk.AccAddress{}, nil, + fmt.Errorf(types.ErrBadMetadataFormatMsg, memo, `Could not find key wasm["msg"]`) + } + + // Make sure the msg key is a map. If it isn't, return an error + _, ok = wasm["msg"].(map[string]interface{}) + if !ok { + return isWasmRouted, sdk.AccAddress{}, nil, + fmt.Errorf(types.ErrBadMetadataFormatMsg, memo, `wasm["msg"] is not a map object`) + } + + // Get the message string by serializing the map + msgBytes, err = json.Marshal(wasm["msg"]) + if err != nil { + // The tokens will be returned + return isWasmRouted, sdk.AccAddress{}, nil, + fmt.Errorf(types.ErrBadMetadataFormatMsg, memo, err.Error()) + } + + return isWasmRouted, contractAddr, msgBytes, nil +} + +func (h WasmHooks) SendPacketOverride(i ICS4Middleware, ctx sdk.Context, chanCap *capabilitytypes.Capability, packet ibcexported.PacketI) error { + concretePacket, ok := packet.(channeltypes.Packet) + if !ok { + return i.channel.SendPacket(ctx, chanCap, packet) // continue + } + + isIcs20, data := isIcs20Packet(concretePacket) + if !isIcs20 { + return i.channel.SendPacket(ctx, chanCap, packet) // continue + } + + isCallbackRouted, metadata := jsonStringHasKey(data.GetMemo(), types.IBCCallbackKey) + if !isCallbackRouted { + return i.channel.SendPacket(ctx, chanCap, packet) // continue + } + + // We remove the callback metadata from the memo as it has already been processed. + + // If the only available key in the memo is the callback, we should remove the memo + // from the data completely so the packet is sent without it. + // This way receiver chains that are on old versions of IBC will be able to process the packet + + callbackRaw := metadata[types.IBCCallbackKey] // This will be used later. + delete(metadata, types.IBCCallbackKey) + bzMetadata, err := json.Marshal(metadata) + if err != nil { + return sdkerrors.Wrap(err, "Send packet with callback error") + } + stringMetadata := string(bzMetadata) + if stringMetadata == "{}" { + data.Memo = "" + } else { + data.Memo = stringMetadata + } + dataBytes, err := json.Marshal(data) + if err != nil { + return sdkerrors.Wrap(err, "Send packet with callback error") + } + + packetWithoutCallbackMemo := channeltypes.Packet{ + Sequence: concretePacket.Sequence, + SourcePort: concretePacket.SourcePort, + SourceChannel: concretePacket.SourceChannel, + DestinationPort: concretePacket.DestinationPort, + DestinationChannel: concretePacket.DestinationChannel, + Data: dataBytes, + TimeoutTimestamp: concretePacket.TimeoutTimestamp, + TimeoutHeight: concretePacket.TimeoutHeight, + } + + err = i.channel.SendPacket(ctx, chanCap, packetWithoutCallbackMemo) + if err != nil { + return err + } + + // Make sure the callback contract is a string and a valid bech32 addr. If it isn't, ignore this packet + contract, ok := callbackRaw.(string) + if !ok { + return nil + } + _, err = sdk.AccAddressFromBech32(contract) + if err != nil { + return nil + } + + h.ibcHooksKeeper.StorePacketCallback(ctx, packet.GetSourceChannel(), packet.GetSequence(), contract) + return nil +} + +func (h WasmHooks) OnAcknowledgementPacketOverride(im IBCMiddleware, ctx sdk.Context, packet channeltypes.Packet, acknowledgement []byte, relayer sdk.AccAddress) error { + err := im.App.OnAcknowledgementPacket(ctx, packet, acknowledgement, relayer) + if err != nil { + return err + } + + if !h.ProperlyConfigured() { + // Not configured. Return from the underlying implementation + return nil + } + + contract := h.ibcHooksKeeper.GetPacketCallback(ctx, packet.GetSourceChannel(), packet.GetSequence()) + if contract == "" { + // No callback configured + return nil + } + + contractAddr, err := sdk.AccAddressFromBech32(contract) + if err != nil { + return sdkerrors.Wrap(err, "Ack callback error") // The callback configured is not a bech32. Error out + } + + success := "false" + if !osmoutils.IsAckError(acknowledgement) { + success = "true" + } + + // Notify the sender that the ack has been received + ackAsJson, err := json.Marshal(acknowledgement) + if err != nil { + // If the ack is not a json object, error + return err + } + + sudoMsg := []byte(fmt.Sprintf( + `{"ibc_lifecycle_complete": {"ibc_ack": {"channel": "%s", "sequence": %d, "ack": %s, "success": %s}}}`, + packet.SourceChannel, packet.Sequence, ackAsJson, success)) + _, err = h.ContractKeeper.Sudo(ctx, contractAddr, sudoMsg) + if err != nil { + // error processing the callback + // ToDo: Open Question: Should we also delete the callback here? + return sdkerrors.Wrap(err, "Ack callback error") + } + h.ibcHooksKeeper.DeletePacketCallback(ctx, packet.GetSourceChannel(), packet.GetSequence()) + return nil +} + +func (h WasmHooks) OnTimeoutPacketOverride(im IBCMiddleware, ctx sdk.Context, packet channeltypes.Packet, relayer sdk.AccAddress) error { + err := im.App.OnTimeoutPacket(ctx, packet, relayer) + if err != nil { + return err + } + + if !h.ProperlyConfigured() { + // Not configured. Return from the underlying implementation + return nil + } + + contract := h.ibcHooksKeeper.GetPacketCallback(ctx, packet.GetSourceChannel(), packet.GetSequence()) + if contract == "" { + // No callback configured + return nil + } + + contractAddr, err := sdk.AccAddressFromBech32(contract) + if err != nil { + return sdkerrors.Wrap(err, "Timeout callback error") // The callback configured is not a bech32. Error out + } + + sudoMsg := []byte(fmt.Sprintf( + `{"ibc_lifecycle_complete": {"ibc_timeout": {"channel": "%s", "sequence": %d}}}`, + packet.SourceChannel, packet.Sequence)) + _, err = h.ContractKeeper.Sudo(ctx, contractAddr, sudoMsg) + if err != nil { + // error processing the callback. This could be because the contract doesn't implement the message type to + // process the callback. Retrying this will not help, so we can delete the callback from storage. + // Since the packet has timed out, we don't expect any other responses that may trigger the callback. + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + "ibc-timeout-callback-error", + sdk.NewAttribute("contract", contractAddr.String()), + sdk.NewAttribute("message", string(sudoMsg)), + sdk.NewAttribute("error", err.Error()), + ), + }) + } + h.ibcHooksKeeper.DeletePacketCallback(ctx, packet.GetSourceChannel(), packet.GetSequence()) + return nil +} From ba4623a99121beee236763bf5f5a378abf43bc64 Mon Sep 17 00:00:00 2001 From: Jacob Gadikian Date: Mon, 24 Apr 2023 12:50:17 +0700 Subject: [PATCH 010/131] correct the token factory module path --- Makefile | 32 ++---- app/app.go | 3 - app/keepers/keepers.go | 12 +-- app/keepers/keys.go | 4 +- app/keepers/querier.go | 2 +- app/modules.go | 8 +- app/upgrades/v13/constants.go | 4 +- app/upgrades/v13/upgrades.go | 2 +- app/upgrades/v14/constants.go | 2 +- app/upgrades/v15/upgrades.go | 2 +- cmd/junod/cmd/balances_from_state_export.go | 2 +- cmd/junod/cmd/forceprune.go | 2 +- go.mod | 1 - proto/buf.lock | 6 +- proto/buf.yaml | 4 +- tests/interchaintest/go.mod | 2 +- tests/interchaintest/go.sum | 4 +- x/feeshare/module.go | 5 - x/ibc-hooks/keeper/keeper.go | 2 +- x/ibc-hooks/sdkmodule.go | 2 +- x/mint/client/rest/grpc_query_test.go | 109 -------------------- x/mint/client/rest/query.go | 86 --------------- x/mint/client/rest/rest.go | 14 --- 23 files changed, 42 insertions(+), 268 deletions(-) delete mode 100644 x/mint/client/rest/grpc_query_test.go delete mode 100644 x/mint/client/rest/query.go delete mode 100644 x/mint/client/rest/rest.go diff --git a/Makefile b/Makefile index e18cea320..9ba3aee32 100644 --- a/Makefile +++ b/Makefile @@ -156,43 +156,31 @@ endif .PHONY: get-heighliner local-image ############################################################################### -### Proto ### +### Protobuf ### ############################################################################### -protoVer=v0.12.1 -protoImageName=tendermintdev/sdk-proto-gen:$(protoVer) -containerProtoGen=juno-proto-gen-$(protoVer) -containerProtoGenAny=juno-proto-gen-any-$(protoVer) -containerProtoGenSwagger=juno-proto-gen-swagger-$(protoVer) -containerProtoFmt=juno-proto-fmt-$(protoVer) +protoVer=0.11.6 +protoImageName=ghcr.io/cosmos/proto-builder:$(protoVer) +protoImage=$(DOCKER) run --rm -v $(CURDIR):/workspace --workdir /workspace $(protoImageName) proto-all: proto-format proto-lint proto-gen proto-gen: @echo "Generating Protobuf files" - @if docker ps -a --format '{{.Names}}' | grep -Eq "^${containerProtoGen}$$"; then docker start -a $(containerProtoGen); else docker run --name $(containerProtoGen) -v $(CURDIR):/workspace --workdir /workspace $(protoImageName) \ - sh ./scripts/protocgen.sh; fi - -# This generates the SDK's custom wrapper for google.protobuf.Any. It should only be run manually when needed -proto-gen-any: - @echo "Generating Protobuf Any" - @if docker ps -a --format '{{.Names}}' | grep -Eq "^${containerProtoGenAny}$$"; then docker start -a $(containerProtoGenAny); else docker run --name $(containerProtoGenAny) -v $(CURDIR):/workspace --workdir /workspace $(protoImageName) \ - sh ./scripts/protocgen-any.sh; fi + @$(protoImage) sh ./scripts/protocgen.sh proto-swagger-gen: @echo "Generating Protobuf Swagger" - @if docker ps -a --format '{{.Names}}' | grep -Eq "^${containerProtoGenSwagger}$$"; then docker start -a $(containerProtoGenSwagger); else docker run --name $(containerProtoGenSwagger) -v $(CURDIR):/workspace --workdir /workspace $(protoImageName) \ - sh ./scripts/protoc-swagger-gen.sh; fi + @$(protoImage) sh ./scripts/protoc-swagger-gen.sh + $(MAKE) update-swagger-docs proto-format: - @echo "Formatting Protobuf files" - @if docker ps -a --format '{{.Names}}' | grep -Eq "^${containerProtoFmt}$$"; then docker start -a $(containerProtoFmt); else docker run --name $(containerProtoFmt) -v $(CURDIR):/workspace --workdir /workspace tendermintdev/docker-build-proto \ - find ./ -not -path "./third_party/*" -name "*.proto" -exec clang-format -i {} \; ; fi + @$(protoImage) find ./ -name "*.proto" -exec clang-format -i {} \; proto-lint: - @$(DOCKER_BUF) lint --error-format=json + @$(protoImage) buf lint --error-format=json proto-check-breaking: - @$(DOCKER_BUF) breaking --against $(HTTPS_GIT)#branch=main + @$(protoImage) buf breaking --against $(HTTPS_GIT)#branch=main .PHONY: proto-all proto-gen proto-gen-any proto-swagger-gen proto-format proto-lint proto-check-breaking proto-update-deps docs \ No newline at end of file diff --git a/app/app.go b/app/app.go index 5bf458aa8..7903ff8ab 100644 --- a/app/app.go +++ b/app/app.go @@ -30,7 +30,6 @@ import ( "github.com/cosmos/cosmos-sdk/types/module" "github.com/cosmos/cosmos-sdk/version" "github.com/cosmos/cosmos-sdk/x/auth/ante" - authrest "github.com/cosmos/cosmos-sdk/x/auth/client/rest" authtx "github.com/cosmos/cosmos-sdk/x/auth/tx" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" "github.com/cosmos/cosmos-sdk/x/crisis" @@ -457,8 +456,6 @@ func (app *App) GetSubspace(moduleName string) paramstypes.Subspace { func (app *App) RegisterAPIRoutes(apiSvr *api.Server, _ config.APIConfig) { clientCtx := apiSvr.ClientCtx rpc.RegisterRoutes(clientCtx, apiSvr.Router) - // Register legacy tx routes. - authrest.RegisterTxRoutes(clientCtx, apiSvr.Router) // Register new tx routes from grpc-gateway. authtx.RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCGatewayRouter) // Register new tendermint queries routes from grpc-gateway. diff --git a/app/keepers/keepers.go b/app/keepers/keepers.go index 1e3659f98..e7e414a5a 100644 --- a/app/keepers/keepers.go +++ b/app/keepers/keepers.go @@ -3,10 +3,12 @@ package keepers import ( "path/filepath" - ibchookstypes "github.com/osmosis-labs/osmosis/x/ibc-hooks/types" + ibchookstypes "github.com/CosmosContracts/juno/v15/x/ibc-hooks/types" "github.com/CosmWasm/wasmd/x/wasm" wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" + ibchooks "github.com/CosmosContracts/juno/v15/x/ibc-hooks" + ibchookskeeper "github.com/CosmosContracts/juno/v15/x/ibc-hooks/keeper" mintkeeper "github.com/CosmosContracts/juno/v15/x/mint/keeper" minttypes "github.com/CosmosContracts/juno/v15/x/mint/types" "github.com/cosmos/cosmos-sdk/baseapp" @@ -54,16 +56,14 @@ import ( porttypes "github.com/cosmos/ibc-go/v7/modules/core/05-port/types" ibchost "github.com/cosmos/ibc-go/v7/modules/core/24-host" ibckeeper "github.com/cosmos/ibc-go/v7/modules/core/keeper" - ibchooks "github.com/osmosis-labs/osmosis/x/ibc-hooks" - ibchookskeeper "github.com/osmosis-labs/osmosis/x/ibc-hooks/keeper" packetforward "github.com/strangelove-ventures/packet-forward-middleware/v7/router" packetforwardkeeper "github.com/strangelove-ventures/packet-forward-middleware/v7/router/keeper" packetforwardtypes "github.com/strangelove-ventures/packet-forward-middleware/v7/router/types" - "github.com/CosmosContracts/juno/x/tokenfactory/bindings" - tokenfactorykeeper "github.com/CosmosContracts/juno/x/tokenfactory/keeper" - tokenfactorytypes "github.com/CosmosContracts/juno/x/tokenfactory/types" + "github.com/CosmosContracts/juno/v15/x/tokenfactory/bindings" + tokenfactorykeeper "github.com/CosmosContracts/juno/v15/x/tokenfactory/keeper" + tokenfactorytypes "github.com/CosmosContracts/juno/v15/x/tokenfactory/types" icahost "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/host" icahostkeeper "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/host/keeper" diff --git a/app/keepers/keys.go b/app/keepers/keys.go index 024d39eb6..cc4ce2f14 100644 --- a/app/keepers/keys.go +++ b/app/keepers/keys.go @@ -3,8 +3,9 @@ package keepers import ( "github.com/CosmWasm/wasmd/x/wasm" feesharetypes "github.com/CosmosContracts/juno/v15/x/feeshare/types" + ibchookstypes "github.com/CosmosContracts/juno/v15/x/ibc-hooks/types" minttypes "github.com/CosmosContracts/juno/v15/x/mint/types" - tokenfactorytypes "github.com/CosmosContracts/juno/x/tokenfactory/types" + tokenfactorytypes "github.com/CosmosContracts/juno/v15/x/tokenfactory/types" storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" @@ -24,7 +25,6 @@ import ( ibcfeetypes "github.com/cosmos/ibc-go/v7/modules/apps/29-fee/types" ibctransfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" ibchost "github.com/cosmos/ibc-go/v7/modules/core/24-host" - ibchookstypes "github.com/osmosis-labs/osmosis/x/ibc-hooks/types" icqtypes "github.com/strangelove-ventures/async-icq/v7/types" packetforwardtypes "github.com/strangelove-ventures/packet-forward-middleware/v7/router/types" ) diff --git a/app/keepers/querier.go b/app/keepers/querier.go index b31142f21..475451628 100644 --- a/app/keepers/querier.go +++ b/app/keepers/querier.go @@ -1,4 +1,4 @@ -// this file used from osmosis, ref: https://github.com/osmosis-labs/osmosis/blob/2ce971f4c6aa85d3ef7ba33d60e0ae74b923ab83/app/keepers/querier.go +// this file used from osmosis, ref: https://github.com/CosmosContracts/juno/v15/blob/2ce971f4c6aa85d3ef7ba33d60e0ae74b923ab83/app/keepers/querier.go // Original Author: https://github.com/nicolaslara package keepers diff --git a/app/modules.go b/app/modules.go index 49a53b544..53c9d5071 100644 --- a/app/modules.go +++ b/app/modules.go @@ -6,10 +6,12 @@ import ( feeshare "github.com/CosmosContracts/juno/v15/x/feeshare" feesharetypes "github.com/CosmosContracts/juno/v15/x/feeshare/types" "github.com/CosmosContracts/juno/v15/x/globalfee" + ibchooks "github.com/CosmosContracts/juno/v15/x/ibc-hooks" + ibchookstypes "github.com/CosmosContracts/juno/v15/x/ibc-hooks/types" "github.com/CosmosContracts/juno/v15/x/mint" minttypes "github.com/CosmosContracts/juno/v15/x/mint/types" - "github.com/CosmosContracts/juno/x/tokenfactory" - tokenfactorytypes "github.com/CosmosContracts/juno/x/tokenfactory/types" + "github.com/CosmosContracts/juno/v15/x/tokenfactory" + tokenfactorytypes "github.com/CosmosContracts/juno/v15/x/tokenfactory/types" "github.com/cosmos/cosmos-sdk/types/module" "github.com/cosmos/cosmos-sdk/x/auth" authsims "github.com/cosmos/cosmos-sdk/x/auth/simulation" @@ -50,8 +52,6 @@ import ( ibctransfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" ibc "github.com/cosmos/ibc-go/v7/modules/core" ibchost "github.com/cosmos/ibc-go/v7/modules/core/24-host" - ibchooks "github.com/osmosis-labs/osmosis/x/ibc-hooks" - ibchookstypes "github.com/osmosis-labs/osmosis/x/ibc-hooks/types" icq "github.com/strangelove-ventures/async-icq/v7" icqtypes "github.com/strangelove-ventures/async-icq/v7/types" packetforward "github.com/strangelove-ventures/packet-forward-middleware/v7/router" diff --git a/app/upgrades/v13/constants.go b/app/upgrades/v13/constants.go index 85778505f..3e51991c4 100644 --- a/app/upgrades/v13/constants.go +++ b/app/upgrades/v13/constants.go @@ -3,11 +3,11 @@ package v13 import ( "github.com/CosmosContracts/juno/v15/app/upgrades" feesharetypes "github.com/CosmosContracts/juno/v15/x/feeshare/types" - tokenfactorytypes "github.com/CosmosContracts/juno/x/tokenfactory/types" + ibchookstypes "github.com/CosmosContracts/juno/v15/x/ibc-hooks/types" + tokenfactorytypes "github.com/CosmosContracts/juno/v15/x/tokenfactory/types" store "github.com/cosmos/cosmos-sdk/store/types" icacontrollertypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/types" ibcfeetypes "github.com/cosmos/ibc-go/v7/modules/apps/29-fee/types" - ibchookstypes "github.com/osmosis-labs/osmosis/x/ibc-hooks/types" packetforwardtypes "github.com/strangelove-ventures/packet-forward-middleware/v7/router/types" ) diff --git a/app/upgrades/v13/upgrades.go b/app/upgrades/v13/upgrades.go index 64fcf671a..dad40ebe3 100644 --- a/app/upgrades/v13/upgrades.go +++ b/app/upgrades/v13/upgrades.go @@ -16,7 +16,7 @@ import ( // types feesharetypes "github.com/CosmosContracts/juno/v15/x/feeshare/types" - tokenfactorytypes "github.com/CosmosContracts/juno/x/tokenfactory/types" + tokenfactorytypes "github.com/CosmosContracts/juno/v15/x/tokenfactory/types" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" ibcfeetypes "github.com/cosmos/ibc-go/v7/modules/apps/29-fee/types" diff --git a/app/upgrades/v14/constants.go b/app/upgrades/v14/constants.go index eadd0e971..89fa9c6d2 100644 --- a/app/upgrades/v14/constants.go +++ b/app/upgrades/v14/constants.go @@ -3,8 +3,8 @@ package v14 import ( "github.com/CosmosContracts/juno/v15/app/upgrades" "github.com/CosmosContracts/juno/v15/x/globalfee" + ibchookstypes "github.com/CosmosContracts/juno/v15/x/ibc-hooks/types" store "github.com/cosmos/cosmos-sdk/store/types" - ibchookstypes "github.com/osmosis-labs/osmosis/x/ibc-hooks/types" ) // UpgradeName defines the on-chain upgrade name for the upgrade. diff --git a/app/upgrades/v15/upgrades.go b/app/upgrades/v15/upgrades.go index 060978dfe..252b6070e 100644 --- a/app/upgrades/v15/upgrades.go +++ b/app/upgrades/v15/upgrades.go @@ -9,7 +9,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" - tokenfactorytypes "github.com/CosmosContracts/juno/x/tokenfactory/types" + tokenfactorytypes "github.com/CosmosContracts/juno/v15/x/tokenfactory/types" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" ) diff --git a/cmd/junod/cmd/balances_from_state_export.go b/cmd/junod/cmd/balances_from_state_export.go index 4e9722afe..cab20517c 100644 --- a/cmd/junod/cmd/balances_from_state_export.go +++ b/cmd/junod/cmd/balances_from_state_export.go @@ -1,7 +1,7 @@ package cmd // modified from osmosis -// https://github.com/osmosis-labs/osmosis/blob/main/cmd/osmosisd/cmd/balances_from_state_export.go +// https://github.com/CosmosContracts/juno/v15/blob/main/cmd/osmosisd/cmd/balances_from_state_export.go import ( "encoding/csv" diff --git a/cmd/junod/cmd/forceprune.go b/cmd/junod/cmd/forceprune.go index a585f9691..f80c3f178 100644 --- a/cmd/junod/cmd/forceprune.go +++ b/cmd/junod/cmd/forceprune.go @@ -3,7 +3,7 @@ package cmd // DONTCOVER // from osmosis -// https://github.com/osmosis-labs/osmosis/blob/main/cmd/junod/cmd/forceprune.go +// https://github.com/CosmosContracts/juno/v15/blob/main/cmd/junod/cmd/forceprune.go import ( "fmt" diff --git a/go.mod b/go.mod index d20480ef7..41b76f68b 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,6 @@ require ( github.com/golang/protobuf v1.5.3 github.com/gorilla/mux v1.8.0 github.com/grpc-ecosystem/grpc-gateway v1.16.0 - github.com/osmosis-labs/osmosis/x/ibc-hooks v0.0.0-20230201151635-ef43e092d196 github.com/prometheus/client_golang v1.15.0 github.com/spf13/cast v1.5.0 github.com/spf13/cobra v1.7.0 diff --git a/proto/buf.lock b/proto/buf.lock index fae8adcbe..6bfb203f7 100644 --- a/proto/buf.lock +++ b/proto/buf.lock @@ -5,15 +5,19 @@ deps: owner: cosmos repository: cosmos-proto commit: 1935555c206d4afb9e94615dfd0fad31 + digest: shake256:c74d91a3ac7ae07d579e90eee33abf9b29664047ac8816500cf22c081fec0d72d62c89ce0bebafc1f6fec7aa5315be72606717740ca95007248425102c365377 - remote: buf.build owner: cosmos repository: cosmos-sdk - commit: 8dc523b705c34317bfd4a961fba89e72 + commit: 51aaa75f36aa4190b2965726557f499e + digest: shake256:fab0021db39a20737093bda0096c3f6b01f1a87f93675532488fce92768992ea39023d57fa6a4b68d25a93b63f48af6404f0de54b35e22ae2b4ea8a9d10b723f - remote: buf.build owner: cosmos repository: gogo-proto commit: 34d970b699f84aa382f3c29773a60836 + digest: shake256:3d3bee5229ba579e7d19ffe6e140986a228b48a8c7fe74348f308537ab95e9135210e81812489d42cd8941d33ff71f11583174ccc5972e86e6112924b6ce9f04 - remote: buf.build owner: googleapis repository: googleapis commit: 5ae7f88519b04fe1965da0f8a375a088 + digest: shake256:27d9fcdc0e3eb957449dc3d17e2d24c7ce59c3c483ecf128818183c336dfd28595ecd13771fb3172247775caf7707c4076dd8e70c5ac2cbcac170df35e4d0028 diff --git a/proto/buf.yaml b/proto/buf.yaml index c621b97be..80dd620c1 100644 --- a/proto/buf.yaml +++ b/proto/buf.yaml @@ -1,7 +1,7 @@ version: v1 name: buf.build/osmosis-labs/osmosis deps: - - buf.build/cosmos/cosmos-sdk + - buf.build/cosmos/cosmos-sdk:v0.47.0 - buf.build/cosmos/cosmos-proto - buf.build/cosmos/gogo-proto - buf.build/googleapis/googleapis @@ -20,4 +20,4 @@ lint: - PACKAGE_VERSION_SUFFIX - RPC_REQUEST_STANDARD_NAME ignore: - - tendermint \ No newline at end of file + - tendermint diff --git a/tests/interchaintest/go.mod b/tests/interchaintest/go.mod index 82250843a..e447fa393 100644 --- a/tests/interchaintest/go.mod +++ b/tests/interchaintest/go.mod @@ -5,7 +5,7 @@ go 1.19 require ( github.com/CosmosContracts/juno/v13 v13.0.0 github.com/cosmos/cosmos-sdk v0.45.14 - github.com/cosmos/ibc-go/v4 v4.3.0 + github.com/cosmos/ibc-go/v7 v4.3.0 github.com/strangelove-ventures/interchaintest/v4 v4.0.0-20230331040355-5d08aab13017 github.com/stretchr/testify v1.8.2 go.uber.org/zap v1.23.0 diff --git a/tests/interchaintest/go.sum b/tests/interchaintest/go.sum index 1411e44e7..ebf06eba6 100644 --- a/tests/interchaintest/go.sum +++ b/tests/interchaintest/go.sum @@ -166,8 +166,8 @@ 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.5 h1:rGA3hOrgNxgRM5wYcSCxgQBap7fW82WZgY78V9po/iY= github.com/cosmos/iavl v0.19.5/go.mod h1:X9PKD3J0iFxdmgNLa7b2LYWdsGd90ToV5cAONApkEPw= -github.com/cosmos/ibc-go/v4 v4.3.0 h1:yOzVsyZzsv4XPBux8gq+D0LhZn45yGWKjvT+6Vyo5no= -github.com/cosmos/ibc-go/v4 v4.3.0/go.mod h1:CcLvIoi9NNtIbNsxs4KjBGjYhlwqtsmXy1AKARKiMzQ= +github.com/cosmos/ibc-go/v7 v4.3.0 h1:yOzVsyZzsv4XPBux8gq+D0LhZn45yGWKjvT+6Vyo5no= +github.com/cosmos/ibc-go/v7 v4.3.0/go.mod h1:CcLvIoi9NNtIbNsxs4KjBGjYhlwqtsmXy1AKARKiMzQ= github.com/cosmos/interchain-security v1.0.0 h1:xNQjjigqH3mzEKSGQhAhKy8I0TA8XR2z5rRTxRBKK3o= github.com/cosmos/interchain-security v1.0.0/go.mod h1:J9SbXUJT1GSe+mZy+MDCxtuAfbhwCKBEJRYnfjXsE8Q= github.com/cosmos/ledger-cosmos-go v0.12.2 h1:/XYaBlE2BJxtvpkHiBm97gFGSGmYGKunKyF3nNqAXZA= diff --git a/x/feeshare/module.go b/x/feeshare/module.go index 9aac445a7..73c3fab16 100644 --- a/x/feeshare/module.go +++ b/x/feeshare/module.go @@ -137,11 +137,6 @@ func (am AppModule) QuerierRoute() string { return types.RouterKey } -// LegacyQuerierHandler returns the claim module's Querier. -func (am AppModule) LegacyQuerierHandler(_ *codec.LegacyAmino) sdk.Querier { - return nil -} - // RegisterServices registers a GRPC query service to respond to the // module-specific GRPC queries. func (am AppModule) RegisterServices(cfg module.Configurator) { diff --git a/x/ibc-hooks/keeper/keeper.go b/x/ibc-hooks/keeper/keeper.go index 44ad330f5..c5d0757f6 100644 --- a/x/ibc-hooks/keeper/keeper.go +++ b/x/ibc-hooks/keeper/keeper.go @@ -5,7 +5,7 @@ import ( "github.com/cosmos/cosmos-sdk/types/address" - "github.com/tendermint/tendermint/libs/log" + "github.com/cometbft/cometbft/libs/log" "github.com/CosmosContracts/juno/v15/x/ibc-hooks/types" diff --git a/x/ibc-hooks/sdkmodule.go b/x/ibc-hooks/sdkmodule.go index 5c4ea5ad9..3f3e6f4ce 100644 --- a/x/ibc-hooks/sdkmodule.go +++ b/x/ibc-hooks/sdkmodule.go @@ -18,8 +18,8 @@ import ( "github.com/CosmosContracts/juno/v15/osmoutils" + abci "github.com/cometbft/cometbft/abci/types" sdk "github.com/cosmos/cosmos-sdk/types" - abci "github.com/tendermint/tendermint/abci/types" ) var ( diff --git a/x/mint/client/rest/grpc_query_test.go b/x/mint/client/rest/grpc_query_test.go deleted file mode 100644 index f7c8a58fd..000000000 --- a/x/mint/client/rest/grpc_query_test.go +++ /dev/null @@ -1,109 +0,0 @@ -//go:build norace -// +build norace - -package rest_test - -import ( - "fmt" - "testing" - - "github.com/cosmos/cosmos-sdk/testutil" - sdk "github.com/cosmos/cosmos-sdk/types" - grpctypes "github.com/cosmos/cosmos-sdk/types/grpc" - - "github.com/cosmos/gogoproto/proto" - "github.com/stretchr/testify/suite" - - minttypes "github.com/CosmosContracts/juno/v15/x/mint/types" -) - -type IntegrationTestSuite struct { - suite.Suite - cfg network.Config - network *network.Network -} - -func (s *IntegrationTestSuite) SetupSuite() { - s.T().Log("setting up integration test suite") - - cfg := network.DefaultConfig() - - genesisState := cfg.GenesisState - cfg.NumValidators = 1 - - var mintData minttypes.GenesisState - s.Require().NoError(cfg.Codec.UnmarshalJSON(genesisState[minttypes.ModuleName], &mintData)) - - inflation := sdk.MustNewDecFromStr("1.0") - mintData.Minter.Inflation = inflation - - mintDataBz, err := cfg.Codec.MarshalJSON(&mintData) - s.Require().NoError(err) - genesisState[minttypes.ModuleName] = mintDataBz - cfg.GenesisState = genesisState - - s.cfg = cfg - s.network = network.New(s.T(), cfg) - - _, err = s.network.WaitForHeight(1) - s.Require().NoError(err) -} - -func (s *IntegrationTestSuite) TearDownSuite() { - s.T().Log("tearing down integration test suite") - s.network.Cleanup() -} - -func (s *IntegrationTestSuite) TestQueryGRPC() { - val := s.network.Validators[0] - baseURL := val.APIAddress - testCases := []struct { - name string - url string - headers map[string]string - respType proto.Message - expected proto.Message - }{ - { - "gRPC request params", - fmt.Sprintf("%s/cosmos/mint/v1beta1/params", baseURL), - map[string]string{}, - &minttypes.QueryParamsResponse{}, - &minttypes.QueryParamsResponse{ - Params: minttypes.NewParams("stake", (60 * 60 * 8766 / 5)), - }, - }, - { - "gRPC request inflation", - fmt.Sprintf("%s/cosmos/mint/v1beta1/inflation", baseURL), - map[string]string{}, - &minttypes.QueryInflationResponse{}, - &minttypes.QueryInflationResponse{ - Inflation: sdk.NewDec(1), - }, - }, - { - "gRPC request annual provisions", - fmt.Sprintf("%s/cosmos/mint/v1beta1/annual_provisions", baseURL), - map[string]string{ - grpctypes.GRPCBlockHeightHeader: "1", - }, - &minttypes.QueryAnnualProvisionsResponse{}, - &minttypes.QueryAnnualProvisionsResponse{ - AnnualProvisions: sdk.NewDec(500000000), - }, - }, - } - for _, tc := range testCases { - resp, err := testutil.GetRequestWithHeaders(tc.url, tc.headers) - s.Run(tc.name, func() { - s.Require().NoError(err) - s.Require().NoError(val.ClientCtx.Codec.UnmarshalJSON(resp, tc.respType)) - s.Require().Equal(tc.expected.String(), tc.respType.String()) - }) - } -} - -func TestIntegrationTestSuite(t *testing.T) { - suite.Run(t, new(IntegrationTestSuite)) -} diff --git a/x/mint/client/rest/query.go b/x/mint/client/rest/query.go deleted file mode 100644 index e87cd14e5..000000000 --- a/x/mint/client/rest/query.go +++ /dev/null @@ -1,86 +0,0 @@ -package rest - -import ( - "fmt" - "net/http" - - "github.com/gorilla/mux" - - "github.com/CosmosContracts/juno/v15/x/mint/types" - "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/types/rest" -) - -func registerQueryRoutes(clientCtx client.Context, r *mux.Router) { - r.HandleFunc( - "/minting/parameters", - queryParamsHandlerFn(clientCtx), - ).Methods("GET") - - r.HandleFunc( - "/minting/inflation", - queryInflationHandlerFn(clientCtx), - ).Methods("GET") - - r.HandleFunc( - "/minting/annual-provisions", - queryAnnualProvisionsHandlerFn(clientCtx), - ).Methods("GET") -} - -func queryParamsHandlerFn(clientCtx client.Context) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - route := fmt.Sprintf("custom/%s/%s", types.QuerierRoute, types.QueryParameters) - - clientCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, clientCtx, r) - if !ok { - return - } - - res, height, err := clientCtx.QueryWithData(route, nil) - if rest.CheckInternalServerError(w, err) { - return - } - - clientCtx = clientCtx.WithHeight(height) - rest.PostProcessResponse(w, clientCtx, res) - } -} - -func queryInflationHandlerFn(clientCtx client.Context) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - route := fmt.Sprintf("custom/%s/%s", types.QuerierRoute, types.QueryInflation) - - clientCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, clientCtx, r) - if !ok { - return - } - - res, height, err := clientCtx.QueryWithData(route, nil) - if rest.CheckInternalServerError(w, err) { - return - } - - clientCtx = clientCtx.WithHeight(height) - rest.PostProcessResponse(w, clientCtx, res) - } -} - -func queryAnnualProvisionsHandlerFn(clientCtx client.Context) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - route := fmt.Sprintf("custom/%s/%s", types.QuerierRoute, types.QueryAnnualProvisions) - - clientCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, clientCtx, r) - if !ok { - return - } - - res, height, err := clientCtx.QueryWithData(route, nil) - if rest.CheckInternalServerError(w, err) { - return - } - - clientCtx = clientCtx.WithHeight(height) - rest.PostProcessResponse(w, clientCtx, res) - } -} diff --git a/x/mint/client/rest/rest.go b/x/mint/client/rest/rest.go deleted file mode 100644 index 2ed28d41d..000000000 --- a/x/mint/client/rest/rest.go +++ /dev/null @@ -1,14 +0,0 @@ -package rest - -import ( - "github.com/gorilla/mux" - - "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/client/rest" -) - -// RegisterRoutes registers minting module REST handlers on the provided router. -func RegisterRoutes(clientCtx client.Context, rtr *mux.Router) { - r := rest.WithHTTPDeprecationHeaders(rtr) - registerQueryRoutes(clientCtx, r) -} From e2932e2ecdf3687ef0cd2b0a40af2b5704368e5c Mon Sep 17 00:00:00 2001 From: Jacob Gadikian Date: Mon, 24 Apr 2023 12:51:50 +0700 Subject: [PATCH 011/131] tidy --- go.sum | 1396 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1396 insertions(+) create mode 100644 go.sum diff --git a/go.sum b/go.sum new file mode 100644 index 000000000..bb349ba58 --- /dev/null +++ b/go.sum @@ -0,0 +1,1396 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +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= +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= +cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= +cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +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/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/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/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= +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +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= +collectd.org v0.3.0/go.mod h1:A/8DzQBkF6abtvrT2j/AU/4tiBgJWYyh0y/oB/4MlWE= +cosmossdk.io/api v0.3.1/go.mod h1:DfHfMkiNA2Uhy8fj0JJlOCYOBp4eWUUJ1te5zBGNyIw= +cosmossdk.io/core v0.5.1/go.mod h1:KZtwHCLjcFuo0nmDc24Xy6CRNEL9Vl/MeimQ2aC7NLE= +cosmossdk.io/depinject v1.0.0-alpha.3/go.mod h1:eRbcdQ7MRpIPEM5YUJh8k97nxHpYbc3sMUnEtt8HPWU= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +filippo.io/edwards25519 v1.0.0-rc.1/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns= +filippo.io/edwards25519 v1.0.0/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/go.mod h1:hN7oaIRCjzsZ2dE+yG5k+rsdt3qcwykqK6HVGcKwsw4= +github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= +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/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/go.mod h1:URdX5+vg25ts3aCh8H5IFZybJYKWhJHYMTnf+ULtoC4= +github.com/CloudyKit/fastprinter v0.0.0-20170127035650-74b38d55f37a/go.mod h1:EFZQ978U7x8IRnstaskI3IysnWY5Ao3QgZUKOXlsAdw= +github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno= +github.com/CloudyKit/jet v2.1.3-0.20180809161101-62edd43e4f88+incompatible/go.mod h1:HPYO+50pSWkPoj9Q/eq0aRGByCL6ScRlUmiEX5Zgm+w= +github.com/CloudyKit/jet/v3 v3.0.0/go.mod h1:HKQPgSJmdK8hdoAbKUUWajkHyHo4RaU5rMdUywE7VMo= +github.com/CosmWasm/wasmd v0.40.0-rc.1.0.20230422061626-b85abcf1d7b8/go.mod h1:uacdue6EGn9JA1TqBNHB3iCe4PCIChuFT23AzIl2VME= +github.com/CosmWasm/wasmvm v1.2.3/go.mod h1:vW/E3h8j9xBQs9bCoijDuawKo9kCtxOaS8N8J7KFtkc= +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.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= +github.com/DataDog/zstd v1.5.0/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= +github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo= +github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= +github.com/Joker/jade v1.0.1-0.20190614124447-d475f43051e7/go.mod h1:6E6s8o2AE4KhCrqr6GRJjdC/gNfTdxkIXvuGZZda2VM= +github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= +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/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= +github.com/Workiva/go-datastructures v1.0.53/go.mod h1:1yZL+zfsztete+ePzZz/Zb1/t5BnDuE2Ya2MMGhzP6A= +github.com/Zilliqa/gozilliqa-sdk v1.2.1-0.20201201074141-dd0ecada1be6/go.mod h1:eSYp2T6f0apnuW8TzhV3f6Aff2SE8Dwio++U4ha4yEM= +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/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= +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/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= +github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4= +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.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +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/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= +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/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816/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.22.2/go.mod h1:wqgTSL29+50LRkmOVknEdmt8ZojIzhuWvgu/iptuN7Y= +github.com/btcsuite/btcd/btcec/v2 v2.1.2/go.mod h1:ctjw4H1kknNJmRN4iP1R7bTQ+v3GJkZBd6mui8ZsAZE= +github.com/btcsuite/btcd/btcec/v2 v2.3.2/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= +github.com/btcsuite/btcd/chaincfg/chainhash v1.0.0/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= +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-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/go.mod h1:0DVlHczLPewLcPGEIeUEzfOJhqGPQ0mJJRDBtD307+o= +github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= +github.com/btcsuite/goleveldb v1.0.0/go.mod h1:QiK9vBlgftBg6rWQIj6wFzbPfRjiykIEhBH4obrXJ/I= +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/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/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/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +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/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cloudflare/cloudflare-go v0.14.0/go.mod h1:EnwdgGMaFOruiPZRFSgn+TsQ3hQ7C/YWzIGLeu5c304= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= +github.com/cockroachdb/datadriven v1.0.0/go.mod h1:5Ib8Meh+jk1RlHIXej6Pzevx/NLlNvQB9pmSBZErGA4= +github.com/cockroachdb/datadriven v1.0.2/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= +github.com/cockroachdb/errors v1.6.1/go.mod h1:tm6FTP5G81vwJ5lC0SizQo374JNCOPrHyXGitRJoDqM= +github.com/cockroachdb/errors v1.8.1/go.mod h1:qGwQn6JmZ+oMjuLwjWzUNqblqk0xl4CVV3SQbGwK7Ac= +github.com/cockroachdb/errors v1.9.1/go.mod h1:2sxOtL2WIc096WSZqZ5h8fa17rdDq9HZOZLBCor4mBk= +github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI= +github.com/cockroachdb/logtags v0.0.0-20211118104740-dabe8e521a4f/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= +github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= +github.com/cockroachdb/pebble v0.0.0-20220817183557-09c6e030a677/go.mod h1:890yq1fUb9b6dGNwssgeUO5vQV9qfXnCPxAJhBQfXw0= +github.com/cockroachdb/redact v1.0.8/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= +github.com/cockroachdb/redact v1.1.3/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= +github.com/cockroachdb/sentry-go v0.6.1-cockroachdb.2/go.mod h1:8BT+cPK6xvFOcRlk0R8eg+OTkcqI6baNH4xAkpiYVvQ= +github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= +github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= +github.com/coinbase/kryptology v1.8.0/go.mod h1:RYXOAPdzOGUe3qlSFkMGn58i3xUA8hmxYHksuq+8ciI= +github.com/coinbase/rosetta-sdk-go v0.7.9/go.mod h1:0/knutI7XGVqXmmH4OQD8OckFrbQ8yMsUZTG7FXCR2M= +github.com/cometbft/cometbft-db v0.7.0/go.mod h1:yiKJIm2WKrt6x8Cyxtq9YTEcIMPcEe4XPxhgX59Fzf0= +github.com/confio/ics23/go v0.9.0/go.mod h1:4LPZ2NYqnYIVRklaozjNR1FScgDJ2s5Xrp+e/mYVRak= +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/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= +github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/cosmos/btcutil v1.0.5/go.mod h1:IyB7iuqZMJlthe2tkIFL33xPyzbFYP0XVdS8P5lUPis= +github.com/cosmos/cosmos-db v0.0.0-20221226095112-f3c38ecb5e32/go.mod h1:kwMlEC4wWvB48zAShGKVqboJL6w4zCLesaNQ3YLU2BQ= +github.com/cosmos/cosmos-proto v1.0.0-beta.2/go.mod h1:+XRCLJ14pr5HFEHIUcn51IKXD1Fy3rkEQqt4WqmN4V0= +github.com/cosmos/cosmos-sdk v0.47.1/go.mod h1:14tO5KQaTrl2q3OxBnDRfue7TRN9zkXS0cLutrSqkOo= +github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d/go.mod h1:tSxLoYXyBmiFeKpvmq4dzayMdCjCnu8uqmCysIGBT2Y= +github.com/cosmos/go-bip39 v1.0.0/go.mod h1:RNJv0H/pOIVgxw6KS7QeX2a0Uo0aKUlfhZ4xuwvCdJw= +github.com/cosmos/gogoproto v1.4.8/go.mod h1:hnb0DIEWTv+wdNzNcqus5xCQXq5+CXauq1FJuurRfVY= +github.com/cosmos/gorocksdb v1.2.0/go.mod h1:aaKvKItm514hKfNJpUJXnnOWeBnk2GL4+Qw9NHizILw= +github.com/cosmos/iavl v0.20.0/go.mod h1:WO7FyvaZJoH65+HFOsDir7xU9FWk2w9cHXNW1XHcl7A= +github.com/cosmos/keyring v1.2.0/go.mod h1:fc+wB5KTk9wQ9sDx0kFXB3A0MaeGHM9AwRStKOQ5vOA= +github.com/cosmos/ledger-cosmos-go v0.12.2/go.mod h1:ZcqYgnfNJ6lAXe4HPtWgarNEY+B74i+2/8MhZw4ziiI= +github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= +github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/creachadair/taskgroup v0.4.2/go.mod h1:qiXUOSrbwAY3u0JPGTzObbE3yf9hcXHDKBZ2ZjpCbgM= +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/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/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/decred/dcrd/dcrec/secp256k1/v4 v4.1.0/go.mod h1:DZGJHZMqrU4JJqFAWUS2UO1+lbSKsdiOoYi9Zzey7Fc= +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/go.mod h1:xH/i4TFMt8koVQZ6WFms69WAsDWr2XsYL3Hkl7jkoLE= +github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= +github.com/dgraph-io/badger/v2 v2.2007.4/go.mod h1:vSw/ax2qojzbN6eXHIx6KPKtCSHJN/Uz0X0VPruTIhk= +github.com/dgraph-io/badger/v3 v3.2103.2/go.mod h1:RHo4/GmYcKKh5Lxu63wLEMHJ70Pac2JqZRYGhlyAo2M= +github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= +github.com/dgraph-io/ristretto v0.0.3/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= +github.com/dgraph-io/ristretto v0.1.0/go.mod h1:fux0lOrBhrVCJd3lcTHsIJhq1T2rokOu6v9Vcb3Q9ug= +github.com/dgraph-io/ristretto v0.1.1/go.mod h1:S1GPSBCYCIhmVNfcth17y2zZtQT6wzkzgwUve0VDWWA= +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/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/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/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/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= +github.com/dvsekhvalnov/jose2go v1.5.0/go.mod h1:QsHjhyTlD/lAVqn/NSbVZmSCGeDehTB/mPZadG+mhXU= +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 v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= +github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= +github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw= +github.com/ethereum/go-ethereum v1.10.17/go.mod h1:Lt5WzjM07XlXc95YzrhosmR4J9Ahd6X2wyEV2SvGhk0= +github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= +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/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= +github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/felixge/httpsnoop v1.0.2/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= +github.com/flosch/pongo2 v0.0.0-20190707114632-bbf5a6c351f4/go.mod h1:T9YF2M40nIgbVgp3rreNmTged+9HrbNTIQf1PsaIiTA= +github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= +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/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/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= +github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= +github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= +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/getsentry/sentry-go v0.12.0/go.mod h1:NSap0JBYWzHND8oMbyi0+XZhUalc1TBdRL1M71JZW2c= +github.com/getsentry/sentry-go v0.17.0/go.mod h1:B82dxtBvxG0KaPD8/hfSV+VcHD+Lg/xUS4JuQn1P4cM= +github.com/ghemawat/stream v0.0.0-20171120220530-696b145b53b9/go.mod h1:106OIgooyS7OzLDOpUGgm9fA3bQENb/cFSyyBmMoJDs= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-gonic/gin v1.8.1/go.mod h1:ji8BvRH1azfM+SYow9zQ6SZMvR8qOMZHmsCuWR9tTTk= +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-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= +github.com/go-chi/chi/v5 v5.0.0/go.mod h1:BBug9lr0cqtdAhsu6R4AAdvufI0/XBzAQSsUqJpoZOs= +github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= +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= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= +github.com/go-kit/kit v0.12.0/go.mod h1:lHd+EkCZPIwYItmGDDRdhinkzX2A1sj+M9biaEaizzs= +github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= +github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= +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.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs= +github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA= +github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos= +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/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= +github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= +github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= +github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +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/go.mod h1:S7rR8FRQyG3QFESeSv4l2WnsyzlCLG0CzBbUUo/mbic= +github.com/gogo/googleapis v0.0.0-20180223154316-0cd9801be74a/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= +github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= +github.com/gogo/googleapis v1.4.1/go.mod h1:2lpHqI5OcWCtVElxXnPt+s8oJvMpySlOyM6xDCrzib4= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/gogo/status v1.1.0/go.mod h1:BFv9nrluPLmrS0EmGVvLaPNmRosr9KapBYd5/hpY1WM= +github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= +github.com/golang-jwt/jwt/v4 v4.3.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= +github.com/golang-jwt/jwt/v4 v4.4.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +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.1.0/go.mod h1:pfYeQZ3JWZoXTV5sFc986z3HTpwQs9At6P4ImfuP3NQ= +github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +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/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +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/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= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +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.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +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/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= +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/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= +github.com/google/flatbuffers v1.11.0/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= +github.com/google/flatbuffers v1.12.1/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= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +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.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= +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/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +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/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= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +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-20210407192527-94a9f03dee38/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/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/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= +github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q= +github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gorilla/websocket v1.4.1/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/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +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/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= +github.com/grpc-ecosystem/grpc-gateway v1.8.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c/go.mod h1:NMPJylDgVpX0MLRlPy15sqSwOFv/U1GZ2m21JhFfek0= +github.com/gtank/merlin v0.1.1-0.20191105220539-8318aed1a79f/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/bIQ+s= +github.com/gtank/merlin v0.1.1/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/bIQ+s= +github.com/gtank/ristretto255 v0.1.2/go.mod h1:Ph5OpO6c7xKUGROZfWVLiJf9icMDwUeIvY4OmlYW69o= +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-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +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-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/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +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/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +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.1.0/go.mod h1:w3BHWjwJbFU29IRHL1Iqkw3sus+7FctEyM4RqDxYNzo= +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.3-0.20220313090229-ca81a64b4204/go.mod h1:ZxNlw5WqJj6wSsRK5+YfflQGXYfccj5VgQsMNixHM7Y= +github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= +github.com/hydrogen18/memlistener v0.0.0-20141126152155-54553eb933fb/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= +github.com/hydrogen18/memlistener v0.0.0-20200120041712-dcc25e7acd91/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= +github.com/iancoleman/orderedmap v0.2.0/go.mod h1:N0Wam8K1arqPXNWjMo21EXnBPOPp36vB07FNRdD2geA= +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/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= +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.1.0/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/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/iris-contrib/blackfriday v2.0.0+incompatible/go.mod h1:UzZ2bDEoaSGPbkg6SAB4att1aAwTmVIx/5gCVqeyUdI= +github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/+fafWORmlnuysV2EMP8MW+qe0= +github.com/iris-contrib/i18n v0.0.0-20171121225848-987a633949d0/go.mod h1:pMCz62A0xJL6I+umB2YTlFRwWXaDFA0jy+5HzGiJjqI= +github.com/iris-contrib/jade v1.1.3/go.mod h1:H/geBymxJhShH5kecoiOCSssPX7QWYH7UaeZTSWddIk= +github.com/iris-contrib/pongo2 v0.0.1/go.mod h1:Ssh+00+3GAZqSQb30AvBRNxBx7rf0GqwkjqxNd0u65g= +github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw= +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 v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= +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= +github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= +github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +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/juju/errors v0.0.0-20181118221551-089d3ea4e4d5/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q= +github.com/juju/loggo v0.0.0-20180524022052-584905176618/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U= +github.com/juju/testing v0.0.0-20180920084828-472a3e8b2073/go.mod h1:63prj8cnj0tU0S9OHjGJn+b1h0ZghCndfnbQolrYTwA= +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/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= +github.com/karalabe/usb v0.0.2/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU= +github.com/kataras/golog v0.0.9/go.mod h1:12HJgwBIZFNGL0EJnMRhmvGA0PQGx8VFwrZtM4CqbAk= +github.com/kataras/golog v0.0.10/go.mod h1:yJ8YKCmyL+nWjERB90Qwn+bdyBZsaQwU3bTVFgkFIp8= +github.com/kataras/iris/v12 v12.0.1/go.mod h1:udK4vLQKkdDqMGJJVd/msuMtN6hpYJhg/lSzuxjhO+U= +github.com/kataras/iris/v12 v12.1.8/go.mod h1:LMYy4VlP67TQ3Zgriz8RE2h2kMZV2SgMYbq3UhfoFmE= +github.com/kataras/neffos v0.0.10/go.mod h1:ZYmJC07hQPW67eKuzlfY7SO3bC0mw83A3j6im82hfqw= +github.com/kataras/neffos v0.0.14/go.mod h1:8lqADm8PnbeFfL7CLXh1WHw53dG27MC3pgi2R1rmoTE= +github.com/kataras/pio v0.0.0-20190103105442-ea782b38602d/go.mod h1:NV88laa9UiiDuX9AhMbDPkGYSPugBOV6yTZB1l2K9Z0= +github.com/kataras/pio v0.0.2/go.mod h1:hAoW0t9UmXi4R5Oyq5Z4irTbaTsOemSrDGUtaTl7Dro= +github.com/kataras/sitemap v0.0.5/go.mod h1:KY2eugMKiPwsJgx7+U103YZehfvNGOXURubcGyk0Bz8= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= +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.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/compress v1.9.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/compress v1.9.7/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +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.16.3/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/klauspost/cpuid v0.0.0-20170728055534-ae7887de9fa5/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= +github.com/klauspost/cpuid v1.2.1/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.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +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/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.1.11/go.mod h1:i541M3Fj6f76NZtHSj7TXnyM8n2gaodfvfxNnFqi74g= +github.com/labstack/echo/v4 v4.2.1/go.mod h1:AA49e0DZ8kk5jTOOCKNuPR6oTnBS0dYiM4FW1e6jwpg= +github.com/labstack/echo/v4 v4.5.0/go.mod h1:czIriw4a0C1dFun+ObrXp7ok03xON0N1awStJ6ArI7Y= +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.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= +github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= +github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= +github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= +github.com/linxGnu/grocksdb v1.7.10/go.mod h1:0hTf+iA+GOr0jDX4CgIYyJZxqOH9XlBh6KVj8+zmF34= +github.com/lucasjones/reggen v0.0.0-20180717132126-cdb49ff09d77/go.mod h1:5ELEyG+X8f+meRWHuqUOewBOhvHkl7M76pdGEansxW4= +github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= +github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= +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.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.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= +github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +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.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/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.17/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.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/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/mediocregopher/mediocre-go-lib v0.0.0-20181029021733-cb65787f37ed/go.mod h1:dSsfyI2zABAdhcbvkXqgxOxrCsbYeHCPgrZkku60dSg= +github.com/mediocregopher/radix/v3 v3.3.0/go.mod h1:EmfVyvspXz1uZEyPBMyGK+kjWiKQGvsUt6O3Pj+LDCQ= +github.com/mediocregopher/radix/v3 v3.4.2/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i4n7wVopoX3x7Bv8= +github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= +github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643/go.mod h1:43+3pMjjKimDBf5Kr4ZFNGbLql1zKkbImw+fZbw3geM= +github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0/go.mod h1:43+3pMjjKimDBf5Kr4ZFNGbLql1zKkbImw+fZbw3geM= +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/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +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.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/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +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/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ= +github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae/go.mod h1:qAyveg+e4CE+eKJXWVjKXM4ck2QobLqTDytGJbLLhJg= +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= +github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mwitkow/grpc-proxy v0.0.0-20181017164139-0f1106ef9c76/go.mod h1:x5OoJHDHqxHS801UIuhqGl6QdSAEJvtausosHSdazIo= +github.com/naoina/go-stringutil v0.1.0/go.mod h1:XJ2SJL9jCtBh+P9q5btrd/Ylo8XwT/h1USek5+NqSA0= +github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416/go.mod h1:NBIhNtsFMo3G2szEBne+bO4gS192HuIYRqfvOWb4i1E= +github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= +github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= +github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k= +github.com/nats-io/nats.go v1.8.1/go.mod h1:BrFz9vVn0fU3AcH9Vn4Kd7W0NpJ651tD5omQ3M8LwxM= +github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= +github.com/nats-io/nkeys v0.0.2/go.mod h1:dab7URMsZm6Z/jp9Z5UGa87Uutgc2mVpXLC4B7TDb/4= +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/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= +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/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.13.0/go.mod h1:+REjRxOmWfHCjfv9TTWB1jD1Frx4XydAD3zm1lskyM0= +github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= +github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= +github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= +github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= +github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= +github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= +github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= +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/osmosis-labs/osmosis/osmoutils v0.0.3-rc0/go.mod h1:rO4YKI0ZQkS3o4UDhFuQFy+j4eM/as8GLvuBDNBStkQ= +github.com/osmosis-labs/osmosis/x/ibc-hooks v0.0.0-20230201151635-ef43e092d196/go.mod h1:eoSRNkeqi3ufOmvY8XcW8y0NgbbaPyBTEn7DTxq8XY4= +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/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +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/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo= +github.com/pelletier/go-toml/v2 v2.0.6/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek= +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/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o= +github.com/petermattis/goid v0.0.0-20221215004737-a150e88a970d/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= +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= +github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +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/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= +github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= +github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= +github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= +github.com/prometheus/client_golang v1.15.0/go.mod h1:e9yaBhRPU2pPNsZwE+JdQl0KEt1N9XgF6zxWmaC0xOk= +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/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +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= +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= +github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= +github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= +github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.3.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= +github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +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-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/regen-network/cosmos-proto v0.3.1/go.mod h1:jO0sVX6a1B36nmE8C9xBFXpNwWejXC7QqCOnH3O0+YM= +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/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= +github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= +github.com/rs/cors v1.8.3/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= +github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/zerolog v1.27.0/go.mod h1:7frBqO0oezxmnO7GF86FY++uy8I0Tk/If5ni1G9Qc0U= +github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +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/ryanuber/columnize v2.1.0+incompatible/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.3.1/go.mod h1:F73l+cr82YSh10GxyRI6qZiCgK64VaZjwesgfQ1/iLM= +github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g= +github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw= +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/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +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= +github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +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.3/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/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.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= +github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= +github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +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.15.0/go.mod h1:fFcTBJxvhhzSJiZy8n+PeW6t8l+KeT/uTARa0jHOQLA= +github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4/go.mod h1:RZLeN1LMWmRsyYjvAu+I6Dm9QmlDaIIt+Y+4Kd7Tp+Q= +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/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +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= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= +github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= +github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d/go.mod h1:RRCYJbIwD5jmqPI9XoAFR0OcDxqUctll6zUj/+B4S48= +github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c/go.mod h1:ahpPrc7HpcfEWDQRZEmnXMzHY03mLDYMCxeDzy46i+8= +github.com/tendermint/go-amino v0.16.0/go.mod h1:TQU0M1i/ImAo+tYpZi73AU3V/dKeCoMC9Sphe2ZwGME= +github.com/tidwall/btree v1.6.0/go.mod h1:twD9XRA5jj9VUQGELzDO4HPQTNJsoWWfYEL+EUQ2cKY= +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= +github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs= +github.com/tyler-smith/go-bip39 v1.0.2/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs= +github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= +github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M= +github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= +github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= +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/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= +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/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= +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/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= +github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= +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/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= +github.com/ybbus/jsonrpc v2.1.2+incompatible/go.mod h1:XJrh1eMSzdIYFbM08flv0wp5G35eRniyeGut1z+LSiE= +github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= +github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= +github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc= +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.1/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= +github.com/zondax/ledger-go v0.14.1/go.mod h1:fZ3Dqg6qcdXWSOJFKMG8GCTnD7slO/RL2feOQv8K320= +go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= +go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= +go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= +go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +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.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= +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-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190909091759-094676da4a83/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +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-20210921155107-089bfa567519/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.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= +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-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= +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= +golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= +golang.org/x/exp v0.0.0-20200513190911-00229845015e/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= +golang.org/x/exp v0.0.0-20230321023759-10a507213a29/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= +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-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +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/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.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-20180826012351-8a410e7b638d/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-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= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200421231249-e086a090c8fd/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +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-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-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= +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= +golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +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/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= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +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/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +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= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +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= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +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= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +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-20200905004654-be1d3432aa8f/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= +golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210112080510-489259a85091/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-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210316164454-77fc1eacc6aa/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-20210403161142-5e06dd20ab57/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-20210615035016-665e8c7367d1/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-20210909193231-528a39cd75f3/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-20211007075335-d3039528d8ac/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-20211216021012-1d35b9e2eb4e/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-20220412211240-33da011f77ad/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-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.7.0/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.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= +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= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +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/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +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-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/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-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/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= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190327201419-c70d86f8b7cf/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200108203644-89082a384178/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-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= +golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= +golang.org/x/tools v0.0.0-20201022035929-9cf592e881e9/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +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.3/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/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/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0= +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= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= +google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= +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/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +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/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto v0.0.0-20180518175338-11a468237815/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +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= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +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= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +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= +google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= +google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +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-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= +google.golang.org/genproto v0.0.0-20230216225411-c8e22ba71e44/go.mod h1:8B0gmkoRebU8ukX6HP+4wrVQUY1+6PkQ44BSyIlflHA= +google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= +google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.19.1/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.32.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= +google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= +google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g= +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= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= +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.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.30.0/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-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +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/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= +gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= +gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c= +gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200619000410-60c24ae608a6/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns= +gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/urfave/cli.v1 v1.20.0/go.mod h1:vuBzUtMdQeixQj8LVd+/98pzhxNGQoyuPBlsXHOQNO0= +gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= +gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20191120175047-4206685974f2/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= +honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +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/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= +nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= +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= +sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= From d490dbb4c3743c8169d1d055206a39b358538ff7 Mon Sep 17 00:00:00 2001 From: Jacob Gadikian Date: Mon, 24 Apr 2023 12:57:46 +0700 Subject: [PATCH 012/131] module import versioning --- app/app.go | 2 +- go.mod | 3 --- go.sum | 17 +++++++++++++++++ 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/app/app.go b/app/app.go index 7903ff8ab..5a6eaac85 100644 --- a/app/app.go +++ b/app/app.go @@ -7,6 +7,7 @@ import ( "strconv" "strings" + "cosmossdk.io/api" "cosmossdk.io/simapp" "github.com/CosmosContracts/juno/v15/app/openapiconsole" "github.com/CosmosContracts/juno/v15/docs" @@ -21,7 +22,6 @@ import ( "github.com/cosmos/cosmos-sdk/client/rpc" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/codec/types" - "github.com/cosmos/cosmos-sdk/server/api" "github.com/cosmos/cosmos-sdk/server/config" servertypes "github.com/cosmos/cosmos-sdk/server/types" sdk "github.com/cosmos/cosmos-sdk/types" diff --git a/go.mod b/go.mod index 41b76f68b..1ac0fb288 100644 --- a/go.mod +++ b/go.mod @@ -154,13 +154,10 @@ require ( replace ( // cosmos keyring github.com/99designs/keyring => github.com/cosmos/keyring v1.2.0 - // TODO: Simapp dependency, review removing when updating to SDK with backported update https://github.com/cosmos/cosmos-sdk/issues/13423 - github.com/btcsuite/btcd => github.com/btcsuite/btcd v0.22.2 // indirect // dgrijalva/jwt-go is deprecated and doesn't receive security updates. // TODO: remove it: https://github.com/cosmos/cosmos-sdk/issues/13134 github.com/dgrijalva/jwt-go => github.com/golang-jwt/jwt/v4 v4.4.2 // Fix upstream GHSA-h395-qcrw-5vmq vulnerability. // TODO Remove it: https://github.com/cosmos/cosmos-sdk/issues/10409 github.com/gin-gonic/gin => github.com/gin-gonic/gin v1.8.1 - ) diff --git a/go.sum b/go.sum index bb349ba58..cf9ffc308 100644 --- a/go.sum +++ b/go.sum @@ -39,7 +39,11 @@ cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RX 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= collectd.org v0.3.0/go.mod h1:A/8DzQBkF6abtvrT2j/AU/4tiBgJWYyh0y/oB/4MlWE= +cosmossdk.io/api v0.2.5-0.20230419061743-48d3d99110e7 h1:GTktofPmReteYJY0UWyeZpwp2T8DMgco5xhbRp3lsc0= +cosmossdk.io/api v0.2.5-0.20230419061743-48d3d99110e7/go.mod h1:z7wxLneHxynJAwnCtm+gd+Rnx4Tn1e4LJ7klB5C/5FY= cosmossdk.io/api v0.3.1/go.mod h1:DfHfMkiNA2Uhy8fj0JJlOCYOBp4eWUUJ1te5zBGNyIw= +cosmossdk.io/core v0.3.2 h1:KlQIufpJHJvOs7YLGTZsZcCo1WlkencDXepsr8STKZQ= +cosmossdk.io/core v0.3.2/go.mod h1:CO7vbe+evrBvHc0setFHL/u7nlY7HJGzdRSBkT/sirc= cosmossdk.io/core v0.5.1/go.mod h1:KZtwHCLjcFuo0nmDc24Xy6CRNEL9Vl/MeimQ2aC7NLE= cosmossdk.io/depinject v1.0.0-alpha.3/go.mod h1:eRbcdQ7MRpIPEM5YUJh8k97nxHpYbc3sMUnEtt8HPWU= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= @@ -59,6 +63,8 @@ github.com/CloudyKit/fastprinter v0.0.0-20170127035650-74b38d55f37a/go.mod h1:EF github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno= github.com/CloudyKit/jet v2.1.3-0.20180809161101-62edd43e4f88+incompatible/go.mod h1:HPYO+50pSWkPoj9Q/eq0aRGByCL6ScRlUmiEX5Zgm+w= github.com/CloudyKit/jet/v3 v3.0.0/go.mod h1:HKQPgSJmdK8hdoAbKUUWajkHyHo4RaU5rMdUywE7VMo= +github.com/CosmWasm/wasmd v0.31.0-rc0/go.mod h1:K7PYeURGa725BFo8z2VEmch+MVWtkEMrSEw1v/vpG94= +github.com/CosmWasm/wasmd v0.40.0-rc.1.0.20230422061626-b85abcf1d7b8 h1:daJIcrTcYkpDtn1DXqbGhnQkCPSD93El6mXfv15VJRA= github.com/CosmWasm/wasmd v0.40.0-rc.1.0.20230422061626-b85abcf1d7b8/go.mod h1:uacdue6EGn9JA1TqBNHB3iCe4PCIChuFT23AzIl2VME= github.com/CosmWasm/wasmvm v1.2.3/go.mod h1:vW/E3h8j9xBQs9bCoijDuawKo9kCtxOaS8N8J7KFtkc= github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= @@ -119,17 +125,24 @@ github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kB github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816/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-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.22.1/go.mod h1:wqgTSL29+50LRkmOVknEdmt8ZojIzhuWvgu/iptuN7Y= github.com/btcsuite/btcd v0.22.2/go.mod h1:wqgTSL29+50LRkmOVknEdmt8ZojIzhuWvgu/iptuN7Y= github.com/btcsuite/btcd/btcec/v2 v2.1.2/go.mod h1:ctjw4H1kknNJmRN4iP1R7bTQ+v3GJkZBd6mui8ZsAZE= github.com/btcsuite/btcd/btcec/v2 v2.3.2/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= github.com/btcsuite/btcd/chaincfg/chainhash v1.0.0/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= 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-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/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= +github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= 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= @@ -187,6 +200,8 @@ github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfc github.com/cosmos/btcutil v1.0.5/go.mod h1:IyB7iuqZMJlthe2tkIFL33xPyzbFYP0XVdS8P5lUPis= github.com/cosmos/cosmos-db v0.0.0-20221226095112-f3c38ecb5e32/go.mod h1:kwMlEC4wWvB48zAShGKVqboJL6w4zCLesaNQ3YLU2BQ= github.com/cosmos/cosmos-proto v1.0.0-beta.2/go.mod h1:+XRCLJ14pr5HFEHIUcn51IKXD1Fy3rkEQqt4WqmN4V0= +github.com/cosmos/cosmos-sdk v0.46.12/go.mod h1:bG4AkW9bqc8ycrryyKGQEl3YV9BY2wr6HggGq8kvcgM= +github.com/cosmos/cosmos-sdk v0.47.1 h1:HnaCYtaAMWZp1SdlwwE1mPJ8kFlZ/TuEJ/ciNXH6Uno= github.com/cosmos/cosmos-sdk v0.47.1/go.mod h1:14tO5KQaTrl2q3OxBnDRfue7TRN9zkXS0cLutrSqkOo= github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d/go.mod h1:tSxLoYXyBmiFeKpvmq4dzayMdCjCnu8uqmCysIGBT2Y= github.com/cosmos/go-bip39 v1.0.0/go.mod h1:RNJv0H/pOIVgxw6KS7QeX2a0Uo0aKUlfhZ4xuwvCdJw= @@ -498,6 +513,7 @@ github.com/iris-contrib/pongo2 v0.0.1/go.mod h1:Ssh+00+3GAZqSQb30AvBRNxBx7rf0Gqw github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw= 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/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= @@ -898,6 +914,7 @@ go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9E 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= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= From b6efe8101880f6d197f17359e2892e63f22bb967 Mon Sep 17 00:00:00 2001 From: Jacob Gadikian Date: Mon, 24 Apr 2023 13:17:29 +0700 Subject: [PATCH 013/131] resolve import of an old juno --- go.mod | 2 ++ x/globalfee/genesis_test.go | 2 +- x/mint/module.go | 7 ------- 3 files changed, 3 insertions(+), 8 deletions(-) diff --git a/go.mod b/go.mod index 1ac0fb288..10bd4b670 100644 --- a/go.mod +++ b/go.mod @@ -160,4 +160,6 @@ replace ( // Fix upstream GHSA-h395-qcrw-5vmq vulnerability. // TODO Remove it: https://github.com/cosmos/cosmos-sdk/issues/10409 github.com/gin-gonic/gin => github.com/gin-gonic/gin v1.8.1 + + github.com/cosmos/cosmos-sdk => github.com/notional-labs/cosmos-sdk v0.47.2-0.20230424060617-ebc292e8de8b ) diff --git a/x/globalfee/genesis_test.go b/x/globalfee/genesis_test.go index 03102c34b..fa2e624eb 100644 --- a/x/globalfee/genesis_test.go +++ b/x/globalfee/genesis_test.go @@ -5,7 +5,7 @@ import ( "time" "cosmossdk.io/simapp" - appparams "github.com/CosmosContracts/juno/app/params" + appparams "github.com/CosmosContracts/juno/v15/app/params" dbm "github.com/cometbft/cometbft-db" "github.com/cometbft/cometbft/libs/log" tmproto "github.com/cometbft/cometbft/proto/tendermint/types" diff --git a/x/mint/module.go b/x/mint/module.go index a1ede3e55..f7f2c7f9c 100644 --- a/x/mint/module.go +++ b/x/mint/module.go @@ -7,12 +7,10 @@ import ( "math/rand" abci "github.com/cometbft/cometbft/abci/types" - "github.com/gorilla/mux" "github.com/grpc-ecosystem/grpc-gateway/runtime" "github.com/spf13/cobra" "github.com/CosmosContracts/juno/v15/x/mint/client/cli" - "github.com/CosmosContracts/juno/v15/x/mint/client/rest" "github.com/CosmosContracts/juno/v15/x/mint/keeper" "github.com/CosmosContracts/juno/v15/x/mint/simulation" "github.com/CosmosContracts/juno/v15/x/mint/types" @@ -64,11 +62,6 @@ func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, _ client.TxEncodingCo return types.ValidateGenesis(data) } -// RegisterRESTRoutes registers the REST routes for the mint module. -func (AppModuleBasic) RegisterRESTRoutes(clientCtx client.Context, rtr *mux.Router) { - rest.RegisterRoutes(clientCtx, rtr) -} - // RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the mint module. func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) { if err := types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(clientCtx)); err != nil { From 48de4c4de1fc558a0d8283a24b86a54cec0aedb7 Mon Sep 17 00:00:00 2001 From: Jacob Gadikian Date: Mon, 24 Apr 2023 13:27:04 +0700 Subject: [PATCH 014/131] upgrade tests --- app/apptesting/events.go | 17 ++ app/apptesting/test_suite.go | 295 +++++++++++++++++++++++++++++++++++ go.mod | 3 + tests/interchaintest/go.mod | 6 +- 4 files changed, 317 insertions(+), 4 deletions(-) create mode 100644 app/apptesting/events.go create mode 100644 app/apptesting/test_suite.go diff --git a/app/apptesting/events.go b/app/apptesting/events.go new file mode 100644 index 000000000..f5a434937 --- /dev/null +++ b/app/apptesting/events.go @@ -0,0 +1,17 @@ +package apptesting + +import sdk "github.com/cosmos/cosmos-sdk/types" + +// AssertEventEmitted asserts that ctx's event manager has emitted the given number of events +// of the given type. +func (s *KeeperTestHelper) AssertEventEmitted(ctx sdk.Context, eventTypeExpected string, numEventsExpected int) { + allEvents := ctx.EventManager().Events() + // filter out other events + actualEvents := make([]sdk.Event, 0) + for _, event := range allEvents { + if event.Type == eventTypeExpected { + actualEvents = append(actualEvents, event) + } + } + s.Equal(numEventsExpected, len(actualEvents)) +} diff --git a/app/apptesting/test_suite.go b/app/apptesting/test_suite.go new file mode 100644 index 000000000..baaa91c1f --- /dev/null +++ b/app/apptesting/test_suite.go @@ -0,0 +1,295 @@ +package apptesting + +import ( + "encoding/json" + "fmt" + "testing" + "time" + + abci "github.com/cometbft/cometbft/abci/types" + "github.com/cometbft/cometbft/crypto/ed25519" + "github.com/cometbft/cometbft/libs/log" + tmtypes "github.com/cometbft/cometbft/proto/tendermint/types" + "github.com/cosmos/cosmos-sdk/baseapp" + "github.com/cosmos/cosmos-sdk/client" + cdctypes "github.com/cosmos/cosmos-sdk/codec/types" + "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" + "github.com/cosmos/cosmos-sdk/simapp" + "github.com/cosmos/cosmos-sdk/store/rootmulti" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/tx/signing" + authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing" + "github.com/cosmos/cosmos-sdk/x/authz" + distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" + slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" + "github.com/cosmos/cosmos-sdk/x/staking" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" + dbm "github.com/tendermint/tm-db" + + authzcodec "github.com/CosmosContracts/juno/v15/x/tokenfactory/types/authzcodec" + + "github.com/CosmosContracts/juno/v15/app" + minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" +) + +type KeeperTestHelper struct { + suite.Suite + + App *app.TokenApp + Ctx sdk.Context + QueryHelper *baseapp.QueryServiceTestHelper + TestAccs []sdk.AccAddress +} + +var ( + SecondaryDenom = "uion" + SecondaryAmount = sdk.NewInt(100000000) +) + +// Setup sets up basic environment for suite (App, Ctx, and test accounts) +func (s *KeeperTestHelper) Setup() { + s.App = app.Setup(false) + s.Ctx = s.App.BaseApp.NewContext(false, tmtypes.Header{Height: 1, ChainID: "osmosis-1", Time: time.Now().UTC()}) + s.QueryHelper = &baseapp.QueryServiceTestHelper{ + GRPCQueryRouter: s.App.GRPCQueryRouter(), + Ctx: s.Ctx, + } + s.TestAccs = CreateRandomAccounts(3) +} + +func (s *KeeperTestHelper) SetupTestForInitGenesis() { + // Setting to True, leads to init genesis not running + s.App = app.Setup(true) + s.Ctx = s.App.BaseApp.NewContext(true, tmtypes.Header{}) +} + +// CreateTestContext creates a test context. +func (s *KeeperTestHelper) CreateTestContext() sdk.Context { + ctx, _ := s.CreateTestContextWithMultiStore() + return ctx +} + +// CreateTestContextWithMultiStore creates a test context and returns it together with multi store. +func (s *KeeperTestHelper) CreateTestContextWithMultiStore() (sdk.Context, sdk.CommitMultiStore) { + db := dbm.NewMemDB() + logger := log.NewNopLogger() + + ms := rootmulti.NewStore(db, logger) + + return sdk.NewContext(ms, tmtypes.Header{}, false, logger), ms +} + +// CreateTestContext creates a test context. +func (s *KeeperTestHelper) Commit() { + oldHeight := s.Ctx.BlockHeight() + oldHeader := s.Ctx.BlockHeader() + s.App.Commit() + newHeader := tmtypes.Header{Height: oldHeight + 1, ChainID: oldHeader.ChainID, Time: oldHeader.Time.Add(time.Second)} + s.App.BeginBlock(abci.RequestBeginBlock{Header: newHeader}) + s.Ctx = s.App.NewContext(false, newHeader) +} + +// FundAcc funds target address with specified amount. +func (s *KeeperTestHelper) FundAcc(acc sdk.AccAddress, amounts sdk.Coins) { + err := simapp.FundAccount(s.App.BankKeeper, s.Ctx, acc, amounts) + s.Require().NoError(err) +} + +// FundModuleAcc funds target modules with specified amount. +func (s *KeeperTestHelper) FundModuleAcc(moduleName string, amounts sdk.Coins) { + err := simapp.FundModuleAccount(s.App.BankKeeper, s.Ctx, moduleName, amounts) + s.Require().NoError(err) +} + +func (s *KeeperTestHelper) MintCoins(coins sdk.Coins) { + err := s.App.BankKeeper.MintCoins(s.Ctx, minttypes.ModuleName, coins) + s.Require().NoError(err) +} + +// SetupValidator sets up a validator and returns the ValAddress. +func (s *KeeperTestHelper) SetupValidator(bondStatus stakingtypes.BondStatus) sdk.ValAddress { + valPub := secp256k1.GenPrivKey().PubKey() + valAddr := sdk.ValAddress(valPub.Address()) + bondDenom := s.App.StakingKeeper.GetParams(s.Ctx).BondDenom + selfBond := sdk.NewCoins(sdk.Coin{Amount: sdk.NewInt(100), Denom: bondDenom}) + + s.FundAcc(sdk.AccAddress(valAddr), selfBond) + + stakingHandler := staking.NewHandler(s.App.StakingKeeper) + stakingCoin := sdk.NewCoin(sdk.DefaultBondDenom, selfBond[0].Amount) + ZeroCommission := stakingtypes.NewCommissionRates(sdk.ZeroDec(), sdk.ZeroDec(), sdk.ZeroDec()) + msg, err := stakingtypes.NewMsgCreateValidator(valAddr, valPub, stakingCoin, stakingtypes.Description{}, ZeroCommission, sdk.OneInt()) + s.Require().NoError(err) + res, err := stakingHandler(s.Ctx, msg) + s.Require().NoError(err) + s.Require().NotNil(res) + + val, found := s.App.StakingKeeper.GetValidator(s.Ctx, valAddr) + s.Require().True(found) + + val = val.UpdateStatus(bondStatus) + s.App.StakingKeeper.SetValidator(s.Ctx, val) + + consAddr, err := val.GetConsAddr() + s.Suite.Require().NoError(err) + + signingInfo := slashingtypes.NewValidatorSigningInfo( + consAddr, + s.Ctx.BlockHeight(), + 0, + time.Unix(0, 0), + false, + 0, + ) + s.App.SlashingKeeper.SetValidatorSigningInfo(s.Ctx, consAddr, signingInfo) + + return valAddr +} + +// BeginNewBlock starts a new block. +func (s *KeeperTestHelper) BeginNewBlock() { + var valAddr []byte + + validators := s.App.StakingKeeper.GetAllValidators(s.Ctx) + if len(validators) >= 1 { + valAddrFancy, err := validators[0].GetConsAddr() + s.Require().NoError(err) + valAddr = valAddrFancy.Bytes() + } else { + valAddrFancy := s.SetupValidator(stakingtypes.Bonded) + validator, _ := s.App.StakingKeeper.GetValidator(s.Ctx, valAddrFancy) + valAddr2, _ := validator.GetConsAddr() + valAddr = valAddr2.Bytes() + } + + s.BeginNewBlockWithProposer(valAddr) +} + +// BeginNewBlockWithProposer begins a new block with a proposer. +func (s *KeeperTestHelper) BeginNewBlockWithProposer(proposer sdk.ValAddress) { + validator, found := s.App.StakingKeeper.GetValidator(s.Ctx, proposer) + s.Assert().True(found) + + valConsAddr, err := validator.GetConsAddr() + s.Require().NoError(err) + + valAddr := valConsAddr.Bytes() + + newBlockTime := s.Ctx.BlockTime().Add(5 * time.Second) + + header := tmtypes.Header{Height: s.Ctx.BlockHeight() + 1, Time: newBlockTime} + newCtx := s.Ctx.WithBlockTime(newBlockTime).WithBlockHeight(s.Ctx.BlockHeight() + 1) + s.Ctx = newCtx + lastCommitInfo := abci.LastCommitInfo{ + Votes: []abci.VoteInfo{{ + Validator: abci.Validator{Address: valAddr, Power: 1000}, + SignedLastBlock: true, + }}, + } + reqBeginBlock := abci.RequestBeginBlock{Header: header, LastCommitInfo: lastCommitInfo} + + fmt.Println("beginning block ", s.Ctx.BlockHeight()) + s.App.BeginBlocker(s.Ctx, reqBeginBlock) +} + +// EndBlock ends the block. +func (s *KeeperTestHelper) EndBlock() { + reqEndBlock := abci.RequestEndBlock{Height: s.Ctx.BlockHeight()} + s.App.EndBlocker(s.Ctx, reqEndBlock) +} + +// AllocateRewardsToValidator allocates reward tokens to a distribution module then allocates rewards to the validator address. +func (s *KeeperTestHelper) AllocateRewardsToValidator(valAddr sdk.ValAddress, rewardAmt sdk.Int) { + validator, found := s.App.StakingKeeper.GetValidator(s.Ctx, valAddr) + s.Require().True(found) + + // allocate reward tokens to distribution module + coins := sdk.Coins{sdk.NewCoin(sdk.DefaultBondDenom, rewardAmt)} + err := simapp.FundModuleAccount(s.App.BankKeeper, s.Ctx, distrtypes.ModuleName, coins) + s.Require().NoError(err) + + // allocate rewards to validator + s.Ctx = s.Ctx.WithBlockHeight(s.Ctx.BlockHeight() + 1) + decTokens := sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: sdk.NewDec(20000)}} + s.App.DistrKeeper.AllocateTokensToValidator(s.Ctx, validator, decTokens) +} + +// BuildTx builds a transaction. +func (s *KeeperTestHelper) BuildTx( + txBuilder client.TxBuilder, + msgs []sdk.Msg, + sigV2 signing.SignatureV2, + memo string, txFee sdk.Coins, + gasLimit uint64, +) authsigning.Tx { + err := txBuilder.SetMsgs(msgs[0]) + s.Require().NoError(err) + + err = txBuilder.SetSignatures(sigV2) + s.Require().NoError(err) + + txBuilder.SetMemo(memo) + txBuilder.SetFeeAmount(txFee) + txBuilder.SetGasLimit(gasLimit) + + return txBuilder.GetTx() +} + +// CreateRandomAccounts is a function return a list of randomly generated AccAddresses +func CreateRandomAccounts(numAccts int) []sdk.AccAddress { + testAddrs := make([]sdk.AccAddress, numAccts) + for i := 0; i < numAccts; i++ { + pk := ed25519.GenPrivKey().PubKey() + testAddrs[i] = sdk.AccAddress(pk.Address()) + } + + return testAddrs +} + +func TestMessageAuthzSerialization(t *testing.T, msg sdk.Msg) { + someDate := time.Date(1, 1, 1, 1, 1, 1, 1, time.UTC) + const ( + mockGranter string = "cosmos1abc" + mockGrantee string = "cosmos1xyz" + ) + + var ( + mockMsgGrant authz.MsgGrant + mockMsgRevoke authz.MsgRevoke + mockMsgExec authz.MsgExec + ) + + // Authz: Grant Msg + typeURL := sdk.MsgTypeURL(msg) + grant, err := authz.NewGrant(authz.NewGenericAuthorization(typeURL), someDate.Add(time.Hour)) + require.NoError(t, err) + + msgGrant := authz.MsgGrant{Granter: mockGranter, Grantee: mockGrantee, Grant: grant} + msgGrantBytes := json.RawMessage(sdk.MustSortJSON(authzcodec.ModuleCdc.MustMarshalJSON(&msgGrant))) + err = authzcodec.ModuleCdc.UnmarshalJSON(msgGrantBytes, &mockMsgGrant) + require.NoError(t, err) + + // Authz: Revoke Msg + msgRevoke := authz.MsgRevoke{Granter: mockGranter, Grantee: mockGrantee, MsgTypeUrl: typeURL} + msgRevokeByte := json.RawMessage(sdk.MustSortJSON(authzcodec.ModuleCdc.MustMarshalJSON(&msgRevoke))) + err = authzcodec.ModuleCdc.UnmarshalJSON(msgRevokeByte, &mockMsgRevoke) + require.NoError(t, err) + + // Authz: Exec Msg + msgAny, err := cdctypes.NewAnyWithValue(msg) + require.NoError(t, err) + msgExec := authz.MsgExec{Grantee: mockGrantee, Msgs: []*cdctypes.Any{msgAny}} + execMsgByte := json.RawMessage(sdk.MustSortJSON(authzcodec.ModuleCdc.MustMarshalJSON(&msgExec))) + err = authzcodec.ModuleCdc.UnmarshalJSON(execMsgByte, &mockMsgExec) + require.NoError(t, err) + require.Equal(t, msgExec.Msgs[0].Value, mockMsgExec.Msgs[0].Value) +} + +func GenerateTestAddrs() (string, string) { + pk1 := ed25519.GenPrivKey().PubKey() + validAddr := sdk.AccAddress(pk1.Address()).String() + invalidAddr := sdk.AccAddress("invalid").String() + return validAddr, invalidAddr +} diff --git a/go.mod b/go.mod index 10bd4b670..f0521a279 100644 --- a/go.mod +++ b/go.mod @@ -161,5 +161,8 @@ replace ( // TODO Remove it: https://github.com/cosmos/cosmos-sdk/issues/10409 github.com/gin-gonic/gin => github.com/gin-gonic/gin v1.8.1 + // temporary, need to fix, issue is at import of: github.com/cosmos/gogogateway + github.com/gogo/protobuf v1.3.3 => github.com/gogo/protobuf v1.3.2 + github.com/cosmos/cosmos-sdk => github.com/notional-labs/cosmos-sdk v0.47.2-0.20230424060617-ebc292e8de8b ) diff --git a/tests/interchaintest/go.mod b/tests/interchaintest/go.mod index e447fa393..46741cd1a 100644 --- a/tests/interchaintest/go.mod +++ b/tests/interchaintest/go.mod @@ -3,10 +3,8 @@ module github.com/CosmosContracts/juno/tests/interchaintest go 1.19 require ( - github.com/CosmosContracts/juno/v13 v13.0.0 - github.com/cosmos/cosmos-sdk v0.45.14 - github.com/cosmos/ibc-go/v7 v4.3.0 - github.com/strangelove-ventures/interchaintest/v4 v4.0.0-20230331040355-5d08aab13017 + github.com/cosmos/cosmos-sdk v0.47.1 + github.com/cosmos/ibc-go/v7 v7.0.0 github.com/stretchr/testify v1.8.2 go.uber.org/zap v1.23.0 ) From c429f1bc86dd54e9f150f8e06eba5706143effc8 Mon Sep 17 00:00:00 2001 From: Jacob Gadikian Date: Mon, 24 Apr 2023 13:27:58 +0700 Subject: [PATCH 015/131] fix simapp import path --- app/apptesting/test_suite.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/apptesting/test_suite.go b/app/apptesting/test_suite.go index baaa91c1f..329a72ccc 100644 --- a/app/apptesting/test_suite.go +++ b/app/apptesting/test_suite.go @@ -6,6 +6,7 @@ import ( "testing" "time" + "cosmossdk.io/simapp" abci "github.com/cometbft/cometbft/abci/types" "github.com/cometbft/cometbft/crypto/ed25519" "github.com/cometbft/cometbft/libs/log" @@ -14,7 +15,6 @@ import ( "github.com/cosmos/cosmos-sdk/client" cdctypes "github.com/cosmos/cosmos-sdk/codec/types" "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" - "github.com/cosmos/cosmos-sdk/simapp" "github.com/cosmos/cosmos-sdk/store/rootmulti" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/tx/signing" From 3b7701db0d1f91fd51c98de7ef1ed54f0f8074da Mon Sep 17 00:00:00 2001 From: Jacob Gadikian Date: Mon, 24 Apr 2023 13:32:01 +0700 Subject: [PATCH 016/131] add osmoutils and change import paths --- osmoutils/.DS_Store | Bin 0 -> 6148 bytes osmoutils/accum/accum.go | 401 +++++ osmoutils/accum/accum.pb.go | 860 +++++++++ osmoutils/accum/accum_helpers.go | 61 + osmoutils/accum/accum_helpers_test.go | 50 + osmoutils/accum/accum_test.go | 1568 +++++++++++++++++ osmoutils/accum/errors.go | 44 + osmoutils/accum/export_test.go | 77 + osmoutils/accum/module.go | 3 + osmoutils/accum/options.go | 20 + osmoutils/accum/options_test.go | 32 + osmoutils/accum/prefix.go | 30 + osmoutils/address.go | 12 + osmoutils/cache_ctx.go | 80 + osmoutils/cache_ctx_test.go | 59 + osmoutils/cli_helpers.go | 76 + osmoutils/coin_helper.go | 46 + osmoutils/coin_helper_test.go | 83 + osmoutils/conv_helper.go | 16 + osmoutils/cosmwasm/helpers.go | 223 +++ osmoutils/encoding_helper.go | 25 + osmoutils/encoding_helper_test.go | 29 + osmoutils/export_test.go | 11 + osmoutils/generic_helper.go | 17 + osmoutils/go.mod | 145 ++ osmoutils/go.sum | 1352 ++++++++++++++ osmoutils/ibc.go | 70 + osmoutils/module_account.go | 86 + osmoutils/module_account_test.go | 66 + osmoutils/noapptest/cdc.go | 45 + osmoutils/noapptest/ctx.go | 32 + osmoutils/osmoassert/assertions.go | 60 + osmoutils/osmocli/cli_tester.go | 111 ++ osmoutils/osmocli/flag_advice.go | 79 + osmoutils/osmocli/index_cmd.go | 31 + osmoutils/osmocli/parsers.go | 343 ++++ osmoutils/osmocli/parsers_test.go | 166 ++ osmoutils/osmocli/query_cmd_wrap.go | 181 ++ osmoutils/osmocli/string_formatter.go | 49 + osmoutils/osmocli/tx_cmd_wrap.go | 99 ++ osmoutils/parse.go | 71 + osmoutils/partialord/internal/dag/dag.go | 320 ++++ osmoutils/partialord/internal/dag/dag_test.go | 154 ++ osmoutils/partialord/internal/dag/module.go | 9 + osmoutils/partialord/module.go | 2 + osmoutils/partialord/partialord.go | 97 + osmoutils/partialord/partialord_test.go | 74 + osmoutils/slice_helper.go | 94 + osmoutils/slice_helper_test.go | 93 + osmoutils/store_helper.go | 194 ++ osmoutils/store_helper_test.go | 1245 +++++++++++++ osmoutils/sumtree/README.md | 151 ++ osmoutils/sumtree/constants.go | 13 + osmoutils/sumtree/legacy/v101/old_tree.json | 12 + osmoutils/sumtree/legacy/v101/tree.go | 101 ++ osmoutils/sumtree/legacy/v101/tree_test.go | 147 ++ osmoutils/sumtree/node.go | 261 +++ osmoutils/sumtree/tree.go | 295 ++++ osmoutils/sumtree/tree.pb.go | 737 ++++++++ osmoutils/sumtree/tree_test.go | 136 ++ 60 files changed, 10944 insertions(+) create mode 100644 osmoutils/.DS_Store create mode 100644 osmoutils/accum/accum.go create mode 100644 osmoutils/accum/accum.pb.go create mode 100644 osmoutils/accum/accum_helpers.go create mode 100644 osmoutils/accum/accum_helpers_test.go create mode 100644 osmoutils/accum/accum_test.go create mode 100644 osmoutils/accum/errors.go create mode 100644 osmoutils/accum/export_test.go create mode 100644 osmoutils/accum/module.go create mode 100644 osmoutils/accum/options.go create mode 100644 osmoutils/accum/options_test.go create mode 100644 osmoutils/accum/prefix.go create mode 100644 osmoutils/address.go create mode 100644 osmoutils/cache_ctx.go create mode 100644 osmoutils/cache_ctx_test.go create mode 100644 osmoutils/cli_helpers.go create mode 100644 osmoutils/coin_helper.go create mode 100644 osmoutils/coin_helper_test.go create mode 100644 osmoutils/conv_helper.go create mode 100644 osmoutils/cosmwasm/helpers.go create mode 100644 osmoutils/encoding_helper.go create mode 100644 osmoutils/encoding_helper_test.go create mode 100644 osmoutils/export_test.go create mode 100644 osmoutils/generic_helper.go create mode 100644 osmoutils/go.mod create mode 100644 osmoutils/go.sum create mode 100644 osmoutils/ibc.go create mode 100644 osmoutils/module_account.go create mode 100644 osmoutils/module_account_test.go create mode 100644 osmoutils/noapptest/cdc.go create mode 100644 osmoutils/noapptest/ctx.go create mode 100644 osmoutils/osmoassert/assertions.go create mode 100644 osmoutils/osmocli/cli_tester.go create mode 100644 osmoutils/osmocli/flag_advice.go create mode 100644 osmoutils/osmocli/index_cmd.go create mode 100644 osmoutils/osmocli/parsers.go create mode 100644 osmoutils/osmocli/parsers_test.go create mode 100644 osmoutils/osmocli/query_cmd_wrap.go create mode 100644 osmoutils/osmocli/string_formatter.go create mode 100644 osmoutils/osmocli/tx_cmd_wrap.go create mode 100644 osmoutils/parse.go create mode 100644 osmoutils/partialord/internal/dag/dag.go create mode 100644 osmoutils/partialord/internal/dag/dag_test.go create mode 100644 osmoutils/partialord/internal/dag/module.go create mode 100644 osmoutils/partialord/module.go create mode 100644 osmoutils/partialord/partialord.go create mode 100644 osmoutils/partialord/partialord_test.go create mode 100644 osmoutils/slice_helper.go create mode 100644 osmoutils/slice_helper_test.go create mode 100644 osmoutils/store_helper.go create mode 100644 osmoutils/store_helper_test.go create mode 100644 osmoutils/sumtree/README.md create mode 100644 osmoutils/sumtree/constants.go create mode 100644 osmoutils/sumtree/legacy/v101/old_tree.json create mode 100644 osmoutils/sumtree/legacy/v101/tree.go create mode 100644 osmoutils/sumtree/legacy/v101/tree_test.go create mode 100644 osmoutils/sumtree/node.go create mode 100644 osmoutils/sumtree/tree.go create mode 100644 osmoutils/sumtree/tree.pb.go create mode 100644 osmoutils/sumtree/tree_test.go diff --git a/osmoutils/.DS_Store b/osmoutils/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..f9b392d6f5ef6c6e70d98b5504d75bd7a6cd9f4e GIT binary patch literal 6148 zcmeHLyH3L}6upL)K3F<3W@2C~Ul6LYu%SxKl(vFO390&EL|IuX{-F~C8|)0Mu=NM% zH?VWAZCX1Ix>bPe$Ue@^v3+vf*hz^>~^= z>#a@{4pLkfa1J;JexC#U>=vm_9UK#~pI1)}BIqA;B=UXPND?i$A6 z%2*-P3R0nKilAYDV@y37(b!%`Dt8zqgJtSDY&{*Eyh}Zq%$2U6nU+5CFfdi2ZbYHf zI6|#Q!=%EUc^=QyI6GTv%F}FQi z;d7K`nA+Yxmf8~in5yzwmLBY)8%%n%^6m!5bVE4@oCANu0bUT)jvdK>`y8e@fsAPLnJsG17>i6K;T#68XPHO2~6a}w&+frK7e=r0r@M@Rpj zq?7O!y3#q|9IzeOR;M-I|Bv&(|LsQZ%sJp3_*V{yLbKIu;Fk2>nz}jOYdz$1WKPVB o70M 0 { + for iNdEx := len(m.AccumValue) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.AccumValue[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintAccum(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *Options) 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 *Options) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Options) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *Record) 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 *Record) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Record) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Options != nil { + { + size, err := m.Options.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintAccum(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + } + if len(m.UnclaimedRewards) > 0 { + for iNdEx := len(m.UnclaimedRewards) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.UnclaimedRewards[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintAccum(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + } + if len(m.InitAccumValue) > 0 { + for iNdEx := len(m.InitAccumValue) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.InitAccumValue[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintAccum(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + { + size := m.NumShares.Size() + i -= size + if _, err := m.NumShares.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintAccum(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func encodeVarintAccum(dAtA []byte, offset int, v uint64) int { + offset -= sovAccum(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *AccumulatorContent) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.AccumValue) > 0 { + for _, e := range m.AccumValue { + l = e.Size() + n += 1 + l + sovAccum(uint64(l)) + } + } + l = m.TotalShares.Size() + n += 1 + l + sovAccum(uint64(l)) + return n +} + +func (m *Options) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *Record) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.NumShares.Size() + n += 1 + l + sovAccum(uint64(l)) + if len(m.InitAccumValue) > 0 { + for _, e := range m.InitAccumValue { + l = e.Size() + n += 1 + l + sovAccum(uint64(l)) + } + } + if len(m.UnclaimedRewards) > 0 { + for _, e := range m.UnclaimedRewards { + l = e.Size() + n += 1 + l + sovAccum(uint64(l)) + } + } + if m.Options != nil { + l = m.Options.Size() + n += 1 + l + sovAccum(uint64(l)) + } + return n +} + +func sovAccum(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozAccum(x uint64) (n int) { + return sovAccum(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *AccumulatorContent) 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 ErrIntOverflowAccum + } + 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: AccumulatorContent: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AccumulatorContent: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AccumValue", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAccum + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthAccum + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthAccum + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AccumValue = append(m.AccumValue, types.DecCoin{}) + if err := m.AccumValue[len(m.AccumValue)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TotalShares", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAccum + } + 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 ErrInvalidLengthAccum + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthAccum + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.TotalShares.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipAccum(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthAccum + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Options) 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 ErrIntOverflowAccum + } + 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: Options: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Options: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipAccum(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthAccum + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Record) 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 ErrIntOverflowAccum + } + 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: Record: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Record: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NumShares", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAccum + } + 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 ErrInvalidLengthAccum + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthAccum + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.NumShares.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field InitAccumValue", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAccum + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthAccum + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthAccum + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.InitAccumValue = append(m.InitAccumValue, types.DecCoin{}) + if err := m.InitAccumValue[len(m.InitAccumValue)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field UnclaimedRewards", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAccum + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthAccum + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthAccum + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.UnclaimedRewards = append(m.UnclaimedRewards, types.DecCoin{}) + if err := m.UnclaimedRewards[len(m.UnclaimedRewards)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Options", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAccum + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthAccum + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthAccum + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Options == nil { + m.Options = &Options{} + } + if err := m.Options.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipAccum(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthAccum + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipAccum(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, ErrIntOverflowAccum + } + 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, ErrIntOverflowAccum + } + 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, ErrIntOverflowAccum + } + 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, ErrInvalidLengthAccum + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupAccum + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthAccum + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthAccum = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowAccum = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupAccum = fmt.Errorf("proto: unexpected end of group") +) diff --git a/osmoutils/accum/accum_helpers.go b/osmoutils/accum/accum_helpers.go new file mode 100644 index 000000000..3d2bbf7f8 --- /dev/null +++ b/osmoutils/accum/accum_helpers.go @@ -0,0 +1,61 @@ +package accum + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/CosmosContracts/juno/v15/osmoutils" +) + +var minusOne = sdk.NewDec(-1) + +// Creates a new position or override an existing position +// at accumulator's current value with a specific number of shares and unclaimed rewards +func initOrUpdatePosition(accum AccumulatorObject, accumulatorValue sdk.DecCoins, index string, numShareUnits sdk.Dec, unclaimedRewards sdk.DecCoins, options *Options) { + position := Record{ + NumShares: numShareUnits, + InitAccumValue: accumulatorValue, + UnclaimedRewards: unclaimedRewards, + Options: options, + } + osmoutils.MustSet(accum.store, FormatPositionPrefixKey(accum.name, index), &position) +} + +// Gets addr's current position from store +func GetPosition(accum AccumulatorObject, name string) (Record, error) { + position := Record{} + found, err := osmoutils.Get(accum.store, FormatPositionPrefixKey(accum.name, name), &position) + if err != nil { + return Record{}, err + } + if !found { + return Record{}, NoPositionError{name} + } + + return position, nil +} + +// Gets total unclaimed rewards, including existing and newly accrued unclaimed rewards +func GetTotalRewards(accum AccumulatorObject, position Record) sdk.DecCoins { + totalRewards := position.UnclaimedRewards + + // TODO: add a check that accum.value is greater than position.InitAccumValue + accumulatorRewards := accum.value.Sub(position.InitAccumValue).MulDec(position.NumShares) + totalRewards = totalRewards.Add(accumulatorRewards...) + + return totalRewards +} + +// validateAccumulatorValue validates the provided accumulator. +// All coins in custom accumulator value must be non-negative. +// Custom accumulator value must be a superset of the old accumulator value. +// Fails if any coin is negative. On success, returns nil. +func validateAccumulatorValue(customAccumulatorValue, oldPositionAccumulatorValue sdk.DecCoins) error { + if customAccumulatorValue.IsAnyNegative() { + return NegativeCustomAccError{customAccumulatorValue} + } + newValue, IsAnyNegative := customAccumulatorValue.SafeSub(oldPositionAccumulatorValue) + if IsAnyNegative { + return NegativeAccDifferenceError{newValue.MulDec(minusOne)} + } + return nil +} diff --git a/osmoutils/accum/accum_helpers_test.go b/osmoutils/accum/accum_helpers_test.go new file mode 100644 index 000000000..0bcd7a5a3 --- /dev/null +++ b/osmoutils/accum/accum_helpers_test.go @@ -0,0 +1,50 @@ +package accum_test + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/CosmosContracts/juno/v15/osmoutils/accum" +) + +func (suite *AccumTestSuite) TestValidateAccumulatorValue() { + tests := map[string]struct { + customAccumulatorValue sdk.DecCoins + oldPositionAccumulatorValue sdk.DecCoins + expectError error + }{ + "negative custom coins - error": { + customAccumulatorValue: initialCoinsDenomOne.MulDec(sdk.NewDec(-1)), + oldPositionAccumulatorValue: emptyCoins, + expectError: accum.NegativeCustomAccError{initialCoinsDenomOne.MulDec(sdk.NewDec(-1))}, + }, + "old accumulator coins are greater than new - error": { + customAccumulatorValue: initialCoinsDenomOne, + oldPositionAccumulatorValue: initialCoinsDenomOne.Add(sdk.NewDecCoin(initialCoinDenomOne.Denom, sdk.OneInt())), + expectError: accum.NegativeAccDifferenceError{sdk.NewDecCoins(sdk.NewDecCoin(initialCoinDenomOne.Denom, sdk.OneInt()))}, + }, + "old accumulator coins are a superset of new - error": { + customAccumulatorValue: initialCoinsDenomOne, + oldPositionAccumulatorValue: initialCoinsDenomOne.Add(initialCoinDenomTwo), + expectError: accum.NegativeAccDifferenceError{sdk.NewDecCoins(initialCoinDenomTwo)}, + }, + "new accumulator coins are a superset of old - success": { + customAccumulatorValue: initialCoinsDenomOne.Add(initialCoinDenomTwo), + oldPositionAccumulatorValue: initialCoinsDenomOne, + }, + } + + for name, tc := range tests { + suite.Run(name, func() { + suite.SetupTest() + + err := accum.ValidateAccumulatorValue(tc.customAccumulatorValue, tc.oldPositionAccumulatorValue) + + if tc.expectError != nil { + suite.Require().Error(err) + suite.Require().Equal(tc.expectError, err) + return + } + suite.Require().NoError(err) + }) + } +} diff --git a/osmoutils/accum/accum_test.go b/osmoutils/accum/accum_test.go new file mode 100644 index 000000000..d771221be --- /dev/null +++ b/osmoutils/accum/accum_test.go @@ -0,0 +1,1568 @@ +package accum_test + +import ( + "math/rand" + "testing" + + "github.com/cosmos/cosmos-sdk/store" + iavlstore "github.com/cosmos/cosmos-sdk/store/iavl" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/iavl" + "github.com/gogo/protobuf/proto" + "github.com/stretchr/testify/suite" + dbm "github.com/tendermint/tm-db" + + "github.com/CosmosContracts/juno/v15/osmoutils" + accumPackage "github.com/CosmosContracts/juno/v15/osmoutils/accum" + "github.com/CosmosContracts/juno/v15/osmoutils/osmoassert" +) + +type AccumTestSuite struct { + suite.Suite + + store store.KVStore +} + +var ( + testAddressOne = sdk.AccAddress([]byte("addr1_______________")).String() + testAddressTwo = sdk.AccAddress([]byte("addr2_______________")).String() + testAddressThree = sdk.AccAddress([]byte("addr3_______________")).String() + + emptyPositionOptions = accumPackage.Options{} + testNameOne = "myaccumone" + testNameTwo = "myaccumtwo" + testNameThree = "myaccumthree" + denomOne = "denomone" + denomTwo = "denomtwo" + denomThree = "denomthree" + + emptyCoins = sdk.DecCoins(nil) + emptyDec = sdk.NewDec(0) + + initialValueOne = sdk.MustNewDecFromStr("100.1") + initialCoinDenomOne = sdk.NewDecCoinFromDec(denomOne, initialValueOne) + initialCoinDenomTwo = sdk.NewDecCoinFromDec(denomTwo, initialValueOne) + initialCoinDenomThree = sdk.NewDecCoinFromDec(denomThree, initialValueOne) + initialCoinsDenomOne = sdk.NewDecCoins(initialCoinDenomOne) + + positionOne = accumPackage.Record{ + NumShares: sdk.NewDec(100), + InitAccumValue: emptyCoins, + UnclaimedRewards: emptyCoins, + } + + positionOneV2 = accumPackage.Record{ + NumShares: sdk.NewDec(150), + InitAccumValue: emptyCoins, + UnclaimedRewards: emptyCoins, + } + + positionTwo = accumPackage.Record{ + NumShares: sdk.NewDec(200), + InitAccumValue: emptyCoins, + UnclaimedRewards: emptyCoins, + } + + positionThree = accumPackage.Record{ + NumShares: sdk.NewDec(300), + InitAccumValue: emptyCoins, + UnclaimedRewards: emptyCoins, + } +) + +func withInitialAccumValue(record accumPackage.Record, initialAccum sdk.DecCoins) accumPackage.Record { + record.InitAccumValue = initialAccum + return record +} + +func withUnclaimedRewards(record accumPackage.Record, unclaimedRewards sdk.DecCoins) accumPackage.Record { + record.UnclaimedRewards = unclaimedRewards + return record +} + +// Sets/resets KVStore to use for tests under `suite.store` +func (suite *AccumTestSuite) SetupTest() { + db := dbm.NewMemDB() + tree, err := iavl.NewMutableTree(db, 100, false) + suite.Require().NoError(err) + _, _, err = tree.SaveVersion() + suite.Require().Nil(err) + kvstore := iavlstore.UnsafeNewStore(tree) + suite.store = kvstore +} + +func TestAccumTestSuite(t *testing.T) { + suite.Run(t, new(AccumTestSuite)) +} + +func (suite *AccumTestSuite) TestMakeAndGetAccum() { + // We set up store once at beginning so we can test duplicates + suite.SetupTest() + + type testcase struct { + testName string + accumName string + expAccum accumPackage.AccumulatorObject + expSetPass bool + expGetPass bool + } + + tests := []testcase{ + { + testName: "create valid accumulator", + accumName: "fee-accumulator", + expSetPass: true, + expGetPass: true, + }, + { + testName: "create duplicate accumulator", + accumName: "fee-accumulator", + expSetPass: false, + expGetPass: true, + }, + } + + for _, tc := range tests { + tc := tc + suite.Run(tc.testName, func() { + // Creates raw accumulator object with test case's accum name and zero initial value + expAccum := accumPackage.MakeTestAccumulator(suite.store, tc.accumName, emptyCoins, emptyDec) + + err := accumPackage.MakeAccumulator(suite.store, tc.accumName) + + if !tc.expSetPass { + suite.Require().Error(err) + } + + retrievedAccum, err := accumPackage.GetAccumulator(suite.store, tc.accumName) + + if tc.expGetPass { + suite.Require().NoError(err) + suite.Require().Equal(expAccum, retrievedAccum) + } else { + suite.Require().Error(err) + } + }) + } +} + +func (suite *AccumTestSuite) TestMakeAccumulatorWithValueAndShares() { + // We set up store once at beginning so we can test duplicates + suite.SetupTest() + + type testcase struct { + testName string + accumName string + accumValue sdk.DecCoins + totalShares sdk.Dec + expAccum accumPackage.AccumulatorObject + expSetPass bool + expGetPass bool + } + + tests := []testcase{ + { + testName: "create valid accumulator", + accumName: "fee-accumulator", + accumValue: sdk.NewDecCoins(sdk.NewDecCoin("foo", sdk.NewInt(10)), sdk.NewDecCoin("bar", sdk.NewInt(20))), + totalShares: sdk.NewDec(30), + expSetPass: true, + expGetPass: true, + }, + { + testName: "create duplicate accumulator", + accumName: "fee-accumulator", + accumValue: sdk.NewDecCoins(sdk.NewDecCoin("foo", sdk.NewInt(10)), sdk.NewDecCoin("bar", sdk.NewInt(20))), + totalShares: sdk.NewDec(30), + expSetPass: false, + expGetPass: true, + }, + } + + for _, tc := range tests { + tc := tc + suite.Run(tc.testName, func() { + // Creates raw accumulator object with test case's accum name and zero initial value + expAccum := accumPackage.MakeTestAccumulator(suite.store, tc.accumName, emptyCoins, emptyDec) + + err := accumPackage.MakeAccumulatorWithValueAndShare(suite.store, tc.accumName, tc.accumValue, tc.totalShares) + + if !tc.expSetPass { + suite.Require().Error(err) + } + + retrievedAccum, err := accumPackage.GetAccumulator(suite.store, tc.accumName) + + if tc.expGetPass { + suite.Require().NoError(err) + suite.Require().Equal(expAccum, retrievedAccum) + } else { + suite.Require().Error(err) + } + }) + } +} + +func (suite *AccumTestSuite) TestNewPosition() { + // We setup store and accum + // once at beginning so we can test duplicate positions + suite.SetupTest() + + // Setup. + accObject := accumPackage.MakeTestAccumulator(suite.store, testNameOne, emptyCoins, emptyDec) + + tests := map[string]struct { + accObject accumPackage.AccumulatorObject + name string + numShareUnits sdk.Dec + options *accumPackage.Options + expectedPosition accumPackage.Record + }{ + "test address one - position created": { + accObject: accObject, + name: testAddressOne, + numShareUnits: positionOne.NumShares, + expectedPosition: positionOne, + }, + "test address two (non-nil options) - position created": { + accObject: accObject, + name: testAddressTwo, + numShareUnits: positionTwo.NumShares, + expectedPosition: positionTwo, + options: &emptyPositionOptions, + }, + "test address one - position overwritten": { + accObject: accObject, + name: testAddressOne, + numShareUnits: positionOneV2.NumShares, + expectedPosition: positionOneV2, + }, + "test address three - added": { + accObject: accObject, + name: testAddressThree, + numShareUnits: positionThree.NumShares, + expectedPosition: positionThree, + }, + "test address one with non-empty accumulator - position created": { + accObject: accumPackage.MakeTestAccumulator(suite.store, testNameTwo, initialCoinsDenomOne, emptyDec), + name: testAddressOne, + numShareUnits: positionOne.NumShares, + expectedPosition: withInitialAccumValue(positionOne, initialCoinsDenomOne), + }, + } + + for name, tc := range tests { + tc := tc + suite.Run(name, func() { + // System under test. + tc.accObject.NewPosition(tc.name, tc.numShareUnits, tc.options) + + // Assertions. + position := tc.accObject.MustGetPosition(tc.name) + + suite.Require().Equal(tc.expectedPosition.NumShares, position.NumShares) + suite.Require().Equal(tc.expectedPosition.InitAccumValue, position.InitAccumValue) + suite.Require().Equal(tc.expectedPosition.UnclaimedRewards, position.UnclaimedRewards) + + if tc.options == nil { + suite.Require().Nil(position.Options) + return + } + + suite.Require().Equal(*tc.options, *position.Options) + }) + } +} + +func (suite *AccumTestSuite) TestNewPositionCustomAcc() { + // We setup store and accum + // once at beginning so we can test duplicate positions + suite.SetupTest() + + // Setup. + accObject := accumPackage.MakeTestAccumulator(suite.store, testNameOne, initialCoinsDenomOne, emptyDec) + + tests := map[string]struct { + accObject accumPackage.AccumulatorObject + name string + numShareUnits sdk.Dec + customAcc sdk.DecCoins + options *accumPackage.Options + expectedPosition accumPackage.Record + expectedError error + }{ + "custom acc value equals to acc": { + accObject: accObject, + name: testAddressOne, + numShareUnits: positionOne.NumShares, + customAcc: accObject.GetValue(), + expectedPosition: accumPackage.Record{ + NumShares: positionOne.NumShares, + InitAccumValue: accObject.GetValue(), + UnclaimedRewards: emptyCoins, + }, + }, + "custom acc value does not equal to acc": { + accObject: accObject, + name: testAddressTwo, + numShareUnits: positionTwo.NumShares, + customAcc: accObject.GetValue().MulDec(sdk.NewDec(2)), + expectedPosition: accumPackage.Record{ + NumShares: positionTwo.NumShares, + InitAccumValue: accObject.GetValue().MulDec(sdk.NewDec(2)), + UnclaimedRewards: emptyCoins, + }, + options: &emptyPositionOptions, + }, + "negative acc value - error": { + accObject: accObject, + name: testAddressOne, + numShareUnits: positionOne.NumShares, + customAcc: accObject.GetValue().MulDec(sdk.NewDec(-1)), + expectedError: accumPackage.NegativeCustomAccError{accObject.GetValue().MulDec(sdk.NewDec(-1))}, + }, + } + + for name, tc := range tests { + tc := tc + suite.Run(name, func() { + // System under test. + err := tc.accObject.NewPositionCustomAcc(tc.name, tc.numShareUnits, tc.customAcc, tc.options) + + if tc.expectedError != nil { + suite.Require().Error(err) + suite.Require().Equal(tc.expectedError, err) + return + } + suite.Require().NoError(err) + + // Assertions. + position := tc.accObject.MustGetPosition(tc.name) + + suite.Require().Equal(tc.expectedPosition.NumShares, position.NumShares) + suite.Require().Equal(tc.expectedPosition.InitAccumValue, position.InitAccumValue) + suite.Require().Equal(tc.expectedPosition.UnclaimedRewards, position.UnclaimedRewards) + + if tc.options == nil { + suite.Require().Nil(position.Options) + return + } + + suite.Require().Equal(*tc.options, *position.Options) + }) + } +} + +func (suite *AccumTestSuite) TestClaimRewards() { + var ( + doubleCoinsDenomOne = sdk.NewDecCoinFromDec(denomOne, initialValueOne.MulInt64(2)) + + tripleDenomOneAndTwo = sdk.NewDecCoins( + sdk.NewDecCoinFromDec(denomOne, initialValueOne), + sdk.NewDecCoinFromDec(denomTwo, sdk.NewDec(3))) + ) + + // single output convenience wrapper. + toCoins := func(decCoins sdk.DecCoins) sdk.Coins { + coins, _ := decCoins.TruncateDecimal() + return coins + } + + // We setup store and accum + // once at beginning so we can test duplicate positions + suite.SetupTest() + + // Setup. + + // 1. No rewards, 2 position accumulator. + accumNoRewards := accumPackage.MakeTestAccumulator(suite.store, testNameOne, emptyCoins, emptyDec) + + // Create positions at testAddressOne and testAddressTwo. + accumNoRewards.NewPosition(testAddressOne, positionOne.NumShares, nil) + accumNoRewards.NewPosition(testAddressTwo, positionTwo.NumShares, nil) + + // 2. One accumulator reward coin, 1 position accumulator, no unclaimed rewards in position. + accumOneReward := accumPackage.MakeTestAccumulator(suite.store, testNameTwo, initialCoinsDenomOne, emptyDec) + + // Create position at testAddressThree. + accumOneReward = accumPackage.WithPosition(accumOneReward, testAddressThree, withInitialAccumValue(positionThree, initialCoinsDenomOne)) + + // Double the accumulator value. + accumOneReward.SetValue(sdk.NewDecCoins(doubleCoinsDenomOne)) + + // 3. Multi accumulator rewards, 2 position accumulator, some unclaimed rewards. + accumThreeRewards := accumPackage.MakeTestAccumulator(suite.store, testNameThree, sdk.NewDecCoins(), emptyDec) + + // Create positions at testAddressOne + // This position has unclaimed rewards set. + accumThreeRewards = accumPackage.WithPosition(accumThreeRewards, testAddressOne, withUnclaimedRewards(positionOne, initialCoinsDenomOne)) + + // Create positions at testAddressThree with no unclaimed rewards. + accumThreeRewards.NewPosition(testAddressTwo, positionTwo.NumShares, nil) + + // Triple the accumulator value. + accumThreeRewards.SetValue(tripleDenomOneAndTwo) + + tests := []struct { + testName string + accObject accumPackage.AccumulatorObject + accName string + expectedResult sdk.Coins + updateNumSharesToZero bool + expectError error + }{ + { + testName: "claim at testAddressOne with no rewards - success", + accObject: accumNoRewards, + accName: testAddressOne, + expectedResult: toCoins(emptyCoins), + }, + { + testName: "delete accum - claim at testAddressOne with no rewards - success", + accObject: accumNoRewards, + accName: testAddressOne, + updateNumSharesToZero: true, + expectedResult: toCoins(emptyCoins), + }, + { + testName: "claim at testAddressTwo with no rewards - success", + accObject: accumNoRewards, + accName: testAddressTwo, + expectedResult: toCoins(emptyCoins), + }, + { + testName: "claim at testAddressTwo with no rewards - error - no position", + accObject: accumNoRewards, + accName: testAddressThree, + expectError: accumPackage.NoPositionError{Name: testAddressThree}, + }, + { + testName: "claim at testAddressThree with single reward token - success", + accObject: accumOneReward, + accName: testAddressThree, + // denomOne: (200.2 - 100.1) * 300 (accum diff * share count) = 30030 + expectedResult: toCoins(initialCoinsDenomOne.MulDec(positionThree.NumShares)), + }, + { + testName: "claim at testAddressOne with multiple reward tokens and unclaimed rewards - success", + accObject: accumThreeRewards, + accName: testAddressOne, + // denomOne: (300.3 - 0) * 100 (accum diff * share count) + 100.1 (unclaimed rewards) = 30130.1 + // denomTwo: (3 - 0) * 100 (accum diff * share count) = 300 + expectedResult: toCoins(tripleDenomOneAndTwo.MulDec(positionOne.NumShares).Add(initialCoinDenomOne)), + }, + { + testName: "delete accum - claim at testAddressOne with multiple reward tokens and unclaimed rewards - success", + accObject: accumThreeRewards, + accName: testAddressOne, + updateNumSharesToZero: true, + // all claimed during the previous test + expectedResult: toCoins(emptyCoins), + }, + { + testName: "claim at testAddressTwo with multiple reward tokens and no unclaimed rewards - success", + accObject: accumThreeRewards, + accName: testAddressTwo, + // denomOne: (100.1 - 0) * 200 (accum diff * share count) = 200020 + // denomTwo: (3 - 0) * 200 (accum diff * share count) = 600 + expectedResult: toCoins(tripleDenomOneAndTwo.MulDec(positionTwo.NumShares)), + }, + } + + for _, tc := range tests { + tc := tc + suite.Run(tc.testName, func() { + if tc.updateNumSharesToZero { + positionSize, err := tc.accObject.GetPositionSize(tc.accName) + suite.Require().NoError(err) + err = tc.accObject.UpdatePosition(tc.accName, positionSize.Neg()) + suite.Require().NoError(err) + } + // System under test. + actualResult, _, err := tc.accObject.ClaimRewards(tc.accName) + + // Assertions. + + if tc.expectError != nil { + suite.Require().Error(err) + suite.Require().Equal(tc.expectError, err) + return + } + + suite.Require().NoError(err) + suite.Require().Equal(tc.expectedResult.String(), actualResult.String()) + + osmoassert.ConditionalPanic(suite.T(), tc.updateNumSharesToZero, func() { + finalPosition := tc.accObject.MustGetPosition(tc.accName) + suite.Require().NoError(err) + + // Unclaimed rewards are reset. + suite.Require().Equal(emptyCoins, finalPosition.UnclaimedRewards) + }) + }) + } +} + +func (suite *AccumTestSuite) TestAddToPosition() { + type testcase struct { + startingNumShares sdk.Dec + startingUnclaimedRewards sdk.DecCoins + newShares sdk.Dec + + // accumInit and expAccumDelta specify the initial accum value + // and how much it has changed since the position being added + // to was created + accumInit sdk.DecCoins + expAccumDelta sdk.DecCoins + + addrDoesNotExist bool + expPass bool + } + + tests := map[string]testcase{ + "zero shares with no new rewards": { + startingNumShares: sdk.ZeroDec(), + startingUnclaimedRewards: sdk.NewDecCoins(), + newShares: sdk.OneDec(), + accumInit: sdk.NewDecCoins(), + // unchanged accum value, so no unclaimed rewards + expAccumDelta: sdk.NewDecCoins(), + expPass: true, + }, + "non-zero shares with no new rewards": { + startingNumShares: initialValueOne, + startingUnclaimedRewards: sdk.NewDecCoins(), + newShares: sdk.NewDec(10), + accumInit: sdk.NewDecCoins(), + // unchanged accum value, so no unclaimed rewards + expAccumDelta: sdk.NewDecCoins(), + expPass: true, + }, + "non-zero shares with new rewards in one denom": { + startingNumShares: initialValueOne, + startingUnclaimedRewards: sdk.NewDecCoins(), + newShares: sdk.OneDec(), + accumInit: sdk.NewDecCoins(), + // unclaimed rewards since last update + expAccumDelta: sdk.NewDecCoins(initialCoinDenomOne), + expPass: true, + }, + "non-zero shares with new rewards in two denoms": { + startingNumShares: initialValueOne, + startingUnclaimedRewards: sdk.NewDecCoins(), + newShares: sdk.OneDec(), + accumInit: sdk.NewDecCoins(), + expAccumDelta: sdk.NewDecCoins(initialCoinDenomOne, initialCoinDenomTwo), + expPass: true, + }, + "non-zero shares with both existing and new rewards": { + startingNumShares: initialValueOne, + startingUnclaimedRewards: sdk.NewDecCoins(sdk.NewDecCoin(denomOne, sdk.NewInt(11)), sdk.NewDecCoin(denomTwo, sdk.NewInt(11))), + newShares: sdk.OneDec(), + accumInit: sdk.NewDecCoins(), + expAccumDelta: sdk.NewDecCoins(initialCoinDenomOne, initialCoinDenomTwo), + expPass: true, + }, + "non-zero shares with both existing (one denom) and new rewards (two denoms)": { + startingNumShares: initialValueOne, + startingUnclaimedRewards: sdk.NewDecCoins(initialCoinDenomOne), + newShares: sdk.OneDec(), + accumInit: sdk.NewDecCoins(), + expAccumDelta: sdk.NewDecCoins(initialCoinDenomOne, initialCoinDenomTwo), + expPass: true, + }, + "non-zero shares with both existing (one denom) and new rewards (two new denoms)": { + startingNumShares: initialValueOne, + startingUnclaimedRewards: sdk.NewDecCoins(initialCoinDenomOne), + newShares: sdk.OneDec(), + accumInit: sdk.NewDecCoins(), + expAccumDelta: sdk.NewDecCoins(initialCoinDenomTwo, initialCoinDenomThree), + expPass: true, + }, + "nonzero accumulator starting value, delta with same denoms": { + startingNumShares: initialValueOne, + startingUnclaimedRewards: sdk.NewDecCoins(initialCoinDenomOne), + newShares: sdk.OneDec(), + accumInit: sdk.NewDecCoins(initialCoinDenomOne, initialCoinDenomTwo), + expAccumDelta: sdk.NewDecCoins(initialCoinDenomOne, initialCoinDenomTwo), + expPass: true, + }, + "nonzero accumulator starting value, delta with new denoms": { + startingNumShares: initialValueOne, + startingUnclaimedRewards: sdk.NewDecCoins(initialCoinDenomOne), + newShares: sdk.OneDec(), + accumInit: sdk.NewDecCoins(initialCoinDenomOne, initialCoinDenomTwo), + expAccumDelta: sdk.NewDecCoins(initialCoinDenomTwo, initialCoinDenomThree), + expPass: true, + }, + "decimal shares with new rewards in two denoms": { + startingNumShares: initialValueOne, + startingUnclaimedRewards: sdk.NewDecCoins(), + newShares: sdk.NewDecWithPrec(983429874321, 5), + accumInit: sdk.NewDecCoins(), + expAccumDelta: sdk.NewDecCoins(initialCoinDenomOne, initialCoinDenomTwo), + expPass: true, + }, + + // error catching + "account does not exist": { + addrDoesNotExist: true, + expPass: false, + + startingNumShares: sdk.OneDec(), + startingUnclaimedRewards: emptyCoins, + newShares: sdk.OneDec(), + accumInit: emptyCoins, + expAccumDelta: sdk.NewDecCoins(), + }, + "attempt to add zero shares": { + startingNumShares: initialValueOne, + startingUnclaimedRewards: emptyCoins, + newShares: sdk.ZeroDec(), + accumInit: emptyCoins, + expAccumDelta: sdk.NewDecCoins(), + expPass: false, + }, + "attempt to add negative shares": { + startingNumShares: initialValueOne, + startingUnclaimedRewards: emptyCoins, + newShares: sdk.OneDec().Neg(), + accumInit: emptyCoins, + expAccumDelta: sdk.NewDecCoins(), + expPass: false, + }, + } + + for name, tc := range tests { + suite.Run(name, func() { + // We reset the store for each test + suite.SetupTest() + positionName := osmoutils.CreateRandomAccounts(1)[0].String() + + // Create a new accumulator with initial value specified by test case + curAccum := accumPackage.MakeTestAccumulator(suite.store, testNameOne, tc.accumInit, emptyDec) + + // Create new position in store (raw to minimize dependencies) + if !tc.addrDoesNotExist { + accumPackage.CreateRawPosition(curAccum, positionName, tc.startingNumShares, tc.startingUnclaimedRewards, nil) + } + + // Update accumulator with expAccumDelta (increasing position's rewards by a proportional amount) + curAccum = accumPackage.MakeTestAccumulator(suite.store, testNameOne, tc.accumInit.Add(tc.expAccumDelta...), emptyDec) + + // Add newShares to position + err := curAccum.AddToPosition(positionName, tc.newShares) + + if tc.expPass { + suite.Require().NoError(err) + + // Get updated position for comparison + newPosition, err := accumPackage.GetPosition(curAccum, positionName) + suite.Require().NoError(err) + + // Ensure position's accumulator value is moved up to init + delta + suite.Require().Equal(tc.accumInit.Add(tc.expAccumDelta...), newPosition.InitAccumValue) + + // Ensure accrued rewards are moved into UnclaimedRewards (both when it starts empty and not) + suite.Require().Equal(tc.startingUnclaimedRewards.Add(tc.expAccumDelta.MulDec(tc.startingNumShares)...), newPosition.UnclaimedRewards) + + // Ensure address's position properly reflects new number of shares + suite.Require().Equal(tc.startingNumShares.Add(tc.newShares), newPosition.NumShares) + + // Ensure a new position isn't created or removed from memory + allAccumPositions, err := curAccum.GetAllPositions() + suite.Require().NoError(err) + suite.Require().True(len(allAccumPositions) == 1) + } else { + suite.Require().Error(err) + + // Further checks to ensure state was not mutated upon error + if !tc.addrDoesNotExist { + // Get new position for comparison + newPosition, err := accumPackage.GetPosition(curAccum, positionName) + suite.Require().NoError(err) + + // Ensure that numShares, accumulator value, and unclaimed rewards are unchanged + suite.Require().Equal(tc.startingNumShares, newPosition.NumShares) + suite.Require().Equal(tc.accumInit, newPosition.InitAccumValue) + suite.Require().Equal(tc.startingUnclaimedRewards, newPosition.UnclaimedRewards) + } + } + }) + } +} + +// TestAddToPositionCustomAcc this test only focuses on testing the +// custom accumulator value functionality of adding to position. +func (suite *AccumTestSuite) TestAddToPositionCustomAcc() { + // We setup store and accum + // once at beginning so we can test duplicate positions + suite.SetupTest() + + // Setup. + accObject := accumPackage.MakeTestAccumulator(suite.store, testNameOne, initialCoinsDenomOne, emptyDec) + + tests := map[string]struct { + accObject accumPackage.AccumulatorObject + name string + numShareUnits sdk.Dec + customAcc sdk.DecCoins + expectedPosition accumPackage.Record + expectedError error + }{ + "custom acc value equals to acc": { + accObject: accObject, + name: testAddressOne, + numShareUnits: positionOne.NumShares, + customAcc: accObject.GetValue(), + expectedPosition: accumPackage.Record{ + NumShares: positionOne.NumShares, + InitAccumValue: accObject.GetValue(), + UnclaimedRewards: emptyCoins, + }, + }, + "custom acc value does not equal to acc": { + accObject: accObject, + name: testAddressTwo, + numShareUnits: positionTwo.NumShares, + customAcc: accObject.GetValue().MulDec(sdk.NewDec(2)), + expectedPosition: accumPackage.Record{ + NumShares: positionTwo.NumShares, + InitAccumValue: accObject.GetValue().MulDec(sdk.NewDec(2)), + UnclaimedRewards: emptyCoins, + }, + }, + } + + for name, tc := range tests { + tc := tc + suite.Run(name, func() { + // Setup + err := tc.accObject.NewPositionCustomAcc(tc.name, sdk.ZeroDec(), tc.accObject.GetValue(), nil) + suite.Require().NoError(err) + + // System under test. + err = tc.accObject.AddToPositionCustomAcc(tc.name, tc.numShareUnits, tc.customAcc) + + if tc.expectedError != nil { + suite.Require().Error(err) + suite.Require().Equal(tc.expectedError, err) + return + } + suite.Require().NoError(err) + + // Assertions. + position := tc.accObject.MustGetPosition(tc.name) + + suite.Require().Equal(tc.expectedPosition.NumShares, position.NumShares) + suite.Require().Equal(tc.expectedPosition.InitAccumValue, position.InitAccumValue) + suite.Require().Equal(tc.expectedPosition.UnclaimedRewards, position.UnclaimedRewards) + suite.Require().Nil(position.Options) + }) + } +} + +func (suite *AccumTestSuite) TestRemoveFromPosition() { + type testcase struct { + startingNumShares sdk.Dec + startingUnclaimedRewards sdk.DecCoins + removedShares sdk.Dec + + // accumInit and expAccumDelta specify the initial accum value + // and how much it has changed since the position being added + // to was created + accumInit sdk.DecCoins + expAccumDelta sdk.DecCoins + + addrDoesNotExist bool + expPass bool + } + + tests := map[string]testcase{ + "no new rewards": { + startingNumShares: initialValueOne, + startingUnclaimedRewards: sdk.NewDecCoins(), + removedShares: sdk.OneDec(), + accumInit: sdk.NewDecCoins(), + // unchanged accum value, so no unclaimed rewards + expAccumDelta: sdk.NewDecCoins(), + expPass: true, + }, + "new rewards in one denom": { + startingNumShares: initialValueOne, + startingUnclaimedRewards: sdk.NewDecCoins(), + removedShares: sdk.OneDec(), + accumInit: sdk.NewDecCoins(), + // unclaimed rewards since last update + expAccumDelta: sdk.NewDecCoins(initialCoinDenomOne), + expPass: true, + }, + "new rewards in two denoms": { + startingNumShares: initialValueOne, + startingUnclaimedRewards: sdk.NewDecCoins(), + removedShares: sdk.OneDec(), + accumInit: sdk.NewDecCoins(), + expAccumDelta: sdk.NewDecCoins(initialCoinDenomOne, initialCoinDenomTwo), + expPass: true, + }, + "both existing and new rewards": { + startingNumShares: initialValueOne, + startingUnclaimedRewards: sdk.NewDecCoins(sdk.NewDecCoin(denomOne, sdk.NewInt(11)), sdk.NewDecCoin(denomTwo, sdk.NewInt(11))), + removedShares: sdk.OneDec(), + accumInit: sdk.NewDecCoins(), + expAccumDelta: sdk.NewDecCoins(initialCoinDenomOne, initialCoinDenomTwo), + expPass: true, + }, + "both existing (one denom) and new rewards (two denoms, one overlapping)": { + startingNumShares: initialValueOne, + startingUnclaimedRewards: sdk.NewDecCoins(initialCoinDenomOne), + removedShares: sdk.OneDec(), + accumInit: sdk.NewDecCoins(), + expAccumDelta: sdk.NewDecCoins(initialCoinDenomOne, initialCoinDenomTwo), + expPass: true, + }, + "both existing (one denom) and new rewards (two new denoms)": { + startingNumShares: initialValueOne, + startingUnclaimedRewards: sdk.NewDecCoins(initialCoinDenomOne), + removedShares: sdk.OneDec(), + accumInit: sdk.NewDecCoins(), + expAccumDelta: sdk.NewDecCoins(initialCoinDenomTwo, initialCoinDenomThree), + expPass: true, + }, + "nonzero accumulator starting value, delta with same denoms": { + startingNumShares: initialValueOne, + startingUnclaimedRewards: sdk.NewDecCoins(initialCoinDenomOne), + removedShares: sdk.OneDec(), + accumInit: sdk.NewDecCoins(initialCoinDenomOne, initialCoinDenomTwo), + expAccumDelta: sdk.NewDecCoins(initialCoinDenomOne, initialCoinDenomTwo), + expPass: true, + }, + "nonzero accumulator starting value, delta with new denoms": { + startingNumShares: initialValueOne, + startingUnclaimedRewards: sdk.NewDecCoins(initialCoinDenomOne), + removedShares: sdk.OneDec(), + accumInit: sdk.NewDecCoins(initialCoinDenomOne, initialCoinDenomTwo), + expAccumDelta: sdk.NewDecCoins(initialCoinDenomTwo, initialCoinDenomThree), + expPass: true, + }, + "remove decimal shares with new rewards in two denoms": { + startingNumShares: sdk.NewDec(1000000), + startingUnclaimedRewards: sdk.NewDecCoins(), + removedShares: sdk.NewDecWithPrec(7489274134, 5), + accumInit: sdk.NewDecCoins(), + expAccumDelta: sdk.NewDecCoins(initialCoinDenomOne, initialCoinDenomTwo), + expPass: true, + }, + "attempt to remove exactly numShares": { + startingNumShares: sdk.OneDec(), + startingUnclaimedRewards: emptyCoins, + removedShares: sdk.OneDec(), + accumInit: emptyCoins, + expAccumDelta: sdk.NewDecCoins(), + expPass: true, + }, + + // error catching + "account does not exist": { + addrDoesNotExist: true, + expPass: false, + + startingNumShares: initialValueOne, + startingUnclaimedRewards: emptyCoins, + removedShares: sdk.OneDec(), + accumInit: emptyCoins, + expAccumDelta: sdk.NewDecCoins(), + }, + "attempt to remove zero shares": { + startingNumShares: initialValueOne, + startingUnclaimedRewards: emptyCoins, + removedShares: sdk.ZeroDec(), + accumInit: emptyCoins, + expAccumDelta: sdk.NewDecCoins(), + expPass: false, + }, + "attempt to remove negative shares": { + startingNumShares: sdk.OneDec(), + startingUnclaimedRewards: emptyCoins, + removedShares: sdk.OneDec().Neg(), + accumInit: emptyCoins, + expAccumDelta: sdk.NewDecCoins(), + expPass: false, + }, + } + + for name, tc := range tests { + suite.Run(name, func() { + // We reset the store for each test + suite.SetupTest() + positionName := osmoutils.CreateRandomAccounts(1)[0].String() + + // Create a new accumulator with initial value specified by test case + curAccum := accumPackage.MakeTestAccumulator(suite.store, testNameOne, tc.accumInit, emptyDec) + + // Create new position in store (raw to minimize dependencies) + if !tc.addrDoesNotExist { + accumPackage.CreateRawPosition(curAccum, positionName, tc.startingNumShares, tc.startingUnclaimedRewards, nil) + } + + // Update accumulator with expAccumDelta (increasing position's rewards by a proportional amount) + curAccum = accumPackage.MakeTestAccumulator(suite.store, testNameOne, tc.accumInit.Add(tc.expAccumDelta...), emptyDec) + + // Remove removedShares from position + err := curAccum.RemoveFromPosition(positionName, tc.removedShares) + + if tc.expPass { + suite.Require().NoError(err) + + // Get updated position for comparison + newPosition, err := accumPackage.GetPosition(curAccum, positionName) + suite.Require().NoError(err) + + // Ensure position's accumulator value is moved up to init + delta + suite.Require().Equal(tc.accumInit.Add(tc.expAccumDelta...), newPosition.InitAccumValue) + + // Ensure accrued rewards are moved into UnclaimedRewards (both when it starts empty and not) + suite.Require().Equal(tc.startingUnclaimedRewards.Add(tc.expAccumDelta.MulDec(tc.startingNumShares)...), newPosition.UnclaimedRewards) + + // Ensure address's position properly reflects new number of shares + if (tc.startingNumShares.Sub(tc.removedShares)).Equal(sdk.ZeroDec()) { + suite.Require().Equal(emptyDec, newPosition.NumShares) + } else { + suite.Require().Equal(tc.startingNumShares.Sub(tc.removedShares), newPosition.NumShares) + } + + // Ensure a new position isn't created in memory (only old one is overwritten) + allAccumPositions, err := curAccum.GetAllPositions() + suite.Require().NoError(err) + suite.Require().True(len(allAccumPositions) == 1) + } else { + suite.Require().Error(err) + + // Further checks to ensure state was not mutated upon error + if !tc.addrDoesNotExist { + // Get new position for comparison + newPosition, err := accumPackage.GetPosition(curAccum, positionName) + suite.Require().NoError(err) + + // Ensure that numShares, accumulator value, and unclaimed rewards are unchanged + suite.Require().Equal(tc.startingNumShares, newPosition.NumShares) + suite.Require().Equal(tc.accumInit, newPosition.InitAccumValue) + suite.Require().Equal(tc.startingUnclaimedRewards, newPosition.UnclaimedRewards) + } + } + }) + } +} + +// TestRemoveFromPositionCustomAcc this test only focuses on testing the +// custom accumulator value functionality of removing from a position. +func (suite *AccumTestSuite) TestRemoveFromPositionCustomAcc() { + // We setup store and accum + // once at beginning so we can test duplicate positions + suite.SetupTest() + + baseAccumValue := initialCoinsDenomOne + + // Setup. + accObject := accumPackage.MakeTestAccumulator(suite.store, testNameOne, baseAccumValue, emptyDec) + + tests := map[string]struct { + accObject accumPackage.AccumulatorObject + name string + numShareUnits sdk.Dec + customAcc sdk.DecCoins + expectedPosition accumPackage.Record + expectedError error + }{ + "custom acc value equals to acc": { + accObject: accObject, + name: testAddressOne, + numShareUnits: positionOne.NumShares, + customAcc: baseAccumValue, + expectedPosition: accumPackage.Record{ + NumShares: sdk.ZeroDec(), + InitAccumValue: baseAccumValue, + // base value - 0.5 * base = base value + UnclaimedRewards: baseAccumValue.MulDec(sdk.NewDecWithPrec(5, 1)).MulDec(positionOne.NumShares), + }, + }, + "custom acc value does not equal to acc": { + accObject: accObject, + name: testAddressTwo, + numShareUnits: positionTwo.NumShares, + customAcc: baseAccumValue.MulDec(sdk.NewDecWithPrec(75, 2)), + expectedPosition: accumPackage.Record{ + NumShares: sdk.ZeroDec(), + InitAccumValue: baseAccumValue.MulDec(sdk.NewDecWithPrec(75, 2)), + // base value - 0.75 * base = 0.25 * base + UnclaimedRewards: baseAccumValue.MulDec(sdk.NewDecWithPrec(25, 2)).MulDec(positionTwo.NumShares), + }, + }, + } + + for name, tc := range tests { + tc := tc + suite.Run(name, func() { + // Setup + + // Original position's accum is always set to 0.5 * base value. + err := tc.accObject.NewPositionCustomAcc(tc.name, tc.numShareUnits, initialCoinsDenomOne.MulDec(sdk.NewDecWithPrec(5, 1)), nil) + suite.Require().NoError(err) + + tc.accObject.SetValue(tc.customAcc) + + // System under test. + err = tc.accObject.RemoveFromPositionCustomAcc(tc.name, tc.numShareUnits, tc.customAcc) + + if tc.expectedError != nil { + suite.Require().Error(err) + suite.Require().Equal(tc.expectedError, err) + return + } + suite.Require().NoError(err) + + // Assertions. + position := tc.accObject.MustGetPosition(tc.name) + + suite.Require().Equal(tc.expectedPosition.NumShares, position.NumShares) + suite.Require().Equal(tc.expectedPosition.InitAccumValue, position.InitAccumValue) + suite.Require().Equal(tc.expectedPosition.UnclaimedRewards, position.UnclaimedRewards) + suite.Require().Nil(position.Options) + }) + } +} + +func (suite *AccumTestSuite) TestGetPositionSize() { + type testcase struct { + numShares sdk.Dec + changedShares sdk.Dec + + // accumInit and expAccumDelta specify the initial accum value + // and how much it has changed since the position being added + // to was created + accumInit sdk.DecCoins + expAccumDelta sdk.DecCoins + + addrDoesNotExist bool + expPass bool + } + + tests := map[string]testcase{ + "unchanged accumulator": { + numShares: sdk.OneDec(), + accumInit: sdk.NewDecCoins(), + expAccumDelta: sdk.NewDecCoins(), + changedShares: sdk.ZeroDec(), + expPass: true, + }, + "changed accumulator": { + numShares: sdk.OneDec(), + accumInit: sdk.NewDecCoins(), + expAccumDelta: sdk.NewDecCoins(initialCoinDenomOne, initialCoinDenomTwo), + changedShares: sdk.ZeroDec(), + expPass: true, + }, + "changed number of shares": { + numShares: sdk.OneDec(), + accumInit: sdk.NewDecCoins(), + expAccumDelta: sdk.NewDecCoins(), + changedShares: sdk.OneDec(), + expPass: true, + }, + "account does not exist": { + addrDoesNotExist: true, + expPass: false, + + numShares: sdk.OneDec(), + accumInit: sdk.NewDecCoins(), + expAccumDelta: sdk.NewDecCoins(), + changedShares: sdk.ZeroDec(), + }, + } + + for name, tc := range tests { + suite.Run(name, func() { + // We reset the store for each test + suite.SetupTest() + positionName := osmoutils.CreateRandomAccounts(1)[0].String() + + // Create a new accumulator with initial value specified by test case + curAccum := accumPackage.MakeTestAccumulator(suite.store, testNameOne, tc.accumInit, emptyDec) + + // Create new position in store (raw to minimize dependencies) + if !tc.addrDoesNotExist { + accumPackage.CreateRawPosition(curAccum, positionName, tc.numShares, sdk.NewDecCoins(), nil) + } + + // Update accumulator with expAccumDelta (increasing position's rewards by a proportional amount) + curAccum = accumPackage.MakeTestAccumulator(suite.store, testNameOne, tc.accumInit.Add(tc.expAccumDelta...), emptyDec) + + // Get position size from valid address (or from nonexistant if address does not exist) + positionSize, err := curAccum.GetPositionSize(positionName) + + if tc.changedShares.GT(sdk.ZeroDec()) { + accumPackage.CreateRawPosition(curAccum, positionName, tc.numShares.Add(tc.changedShares), sdk.NewDecCoins(), nil) + } + + positionSize, err = curAccum.GetPositionSize(positionName) + + if tc.expPass { + suite.Require().NoError(err) + suite.Require().Equal(tc.numShares.Add(tc.changedShares), positionSize) + + // Ensure nothing was added or removed from store + allAccumPositions, err := curAccum.GetAllPositions() + suite.Require().NoError(err) + suite.Require().True(len(allAccumPositions) == 1) + } else { + suite.Require().Error(err) + } + }) + } +} + +// TestMarhsalUnmarshalRecord displays that we may use Records without options +// For records with nil options, adding new fields to `Options`, should not +// require future migrations. +func (suite *AccumTestSuite) TestMarhsalUnmarshalRecord() { + suite.SetupTest() + + recordNoOptions := accumPackage.Record{ + NumShares: sdk.OneDec(), + InitAccumValue: sdk.NewDecCoins( + sdk.NewDecCoinFromDec(denomOne, sdk.OneDec()), + ), + UnclaimedRewards: sdk.NewDecCoins( + sdk.NewDecCoinFromDec(denomOne, sdk.OneDec()), + ), + } + + bz, err := proto.Marshal(&recordNoOptions) + suite.Require().NoError(err) + + var unmarshaledRecord accumPackage.Record + proto.Unmarshal(bz, &unmarshaledRecord) + // Options should be nil, not an empty struct + suite.Require().True(unmarshaledRecord.Options == nil) +} + +func (suite *AccumTestSuite) TestAddToAccumulator() { + tests := map[string]struct { + updateAmount sdk.DecCoins + + expectedValue sdk.DecCoins + }{ + "positive": { + updateAmount: initialCoinsDenomOne, + + expectedValue: initialCoinsDenomOne, + }, + "negative": { + updateAmount: initialCoinsDenomOne.MulDec(sdk.NewDec(-1)), + + expectedValue: initialCoinsDenomOne.MulDec(sdk.NewDec(-1)), + }, + "multiple coins": { + updateAmount: initialCoinsDenomOne.Add(initialCoinDenomTwo), + + expectedValue: initialCoinsDenomOne.Add(initialCoinDenomTwo), + }, + } + + for name, tc := range tests { + suite.Run(name, func() { + // Setup + suite.SetupTest() + + err := accumPackage.MakeAccumulator(suite.store, testNameOne) + suite.Require().NoError(err) + originalAccum, err := accumPackage.GetAccumulator(suite.store, testNameOne) + suite.Require().NoError(err) + + // System under test. + originalAccum.AddToAccumulator(tc.updateAmount) + + // Validations. + + // validate that the reciever is mutated. + suite.Require().Equal(tc.expectedValue, originalAccum.GetValue()) + + accumFromStore, err := accumPackage.GetAccumulator(suite.store, testNameOne) + suite.Require().NoError(err) + + // validate that store is updated. + suite.Require().Equal(tc.expectedValue, accumFromStore.GetValue()) + }) + } +} + +func (suite *AccumTestSuite) TestUpdatePosition() { + // Setup. + accObject := accumPackage.MakeTestAccumulator(suite.store, testNameOne, initialCoinsDenomOne, emptyDec) + + tests := map[string]struct { + name string + numShares sdk.Dec + expectedPosition accumPackage.Record + expectError error + }{ + "positive - acts as AddToPosition": { + name: testAddressOne, + numShares: sdk.OneDec(), + + expectedPosition: accumPackage.Record{ + NumShares: sdk.OneDec().MulInt64(2), + InitAccumValue: initialCoinsDenomOne, + UnclaimedRewards: emptyCoins, + }, + }, + "negative - acts as RemoveFromPosition": { + name: testAddressOne, + numShares: sdk.OneDec().Neg(), + + expectedPosition: accumPackage.Record{ + NumShares: sdk.ZeroDec(), + InitAccumValue: initialCoinsDenomOne, + UnclaimedRewards: emptyCoins, + }, + }, + "zero - error": { + name: testAddressOne, + numShares: sdk.ZeroDec(), + + expectError: accumPackage.ZeroSharesError, + }, + } + + for name, tc := range tests { + suite.Run(name, func() { + suite.SetupTest() + + err := accObject.NewPosition(tc.name, sdk.OneDec(), nil) + suite.Require().NoError(err) + + err = accObject.UpdatePosition(tc.name, tc.numShares) + + if tc.expectError != nil { + suite.Require().Error(err) + suite.Require().ErrorIs(err, tc.expectError) + return + } + suite.Require().NoError(err) + + updatedPosition := accObject.MustGetPosition(tc.name) + + // Assertions. + position := accObject.MustGetPosition(tc.name) + + suite.Require().Equal(tc.expectedPosition.NumShares, updatedPosition.NumShares) + suite.Require().Equal(tc.expectedPosition.InitAccumValue, updatedPosition.InitAccumValue) + suite.Require().Equal(tc.expectedPosition.UnclaimedRewards, updatedPosition.UnclaimedRewards) + suite.Require().Nil(position.Options) + }) + } +} + +// TestUpdatePositionCustomAcc this test only focuses on testing the +// custom accumulator value functionality of updating a position. +func (suite *AccumTestSuite) TestUpdatePositionCustomAcc() { + tests := []struct { + testName string + initialShares sdk.Dec + initialAccum sdk.DecCoins + accName string + numShareUnits sdk.Dec + customAcc sdk.DecCoins + expectedPosition accumPackage.Record + expectedError error + }{ + { + testName: "custom acc value equals to acc; positive shares -> acts as AddToPosition", + initialShares: sdk.ZeroDec(), + initialAccum: initialCoinsDenomOne, + accName: testAddressOne, + numShareUnits: positionOne.NumShares, + customAcc: initialCoinsDenomOne, + expectedPosition: accumPackage.Record{ + NumShares: positionOne.NumShares, + InitAccumValue: initialCoinsDenomOne, + UnclaimedRewards: emptyCoins, + }, + }, + { + testName: "custom acc value does not equal to acc; remove same amount -> acts as RemoveFromPosition", + initialShares: positionTwo.NumShares, + initialAccum: initialCoinsDenomOne, + accName: testAddressTwo, + numShareUnits: positionTwo.NumShares.Neg(), // note: negative shares + customAcc: initialCoinsDenomOne.MulDec(sdk.NewDec(2)), + expectedPosition: accumPackage.Record{ + NumShares: sdk.ZeroDec(), // results in 0 shares (200 - 200) + InitAccumValue: initialCoinsDenomOne.MulDec(sdk.NewDec(2)), + UnclaimedRewards: emptyCoins, + }, + }, + { + testName: "custom acc value does not equal to acc; remove diff amount -> acts as RemoveFromPosition", + initialShares: positionTwo.NumShares, + initialAccum: initialCoinsDenomOne, + accName: testAddressTwo, + numShareUnits: positionOne.NumShares.Neg(), // note: negative shares + customAcc: initialCoinsDenomOne.MulDec(sdk.NewDec(2)), + expectedPosition: accumPackage.Record{ + NumShares: positionOne.NumShares, // results in 100 shares (200 - 100) + InitAccumValue: initialCoinsDenomOne.MulDec(sdk.NewDec(2)), + UnclaimedRewards: emptyCoins, + }, + }, + } + + for _, tc := range tests { + tc := tc + suite.Run(tc.testName, func() { + suite.SetupTest() + + // make accumualtor based off of tc.accObject + err := accumPackage.MakeAccumulator(suite.store, testNameOne) + suite.Require().NoError(err) + + accumObject, err := accumPackage.GetAccumulator(suite.store, testNameOne) + suite.Require().NoError(err) + + // manually update accumulator value + accumObject.AddToAccumulator(initialCoinsDenomOne) + + // Setup + err = accumObject.NewPositionCustomAcc(tc.accName, tc.initialShares, tc.initialAccum, nil) + suite.Require().NoError(err) + + // System under test. + err = accumObject.UpdatePositionCustomAcc(tc.accName, tc.numShareUnits, tc.customAcc) + + if tc.expectedError != nil { + suite.Require().Error(err) + suite.Require().Equal(tc.expectedError, err) + return + } + suite.Require().NoError(err) + + accumObject, err = accumPackage.GetAccumulator(suite.store, testNameOne) + suite.Require().NoError(err) + + position := accumObject.MustGetPosition(tc.accName) + // Assertions. + + suite.Require().Equal(tc.expectedPosition.NumShares, position.NumShares) + suite.Require().Equal(tc.expectedPosition.InitAccumValue, position.InitAccumValue) + suite.Require().Equal(tc.expectedPosition.UnclaimedRewards, position.UnclaimedRewards) + suite.Require().Nil(position.Options) + }) + } +} + +func (suite *AccumTestSuite) TestHasPosition() { + // We setup store and accum + // once at beginning. + suite.SetupTest() + + const ( + defaultPositionName = "posname" + ) + + // Setup. + accObject := accumPackage.MakeTestAccumulator(suite.store, testNameOne, initialCoinsDenomOne, emptyDec) + + tests := []struct { + name string + preCreatePosition bool + }{ + { + name: "position does not exist -> false", + preCreatePosition: false, + }, + { + name: "position exists -> true", + preCreatePosition: true, + }, + } + + for _, tc := range tests { + tc := tc + suite.Run(tc.name, func() { + // Setup + if tc.preCreatePosition { + err := accObject.NewPosition(defaultPositionName, sdk.ZeroDec(), nil) + suite.Require().NoError(err) + } + + hasPosition, err := accObject.HasPosition(defaultPositionName) + suite.NoError(err) + + suite.Equal(tc.preCreatePosition, hasPosition) + }) + } +} + +func (suite *AccumTestSuite) TestSetPositionCustomAcc() { + // We setup store and accum + // once at beginning. + suite.SetupTest() + + // Setup. + var ( + accObject = accumPackage.MakeTestAccumulator(suite.store, testNameOne, initialCoinsDenomOne, emptyDec) + validPositionName = testAddressThree + invalidPositionName = testAddressTwo + ) + + tests := map[string]struct { + positionName string + customAccumulatorValue sdk.DecCoins + expectedError error + }{ + "valid update greater than initial value": { + positionName: validPositionName, + customAccumulatorValue: initialCoinsDenomOne.Add(initialCoinDenomOne), + }, + "valid update equal to the initial value": { + positionName: validPositionName, + customAccumulatorValue: initialCoinsDenomOne, + }, + "invalid position - different name": { + positionName: invalidPositionName, + expectedError: accumPackage.NoPositionError{Name: invalidPositionName}, + }, + } + + for name, tc := range tests { + suite.Run(name, func() { + // Setup + err := accObject.NewPositionCustomAcc(validPositionName, sdk.OneDec(), initialCoinsDenomOne, nil) + suite.Require().NoError(err) + + // System under test. + err = accObject.SetPositionCustomAcc(tc.positionName, tc.customAccumulatorValue) + + // Assertions. + if tc.expectedError != nil { + suite.Require().Error(err) + suite.Require().Equal(tc.expectedError, err) + return + } + suite.Require().NoError(err) + + position := accObject.MustGetPosition(tc.positionName) + suite.Require().Equal(tc.customAccumulatorValue, position.GetInitAccumValue()) + // unchanged + suite.Require().Equal(sdk.OneDec(), position.NumShares) + suite.Require().Equal(emptyCoins, position.GetUnclaimedRewards()) + }) + } +} + +// We run a series of partially random operations on two accumulators to ensure that total shares are properly tracked in state +func (suite *AccumTestSuite) TestGetTotalShares() { + suite.SetupTest() + + // Set seed to make tests deterministic + rand.Seed(1) + + // Set up two accumulators to ensure we can test all relevant behavior + err := accumPackage.MakeAccumulator(suite.store, testNameOne) + suite.Require().NoError(err) + err = accumPackage.MakeAccumulator(suite.store, testNameTwo) + suite.Require().NoError(err) + + // Fetch both accumulators for initial sanity tests + accumOne, err := accumPackage.GetAccumulator(suite.store, testNameOne) + suite.Require().NoError(err) + accumTwo, err := accumPackage.GetAccumulator(suite.store, testNameTwo) + suite.Require().NoError(err) + + // Ensure that both accums start at zero shares + accumOneShares, err := accumOne.GetTotalShares() + suite.Require().NoError(err) + accumTwoShares, err := accumTwo.GetTotalShares() + suite.Require().NoError(err) + suite.Require().Equal(sdk.ZeroDec(), accumOneShares) + suite.Require().Equal(sdk.ZeroDec(), accumTwoShares) + + // Create position on first accum and pull new accum objects from state + err = accumOne.NewPosition(testAddressOne, sdk.OneDec(), nil) + suite.Require().NoError(err) + accumOne, err = accumPackage.GetAccumulator(suite.store, testNameOne) + suite.Require().NoError(err) + accumTwo, err = accumPackage.GetAccumulator(suite.store, testNameTwo) + suite.Require().NoError(err) + + // Check that total shares for accum one has updated properly and accum two shares are unchanged + accumOneShares, err = accumOne.GetTotalShares() + suite.Require().NoError(err) + accumTwoShares, err = accumTwo.GetTotalShares() + suite.Require().NoError(err) + suite.Require().Equal(sdk.OneDec(), accumOneShares) + suite.Require().Equal(sdk.ZeroDec(), accumTwoShares) + + // Run a number of NewPosition, AddToPosition, and RemoveFromPosition operations on each accum + testAddresses := []string{testAddressOne, testAddressTwo, testAddressThree} + accums := []accumPackage.AccumulatorObject{accumOne, accumTwo} + expectedShares := []sdk.Dec{sdk.OneDec(), sdk.ZeroDec()} + + for i := 1; i <= 10; i++ { + // Cycle through accounts and accumulators + curAddr := testAddresses[i%3] + curAccum := accums[i%2] + + // We set a baseAmt that varies with the iteration to increase coverage + baseAmt := sdk.NewDec(int64(i)).Mul(sdk.NewDec(10)) + + // If addr doesn't have a position yet, we make one + positionExists, err := curAccum.HasPosition(curAddr) + suite.Require().NoError(err) + if !positionExists { + err = curAccum.NewPosition(curAddr, baseAmt, nil) + suite.Require().NoError(err) + } + + // We generate a random binary value (0 or 1) to determine + // whether we will add and/or remove liquidity this loop + addShares := sdk.NewDec(int64(rand.Int()) % 2) + removeShares := sdk.NewDec(int64(rand.Int()) % 2) + + // Half the time, we add to the new position + addAmt := baseAmt.Mul(addShares) + if addAmt.GT(sdk.ZeroDec()) { + err = curAccum.AddToPosition(curAddr, addAmt) + suite.Require().NoError(err) + } + + // Half the time, we remove one share from the position + amtToRemove := sdk.OneDec().Mul(removeShares) + if amtToRemove.GT(sdk.ZeroDec()) { + err = curAccum.RemoveFromPosition(curAddr, amtToRemove) + suite.Require().NoError(err) + } + + // Finally, we update our expected number of shares for the accumulator + // we targeted in this loop + if !positionExists { + // If a new position was created, we factor its new shares in + expectedShares[i%2] = expectedShares[i%2].Add(baseAmt) + } + expectedShares[i%2] = expectedShares[i%2].Add(addAmt).Sub(amtToRemove) + } + + // Get updated accums from state to validate results + accumOne, err = accumPackage.GetAccumulator(suite.store, testNameOne) + suite.Require().NoError(err) + accumTwo, err = accumPackage.GetAccumulator(suite.store, testNameTwo) + suite.Require().NoError(err) + + // Ensure that total shares in each accum matches our expected number of shares + accumOneShares, err = accumOne.GetTotalShares() + suite.Require().NoError(err) + accumTwoShares, err = accumTwo.GetTotalShares() + suite.Require().NoError(err) + suite.Require().Equal(expectedShares[0], accumOneShares) + suite.Require().Equal(expectedShares[1], accumTwoShares) +} diff --git a/osmoutils/accum/errors.go b/osmoutils/accum/errors.go new file mode 100644 index 000000000..397cdb407 --- /dev/null +++ b/osmoutils/accum/errors.go @@ -0,0 +1,44 @@ +package accum + +import ( + "errors" + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +var ( + ZeroSharesError = errors.New("shares must be non-zero") +) + +type NoPositionError struct { + Name string +} + +func (e NoPositionError) Error() string { + return fmt.Sprintf("no position found for position key (%s)", e.Name) +} + +type NegativeCustomAccError struct { + CustomAccumulatorValue sdk.DecCoins +} + +func (e NegativeCustomAccError) Error() string { + return fmt.Sprintf("customAccumulatorValue must be non-negative, was (%s)", e.CustomAccumulatorValue) +} + +type NegativeAccDifferenceError struct { + AccumulatorDifference sdk.DecCoins +} + +func (e NegativeAccDifferenceError) Error() string { + return fmt.Sprintf("difference (%s) between the old and the new accumulator value is negative", e.AccumulatorDifference) +} + +type AccumDoesNotExistError struct { + AccumName string +} + +func (e AccumDoesNotExistError) Error() string { + return fmt.Sprintf("Accumulator name %s does not exist in store", e.AccumName) +} diff --git a/osmoutils/accum/export_test.go b/osmoutils/accum/export_test.go new file mode 100644 index 000000000..0a44d52d5 --- /dev/null +++ b/osmoutils/accum/export_test.go @@ -0,0 +1,77 @@ +package accum + +import ( + "errors" + + "github.com/gogo/protobuf/proto" + + "github.com/cosmos/cosmos-sdk/store" + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/CosmosContracts/juno/v15/osmoutils" +) + +// GetAllPositions returns all positions associated with the receiver accumulator. +// Returns error if any database errors occur. +// This function is currently used for testing purposes only. +// If there is a need to use this function in production, it +// can be moved to a non-test file. +func (accum AccumulatorObject) GetAllPositions() ([]Record, error) { + return osmoutils.GatherValuesFromStorePrefix(accum.store, FormatPositionPrefixKey(accum.name, ""), parseRecordFromBz) +} + +// Creates an accumulator object for testing purposes +func MakeTestAccumulator(store store.KVStore, name string, value sdk.DecCoins, totalShares sdk.Dec) AccumulatorObject { + // We store an accumulator object in state even if unused in tests + // because position operations still require GetAccumulator to work + _ = MakeAccumulator(store, name) + return AccumulatorObject{ + store: store, + name: name, + value: value, + totalShares: totalShares, + } +} + +func CreateRawPosition(accum AccumulatorObject, name string, numShareUnits sdk.Dec, unclaimedRewards sdk.DecCoins, options *Options) { + initOrUpdatePosition(accum, accum.value, name, numShareUnits, unclaimedRewards, options) +} + +// Gets store from accumulator for testing purposes +func GetStore(accum AccumulatorObject) store.KVStore { + return accum.store +} + +// parseRecordFromBz parses a record from a byte slice. +// Returns error if fails to unmarshal or if the given bytes slice +// is empty. +func parseRecordFromBz(bz []byte) (record Record, err error) { + if len(bz) == 0 { + return Record{}, errors.New("record not found") + } + err = proto.Unmarshal(bz, &record) + if err != nil { + return Record{}, err + } + return record, nil +} + +func ValidateAccumulatorValue(customAccumulatorValue, oldPositionAccumulatorValue sdk.DecCoins) error { + return validateAccumulatorValue(customAccumulatorValue, oldPositionAccumulatorValue) +} + +// WithPosition is a decorator test function to append a position with the given name to the given accumulator. +func WithPosition(accum AccumulatorObject, name string, position Record) AccumulatorObject { + osmoutils.MustSet(accum.store, FormatPositionPrefixKey(accum.name, name), &position) + return accum +} + +// SetValue is a convinience test helper for updatung the value of an accumulator object +// in tests. +func (accum *AccumulatorObject) SetValue(value sdk.DecCoins) { + accum.value = value +} + +func (o *Options) Validate() error { + return o.validate() +} diff --git a/osmoutils/accum/module.go b/osmoutils/accum/module.go new file mode 100644 index 000000000..297d7feb3 --- /dev/null +++ b/osmoutils/accum/module.go @@ -0,0 +1,3 @@ +// package accumulator allows one to define an accumulator to accommodate constant-rate +// (linear) distribution mechanisms with constant runtime and linear memory +package accum diff --git a/osmoutils/accum/options.go b/osmoutils/accum/options.go new file mode 100644 index 000000000..51add520d --- /dev/null +++ b/osmoutils/accum/options.go @@ -0,0 +1,20 @@ +package accum + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" +) + +var one = sdk.OneDec() + +// validate returns nil if Options are valid. +// Error otherwise. Note, that, currently, +// options do not contain any fields. We +// create them to be able to extend in the +// future with auto-compounding logic. +// As a result, this always returns nil. +func (o *Options) validate() error { + if o == nil { + return nil + } + return nil +} diff --git a/osmoutils/accum/options_test.go b/osmoutils/accum/options_test.go new file mode 100644 index 000000000..7c85e4e6f --- /dev/null +++ b/osmoutils/accum/options_test.go @@ -0,0 +1,32 @@ +package accum_test + +import "github.com/CosmosContracts/juno/v15/osmoutils/accum" + +// TestOptionsValidate tests that the options are validated correctly. +func (suite *AccumTestSuite) TestOptionsValidate() { + tests := map[string]struct { + options *accum.Options + expectError error + }{ + "nil options - success": { + options: nil, + }, + "non-nil options - success": { + options: &accum.Options{}, + }, + } + + for name, tc := range tests { + suite.Run(name, func() { + suite.SetupTest() + + err := tc.options.Validate() + + if tc.expectError != nil { + suite.Require().Error(err) + return + } + suite.Require().NoError(err) + }) + } +} diff --git a/osmoutils/accum/prefix.go b/osmoutils/accum/prefix.go new file mode 100644 index 000000000..4dea6af88 --- /dev/null +++ b/osmoutils/accum/prefix.go @@ -0,0 +1,30 @@ +package accum + +import "fmt" + +const ( + modulePrefix = "accum" + accumulatorPrefix = "acc" + positionPrefix = "pos" +) + +// formatAccumPrefix returns the key prefix used for any +// accum module values to be stored in the KVStore. +// Returns "accum/{key}" as bytes. +func formatModulePrefixKey(key string) []byte { + return []byte(fmt.Sprintf("%s/%s", modulePrefix, key)) +} + +// formatAccumPrefix returns the key prefix used +// specifically for accumulator values in the KVStore. +// Returns "accum/acc/{name}" as bytes. +func formatAccumPrefixKey(name string) []byte { + return formatModulePrefixKey(fmt.Sprintf("%s/%s", accumulatorPrefix, name)) +} + +// FormatPositionPrefixKey returns the key prefix used +// specifically for position values in the KVStore. +// Returns "accum/pos/{accumName}/{name}" as bytes. +func FormatPositionPrefixKey(accumName, name string) []byte { + return formatAccumPrefixKey(fmt.Sprintf("%s/%s/%s", positionPrefix, accumName, name)) +} diff --git a/osmoutils/address.go b/osmoutils/address.go new file mode 100644 index 000000000..fb47d79da --- /dev/null +++ b/osmoutils/address.go @@ -0,0 +1,12 @@ +package osmoutils + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/address" +) + +// NewModuleAddressWithPrefix returns a new module address with the given prefix and identifier. +func NewModuleAddressWithPrefix(moduleName, prefix string, identifier []byte) sdk.AccAddress { + key := append([]byte(prefix), identifier...) + return address.Module(moduleName, key) +} diff --git a/osmoutils/cache_ctx.go b/osmoutils/cache_ctx.go new file mode 100644 index 000000000..0d4cbe680 --- /dev/null +++ b/osmoutils/cache_ctx.go @@ -0,0 +1,80 @@ +package osmoutils + +import ( + "errors" + "fmt" + "runtime" + "runtime/debug" + + "github.com/cosmos/cosmos-sdk/store/types" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// This function lets you run the function f, but if theres an error or panic +// drop the state machine change and log the error. +// If there is no error, proceeds as normal (but with some slowdown due to SDK store weirdness) +// Try to avoid usage of iterators in f. +// +// If its an out of gas panic, this function will also panic like in normal tx execution flow. +// This is still safe for beginblock / endblock code though, as they do not have out of gas panics. +func ApplyFuncIfNoError(ctx sdk.Context, f func(ctx sdk.Context) error) (err error) { + // Add a panic safeguard + defer func() { + if recoveryError := recover(); recoveryError != nil { + if isErr, _ := IsOutOfGasError(recoveryError); isErr { + // We panic with the same error, to replicate the normal tx execution flow. + panic(recoveryError) + } else { + PrintPanicRecoveryError(ctx, recoveryError) + err = errors.New("panic occurred during execution") + } + } + }() + // makes a new cache context, which all state changes get wrapped inside of. + cacheCtx, write := ctx.CacheContext() + err = f(cacheCtx) + if err != nil { + ctx.Logger().Error(err.Error()) + } else { + // no error, write the output of f + write() + ctx.EventManager().EmitEvents(cacheCtx.EventManager().Events()) + } + return err +} + +// Frustratingly, this has to return the error descriptor, not an actual error itself +// because the SDK errors here are not actually errors. (They don't implement error interface) +func IsOutOfGasError(err any) (bool, string) { + switch e := err.(type) { + case types.ErrorOutOfGas: + return true, e.Descriptor + case types.ErrorGasOverflow: + return true, e.Descriptor + default: + return false, "" + } +} + +// PrintPanicRecoveryError error logs the recoveryError, along with the stacktrace, if it can be parsed. +// If not emits them to stdout. +func PrintPanicRecoveryError(ctx sdk.Context, recoveryError interface{}) { + errStackTrace := string(debug.Stack()) + switch e := recoveryError.(type) { + case types.ErrorOutOfGas: + ctx.Logger().Debug("out of gas error inside panic recovery block: " + e.Descriptor) + return + case string: + ctx.Logger().Error("Recovering from (string) panic: " + e) + case runtime.Error: + ctx.Logger().Error("recovered (runtime.Error) panic: " + e.Error()) + case error: + ctx.Logger().Error("recovered (error) panic: " + e.Error()) + default: + ctx.Logger().Error("recovered (default) panic. Could not capture logs in ctx, see stdout") + fmt.Println("Recovering from panic ", recoveryError) + debug.PrintStack() + return + } + ctx.Logger().Error("stack trace: " + errStackTrace) +} diff --git a/osmoutils/cache_ctx_test.go b/osmoutils/cache_ctx_test.go new file mode 100644 index 000000000..93d70205b --- /dev/null +++ b/osmoutils/cache_ctx_test.go @@ -0,0 +1,59 @@ +package osmoutils_test + +import ( + "github.com/cosmos/cosmos-sdk/store/types" + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/CosmosContracts/juno/v15/osmoutils" +) + +var expectedOutOfGasError = types.ErrorOutOfGas{Descriptor: "my func"} + +func consumeGas(ctx sdk.Context, gas uint64, numTimes int) error { + for i := 0; i < numTimes; i++ { + ctx.GasMeter().ConsumeGas(gas, "my func") + } + return nil +} + +func (s *TestSuite) TestCacheCtxConsumeGas() { + // every test case adds 1k gas 10 times + testcases := map[string]struct { + gasLimit uint64 + gasUsedPreCtx uint64 + gasUsedPostCtx uint64 + expectPanic bool + }{ + "no gas limit hit": { + gasLimit: 15_000, + gasUsedPreCtx: 111, + gasUsedPostCtx: 111 + 10_000, + expectPanic: false, + }, + "gas limit hit": { + gasLimit: 10_000, + gasUsedPreCtx: 111, + gasUsedPostCtx: 111 + 10_000, + expectPanic: true, + }, + } + for name, tc := range testcases { + s.Run(name, func() { + ctx := s.ctx.WithGasMeter(sdk.NewGasMeter(tc.gasLimit)) + ctx.GasMeter().ConsumeGas(tc.gasUsedPreCtx, "pre ctx") + var err error + f := func() { + osmoutils.ApplyFuncIfNoError(ctx, func(c sdk.Context) error { + return consumeGas(c, 1000, 10) + }) + } + if tc.expectPanic { + s.PanicsWithValue(expectedOutOfGasError, f) + } else { + f() + s.Require().NoError(err) + } + s.Equal(tc.gasUsedPostCtx, ctx.GasMeter().GasConsumed()) + }) + } +} diff --git a/osmoutils/cli_helpers.go b/osmoutils/cli_helpers.go new file mode 100644 index 000000000..e07c2d43a --- /dev/null +++ b/osmoutils/cli_helpers.go @@ -0,0 +1,76 @@ +package osmoutils + +import ( + "fmt" + "strconv" + "strings" + + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/testutil/network" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/tendermint/tendermint/crypto/ed25519" +) + +func DefaultFeeString(cfg network.Config) string { + feeCoins := sdk.NewCoins(sdk.NewCoin(cfg.BondDenom, sdk.NewInt(10))) + return fmt.Sprintf("--%s=%s", flags.FlagFees, feeCoins.String()) +} + +const ( + base = 10 + bitlen = 64 +) + +func ParseUint64SliceFromString(s string, separator string) ([]uint64, error) { + var parsedInts []uint64 + for _, s := range strings.Split(s, separator) { + s = strings.TrimSpace(s) + + parsed, err := strconv.ParseUint(s, base, bitlen) + if err != nil { + return []uint64{}, err + } + parsedInts = append(parsedInts, parsed) + } + return parsedInts, nil +} + +func ParseSdkIntFromString(s string, separator string) ([]sdk.Int, error) { + var parsedInts []sdk.Int + for _, weightStr := range strings.Split(s, separator) { + weightStr = strings.TrimSpace(weightStr) + + parsed, err := strconv.ParseUint(weightStr, base, bitlen) + if err != nil { + return parsedInts, err + } + parsedInts = append(parsedInts, sdk.NewIntFromUint64(parsed)) + } + return parsedInts, nil +} + +func ParseSdkDecFromString(s string, separator string) ([]sdk.Dec, error) { + var parsedDec []sdk.Dec + for _, weightStr := range strings.Split(s, separator) { + weightStr = strings.TrimSpace(weightStr) + + parsed, err := sdk.NewDecFromStr(weightStr) + if err != nil { + return parsedDec, err + } + + parsedDec = append(parsedDec, parsed) + } + return parsedDec, nil +} + +// CreateRandomAccounts is a function return a list of randomly generated AccAddresses +func CreateRandomAccounts(numAccts int) []sdk.AccAddress { + testAddrs := make([]sdk.AccAddress, numAccts) + for i := 0; i < numAccts; i++ { + pk := ed25519.GenPrivKey().PubKey() + testAddrs[i] = sdk.AccAddress(pk.Address()) + } + + return testAddrs +} diff --git a/osmoutils/coin_helper.go b/osmoutils/coin_helper.go new file mode 100644 index 000000000..61f2fb195 --- /dev/null +++ b/osmoutils/coin_helper.go @@ -0,0 +1,46 @@ +package osmoutils + +import ( + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// TODO: Get this into the SDK https://github.com/cosmos/cosmos-sdk/issues/12538 +func CoinsDenoms(coins sdk.Coins) []string { + denoms := make([]string, len(coins)) + for i, coin := range coins { + denoms[i] = coin.Denom + } + return denoms +} + +// MinCoins returns the minimum of each denom between both coins. +// For now it assumes they have the same denoms. +// TODO: Replace with method in SDK once we update our version +func MinCoins(coinsA sdk.Coins, coinsB sdk.Coins) sdk.Coins { + resCoins := sdk.Coins{} + for i, coin := range coinsA { + if coinsB[i].Amount.GT(coin.Amount) { + resCoins = append(resCoins, coin) + } else { + resCoins = append(resCoins, coinsB[i]) + } + } + return resCoins +} + +// SubDecCoinArrays subtracts the contents of the second param from the first (decCoinsArrayA - decCoinsArrayB) +// Note that this takes in two _arrays_ of DecCoins, meaning that each term itself is of type DecCoins (i.e. an array of DecCoin). +func SubDecCoinArrays(decCoinsArrayA []sdk.DecCoins, decCoinsArrayB []sdk.DecCoins) ([]sdk.DecCoins, error) { + if len(decCoinsArrayA) != len(decCoinsArrayB) { + return []sdk.DecCoins{}, fmt.Errorf("DecCoin arrays must be of equal length to be subtracted") + } + + finalDecCoinArray := []sdk.DecCoins{} + for i := range decCoinsArrayA { + finalDecCoinArray = append(finalDecCoinArray, decCoinsArrayA[i].Sub(decCoinsArrayB[i])) + } + + return finalDecCoinArray, nil +} diff --git a/osmoutils/coin_helper_test.go b/osmoutils/coin_helper_test.go new file mode 100644 index 000000000..1d7ecf4c8 --- /dev/null +++ b/osmoutils/coin_helper_test.go @@ -0,0 +1,83 @@ +package osmoutils_test + +import ( + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/require" + + "github.com/CosmosContracts/juno/v15/osmoutils" +) + +func TestSubDecCoins(t *testing.T) { + var ( + emptyCoins = sdk.DecCoins(nil) + fiftyFooCoins = sdk.NewDecCoin("foo", sdk.NewInt(50)) + fiftyBarCoins = sdk.NewDecCoin("bar", sdk.NewInt(50)) + hundredFooCoins = sdk.NewDecCoin("foo", sdk.NewInt(100)) + hundredBarCoins = sdk.NewDecCoin("bar", sdk.NewInt(100)) + + fiftyEach = sdk.NewDecCoins(fiftyFooCoins, fiftyBarCoins) + hundredEach = sdk.NewDecCoins(hundredFooCoins, hundredBarCoins) + ) + + tests := map[string]struct { + firstInput []sdk.DecCoins + secondInput []sdk.DecCoins + + expectedOutput []sdk.DecCoins + expectError bool + }{ + "[[100foo, 100bar], [100foo, 100bar]] - [[50foo, 50bar], [50foo, 100bar]]": { + firstInput: []sdk.DecCoins{hundredEach, hundredEach}, + secondInput: []sdk.DecCoins{fiftyEach, hundredEach}, + + expectedOutput: []sdk.DecCoins{fiftyEach, emptyCoins}, + }, + "[[100bar, 100foo], [100foo, 100bar]] - [[50foo, 50bar], [50foo, 100bar]]": { + firstInput: []sdk.DecCoins{ + sdk.NewDecCoins(hundredBarCoins, hundredFooCoins), + hundredEach, + }, + secondInput: []sdk.DecCoins{fiftyEach, hundredEach}, + + expectedOutput: []sdk.DecCoins{fiftyEach, emptyCoins}, + }, + "both inputs empty": { + firstInput: []sdk.DecCoins{}, + secondInput: []sdk.DecCoins{}, + + expectedOutput: []sdk.DecCoins{}, + }, + "[[100foo]] - [[50foo]]": { + firstInput: []sdk.DecCoins{sdk.NewDecCoins(hundredFooCoins)}, + secondInput: []sdk.DecCoins{sdk.NewDecCoins(fiftyFooCoins)}, + + expectedOutput: []sdk.DecCoins{sdk.NewDecCoins(fiftyFooCoins)}, + }, + + // error catching + + "different length inputs": { + firstInput: []sdk.DecCoins{hundredEach, hundredEach, hundredEach}, + secondInput: []sdk.DecCoins{fiftyEach, hundredEach}, + + expectedOutput: []sdk.DecCoins{}, + expectError: true, + }, + } + for name, tc := range tests { + t.Run(name, func(t *testing.T) { + actualOutput, err := osmoutils.SubDecCoinArrays(tc.firstInput, tc.secondInput) + + if tc.expectError { + require.Error(t, err) + require.Equal(t, tc.expectedOutput, actualOutput) + return + } + + require.NoError(t, err) + require.Equal(t, tc.expectedOutput, actualOutput) + }) + } +} diff --git a/osmoutils/conv_helper.go b/osmoutils/conv_helper.go new file mode 100644 index 000000000..bd675e481 --- /dev/null +++ b/osmoutils/conv_helper.go @@ -0,0 +1,16 @@ +package osmoutils + +import ( + "encoding/binary" + "strconv" +) + +func Uint64ToBytes(i uint64) []byte { + key := make([]byte, 8) + binary.LittleEndian.PutUint64(key, i) + return key +} + +func Uint64ToString(i uint64) string { + return strconv.FormatUint(i, 10) +} diff --git a/osmoutils/cosmwasm/helpers.go b/osmoutils/cosmwasm/helpers.go new file mode 100644 index 000000000..4ee9464bc --- /dev/null +++ b/osmoutils/cosmwasm/helpers.go @@ -0,0 +1,223 @@ +package cosmwasm + +import ( + "encoding/json" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// ContracKeeper defines the interface needed to be fulfilled for +// the ContractKeeper. +type ContractKeeper interface { + Instantiate( + ctx sdk.Context, + codeID uint64, + creator, admin sdk.AccAddress, + initMsg []byte, + label string, + deposit sdk.Coins, + ) (sdk.AccAddress, []byte, error) + + Sudo(ctx sdk.Context, contractAddress sdk.AccAddress, msg []byte) ([]byte, error) + + Execute(ctx sdk.Context, contractAddress sdk.AccAddress, caller sdk.AccAddress, msg []byte, coins sdk.Coins) ([]byte, error) +} + +// WasmKeeper defines the interface needed to be fulfilled for +// the WasmKeeper. +type WasmKeeper interface { + QuerySmart(ctx sdk.Context, contractAddress sdk.AccAddress, queryMsg []byte) ([]byte, error) +} + +// Query is a generic function to query a CosmWasm smart contract with the given request. +// The function marshals the request into JSON, performs a smart query using the Wasm keeper, and then +// unmarshals the response into the provided response type. +// It returns the response of the specified type and an error if the JSON marshaling, smart query, +// or JSON unmarshaling process fails. +// +// The function uses generics, and T and K represent the request and response types, respectively. +// +// Parameters: +// - ctx: The SDK context. +// - wasmKeeper: The Wasm keeper to query the smart contract. +// - contractAddress: The Bech32 address of the smart contract. +// - request: The request of type T to be sent to the smart contract. +// +// Returns: +// - response: The response of type K from the smart contract. +// - err: An error if the JSON marshaling, smart query, or JSON unmarshaling process fails; otherwise, nil. +func Query[T any, K any](ctx sdk.Context, wasmKeeper WasmKeeper, contractAddress string, request T) (response K, err error) { + bz, err := json.Marshal(request) + if err != nil { + return response, err + } + + responseBz, err := wasmKeeper.QuerySmart(ctx, sdk.MustAccAddressFromBech32(contractAddress), bz) + if err != nil { + return response, err + } + + if err := json.Unmarshal(responseBz, &response); err != nil { + return response, err + } + + return response, nil +} + +// MustQuery is a generic function to query a CosmWasm smart contract with the given request. +// It is similar to the Query function but panics if an error occurs during the query. +// The function uses the Query function to perform the smart query and panics if an error is returned. +// +// The function uses generics, and T and K represent the request and response types, respectively. +// +// Parameters: +// - ctx: The SDK context. +// - wasmKeeper: The Wasm keeper to query the smart contract. +// - contractAddress: The Bech32 address of the smart contract. +// - request: The request of type T to be sent to the smart contract. +// +// Returns: +// - response: The response of type K from the smart contract. +// +// Panics: +// - If an error occurs during the JSON marshaling, smart query, or JSON unmarshaling process. +func MustQuery[T any, K any](ctx sdk.Context, wasmKeeper WasmKeeper, contractAddress string, request T) (response K) { + response, err := Query[T, K](ctx, wasmKeeper, contractAddress, request) + if err != nil { + panic(err) + } + + return response +} + +// Sudo is a generic function to execute a sudo message on a CosmWasm smart contract with the given request. +// The function marshals the request into JSON, performs a sudo call using the contract keeper, and then +// unmarshals the response into the provided response type. +// It returns the response of the specified type and an error if the JSON marshaling, sudo call, +// or JSON unmarshaling process fails. +// +// The function uses generics, and T and K represent the request and response types, respectively. +// +// Parameters: +// - ctx: The SDK context. +// - contractKeeper: The Contract keeper to execute the sudo call on the smart contract. +// - contractAddress: The Bech32 address of the smart contract. +// - request: The request of type T to be sent to the smart contract. +// +// Returns: +// - response: The response of type K from the smart contract. +// - err: An error if the JSON marshaling, sudo call, or JSON unmarshaling process fails; otherwise, nil. +func Sudo[T any, K any](ctx sdk.Context, contractKeeper ContractKeeper, contractAddress string, request T) (response K, err error) { + bz, err := json.Marshal(request) + if err != nil { + return response, err + } + + responseBz, err := contractKeeper.Sudo(ctx, sdk.MustAccAddressFromBech32(contractAddress), bz) + if err != nil { + return response, err + } + + // valid empty response + if len(responseBz) == 0 { + return response, nil + } + + if err := json.Unmarshal(responseBz, &response); err != nil { + return response, err + } + + return response, nil +} + +// MustSudo is a generic function to execute a sudo message on a CosmWasm smart contract with the given request. +// It is similar to the Sudo function but panics if an error occurs during the sudo call. +// The function uses the Sudo function to perform the sudo call and panics if an error is returned. +// +// The function uses generics, and T and K represent the request and response types, respectively. +// +// Parameters: +// - ctx: The SDK context. +// - contractKeeper: The Contract keeper to execute the sudo call on the smart contract. +// - contractAddress: The Bech32 address of the smart contract. +// - request: The request of type T to be sent to the smart contract. +// +// Returns: +// - response: The response of type K from the smart contract. +// +// Panics: +// - If an error occurs during the JSON marshaling, sudo call, or JSON unmarshaling process. +func MustSudo[T any, K any](ctx sdk.Context, contractKeeper ContractKeeper, contractAddress string, request T) (response K) { + response, err := Sudo[T, K](ctx, contractKeeper, contractAddress, request) + if err != nil { + panic(err) + } + + return response +} + +// Execute is a generic function to execute a contract call on a given contract address with a specified request. +// It accepts a context, contract keeper, contract address, caller address, coins, and request data. +// This function works with any data type for the request and response (T and K). +// It marshals the request data into JSON format, executes the contract call, and then unmarshals the response +// data back into the specified response type (K). In case of any error, it returns the zero value of the response +// type along with the error. +// +// Parameters: +// - ctx: The SDK context. +// - contractKeeper: An instance of the contract keeper to manage contract interactions. +// - contractAddress: The bech32 address of the contract to be executed. +// - caller: The address of the account making the call. +// - coins: The coins to be transferred during the call. +// - request: The request data, can be of any data type. +// +// Returns: +// - response: The response data, can be of any data type (K). Returns the zero value of K in case of an error. +// - err: An error object that indicates any error during the contract execution or data marshalling/unmarshalling process. +func Execute[T any, K any](ctx sdk.Context, contractKeeper ContractKeeper, contractAddress string, caller sdk.AccAddress, coins sdk.Coins, request T) (response K, err error) { + bz, err := json.Marshal(request) + if err != nil { + return response, err + } + + responseBz, err := contractKeeper.Execute(ctx, sdk.MustAccAddressFromBech32(contractAddress), caller, bz, coins) + if err != nil { + return response, err + } + + // valid empty response + if len(responseBz) == 0 { + return response, nil + } + + if err := json.Unmarshal(responseBz, &response); err != nil { + return response, err + } + + return response, nil +} + +// MustExecute is a wrapper around the Execute function, which provides a more concise API for +// executing a contract call on a given contract address with a specified request. +// It works with any data type for the request and response (T and K). +// This function panics if an error occurs during the contract execution or data marshalling/unmarshalling process. +// Use this function when you're confident that the contract execution will not encounter any errors. +// +// Parameters: +// - ctx: The SDK context. +// - contractKeeper: An instance of the contract keeper to manage contract interactions. +// - contractAddress: The bech32 address of the contract to be executed. +// - caller: The address of the account making the call. +// - coins: The coins to be transferred during the call. +// - request: The request data, can be of any data type. +// +// Returns: +// - response: The response data, can be of any data type (K). +func MustExecute[T any, K any](ctx sdk.Context, contractKeeper ContractKeeper, contractAddress string, caller sdk.AccAddress, coins sdk.Coins, request T) (response K) { + response, err := Execute[T, K](ctx, contractKeeper, contractAddress, caller, coins, request) + if err != nil { + panic(err) + } + + return response +} diff --git a/osmoutils/encoding_helper.go b/osmoutils/encoding_helper.go new file mode 100644 index 000000000..8d81fb823 --- /dev/null +++ b/osmoutils/encoding_helper.go @@ -0,0 +1,25 @@ +package osmoutils + +import ( + "fmt" + "time" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +func FormatFixedLengthU64(d uint64) string { + return fmt.Sprintf("%0.20d", d) +} + +func FormatTimeString(t time.Time) string { + return t.UTC().Round(0).Format(sdk.SortableTimeFormat) +} + +// Parses a string encoded using FormatTimeString back into a time.Time +func ParseTimeString(s string) (time.Time, error) { + t, err := time.Parse(sdk.SortableTimeFormat, s) + if err != nil { + return t, err + } + return t.UTC().Round(0), nil +} diff --git a/osmoutils/encoding_helper_test.go b/osmoutils/encoding_helper_test.go new file mode 100644 index 000000000..35690501b --- /dev/null +++ b/osmoutils/encoding_helper_test.go @@ -0,0 +1,29 @@ +package osmoutils + +import ( + "math" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestFormatFixedLengthU64(t *testing.T) { + tests := map[string]struct { + d uint64 + want string + }{ + "0": {0, "00000000000000000000"}, + "1": {1, "00000000000000000001"}, + "9": {9, "00000000000000000009"}, + "10": {10, "00000000000000000010"}, + "123": {123, "00000000000000000123"}, + "max u64": {math.MaxUint64, "18446744073709551615"}, + } + for name, tt := range tests { + t.Run(name, func(t *testing.T) { + got := FormatFixedLengthU64(tt.d) + assert.Equal(t, tt.want, got) + assert.Equal(t, len(got), 20) + }) + } +} diff --git a/osmoutils/export_test.go b/osmoutils/export_test.go new file mode 100644 index 000000000..3ae6a32c2 --- /dev/null +++ b/osmoutils/export_test.go @@ -0,0 +1,11 @@ +package osmoutils + +import db "github.com/tendermint/tm-db" + +func GatherValuesFromIterator[T any](iterator db.Iterator, parseValue func([]byte) (T, error), stopFn func([]byte) bool) ([]T, error) { + return gatherValuesFromIterator(iterator, parseValue, stopFn) +} + +func NoStopFn(key []byte) bool { + return noStopFn(key) +} diff --git a/osmoutils/generic_helper.go b/osmoutils/generic_helper.go new file mode 100644 index 000000000..0a008afcb --- /dev/null +++ b/osmoutils/generic_helper.go @@ -0,0 +1,17 @@ +package osmoutils + +import "reflect" + +// MakeNew makes a new instance of generic T. +// if T is a pointer, makes a new instance of the underlying struct via reflection, +// and then a pointer to it. +func MakeNew[T any]() T { + var v T + if typ := reflect.TypeOf(v); typ.Kind() == reflect.Ptr { + elem := typ.Elem() + //nolint:forcetypeassert + return reflect.New(elem).Interface().(T) // must use reflect + } else { + return *new(T) // v is not ptr, alloc with new + } +} diff --git a/osmoutils/go.mod b/osmoutils/go.mod new file mode 100644 index 000000000..6870dc93e --- /dev/null +++ b/osmoutils/go.mod @@ -0,0 +1,145 @@ +module github.com/osmosis-labs/osmosis/osmoutils + +go 1.20 + +require ( + github.com/cosmos/cosmos-sdk v0.47.1 + github.com/cosmos/iavl v0.19.5 + github.com/cosmos/ibc-go/v4 v4.3.0 + github.com/gogo/protobuf v1.3.3 + github.com/spf13/cobra v1.7.0 + github.com/spf13/pflag v1.0.5 + github.com/stretchr/testify v1.8.2 + github.com/tendermint/tendermint v0.34.26 + github.com/tendermint/tm-db v0.6.8-0.20220506192307-f628bb5dc95b + golang.org/x/exp v0.0.0-20230131160201-f062dba9d201 +) + +require ( + 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.1 // indirect + github.com/beorn7/perks v1.0.1 // indirect + github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816 // indirect + github.com/btcsuite/btcd v0.22.2 // indirect + github.com/cenkalti/backoff/v4 v4.1.3 // indirect + github.com/cespare/xxhash v1.1.0 // indirect + github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/coinbase/rosetta-sdk-go v0.7.9 // indirect + github.com/confio/ics23/go v0.9.0 // indirect + github.com/cosmos/btcutil v1.0.5 // indirect + github.com/cosmos/go-bip39 v1.0.0 // indirect + github.com/cosmos/gorocksdb v1.2.0 // indirect + github.com/cosmos/ledger-cosmos-go v0.12.2 // indirect + github.com/creachadair/taskgroup v0.3.2 // indirect + github.com/danieljoos/wincred v1.1.2 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect + github.com/dgraph-io/badger/v3 v3.2103.2 // indirect + github.com/dgraph-io/ristretto v0.1.0 // indirect + github.com/dustin/go-humanize v1.0.1-0.20200219035652-afde56e7acac // indirect + github.com/dvsekhvalnov/jose2go v1.5.0 // indirect + github.com/felixge/httpsnoop v1.0.2 // indirect + github.com/frankban/quicktest v1.14.4 // indirect + github.com/fsnotify/fsnotify v1.6.0 // indirect + github.com/gin-gonic/gin v1.8.1 // 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/go-playground/validator/v10 v10.11.1 // indirect + github.com/goccy/go-json v0.10.2 // 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/protobuf v1.5.3 // indirect + github.com/golang/snappy v0.0.4 // indirect + github.com/google/btree v1.1.2 // indirect + github.com/google/flatbuffers v1.12.1 // indirect + github.com/google/gofuzz v1.2.0 // indirect + github.com/google/orderedcode v0.0.1 // indirect + github.com/gorilla/handlers v1.5.1 // indirect + github.com/gorilla/mux v1.8.0 // indirect + github.com/gorilla/websocket v1.5.0 // indirect + github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect + github.com/grpc-ecosystem/grpc-gateway v1.16.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-immutable-radix v1.3.1 // indirect + github.com/hashicorp/go-uuid v1.0.2 // 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-20220222234857-c00d1f31bab3 // indirect + github.com/improbable-eng/grpc-web v0.15.0 // indirect + github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/jhump/protoreflect v1.13.1-0.20220928232736-101791cb1b4c // indirect + github.com/jmhodges/levigo v1.0.0 // indirect + github.com/klauspost/compress v1.15.11 // indirect + github.com/lib/pq v1.10.7 // indirect + github.com/libp2p/go-buffer-pool v0.1.0 // indirect + github.com/magiconair/properties v1.8.7 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.17 // indirect + github.com/matttproud/golang_protobuf_extensions v1.0.4 // 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 + github.com/onsi/ginkgo v1.16.4 // indirect + github.com/onsi/gomega v1.26.0 // indirect + github.com/pelletier/go-toml/v2 v2.0.6 // indirect + github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/prometheus/client_golang v1.15.0 // indirect + github.com/prometheus/client_model v0.3.0 // indirect + github.com/prometheus/common v0.42.0 // indirect + github.com/prometheus/procfs v0.9.0 // indirect + github.com/rakyll/statik v0.1.7 // indirect + github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect + github.com/regen-network/cosmos-proto v0.3.1 // indirect + github.com/rogpeppe/go-internal v1.10.0 // indirect + 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.3 // indirect + github.com/spf13/cast v1.5.0 // indirect + github.com/spf13/jwalterweatherman v1.1.0 // indirect + github.com/spf13/viper v1.15.0 // indirect + github.com/subosito/gotenv v1.4.2 // indirect + github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // 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.1 // indirect + github.com/zondax/ledger-go v0.14.1 // indirect + go.etcd.io/bbolt v1.3.6 // indirect + go.opencensus.io v0.24.0 // indirect + golang.org/x/crypto v0.5.0 // indirect + golang.org/x/net v0.9.0 // indirect + golang.org/x/sys v0.7.0 // indirect + golang.org/x/term v0.7.0 // indirect + golang.org/x/text v0.9.0 // indirect + golang.org/x/tools v0.8.0 // indirect + google.golang.org/genproto v0.0.0-20230125152338-dcaf20b6aeaa // indirect + google.golang.org/grpc v1.53.0 // indirect + google.golang.org/protobuf v1.30.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + nhooyr.io/websocket v1.8.7 // indirect +) + +replace ( + // Our cosmos-sdk branch is: https://github.com/osmosis-labs/cosmos-sdk, current branch: v16.x. Direct commit link: https://github.com/osmosis-labs/cosmos-sdk/commit/43c58d9061e3b8e0f06c3d9efef8c728800ab554 + github.com/cosmos/cosmos-sdk => github.com/osmosis-labs/cosmos-sdk v0.45.1-0.20230326212251-7a2cf2993434 + // use cosmos-compatible protobufs + github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 + github.com/tendermint/tendermint => github.com/informalsystems/tendermint v0.34.24 + // use grpc compatible with cosmos protobufs + google.golang.org/grpc => google.golang.org/grpc v1.33.2 +) diff --git a/osmoutils/go.sum b/osmoutils/go.sum new file mode 100644 index 000000000..90d4d78d2 --- /dev/null +++ b/osmoutils/go.sum @@ -0,0 +1,1352 @@ +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= +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= +cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= +cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +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/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/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/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= +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +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= +collectd.org v0.3.0/go.mod h1:A/8DzQBkF6abtvrT2j/AU/4tiBgJWYyh0y/oB/4MlWE= +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= +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/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= +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/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/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= +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= +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/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= +github.com/Workiva/go-datastructures v1.0.53/go.mod h1:1yZL+zfsztete+ePzZz/Zb1/t5BnDuE2Ya2MMGhzP6A= +github.com/Zilliqa/gozilliqa-sdk v1.2.1-0.20201201074141-dd0ecada1be6/go.mod h1:eSYp2T6f0apnuW8TzhV3f6Aff2SE8Dwio++U4ha4yEM= +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/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= +github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA= +github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4= +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.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +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/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816 h1:41iFGWnSlI2gVpmOtVTJZNodLdLQLn/KsJqFvXwnd/s= +github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816/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-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.22.1/go.mod h1:wqgTSL29+50LRkmOVknEdmt8ZojIzhuWvgu/iptuN7Y= +github.com/btcsuite/btcd v0.22.2 h1:vBZ+lGGd1XubpOWO67ITJpAEsICWhA0YzqkcpkgNBfo= +github.com/btcsuite/btcd v0.22.2/go.mod h1:wqgTSL29+50LRkmOVknEdmt8ZojIzhuWvgu/iptuN7Y= +github.com/btcsuite/btcd/btcec/v2 v2.1.2/go.mod h1:ctjw4H1kknNJmRN4iP1R7bTQ+v3GJkZBd6mui8ZsAZE= +github.com/btcsuite/btcd/btcec/v2 v2.3.2 h1:5n0X6hX0Zk+6omWcihdYvdAlGf2DfasC0GMf7DClJ3U= +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-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= +github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= +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= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +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/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +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/confio/ics23/go v0.9.0 h1:cWs+wdbS2KRPZezoaaj+qBleXgUk5WOQFMP3CQFGTr4= +github.com/confio/ics23/go v0.9.0/go.mod h1:4LPZ2NYqnYIVRklaozjNR1FScgDJ2s5Xrp+e/mYVRak= +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= +github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/cosmos/btcutil v1.0.5 h1:t+ZFcX77LpKtDBhjucvnOH8C2l2ioGsBNEQ3jef8xFk= +github.com/cosmos/btcutil v1.0.5/go.mod h1:IyB7iuqZMJlthe2tkIFL33xPyzbFYP0XVdS8P5lUPis= +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/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.5 h1:rGA3hOrgNxgRM5wYcSCxgQBap7fW82WZgY78V9po/iY= +github.com/cosmos/iavl v0.19.5/go.mod h1:X9PKD3J0iFxdmgNLa7b2LYWdsGd90ToV5cAONApkEPw= +github.com/cosmos/ibc-go/v4 v4.3.0 h1:yOzVsyZzsv4XPBux8gq+D0LhZn45yGWKjvT+6Vyo5no= +github.com/cosmos/ibc-go/v4 v4.3.0/go.mod h1:CcLvIoi9NNtIbNsxs4KjBGjYhlwqtsmXy1AKARKiMzQ= +github.com/cosmos/ledger-cosmos-go v0.12.2 h1:/XYaBlE2BJxtvpkHiBm97gFGSGmYGKunKyF3nNqAXZA= +github.com/cosmos/ledger-cosmos-go v0.12.2/go.mod h1:ZcqYgnfNJ6lAXe4HPtWgarNEY+B74i+2/8MhZw4ziiI= +github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= +github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +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 h1:YLtO71vCjJRCBcrPMtQ9nqBsqpA1m5sE92cU+pd5Mcc= +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.4/go.mod h1:vSw/ax2qojzbN6eXHIx6KPKtCSHJN/Uz0X0VPruTIhk= +github.com/dgraph-io/badger/v3 v3.2103.2 h1:dpyM5eCJAtQCBcMCZcT4UBZchuTJgCywerHHgmxfxM8= +github.com/dgraph-io/badger/v3 v3.2103.2/go.mod h1:RHo4/GmYcKKh5Lxu63wLEMHJ70Pac2JqZRYGhlyAo2M= +github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= +github.com/dgraph-io/ristretto v0.0.3/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= +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/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= +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/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/dustin/go-humanize v1.0.1-0.20200219035652-afde56e7acac h1:opbrjaN/L8gg6Xh5D04Tem+8xVcz6ajZlGCs49mQgyg= +github.com/dustin/go-humanize v1.0.1-0.20200219035652-afde56e7acac/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/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 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/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.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= +github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/felixge/httpsnoop v1.0.2 h1:+nS9g82KMXccJ/wp0zyRW9ZBHFETmMGtkk+2CTTrW4o= +github.com/felixge/httpsnoop v1.0.2/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/fjl/memsize v0.0.0-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.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= +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/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.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= +github.com/gin-gonic/gin v1.8.1 h1:4+fr/el88TOO3ewCmQr8cx/CtZ/umlIRIs5M4NTNjf8= +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= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= +github.com/go-kit/kit v0.12.0 h1:e4o3o3IsBfAKQh5Qbbiqyfu97Ku7jrO/JbohvztANh4= +github.com/go-kit/kit v0.12.0/go.mod h1:lHd+EkCZPIwYItmGDDRdhinkzX2A1sj+M9biaEaizzs= +github.com/go-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU= +github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +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/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= +github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU= +github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= +github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho= +github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= +github.com/go-playground/validator/v10 v10.11.1 h1:prmOlTVv+YjZjmRmNSF3VmspqJIxJWXmqUsHwfTRRkQ= +github.com/go-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/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +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= +github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8= +github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= +github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo= +github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= +github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= +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= +github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +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.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= +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= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +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.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.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/flatbuffers v1.12.1 h1:MVlul7pQNoDzWRLTw5imwYsl+usrS1TXG2H4jg6ImGw= +github.com/google/flatbuffers v1.12.1/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= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +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.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= +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/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/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= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +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/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/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/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= +github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4= +github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q= +github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +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/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/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= +github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= +github.com/grpc-ecosystem/grpc-gateway v1.8.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c h1:6rhixN/i8ZofjG1Y75iExal34USq5p+wiN1tpie8IrU= +github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c/go.mod h1:NMPJylDgVpX0MLRlPy15sqSwOFv/U1GZ2m21JhFfek0= +github.com/gtank/merlin v0.1.1-0.20191105220539-8318aed1a79f/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/bIQ+s= +github.com/gtank/merlin v0.1.1 h1:eQ90iG7K9pOhtereWsmyRJ6RAwcP4tHTDBHXNg+u5is= +github.com/gtank/merlin v0.1.1/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/bIQ+s= +github.com/gtank/ristretto255 v0.1.2 h1:JEqUCPA1NvLq5DwYtuzigd7ss8fwbYay9fi4/5uMzcc= +github.com/gtank/ristretto255 v0.1.2/go.mod h1:Ph5OpO6c7xKUGROZfWVLiJf9icMDwUeIvY4OmlYW69o= +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-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= +github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +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-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/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE= +github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-version v1.2.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/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/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/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/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +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/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/informalsystems/tendermint v0.34.24 h1:2beNEg5tp+U5oj/Md+0xDBsMHGbdue31T3OrstS6xS0= +github.com/informalsystems/tendermint v0.34.24/go.mod h1:rXVrl4OYzmIa1I91av3iLv2HS0fGSiucyW9J4aMTpKI= +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/gopoet v0.0.0-20190322174617-17282ff210b3/go.mod h1:me9yfT6IJSlOL3FCfrg+L6yzUEZ+5jW6WHt4Sk+UPUI= +github.com/jhump/gopoet v0.1.0/go.mod h1:me9yfT6IJSlOL3FCfrg+L6yzUEZ+5jW6WHt4Sk+UPUI= +github.com/jhump/goprotoc v0.5.0/go.mod h1:VrbvcYrQOrTi3i0Vf+m+oqQWk9l72mjkJCYo7UvLHRQ= +github.com/jhump/protoreflect v1.11.0/go.mod h1:U7aMIjN0NWq9swDP7xDdoMfRHb35uiuTd3Z9nFXJf5E= +github.com/jhump/protoreflect v1.13.1-0.20220928232736-101791cb1b4c h1:XImQJfpJLmGEEd8ll5yPVyL/aEvmgGHW4WYTyNseLOM= +github.com/jhump/protoreflect v1.13.1-0.20220928232736-101791cb1b4c/go.mod h1:JytZfP5d0r8pVNLZvai7U/MCuTWITgrI4tTg7puQFKI= +github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +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= +github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= +github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +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.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/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.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.11 h1:Lcadnb3RKGin4FYM/orgq0qde+nc15E5Cbqg4B9Sx9c= +github.com/klauspost/compress v1.15.11/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= +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.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +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/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= +github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= +github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw= +github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= +github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= +github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= +github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= +github.com/lucasjones/reggen v0.0.0-20180717132126-cdb49ff09d77/go.mod h1:5ELEyG+X8f+meRWHuqUOewBOhvHkl7M76pdGEansxW4= +github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= +github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= +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.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-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.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/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= +github.com/mattn/go-isatty v0.0.17/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.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.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= +github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +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= +github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +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.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= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +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= +github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU= +github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mwitkow/grpc-proxy v0.0.0-20181017164139-0f1106ef9c76/go.mod h1:x5OoJHDHqxHS801UIuhqGl6QdSAEJvtausosHSdazIo= +github.com/naoina/go-stringutil v0.1.0/go.mod h1:XJ2SJL9jCtBh+P9q5btrd/Ylo8XwT/h1USek5+NqSA0= +github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416/go.mod h1:NBIhNtsFMo3G2szEBne+bO4gS192HuIYRqfvOWb4i1E= +github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= +github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= +github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k= +github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= +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/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= +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/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= +github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= +github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= +github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.26.0 h1:03cDLK28U6hWvCAns6NeydX3zIm4SF3ci69ulidS32Q= +github.com/onsi/gomega v1.26.0/go.mod h1:r+zV744Re+DiYCIPRlYOTxn0YkOLcAnW8k1xXdMPGhM= +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.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= +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/osmosis-labs/cosmos-sdk v0.45.1-0.20230326212251-7a2cf2993434 h1:RetElHdhDl6f00Tjj7ii2r+HX2aa/u+dhgwQb5hKv8Y= +github.com/osmosis-labs/cosmos-sdk v0.45.1-0.20230326212251-7a2cf2993434/go.mod h1:ss3tUfPTwaa6NsoPZrCR7xOqLqCK0LwoNbc2Q8Zs5/Y= +github.com/otiai10/copy v1.7.0 h1:hVoPiN+t+7d2nzzwMiDHPSOogsWAStewq3TwU05+clE= +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 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/v2 v2.0.6 h1:nrzqCb7j9cDFj2coyLNLaZuJTLjWjlaz6nvTvIwycIU= +github.com/pelletier/go-toml/v2 v2.0.6/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek= +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= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +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= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= +github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= +github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= +github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= +github.com/prometheus/client_golang v1.15.0 h1:5fCgGYogn0hFdhyhLbw7hEsWxufKtY9klyvdNfFlFhM= +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/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= +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= +github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= +github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= +github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.3.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI= +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= +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= +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.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= +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/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= +github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +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.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/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= +github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +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.3 h1:41FoI0fD7OR7mGcKE/aOiLkGreyf8ifIOQmJANWogMk= +github.com/spf13/afero v1.9.3/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= +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.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= +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= +github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +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.15.0 h1:js3yy885G8xwJa6iOISGFwd+qlUo5AvyXb7CiihdtiU= +github.com/spf13/viper v1.15.0/go.mod h1:fFcTBJxvhhzSJiZy8n+PeW6t8l+KeT/uTARa0jHOQLA= +github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4/go.mod h1:RZLeN1LMWmRsyYjvAu+I6Dm9QmlDaIIt+Y+4Kd7Tp+Q= +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/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= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +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/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= +github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= +github.com/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/tm-db v0.6.8-0.20220506192307-f628bb5dc95b h1:Y3ZPG6gdDCAV2sdGkD759ji/09GzaNu1X3qKTmZIbTo= +github.com/tendermint/tm-db v0.6.8-0.20220506192307-f628bb5dc95b/go.mod h1:ADqbS9NOSnBRK9R2RtYC61CdsHmVMD/yXAzcMuPexbU= +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= +github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs= +github.com/tyler-smith/go-bip39 v1.0.2/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs= +github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= +github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= +github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= +github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= +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/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.1 h1:gQe66rtmyZ8VeGFcOpbuH3r7erYtNEAezCAYu8LdkJo= +github.com/zondax/hid v0.9.1/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= +github.com/zondax/ledger-go v0.14.1 h1:Pip65OOl4iJ84WTpA4BKChvOufMhhbxED3BaihoZN4c= +github.com/zondax/ledger-go v0.14.1/go.mod h1:fZ3Dqg6qcdXWSOJFKMG8GCTnD7slO/RL2feOQv8K320= +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= +go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= +go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= +go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +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.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= +go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= +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= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190909091759-094676da4a83/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +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.5.0 h1:U/0M97KRkSFvyD/3FSmdP5W5swImpNgle/EHFhOsQPE= +golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU= +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-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= +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= +golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= +golang.org/x/exp v0.0.0-20230131160201-f062dba9d201 h1:BEABXpNXLEz0WxtA+6CQIz2xkg80e+1zrhWyMcq8VzE= +golang.org/x/exp v0.0.0-20230131160201-f062dba9d201/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= +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= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +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/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/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.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk= +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-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= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200421231249-e086a090c8fd/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +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-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-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/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.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM= +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= +golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +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/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= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +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/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= +golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +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= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +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= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +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= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +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-20200905004654-be1d3432aa8f/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= +golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210112080510-489259a85091/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-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210316164454-77fc1eacc6aa/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-20210615035016-665e8c7367d1/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-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-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-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU= +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.7.0 h1:BEvjmm5fURWqcfbSKTdpkDXYBrUS1c0m8agp14W48vQ= +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= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +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/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= +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= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200108203644-89082a384178/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-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= +golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= +golang.org/x/tools v0.0.0-20201022035929-9cf592e881e9/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +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.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.8.0 h1:vSDcovVPld282ceKgDimkRSC8kpaH1dgyc9UMzlt84Y= +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= +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= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= +google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= +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/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/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= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +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= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +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= +google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200324203455-a04cca1dde73/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= +google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +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-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20230125152338-dcaf20b6aeaa h1:qQPhfbPO23fwm/9lQr91L1u62Zo6cm+zI+slZT+uf+o= +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= +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= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= +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.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= +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/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/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= +gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= +gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c= +gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200619000410-60c24ae608a6/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns= +gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/urfave/cli.v1 v1.20.0/go.mod h1:vuBzUtMdQeixQj8LVd+/98pzhxNGQoyuPBlsXHOQNO0= +gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= +gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +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/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= +nhooyr.io/websocket v1.8.7 h1:usjR2uOr/zjjkVMy0lW+PPohFok7PCow5sDjLgX4P4g= +nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= +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= +sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= diff --git a/osmoutils/ibc.go b/osmoutils/ibc.go new file mode 100644 index 000000000..72ddedac3 --- /dev/null +++ b/osmoutils/ibc.go @@ -0,0 +1,70 @@ +package osmoutils + +import ( + "encoding/json" + sdk "github.com/cosmos/cosmos-sdk/types" + transfertypes "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types" + channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" + ibcexported "github.com/cosmos/ibc-go/v4/modules/core/exported" +) + +// NewEmitErrorAcknowledgement creates a new error acknowledgement after having emitted an event with the +// details of the error. +func NewEmitErrorAcknowledgement(ctx sdk.Context, err error, errorContexts ...string) channeltypes.Acknowledgement { + attributes := make([]sdk.Attribute, len(errorContexts)+1) + attributes[0] = sdk.NewAttribute("error", err.Error()) + for i, s := range errorContexts { + attributes[i+1] = sdk.NewAttribute("error-context", s) + } + + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + "ibc-acknowledgement-error", + attributes..., + ), + }) + + return channeltypes.NewErrorAcknowledgement(err) +} + +// MustExtractDenomFromPacketOnRecv takes a packet with a valid ICS20 token data in the Data field and returns the +// denom as represented in the local chain. +// If the data cannot be unmarshalled this function will panic +func MustExtractDenomFromPacketOnRecv(packet ibcexported.PacketI) string { + var data transfertypes.FungibleTokenPacketData + if err := json.Unmarshal(packet.GetData(), &data); err != nil { + panic("unable to unmarshal ICS20 packet data") + } + + var denom string + if transfertypes.ReceiverChainIsSource(packet.GetSourcePort(), packet.GetSourceChannel(), data.Denom) { + // remove prefix added by sender chain + voucherPrefix := transfertypes.GetDenomPrefix(packet.GetSourcePort(), packet.GetSourceChannel()) + + unprefixedDenom := data.Denom[len(voucherPrefix):] + + // coin denomination used in sending from the escrow address + denom = unprefixedDenom + + // The denomination used to send the coins is either the native denom or the hash of the path + // if the denomination is not native. + denomTrace := transfertypes.ParseDenomTrace(unprefixedDenom) + if denomTrace.Path != "" { + denom = denomTrace.IBCDenom() + } + } else { + prefixedDenom := transfertypes.GetDenomPrefix(packet.GetDestPort(), packet.GetDestChannel()) + data.Denom + denom = transfertypes.ParseDenomTrace(prefixedDenom).IBCDenom() + } + return denom +} + +// IsAckError checks an IBC acknowledgement to see if it's an error. +// This is a replacement for ack.Success() which is currently not working on some circumstances +func IsAckError(acknowledgement []byte) bool { + var ackErr channeltypes.Acknowledgement_Error + if err := json.Unmarshal(acknowledgement, &ackErr); err == nil && len(ackErr.Error) > 0 { + return true + } + return false +} diff --git a/osmoutils/module_account.go b/osmoutils/module_account.go new file mode 100644 index 000000000..661047e94 --- /dev/null +++ b/osmoutils/module_account.go @@ -0,0 +1,86 @@ +package osmoutils + +import ( + "errors" + "fmt" + "reflect" + + sdk "github.com/cosmos/cosmos-sdk/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + vestingtypes "github.com/cosmos/cosmos-sdk/x/auth/vesting/types" +) + +// OsmoUtilsExtraAccountTypes is a map of extra account types that can be overridden. +// This is defined as a global variable so it can be modified in the chain's app.go and used here without +// having to import the chain. Specifically, this is used for compatibility with Osmosis' Cosmos SDK fork +var OsmoUtilsExtraAccountTypes map[reflect.Type]struct{} + +type AccountKeeper interface { + NewAccount(sdk.Context, authtypes.AccountI) authtypes.AccountI + + GetAccount(ctx sdk.Context, addr sdk.AccAddress) authtypes.AccountI + SetAccount(ctx sdk.Context, acc authtypes.AccountI) +} + +// CanCreateModuleAccountAtAddr tells us if we can safely make a module account at +// a given address. By collision resistance of the address (given API safe construction), +// the only way for an account to be already be at this address is if its claimed by the same +// pre-image from the correct module, +// or some SDK command breaks assumptions and creates an account at designated address. +// This function checks if there is an account at that address, and runs some safety checks +// to be extra-sure its not a user account (e.g. non-zero sequence, pubkey, of fore-seen account types). +// If there is no account, or if we believe its not a user-spendable account, we allow module account +// creation at the address. +// else, we do not. +// +// TODO: This is generally from an SDK design flaw +// code based off wasmd code: https://github.com/CosmWasm/wasmd/pull/996 +// Its _mandatory_ that the caller do the API safe construction to generate a module account addr, +// namely, address.Module(ModuleName, {key}) +func CanCreateModuleAccountAtAddr(ctx sdk.Context, ak AccountKeeper, addr sdk.AccAddress) error { + existingAcct := ak.GetAccount(ctx, addr) + if existingAcct == nil { + return nil + } + if existingAcct.GetSequence() != 0 || existingAcct.GetPubKey() != nil { + return fmt.Errorf("cannot create module account %s, "+ + "due to an account at that address already existing & having sent txs", addr) + } + overrideAccountTypes := map[reflect.Type]struct{}{ + reflect.TypeOf(&authtypes.BaseAccount{}): {}, + reflect.TypeOf(&vestingtypes.DelayedVestingAccount{}): {}, + reflect.TypeOf(&vestingtypes.ContinuousVestingAccount{}): {}, + reflect.TypeOf(&vestingtypes.BaseVestingAccount{}): {}, + reflect.TypeOf(&vestingtypes.PeriodicVestingAccount{}): {}, + reflect.TypeOf(&vestingtypes.PermanentLockedAccount{}): {}, + } + for extraAccountType := range OsmoUtilsExtraAccountTypes { + overrideAccountTypes[extraAccountType] = struct{}{} + } + + if _, clear := overrideAccountTypes[reflect.TypeOf(existingAcct)]; clear { + return nil + } + return errors.New("cannot create module account %s, " + + "due to an account at that address already existing & not being an overrideable type") +} + +// CreateModuleAccount creates a module account at the provided address. +// It overrides an account if it exists at that address, with a non-zero sequence number & pubkey +// Contract: addr is derived from `address.Module(ModuleName, key)` +func CreateModuleAccount(ctx sdk.Context, ak AccountKeeper, addr sdk.AccAddress) error { + err := CanCreateModuleAccountAtAddr(ctx, ak, addr) + if err != nil { + return err + } + + acc := ak.NewAccount( + ctx, + authtypes.NewModuleAccount( + authtypes.NewBaseAccountWithAddress(addr), + addr.String(), + ), + ) + ak.SetAccount(ctx, acc) + return nil +} diff --git a/osmoutils/module_account_test.go b/osmoutils/module_account_test.go new file mode 100644 index 000000000..1119812ef --- /dev/null +++ b/osmoutils/module_account_test.go @@ -0,0 +1,66 @@ +package osmoutils_test + +import ( + "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/address" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + + "github.com/CosmosContracts/juno/v15/osmoutils" + "github.com/CosmosContracts/juno/v15/osmoutils/osmoassert" +) + +func (s *TestSuite) TestCreateModuleAccount() { + baseWithAddr := func(addr sdk.AccAddress) authtypes.AccountI { + acc := authtypes.ProtoBaseAccount() + acc.SetAddress(addr) + return acc + } + userAccViaSeqnum := func(addr sdk.AccAddress) authtypes.AccountI { + base := baseWithAddr(addr) + base.SetSequence(2) + return base + } + userAccViaPubkey := func(addr sdk.AccAddress) authtypes.AccountI { + base := baseWithAddr(addr) + base.SetPubKey(secp256k1.GenPrivKey().PubKey()) + return base + } + defaultModuleAccAddr := address.Module("dummy module", []byte{1}) + testcases := map[string]struct { + priorAccounts []authtypes.AccountI + moduleAccAddr sdk.AccAddress + expErr bool + }{ + "no prior acc": { + priorAccounts: []authtypes.AccountI{}, + moduleAccAddr: defaultModuleAccAddr, + expErr: false, + }, + "prior empty acc at addr": { + priorAccounts: []authtypes.AccountI{baseWithAddr(defaultModuleAccAddr)}, + moduleAccAddr: defaultModuleAccAddr, + expErr: false, + }, + "prior user acc at addr (sequence)": { + priorAccounts: []authtypes.AccountI{userAccViaSeqnum(defaultModuleAccAddr)}, + moduleAccAddr: defaultModuleAccAddr, + expErr: true, + }, + "prior user acc at addr (pubkey)": { + priorAccounts: []authtypes.AccountI{userAccViaPubkey(defaultModuleAccAddr)}, + moduleAccAddr: defaultModuleAccAddr, + expErr: true, + }, + } + for name, tc := range testcases { + s.Run(name, func() { + s.SetupTest() + for _, priorAcc := range tc.priorAccounts { + s.accountKeeper.SetAccount(s.ctx, priorAcc) + } + err := osmoutils.CreateModuleAccount(s.ctx, s.accountKeeper, tc.moduleAccAddr) + osmoassert.ConditionalError(s.T(), tc.expErr, err) + }) + } +} diff --git a/osmoutils/noapptest/cdc.go b/osmoutils/noapptest/cdc.go new file mode 100644 index 000000000..8f9a25905 --- /dev/null +++ b/osmoutils/noapptest/cdc.go @@ -0,0 +1,45 @@ +package noapptest + +// NOTE: This file is pulled from the SDK: +// https://github.com/cosmos/cosmos-sdk/blob/2eb51447494163bc9beef1b2cc8aa91c3691b2a7/types/module/testutil/codec.go#L23 +import ( + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/codec/types" + "github.com/cosmos/cosmos-sdk/std" + "github.com/cosmos/cosmos-sdk/types/module" + "github.com/cosmos/cosmos-sdk/x/auth/tx" +) + +// TestEncodingConfig defines an encoding configuration that is used for testing +// purposes. Note, MakeTestEncodingConfig takes a series of AppModuleBasic types +// which should only contain the relevant module being tested and any potential +// dependencies. +type TestEncodingConfig struct { + InterfaceRegistry types.InterfaceRegistry + Codec codec.Codec + TxConfig client.TxConfig + Amino *codec.LegacyAmino +} + +func MakeTestEncodingConfig(modules ...module.AppModuleBasic) TestEncodingConfig { + cdc := codec.NewLegacyAmino() + interfaceRegistry := types.NewInterfaceRegistry() + codec := codec.NewProtoCodec(interfaceRegistry) + + encCfg := TestEncodingConfig{ + InterfaceRegistry: interfaceRegistry, + Codec: codec, + TxConfig: tx.NewTxConfig(codec, tx.DefaultSignModes), + Amino: cdc, + } + + mb := module.NewBasicManager(modules...) + + std.RegisterLegacyAminoCodec(encCfg.Amino) + std.RegisterInterfaces(encCfg.InterfaceRegistry) + mb.RegisterLegacyAminoCodec(encCfg.Amino) + mb.RegisterInterfaces(encCfg.InterfaceRegistry) + + return encCfg +} diff --git a/osmoutils/noapptest/ctx.go b/osmoutils/noapptest/ctx.go new file mode 100644 index 000000000..834cf6797 --- /dev/null +++ b/osmoutils/noapptest/ctx.go @@ -0,0 +1,32 @@ +package noapptest + +import ( + "time" + + "github.com/cosmos/cosmos-sdk/store" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/tendermint/tendermint/libs/log" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + + dbm "github.com/tendermint/tm-db" +) + +func CtxWithStoreKeys(keys []sdk.StoreKey, header tmproto.Header, isCheckTx bool) sdk.Context { + db := dbm.NewMemDB() + logger := log.NewNopLogger() + cms := store.NewCommitMultiStore(db, logger) + for _, key := range keys { + cms.MountStoreWithDB(key, sdk.StoreTypeIAVL, nil) + } + err := cms.LoadLatestVersion() + if err != nil { + panic(err) + } + return sdk.NewContext(cms, header, isCheckTx, logger) +} + +func DefaultCtxWithStoreKeys(storeKeys []sdk.StoreKey) sdk.Context { + header := tmproto.Header{Height: 1, ChainID: "osmoutils-test-1", Time: time.Now().UTC()} + deliverTx := false + return CtxWithStoreKeys(storeKeys, header, deliverTx) +} diff --git a/osmoutils/osmoassert/assertions.go b/osmoutils/osmoassert/assertions.go new file mode 100644 index 000000000..aad23e991 --- /dev/null +++ b/osmoutils/osmoassert/assertions.go @@ -0,0 +1,60 @@ +package osmoassert + +import ( + "fmt" + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/require" +) + +// ConditionalPanic checks if expectPanic is true, asserts that sut (system under test) +// panics. If expectPanic is false, asserts that sut does not panic. +// returns true if sut panics and false it it does not +func ConditionalPanic(t *testing.T, expectPanic bool, sut func()) { + if expectPanic { + require.Panics(t, sut) + return + } + require.NotPanics(t, sut) +} + +// ConditionalError checks if expectError is true, asserts that err is an error +// If expectError is false, asserts that err is nil +func ConditionalError(t *testing.T, expectError bool, err error) { + if expectError { + require.Error(t, err) + return + } + require.NoError(t, err) +} + +// DecApproxEq is a helper function to compare two decimals. +// It validates the two decimal are within a certain tolerance. +// If not, it fails with a message. +func DecApproxEq(t *testing.T, d1 sdk.Dec, d2 sdk.Dec, tol sdk.Dec, msgAndArgs ...interface{}) { + diff := d1.Sub(d2).Abs() + msg := messageFromMsgAndArgs(msgAndArgs...) + require.True(t, diff.LTE(tol), "expected |d1 - d2| <:\t%s\ngot |d1 - d2| = \t\t%s\nd1: %s, d2: %s\n%s", tol, diff, d1, d2, msg) +} + +func messageFromMsgAndArgs(msgAndArgs ...interface{}) string { + if len(msgAndArgs) == 0 || msgAndArgs == nil { + return "" + } + if len(msgAndArgs) == 1 { + msg := msgAndArgs[0] + if msgAsStr, ok := msg.(string); ok { + return msgAsStr + } + return fmt.Sprintf("%+v", msg) + } + if len(msgAndArgs) > 1 { + msgFormat, ok := msgAndArgs[0].(string) + if !ok { + return "error formatting additional arguments for DecApproxEq, please disregard." + } + return fmt.Sprintf(msgFormat, msgAndArgs[1:]...) + } + return "" +} diff --git a/osmoutils/osmocli/cli_tester.go b/osmoutils/osmocli/cli_tester.go new file mode 100644 index 000000000..4ef6aaf9b --- /dev/null +++ b/osmoutils/osmocli/cli_tester.go @@ -0,0 +1,111 @@ +package osmocli + +import ( + "strings" + "testing" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/gogo/protobuf/proto" + "github.com/spf13/cobra" + "github.com/spf13/pflag" + "github.com/stretchr/testify/require" +) + +type TxCliTestCase[M sdk.Msg] struct { + Cmd string + ExpectedMsg M + ExpectedErr bool + OnlyCheckValidateBasic bool +} + +type QueryCliTestCase[Q proto.Message] struct { + Cmd string + ExpectedQuery Q + ExpectedErr bool +} + +func RunTxTestCases[M sdk.Msg](t *testing.T, desc *TxCliDesc, testcases map[string]TxCliTestCase[M]) { + for name, tc := range testcases { + t.Run(name, func(t *testing.T) { + RunTxTestCase(t, desc, &tc) + }) + } +} + +func RunQueryTestCases[Q proto.Message](t *testing.T, desc *QueryDescriptor, testcases map[string]QueryCliTestCase[Q]) { + for name, tc := range testcases { + t.Run(name, func(t *testing.T) { + RunQueryTestCase(t, desc, &tc) + }) + } +} + +func RunTxTestCase[M sdk.Msg](t *testing.T, desc *TxCliDesc, tc *TxCliTestCase[M]) { + cmd := BuildTxCli[M](desc) + err := resetCommandFlagValues(cmd) + require.NoError(t, err, "error in resetCommandFlagValues") + args := strings.Split(tc.Cmd, " ") + err = cmd.Flags().Parse(args) + require.NoError(t, err, "error in cmd.Flags().Parse(args)") + clientCtx := newClientContextWithFrom(t, cmd.Flags()) + + msg, err := desc.ParseAndBuildMsg(clientCtx, args, cmd.Flags()) + if tc.ExpectedErr { + require.Error(t, err) + return + } + require.NoError(t, err, "error in desc.ParseAndBuildMsg") + if tc.OnlyCheckValidateBasic { + require.NoError(t, msg.ValidateBasic()) + return + } + + require.Equal(t, tc.ExpectedMsg, msg) +} + +func RunQueryTestCase[Q proto.Message](t *testing.T, desc *QueryDescriptor, tc *QueryCliTestCase[Q]) { + cmd := BuildQueryCli[Q, int](desc, nil) + err := resetCommandFlagValues(cmd) + require.NoError(t, err, "error in resetCommandFlagValues") + args := strings.Split(tc.Cmd, " ") + err = cmd.Flags().Parse(args) + require.NoError(t, err, "error in cmd.Flags().Parse(args)") + + req, err := desc.ParseQuery(args, cmd.Flags()) + if tc.ExpectedErr { + require.Error(t, err) + return + } + require.NoError(t, err, "error in desc.ParseQuery") + require.Equal(t, tc.ExpectedQuery, req) +} + +// This logic is copied from the SDK, it should've just been publicly exposed. +// But instead its buried within a mega-method. +func newClientContextWithFrom(t *testing.T, fs *pflag.FlagSet) client.Context { + clientCtx := client.Context{} + from, _ := fs.GetString(flags.FlagFrom) + fromAddr, fromName, _, err := client.GetFromFields(nil, from, true) + require.NoError(t, err) + + clientCtx = clientCtx.WithFrom(from).WithFromAddress(fromAddr).WithFromName(fromName) + return clientCtx +} + +// taken from https://github.com/golang/debug/pull/8, +// due to no cobra command for resetting flag value +func resetCommandFlagValues(cmd *cobra.Command) error { + var retErr error = nil + cmd.Flags().VisitAll(func(f *pflag.Flag) { + if f.Changed { + err := f.Value.Set(f.DefValue) + if err != nil { + retErr = err + } + f.Changed = false + } + }) + return retErr +} diff --git a/osmoutils/osmocli/flag_advice.go b/osmoutils/osmocli/flag_advice.go new file mode 100644 index 000000000..11da922a3 --- /dev/null +++ b/osmoutils/osmocli/flag_advice.go @@ -0,0 +1,79 @@ +package osmocli + +import ( + "strings" + + "github.com/spf13/cobra" + "github.com/spf13/pflag" +) + +type FlagAdvice struct { + HasPagination bool + + // Map of FieldName -> FlagName + CustomFlagOverrides map[string]string + CustomFieldParsers map[string]CustomFieldParserFn + + // Tx sender value + IsTx bool + TxSenderFieldName string + FromValue string +} + +type FlagDesc struct { + RequiredFlags []*pflag.FlagSet + OptionalFlags []*pflag.FlagSet +} + +type FieldReadLocation = bool + +const ( + UsedArg FieldReadLocation = true + UsedFlag FieldReadLocation = false +) + +// CustomFieldParser function. +type CustomFieldParserFn = func(arg string, flags *pflag.FlagSet) (valueToSet any, usedArg FieldReadLocation, err error) + +func (f FlagAdvice) Sanitize() FlagAdvice { + // map CustomFlagOverrides & CustomFieldParser keys to lower-case + // initialize if uninitialized + newFlagOverrides := make(map[string]string, len(f.CustomFlagOverrides)) + for k, v := range f.CustomFlagOverrides { + newFlagOverrides[strings.ToLower(k)] = v + } + f.CustomFlagOverrides = newFlagOverrides + newFlagParsers := make(map[string]CustomFieldParserFn, len(f.CustomFieldParsers)) + for k, v := range f.CustomFieldParsers { + newFlagParsers[strings.ToLower(k)] = v + } + f.CustomFieldParsers = newFlagParsers + return f +} + +func FlagOnlyParser[v any](f func(fs *pflag.FlagSet) (v, error)) CustomFieldParserFn { + return func(_arg string, fs *pflag.FlagSet) (any, FieldReadLocation, error) { + t, err := f(fs) + return t, UsedFlag, err + } +} + +// AddFlags from desc to cmd. +// Required flags are marked as required. +func AddFlags(cmd *cobra.Command, desc FlagDesc) { + for i := 0; i < len(desc.OptionalFlags); i++ { + cmd.Flags().AddFlagSet(desc.OptionalFlags[i]) + } + for i := 0; i < len(desc.RequiredFlags); i++ { + fs := desc.RequiredFlags[i] + cmd.Flags().AddFlagSet(fs) + + // mark all these flags as required. + fs.VisitAll(func(flag *pflag.Flag) { + err := cmd.MarkFlagRequired(flag.Name) + if err != nil { + panic(err) + } + }) + } +} diff --git a/osmoutils/osmocli/index_cmd.go b/osmoutils/osmocli/index_cmd.go new file mode 100644 index 000000000..b1d3f0da1 --- /dev/null +++ b/osmoutils/osmocli/index_cmd.go @@ -0,0 +1,31 @@ +package osmocli + +import ( + "fmt" + + "github.com/spf13/cobra" +) + +// Index command, but short is not set. That is left to caller. +func IndexCmd(moduleName string) *cobra.Command { + return &cobra.Command{ + Use: moduleName, + Short: fmt.Sprintf("Querying commands for the %s module", moduleName), + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + RunE: indexRunCmd, + } +} + +func indexRunCmd(cmd *cobra.Command, args []string) error { + usageTemplate := `Usage:{{if .HasAvailableSubCommands}} + {{.CommandPath}} [command]{{end}} + +{{if .HasAvailableSubCommands}}Available Commands:{{range .Commands}}{{if .IsAvailableCommand}} + {{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}} + +Use "{{.CommandPath}} [command] --help" for more information about a command.{{end}} +` + cmd.SetUsageTemplate(usageTemplate) + return cmd.Help() +} diff --git a/osmoutils/osmocli/parsers.go b/osmoutils/osmocli/parsers.go new file mode 100644 index 000000000..0ec5f4941 --- /dev/null +++ b/osmoutils/osmocli/parsers.go @@ -0,0 +1,343 @@ +package osmocli + +import ( + "fmt" + "reflect" + "strconv" + "strings" + "time" + + "github.com/cosmos/cosmos-sdk/client" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/spf13/pflag" + + "github.com/CosmosContracts/juno/v15/osmoutils" +) + +// Parses arguments 1-1 from args +// makes an exception, where it allows Pagination to come from flags. +func ParseFieldsFromFlagsAndArgs[reqP any](flagAdvice FlagAdvice, flags *pflag.FlagSet, args []string) (reqP, error) { + req := osmoutils.MakeNew[reqP]() + v := reflect.ValueOf(req).Elem() + t := v.Type() + + argIndexOffset := 0 + // Iterate over the fields in the struct + for i := 0; i < t.NumField(); i++ { + arg := "" + if len(args) > i+argIndexOffset { + arg = args[i+argIndexOffset] + } + usedArg, err := ParseField(v, t, i, arg, flagAdvice, flags) + if err != nil { + return req, err + } + if !usedArg { + argIndexOffset -= 1 + } + } + return req, nil +} + +func ParseNumFields[reqP any]() int { + req := osmoutils.MakeNew[reqP]() + v := reflect.ValueOf(req).Elem() + t := v.Type() + return t.NumField() +} + +func ParseExpectedQueryFnName[reqP any]() string { + req := osmoutils.MakeNew[reqP]() + v := reflect.ValueOf(req).Elem() + s := v.Type().String() + // handle some non-std queries + var prefixTrimmed string + if strings.Contains(s, "Query") { + prefixTrimmed = strings.Split(s, "Query")[1] + } else { + prefixTrimmed = strings.Split(s, ".")[1] + } + suffixTrimmed := strings.TrimSuffix(prefixTrimmed, "Request") + return suffixTrimmed +} + +func ParseHasPagination[reqP any]() bool { + req := osmoutils.MakeNew[reqP]() + t := reflect.ValueOf(req).Elem().Type() + for i := 0; i < t.NumField(); i++ { + fType := t.Field(i) + if fType.Type.String() == paginationType { + return true + } + } + return false +} + +const paginationType = "*query.PageRequest" + +// ParseField parses field #fieldIndex from either an arg or a flag. +// Returns true if it was parsed from an argument. +// Returns error if there was an issue in parsing this field. +func ParseField(v reflect.Value, t reflect.Type, fieldIndex int, arg string, flagAdvice FlagAdvice, flags *pflag.FlagSet) (bool, error) { + fVal := v.Field(fieldIndex) + fType := t.Field(fieldIndex) + // fmt.Printf("Field %d: %s %s %s\n", fieldIndex, fType.Name, fType.Type, fType.Type.Kind()) + + lowercaseFieldNameStr := strings.ToLower(fType.Name) + if parseFn, ok := flagAdvice.CustomFieldParsers[lowercaseFieldNameStr]; ok { + v, usedArg, err := parseFn(arg, flags) + if err == nil { + fVal.Set(reflect.ValueOf(v)) + } + return usedArg, err + } + + parsedFromFlag, err := ParseFieldFromFlag(fVal, fType, flagAdvice, flags) + if err != nil { + return false, err + } + if parsedFromFlag { + return false, nil + } + return true, ParseFieldFromArg(fVal, fType, arg) +} + +// ParseFieldFromFlag attempts to parses the value of a field in a struct from a flag. +// The field is identified by the provided `reflect.StructField`. +// The flag advice and `pflag.FlagSet` are used to determine the flag to parse the field from. +// If the field corresponds to a value from a flag, true is returned. +// Otherwise, `false` is returned. +// In the true case, the parsed value is set on the provided `reflect.Value`. +// An error is returned if there is an issue parsing the field from the flag. +func ParseFieldFromFlag(fVal reflect.Value, fType reflect.StructField, flagAdvice FlagAdvice, flags *pflag.FlagSet) (bool, error) { + lowercaseFieldNameStr := strings.ToLower(fType.Name) + if flagName, ok := flagAdvice.CustomFlagOverrides[lowercaseFieldNameStr]; ok { + return true, parseFieldFromDirectlySetFlag(fVal, fType, flagAdvice, flagName, flags) + } + + kind := fType.Type.Kind() + switch kind { + case reflect.String: + if flagAdvice.IsTx { + // matchesFieldName is true if lowercaseFieldNameStr is the same as TxSenderFieldName, + // or if TxSenderFieldName is left blank, then matches fields named "sender" or "owner" + matchesFieldName := (flagAdvice.TxSenderFieldName == lowercaseFieldNameStr) || + (flagAdvice.TxSenderFieldName == "" && (lowercaseFieldNameStr == "sender" || lowercaseFieldNameStr == "owner")) + if matchesFieldName { + fVal.SetString(flagAdvice.FromValue) + return true, nil + } + } + case reflect.Ptr: + if flagAdvice.HasPagination { + typeStr := fType.Type.String() + if typeStr == paginationType { + pageReq, err := client.ReadPageRequest(flags) + if err != nil { + return true, err + } + fVal.Set(reflect.ValueOf(pageReq)) + return true, nil + } + } + } + return false, nil +} + +func parseFieldFromDirectlySetFlag(fVal reflect.Value, fType reflect.StructField, flagAdvice FlagAdvice, flagName string, flags *pflag.FlagSet) error { + // get string. If its a string great, run through arg parser. Otherwise try setting directly + s, err := flags.GetString(flagName) + if err != nil { + flag := flags.Lookup(flagName) + if flag == nil { + return fmt.Errorf("Programmer set the flag name wrong. Flag %s does not exist", flagName) + } + t := flag.Value.Type() + if t == "uint64" { + u, err := flags.GetUint64(flagName) + if err != nil { + return err + } + fVal.SetUint(u) + return nil + } + } + return ParseFieldFromArg(fVal, fType, s) +} + +func ParseFieldFromArg(fVal reflect.Value, fType reflect.StructField, arg string) error { + // We cant pass in a negative number due to the way pflags works... + // This is an (extraordinarily ridiculous) workaround that checks if a negative int is encapsulated in square brackets, + // and if so, trims the square brackets + if strings.HasPrefix(arg, "[") && strings.HasSuffix(arg, "]") && arg[1] == '-' { + arg = strings.TrimPrefix(arg, "[") + arg = strings.TrimSuffix(arg, "]") + } + + switch fType.Type.Kind() { + // SetUint allows anyof type u8, u16, u32, u64, and uint + case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint: + u, err := ParseUint(arg, fType.Name) + if err != nil { + return err + } + fVal.SetUint(u) + return nil + // SetInt allows anyof type i8,i16,i32,i64 and int + case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int: + typeStr := fType.Type.String() + var i int64 + var err error + if typeStr == "time.Duration" { + dur, err2 := time.ParseDuration(arg) + i, err = int64(dur), err2 + } else { + i, err = ParseInt(arg, fType.Name) + } + if err != nil { + return err + } + fVal.SetInt(i) + return nil + case reflect.Float32, reflect.Float64: + typeStr := fType.Type.String() + f, err := ParseFloat(arg, typeStr) + if err != nil { + return err + } + fVal.SetFloat(f) + return nil + case reflect.String: + s, err := ParseDenom(arg, fType.Name) + if err != nil { + return err + } + fVal.SetString(s) + return nil + case reflect.Ptr: + case reflect.Slice: + typeStr := fType.Type.String() + if typeStr == "[]uint64" { + // Parse comma-separated uint64 values into []uint64 slice + strValues := strings.Split(arg, ",") + values := make([]uint64, len(strValues)) + for i, strValue := range strValues { + u, err := strconv.ParseUint(strValue, 10, 64) + if err != nil { + return err + } + values[i] = u + } + fVal.Set(reflect.ValueOf(values)) + return nil + } + if typeStr == "types.Coins" { + coins, err := ParseCoins(arg, fType.Name) + if err != nil { + return err + } + fVal.Set(reflect.ValueOf(coins)) + return nil + } + case reflect.Struct: + typeStr := fType.Type.String() + var v any + var err error + if typeStr == "types.Coin" { + v, err = ParseCoin(arg, fType.Name) + } else if typeStr == "types.Int" { + v, err = ParseSdkInt(arg, fType.Name) + } else if typeStr == "time.Time" { + v, err = ParseUnixTime(arg, fType.Name) + } else if typeStr == "types.Dec" { + v, err = ParseSdkDec(arg, fType.Name) + } else { + return fmt.Errorf("struct field type not recognized. Got type %v", fType) + } + + if err != nil { + return err + } + fVal.Set(reflect.ValueOf(v)) + return nil + } + fmt.Println(fType.Type.Kind().String()) + return fmt.Errorf("field type not recognized. Got type %v", fType) +} + +func ParseUint(arg string, fieldName string) (uint64, error) { + v, err := strconv.ParseUint(arg, 10, 64) + if err != nil { + return 0, fmt.Errorf("could not parse %s as uint for field %s: %w", arg, fieldName, err) + } + return v, nil +} + +func ParseFloat(arg string, fieldName string) (float64, error) { + v, err := strconv.ParseFloat(arg, 64) + if err != nil { + return 0, fmt.Errorf("could not parse %s as float for field %s: %w", arg, fieldName, err) + } + return v, nil +} + +func ParseInt(arg string, fieldName string) (int64, error) { + v, err := strconv.ParseInt(arg, 10, 64) + if err != nil { + return 0, fmt.Errorf("could not parse %s as int for field %s: %w", arg, fieldName, err) + } + return v, nil +} + +func ParseUnixTime(arg string, fieldName string) (time.Time, error) { + timeUnix, err := strconv.ParseInt(arg, 10, 64) + if err != nil { + parsedTime, err := time.Parse(sdk.SortableTimeFormat, arg) + if err != nil { + return time.Time{}, fmt.Errorf("could not parse %s as time for field %s: %w", arg, fieldName, err) + } + + return parsedTime, nil + } + startTime := time.Unix(timeUnix, 0) + return startTime, nil +} + +func ParseDenom(arg string, fieldName string) (string, error) { + return strings.TrimSpace(arg), nil +} + +// TODO: Make this able to read from some local alias file for denoms. +func ParseCoin(arg string, fieldName string) (sdk.Coin, error) { + coin, err := sdk.ParseCoinNormalized(arg) + if err != nil { + return sdk.Coin{}, fmt.Errorf("could not parse %s as sdk.Coin for field %s: %w", arg, fieldName, err) + } + return coin, nil +} + +// TODO: Make this able to read from some local alias file for denoms. +func ParseCoins(arg string, fieldName string) (sdk.Coins, error) { + coins, err := sdk.ParseCoinsNormalized(arg) + if err != nil { + return sdk.Coins{}, fmt.Errorf("could not parse %s as sdk.Coins for field %s: %w", arg, fieldName, err) + } + return coins, nil +} + +// TODO: This really shouldn't be getting used in the CLI, its misdesign on the CLI ux +func ParseSdkInt(arg string, fieldName string) (sdk.Int, error) { + i, ok := sdk.NewIntFromString(arg) + if !ok { + return sdk.Int{}, fmt.Errorf("could not parse %s as sdk.Int for field %s", arg, fieldName) + } + return i, nil +} + +func ParseSdkDec(arg, fieldName string) (sdk.Dec, error) { + i, err := sdk.NewDecFromStr(arg) + if err != nil { + return sdk.Dec{}, fmt.Errorf("could not parse %s as sdk.Dec for field %s: %w", arg, fieldName, err) + } + return i, nil +} diff --git a/osmoutils/osmocli/parsers_test.go b/osmoutils/osmocli/parsers_test.go new file mode 100644 index 000000000..181af5174 --- /dev/null +++ b/osmoutils/osmocli/parsers_test.go @@ -0,0 +1,166 @@ +package osmocli + +import ( + "reflect" + "testing" + "time" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/require" +) + +type testingStruct struct { + Int int64 + UInt uint64 + String string + Float float64 + Duration time.Duration + Pointer *testingStruct + Slice sdk.Coins + Struct interface{} + Dec sdk.Dec +} + +func TestParseFieldFromArg(t *testing.T) { + tests := map[string]struct { + testingStruct + arg string + fieldIndex int + + expectedStruct testingStruct + expectingErr bool + }{ + "Int value changes from -20 to 10": { + testingStruct: testingStruct{Int: -20}, + arg: "10", + fieldIndex: 0, + expectedStruct: testingStruct{Int: 10}, + }, + "Attempt to change Int value 20 to string value": { // does not return error, simply does not change the struct + testingStruct: testingStruct{Int: 20}, + arg: "hello", + fieldIndex: 0, + expectedStruct: testingStruct{Int: 20}, + }, + "UInt value changes from 20 to 10": { + testingStruct: testingStruct{UInt: 20}, + arg: "10", + fieldIndex: 1, + expectedStruct: testingStruct{UInt: 10}, + }, + "String value change": { + testingStruct: testingStruct{String: "hello"}, + arg: "world", + fieldIndex: 2, + expectedStruct: testingStruct{String: "world"}, + }, + "Changing unset value (simply sets the value)": { + testingStruct: testingStruct{Int: 20}, + arg: "hello", + fieldIndex: 2, + expectedStruct: testingStruct{Int: 20, String: "hello"}, + }, + "Float value change": { + testingStruct: testingStruct{Float: 20.0}, + arg: "30.0", + fieldIndex: 3, + expectedStruct: testingStruct{Float: 30.0}, + }, + "Duration value changes from .Hour to .Second": { + testingStruct: testingStruct{Duration: time.Hour}, + arg: "1s", + fieldIndex: 4, + expectedStruct: testingStruct{Duration: time.Second}, + }, + "Attempt to change pointer": { // for reflect.Ptr kind ParseFieldFromArg does nothing, hence no changes take place + testingStruct: testingStruct{Pointer: &testingStruct{}}, + arg: "*whatever", + fieldIndex: 5, + expectedStruct: testingStruct{Pointer: &testingStruct{}}, + }, + "Slice change": { + testingStruct: testingStruct{Slice: sdk.Coins{ + sdk.NewCoin("foo", sdk.NewInt(100)), + sdk.NewCoin("bar", sdk.NewInt(100)), + }}, + arg: "10foo,10bar", // Should be of a format suitable for ParseCoinsNormalized + fieldIndex: 6, + expectedStruct: testingStruct{Slice: sdk.Coins{ // swapped places due to lexicographic order + sdk.NewCoin("bar", sdk.NewInt(10)), + sdk.NewCoin("foo", sdk.NewInt(10)), + }}, + }, + "Struct (sdk.Coin) change": { + testingStruct: testingStruct{Struct: sdk.NewCoin("bar", sdk.NewInt(10))}, // only supports sdk.Int, sdk.Coin or time.Time, other structs are not recognized + arg: "100bar", + fieldIndex: 7, + expectedStruct: testingStruct{Struct: sdk.NewCoin("bar", sdk.NewInt(10))}, + }, + "Unrecognizable struct": { + testingStruct: testingStruct{Struct: testingStruct{}}, // only supports sdk.Int, sdk.Coin or time.Time, other structs are not recognized + arg: "whatever", + fieldIndex: 7, + expectingErr: true, + }, + "Multiple fields in struct are set": { + testingStruct: testingStruct{Int: 20, UInt: 10, String: "hello", Pointer: &testingStruct{}}, + arg: "world", + fieldIndex: 2, + expectedStruct: testingStruct{Int: 20, UInt: 10, String: "world", Pointer: &testingStruct{}}, + }, + "All fields in struct set": { + testingStruct: testingStruct{ + Int: 20, + UInt: 10, + String: "hello", + Float: 30.0, + Duration: time.Second, + Pointer: &testingStruct{}, + Slice: sdk.Coins{ + sdk.NewCoin("foo", sdk.NewInt(100)), + sdk.NewCoin("bar", sdk.NewInt(100)), + }, + Struct: sdk.NewCoin("bar", sdk.NewInt(10)), + }, + arg: "1foo,15bar", + fieldIndex: 6, + expectedStruct: testingStruct{ + Int: 20, + UInt: 10, + String: "hello", + Float: 30.0, + Duration: time.Second, + Pointer: &testingStruct{}, + Slice: sdk.Coins{ + sdk.NewCoin("bar", sdk.NewInt(15)), + sdk.NewCoin("foo", sdk.NewInt(1)), + }, + Struct: sdk.NewCoin("bar", sdk.NewInt(10)), + }, + }, + "Dec struct": { + testingStruct: testingStruct{Dec: sdk.MustNewDecFromStr("100")}, + arg: "10", + fieldIndex: 8, + expectedStruct: testingStruct{Dec: sdk.MustNewDecFromStr("10")}, + }, + } + + for name, tc := range tests { + t.Run(name, func(t *testing.T) { + val := reflect.ValueOf(&tc.testingStruct).Elem() + typ := reflect.TypeOf(&tc.testingStruct).Elem() + + fVal := val.Field(tc.fieldIndex) + fType := typ.Field(tc.fieldIndex) + + err := ParseFieldFromArg(fVal, fType, tc.arg) + + if !tc.expectingErr { + require.Equal(t, tc.expectedStruct, tc.testingStruct) + } else { + require.Error(t, err) + } + }) + } +} diff --git a/osmoutils/osmocli/query_cmd_wrap.go b/osmoutils/osmocli/query_cmd_wrap.go new file mode 100644 index 000000000..86c8e777b --- /dev/null +++ b/osmoutils/osmocli/query_cmd_wrap.go @@ -0,0 +1,181 @@ +package osmocli + +import ( + "context" + "fmt" + "reflect" + "strings" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + grpc1 "github.com/gogo/protobuf/grpc" + "github.com/gogo/protobuf/proto" + "github.com/spf13/cobra" + "github.com/spf13/pflag" +) + +// global variable set on index command. +// helps populate Longs, when not set in QueryDescriptor. +var lastQueryModuleName string + +type QueryDescriptor struct { + Use string + Short string + Long string + + HasPagination bool + + QueryFnName string + + Flags FlagDesc + // Map of FieldName -> FlagName + CustomFlagOverrides map[string]string + // Map of FieldName -> CustomParseFn + CustomFieldParsers map[string]CustomFieldParserFn + + ParseQuery func(args []string, flags *pflag.FlagSet) (proto.Message, error) + + ModuleName string + numArgs int +} + +func QueryIndexCmd(moduleName string) *cobra.Command { + cmd := IndexCmd(moduleName) + cmd.Short = fmt.Sprintf("Querying commands for the %s module", moduleName) + lastQueryModuleName = moduleName + return cmd +} + +func AddQueryCmd[Q proto.Message, querier any](cmd *cobra.Command, newQueryClientFn func(grpc1.ClientConn) querier, f func() (*QueryDescriptor, Q)) { + desc, _ := f() + subCmd := BuildQueryCli[Q](desc, newQueryClientFn) + cmd.AddCommand(subCmd) +} + +func (desc *QueryDescriptor) FormatLong(moduleName string) { + desc.Long = FormatLongDesc(desc.Long, NewLongMetadata(moduleName).WithShort(desc.Short)) +} + +func prepareDescriptor[reqP proto.Message](desc *QueryDescriptor) { + if !desc.HasPagination { + desc.HasPagination = ParseHasPagination[reqP]() + } + if desc.QueryFnName == "" { + desc.QueryFnName = ParseExpectedQueryFnName[reqP]() + } + if strings.Contains(desc.Long, "{") { + if desc.ModuleName == "" { + desc.ModuleName = lastQueryModuleName + } + desc.FormatLong(desc.ModuleName) + } + + desc.numArgs = ParseNumFields[reqP]() - len(desc.CustomFlagOverrides) + if desc.HasPagination { + desc.numArgs = desc.numArgs - 1 + } +} + +func BuildQueryCli[reqP proto.Message, querier any](desc *QueryDescriptor, newQueryClientFn func(grpc1.ClientConn) querier) *cobra.Command { + prepareDescriptor[reqP](desc) + if desc.ParseQuery == nil { + desc.ParseQuery = func(args []string, fs *pflag.FlagSet) (proto.Message, error) { + flagAdvice := FlagAdvice{ + HasPagination: desc.HasPagination, + CustomFlagOverrides: desc.CustomFlagOverrides, + CustomFieldParsers: desc.CustomFieldParsers, + }.Sanitize() + return ParseFieldsFromFlagsAndArgs[reqP](flagAdvice, fs, args) + } + } + + cmd := &cobra.Command{ + Use: desc.Use, + Short: desc.Short, + Long: desc.Long, + Args: cobra.ExactArgs(desc.numArgs), + RunE: queryLogic(desc, newQueryClientFn), + } + flags.AddQueryFlagsToCmd(cmd) + AddFlags(cmd, desc.Flags) + if desc.HasPagination { + cmdName := strings.Split(desc.Use, " ")[0] + flags.AddPaginationFlagsToCmd(cmd, cmdName) + } + + return cmd +} + +// SimpleQueryCmd builds a query, for the common, simple case. +// It detects that the querier function name is the same as the ProtoMessage name, +// with just the "Query" and "Request" args chopped off. +// It expects all proto fields to appear as arguments, in order. +func SimpleQueryCmd[reqP proto.Message, querier any](use string, short string, long string, + moduleName string, newQueryClientFn func(grpc1.ClientConn) querier, +) *cobra.Command { + desc := QueryDescriptor{ + Use: use, + Short: short, + Long: FormatLongDesc(long, NewLongMetadata(moduleName).WithShort(short)), + } + return BuildQueryCli[reqP](&desc, newQueryClientFn) +} + +func GetParams[reqP proto.Message, querier any](moduleName string, + newQueryClientFn func(grpc1.ClientConn) querier, +) *cobra.Command { + return BuildQueryCli[reqP](&QueryDescriptor{ + Use: "params [flags]", + Short: fmt.Sprintf("Get the params for the x/%s module", moduleName), + QueryFnName: "Params", + }, newQueryClientFn) +} + +func callQueryClientFn(ctx context.Context, fnName string, req proto.Message, q any) (res proto.Message, err error) { + qVal := reflect.ValueOf(q) + method := qVal.MethodByName(fnName) + if (method == reflect.Value{}) { + return nil, fmt.Errorf("Method %s does not exist on the querier."+ + " You likely need to override QueryFnName in your Query descriptor", fnName) + } + args := []reflect.Value{ + reflect.ValueOf(ctx), + reflect.ValueOf(req), + } + results := method.Call(args) + if len(results) != 2 { + panic("We got something wrong") + } + if !results[1].IsNil() { + //nolint:forcetypeassert + err = results[1].Interface().(error) + return res, err + } + //nolint:forcetypeassert + res = results[0].Interface().(proto.Message) + return res, nil +} + +func queryLogic[querier any](desc *QueryDescriptor, + newQueryClientFn func(grpc1.ClientConn) querier, +) func(cmd *cobra.Command, args []string) error { + return func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + queryClient := newQueryClientFn(clientCtx) + + req, err := desc.ParseQuery(args, cmd.Flags()) + if err != nil { + return err + } + + res, err := callQueryClientFn(cmd.Context(), desc.QueryFnName, req, queryClient) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + } +} diff --git a/osmoutils/osmocli/string_formatter.go b/osmoutils/osmocli/string_formatter.go new file mode 100644 index 000000000..43c57725e --- /dev/null +++ b/osmoutils/osmocli/string_formatter.go @@ -0,0 +1,49 @@ +package osmocli + +import ( + "fmt" + "strings" + "text/template" + + "github.com/cosmos/cosmos-sdk/version" +) + +type LongMetadata struct { + BinaryName string + CommandPrefix string + Short string + + // Newline Example: + ExampleHeader string +} + +func NewLongMetadata(moduleName string) *LongMetadata { + commandPrefix := fmt.Sprintf("$ %s q %s", version.AppName, moduleName) + return &LongMetadata{ + BinaryName: version.AppName, + CommandPrefix: commandPrefix, + } +} + +func (m *LongMetadata) WithShort(short string) *LongMetadata { + m.Short = short + return m +} + +func FormatLongDesc(longString string, meta *LongMetadata) string { + template, err := template.New("long_description").Parse(longString) + if err != nil { + panic("incorrectly configured long message") + } + bld := strings.Builder{} + meta.ExampleHeader = "\n\nExample:" + err = template.Execute(&bld, meta) + if err != nil { + panic("incorrectly configured long message") + } + return strings.TrimSpace(bld.String()) +} + +func FormatLongDescDirect(longString string, moduleName string) string { + return FormatLongDesc(longString, NewLongMetadata(moduleName)) +} diff --git a/osmoutils/osmocli/tx_cmd_wrap.go b/osmoutils/osmocli/tx_cmd_wrap.go new file mode 100644 index 000000000..48725fe9e --- /dev/null +++ b/osmoutils/osmocli/tx_cmd_wrap.go @@ -0,0 +1,99 @@ +package osmocli + +import ( + "fmt" + "strings" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/client/tx" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/spf13/cobra" + "github.com/spf13/pflag" +) + +func TxIndexCmd(moduleName string) *cobra.Command { + cmd := IndexCmd(moduleName) + cmd.Short = fmt.Sprintf("%s transactions subcommands", moduleName) + return cmd +} + +type TxCliDesc struct { + Use string + Short string + Long string + Example string + + NumArgs int + // Contract: len(args) = NumArgs + ParseAndBuildMsg func(clientCtx client.Context, args []string, flags *pflag.FlagSet) (sdk.Msg, error) + TxSignerFieldName string + + Flags FlagDesc + // Map of FieldName -> FlagName + CustomFlagOverrides map[string]string + // Map of FieldName -> CustomParseFn + CustomFieldParsers map[string]CustomFieldParserFn +} + +func AddTxCmd[M sdk.Msg](cmd *cobra.Command, f func() (*TxCliDesc, M)) { + desc, _ := f() + subCmd := BuildTxCli[M](desc) + cmd.AddCommand(subCmd) +} + +func BuildTxCli[M sdk.Msg](desc *TxCliDesc) *cobra.Command { + desc.TxSignerFieldName = strings.ToLower(desc.TxSignerFieldName) + if desc.NumArgs == 0 { + // NumArgs = NumFields - 1, since 1 field is from the msg + desc.NumArgs = ParseNumFields[M]() - 1 - len(desc.CustomFlagOverrides) - len(desc.CustomFieldParsers) + } + if desc.ParseAndBuildMsg == nil { + desc.ParseAndBuildMsg = func(clientCtx client.Context, args []string, flags *pflag.FlagSet) (sdk.Msg, error) { + flagAdvice := FlagAdvice{ + IsTx: true, + TxSenderFieldName: desc.TxSignerFieldName, + FromValue: clientCtx.GetFromAddress().String(), + CustomFlagOverrides: desc.CustomFlagOverrides, + CustomFieldParsers: desc.CustomFieldParsers, + }.Sanitize() + return ParseFieldsFromFlagsAndArgs[M](flagAdvice, flags, args) + } + } + return desc.BuildCommandCustomFn() +} + +// Creates a new cobra command given the description. +// Its up to then caller to add CLI flags, aside from `flags.AddTxFlagsToCmd(cmd)` +func (desc TxCliDesc) BuildCommandCustomFn() *cobra.Command { + cmd := &cobra.Command{ + Use: desc.Use, + Short: desc.Short, + Args: cobra.ExactArgs(desc.NumArgs), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + txf := tx.NewFactoryCLI(clientCtx, cmd.Flags()).WithTxConfig(clientCtx.TxConfig).WithAccountRetriever(clientCtx.AccountRetriever) + + msg, err := desc.ParseAndBuildMsg(clientCtx, args, cmd.Flags()) + if err != nil { + return err + } + + return tx.GenerateOrBroadcastTxWithFactory(clientCtx, txf, msg) + }, + } + if desc.Example != "" { + cmd.Example = desc.Example + } + if desc.Long != "" { + cmd.Long = desc.Long + } + + flags.AddTxFlagsToCmd(cmd) + AddFlags(cmd, desc.Flags) + return cmd +} diff --git a/osmoutils/parse.go b/osmoutils/parse.go new file mode 100644 index 000000000..808e3dcab --- /dev/null +++ b/osmoutils/parse.go @@ -0,0 +1,71 @@ +package osmoutils + +import ( + "encoding/json" + "fmt" + "os" + + "github.com/cosmos/cosmos-sdk/x/gov/client/cli" + "github.com/spf13/pflag" +) + +type Proposal struct { + Title string + Description string + Deposit string +} + +var ProposalFlags = []string{ + cli.FlagTitle, + cli.FlagDescription, + cli.FlagDeposit, +} + +func (p Proposal) validate() error { + if p.Title == "" { + return fmt.Errorf("proposal title is required") + } + + if p.Description == "" { + return fmt.Errorf("proposal description is required") + } + return nil +} + +func ParseProposalFlags(fs *pflag.FlagSet) (*Proposal, error) { + proposal := &Proposal{} + proposalFile, _ := fs.GetString(cli.FlagProposal) + + if proposalFile == "" { + proposal.Title, _ = fs.GetString(cli.FlagTitle) + proposal.Description, _ = fs.GetString(cli.FlagDescription) + proposal.Deposit, _ = fs.GetString(cli.FlagDeposit) + if err := proposal.validate(); err != nil { + return nil, err + } + + return proposal, nil + } + + for _, flag := range ProposalFlags { + if v, _ := fs.GetString(flag); v != "" { + return nil, fmt.Errorf("--%s flag provided alongside --proposal, which is a noop", flag) + } + } + + contents, err := os.ReadFile(proposalFile) + if err != nil { + return nil, err + } + + err = json.Unmarshal(contents, proposal) + if err != nil { + return nil, err + } + + if err := proposal.validate(); err != nil { + return nil, err + } + + return proposal, nil +} diff --git a/osmoutils/partialord/internal/dag/dag.go b/osmoutils/partialord/internal/dag/dag.go new file mode 100644 index 000000000..d33a0a63a --- /dev/null +++ b/osmoutils/partialord/internal/dag/dag.go @@ -0,0 +1,320 @@ +package dag + +import ( + "fmt" + "sort" +) + +// DAG struct maintains a directed acyclic graph, using adjacency lists to track edges. +type DAG struct { + // there is a directed edge from u -> v, if directedEdgeList[u][v] = 1 + // there is a directed edge from v -> u, if directedEdgeList[u][v] = -1 + directedEdgeList []map[int]int8 + nodeNameToId map[string]int + idToNodeNames map[int]string +} + +func NewDAG(nodes []string) DAG { + nodeNameToId := make(map[string]int, len(nodes)) + idToNodeNames := make(map[int]string, len(nodes)) + directedEdgeList := make([]map[int]int8, len(nodes)) + for i, node := range nodes { + nodeNameToId[node] = i + idToNodeNames[i] = node + directedEdgeList[i] = map[int]int8{} + } + if len(nodeNameToId) != len(nodes) { + panic("provided multiple nodes with the same name") + } + return DAG{ + directedEdgeList: directedEdgeList, + nodeNameToId: nodeNameToId, + idToNodeNames: idToNodeNames, + } +} + +// Copy returns a new dag struct that is a copy of the original dag. +// Edges can be mutated in the copy, without altering the original. +func (dag DAG) Copy() DAG { + directedEdgeList := make([]map[int]int8, len(dag.nodeNameToId)) + for i := 0; i < len(dag.nodeNameToId); i++ { + originalEdgeList := dag.directedEdgeList[i] + directedEdgeList[i] = make(map[int]int8, len(originalEdgeList)) + for k, v := range originalEdgeList { + directedEdgeList[i][k] = v + } + } + // we re-use nodeNameToId and idToNodeNames as these are fixed at dag creation. + return DAG{ + directedEdgeList: directedEdgeList, + nodeNameToId: dag.nodeNameToId, + idToNodeNames: dag.idToNodeNames, + } +} + +func (dag DAG) hasDirectedEdge(u, v int) bool { + uAdjacencyList := dag.directedEdgeList[u] + _, exists := uAdjacencyList[v] + return exists +} + +// addEdge adds a directed edge from u -> v. +func (dag *DAG) addEdge(u, v int) error { + if u == v { + return fmt.Errorf("can't make self-edge") + } + if dag.hasDirectedEdge(v, u) { + return fmt.Errorf("dag has conflicting edge") + } + dag.directedEdgeList[u][v] = 1 + dag.directedEdgeList[v][u] = -1 + return nil +} + +// replaceEdge adds a directed edge from u -> v. +// it removes any edge that may already exist between the two. +func (dag *DAG) replaceEdge(u, v int) error { + if u == v { + return fmt.Errorf("can't make self-edge") + } + + dag.directedEdgeList[u][v] = 1 + dag.directedEdgeList[v][u] = -1 + return nil +} + +// resetEdges deletes all edges directed to or from node `u` +func (dag *DAG) resetEdges(u int) { + edges := dag.directedEdgeList[u] + for v := range edges { + delete(dag.directedEdgeList[v], u) + } + dag.directedEdgeList[u] = map[int]int8{} +} + +// deleteEdge deletes edges between u and v. +func (dag *DAG) deleteEdge(u, v int) { + delete(dag.directedEdgeList[u], v) + delete(dag.directedEdgeList[v], u) +} + +// AddEdge checks if either edge between u and v exists and adds a directed edge from u -> v +func (dag *DAG) AddEdge(u, v string) error { + uIndex, uExists := dag.nodeNameToId[u] + vIndex, vExists := dag.nodeNameToId[v] + if !uExists || !vExists { + return fmt.Errorf("one of %s, %s does not exist in dag", u, v) + } + return dag.addEdge(uIndex, vIndex) +} + +// ReplaceEdge adds a directed edge from u -> v. +// it removes any edge that may already exist between the two. +func (dag *DAG) ReplaceEdge(u, v string) error { + uIndex, uExists := dag.nodeNameToId[u] + vIndex, vExists := dag.nodeNameToId[v] + if !uExists || !vExists { + return fmt.Errorf("one of %s, %s does not exist in dag", u, v) + } + return dag.replaceEdge(uIndex, vIndex) +} + +// AddFirstElements sets the provided elements to be first in all orderings. +// So if were making an ordering over {A, B, C, D, E}, and elems provided is {D, B, A} +// then we are guaranteed that the total ordering will begin with {D, B, A} +func (dag *DAG) AddFirstElements(nodes ...string) error { + nodeIds, err := dag.namesToIds(nodes) + if err != nil { + return err + } + + return dag.addFirst(nodeIds) +} + +func (dag *DAG) addFirst(nodes []int) error { + nodeMap := map[int]bool{} + for i := 0; i < len(nodes); i++ { + nodeMap[nodes[i]] = true + } + // First we add an edge from nodes[-1] to every node in the graph aside from the provided first nodes. + // then we make nodes[-1] depend on nodes[-2], etc. + // We also clear all other edges from nodes[-2], to override previous settings. + lastOfFirstNodes := nodes[len(nodes)-1] + for i := 0; i < len(dag.nodeNameToId); i++ { + // skip any node in the 'first set' + _, inMap := nodeMap[i] + if inMap { + continue + } + // We make everything on `lastOfFirstNodes`, and therefore have an edge from `lastOfFirstNodes` to it + err := dag.replaceEdge(lastOfFirstNodes, i) + // can't happen by above check + if err != nil { + return err + } + } + + // Make nodes[i+1] depend on nodes[i] + for i := len(nodes) - 2; i >= 0; i-- { + dag.resetEdges(nodes[i]) + err := dag.replaceEdge(nodes[i], nodes[i+1]) + // can't happen by above check + if err != nil { + return err + } + } + return nil +} + +// AddLastElements sets the provided elements to be last in all orderings. +// So if were making an ordering over {A, B, C, D, E}, and elems provided is {D, B, A} +// then we are guaranteed that the total ordering will end with {D, B, A} +func (dag *DAG) AddLastElements(nodes ...string) error { + nodeIds, err := dag.namesToIds(nodes) + if err != nil { + return err + } + + return dag.addLast(nodeIds) +} + +func (dag *DAG) addLast(nodes []int) error { + nodeMap := map[int]bool{} + for i := 0; i < len(nodes); i++ { + nodeMap[nodes[i]] = true + } + // First we add an edge from every node in the graph aside from the provided last nodes, to nodes[0] + // then we make nodes[1] depend on nodes[0], etc. + // We also clear all other edges from nodes[1], to override previous settings. + firstOfLastNodes := nodes[0] + for i := 0; i < len(dag.nodeNameToId); i++ { + // skip any node in the 'last set' + _, inMap := nodeMap[i] + if inMap { + continue + } + // We make `firstOfLastNodes` depend on every node, and therefore have an edge from each node to `firstOfLastNodes` + err := dag.replaceEdge(i, firstOfLastNodes) + // can't happen by above check + if err != nil { + return err + } + } + + // Make nodes[i] depend on nodes[i-1], and clear all other edges from nodes[i] + for i := 1; i < len(nodes); i++ { + dag.resetEdges(nodes[i]) + err := dag.replaceEdge(nodes[i-1], nodes[i]) + // can't happen by above check + if err != nil { + return err + } + } + return nil +} + +func (dag DAG) hasEdges() bool { + for _, m := range dag.directedEdgeList { + if len(m) > 0 { + return true + } + } + return false +} + +func (dag *DAG) namesToIds(names []string) ([]int, error) { + nodeIds := []int{} + for _, name := range names { + nodeIndex, nodeExists := dag.nodeNameToId[name] + if !nodeExists { + return []int{}, fmt.Errorf("%s does not exist in dag", name) + } + nodeIds = append(nodeIds, nodeIndex) + } + return nodeIds, nil +} + +func (dag DAG) idsToNames(ids []int) []string { + sortedNames := make([]string, 0, len(ids)) + for i := 0; i < len(dag.nodeNameToId); i++ { + id := ids[i] + sortedNames = append(sortedNames, dag.idToNodeNames[id]) + } + return sortedNames +} + +func (dag DAG) hasIncomingEdge(u int) bool { + adjacencyList := dag.directedEdgeList[u] + for _, v := range adjacencyList { + if v == -1 { + return true + } + } + return false +} + +// returns nodes with no incoming edges. +func (dag *DAG) topologicalTopLevelNodes() []int { + topLevelNodes := []int{} + + for i := 0; i < len(dag.nodeNameToId); i++ { + if !dag.hasIncomingEdge(i) { + topLevelNodes = append(topLevelNodes, i) + } + } + + return topLevelNodes +} + +// Returns a Topological Sort of the DAG, using Kahn's algorithm. +// https://en.wikipedia.org/wiki/Topological_sorting#Kahn's_algorithm +func (dag DAG) TopologicalSort() []string { + // G is the mutable graph we work on, which we remove edges from. + G := dag.Copy() + // L in pseudocode + sortedIDs := make([]int, 0, len(dag.nodeNameToId)) + topLevelNodes := dag.topologicalTopLevelNodes() + + // while len(topLevelNodes) != 0 + for { + if len(topLevelNodes) == 0 { + break + } + // pop a node `n`` off of topLevelNodes + n := topLevelNodes[0] + topLevelNodes = topLevelNodes[1:] + // add it to the sorted list + sortedIDs = append(sortedIDs, n) + nEdgeList := G.directedEdgeList[n] + + // normally we'd do map iteration, but because we need cross-machine determinism, + // we gather all the nodes M for which there is an edge n -> m, sort that list, + // and then iterate over it. + nodesM := make([]int, 0, len(nEdgeList)) + for m, direction := range nEdgeList { + if direction != 1 { + panic("dag: topological sort correctness error. " + + "Popped node n was expected to have no incoming edges") + } + nodesM = append(nodesM, m) + } + + sort.Ints(nodesM) + + for _, m := range nodesM { + // remove edge from n -> m + G.deleteEdge(n, m) + // if m has no incomingEdges, add to topLevelNodes + if !G.hasIncomingEdge(m) { + topLevelNodes = append(topLevelNodes, m) + } + } + } + + if G.hasEdges() { + fmt.Println(G) + panic("dag: invalid construction, attempted to topologically sort a tree that is not a dag. A cycle exists") + } + + return dag.idsToNames(sortedIDs) +} diff --git a/osmoutils/partialord/internal/dag/dag_test.go b/osmoutils/partialord/internal/dag/dag_test.go new file mode 100644 index 000000000..bae8bd6d1 --- /dev/null +++ b/osmoutils/partialord/internal/dag/dag_test.go @@ -0,0 +1,154 @@ +package dag_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/CosmosContracts/juno/v15/osmoutils/partialord/internal/dag" +) + +type edge struct { + start, end string +} + +func TestTopologicalSort(t *testing.T) { + // Tests that topological sort works for various inputs. + // We hardcode the satisfying solution in the tests, even though it suffices + // to check that the partial ordering is sufficient. (and thats the only guarantee given externally) + // This is to ensure we catch differences in order between changes, and across machines. + simpleNodes := []string{"dog", "cat", "banana", "apple"} + simpleNodesRev := []string{"apple", "banana", "cat", "dog"} + tests := []struct { + nodes []string + edges []edge + expectedTopologicalOrder []string + }{ + { + // alphabetical ordering of simple nodes + nodes: simpleNodes, + edges: []edge{{"banana", "apple"}, {"cat", "banana"}, {"dog", "cat"}}, + expectedTopologicalOrder: simpleNodes, + }, + { + // apple > dog + nodes: simpleNodes, + edges: []edge{{"apple", "dog"}}, + expectedTopologicalOrder: []string{"cat", "banana", "apple", "dog"}, + }, + { + // apple > everything + nodes: simpleNodes, + edges: []edge{{"apple", "banana"}, {"apple", "cat"}, {"apple", "dog"}}, + expectedTopologicalOrder: []string{"apple", "dog", "cat", "banana"}, + }, + { + // apple > everything, on list with reversed initial order + nodes: simpleNodesRev, + edges: []edge{{"apple", "banana"}, {"apple", "cat"}, {"apple", "dog"}}, + expectedTopologicalOrder: []string{"apple", "banana", "cat", "dog"}, + }, + } + for _, tc := range tests { + dag := dag.NewDAG(tc.nodes) + for _, edge := range tc.edges { + err := dag.AddEdge(edge.start, edge.end) + require.NoError(t, err) + } + order := dag.TopologicalSort() + require.Equal(t, tc.expectedTopologicalOrder, order) + } +} + +func TestAddFirst(t *testing.T) { + simpleNodes := []string{"frog", "elephant", "dog", "cat", "banana", "apple"} + tests := []struct { + nodes []string + first []string + replaceEdges []edge + expectedTopologicalOrder []string + }{ + { + nodes: simpleNodes, + first: []string{"frog"}, + replaceEdges: []edge{{"banana", "apple"}, {"cat", "banana"}, {"dog", "cat"}}, + expectedTopologicalOrder: simpleNodes, + }, + { + nodes: simpleNodes, + first: []string{"elephant"}, + replaceEdges: []edge{{"banana", "apple"}, {"apple", "frog"}, {"dog", "cat"}}, + expectedTopologicalOrder: []string{"elephant", "dog", "banana", "cat", "apple", "frog"}, + }, + { + nodes: simpleNodes, + first: []string{"elephant", "frog"}, + replaceEdges: []edge{}, + expectedTopologicalOrder: []string{"elephant", "frog", "dog", "cat", "banana", "apple"}, + }, + { + // add three items in first, if implemented incorrectly could cause a cycle + nodes: simpleNodes, + first: []string{"dog", "elephant", "frog"}, + replaceEdges: []edge{}, + expectedTopologicalOrder: []string{"dog", "elephant", "frog", "cat", "banana", "apple"}, + }, + } + for _, tc := range tests { + dag := dag.NewDAG(tc.nodes) + dag.AddFirstElements(tc.first...) + for _, edge := range tc.replaceEdges { + err := dag.ReplaceEdge(edge.start, edge.end) + require.NoError(t, err) + } + order := dag.TopologicalSort() + require.Equal(t, tc.expectedTopologicalOrder, order) + } +} + +func TestAddLast(t *testing.T) { + simpleNodes := []string{"frog", "elephant", "dog", "cat", "banana", "apple"} + tests := []struct { + nodes []string + last []string + replaceEdges []edge + expectedTopologicalOrder []string + }{ + { + // causes no order change + nodes: simpleNodes, + last: []string{"apple"}, + replaceEdges: []edge{{"banana", "apple"}, {"cat", "banana"}, {"dog", "cat"}}, + expectedTopologicalOrder: simpleNodes, + }, + { + nodes: simpleNodes, + last: []string{"elephant"}, + replaceEdges: []edge{{"banana", "apple"}, {"apple", "frog"}, {"dog", "cat"}}, + expectedTopologicalOrder: []string{"dog", "banana", "cat", "apple", "frog", "elephant"}, + }, + { + nodes: simpleNodes, + last: []string{"elephant", "frog"}, + replaceEdges: []edge{}, + expectedTopologicalOrder: []string{"dog", "cat", "banana", "apple", "elephant", "frog"}, + }, + { + // add three items in last, if implemented incorrectly could cause a cycle + nodes: simpleNodes, + last: []string{"dog", "elephant", "frog"}, + replaceEdges: []edge{}, + expectedTopologicalOrder: []string{"cat", "banana", "apple", "dog", "elephant", "frog"}, + }, + } + for _, tc := range tests { + dag := dag.NewDAG(tc.nodes) + dag.AddLastElements(tc.last...) + for _, edge := range tc.replaceEdges { + err := dag.ReplaceEdge(edge.start, edge.end) + require.NoError(t, err) + } + order := dag.TopologicalSort() + require.Equal(t, tc.expectedTopologicalOrder, order) + } +} diff --git a/osmoutils/partialord/internal/dag/module.go b/osmoutils/partialord/internal/dag/module.go new file mode 100644 index 000000000..4b4bcd971 --- /dev/null +++ b/osmoutils/partialord/internal/dag/module.go @@ -0,0 +1,9 @@ +// Package dag implements a simple Directed Acyclical Graph (DAG) for deterministic topological sorts +// +// It should not be externally exposed, and is intended to be a very simple dag implementation +// utilizing adjacency lists to store edges. +// +// This package is intended to be used for small scales, where performance of the algorithms is not critical. +// (e.g. sub 10k entries) +// Thus none of the algorithms in here are benchmarked, and just have correctness checks. +package dag diff --git a/osmoutils/partialord/module.go b/osmoutils/partialord/module.go new file mode 100644 index 000000000..1d02c8665 --- /dev/null +++ b/osmoutils/partialord/module.go @@ -0,0 +1,2 @@ +// package partialord allows one to define partial orderings, and derive a total ordering +package partialord diff --git a/osmoutils/partialord/partialord.go b/osmoutils/partialord/partialord.go new file mode 100644 index 000000000..1b9a84348 --- /dev/null +++ b/osmoutils/partialord/partialord.go @@ -0,0 +1,97 @@ +package partialord + +import ( + "sort" + + "github.com/CosmosContracts/juno/v15/osmoutils/partialord/internal/dag" +) + +type PartialOrdering struct { + // underlying dag, the partial ordering is stored via a dag + // https://en.wikipedia.org/wiki/Topological_sorting#Relation_to_partial_orders + dag dag.DAG + // bools for sealing, to prevent repeated invocation of first or last methods. + firstSealed bool + lastSealed bool +} + +// NewPartialOrdering creates a new partial ordering over the set of provided elements. +func NewPartialOrdering(elements []string) PartialOrdering { + elementsCopy := make([]string, len(elements)) + copy(elementsCopy, elements) + sort.Strings(elementsCopy) + return PartialOrdering{ + dag: dag.NewDAG(elementsCopy), + firstSealed: false, + lastSealed: false, + } +} + +func handleDAGErr(err error) { + // all dag errors are logic errors that the intended users of this package should not make. + if err != nil { + panic(err) + } +} + +// After marks that A should come after B +func (ord *PartialOrdering) After(A string, B string) { + // Set that A depends on B / an edge from B -> A + err := ord.dag.AddEdge(B, A) + handleDAGErr(err) +} + +// After marks that A should come before B +func (ord *PartialOrdering) Before(A string, B string) { + // Set that B depends on A / an edge from A -> B + err := ord.dag.AddEdge(A, B) + handleDAGErr(err) +} + +// Sets elems to be the first elements in the ordering. +// So if were making an ordering over {A, B, C, D, E}, and elems provided is {D, B, A} +// then we are guaranteed that the total ordering will begin with {D, B, A} +func (ord *PartialOrdering) FirstElements(elems ...string) { + if ord.firstSealed { + panic("FirstElements has already been called") + } + // We make every node in the dag have a dependency on elems[-1] + // then we change elems[-1] to depend on elems[-2], and so forth. + err := ord.dag.AddFirstElements(elems...) + handleDAGErr(err) + ord.firstSealed = true +} + +// Sets elems to be the last elements in the ordering. +// So if were making an ordering over {A, B, C, D, E}, and elems provided is {D, B, A} +// then we are guaranteed that the total ordering will end with {D, B, A} +func (ord *PartialOrdering) LastElements(elems ...string) { + if ord.lastSealed { + panic("FirstElements has already been called") + } + // We make every node in the dag have a dependency on elems[0] + // then we make elems[1] depend on elems[0], and so forth. + err := ord.dag.AddLastElements(elems...) + handleDAGErr(err) + ord.lastSealed = true +} + +// Sequence sets a sequence of ordering constraints. +// So if were making an ordering over {A, B, C, D, E}, and elems provided is {D, B, A} +// then we are guaranteed that the total ordering will have D comes before B comes before A. +// (They're may be elements interspersed, e.g. {D, C, E, B, A} is a valid ordering) +func (ord *PartialOrdering) Sequence(seq ...string) { + // We make every node in the sequence have a prior node + for i := 0; i < (len(seq) - 1); i++ { + err := ord.dag.AddEdge(seq[i], seq[i+1]) + handleDAGErr(err) + } +} + +// TotalOrdering returns a deterministically chosen total ordering that satisfies all specified +// partial ordering constraints. +// +// Panics if no total ordering exists. +func (ord *PartialOrdering) TotalOrdering() []string { + return ord.dag.TopologicalSort() +} diff --git a/osmoutils/partialord/partialord_test.go b/osmoutils/partialord/partialord_test.go new file mode 100644 index 000000000..46ff28dfa --- /dev/null +++ b/osmoutils/partialord/partialord_test.go @@ -0,0 +1,74 @@ +package partialord_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/CosmosContracts/juno/v15/osmoutils/partialord" +) + +func TestAPI(t *testing.T) { + // begin block use case, we have a dozen modules, but only care about a couple orders. + // In practice this will be gotten from some API, e.g. app.AllModuleNames() + moduleNames := []string{ + "auth", "authz", "bank", "capabilities", + "staking", "distribution", "epochs", "mint", "upgrades", "wasm", "ibc", + "ibctransfers", + } + beginBlockOrd := partialord.NewPartialOrdering(moduleNames) + beginBlockOrd.FirstElements("upgrades", "epochs", "capabilities") + beginBlockOrd.After("ibctransfers", "ibc") + beginBlockOrd.Before("mint", "distribution") + // This is purely just to test last functionality, doesn't make sense in context + beginBlockOrd.LastElements("auth", "authz", "wasm") + + totalOrd := beginBlockOrd.TotalOrdering() + expTotalOrd := []string{ + "upgrades", "epochs", "capabilities", + "bank", "ibc", "mint", "staking", "ibctransfers", "distribution", + "auth", "authz", "wasm", + } + require.Equal(t, expTotalOrd, totalOrd) +} + +func TestNonStandardAPIOrder(t *testing.T) { + // This test uses direct ordering before First, and after Last + names := []string{"A", "B", "C", "D", "E", "F", "G"} + ord := partialord.NewPartialOrdering(names) + ord.After("A", "C") + ord.After("A", "D") + ord.After("E", "B") + // overrides the "A" after "C" & "A" after "D" constraints + ord.FirstElements("A", "B", "C") + expOrdering := []string{"A", "B", "C", "D", "E", "F", "G"} + require.Equal(t, expOrdering, ord.TotalOrdering()) + + ord.After("E", "D") + expOrdering = []string{"A", "B", "C", "D", "F", "G", "E"} + require.Equal(t, expOrdering, ord.TotalOrdering()) + + ord.LastElements("G") + ord.After("F", "E") + expOrdering = []string{"A", "B", "C", "D", "E", "F", "G"} + require.Equal(t, expOrdering, ord.TotalOrdering()) +} + +// This test ad-hocly tests combination of multiple sequences, first elements, and an After +// invokation. +func TestSequence(t *testing.T) { + // This test uses direct ordering before First, and after Last + names := []string{"A", "B", "C", "D", "E", "F", "G"} + ord := partialord.NewPartialOrdering(names) + // Make B A C a sequence + ord.Sequence("B", "A", "C") + // Make A G E a sub-sequence + ord.Sequence("A", "G", "E") + // make first elements D B F + ord.FirstElements("D", "B", "F") + // make C come after E + ord.After("C", "G") + + expOrdering := []string{"D", "B", "F", "A", "G", "C", "E"} + require.Equal(t, expOrdering, ord.TotalOrdering()) +} diff --git a/osmoutils/slice_helper.go b/osmoutils/slice_helper.go new file mode 100644 index 000000000..6263794c3 --- /dev/null +++ b/osmoutils/slice_helper.go @@ -0,0 +1,94 @@ +package osmoutils + +import ( + "reflect" + "sort" + + "golang.org/x/exp/constraints" +) + +// SortSlice sorts a slice of type T elements that implement constraints.Ordered. +// Mutates input slice s +func SortSlice[T constraints.Ordered](s []T) { + sort.Slice(s, func(i, j int) bool { + return s[i] < s[j] + }) +} + +func Filter[T interface{}](filter func(T) bool, s []T) []T { + filteredSlice := []T{} + for _, s := range s { + if filter(s) { + filteredSlice = append(filteredSlice, s) + } + } + return filteredSlice +} + +// ReverseSlice reverses the input slice in place. +// Does mutate argument. +func ReverseSlice[T any](s []T) []T { + maxIndex := len(s) + for i := 0; i < maxIndex/2; i++ { + temp := s[i] + s[i] = s[maxIndex-i-1] + s[maxIndex-1-i] = temp + } + return s +} + +// ContainsDuplicate checks if there are any duplicate +// elements in the slice. +func ContainsDuplicate[T any](arr []T) bool { + visited := make(map[any]bool, 0) + for i := 0; i < len(arr); i++ { + if visited[arr[i]] { + return true + } else { + visited[arr[i]] = true + } + } + return false +} + +// ContainsDuplicateDeepEqual returns true if there are duplicates +// in the slice by performing deep comparison. This is useful +// for comparing matrices or slices of pointers. +// Returns false if there are no deep equal duplicates. +func ContainsDuplicateDeepEqual[T any](multihops []T) bool { + for i := 0; i < len(multihops)-1; i++ { + if reflect.DeepEqual(multihops[i], multihops[i+1]) { + return true + } + } + return false +} + +type LessFunc[T any] func(a, b T) bool + +// MergeSlices efficiently merges two sorted slices into a single sorted slice. +// The resulting slice contains all elements from slice1 and slice2, sorted according to the less function. +// The input slices must be sorted in ascending order according to the less function. +// The less function takes two elements of type T and returns a boolean value indicating whether the first element is less than the second element. +// The function returns a new slice containing all elements from slice1 and slice2, sorted according to the less function. +// The function does not modify the input slices. +func MergeSlices[T any](slice1, slice2 []T, less LessFunc[T]) []T { + result := make([]T, 0, len(slice1)+len(slice2)) + i, j := 0, 0 + + for i < len(slice1) && j < len(slice2) { + if less(slice1[i], slice2[j]) { + result = append(result, slice1[i]) + i++ + } else { + result = append(result, slice2[j]) + j++ + } + } + + // Append any remaining elements from slice1 and slice2 + result = append(result, slice1[i:]...) + result = append(result, slice2[j:]...) + + return result +} diff --git a/osmoutils/slice_helper_test.go b/osmoutils/slice_helper_test.go new file mode 100644 index 000000000..72321b334 --- /dev/null +++ b/osmoutils/slice_helper_test.go @@ -0,0 +1,93 @@ +package osmoutils_test + +import ( + "reflect" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/CosmosContracts/juno/v15/osmoutils" +) + +func TestReverseSlice(t *testing.T) { + tests := map[string]struct { + s []string + + expectedSolvedInput []string + }{ + "Even length array": {s: []string{"a", "b", "c", "d"}, expectedSolvedInput: []string{"d", "c", "b", "a"}}, + "Empty array": {s: []string{}, expectedSolvedInput: []string{}}, + "Odd length array": {s: []string{"a", "b", "c"}, expectedSolvedInput: []string{"c", "b", "a"}}, + "Single element array": {s: []string{"a"}, expectedSolvedInput: []string{"a"}}, + "Array with empty string": {s: []string{"a", "b", "c", "", "d"}, expectedSolvedInput: []string{"d", "", "c", "b", "a"}}, + "Array with numbers": {s: []string{"a", "b", "c", "1", "2", "3"}, expectedSolvedInput: []string{"3", "2", "1", "c", "b", "a"}}, + } + for name, tc := range tests { + t.Run(name, func(t *testing.T) { + actualSolvedInput := osmoutils.ReverseSlice(tc.s) + require.Equal(t, tc.expectedSolvedInput, actualSolvedInput) + }) + } +} + +func TestMergeSlices(t *testing.T) { + lessInt := func(a, b int) bool { + return a < b + } + testCases := []struct { + name string + slice1 []int + slice2 []int + less func(a, b int) bool + want []int + }{ + { + name: "basic merge", + slice1: []int{1, 3, 5}, + slice2: []int{2, 4, 6}, + less: lessInt, + want: []int{1, 2, 3, 4, 5, 6}, + }, + { + name: "Empty slice1", + slice1: []int{}, + slice2: []int{2, 4, 6}, + less: lessInt, + want: []int{2, 4, 6}, + }, + { + name: "Empty slice2", + slice1: []int{1, 3, 5}, + slice2: []int{}, + less: lessInt, + want: []int{1, 3, 5}, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + got := osmoutils.MergeSlices(tc.slice1, tc.slice2, lessInt) + if !reflect.DeepEqual(got, tc.want) { + t.Errorf("got: %v, want: %v", got, tc.want) + } + }) + } +} + +func TestContainsDuplicateDeepEqual(t *testing.T) { + tests := []struct { + input []interface{} + want bool + }{ + {[]interface{}{[]int{1, 2, 3}, []int{4, 5, 6}}, false}, + {[]interface{}{[]int{1, 2, 3}, []int{1, 2, 3}}, true}, + {[]interface{}{[]string{"hello", "world"}, []string{"goodbye", "world"}}, false}, + {[]interface{}{[]string{"hello", "world"}, []string{"hello", "world"}}, true}, + {[]interface{}{[][]int{{1, 2}, {3, 4}}, [][]int{{1, 2}, {3, 4}}}, true}, + } + + for _, tt := range tests { + got := osmoutils.ContainsDuplicateDeepEqual(tt.input) + require.Equal(t, tt.want, got) + } +} diff --git a/osmoutils/store_helper.go b/osmoutils/store_helper.go new file mode 100644 index 000000000..232815179 --- /dev/null +++ b/osmoutils/store_helper.go @@ -0,0 +1,194 @@ +package osmoutils + +import ( + "errors" + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + db "github.com/tendermint/tm-db" + + "github.com/cosmos/cosmos-sdk/store" + "github.com/gogo/protobuf/proto" +) + +var ( + ErrNoValuesInRange = errors.New("No values in range") +) + +func GatherAllKeysFromStore(storeObj store.KVStore) []string { + iterator := storeObj.Iterator(nil, nil) + defer iterator.Close() + + keys := []string{} + for ; iterator.Valid(); iterator.Next() { + keys = append(keys, string(iterator.Key())) + } + return keys +} + +func GatherValuesFromStore[T any](storeObj store.KVStore, keyStart []byte, keyEnd []byte, parseValue func([]byte) (T, error)) ([]T, error) { + iterator := storeObj.Iterator(keyStart, keyEnd) + defer iterator.Close() + return gatherValuesFromIterator(iterator, parseValue, noStopFn) +} + +// GatherValuesFromStorePrefix is a decorator around GatherValuesFromStorePrefixWithKeyParser. It overwrites the parse function to +// disable parsing keys, only keeping values +func GatherValuesFromStorePrefix[T any](storeObj store.KVStore, prefix []byte, parseValue func([]byte) (T, error)) ([]T, error) { + // Replace a callback with the one that takes both key and value + // but ignores the key. + parseOnlyValue := func(_ []byte, value []byte) (T, error) { + return parseValue(value) + } + return GatherValuesFromStorePrefixWithKeyParser(storeObj, prefix, parseOnlyValue) +} + +// GatherValuesFromStorePrefixWithKeyParser is a helper function that gathers values from a given store prefix. While iterating through +// the entries, it parses both key and the value using the provided parse function to return the desired type. +// Returns error if: +// - the parse function returns an error. +// - internal database error +func GatherValuesFromStorePrefixWithKeyParser[T any](storeObj store.KVStore, prefix []byte, parse func(key []byte, value []byte) (T, error)) ([]T, error) { + iterator := sdk.KVStorePrefixIterator(storeObj, prefix) + defer iterator.Close() + return gatherValuesFromIteratorWithKeyParser(iterator, parse, noStopFn) +} + +func GetValuesUntilDerivedStop[T any](storeObj store.KVStore, keyStart []byte, stopFn func([]byte) bool, parseValue func([]byte) (T, error)) ([]T, error) { + // SDK iterator is broken for nil end time, and non-nil start time + // https://github.com/cosmos/cosmos-sdk/issues/12661 + // hence we use []byte{0xff} + keyEnd := []byte{0xff} + return GetIterValuesWithStop(storeObj, keyStart, keyEnd, false, stopFn, parseValue) +} + +func makeIterator(storeObj store.KVStore, keyStart []byte, keyEnd []byte, reverse bool) store.Iterator { + if reverse { + return storeObj.ReverseIterator(keyStart, keyEnd) + } + return storeObj.Iterator(keyStart, keyEnd) +} + +func GetIterValuesWithStop[T any]( + storeObj store.KVStore, + keyStart []byte, + keyEnd []byte, + reverse bool, + stopFn func([]byte) bool, + parseValue func([]byte) (T, error), +) ([]T, error) { + iter := makeIterator(storeObj, keyStart, keyEnd, reverse) + defer iter.Close() + + return gatherValuesFromIterator(iter, parseValue, stopFn) +} + +// HasAnyAtPrefix returns true if there is at least one value in the given prefix. +func HasAnyAtPrefix[T any](storeObj store.KVStore, prefix []byte, parseValue func([]byte) (T, error)) (bool, error) { + _, err := GetFirstValueInRange(storeObj, prefix, sdk.PrefixEndBytes(prefix),false, parseValue) + if err != nil { + if err == ErrNoValuesInRange { + return false, nil + } + return false, err + } + + return true, nil +} + +func GetFirstValueAfterPrefixInclusive[T any](storeObj store.KVStore, keyStart []byte, parseValue func([]byte) (T, error)) (T, error) { + // SDK iterator is broken for nil end time, and non-nil start time + // https://github.com/cosmos/cosmos-sdk/issues/12661 + // hence we use []byte{0xff} + return GetFirstValueInRange(storeObj, keyStart, []byte{0xff}, false, parseValue) +} + +func GetFirstValueInRange[T any](storeObj store.KVStore, keyStart []byte, keyEnd []byte, reverseIterate bool, parseValue func([]byte) (T, error)) (T, error) { + iterator := makeIterator(storeObj, keyStart, keyEnd, reverseIterate) + defer iterator.Close() + + if !iterator.Valid() { + var blankValue T + return blankValue, ErrNoValuesInRange + } + + return parseValue(iterator.Value()) +} + +func gatherValuesFromIterator[T any](iterator db.Iterator, parseValue func([]byte) (T, error), stopFn func([]byte) bool) ([]T, error) { + // Replace a callback with the one that takes both key and value + // but ignores the key. + parseKeyValue := func(_ []byte, value []byte) (T, error) { + return parseValue(value) + } + return gatherValuesFromIteratorWithKeyParser(iterator, parseKeyValue, stopFn) +} + +func gatherValuesFromIteratorWithKeyParser[T any](iterator db.Iterator, parse func(key []byte, value []byte) (T, error), stopFn func([]byte) bool) ([]T, error) { + values := []T{} + for ; iterator.Valid(); iterator.Next() { + if stopFn(iterator.Key()) { + break + } + val, err := parse(iterator.Key(), iterator.Value()) + if err != nil { + return nil, err + } + values = append(values, val) + } + return values, nil +} + +func noStopFn([]byte) bool { + return false +} + +// MustSet runs store.Set(key, proto.Marshal(value)) +// but panics on any error. +func MustSet(storeObj store.KVStore, key []byte, value proto.Message) { + bz, err := proto.Marshal(value) + if err != nil { + panic(err) + } + + storeObj.Set(key, bz) +} + +// MustGet gets key from store by mutating result +// Panics on any error. +func MustGet(store store.KVStore, key []byte, result proto.Message) { + b := store.Get(key) + if b == nil { + panic(fmt.Errorf("getting at key (%v) should not have been nil", key)) + } + if err := proto.Unmarshal(b, result); err != nil { + panic(err) + } +} + +// MustSetDec sets dec value to store at key. Panics on any error. +func MustSetDec(store store.KVStore, key []byte, value sdk.Dec) { + MustSet(store, key, &sdk.DecProto{ + Dec: value, + }) +} + +// MustGetDec gets dec value from store at key. Panics on any error. +func MustGetDec(store store.KVStore, key []byte) sdk.Dec { + result := &sdk.DecProto{} + MustGet(store, key, result) + return result.Dec +} + +// Get returns a value at key by mutating the result parameter. Returns true if the value was found and the +// result mutated correctly. If the value is not in the store, returns false. Returns error only when database or serialization errors occur. (And when an error occurs, returns false) +func Get(store store.KVStore, key []byte, result proto.Message) (found bool, err error) { + b := store.Get(key) + if b == nil { + return false, nil + } + if err := proto.Unmarshal(b, result); err != nil { + return true, err + } + return true, nil +} diff --git a/osmoutils/store_helper_test.go b/osmoutils/store_helper_test.go new file mode 100644 index 000000000..bb7cace55 --- /dev/null +++ b/osmoutils/store_helper_test.go @@ -0,0 +1,1245 @@ +package osmoutils_test + +import ( + "errors" + "fmt" + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/gogo/protobuf/proto" + "github.com/stretchr/testify/suite" + + "github.com/cosmos/cosmos-sdk/x/auth" + authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + "github.com/cosmos/cosmos-sdk/x/params" + paramskeeper "github.com/cosmos/cosmos-sdk/x/params/keeper" + paramstypes "github.com/cosmos/cosmos-sdk/x/params/types" + + "github.com/CosmosContracts/juno/v15/osmoutils" + "github.com/CosmosContracts/juno/v15/osmoutils/noapptest" + "github.com/CosmosContracts/juno/v15/osmoutils/osmoassert" +) + +// We need to setup a test suite with account keeper +// and a custom store setup. +// unfortunately setting up account implies setting up params +type TestSuite struct { + suite.Suite + + ctx sdk.Context + store sdk.KVStore + + authStoreKey sdk.StoreKey + accountKeeper authkeeper.AccountKeeperI +} + +func (suite *TestSuite) SetupTest() { + // For the test suite, we manually wire a custom store "customStoreKey" + // Auth module (for module_account_test.go) which requires params module as well. + customStoreKey := sdk.NewKVStoreKey("osmoutil_store_test") + suite.authStoreKey = sdk.NewKVStoreKey(authtypes.StoreKey) + // setup ctx + stores + paramsKey := sdk.NewKVStoreKey(paramstypes.StoreKey) + paramsTKey := sdk.NewKVStoreKey(paramstypes.TStoreKey) + suite.ctx = noapptest.DefaultCtxWithStoreKeys( + []sdk.StoreKey{customStoreKey, suite.authStoreKey, paramsKey, paramsTKey}) + suite.store = suite.ctx.KVStore(customStoreKey) + // setup params (needed for auth) + encConfig := noapptest.MakeTestEncodingConfig(auth.AppModuleBasic{}, params.AppModuleBasic{}) + paramsKeeper := paramskeeper.NewKeeper(encConfig.Codec, encConfig.Amino, paramsKey, paramsTKey) + paramsKeeper.Subspace(authtypes.ModuleName) + + // setup auth + maccPerms := map[string][]string{ + "fee_collector": nil, + "mint": {"minter"}, + } + authsubspace, _ := paramsKeeper.GetSubspace(authtypes.ModuleName) + suite.accountKeeper = authkeeper.NewAccountKeeper( + encConfig.Codec, + suite.authStoreKey, + authsubspace, + authtypes.ProtoBaseAccount, maccPerms) +} + +const ( + keyA = "a" + keyB = "b" + keyC = "c" + mockStopValue = "stop" + afterMockStopValue = mockStopValue + keyA + basePrefix = "base" + prefixOne = "one" + prefixTwo = "two" +) + +var ( + oneA = []string{prefixOne + keyA} + oneAB = []string{prefixOne + keyA, prefixOne + keyB} + twoAB = []string{prefixTwo + keyA, prefixTwo + keyB} + oneABC = []string{prefixOne + keyA, prefixOne + keyB, prefixOne + keyC} + oneBCA = []string{prefixOne + keyB, prefixOne + keyC, prefixOne + keyA} + oneABtwoAB = []string{prefixOne + keyA, prefixOne + keyB, prefixTwo + keyA, prefixTwo + keyB} + oneBtwoAoneAtwoB = []string{prefixOne + keyB, prefixTwo + keyA, prefixOne + keyA, prefixTwo + keyB} + oneAtwoAoneBtwoB = []string{prefixOne + keyA, prefixTwo + keyA, prefixOne + keyB, prefixTwo + keyB} + onetwoABCalternating = []string{prefixOne + keyA, prefixTwo + keyA, prefixOne + keyB, prefixTwo + keyB, prefixOne + keyC, prefixTwo + keyC} + mockError = errors.New("mock error") +) + +func TestOsmoUtilsTestSuite(t *testing.T) { + suite.Run(t, new(TestSuite)) +} + +func mockParseValue(b []byte) (string, error) { + return string(b), nil +} + +func mockParseValueWithError(b []byte) (string, error) { + return "", mockError +} + +func mockStop(b []byte) bool { + return string(b) == fmt.Sprintf("%s%s", prefixOne, mockStopValue) +} + +func mockParseWithKey(key []byte, value []byte) (string, error) { + return string(key) + string(value), nil +} + +func mockParseWithKeyError(key []byte, value []byte) (string, error) { + return "", mockError +} + +func (s *TestSuite) TestGatherAllKeysFromStore() { + testcases := map[string]struct { + preSetKeys []string + expectedValues []string + }{ + "multiple keys in lexicographic order": { + preSetKeys: oneABC, + expectedValues: oneABC, + }, + "multiple keys out of lexicographic order": { + preSetKeys: oneBCA, + // we expect output to be in ascending lexicographic order + expectedValues: oneABC, + }, + "no keys": { + preSetKeys: []string{}, + expectedValues: []string{}, + }, + } + + for name, tc := range testcases { + s.Run(name, func() { + s.SetupTest() + for i, key := range tc.preSetKeys { + s.store.Set([]byte(key), []byte(fmt.Sprintf("%v", i))) + } + + actualValues := osmoutils.GatherAllKeysFromStore(s.store) + + s.Require().Equal(tc.expectedValues, actualValues) + }) + } +} + +func (s *TestSuite) TestGatherValuesFromStore() { + testcases := map[string]struct { + preSetKeys []string + keyStart []byte + keyEnd []byte + parseFn func(b []byte) (string, error) + + expectedErr error + expectedValues []string + }{ + "common prefix, exclude end": { + preSetKeys: oneAB, + + keyStart: []byte(prefixOne + keyA), + keyEnd: []byte(prefixOne + keyB), + parseFn: mockParseValue, + + expectedValues: []string{"0"}, + }, + "common prefix, include end": { + preSetKeys: oneAB, + + keyStart: []byte(prefixOne + keyA), + keyEnd: []byte(prefixOne + keyC), + parseFn: mockParseValue, + + expectedValues: []string{"0", "1"}, + }, + "different prefix, inserted in lexicographic order": { + preSetKeys: oneABtwoAB, + + keyStart: []byte(prefixOne + keyA), + keyEnd: []byte(prefixTwo + keyA), + parseFn: mockParseValue, + + expectedValues: []string{"0", "1"}, + }, + "different prefix, inserted out of lexicographic order": { + preSetKeys: oneAtwoAoneBtwoB, + + keyStart: []byte(prefixOne + keyA), + keyEnd: []byte(prefixTwo + keyA), + parseFn: mockParseValue, + + // should get all prefixOne values as keys are stored in ascending lexicographic order + expectedValues: []string{"0", "2"}, + }, + "start key and end key same": { + preSetKeys: oneA, + + keyStart: []byte(prefixOne + keyA), + keyEnd: []byte(prefixOne + keyA), + parseFn: mockParseValue, + + expectedValues: []string{}, + }, + "start key after end key": { + preSetKeys: oneABC, + + keyStart: []byte(prefixOne + keyB), + keyEnd: []byte(prefixOne + keyA), + parseFn: mockParseValue, + + expectedValues: []string{}, + }, + "get all values": { + preSetKeys: oneABC, + + keyStart: nil, + keyEnd: nil, + parseFn: mockParseValue, + + expectedValues: []string{"0", "1", "2"}, + }, + "get all values after start key": { + // SDK iterator is broken for nil end byte, and non-nil start byte + // https://github.com/cosmos/cosmos-sdk/issues/12661 + // so we use []byte{0xff} + preSetKeys: oneABC, + + keyStart: []byte(prefixOne + keyB), + keyEnd: []byte{0xff}, + parseFn: mockParseValue, + + expectedValues: []string{"1", "2"}, + }, + "parse with error": { + preSetKeys: oneABC, + + keyStart: []byte(prefixOne + keyA), + keyEnd: []byte(prefixOne + keyC), + parseFn: mockParseValueWithError, + + expectedErr: mockError, + }, + } + + for name, tc := range testcases { + s.Run(name, func() { + s.SetupTest() + + for i, key := range tc.preSetKeys { + s.store.Set([]byte(key), []byte(fmt.Sprintf("%v", i))) + } + + actualValues, err := osmoutils.GatherValuesFromStore(s.store, tc.keyStart, tc.keyEnd, tc.parseFn) + + if tc.expectedErr != nil { + s.Require().ErrorContains(err, tc.expectedErr.Error()) + s.Require().Nil(actualValues) + return + } + + s.Require().NoError(err) + s.Require().Equal(tc.expectedValues, actualValues) + }) + } +} + +func (s *TestSuite) TestGatherValuesFromStorePrefix() { + testcases := map[string]struct { + prefix []byte + preSetKeys []string + parseFn func(b []byte) (string, error) + + expectedErr error + expectedValues []string + }{ + "common prefix": { + preSetKeys: oneABC, + prefix: []byte(prefixOne), + + parseFn: mockParseValue, + + expectedValues: []string{"0", "1", "2"}, + }, + "different prefixes in order, prefix one requested": { + preSetKeys: oneABtwoAB, + prefix: []byte(prefixOne), + parseFn: mockParseValue, + + expectedValues: []string{"0", "1"}, + }, + "different prefixes in order, prefix two requested": { + preSetKeys: oneABtwoAB, + prefix: []byte(prefixTwo), + parseFn: mockParseValue, + + expectedValues: []string{"2", "3"}, + }, + "different prefixes out of order, prefix one requested": { + preSetKeys: oneBtwoAoneAtwoB, + prefix: []byte(prefixOne), + parseFn: mockParseValue, + + // we expect the prefixOne values in ascending lexicographic order + expectedValues: []string{"2", "0"}, + }, + "different prefixes out of order, prefix two requested": { + preSetKeys: oneBtwoAoneAtwoB, + prefix: []byte(prefixTwo), + parseFn: mockParseValue, + + expectedValues: []string{"1", "3"}, + }, + "prefix doesn't exist, no keys": { + preSetKeys: []string{}, + prefix: []byte(prefixOne), + parseFn: mockParseValue, + + expectedValues: []string{}, + }, + "prefix doesn't exist, only keys with another prefix": { + preSetKeys: twoAB, + prefix: []byte(prefixOne), + parseFn: mockParseValue, + + expectedValues: []string{}, + }, + "parse with error": { + preSetKeys: oneABC, + prefix: []byte(prefixOne), + parseFn: mockParseValueWithError, + + expectedErr: mockError, + }, + } + + for name, tc := range testcases { + s.Run(name, func() { + s.SetupTest() + for i, key := range tc.preSetKeys { + s.store.Set([]byte(key), []byte(fmt.Sprintf("%v", i))) + } + + actualValues, err := osmoutils.GatherValuesFromStorePrefix(s.store, tc.prefix, tc.parseFn) + + if tc.expectedErr != nil { + s.Require().ErrorContains(err, tc.expectedErr.Error()) + s.Require().Nil(actualValues) + return + } + + s.Require().NoError(err) + s.Require().Equal(tc.expectedValues, actualValues) + }) + } +} + +func (s *TestSuite) TestGatherValuesFromStorePrefixWithKeyParser() { + testcases := map[string]struct { + prefix []byte + preSetKeys []string + parseFn func(key []byte, value []byte) (string, error) + + expectedErr error + expectedValues []string + }{ + "common prefix": { + preSetKeys: oneABC, + prefix: []byte(prefixOne), + + parseFn: mockParseWithKey, + + expectedValues: []string{oneABC[0] + "0", oneABC[1] + "1", oneABC[2] + "2"}, + }, + "different prefixes in order, prefix one requested": { + preSetKeys: oneABtwoAB, + prefix: []byte(prefixOne), + parseFn: mockParseWithKey, + + expectedValues: []string{oneABtwoAB[0] + "0", oneABtwoAB[1] + "1"}, + }, + "different prefixes in order, prefix two requested": { + preSetKeys: oneABtwoAB, + prefix: []byte(prefixTwo), + parseFn: mockParseWithKey, + + expectedValues: []string{oneABtwoAB[2] + "2", oneABtwoAB[3] + "3"}, + }, + "different prefixes out of order, prefix one requested": { + preSetKeys: oneBtwoAoneAtwoB, + prefix: []byte(prefixOne), + parseFn: mockParseWithKey, + + // we expect the prefixOne values in ascending lexicographic order + expectedValues: []string{oneBtwoAoneAtwoB[2] + "2", oneBtwoAoneAtwoB[0] + "0"}, + }, + "different prefixes out of order, prefix two requested": { + preSetKeys: oneBtwoAoneAtwoB, + prefix: []byte(prefixTwo), + parseFn: mockParseWithKey, + + expectedValues: []string{oneBtwoAoneAtwoB[1] + "1", oneBtwoAoneAtwoB[3] + "3"}, + }, + "prefix doesn't exist, no keys": { + preSetKeys: []string{}, + prefix: []byte(prefixOne), + parseFn: mockParseWithKey, + + expectedValues: []string{}, + }, + "prefix doesn't exist, only keys with another prefix": { + preSetKeys: twoAB, + prefix: []byte(prefixOne), + parseFn: mockParseWithKey, + + expectedValues: []string{}, + }, + "parse with error": { + preSetKeys: oneABC, + prefix: []byte(prefixOne), + parseFn: mockParseWithKeyError, + + expectedErr: mockError, + }, + } + + for name, tc := range testcases { + s.Run(name, func() { + s.SetupTest() + for i, key := range tc.preSetKeys { + s.store.Set([]byte(key), []byte(fmt.Sprintf("%v", i))) + } + + actualValues, err := osmoutils.GatherValuesFromStorePrefixWithKeyParser(s.store, tc.prefix, tc.parseFn) + + if tc.expectedErr != nil { + s.Require().ErrorContains(err, tc.expectedErr.Error()) + s.Require().Nil(actualValues) + return + } + + s.Require().NoError(err) + s.Require().Equal(tc.expectedValues, actualValues) + }) + } +} + +func (s *TestSuite) TestGetFirstValueAfterPrefixInclusive() { + testcases := map[string]struct { + prefix []byte + preSetKeys []string + parseFn func(b []byte) (string, error) + + expectedErr error + expectedValues string + }{ + "common prefix": { + preSetKeys: oneABC, + prefix: []byte(prefixOne), + + parseFn: mockParseValue, + + expectedValues: "0", + }, + "different prefixes in order, prefix one requested": { + preSetKeys: oneABtwoAB, + prefix: []byte(prefixOne), + parseFn: mockParseValue, + + expectedValues: "0", + }, + "different prefixes in order, prefix two requested": { + preSetKeys: oneABtwoAB, + prefix: []byte(prefixTwo), + parseFn: mockParseValue, + + expectedValues: "2", + }, + "different prefixes out of order, prefix one requested": { + preSetKeys: oneBtwoAoneAtwoB, + prefix: []byte(prefixOne), + parseFn: mockParseValue, + + // we expect the prefixOne values in ascending lexicographic order + expectedValues: "2", + }, + "different prefixes out of order, prefix two requested": { + preSetKeys: oneBtwoAoneAtwoB, + prefix: []byte(prefixTwo), + parseFn: mockParseValue, + + expectedValues: "1", + }, + "prefix doesn't exist, start key lexicographically before existing keys": { + preSetKeys: twoAB, + prefix: []byte(prefixOne), + parseFn: mockParseValue, + + // we expect the first value after the prefix, which is the value associated with the first valid key + expectedValues: "0", + }, + + // error catching + "prefix doesn't exist, no keys": { + preSetKeys: []string{}, + prefix: []byte(prefixOne), + parseFn: mockParseValue, + + expectedErr: errors.New("No values in range"), + expectedValues: "", + }, + "prefix doesn't exist, start key lexicographically after existing keys": { + preSetKeys: twoAB, + prefix: []byte{0xff}, + parseFn: mockParseValue, + + expectedErr: errors.New("No values in range"), + expectedValues: "", + }, + "parse with error": { + preSetKeys: oneABC, + prefix: []byte(prefixOne), + parseFn: mockParseValueWithError, + + expectedErr: mockError, + expectedValues: "", + }, + } + + for name, tc := range testcases { + s.Run(name, func() { + s.SetupTest() + for i, key := range tc.preSetKeys { + s.store.Set([]byte(key), []byte(fmt.Sprintf("%v", i))) + } + + actualValues, err := osmoutils.GetFirstValueAfterPrefixInclusive(s.store, tc.prefix, tc.parseFn) + + if tc.expectedErr != nil { + s.Require().ErrorContains(err, tc.expectedErr.Error()) + s.Require().Equal(tc.expectedValues, actualValues) + return + } + + s.Require().NoError(err) + s.Require().Equal(tc.expectedValues, actualValues) + }) + } +} + +func (s *TestSuite) TestGatherValuesFromIterator() { + testcases := map[string]struct { + // if prefix is set, startValue and endValue are ignored. + // we either create an iterator prefix or a range iterator. + prefix string + startValue string + endValue string + preSetKeys []string + isReverse bool + + expectedValues []string + expectedErr error + }{ + "prefix iterator, no stop": { + preSetKeys: oneABC, + + prefix: prefixOne, + + expectedValues: []string{"0", "1", "2"}, + }, + "prefix iterator, with stop": { + preSetKeys: []string{prefixOne + keyA, prefixOne + mockStopValue, prefixOne + mockStopValue + keyA}, + prefix: prefixOne, + + expectedValues: []string{"0"}, + }, + "prefix iterator, with stop, different insertion order": { + // keyB is lexicographically before mockStopValue so it is returned, but before c + preSetKeys: []string{prefixOne + keyA, prefixOne + mockStopValue, prefixOne + keyB, prefixOne + mockStopValue + keyA}, + prefix: prefixOne, + + expectedValues: []string{"0", "2"}, + }, + "range iterator, no end, no stop": { + preSetKeys: oneABC, + + startValue: prefixOne + keyB, + + expectedValues: []string{"1", "2"}, + }, + "range iterator, no start, no stop": { + preSetKeys: oneABC, + + endValue: prefixOne + keyB, + + expectedValues: []string{"0"}, + }, + "range iterator, no start no end, no stop": { + preSetKeys: oneABC, + expectedValues: []string{"0", "1", "2"}, + }, + "range iterator, with stop": { + preSetKeys: []string{prefixOne + keyA, prefixOne + mockStopValue, prefixOne + afterMockStopValue}, + + expectedValues: []string{"0"}, + }, + "range iterator, reverse": { + preSetKeys: oneABC, + isReverse: true, + + expectedValues: []string{"2", "1", "0"}, + }, + "range iterator, other prefix is excluded with end value": { + preSetKeys: onetwoABCalternating, + startValue: prefixOne + keyB, + endValue: prefixOne + "d", + isReverse: true, + + expectedValues: []string{"4", "2"}, + }, + "parse with error": { + preSetKeys: oneABC, + + prefix: prefixOne, + + expectedErr: mockError, + }, + } + + for name, tc := range testcases { + s.Run(name, func() { + s.SetupTest() + var iterator sdk.Iterator + + for i, key := range tc.preSetKeys { + s.store.Set([]byte(key), []byte(fmt.Sprintf("%v", i))) + } + + if tc.prefix != "" { + iterator = sdk.KVStorePrefixIterator(s.store, []byte(tc.prefix)) + } else { + var startValue, endValue []byte + if tc.startValue != "" { + startValue = []byte(tc.startValue) + } + if tc.endValue != "" { + endValue = []byte(tc.endValue) + } + + if tc.isReverse { + iterator = s.store.ReverseIterator(startValue, endValue) + } else { + iterator = s.store.Iterator(startValue, endValue) + } + defer iterator.Close() + } + + mockParseValueFn := mockParseValue + if tc.expectedErr != nil { + mockParseValueFn = mockParseValueWithError + } + + actualValues, err := osmoutils.GatherValuesFromIterator(iterator, mockParseValueFn, mockStop) + + if tc.expectedErr != nil { + s.Require().ErrorContains(err, tc.expectedErr.Error()) + s.Require().Nil(actualValues) + return + } + + s.Require().NoError(err) + + s.Require().Equal(tc.expectedValues, actualValues) + }) + } +} + +func (s *TestSuite) TestGetIterValuesWithStop() { + testcases := map[string]struct { + preSetKeys []string + keyStart []byte + keyEnd []byte + parseFn func(b []byte) (string, error) + stopFn func(b []byte) bool + isReverse bool + + expectedValues []string + expectedErr error + }{ + "prefix iterator, no stop but exclusive key end": { + preSetKeys: oneABC, + keyStart: []byte(prefixOne + keyA), + keyEnd: []byte(prefixOne + keyC), + parseFn: mockParseValue, + stopFn: mockStop, + isReverse: false, + + expectedValues: []string{"0", "1"}, + }, + "prefix iterator, no stop and inclusive key end": { + preSetKeys: oneAB, + keyStart: []byte(prefixOne + keyA), + keyEnd: []byte(prefixOne + keyC), + parseFn: mockParseValue, + stopFn: mockStop, + isReverse: false, + + expectedValues: []string{"0", "1"}, + }, + "prefix iterator, with stop before end key": { + preSetKeys: []string{prefixOne + keyA, prefixOne + mockStopValue, prefixOne + mockStopValue + keyA}, + keyStart: []byte(prefixOne + keyA), + keyEnd: []byte(prefixOne + keyC), + parseFn: mockParseValue, + stopFn: mockStop, + isReverse: false, + + expectedValues: []string{"0"}, + }, + "prefix iterator, with end key before stop": { + preSetKeys: []string{prefixOne + keyA, prefixOne + keyB, prefixOne + mockStopValue}, + keyStart: []byte(prefixOne + keyA), + keyEnd: []byte(prefixOne + keyB), + parseFn: mockParseValue, + stopFn: mockStop, + isReverse: false, + + expectedValues: []string{"0"}, + }, + "prefix iterator, with stop, different insertion order": { + // keyB is lexicographically before mockStopValue so we expect it to be returned before we hit the stopper + preSetKeys: []string{prefixOne + keyA, prefixOne + mockStopValue, prefixOne + keyB, prefixOne + mockStopValue + keyA}, + keyStart: []byte(prefixOne + keyA), + keyEnd: []byte{0xff}, + parseFn: mockParseValue, + stopFn: mockStop, + isReverse: false, + + expectedValues: []string{"0", "2"}, + }, + "prefix iterator with stop, different insertion order, and reversed iterator": { + preSetKeys: []string{prefixOne + keyA, prefixOne + mockStopValue, prefixOne + keyB, prefixOne + mockStopValue + keyA}, + keyStart: []byte(prefixOne + keyA), + keyEnd: []byte{0xff}, + parseFn: mockParseValue, + stopFn: mockStop, + isReverse: true, + + // only the last value in our preSetKeys should be on the other end of the stopper + expectedValues: []string{"3"}, + }, + "parse with error": { + preSetKeys: oneABC, + keyStart: []byte(prefixOne + keyA), + keyEnd: []byte{0xff}, + parseFn: mockParseValueWithError, + stopFn: mockStop, + isReverse: false, + + expectedErr: mockError, + }, + } + + for name, tc := range testcases { + s.Run(name, func() { + s.SetupTest() + + for i, key := range tc.preSetKeys { + s.store.Set([]byte(key), []byte(fmt.Sprintf("%v", i))) + } + + actualValues, err := osmoutils.GetIterValuesWithStop(s.store, tc.keyStart, tc.keyEnd, tc.isReverse, tc.stopFn, tc.parseFn) + + if tc.expectedErr != nil { + s.Require().ErrorContains(err, tc.expectedErr.Error()) + s.Require().Nil(actualValues) + return + } + + s.Require().NoError(err) + + s.Require().Equal(tc.expectedValues, actualValues) + }) + } +} + +func (s *TestSuite) TestGetValuesUntilDerivedStop() { + testcases := map[string]struct { + preSetKeys []string + keyStart []byte + parseFn func(b []byte) (string, error) + stopFn func(b []byte) bool + + expectedValues []string + expectedErr error + }{ + "prefix iterator, no stop": { + preSetKeys: oneABC, + keyStart: []byte(prefixOne + keyA), + parseFn: mockParseValue, + stopFn: mockStop, + + expectedValues: []string{"0", "1", "2"}, + }, + "prefix iterator, with stop": { + preSetKeys: []string{prefixOne + keyA, prefixOne + mockStopValue, prefixOne + mockStopValue + keyA}, + keyStart: []byte(prefixOne + keyA), + parseFn: mockParseValue, + stopFn: mockStop, + + expectedValues: []string{"0"}, + }, + "prefix iterator, with stop & different insertion order": { + // keyB is lexicographically before mockStopValue so we expect it to be returned before we hit the stopper + preSetKeys: []string{prefixOne + keyA, prefixOne + mockStopValue, prefixOne + keyB, prefixOne + mockStopValue + keyA}, + keyStart: []byte(prefixOne + keyA), + parseFn: mockParseValue, + stopFn: mockStop, + + expectedValues: []string{"0", "2"}, + }, + "parse with error": { + preSetKeys: oneABC, + keyStart: []byte(prefixOne + keyA), + parseFn: mockParseValueWithError, + stopFn: mockStop, + + expectedErr: mockError, + }, + } + + for name, tc := range testcases { + s.Run(name, func() { + s.SetupTest() + for i, key := range tc.preSetKeys { + s.store.Set([]byte(key), []byte(fmt.Sprintf("%v", i))) + } + + actualValues, err := osmoutils.GetValuesUntilDerivedStop(s.store, tc.keyStart, tc.stopFn, tc.parseFn) + + if tc.expectedErr != nil { + s.Require().ErrorContains(err, tc.expectedErr.Error()) + s.Require().Nil(actualValues) + return + } + + s.Require().NoError(err) + + s.Require().Equal(tc.expectedValues, actualValues) + }) + } +} + +func (s *TestSuite) TestNoStopFn_AlwaysFalse() { + s.Require().False(osmoutils.NoStopFn([]byte(keyA))) + s.Require().False(osmoutils.NoStopFn([]byte(keyB))) +} + +// TestMustGet tests that MustGet retrieves the correct +// values from the store and panics if an error is encountered. +func (s *TestSuite) TestMustGet() { + tests := map[string]struct { + // keys and values to preset + preSetKeyValues map[string]proto.Message + + // keys and values to attempt to get and validate + expectedGetKeyValues map[string]proto.Message + + actualResultProto proto.Message + + expectPanic bool + }{ + "basic valid test": { + preSetKeyValues: map[string]proto.Message{ + keyA: &sdk.DecProto{Dec: sdk.OneDec()}, + keyB: &sdk.DecProto{Dec: sdk.OneDec().Add(sdk.OneDec())}, + keyC: &sdk.DecProto{Dec: sdk.OneDec().Add(sdk.OneDec())}, + }, + + expectedGetKeyValues: map[string]proto.Message{ + keyA: &sdk.DecProto{Dec: sdk.OneDec()}, + keyB: &sdk.DecProto{Dec: sdk.OneDec().Add(sdk.OneDec())}, + keyC: &sdk.DecProto{Dec: sdk.OneDec().Add(sdk.OneDec())}, + }, + + actualResultProto: &sdk.DecProto{}, + }, + "attempt to get non-existent key - panic": { + preSetKeyValues: map[string]proto.Message{ + keyA: &sdk.DecProto{Dec: sdk.OneDec()}, + keyC: &sdk.DecProto{Dec: sdk.OneDec().Add(sdk.OneDec())}, + }, + + expectedGetKeyValues: map[string]proto.Message{ + keyB: &sdk.DecProto{Dec: sdk.OneDec().Add(sdk.OneDec())}, + }, + + actualResultProto: &sdk.DecProto{}, + + expectPanic: true, + }, + "invalid proto Dec vs AuthParams- error": { + preSetKeyValues: map[string]proto.Message{ + keyA: &sdk.DecProto{Dec: sdk.OneDec()}, + }, + + expectedGetKeyValues: map[string]proto.Message{ + keyA: &sdk.DecProto{Dec: sdk.OneDec()}, + }, + + actualResultProto: &authtypes.Params{}, + + expectPanic: true, + }, + } + + for name, tc := range tests { + s.Run(name, func() { + s.SetupTest() + // Setup + for key, value := range tc.preSetKeyValues { + osmoutils.MustSet(s.store, []byte(key), value) + } + + osmoassert.ConditionalPanic(s.T(), tc.expectPanic, func() { + for key, expectedValue := range tc.expectedGetKeyValues { + // System under test. + osmoutils.MustGet(s.store, []byte(key), tc.actualResultProto) + // Assertions. + s.Require().Equal(expectedValue.String(), tc.actualResultProto.String()) + } + }) + }) + } +} + +// TestGet tests that Get returns a boolean indicating +// whether value exists for the given key and error +func (s *TestSuite) TestGet() { + tests := map[string]struct { + // keys and values to preset + preSetKeyValues map[string]proto.Message + + // keys and values to attempt to get and validate + expectedGetKeyValues map[string]proto.Message + + actualResultProto proto.Message + + expectFound bool + + expectErr bool + }{ + "basic valid test": { + preSetKeyValues: map[string]proto.Message{ + keyA: &sdk.DecProto{Dec: sdk.OneDec()}, + keyB: &sdk.DecProto{Dec: sdk.OneDec().Add(sdk.OneDec())}, + keyC: &sdk.DecProto{Dec: sdk.OneDec().Add(sdk.OneDec())}, + }, + + expectedGetKeyValues: map[string]proto.Message{ + keyA: &sdk.DecProto{Dec: sdk.OneDec()}, + keyB: &sdk.DecProto{Dec: sdk.OneDec().Add(sdk.OneDec())}, + keyC: &sdk.DecProto{Dec: sdk.OneDec().Add(sdk.OneDec())}, + }, + + actualResultProto: &sdk.DecProto{}, + + expectFound: true, + }, + "attempt to get non-existent key - not found & no err return": { + preSetKeyValues: map[string]proto.Message{ + keyA: &sdk.DecProto{Dec: sdk.OneDec()}, + keyC: &sdk.DecProto{Dec: sdk.OneDec().Add(sdk.OneDec())}, + }, + + expectedGetKeyValues: map[string]proto.Message{ + keyB: &sdk.DecProto{Dec: sdk.OneDec().Add(sdk.OneDec())}, + }, + + actualResultProto: &sdk.DecProto{}, + + expectFound: false, + + expectErr: false, + }, + "invalid proto Dec vs AuthParams - found but Unmarshal err": { + preSetKeyValues: map[string]proto.Message{ + keyA: &sdk.DecProto{Dec: sdk.OneDec()}, + }, + + expectedGetKeyValues: map[string]proto.Message{ + keyA: &sdk.DecProto{Dec: sdk.OneDec()}, + }, + + actualResultProto: &authtypes.Params{}, + + expectFound: true, + + expectErr: true, + }, + } + + for name, tc := range tests { + s.Run(name, func() { + s.SetupTest() + // Setup + for key, value := range tc.preSetKeyValues { + osmoutils.MustSet(s.store, []byte(key), value) + } + + for key, expectedValue := range tc.expectedGetKeyValues { + // System under test. + found, err := osmoutils.Get(s.store, []byte(key), tc.actualResultProto) + // Assertions. + s.Require().Equal(found, tc.expectFound) + if tc.expectErr { + s.Require().Error(err) + } + // make sure found by key & Unmarshal successfully + if !tc.expectErr && tc.expectFound { + s.Require().Equal(expectedValue.String(), tc.actualResultProto.String()) + } + } + }) + } +} + +// TestMustSet tests that MustSet updates the store correctly +// and panics if an error is encountered. +func (s *TestSuite) TestMustSet() { + tests := map[string]struct { + // keys and values to preset + setKey string + setValue proto.Message + + // keys and values to attempt to get and validate + getKeyValues map[string]proto.Message + + actualResultProto proto.Message + + key []byte + result proto.Message + expectPanic bool + }{ + "basic valid Dec test": { + setKey: keyA, + setValue: &sdk.DecProto{ + Dec: sdk.OneDec(), + }, + + actualResultProto: &sdk.DecProto{}, + }, + "basic valid AuthParams test": { + setKey: keyA, + setValue: &authtypes.Params{ + MaxMemoCharacters: 600, + }, + + actualResultProto: &authtypes.Params{}, + }, + "invalid set value": { + setKey: keyA, + setValue: (*sdk.DecProto)(nil), + + expectPanic: true, + }, + } + + for name, tc := range tests { + s.Run(name, func() { + osmoassert.ConditionalPanic(s.T(), tc.expectPanic, func() { + osmoutils.MustSet(s.store, []byte(tc.setKey), tc.setValue) + }) + + if tc.expectPanic { + return + } + + osmoutils.MustGet(s.store, []byte(tc.setKey), tc.actualResultProto) + s.Require().Equal(tc.setValue.String(), tc.actualResultProto.String()) + }) + } +} + +// TestMustGetDec tests that MustGetDec retrieves the correct +// decimal values from the store and panics if an error is encountered. +func (s *TestSuite) TestMustGetDec() { + tests := map[string]struct { + // keys and values to preset + preSetKeyValues map[string]sdk.Dec + + // keys and values to attempt to get and validate + expectedGetKeyValues map[string]sdk.Dec + + expectPanic bool + }{ + "valid get": { + preSetKeyValues: map[string]sdk.Dec{ + keyA: sdk.OneDec(), + keyB: sdk.OneDec().Add(sdk.OneDec()), + keyC: sdk.OneDec().Add(sdk.OneDec()).Add(sdk.OneDec()), + }, + + expectedGetKeyValues: map[string]sdk.Dec{ + keyA: sdk.OneDec(), + keyB: sdk.OneDec().Add(sdk.OneDec()), + keyC: sdk.OneDec().Add(sdk.OneDec()).Add(sdk.OneDec()), + }, + }, + "attempt to get non-existent key - panic": { + preSetKeyValues: map[string]sdk.Dec{ + keyA: sdk.OneDec(), + keyC: sdk.OneDec().Add(sdk.OneDec()).Add(sdk.OneDec()), + }, + + expectedGetKeyValues: map[string]sdk.Dec{ + keyA: sdk.OneDec(), + keyB: {}, // this one panics + }, + + expectPanic: true, + }, + } + + for name, tc := range tests { + s.Run(name, func() { + s.SetupTest() + // Setup + for key, value := range tc.preSetKeyValues { + osmoutils.MustSetDec(s.store, []byte(key), value) + } + + osmoassert.ConditionalPanic(s.T(), tc.expectPanic, func() { + for key, expectedValue := range tc.expectedGetKeyValues { + // System under test. + actualDec := osmoutils.MustGetDec(s.store, []byte(key)) + // Assertions. + s.Require().Equal(expectedValue.String(), actualDec.String()) + } + }) + }) + } +} + +// TestMustSetDec tests that MustSetDec updates the store correctly +// with the right decimal value. +// N.B.: It is non-trivial to cause a panic +// by calling `MustSetDec` because it provides +// a valid proto argument to `MustSet` which will +// only panic if the proto argument is invalid. +// Therefore, we only test a success case here. +func (s *TestSuite) TestMustSetDec() { + originalDecValue := sdk.OneDec() + + // System under test. + osmoutils.MustSetDec(s.store, []byte(keyA), originalDecValue) + + // Assertions. + retrievedDecVaue := osmoutils.MustGetDec(s.store, []byte(keyA)) + s.Require().Equal(originalDecValue.String(), retrievedDecVaue.String()) +} + +func (s *TestSuite) TestHasAnyAtPrefix() { + testcases := map[string]struct { + // if prefix is set, startValue and endValue are ignored. + // we either create an iterator prefix or a range iterator. + prefix string + startValue string + endValue string + preSetKeys []string + isReverse bool + + expectedValue bool + expectedErr error + }{ + "has one": { + preSetKeys: oneA, + + prefix: prefixOne, + + expectedValue: true, + }, + "has multiple": { + preSetKeys: oneABC, + + prefix: prefixOne, + + expectedValue: true, + }, + "has none": { + preSetKeys: oneABC, + + prefix: prefixTwo, + + expectedValue: false, + }, + "prefix lexicogrpahically below existing - does not find correctly": { + preSetKeys: twoAB, + + prefix: prefixOne, + + expectedValue: false, + }, + "prefix lexicogrpahically above existing - does not find correctly": { + preSetKeys: twoAB, + + prefix: string(sdk.PrefixEndBytes([]byte(prefixTwo))), + + expectedValue: false, + }, + "parse with error": { + preSetKeys: oneABC, + + prefix: prefixOne, + + expectedErr: mockError, + }, + } + + for name, tc := range testcases { + s.Run(name, func() { + s.SetupTest() + + for i, key := range tc.preSetKeys { + s.store.Set([]byte(key), []byte(fmt.Sprintf("%v", i))) + } + + mockParseValueFn := mockParseValue + if tc.expectedErr != nil { + mockParseValueFn = mockParseValueWithError + } + + actualValue, err := osmoutils.HasAnyAtPrefix(s.store, []byte(tc.prefix), mockParseValueFn) + + if tc.expectedErr != nil { + s.Require().ErrorContains(err, tc.expectedErr.Error()) + s.Require().False(actualValue) + return + } + + s.Require().NoError(err) + + s.Require().Equal(tc.expectedValue, actualValue) + }) + } +} diff --git a/osmoutils/sumtree/README.md b/osmoutils/sumtree/README.md new file mode 100644 index 000000000..d9aeb7abd --- /dev/null +++ b/osmoutils/sumtree/README.md @@ -0,0 +1,151 @@ +# Prefix-Sum B-Tree specification + +This module implements a B-Tree suitable for efficiently computing a +random prefix sum of data, while allowing the data to be efficiently +updated. + +The prefix sums for N elements x\_1, x\_2, ... x\_N, each with a weight +field, is the sequence y\_1, y\_2, ... y\_N, where +`y_i = sum_{0 <= j <= i} x_j.weight`. This data structure allows one to +edit, insert, and delete entries in the x sequence efficiently, and +efficiently retrieve the prefix sum at any index, where efficiently is +`O(log(N))` state operations. (Note that in the cosmos SDK stack, a +state operation is itself liable to take `O(log(N))` time) + +This is built for the use-case of we have a series of data that is +sorted by time. Each given time has an associated weight field. We want +to be able to very quickly find the total weight for all leaves with +times less than or equal to `t`. The actual implementation is agnostic +to what is the field we sort by. + +## Data structure idea + +The idea underlying this can be decomposed into two parts: + +1. Do some extra (`O(log(N))`) work when modifying the data, to allow + efficiently computing any prefix sum +2. Allow the data entries to be inserted into and deleted from, while + remaining sorted + +The solution for 1. is to build a balanced tree on top of the data. +Every inner node in the tree will be augmented with an "accumulated +weight" field, which contains the sum of the weights of all entries +below it. Notice that upon updating the weight of any leaf, the weights +of all nodes that are "above" this node can be updated efficiently. (As +there ought to only be log(N) such nodes) Furthermore, the root of the +tree's augmented value is the sum of all weights in the tree. + +Then to query the jth prefix sum, you first identify the path to the jth +node in the tree. You keep a running tally of "prefix sum thus far", +which is initialized to the sum of all weights in the tree. Then as you +walk the path from the tree root to the jth leaf, whenever there are +siblings on the right, you subtract their weight from your running +total. The weight when you arrive at the leaf is then the prefix sum. + +Lets illustrate this with a binary tree. + +![binary +tree](https://user-images.githubusercontent.com/6440154/116960474-142bf980-ac66-11eb-9a07-af84ab6d0bfa.png) + +If we want the prefix sum for leaf `12` we compute it as +`1.weight - 7.weight - 13.weight`. (We took a subtraction every time we +took a left) + +Now notice that this solution works for any tree type, where efficiency +just depends on `number of siblings * depth` and as long as that is +parameterized to be `O(log(N))` we maintain our definition of efficient. + +Thus we immediately get a solution to 2., by using a tree that supports +efficient inserts, and deletions, while still maintaining log depth and +a constant number of siblings. We opt for using a B+ tree for this, as +it performs the task well and does not require rebalance operations. +(Which can be costly in an adversarial environment) + +```{=html} + +``` + +## Implementation Details + +The B-Tree implementation under `osmoutils/sumtree` is designed specifically +for allowing efficient computation of a random prefix sum, with the +underlying data being updatable as explained above. + +Every Leaf has a `Weight` field, and the address its stored at in state +is the key which we want to sort by. The implementation sorts leaves as +byteslices, Leafs are sorted under their byteslice key, and the branch +nodes have accumulation for each childs. + +A node is pointed by a `node` struct, used internally. + +``` {.go} +type node struct { + t Tree + level uint8 + key []byte +} +``` + +A `node` struct is a pointer to the key-value pair under +`nodeKey(node.level, node.key)` + +A leaf node is simply a `uint64` integer value stored under +`nodeKey(0, key)`. The key is arbitrary length of byte slice. + +``` {.go} +type Leaf struct { + Value uint64 +} +``` + +A branch node consists of keys and accumulation of the children nodes. + +``` {.go} +type Branch struct { + Children []Child +} + +type Child struct { + Key []byte + Acc uint64 +} +``` + +The following constraints are valid for all branch nodes: + +1. For `c` in `node.Branch().Children`, the node corresponding to `c` + is stored under `nodeKey(node.level-1, c.Key)`. +2. For `c` in `node.Branch().Children`, `c.Acc` is the sum of all + `c'.Acc` where `c'` is in `c.Children`. If `c'` is leaf node, + substitute `c'.Acc` to `Leaf.Value`. +3. For `c` in `node.Branch().Children`, `c.Key` is equal or greater + than `node.key` and lesser than `node.rightSibling().key`. +4. There are no duplicate child stored in more than one of node's + `.Children`. + +### Example + +Here is an example tree data: + + - Level 2 nil + - Level 1 0xaaaa + - Level 0 0xaaaa Value 10 + - Level 0 0xaaaa01 Value 20 + - Level 0 0xaabb Value 30 + - Level 1 0xbb44 + - Level 0 0xbb55 Value 100 + - Level 0 0xbe Value 200 + - Level 1 0xeeaaaa + - Level 0 0xef1234 Value 300 + - Level 0 0xffff Value 400 + +The branch nodes will have the following childrens: + +``` {.go} +require.Equal(sumtree.Get(nodeKey(2, nil)), Children{{0xaaaa, 60}, {0xbb44, 300}, {0xeeaaaa, 700}}) +require.Equal(sumtree.Get(nodeKey(1, 0xaaaa)), Children{{0xaaaa, 10}, {0xaaaa01, 20}, {0xaabb, 30}}) +require.Equal(sumtree.Get(nodeKey(1, 0xbb44)), Children{{0xbb55, 100}, {0xbe, 200}}) +require.Equal(sumtree.Get(nodeKey(1, 0xeeaaaa)), Children{{0xef1234, 300}, {0xffff, 400}}) +``` diff --git a/osmoutils/sumtree/constants.go b/osmoutils/sumtree/constants.go new file mode 100644 index 000000000..ea5b72af2 --- /dev/null +++ b/osmoutils/sumtree/constants.go @@ -0,0 +1,13 @@ +package sumtree + +var nodeKeyPrefix []byte + +const nodeKeyPrefixLen = 5 + +func init() { + // nodeKeyPrefix is assumed to be 5 bytes + nodeKeyPrefix = []byte("node/") + if len(nodeKeyPrefix) != nodeKeyPrefixLen { + panic("Invalid constants in accumulation store") + } +} diff --git a/osmoutils/sumtree/legacy/v101/old_tree.json b/osmoutils/sumtree/legacy/v101/old_tree.json new file mode 100644 index 000000000..b98e97c8e --- /dev/null +++ b/osmoutils/sumtree/legacy/v101/old_tree.json @@ -0,0 +1,12 @@ +[ + ["bm9kZS8AAA==","Ijg0Ig=="], + ["bm9kZS8AABY/Xw+aYtHixkmBhVrYaB0NhtE=","IjU2NiI="], + ["bm9kZS8AAE8=","IjYyOSI="], + ["bm9kZS8AAHWSHmZo0tY=","IjY1MCI="], + ["bm9kZS8AAIPxX7loC058i3Y6Gx1J","Ijc5MCI="], + ["bm9kZS8AAJwWDwcC9QWY","IjE4NiI="], + ["bm9kZS8AAMUvUFTb2Wiw9xc=","IjM0NCI="], + ["bm9kZS8AANSVXIQhEQ==","Ijk1NiI="], + ["bm9kZS8AAOk2eVG6ov9s1HHE","IjMyMyI="], + ["bm9kZS8AAQ==","W3siSW5kZXgiOm51bGwsIkFjYyI6Ijg0In0seyJJbmRleCI6IkZqOWZENXBpMGVMR1NZR0ZXdGhvSFEyRzBRPT0iLCJBY2MiOiI1NjYifSx7IkluZGV4IjoiVHc9PSIsIkFjYyI6IjYyOSJ9LHsiSW5kZXgiOiJkWkllWm1qUzFnPT0iLCJBY2MiOiI2NTAifSx7IkluZGV4IjoiZy9GZnVXZ0xUbnlMZGpvYkhVaz0iLCJBY2MiOiI3OTAifSx7IkluZGV4IjoibkJZUEJ3TDFCWmc9IiwiQWNjIjoiMTg2In0seyJJbmRleCI6InhTOVFWTnZaYUxEM0Z3PT0iLCJBY2MiOiIzNDQifSx7IkluZGV4IjoiMUpWY2hDRVIiLCJBY2MiOiI5NTYifSx7IkluZGV4IjoiNlRaNVVicWkvMnpVY2NRPSIsIkFjYyI6IjMyMyJ9XQ=="] +] diff --git a/osmoutils/sumtree/legacy/v101/tree.go b/osmoutils/sumtree/legacy/v101/tree.go new file mode 100644 index 000000000..22b22a2d0 --- /dev/null +++ b/osmoutils/sumtree/legacy/v101/tree.go @@ -0,0 +1,101 @@ +package v101 + +import ( + "encoding/binary" + "encoding/json" + "fmt" + + "github.com/gogo/protobuf/proto" + + stypes "github.com/cosmos/cosmos-sdk/store/types" + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/CosmosContracts/juno/v15/osmoutils/sumtree" +) + +type Child struct { + Index []byte + Acc sdk.Int +} + +type Children []Child // branch nodes + +func migrateBranchValue(oldValueBz []byte) *sumtree.Node { + var oldValue Children + fmt.Println(string(oldValueBz)) + err := json.Unmarshal(oldValueBz, &oldValue) + if err != nil { + panic(err) + } + cs := make([]*sumtree.Child, len(oldValue)) + for i, oldChild := range oldValue { + cs[i] = &sumtree.Child{Index: oldChild.Index, Accumulation: oldChild.Acc} + } + return &sumtree.Node{Children: cs} +} + +func migrateLeafValue(index []byte, oldValueBz []byte) *sumtree.Leaf { + oldValue := sdk.ZeroInt() + err := json.Unmarshal(oldValueBz, &oldValue) + if err != nil { + panic(err) + } + return sumtree.NewLeaf(index, oldValue) +} + +func nodeKey(level uint16, key []byte) []byte { + bz := make([]byte, 2) + binary.BigEndian.PutUint16(bz, level) + return append(append([]byte("node/"), bz...), key...) +} + +func leafKey(key []byte) []byte { + return nodeKey(0, key) +} + +func migrateTreeNode(store sdk.KVStore, level uint16, key []byte) { + if level == 0 { + migrateTreeLeaf(store, key) + } else { + migrateTreeBranch(store, level, key) + } +} + +func migrateTreeBranch(store sdk.KVStore, level uint16, key []byte) { + keyBz := nodeKey(level, key) + oldValueBz := store.Get(keyBz) + fmt.Println("migrate", keyBz, string(oldValueBz), level) + newValue := migrateBranchValue(oldValueBz) + newValueBz, err := proto.Marshal(newValue) + if err != nil { + panic(err) + } + store.Set(keyBz, newValueBz) + + for _, child := range newValue.Children { + migrateTreeNode(store, level-1, child.Index) + } +} + +func migrateTreeLeaf(store sdk.KVStore, key []byte) { + keyBz := leafKey(key) + oldValueBz := store.Get(keyBz) + newValue := migrateLeafValue(key, oldValueBz) + newValueBz, err := proto.Marshal(newValue) + if err != nil { + panic(err) + } + store.Set(keyBz, newValueBz) +} + +func MigrateTree(store sdk.KVStore) { + iter := stypes.KVStoreReversePrefixIterator(store, []byte("node/")) + defer iter.Close() + if !iter.Valid() { + return + } + keybz := iter.Key()[5:] + level := binary.BigEndian.Uint16(keybz[:2]) + key := keybz[2:] + migrateTreeNode(store, level, key) +} diff --git a/osmoutils/sumtree/legacy/v101/tree_test.go b/osmoutils/sumtree/legacy/v101/tree_test.go new file mode 100644 index 000000000..d09b607bb --- /dev/null +++ b/osmoutils/sumtree/legacy/v101/tree_test.go @@ -0,0 +1,147 @@ +package v101_test + +import ( + "bytes" + "encoding/json" + "fmt" + "os" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/gogo/protobuf/proto" + + "github.com/cosmos/iavl" + + dbm "github.com/tendermint/tm-db" + + iavlstore "github.com/cosmos/cosmos-sdk/store/iavl" + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/CosmosContracts/juno/v15/osmoutils/sumtree" + v101 "github.com/CosmosContracts/juno/v15/osmoutils/sumtree/legacy/v101" +) + +func setupStore() sdk.KVStore { + db := dbm.NewMemDB() + tree, _ := iavl.NewMutableTree(db, 100, false) + _, _, err := tree.SaveVersion() + if err != nil { + panic(err) + } + kvstore := iavlstore.UnsafeNewStore(tree) + return kvstore +} + +func compareBranch(oldValueBz []byte, valueBz []byte) (err error) { + oldValue := v101.Children{} + value := sumtree.Node{} + err = json.Unmarshal(oldValueBz, &oldValue) + if err != nil { + return + } + err = proto.Unmarshal(valueBz, &value) + if err != nil { + return + } + + for i, c := range oldValue { + c2 := value.Children[i] + if !bytes.Equal(c.Index, c2.Index) || !c.Acc.Equal(c2.Accumulation) { + err = fmt.Errorf("branch value mismatch: %+v / %+v", oldValue, value) + return + } + } + return +} + +func compareLeaf(oldValueBz []byte, valueBz []byte) (err error) { + oldValue := sdk.ZeroInt() + value := sumtree.Leaf{} + err = json.Unmarshal(oldValueBz, &oldValue) + if err != nil { + return + } + err = proto.Unmarshal(valueBz, &value) + if err != nil { + return + } + + if !oldValue.Equal(value.Leaf.Accumulation) { + return fmt.Errorf("leaf value mismatch: %+v / %+v", oldValue, value) + } + return +} + +func comparePair(oldKeyBz, oldValueBz, keyBz, valueBz []byte) (err error) { + if !bytes.Equal(oldKeyBz, keyBz) { + err = fmt.Errorf("key bytes mismatch: %x / %x", oldKeyBz, keyBz) + } + + // TODO: properly select error + err = compareBranch(oldValueBz, valueBz) + if err == nil { + return nil + } + err = compareLeaf(oldValueBz, valueBz) + return err +} + +type kvPair struct { + key []byte + value []byte +} + +func pair(iter sdk.Iterator) kvPair { + res := kvPair{iter.Key(), iter.Value()} + iter.Next() + return res +} + +func extract(store sdk.KVStore) (res []kvPair) { + res = []kvPair{} + iter := store.Iterator(nil, nil) + defer iter.Close() + for iter.Valid() { + res = append(res, pair(iter)) + } + return +} + +func readold() []kvPair { + bz, err := os.ReadFile("./old_tree.json") + if err != nil { + panic(err) + } + var data [][][]byte + err = json.Unmarshal(bz, &data) + if err != nil { + panic(err) + } + res := make([]kvPair, len(data)) + for i, pair := range data { + res[i] = kvPair{pair[0], pair[1]} + } + return res +} + +func TestMigrate(t *testing.T) { + store := setupStore() + + oldpairs := readold() + for _, pair := range oldpairs { + fmt.Println("set", pair.key, pair.value) + store.Set(pair.key, pair.value) + } + + v101.MigrateTree(store) + + newpairs := extract(store) + + for i, oldpair := range oldpairs { + fmt.Println(i) + newpair := newpairs[i] + err := comparePair(oldpair.key, oldpair.value, newpair.key, newpair.value) + require.NoError(t, err) + } +} diff --git a/osmoutils/sumtree/node.go b/osmoutils/sumtree/node.go new file mode 100644 index 000000000..fd62f6f3d --- /dev/null +++ b/osmoutils/sumtree/node.go @@ -0,0 +1,261 @@ +package sumtree + +import ( + "bytes" + + "github.com/gogo/protobuf/proto" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +func NewLeaf(key []byte, acc sdk.Int) *Leaf { + return &Leaf{Leaf: &Child{ + Index: key, + Accumulation: acc, + }} +} + +func (ptr *ptr) isLeaf() bool { + return ptr.level == 0 +} + +func (ptr *ptr) node() (res *Node) { + res = new(Node) + bz := ptr.tree.store.Get(ptr.tree.nodeKey(ptr.level, ptr.key)) + if bz != nil { + if err := proto.Unmarshal(bz, res); err != nil { + panic(err) + } + } + return +} + +func (ptr *ptr) set(node *Node) { + bz, err := proto.Marshal(node) + if err != nil { + panic(err) + } + ptr.tree.store.Set(ptr.tree.nodeKey(ptr.level, ptr.key), bz) +} + +func (ptr *ptr) setLeaf(leaf *Leaf) { + if !ptr.isLeaf() { + panic("setLeaf should only be called on pointers to leaf nodes. This ptr is a branch") + } + bz, err := proto.Marshal(leaf) + if err != nil { + panic(err) + } + ptr.tree.store.Set(ptr.tree.leafKey(ptr.key), bz) +} + +func (ptr *ptr) delete() { + ptr.tree.store.Delete(ptr.tree.nodeKey(ptr.level, ptr.key)) +} + +func (ptr *ptr) leftSibling() *ptr { + iter := ptr.tree.ptrReverseIterator(ptr.level, nil, ptr.key) + defer iter.Close() + return iter.ptr() +} + +func (ptr *ptr) rightSibling() *ptr { + iter := ptr.tree.ptrIterator(ptr.level, ptr.key, nil) + defer iter.Close() + if !iter.Valid() { + return nil + } + if ptr.exists() { + // exclude ptr itself + iter.Next() + } + return iter.ptr() +} + +func (ptr *ptr) child(n uint16) *ptr { + // TODO: set end to prefix iterator end + iter := ptr.tree.ptrIterator(ptr.level-1, ptr.node().Children[n].Index, nil) + defer iter.Close() + return iter.ptr() +} + +// parent returns the parent of the provided pointer. +// Behavior is not well defined if the calling pointer does not exist in the tree. +func (ptr *ptr) parent() *ptr { + // See if there is a parent with the same 'key' as this ptr. + parent := ptr.tree.ptrGet(ptr.level+1, ptr.key) + if parent.exists() { + return parent + } + // If not, take the node in the above layer that is lexicographically the closest + // from the left of the key. + parent = parent.leftSibling() + if parent.exists() { + return parent + } + // If there is no such ptr (the parent is not in the tree), return nil + return ptr.tree.ptrGet(ptr.level+1, nil) +} + +// exists returns true if the calling pointer has a node in the tree. +func (ptr *ptr) exists() bool { + if ptr == nil { + return false + } + return ptr.tree.store.Has(ptr.tree.nodeKey(ptr.level, ptr.key)) +} + +// updateAccumulation changes the accumulation value of a ptr in the tree, +// and handles updating the accumulation for all of its parent's augmented data. +func (ptr *ptr) updateAccumulation(c *Child) { + if !ptr.exists() { + return // reached at the root + } + + node := ptr.node() + idx, match := node.find(c.Index) + if !match { + panic("non existing key pushed from the child") + } + node = node.setAcc(idx, c.Accumulation) + ptr.set(node) + ptr.parent().updateAccumulation(&Child{ptr.key, node.accumulate()}) +} + +func (ptr *ptr) push(c *Child) { + if !ptr.exists() { + ptr.create(NewNode(c)) + return + } + + cs := ptr.node() + idx, match := cs.find(c.Index) + + // setting already existing child, move to updateAccumulation + if match { + ptr.updateAccumulation(c) + return + } + + // inserting new child ptr + cs = cs.insert(idx, c) + parent := ptr.parent() + + // split and push-up if overflow + if len(cs.Children) > int(ptr.tree.m) { + split := ptr.tree.m/2 + 1 + leftnode, rightnode := cs.split(int(split)) + ptr.tree.ptrGet(ptr.level, cs.Children[split].Index).create(rightnode) + if !parent.exists() { + parent.create(NewNode( + &Child{ptr.key, leftnode.accumulate()}, + &Child{cs.Children[split].Index, rightnode.accumulate()}, + )) + ptr.set(leftnode) + return + } + // constructing right child + parent.push(&Child{cs.Children[split].Index, rightnode.accumulate()}) + cs = leftnode + parent = ptr.parent() // parent might be changed during the pushing process + } + + parent.updateAccumulation(&Child{ptr.key, cs.accumulate()}) + ptr.set(cs) +} + +func (ptr *ptr) pull(key []byte) { + if !ptr.exists() { + return // reached at the root + } + node := ptr.node() + idx, match := node.find(key) + + if !match { + panic("pulling non existing child") + } + + node = node.delete(idx) + // For sake of efficiently on our use case, we pull only when a ptr gets + // empty. + // if len(data.Index) >= int(ptr.tree.m/2) { + if len(node.Children) > 0 { + ptr.set(node) + ptr.parent().updateAccumulation(&Child{ptr.key, node.accumulate()}) + return + } + + // merge if possible + left := ptr.leftSibling() + right := ptr.rightSibling() + parent := ptr.parent() + ptr.delete() + parent.pull(ptr.key) + + if left.exists() && right.exists() { + // parent might be deleted, retrieve from left + parent = left.parent() + if bytes.Equal(parent.key, right.parent().key) { + leftnode := left.node() + rightnode := right.node() + if len(leftnode.Children)+len(rightnode.Children) < int(ptr.tree.m) { + left.set(leftnode.merge(rightnode)) + right.delete() + parent.pull(right.key) + parent.updateAccumulation(&Child{left.key, leftnode.accumulate()}) + } + } + } +} + +func (node Node) accumulate() (res sdk.Int) { + res = sdk.ZeroInt() + for _, child := range node.Children { + res = res.Add(child.Accumulation) + } + return +} + +func NewNode(cs ...*Child) *Node { + return &Node{Children: cs} +} + +// find returns the appropriate position that key should be inserted +// if match is true, idx is the exact position for the key +// if match is false, idx is the position where the key should be inserted. +func (node Node) find(key []byte) (idx int, match bool) { + for idx, child := range node.Children { + if bytes.Equal(child.Index, key) { + return idx, true + } + // Push new key to the appropriate position + if bytes.Compare(child.Index, key) > 0 { + return idx, false + } + } + + return len(node.Children), false +} + +func (node *Node) setAcc(idx int, acc sdk.Int) *Node { + node.Children[idx] = &Child{node.Children[idx].Index, acc} + return node +} + +func (node *Node) insert(idx int, c *Child) *Node { + arr := append(node.Children[:idx], append([]*Child{c}, node.Children[idx:]...)...) + return NewNode(arr...) +} + +func (node *Node) delete(idx int) *Node { + node = NewNode(append(node.Children[:idx], node.Children[idx+1:]...)...) + return node +} + +func (node *Node) split(idx int) (*Node, *Node) { + return NewNode(node.Children[:idx]...), NewNode(node.Children[idx:]...) +} + +func (node *Node) merge(node2 *Node) *Node { + return NewNode(append(node.Children, node2.Children...)...) +} diff --git a/osmoutils/sumtree/tree.go b/osmoutils/sumtree/tree.go new file mode 100644 index 000000000..9db0c53ca --- /dev/null +++ b/osmoutils/sumtree/tree.go @@ -0,0 +1,295 @@ +/// B+ tree implementation on KVStore + +package sumtree + +import ( + "bytes" + "encoding/binary" + "fmt" + + "github.com/gogo/protobuf/proto" + + store "github.com/cosmos/cosmos-sdk/store" + stypes "github.com/cosmos/cosmos-sdk/store/types" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// Tree is an augmented B+ tree implementation. +// Branches have m sized key index slice. Each key index represents +// the starting index of the child node's index(inclusive), and the +// ending index of the previous node of the child node's index(exclusive). +// TODO: We should abstract out the leaves of this tree to allow more data aside from +// the accumulation value to go there. +type Tree struct { + store store.KVStore + m uint8 +} + +func NewTree(store store.KVStore, m uint8) Tree { + tree := Tree{store, m} + if tree.IsEmpty() { + tree.Set(nil, sdk.ZeroInt()) + } + return tree +} + +func (t Tree) IsEmpty() bool { + return !t.store.Has(t.leafKey(nil)) +} + +func (t Tree) Set(key []byte, acc sdk.Int) { + ptr := t.ptrGet(0, key) + leaf := NewLeaf(key, acc) + ptr.setLeaf(leaf) + + ptr.parent().push(leaf.Leaf) +} + +func (t Tree) Remove(key []byte) { + node := t.ptrGet(0, key) + if !node.exists() { + return + } + parent := node.parent() + node.delete() + parent.pull(key) +} + +func (t Tree) Increase(key []byte, amt sdk.Int) { + value := t.Get(key) + t.Set(key, value.Add(amt)) +} + +func (t Tree) Decrease(key []byte, amt sdk.Int) { + t.Increase(key, amt.Neg()) +} + +func (t Tree) Clear() { + iter := t.store.Iterator(nil, nil) + defer iter.Close() + for ; iter.Valid(); iter.Next() { + t.store.Delete(iter.Key()) + } +} + +// ptr is pointer to a specific node inside the tree. +type ptr struct { + tree Tree + level uint16 + key []byte + // XXX: cache stored value? +} + +// ptrIterator iterates over ptrs in a given level. It only iterates directly over the pointers +// to the nodes, not the actual nodes themselves, to save loading additional data into memory. +type ptrIterator struct { + tree Tree + level uint16 + store.Iterator +} + +func (iter ptrIterator) ptr() *ptr { + if !iter.Valid() { + return nil + } + res := ptr{ + tree: iter.tree, + level: iter.level, + key: iter.Key()[7:], + } + // ptrIterator becomes invalid once retrieve ptr + err := iter.Close() + if err != nil { + panic(err) + } + return &res +} + +// nodeKey takes in a nodes layer, and its key, and constructs the +// its key in the underlying datastore. +func (t Tree) nodeKey(level uint16, key []byte) []byte { + // node key prefix is of len 7 + bz := make([]byte, nodeKeyPrefixLen+2+len(key)) + copy(bz, nodeKeyPrefix) + binary.BigEndian.PutUint16(bz[5:], level) + copy(bz[nodeKeyPrefixLen+2:], key) + return bz +} + +// leafKey constructs a key for a node pointer representing a leaf node. +func (t Tree) leafKey(key []byte) []byte { + return t.nodeKey(0, key) +} + +func (t Tree) root() *ptr { + iter := stypes.KVStoreReversePrefixIterator(t.store, nodeKeyPrefix) + defer iter.Close() + if !iter.Valid() { + return nil + } + key := iter.Key()[5:] + return &ptr{ + tree: t, + level: binary.BigEndian.Uint16(key[:2]), + key: key[2:], + } +} + +// Get returns the (sdk.Int) accumulation value at a given leaf. +func (t Tree) Get(key []byte) sdk.Int { + res := new(Leaf) + keybz := t.leafKey(key) + if !t.store.Has(keybz) { + return sdk.ZeroInt() + } + bz := t.store.Get(keybz) + err := proto.Unmarshal(bz, res) + if err != nil { + panic(err) + } + return res.Leaf.Accumulation +} + +func (ptr *ptr) create(node *Node) { + keybz := ptr.tree.nodeKey(ptr.level, ptr.key) + bz, err := proto.Marshal(node) + if err != nil { + panic(err) + } + ptr.tree.store.Set(keybz, bz) +} + +func (t Tree) ptrGet(level uint16, key []byte) *ptr { + return &ptr{ + tree: t, + level: level, + key: key, + } +} + +func (t Tree) ptrIterator(level uint16, begin, end []byte) ptrIterator { + var endBytes []byte + if end != nil { + endBytes = t.nodeKey(level, end) + } else { + endBytes = stypes.PrefixEndBytes(t.nodeKey(level, nil)) + } + return ptrIterator{ + tree: t, + level: level, + Iterator: t.store.Iterator(t.nodeKey(level, begin), endBytes), + } +} + +func (t Tree) ptrReverseIterator(level uint16, begin, end []byte) ptrIterator { + var endBytes []byte + if end != nil { + endBytes = t.nodeKey(level, end) + } else { + endBytes = stypes.PrefixEndBytes(t.nodeKey(level, nil)) + } + return ptrIterator{ + tree: t, + level: level, + Iterator: t.store.ReverseIterator(t.nodeKey(level, begin), endBytes), + } +} + +func (t Tree) Iterator(begin, end []byte) store.Iterator { + return t.ptrIterator(0, begin, end) +} + +func (t Tree) ReverseIterator(begin, end []byte) store.Iterator { + return t.ptrReverseIterator(0, begin, end) +} + +// accumulationSplit returns the accumulated value for all of the following: +// left: all leaves under nodePointer with key < provided key +// exact: leaf with key = provided key +// right: all leaves under nodePointer with key > provided key +// Note that the equalities here are _exclusive_. +func (ptr *ptr) accumulationSplit(key []byte) (left sdk.Int, exact sdk.Int, right sdk.Int) { + left, exact, right = sdk.ZeroInt(), sdk.ZeroInt(), sdk.ZeroInt() + if ptr.isLeaf() { + var leaf Leaf + bz := ptr.tree.store.Get(ptr.tree.leafKey(ptr.key)) + err := proto.Unmarshal(bz, &leaf) + if err != nil { + panic(err) + } + // Check if the leaf key is to the left of the input key, + // if so this value is on the left. Similar for the other cases. + // Recall that all of the output arguments default to 0, if unset internally. + switch bytes.Compare(ptr.key, key) { + case -1: + left = leaf.Leaf.Accumulation + case 0: + exact = leaf.Leaf.Accumulation + case 1: + right = leaf.Leaf.Accumulation + } + return + } + + node := ptr.node() + idx, match := node.find(key) + if !match { + idx-- + } + left, exact, right = ptr.tree.ptrGet(ptr.level-1, node.Children[idx].Index).accumulationSplit(key) + left = left.Add(NewNode(node.Children[:idx]...).accumulate()) + right = right.Add(NewNode(node.Children[idx+1:]...).accumulate()) + return left, exact, right +} + +// TotalAccumulatedValue returns the sum of the weights for all leaves. +func (t Tree) TotalAccumulatedValue() sdk.Int { + return t.SubsetAccumulation(nil, nil) +} + +// Prefix sum returns the total weight of all leaves with keys <= to the provided key. +func (t Tree) PrefixSum(key []byte) sdk.Int { + return t.SubsetAccumulation(nil, key) +} + +// SubsetAccumulation returns the total value of all leaves with keys +// between start and end (inclusive of both ends) +// if start is nil, it is the beginning of the tree. +// if end is nil, it is the end of the tree. +func (t Tree) SubsetAccumulation(start []byte, end []byte) sdk.Int { + if start == nil { + left, exact, _ := t.root().accumulationSplit(end) + return left.Add(exact) + } + if end == nil { + _, exact, right := t.root().accumulationSplit(start) + return exact.Add(right) + } + _, leftexact, leftrest := t.root().accumulationSplit(start) + _, _, rightest := t.root().accumulationSplit(end) + return leftexact.Add(leftrest).Sub(rightest) +} + +func (t Tree) SplitAcc(key []byte) (sdk.Int, sdk.Int, sdk.Int) { + return t.root().accumulationSplit(key) +} + +func (ptr *ptr) visualize(depth int, acc sdk.Int) { + if !ptr.exists() { + return + } + for i := 0; i < depth; i++ { + fmt.Printf(" ") + } + fmt.Printf("- ") + fmt.Printf("{%d %+v %v}\n", ptr.level, ptr.key, acc) + for i, child := range ptr.node().Children { + childnode := ptr.child(uint16(i)) + childnode.visualize(depth+1, child.Accumulation) + } +} + +// DebugVisualize prints the entire tree to stdout. +func (t Tree) DebugVisualize() { + t.root().visualize(0, sdk.Int{}) +} diff --git a/osmoutils/sumtree/tree.pb.go b/osmoutils/sumtree/tree.pb.go new file mode 100644 index 000000000..4f007610f --- /dev/null +++ b/osmoutils/sumtree/tree.pb.go @@ -0,0 +1,737 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: osmosis/sumtree/v1beta1/tree.proto + +package sumtree + +import ( + fmt "fmt" + _ "github.com/cosmos/cosmos-sdk/types" + github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types" + _ "github.com/gogo/protobuf/gogoproto" + proto "github.com/gogo/protobuf/proto" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = 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 + +type Node struct { + Children []*Child `protobuf:"bytes,1,rep,name=children,proto3" json:"children,omitempty"` +} + +func (m *Node) Reset() { *m = Node{} } +func (m *Node) String() string { return proto.CompactTextString(m) } +func (*Node) ProtoMessage() {} +func (*Node) Descriptor() ([]byte, []int) { + return fileDescriptor_31a1c5f55b935f78, []int{0} +} +func (m *Node) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Node) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Node.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 *Node) XXX_Merge(src proto.Message) { + xxx_messageInfo_Node.Merge(m, src) +} +func (m *Node) XXX_Size() int { + return m.Size() +} +func (m *Node) XXX_DiscardUnknown() { + xxx_messageInfo_Node.DiscardUnknown(m) +} + +var xxx_messageInfo_Node proto.InternalMessageInfo + +func (m *Node) GetChildren() []*Child { + if m != nil { + return m.Children + } + return nil +} + +type Child struct { + Index []byte `protobuf:"bytes,1,opt,name=index,proto3" json:"index,omitempty"` + Accumulation github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,2,opt,name=accumulation,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"accumulation"` +} + +func (m *Child) Reset() { *m = Child{} } +func (m *Child) String() string { return proto.CompactTextString(m) } +func (*Child) ProtoMessage() {} +func (*Child) Descriptor() ([]byte, []int) { + return fileDescriptor_31a1c5f55b935f78, []int{1} +} +func (m *Child) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Child) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Child.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 *Child) XXX_Merge(src proto.Message) { + xxx_messageInfo_Child.Merge(m, src) +} +func (m *Child) XXX_Size() int { + return m.Size() +} +func (m *Child) XXX_DiscardUnknown() { + xxx_messageInfo_Child.DiscardUnknown(m) +} + +var xxx_messageInfo_Child proto.InternalMessageInfo + +func (m *Child) GetIndex() []byte { + if m != nil { + return m.Index + } + return nil +} + +type Leaf struct { + Leaf *Child `protobuf:"bytes,1,opt,name=leaf,proto3" json:"leaf,omitempty"` +} + +func (m *Leaf) Reset() { *m = Leaf{} } +func (m *Leaf) String() string { return proto.CompactTextString(m) } +func (*Leaf) ProtoMessage() {} +func (*Leaf) Descriptor() ([]byte, []int) { + return fileDescriptor_31a1c5f55b935f78, []int{2} +} +func (m *Leaf) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Leaf) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Leaf.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 *Leaf) XXX_Merge(src proto.Message) { + xxx_messageInfo_Leaf.Merge(m, src) +} +func (m *Leaf) XXX_Size() int { + return m.Size() +} +func (m *Leaf) XXX_DiscardUnknown() { + xxx_messageInfo_Leaf.DiscardUnknown(m) +} + +var xxx_messageInfo_Leaf proto.InternalMessageInfo + +func (m *Leaf) GetLeaf() *Child { + if m != nil { + return m.Leaf + } + return nil +} + +func init() { + proto.RegisterType((*Node)(nil), "osmosis.store.v1beta1.Node") + proto.RegisterType((*Child)(nil), "osmosis.store.v1beta1.Child") + proto.RegisterType((*Leaf)(nil), "osmosis.store.v1beta1.Leaf") +} + +func init() { + proto.RegisterFile("osmosis/sumtree/v1beta1/tree.proto", fileDescriptor_31a1c5f55b935f78) +} + +var fileDescriptor_31a1c5f55b935f78 = []byte{ + // 302 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x91, 0xb1, 0x4e, 0xeb, 0x30, + 0x18, 0x85, 0xe3, 0x7b, 0x53, 0x04, 0xa6, 0x53, 0x54, 0xa4, 0xa8, 0x42, 0x6e, 0x94, 0x01, 0x65, + 0xa9, 0x4d, 0x60, 0xe9, 0x88, 0xca, 0x84, 0x40, 0x0c, 0x19, 0xd9, 0x1c, 0xc7, 0x4d, 0x2d, 0x92, + 0xb8, 0xc4, 0x0e, 0x82, 0xb7, 0xe0, 0xb1, 0x3a, 0x76, 0x44, 0x0c, 0x15, 0x4a, 0x5e, 0x04, 0xc5, + 0x09, 0x05, 0x24, 0x24, 0xa6, 0xdf, 0xc7, 0xfe, 0x74, 0xce, 0x91, 0x7f, 0xe8, 0x4b, 0x95, 0x4b, + 0x25, 0x14, 0x51, 0x55, 0xae, 0x4b, 0xce, 0xc9, 0x63, 0x18, 0x73, 0x4d, 0x43, 0xd2, 0x0a, 0xbc, + 0x2a, 0xa5, 0x96, 0xce, 0x51, 0xcf, 0x60, 0xa5, 0x65, 0xc9, 0x71, 0x4f, 0x8c, 0x47, 0xa9, 0x4c, + 0xa5, 0x21, 0x48, 0x7b, 0xea, 0xe0, 0x31, 0x62, 0x86, 0x26, 0x31, 0x55, 0x5f, 0x66, 0x4c, 0x8a, + 0xa2, 0x7b, 0xf7, 0x2f, 0xa0, 0x7d, 0x2b, 0x13, 0xee, 0xcc, 0xe0, 0x3e, 0x5b, 0x8a, 0x2c, 0x29, + 0x79, 0xe1, 0x02, 0xef, 0x7f, 0x70, 0x78, 0x76, 0x8c, 0x7f, 0xcd, 0xc1, 0x97, 0x2d, 0x16, 0xed, + 0x68, 0xff, 0x01, 0x0e, 0xcc, 0x95, 0x33, 0x82, 0x03, 0x51, 0x24, 0xfc, 0xc9, 0x05, 0x1e, 0x08, + 0x86, 0x51, 0x27, 0x9c, 0x08, 0x0e, 0x29, 0x63, 0x55, 0x5e, 0x65, 0x54, 0x0b, 0x59, 0xb8, 0xff, + 0x3c, 0x10, 0x1c, 0xcc, 0xf1, 0x7a, 0x3b, 0xb1, 0xde, 0xb6, 0x93, 0x93, 0x54, 0xe8, 0x65, 0x15, + 0x63, 0x26, 0x73, 0xd2, 0x37, 0xed, 0xc6, 0x54, 0x25, 0xf7, 0x44, 0x3f, 0xaf, 0xb8, 0xc2, 0x57, + 0x85, 0x8e, 0x7e, 0x78, 0xf8, 0x33, 0x68, 0xdf, 0x70, 0xba, 0x70, 0x4e, 0xa1, 0x9d, 0x71, 0xba, + 0x30, 0x81, 0x7f, 0x15, 0x36, 0xe4, 0xfc, 0x7a, 0x5d, 0x23, 0xb0, 0xa9, 0x11, 0x78, 0xaf, 0x11, + 0x78, 0x69, 0x90, 0xb5, 0x69, 0x90, 0xf5, 0xda, 0x20, 0xeb, 0x2e, 0xfc, 0xd6, 0xa4, 0xf7, 0x99, + 0x66, 0x34, 0x56, 0x9f, 0xc2, 0xcc, 0x4a, 0x8b, 0x6c, 0xb7, 0x9b, 0x78, 0xcf, 0x7c, 0xe1, 0xf9, + 0x47, 0x00, 0x00, 0x00, 0xff, 0xff, 0x30, 0x34, 0x4b, 0x32, 0xb5, 0x01, 0x00, 0x00, +} + +func (m *Node) 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 *Node) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Node) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Children) > 0 { + for iNdEx := len(m.Children) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Children[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTree(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *Child) 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 *Child) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Child) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size := m.Accumulation.Size() + i -= size + if _, err := m.Accumulation.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintTree(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + if len(m.Index) > 0 { + i -= len(m.Index) + copy(dAtA[i:], m.Index) + i = encodeVarintTree(dAtA, i, uint64(len(m.Index))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *Leaf) 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 *Leaf) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Leaf) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Leaf != nil { + { + size, err := m.Leaf.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTree(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func encodeVarintTree(dAtA []byte, offset int, v uint64) int { + offset -= sovTree(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *Node) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Children) > 0 { + for _, e := range m.Children { + l = e.Size() + n += 1 + l + sovTree(uint64(l)) + } + } + return n +} + +func (m *Child) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Index) + if l > 0 { + n += 1 + l + sovTree(uint64(l)) + } + l = m.Accumulation.Size() + n += 1 + l + sovTree(uint64(l)) + return n +} + +func (m *Leaf) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Leaf != nil { + l = m.Leaf.Size() + n += 1 + l + sovTree(uint64(l)) + } + return n +} + +func sovTree(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozTree(x uint64) (n int) { + return sovTree(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *Node) 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 ErrIntOverflowTree + } + 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: Node: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Node: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Children", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTree + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTree + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTree + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Children = append(m.Children, &Child{}) + if err := m.Children[len(m.Children)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTree(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTree + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Child) 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 ErrIntOverflowTree + } + 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: Child: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Child: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Index", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTree + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthTree + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthTree + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Index = append(m.Index[:0], dAtA[iNdEx:postIndex]...) + if m.Index == nil { + m.Index = []byte{} + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Accumulation", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTree + } + 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 ErrInvalidLengthTree + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTree + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Accumulation.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTree(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTree + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Leaf) 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 ErrIntOverflowTree + } + 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: Leaf: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Leaf: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Leaf", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTree + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTree + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTree + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Leaf == nil { + m.Leaf = &Child{} + } + if err := m.Leaf.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTree(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTree + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipTree(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, ErrIntOverflowTree + } + 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, ErrIntOverflowTree + } + 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, ErrIntOverflowTree + } + 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, ErrInvalidLengthTree + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupTree + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthTree + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthTree = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowTree = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupTree = fmt.Errorf("proto: unexpected end of group") +) diff --git a/osmoutils/sumtree/tree_test.go b/osmoutils/sumtree/tree_test.go new file mode 100644 index 000000000..bc54db386 --- /dev/null +++ b/osmoutils/sumtree/tree_test.go @@ -0,0 +1,136 @@ +package sumtree_test + +import ( + "bytes" + "math/rand" + "sort" + "testing" + + "github.com/stretchr/testify/suite" + + "github.com/cosmos/iavl" + + dbm "github.com/tendermint/tm-db" + + iavlstore "github.com/cosmos/cosmos-sdk/store/iavl" + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/CosmosContracts/juno/v15/osmoutils/sumtree" +) + +type TreeTestSuite struct { + suite.Suite + + tree sumtree.Tree +} + +func (suite *TreeTestSuite) SetupTest() { + db := dbm.NewMemDB() + tree, err := iavl.NewMutableTree(db, 100, false) + suite.Require().NoError(err) + _, _, err = tree.SaveVersion() + suite.Require().Nil(err) + kvstore := iavlstore.UnsafeNewStore(tree) + suite.tree = sumtree.NewTree(kvstore, 10) +} + +func TestTreeTestSuite(t *testing.T) { + suite.Run(t, new(TreeTestSuite)) +} + +type pair struct { + key []byte + value uint64 +} + +type pairs []pair + +var _ sort.Interface = pairs{} + +func (p pairs) Len() int { + return len(p) +} + +func (p pairs) Less(i, j int) bool { + return bytes.Compare(p[i].key, p[j].key) < 0 +} + +func (p pairs) Swap(i, j int) { + temp := p[i] + p[i] = p[j] + p[j] = temp +} + +func (p pairs) sum() (res uint64) { + for _, pair := range p { + res += pair.value + } + return +} + +func (suite *TreeTestSuite) TestTreeInvariants() { + suite.SetupTest() + + pairs := pairs{pair{[]byte("hello"), 100}} + suite.tree.Set([]byte("hello"), sdk.NewIntFromUint64(100)) + + // tested up to 2000 + for i := 0; i < 500; i++ { + // add a single element + key := make([]byte, rand.Int()%20) + value := rand.Uint64() % 100 + rand.Read(key) + idx := sort.Search(len(pairs), func(n int) bool { return bytes.Compare(pairs[n].key, key) >= 0 }) + if idx < len(pairs) { + if bytes.Equal(pairs[idx].key, key) { + pairs[idx] = pair{key, value} + } else { + pairs = append(pairs, pair{key, value}) + sort.Sort(pairs) + } + } else { + pairs = append(pairs, pair{key, value}) + } + + suite.tree.Set(key, sdk.NewIntFromUint64(value)) + + // check all is right + for _, pair := range pairs { + suite.Require().Equal(suite.tree.Get(pair.key).Uint64(), pair.value) + // XXX: check all branch nodes + } + + // check accumulation calc is alright + left, exact, right := uint64(0), pairs[0].value, pairs[1:].sum() + for idx, pair := range pairs { + tleft, texact, tright := suite.tree.SplitAcc(pair.key) + suite.Require().Equal(left, tleft.Uint64()) + suite.Require().Equal(exact, texact.Uint64()) + suite.Require().Equal(right, tright.Uint64()) + + key := append(pair.key, 0x00) + if idx == len(pairs)-1 { + break + } + if bytes.Equal(key, pairs[idx+1].key) { + break + } + + tleft, texact, tright = suite.tree.SplitAcc(key) + suite.Require().Equal(left+exact, tleft.Uint64()) + suite.Require().Equal(uint64(0), texact.Uint64()) + suite.Require().Equal(right, tright.Uint64()) + + left += exact + exact = pairs[idx+1].value + right -= exact + } + + if rand.Int()%2 == 0 { + idx := rand.Int() % len(pairs) + pair := pairs[idx] + pairs = append(pairs[:idx], pairs[idx+1:]...) + suite.tree.Remove(pair.key) + } + } +} From ae0944f66be23bfd2b127466ceb3da2fcd9be1a5 Mon Sep 17 00:00:00 2001 From: Jacob Gadikian Date: Mon, 24 Apr 2023 13:55:25 +0700 Subject: [PATCH 017/131] use ibc-go v7 in osmoutils --- app/app.go | 2 -- go.mod | 2 ++ osmoutils/cli_helpers.go | 2 +- osmoutils/ibc.go | 7 ++++--- osmoutils/noapptest/ctx.go | 4 ++-- 5 files changed, 9 insertions(+), 8 deletions(-) diff --git a/app/app.go b/app/app.go index 5a6eaac85..7cb5b60f3 100644 --- a/app/app.go +++ b/app/app.go @@ -46,7 +46,6 @@ import ( "github.com/spf13/cast" "github.com/CosmWasm/wasmd/x/wasm" - wasmclient "github.com/CosmWasm/wasmd/x/wasm/client" wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" "github.com/prometheus/client_golang/prometheus" @@ -167,7 +166,6 @@ func GetWasmOpts(appOpts servertypes.AppOptions) []wasm.Option { func getGovProposalHandlers() []govclient.ProposalHandler { var govProposalHandlers []govclient.ProposalHandler - govProposalHandlers = wasmclient.ProposalHandlers govProposalHandlers = append(govProposalHandlers, paramsclient.ProposalHandler, diff --git a/go.mod b/go.mod index f0521a279..2fd4078df 100644 --- a/go.mod +++ b/go.mod @@ -165,4 +165,6 @@ replace ( github.com/gogo/protobuf v1.3.3 => github.com/gogo/protobuf v1.3.2 github.com/cosmos/cosmos-sdk => github.com/notional-labs/cosmos-sdk v0.47.2-0.20230424060617-ebc292e8de8b + + github.com/CosmosContracts/juno/v15/osmoutils => ./osmoutils ) diff --git a/osmoutils/cli_helpers.go b/osmoutils/cli_helpers.go index e07c2d43a..98f2d9acb 100644 --- a/osmoutils/cli_helpers.go +++ b/osmoutils/cli_helpers.go @@ -5,10 +5,10 @@ import ( "strconv" "strings" + "github.com/cometbft/cometbft/crypto/ed25519" "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/testutil/network" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/tendermint/tendermint/crypto/ed25519" ) func DefaultFeeString(cfg network.Config) string { diff --git a/osmoutils/ibc.go b/osmoutils/ibc.go index 72ddedac3..774e63123 100644 --- a/osmoutils/ibc.go +++ b/osmoutils/ibc.go @@ -2,10 +2,11 @@ package osmoutils import ( "encoding/json" + sdk "github.com/cosmos/cosmos-sdk/types" - transfertypes "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - ibcexported "github.com/cosmos/ibc-go/v4/modules/core/exported" + transfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" + channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" + ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" ) // NewEmitErrorAcknowledgement creates a new error acknowledgement after having emitted an event with the diff --git a/osmoutils/noapptest/ctx.go b/osmoutils/noapptest/ctx.go index 834cf6797..2dfe2f36e 100644 --- a/osmoutils/noapptest/ctx.go +++ b/osmoutils/noapptest/ctx.go @@ -3,10 +3,10 @@ package noapptest import ( "time" + "github.com/cometbft/cometbft/libs/log" + tmproto "github.com/cometbft/cometbft/proto/tendermint/types" "github.com/cosmos/cosmos-sdk/store" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/tendermint/tendermint/libs/log" - tmproto "github.com/tendermint/tendermint/proto/tendermint/types" dbm "github.com/tendermint/tm-db" ) From 8f79106814011e4ed4fbcae62381bf7142c0fad5 Mon Sep 17 00:00:00 2001 From: Jacob Gadikian Date: Mon, 24 Apr 2023 14:00:52 +0700 Subject: [PATCH 018/131] tidy finally --- app/app.go | 13 +- go.mod | 76 ++++-- go.sum | 781 +++++++++++++++++++++++++++++++++++++++++++---------- 3 files changed, 698 insertions(+), 172 deletions(-) diff --git a/app/app.go b/app/app.go index 7cb5b60f3..0a9ac3ffc 100644 --- a/app/app.go +++ b/app/app.go @@ -7,7 +7,6 @@ import ( "strconv" "strings" - "cosmossdk.io/api" "cosmossdk.io/simapp" "github.com/CosmosContracts/juno/v15/app/openapiconsole" "github.com/CosmosContracts/juno/v15/docs" @@ -19,9 +18,9 @@ import ( "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/grpc/tmservice" - "github.com/cosmos/cosmos-sdk/client/rpc" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/codec/types" + "github.com/cosmos/cosmos-sdk/server/api" "github.com/cosmos/cosmos-sdk/server/config" servertypes "github.com/cosmos/cosmos-sdk/server/types" sdk "github.com/cosmos/cosmos-sdk/types" @@ -451,16 +450,18 @@ func (app *App) GetSubspace(moduleName string) paramstypes.Subspace { // RegisterAPIRoutes registers all application module routes with the provided // API server. -func (app *App) RegisterAPIRoutes(apiSvr *api.Server, _ config.APIConfig) { +func (app *App) RegisterAPIRoutes(apiSvr *api.Server, apiConfig config.APIConfig) { clientCtx := apiSvr.ClientCtx - rpc.RegisterRoutes(clientCtx, apiSvr.Router) // Register new tx routes from grpc-gateway. authtx.RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCGatewayRouter) + // Register new tendermint queries routes from grpc-gateway. tmservice.RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCGatewayRouter) - // Register legacy and grpc-gateway routes for all modules. - ModuleBasics.RegisterRESTRoutes(clientCtx, apiSvr.Router) + // Register node gRPC service for grpc-gateway. + nodeservice.RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCGatewayRouter) + + // Register grpc-gateway routes for all modules. ModuleBasics.RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCGatewayRouter) // register app's OpenAPI routes. diff --git a/go.mod b/go.mod index 2fd4078df..6962dae96 100644 --- a/go.mod +++ b/go.mod @@ -3,22 +3,66 @@ module github.com/CosmosContracts/juno/v15 go 1.19 require ( + cosmossdk.io/simapp v0.0.0-20230224204036-a6adb0821462 + github.com/CosmWasm/wasmd v0.40.0-rc.1.0.20230422061626-b85abcf1d7b8 + github.com/CosmosContracts/juno/v15/osmoutils v0.0.0-00010101000000-000000000000 + github.com/cometbft/cometbft v0.37.0 github.com/cometbft/cometbft-db v0.7.0 + github.com/cosmos/cosmos-sdk v0.47.1 + github.com/cosmos/ibc-go/v7 v7.0.0 github.com/golang/protobuf v1.5.3 github.com/gorilla/mux v1.8.0 github.com/grpc-ecosystem/grpc-gateway v1.16.0 github.com/prometheus/client_golang v1.15.0 github.com/spf13/cast v1.5.0 github.com/spf13/cobra v1.7.0 + github.com/strangelove-ventures/async-icq/v7 v7.0.0-20230413165143-a3b65ccdc897 + github.com/strangelove-ventures/packet-forward-middleware/v7 v7.0.0-20230412224111-136e94e98861 github.com/stretchr/testify v1.8.2 + github.com/tendermint/tm-db v0.6.8-0.20220506192307-f628bb5dc95b google.golang.org/genproto v0.0.0-20230216225411-c8e22ba71e44 google.golang.org/grpc v1.54.0 gopkg.in/yaml.v2 v2.4.0 ) require ( - github.com/CosmWasm/wasmd v0.40.0-rc.1.0.20230422061626-b85abcf1d7b8 // indirect - github.com/cosmos/cosmos-sdk v0.47.1 // indirect + cloud.google.com/go v0.110.0 // indirect + cloud.google.com/go/compute v1.18.0 // indirect + cloud.google.com/go/compute/metadata v0.2.3 // indirect + cloud.google.com/go/iam v0.12.0 // indirect + cloud.google.com/go/storage v1.29.0 // indirect + cosmossdk.io/errors v1.0.0-beta.7 // indirect + cosmossdk.io/math v1.0.0 // indirect + cosmossdk.io/tools/rosetta v0.2.1 // indirect + github.com/aws/aws-sdk-go v1.44.203 // indirect + github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect + github.com/chzyer/readline v1.5.1 // indirect + github.com/cockroachdb/apd/v2 v2.0.2 // indirect + github.com/cosmos/gogogateway v1.2.0 // indirect + github.com/cosmos/ics23/go v0.9.1-0.20221207100636-b1abd8678aab // indirect + github.com/cosmos/rosetta-sdk-go v0.10.0 // indirect + github.com/gogo/googleapis v1.4.1 // indirect + github.com/gogo/protobuf v1.3.3 // indirect + github.com/golang/mock v1.6.0 // indirect + github.com/google/uuid v1.3.0 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect + github.com/googleapis/gax-go/v2 v2.7.0 // indirect + github.com/hashicorp/go-cleanhttp v0.5.2 // indirect + github.com/hashicorp/go-getter v1.7.1 // indirect + github.com/hashicorp/go-safetemp v1.0.0 // indirect + github.com/hashicorp/go-version v1.6.0 // indirect + github.com/huandu/skiplist v1.2.0 // indirect + github.com/jmespath/go-jmespath v0.4.0 // indirect + github.com/manifoldco/promptui v0.9.0 // indirect + github.com/mitchellh/go-homedir v1.1.0 // indirect + github.com/mitchellh/go-testing-interface v1.14.1 // indirect + github.com/ulikunitz/xz v0.5.11 // indirect + golang.org/x/oauth2 v0.5.0 // indirect + golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect + google.golang.org/api v0.110.0 // indirect + google.golang.org/appengine v1.6.7 // indirect + pgregory.net/rapid v0.5.5 // indirect + sigs.k8s.io/yaml v1.3.0 // indirect ) require ( @@ -29,10 +73,7 @@ require ( 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/CosmWasm/wasmvm v1.2.3 // indirect - github.com/DataDog/zstd v1.5.0 // indirect - github.com/HdrHistogram/hdrhistogram-go v1.1.2 // indirect - github.com/Workiva/go-datastructures v1.0.53 // indirect + github.com/CosmWasm/wasmvm v1.2.3 github.com/armon/go-metrics v0.4.1 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816 // indirect @@ -40,15 +81,10 @@ require ( github.com/cenkalti/backoff/v4 v4.1.3 // indirect github.com/cespare/xxhash v1.1.0 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect - github.com/cockroachdb/errors v1.9.1 // indirect - github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect - github.com/cockroachdb/pebble v0.0.0-20220817183557-09c6e030a677 // indirect - github.com/cockroachdb/redact v1.1.3 // indirect github.com/coinbase/rosetta-sdk-go v0.7.9 // indirect github.com/confio/ics23/go v0.9.0 // indirect github.com/cosmos/btcutil v1.0.5 // indirect - github.com/cosmos/cosmos-db v0.0.0-20221226095112-f3c38ecb5e32 // indirect - github.com/cosmos/cosmos-proto v1.0.0-beta.2 // indirect + github.com/cosmos/cosmos-proto v1.0.0-beta.2 github.com/cosmos/go-bip39 v1.0.0 // indirect github.com/cosmos/gogoproto v1.4.8 github.com/cosmos/gorocksdb v1.2.0 // indirect @@ -68,12 +104,10 @@ require ( github.com/dvsekhvalnov/jose2go v1.5.0 // indirect github.com/felixge/httpsnoop v1.0.2 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect - github.com/getsentry/sentry-go v0.17.0 // indirect github.com/go-kit/kit v0.12.0 // indirect github.com/go-kit/log v0.2.1 // indirect github.com/go-logfmt/logfmt v0.6.0 // indirect github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect - github.com/gogo/gateway v1.1.0 // indirect github.com/golang/glog v1.1.0 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/snappy v0.0.4 // indirect @@ -97,11 +131,8 @@ require ( github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jmhodges/levigo v1.0.0 // indirect github.com/klauspost/compress v1.16.3 // indirect - github.com/kr/pretty v0.3.1 // indirect - github.com/kr/text v0.2.0 // indirect github.com/lib/pq v1.10.7 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect - github.com/linxGnu/grocksdb v1.7.10 // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.17 // indirect @@ -111,7 +142,6 @@ require ( 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/osmosis-labs/osmosis/osmoutils v0.0.3-rc0 // indirect github.com/pelletier/go-toml/v2 v2.0.6 // indirect github.com/petermattis/goid v0.0.0-20221215004737-a150e88a970d // indirect github.com/pkg/errors v0.9.1 // indirect @@ -121,8 +151,6 @@ require ( github.com/prometheus/procfs v0.9.0 // indirect github.com/rakyll/statik v0.1.7 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect - github.com/regen-network/cosmos-proto v0.3.1 // indirect - github.com/rogpeppe/go-internal v1.9.0 // indirect github.com/rs/cors v1.8.3 // indirect github.com/rs/zerolog v1.27.0 github.com/sasha-s/go-deadlock v0.3.1 // indirect @@ -154,6 +182,10 @@ require ( replace ( // cosmos keyring github.com/99designs/keyring => github.com/cosmos/keyring v1.2.0 + + github.com/CosmosContracts/juno/v15/osmoutils => ./osmoutils + + github.com/cosmos/cosmos-sdk => github.com/notional-labs/cosmos-sdk v0.47.2-0.20230424060617-ebc292e8de8b // dgrijalva/jwt-go is deprecated and doesn't receive security updates. // TODO: remove it: https://github.com/cosmos/cosmos-sdk/issues/13134 github.com/dgrijalva/jwt-go => github.com/golang-jwt/jwt/v4 v4.4.2 @@ -163,8 +195,4 @@ replace ( // temporary, need to fix, issue is at import of: github.com/cosmos/gogogateway github.com/gogo/protobuf v1.3.3 => github.com/gogo/protobuf v1.3.2 - - github.com/cosmos/cosmos-sdk => github.com/notional-labs/cosmos-sdk v0.47.2-0.20230424060617-ebc292e8de8b - - github.com/CosmosContracts/juno/v15/osmoutils => ./osmoutils ) diff --git a/go.sum b/go.sum index cf9ffc308..72e59e4a0 100644 --- a/go.sum +++ b/go.sum @@ -19,75 +19,233 @@ 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/go.mod h1:OO6xxXdJyvuJPcEPBLN9BJPD+jep5G1+2U5B5gkRYtA= +cloud.google.com/go v0.110.0 h1:Zc8gqp3+a9/Eyph2KDmcGaPtbKRIoqq4YTlL4NMD0Ys= +cloud.google.com/go v0.110.0/go.mod h1:SJnCLqQ0FCFGSZMUNUf84MV3Aia54kn7pi8st7tMzaY= +cloud.google.com/go/aiplatform v1.22.0/go.mod h1:ig5Nct50bZlzV6NvKaTwmplLLddFx0YReh9WfTO5jKw= +cloud.google.com/go/aiplatform v1.24.0/go.mod h1:67UUvRBKG6GTayHKV8DBv2RtR1t93YRu5B1P3x99mYY= +cloud.google.com/go/analytics v0.11.0/go.mod h1:DjEWCu41bVbYcKyvlws9Er60YE4a//bK6mnhWvQeFNI= +cloud.google.com/go/analytics v0.12.0/go.mod h1:gkfj9h6XRf9+TS4bmuhPEShsh3hH8PAZzm/41OOhQd4= +cloud.google.com/go/area120 v0.5.0/go.mod h1:DE/n4mp+iqVyvxHN41Vf1CR602GiHQjFPusMFW6bGR4= +cloud.google.com/go/area120 v0.6.0/go.mod h1:39yFJqWVgm0UZqWTOdqkLhjoC7uFfgXRC8g/ZegeAh0= +cloud.google.com/go/artifactregistry v1.6.0/go.mod h1:IYt0oBPSAGYj/kprzsBjZ/4LnG/zOcHyFHjWPCi6SAQ= +cloud.google.com/go/artifactregistry v1.7.0/go.mod h1:mqTOFOnGZx8EtSqK/ZWcsm/4U8B77rbcLP6ruDU2Ixk= +cloud.google.com/go/asset v1.5.0/go.mod h1:5mfs8UvcM5wHhqtSv8J1CtxxaQq3AdBxxQi2jGW/K4o= +cloud.google.com/go/asset v1.7.0/go.mod h1:YbENsRK4+xTiL+Ofoj5Ckf+O17kJtgp3Y3nn4uzZz5s= +cloud.google.com/go/asset v1.8.0/go.mod h1:mUNGKhiqIdbr8X7KNayoYvyc4HbbFO9URsjbytpUaW0= +cloud.google.com/go/assuredworkloads v1.5.0/go.mod h1:n8HOZ6pff6re5KYfBXcFvSViQjDwxFkAkmUFffJRbbY= +cloud.google.com/go/assuredworkloads v1.6.0/go.mod h1:yo2YOk37Yc89Rsd5QMVECvjaMKymF9OP+QXWlKXUkXw= +cloud.google.com/go/assuredworkloads v1.7.0/go.mod h1:z/736/oNmtGAyU47reJgGN+KVoYoxeLBoj4XkKYscNI= +cloud.google.com/go/automl v1.5.0/go.mod h1:34EjfoFGMZ5sgJ9EoLsRtdPSNZLcfflJR39VbVNS2M0= +cloud.google.com/go/automl v1.6.0/go.mod h1:ugf8a6Fx+zP0D59WLhqgTDsQI9w07o64uf/Is3Nh5p8= 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/bigquery v1.42.0/go.mod h1:8dRTJxhtG+vwBKzE5OseQn/hiydoQN3EedCaOdYmxRA= cloud.google.com/go/bigtable v1.2.0/go.mod h1:JcVAOl45lrTmQfLj7T6TxyMzIN/3FGGcFm+2xVAli2o= +cloud.google.com/go/billing v1.4.0/go.mod h1:g9IdKBEFlItS8bTtlrZdVLWSSdSyFUZKXNS02zKMOZY= +cloud.google.com/go/billing v1.5.0/go.mod h1:mztb1tBc3QekhjSgmpf/CV4LzWXLzCArwpLmP2Gm88s= +cloud.google.com/go/binaryauthorization v1.1.0/go.mod h1:xwnoWu3Y84jbuHa0zd526MJYmtnVXn0syOjaJgy4+dM= +cloud.google.com/go/binaryauthorization v1.2.0/go.mod h1:86WKkJHtRcv5ViNABtYMhhNWRrD1Vpi//uKEy7aYEfI= +cloud.google.com/go/cloudtasks v1.5.0/go.mod h1:fD92REy1x5woxkKEkLdvavGnPJGEn8Uic9nWuLzqCpY= +cloud.google.com/go/cloudtasks v1.6.0/go.mod h1:C6Io+sxuke9/KNRkbQpihnW93SWDU3uXt92nu85HkYI= +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.10.0/go.mod h1:ER5CLbMxl90o2jtNbGSbtfOpQKR0t15FOtRsugnLrlU= +cloud.google.com/go/compute v1.18.0 h1:FEigFqoDbys2cvFkZ9Fjq4gnHBP55anJ0yQyau2f9oY= +cloud.google.com/go/compute v1.18.0/go.mod h1:1X7yHxec2Ga+Ss6jPyjxRxpu2uu7PLgsOVXvgU0yacs= +cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= +cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= +cloud.google.com/go/containeranalysis v0.5.1/go.mod h1:1D92jd8gRR/c0fGMlymRgxWD3Qw9C1ff6/T7mLgVL8I= +cloud.google.com/go/containeranalysis v0.6.0/go.mod h1:HEJoiEIu+lEXM+k7+qLCci0h33lX3ZqoYFdmPcoO7s4= +cloud.google.com/go/datacatalog v1.3.0/go.mod h1:g9svFY6tuR+j+hrTw3J2dNcmI0dzmSiyOzm8kpLq0a0= +cloud.google.com/go/datacatalog v1.5.0/go.mod h1:M7GPLNQeLfWqeIm3iuiruhPzkt65+Bx8dAKvScX8jvs= +cloud.google.com/go/datacatalog v1.6.0/go.mod h1:+aEyF8JKg+uXcIdAmmaMUmZ3q1b/lKLtXCmXdnc0lbc= +cloud.google.com/go/dataflow v0.6.0/go.mod h1:9QwV89cGoxjjSR9/r7eFDqqjtvbKxAK2BaYU6PVk9UM= +cloud.google.com/go/dataflow v0.7.0/go.mod h1:PX526vb4ijFMesO1o202EaUmouZKBpjHsTlCtB4parQ= +cloud.google.com/go/dataform v0.3.0/go.mod h1:cj8uNliRlHpa6L3yVhDOBrUXH+BPAO1+KFMQQNSThKo= +cloud.google.com/go/dataform v0.4.0/go.mod h1:fwV6Y4Ty2yIFL89huYlEkwUPtS7YZinZbzzj5S9FzCE= +cloud.google.com/go/datalabeling v0.5.0/go.mod h1:TGcJ0G2NzcsXSE/97yWjIZO0bXj0KbVlINXMG9ud42I= +cloud.google.com/go/datalabeling v0.6.0/go.mod h1:WqdISuk/+WIGeMkpw/1q7bK/tFEZxsrFJOJdY2bXvTQ= +cloud.google.com/go/dataqna v0.5.0/go.mod h1:90Hyk596ft3zUQ8NkFfvICSIfHFh1Bc7C4cK3vbhkeo= +cloud.google.com/go/dataqna v0.6.0/go.mod h1:1lqNpM7rqNLVgWBJyk5NF6Uen2PHym0jtVJonplVsDA= 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/datastream v1.2.0/go.mod h1:i/uTP8/fZwgATHS/XFu0TcNUhuA0twZxxQ3EyCUQMwo= +cloud.google.com/go/datastream v1.3.0/go.mod h1:cqlOX8xlyYF/uxhiKn6Hbv6WjwPPuI9W2M9SAXwaLLQ= +cloud.google.com/go/dialogflow v1.15.0/go.mod h1:HbHDWs33WOGJgn6rfzBW1Kv807BE3O1+xGbn59zZWI4= +cloud.google.com/go/dialogflow v1.16.1/go.mod h1:po6LlzGfK+smoSmTBnbkIZY2w8ffjz/RcGSS+sh1el0= +cloud.google.com/go/dialogflow v1.17.0/go.mod h1:YNP09C/kXA1aZdBgC/VtXX74G/TKn7XVCcVumTflA+8= +cloud.google.com/go/documentai v1.7.0/go.mod h1:lJvftZB5NRiFSX4moiye1SMxHx0Bc3x1+p9e/RfXYiU= +cloud.google.com/go/documentai v1.8.0/go.mod h1:xGHNEB7CtsnySCNrCFdCyyMz44RhFEEX2Q7UD0c5IhU= +cloud.google.com/go/domains v0.6.0/go.mod h1:T9Rz3GasrpYk6mEGHh4rymIhjlnIuB4ofT1wTxDeT4Y= +cloud.google.com/go/domains v0.7.0/go.mod h1:PtZeqS1xjnXuRPKE/88Iru/LdfoRyEHYA9nFQf4UKpg= +cloud.google.com/go/edgecontainer v0.1.0/go.mod h1:WgkZ9tp10bFxqO8BLPqv2LlfmQF1X8lZqwW4r1BTajk= +cloud.google.com/go/edgecontainer v0.2.0/go.mod h1:RTmLijy+lGpQ7BXuTDa4C4ssxyXT34NIuHIgKuP4s5w= +cloud.google.com/go/functions v1.6.0/go.mod h1:3H1UA3qiIPRWD7PeZKLvHZ9SaQhR26XIJcC0A5GbvAk= +cloud.google.com/go/functions v1.7.0/go.mod h1:+d+QBcWM+RsrgZfV9xo6KfA1GlzJfxcfZcRPEhDDfzg= +cloud.google.com/go/gaming v1.5.0/go.mod h1:ol7rGcxP/qHTRQE/RO4bxkXq+Fix0j6D4LFPzYTIrDM= +cloud.google.com/go/gaming v1.6.0/go.mod h1:YMU1GEvA39Qt3zWGyAVA9bpYz/yAhTvaQ1t2sK4KPUA= +cloud.google.com/go/gkeconnect v0.5.0/go.mod h1:c5lsNAg5EwAy7fkqX/+goqFsU1Da/jQFqArp+wGNr/o= +cloud.google.com/go/gkeconnect v0.6.0/go.mod h1:Mln67KyU/sHJEBY8kFZ0xTeyPtzbq9StAVvEULYK16A= +cloud.google.com/go/gkehub v0.9.0/go.mod h1:WYHN6WG8w9bXU0hqNxt8rm5uxnk8IH+lPY9J2TV7BK0= +cloud.google.com/go/gkehub v0.10.0/go.mod h1:UIPwxI0DsrpsVoWpLB0stwKCP+WFVG9+y977wO+hBH0= +cloud.google.com/go/grafeas v0.2.0/go.mod h1:KhxgtF2hb0P191HlY5besjYm6MqTSTj3LSI+M+ByZHc= +cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY= +cloud.google.com/go/iam v0.5.0/go.mod h1:wPU9Vt0P4UmCux7mqtRu6jcpPAb74cP1fh50J3QpkUc= +cloud.google.com/go/iam v0.12.0 h1:DRtTY29b75ciH6Ov1PHb4/iat2CLCvrOm40Q0a6DFpE= +cloud.google.com/go/iam v0.12.0/go.mod h1:knyHGviacl11zrtZUoDuYpDgLjvr28sLQaG0YB2GYAY= +cloud.google.com/go/language v1.4.0/go.mod h1:F9dRpNFQmJbkaop6g0JhSBXCNlO90e1KWx5iDdxbWic= +cloud.google.com/go/language v1.6.0/go.mod h1:6dJ8t3B+lUYfStgls25GusK04NLh3eDLQnWM3mdEbhI= +cloud.google.com/go/lifesciences v0.5.0/go.mod h1:3oIKy8ycWGPUyZDR/8RNnTOYevhaMLqh5vLUXs9zvT8= +cloud.google.com/go/lifesciences v0.6.0/go.mod h1:ddj6tSX/7BOnhxCSd3ZcETvtNr8NZ6t/iPhY2Tyfu08= +cloud.google.com/go/longrunning v0.3.0 h1:NjljC+FYPV3uh5/OwWT6pVU+doBqMg2x/rZlE+CamDs= +cloud.google.com/go/mediatranslation v0.5.0/go.mod h1:jGPUhGTybqsPQn91pNXw0xVHfuJ3leR1wj37oU3y1f4= +cloud.google.com/go/mediatranslation v0.6.0/go.mod h1:hHdBCTYNigsBxshbznuIMFNe5QXEowAuNmmC7h8pu5w= +cloud.google.com/go/memcache v1.4.0/go.mod h1:rTOfiGZtJX1AaFUrOgsMHX5kAzaTQ8azHiuDoTPzNsE= +cloud.google.com/go/memcache v1.5.0/go.mod h1:dk3fCK7dVo0cUU2c36jKb4VqKPS22BTkf81Xq617aWM= +cloud.google.com/go/metastore v1.5.0/go.mod h1:2ZNrDcQwghfdtCwJ33nM0+GrBGlVuh8rakL3vdPY3XY= +cloud.google.com/go/metastore v1.6.0/go.mod h1:6cyQTls8CWXzk45G55x57DVQ9gWg7RiH65+YgPsNh9s= +cloud.google.com/go/networkconnectivity v1.4.0/go.mod h1:nOl7YL8odKyAOtzNX73/M5/mGZgqqMeryi6UPZTk/rA= +cloud.google.com/go/networkconnectivity v1.5.0/go.mod h1:3GzqJx7uhtlM3kln0+x5wyFvuVH1pIBJjhCpjzSt75o= +cloud.google.com/go/networksecurity v0.5.0/go.mod h1:xS6fOCoqpVC5zx15Z/MqkfDwH4+m/61A3ODiDV1xmiQ= +cloud.google.com/go/networksecurity v0.6.0/go.mod h1:Q5fjhTr9WMI5mbpRYEbiexTzROf7ZbDzvzCrNl14nyU= +cloud.google.com/go/notebooks v1.2.0/go.mod h1:9+wtppMfVPUeJ8fIWPOq1UnATHISkGXGqTkxeieQ6UY= +cloud.google.com/go/notebooks v1.3.0/go.mod h1:bFR5lj07DtCPC7YAAJ//vHskFBxA5JzYlH68kXVdk34= +cloud.google.com/go/osconfig v1.7.0/go.mod h1:oVHeCeZELfJP7XLxcBGTMBvRO+1nQ5tFG9VQTmYS2Fs= +cloud.google.com/go/osconfig v1.8.0/go.mod h1:EQqZLu5w5XA7eKizepumcvWx+m8mJUhEwiPqWiZeEdg= +cloud.google.com/go/oslogin v1.4.0/go.mod h1:YdgMXWRaElXz/lDk1Na6Fh5orF7gvmJ0FGLIs9LId4E= +cloud.google.com/go/oslogin v1.5.0/go.mod h1:D260Qj11W2qx/HVF29zBg+0fd6YCSjSqLUkY/qEenQU= +cloud.google.com/go/phishingprotection v0.5.0/go.mod h1:Y3HZknsK9bc9dMi+oE8Bim0lczMU6hrX0UpADuMefr0= +cloud.google.com/go/phishingprotection v0.6.0/go.mod h1:9Y3LBLgy0kDTcYET8ZH3bq/7qni15yVUoAxiFxnlSUA= +cloud.google.com/go/privatecatalog v0.5.0/go.mod h1:XgosMUvvPyxDjAVNDYxJ7wBW8//hLDDYmnsNcMGq1K0= +cloud.google.com/go/privatecatalog v0.6.0/go.mod h1:i/fbkZR0hLN29eEWiiwue8Pb+GforiEIBnV9yrRUOKI= 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= cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/recaptchaenterprise v1.3.1/go.mod h1:OdD+q+y4XGeAlxRaMn1Y7/GveP6zmq76byL6tjPE7d4= +cloud.google.com/go/recaptchaenterprise/v2 v2.1.0/go.mod h1:w9yVqajwroDNTfGuhmOjPDN//rZGySaf6PtFVcSCa7o= +cloud.google.com/go/recaptchaenterprise/v2 v2.2.0/go.mod h1:/Zu5jisWGeERrd5HnlS3EUGb/D335f9k51B/FVil0jk= +cloud.google.com/go/recaptchaenterprise/v2 v2.3.0/go.mod h1:O9LwGCjrhGHBQET5CA7dd5NwwNQUErSgEDit1DLNTdo= +cloud.google.com/go/recommendationengine v0.5.0/go.mod h1:E5756pJcVFeVgaQv3WNpImkFP8a+RptV6dDLGPILjvg= +cloud.google.com/go/recommendationengine v0.6.0/go.mod h1:08mq2umu9oIqc7tDy8sx+MNJdLG0fUi3vaSVbztHgJ4= +cloud.google.com/go/recommender v1.5.0/go.mod h1:jdoeiBIVrJe9gQjwd759ecLJbxCDED4A6p+mqoqDvTg= +cloud.google.com/go/recommender v1.6.0/go.mod h1:+yETpm25mcoiECKh9DEScGzIRyDKpZ0cEhWGo+8bo+c= +cloud.google.com/go/redis v1.7.0/go.mod h1:V3x5Jq1jzUcg+UNsRvdmsfuFnit1cfe3Z/PGyq/lm4Y= +cloud.google.com/go/redis v1.8.0/go.mod h1:Fm2szCDavWzBk2cDKxrkmWBqoCiL1+Ctwq7EyqBCA/A= +cloud.google.com/go/retail v1.8.0/go.mod h1:QblKS8waDmNUhghY2TI9O3JLlFk8jybHeV4BF19FrE4= +cloud.google.com/go/retail v1.9.0/go.mod h1:g6jb6mKuCS1QKnH/dpu7isX253absFl6iE92nHwlBUY= +cloud.google.com/go/scheduler v1.4.0/go.mod h1:drcJBmxF3aqZJRhmkHQ9b3uSSpQoltBPGPxGAWROx6s= +cloud.google.com/go/scheduler v1.5.0/go.mod h1:ri073ym49NW3AfT6DZi21vLZrG07GXr5p3H1KxN5QlI= +cloud.google.com/go/secretmanager v1.6.0/go.mod h1:awVa/OXF6IiyaU1wQ34inzQNc4ISIDIrId8qE5QGgKA= +cloud.google.com/go/security v1.5.0/go.mod h1:lgxGdyOKKjHL4YG3/YwIL2zLqMFCKs0UbQwgyZmfJl4= +cloud.google.com/go/security v1.7.0/go.mod h1:mZklORHl6Bg7CNnnjLH//0UlAlaXqiG7Lb9PsPXLfD0= +cloud.google.com/go/security v1.8.0/go.mod h1:hAQOwgmaHhztFhiQ41CjDODdWP0+AE1B3sX4OFlq+GU= +cloud.google.com/go/securitycenter v1.13.0/go.mod h1:cv5qNAqjY84FCN6Y9z28WlkKXyWsgLO832YiWwkCWcU= +cloud.google.com/go/securitycenter v1.14.0/go.mod h1:gZLAhtyKv85n52XYWt6RmeBdydyxfPeTrpToDPw4Auc= +cloud.google.com/go/servicedirectory v1.4.0/go.mod h1:gH1MUaZCgtP7qQiI+F+A+OpeKF/HQWgtAddhTbhL2bs= +cloud.google.com/go/servicedirectory v1.5.0/go.mod h1:QMKFL0NUySbpZJ1UZs3oFAmdvVxhhxB6eJ/Vlp73dfg= +cloud.google.com/go/speech v1.6.0/go.mod h1:79tcr4FHCimOp56lwC01xnt/WPJZc4v3gzyT7FoBkCM= +cloud.google.com/go/speech v1.7.0/go.mod h1:KptqL+BAQIhMsj1kOP2la5DSEEerPDuOP/2mmkhHhZQ= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= 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/go.mod h1:vOEEDNFnciUMhBeT6hsJIn3ieU5cFRmzeLgDvXzfIXc= +cloud.google.com/go/storage v1.27.0/go.mod h1:x9DOL8TK/ygDUMieqwfhdpQryTeEkhGKMi80i/iqR2s= +cloud.google.com/go/storage v1.29.0 h1:6weCgzRvMg7lzuUurI4697AqIRPU1SvzHhynwpW31jI= +cloud.google.com/go/storage v1.29.0/go.mod h1:4puEjyTKnku6gfKoTfNOU/W+a9JyuVNxjpS5GBrB8h4= +cloud.google.com/go/talent v1.1.0/go.mod h1:Vl4pt9jiHKvOgF9KoZo6Kob9oV4lwd/ZD5Cto54zDRw= +cloud.google.com/go/talent v1.2.0/go.mod h1:MoNF9bhFQbiJ6eFD3uSsg0uBALw4n4gaCaEjBw9zo8g= +cloud.google.com/go/videointelligence v1.6.0/go.mod h1:w0DIDlVRKtwPCn/C4iwZIJdvC69yInhW0cfi+p546uU= +cloud.google.com/go/videointelligence v1.7.0/go.mod h1:k8pI/1wAhjznARtVT9U1llUaFNPh7muw8QyOUpavru4= +cloud.google.com/go/vision v1.2.0/go.mod h1:SmNwgObm5DpFBme2xpyOyasvBc1aPdjvMk2bBk0tKD0= +cloud.google.com/go/vision/v2 v2.2.0/go.mod h1:uCdV4PpN1S0jyCyq8sIM42v2Y6zOLkZs+4R9LrGYwFo= +cloud.google.com/go/vision/v2 v2.3.0/go.mod h1:UO61abBx9QRMFkNBbf1D8B1LXdS2cGiiCRx0vSpZoUo= +cloud.google.com/go/webrisk v1.4.0/go.mod h1:Hn8X6Zr+ziE2aNd8SliSDWpEnSS1u4R9+xXZmFiHmGE= +cloud.google.com/go/webrisk v1.5.0/go.mod h1:iPG6fr52Tv7sGk0H6qUFzmL3HHZev1htXuWDEEsqMTg= +cloud.google.com/go/workflows v1.6.0/go.mod h1:6t9F5h/unJz41YqfBmqSASJSXccBLtD1Vwf+KmJENM0= +cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoISEXH2bcHC3M= collectd.org v0.3.0/go.mod h1:A/8DzQBkF6abtvrT2j/AU/4tiBgJWYyh0y/oB/4MlWE= -cosmossdk.io/api v0.2.5-0.20230419061743-48d3d99110e7 h1:GTktofPmReteYJY0UWyeZpwp2T8DMgco5xhbRp3lsc0= -cosmossdk.io/api v0.2.5-0.20230419061743-48d3d99110e7/go.mod h1:z7wxLneHxynJAwnCtm+gd+Rnx4Tn1e4LJ7klB5C/5FY= +cosmossdk.io/api v0.3.1 h1:NNiOclKRR0AOlO4KIqeaG6PS6kswOMhHD0ir0SscNXE= cosmossdk.io/api v0.3.1/go.mod h1:DfHfMkiNA2Uhy8fj0JJlOCYOBp4eWUUJ1te5zBGNyIw= -cosmossdk.io/core v0.3.2 h1:KlQIufpJHJvOs7YLGTZsZcCo1WlkencDXepsr8STKZQ= -cosmossdk.io/core v0.3.2/go.mod h1:CO7vbe+evrBvHc0setFHL/u7nlY7HJGzdRSBkT/sirc= +cosmossdk.io/core v0.5.1 h1:vQVtFrIYOQJDV3f7rw4pjjVqc1id4+mE0L9hHP66pyI= cosmossdk.io/core v0.5.1/go.mod h1:KZtwHCLjcFuo0nmDc24Xy6CRNEL9Vl/MeimQ2aC7NLE= +cosmossdk.io/depinject v1.0.0-alpha.3 h1:6evFIgj//Y3w09bqOUOzEpFj5tsxBqdc5CfkO7z+zfw= cosmossdk.io/depinject v1.0.0-alpha.3/go.mod h1:eRbcdQ7MRpIPEM5YUJh8k97nxHpYbc3sMUnEtt8HPWU= +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 h1:ro9w7eKx23om2tZz/VM2Pf+z2WAbGX1yDQQOJ6iGeJw= +cosmossdk.io/math v1.0.0/go.mod h1:Ygz4wBHrgc7g0N+8+MrnTfS9LLn9aaTGa9hKopuym5k= +cosmossdk.io/simapp v0.0.0-20230224204036-a6adb0821462 h1:g8muUHnXL8vhld2Sjilyhb1UQObc+x9GVuDK43TYZns= +cosmossdk.io/simapp v0.0.0-20230224204036-a6adb0821462/go.mod h1:4Dd3NLoLYoN90kZ0uyHoTHzVVk9+J0v4HhZRBNTAq2c= +cosmossdk.io/tools/rosetta v0.2.1 h1:ddOMatOH+pbxWbrGJKRAawdBkPYLfKXutK9IETnjYxw= +cosmossdk.io/tools/rosetta v0.2.1/go.mod h1:Pqdc1FdvkNV3LcNIkYWt2RQY6IP1ge6YWZk8MhhO9Hw= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= filippo.io/edwards25519 v1.0.0-rc.1/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns= +filippo.io/edwards25519 v1.0.0 h1:0wAIcmJUqRdI8IJ/3eGi5/HwXZWPujYXXlkrQogz0Ek= filippo.io/edwards25519 v1.0.0/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/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= 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/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/CloudyKit/fastprinter v0.0.0-20170127035650-74b38d55f37a/go.mod h1:EFZQ978U7x8IRnstaskI3IysnWY5Ao3QgZUKOXlsAdw= -github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno= -github.com/CloudyKit/jet v2.1.3-0.20180809161101-62edd43e4f88+incompatible/go.mod h1:HPYO+50pSWkPoj9Q/eq0aRGByCL6ScRlUmiEX5Zgm+w= -github.com/CloudyKit/jet/v3 v3.0.0/go.mod h1:HKQPgSJmdK8hdoAbKUUWajkHyHo4RaU5rMdUywE7VMo= -github.com/CosmWasm/wasmd v0.31.0-rc0/go.mod h1:K7PYeURGa725BFo8z2VEmch+MVWtkEMrSEw1v/vpG94= github.com/CosmWasm/wasmd v0.40.0-rc.1.0.20230422061626-b85abcf1d7b8 h1:daJIcrTcYkpDtn1DXqbGhnQkCPSD93El6mXfv15VJRA= github.com/CosmWasm/wasmd v0.40.0-rc.1.0.20230422061626-b85abcf1d7b8/go.mod h1:uacdue6EGn9JA1TqBNHB3iCe4PCIChuFT23AzIl2VME= +github.com/CosmWasm/wasmvm v1.2.3 h1:OKYlobwmVGbl0eSn0mXoAAjE5hIuXnQCLPjbNd91sVY= github.com/CosmWasm/wasmvm v1.2.3/go.mod h1:vW/E3h8j9xBQs9bCoijDuawKo9kCtxOaS8N8J7KFtkc= 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.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= github.com/DataDog/zstd v1.5.0/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= -github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo= -github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= -github.com/Joker/jade v1.0.1-0.20190614124447-d475f43051e7/go.mod h1:6E6s8o2AE4KhCrqr6GRJjdC/gNfTdxkIXvuGZZda2VM= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= +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= -github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= 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/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/go.mod h1:1yZL+zfsztete+ePzZz/Zb1/t5BnDuE2Ya2MMGhzP6A= github.com/Zilliqa/gozilliqa-sdk v1.2.1-0.20201201074141-dd0ecada1be6/go.mod h1:eSYp2T6f0apnuW8TzhV3f6Aff2SE8Dwio++U4ha4yEM= +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/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= +github.com/alecthomas/participle/v2 v2.0.0-alpha7 h1:cK4vjj0VSgb3lN1nuKA5F7dw+1s1pWBe5bx7nNCnN+c= 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= @@ -102,11 +260,15 @@ github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb 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= +github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA= github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4= 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.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/aws/aws-sdk-go v1.44.122/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= +github.com/aws/aws-sdk-go v1.44.203 h1:pcsP805b9acL3wUqa4JR2vg1k2wnItkDYNvfmcy6F+U= +github.com/aws/aws-sdk-go v1.44.203/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= 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= @@ -117,11 +279,14 @@ github.com/aws/aws-sdk-go-v2/service/route53 v1.1.1/go.mod h1:rLiOUrPLW/Er5kRcQ7 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/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= 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/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816 h1:41iFGWnSlI2gVpmOtVTJZNodLdLQLn/KsJqFvXwnd/s= github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816/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= @@ -129,10 +294,13 @@ github.com/btcsuite/btcd v0.0.0-20190315201642-aa6e0f35703c/go.mod h1:DrZx5ec/dm 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.22.1/go.mod h1:wqgTSL29+50LRkmOVknEdmt8ZojIzhuWvgu/iptuN7Y= -github.com/btcsuite/btcd v0.22.2/go.mod h1:wqgTSL29+50LRkmOVknEdmt8ZojIzhuWvgu/iptuN7Y= +github.com/btcsuite/btcd v0.22.2 h1:vBZ+lGGd1XubpOWO67ITJpAEsICWhA0YzqkcpkgNBfo= github.com/btcsuite/btcd/btcec/v2 v2.1.2/go.mod h1:ctjw4H1kknNJmRN4iP1R7bTQ+v3GJkZBd6mui8ZsAZE= +github.com/btcsuite/btcd/btcec/v2 v2.3.2 h1:5n0X6hX0Zk+6omWcihdYvdAlGf2DfasC0GMf7DClJ3U= github.com/btcsuite/btcd/btcec/v2 v2.3.2/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= +github.com/btcsuite/btcd/btcutil v1.1.2 h1:XLMbX8JQEiwMcYft2EGi8zPUkoa0abKIU6/BJSRsjzQ= 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-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= @@ -149,17 +317,28 @@ github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46f 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= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/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/logex v1.2.1 h1:XHDu3E6q+gdHgsdTPH6ImJMIp436vR6MPtH8gP05QzM= +github.com/chzyer/logex v1.2.1/go.mod h1:JLbx6lG2kDbNRFnfkgvh4eRJRPX1QCoOIWomwysCBrQ= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/readline v1.5.1 h1:upd/6fQk4src78LMRzh5vItIt361/o4uq553V8B5sGI= +github.com/chzyer/readline v1.5.1/go.mod h1:Eh+b79XXUwfKfcPLepksvw2tcLE/Ct21YObkaSkeBlk= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/chzyer/test v1.0.0 h1:p3BQDXSxOhOG0P9z6/hGnII4LGiEPOYBhs8asl/fC04= +github.com/chzyer/test v1.0.0/go.mod h1:2JlltgoNkt4TW/z9V/IzDdFaMTM2JPIi26O1pF38GC8= 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= @@ -168,96 +347,126 @@ github.com/cloudflare/cloudflare-go v0.14.0/go.mod h1:EnwdgGMaFOruiPZRFSgn+TsQ3h github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= +github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +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/apd/v3 v3.1.0 h1:MK3Ow7LH0W8zkd5GMKA1PvS9qG3bWFI95WaVNfyZJ/w= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= -github.com/cockroachdb/datadriven v1.0.0/go.mod h1:5Ib8Meh+jk1RlHIXej6Pzevx/NLlNvQB9pmSBZErGA4= -github.com/cockroachdb/datadriven v1.0.2/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= -github.com/cockroachdb/errors v1.6.1/go.mod h1:tm6FTP5G81vwJ5lC0SizQo374JNCOPrHyXGitRJoDqM= -github.com/cockroachdb/errors v1.8.1/go.mod h1:qGwQn6JmZ+oMjuLwjWzUNqblqk0xl4CVV3SQbGwK7Ac= -github.com/cockroachdb/errors v1.9.1/go.mod h1:2sxOtL2WIc096WSZqZ5h8fa17rdDq9HZOZLBCor4mBk= -github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI= -github.com/cockroachdb/logtags v0.0.0-20211118104740-dabe8e521a4f/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= -github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= -github.com/cockroachdb/pebble v0.0.0-20220817183557-09c6e030a677/go.mod h1:890yq1fUb9b6dGNwssgeUO5vQV9qfXnCPxAJhBQfXw0= -github.com/cockroachdb/redact v1.0.8/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= -github.com/cockroachdb/redact v1.1.3/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= -github.com/cockroachdb/sentry-go v0.6.1-cockroachdb.2/go.mod h1:8BT+cPK6xvFOcRlk0R8eg+OTkcqI6baNH4xAkpiYVvQ= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= -github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= 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/cometbft/cometbft v0.37.0 h1:M005vBaSaugvYYmNZwJOopynQSjwLoDTwflnQ/I/eYk= +github.com/cometbft/cometbft v0.37.0/go.mod h1:Y2MMMN//O5K4YKd8ze4r9jmk4Y7h0ajqILXbH5JQFVs= +github.com/cometbft/cometbft-db v0.7.0 h1:uBjbrBx4QzU0zOEnU8KxoDl18dMNgDh+zZRUE0ucsbo= github.com/cometbft/cometbft-db v0.7.0/go.mod h1:yiKJIm2WKrt6x8Cyxtq9YTEcIMPcEe4XPxhgX59Fzf0= +github.com/confio/ics23/go v0.9.0 h1:cWs+wdbS2KRPZezoaaj+qBleXgUk5WOQFMP3CQFGTr4= github.com/confio/ics23/go v0.9.0/go.mod h1:4LPZ2NYqnYIVRklaozjNR1FScgDJ2s5Xrp+e/mYVRak= 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= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/cosmos/btcutil v1.0.5 h1:t+ZFcX77LpKtDBhjucvnOH8C2l2ioGsBNEQ3jef8xFk= github.com/cosmos/btcutil v1.0.5/go.mod h1:IyB7iuqZMJlthe2tkIFL33xPyzbFYP0XVdS8P5lUPis= -github.com/cosmos/cosmos-db v0.0.0-20221226095112-f3c38ecb5e32/go.mod h1:kwMlEC4wWvB48zAShGKVqboJL6w4zCLesaNQ3YLU2BQ= +github.com/cosmos/cosmos-proto v1.0.0-beta.2 h1:X3OKvWgK9Gsejo0F1qs5l8Qn6xJV/AzgIWR2wZ8Nua8= github.com/cosmos/cosmos-proto v1.0.0-beta.2/go.mod h1:+XRCLJ14pr5HFEHIUcn51IKXD1Fy3rkEQqt4WqmN4V0= -github.com/cosmos/cosmos-sdk v0.46.12/go.mod h1:bG4AkW9bqc8ycrryyKGQEl3YV9BY2wr6HggGq8kvcgM= -github.com/cosmos/cosmos-sdk v0.47.1 h1:HnaCYtaAMWZp1SdlwwE1mPJ8kFlZ/TuEJ/ciNXH6Uno= -github.com/cosmos/cosmos-sdk v0.47.1/go.mod h1:14tO5KQaTrl2q3OxBnDRfue7TRN9zkXS0cLutrSqkOo= 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/gogogateway v1.2.0 h1:Ae/OivNhp8DqBi/sh2A8a1D0y638GpL3tkmLQAiKxTE= +github.com/cosmos/gogogateway v1.2.0/go.mod h1:iQpLkGWxYcnCdz5iAdLcRBSw3h7NXeOkZ4GUkT+tbFI= +github.com/cosmos/gogoproto v1.4.2/go.mod h1:cLxOsn1ljAHSV527CHOtaIP91kK6cCrZETRBrkzItWU= +github.com/cosmos/gogoproto v1.4.8 h1:BrHKc6WFZt8+jRV71vKSQE+JrfF+JAnzrKo2VP7wIZ4= github.com/cosmos/gogoproto v1.4.8/go.mod h1:hnb0DIEWTv+wdNzNcqus5xCQXq5+CXauq1FJuurRfVY= +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.20.0 h1:fTVznVlepH0KK8NyKq8w+U7c2L6jofa27aFX6YGlm38= github.com/cosmos/iavl v0.20.0/go.mod h1:WO7FyvaZJoH65+HFOsDir7xU9FWk2w9cHXNW1XHcl7A= +github.com/cosmos/ibc-go/v7 v7.0.0 h1:j4kyywlG0hhDmT9FmSaR5iCIka7Pz7kJTxGWY1nlV9Q= +github.com/cosmos/ibc-go/v7 v7.0.0/go.mod h1:BFh8nKWjr5zeR2OZfhkzdgDzj1+KjRn3aJLpwapStj8= +github.com/cosmos/ics23/go v0.9.1-0.20221207100636-b1abd8678aab h1:I9ialKTQo7248V827Bba4OuKPmk+FPzmTVHsLXaIJWw= +github.com/cosmos/ics23/go v0.9.1-0.20221207100636-b1abd8678aab/go.mod h1:2CwqasX5dSD7Hbp/9b6lhK6BwoBDCBldx7gPKRukR60= +github.com/cosmos/keyring v1.2.0 h1:8C1lBP9xhImmIabyXW4c3vFjjLiBdGCmfLUfeZlV1Yo= github.com/cosmos/keyring v1.2.0/go.mod h1:fc+wB5KTk9wQ9sDx0kFXB3A0MaeGHM9AwRStKOQ5vOA= +github.com/cosmos/ledger-cosmos-go v0.12.2 h1:/XYaBlE2BJxtvpkHiBm97gFGSGmYGKunKyF3nNqAXZA= github.com/cosmos/ledger-cosmos-go v0.12.2/go.mod h1:ZcqYgnfNJ6lAXe4HPtWgarNEY+B74i+2/8MhZw4ziiI= +github.com/cosmos/rosetta-sdk-go v0.10.0 h1:E5RhTruuoA7KTIXUcMicL76cffyeoyvNybzUGSKFTcM= +github.com/cosmos/rosetta-sdk-go v0.10.0/go.mod h1:SImAZkb96YbwvoRkzSMQB6noNJXFgWl/ENIznEoYQI4= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/creachadair/taskgroup v0.4.2 h1:jsBLdAJE42asreGss2xZGZ8fJra7WtwnHWeJFxv2Li8= github.com/creachadair/taskgroup v0.4.2/go.mod h1:qiXUOSrbwAY3u0JPGTzObbE3yf9hcXHDKBZ2ZjpCbgM= 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/cucumber/common/gherkin/go/v22 v22.0.0 h1:4K8NqptbvdOrjL9DEea6HFjSpbdT9+Q5kgLpmmsHYl0= +github.com/cucumber/common/messages/go/v17 v17.1.1 h1:RNqopvIFyLWnKv0LfATh34SWBhXeoFTJnSrgm9cT/Ts= 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 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= 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/dcrec/secp256k1/v4 v4.1.0 h1:HbphB4TFFXpv7MNrT52FGrrgVXF1owhMVTHFZIlnvd4= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0/go.mod h1:DZGJHZMqrU4JJqFAWUS2UO1+lbSKsdiOoYi9Zzey7Fc= 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 v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= +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/badger/v3 v3.2103.2 h1:dpyM5eCJAtQCBcMCZcT4UBZchuTJgCywerHHgmxfxM8= github.com/dgraph-io/badger/v3 v3.2103.2/go.mod h1:RHo4/GmYcKKh5Lxu63wLEMHJ70Pac2JqZRYGhlyAo2M= github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= github.com/dgraph-io/ristretto v0.0.3/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= github.com/dgraph-io/ristretto v0.1.0/go.mod h1:fux0lOrBhrVCJd3lcTHsIJhq1T2rokOu6v9Vcb3Q9ug= +github.com/dgraph-io/ristretto v0.1.1 h1:6CWw5tJNgpegArSHpNHJKldNeq03FQCwYvfMVWajOK8= github.com/dgraph-io/ristretto v0.1.1/go.mod h1:S1GPSBCYCIhmVNfcth17y2zZtQT6wzkzgwUve0VDWWA= 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/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= 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/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= +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/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 v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= -github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -265,92 +474,106 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= +github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= +github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw= github.com/ethereum/go-ethereum v1.10.17/go.mod h1:Lt5WzjM07XlXc95YzrhosmR4J9Ahd6X2wyEV2SvGhk0= -github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= +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.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= -github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/felixge/httpsnoop v1.0.2 h1:+nS9g82KMXccJ/wp0zyRW9ZBHFETmMGtkk+2CTTrW4o= github.com/felixge/httpsnoop v1.0.2/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= -github.com/flosch/pongo2 v0.0.0-20190707114632-bbf5a6c351f4/go.mod h1:T9YF2M40nIgbVgp3rreNmTged+9HrbNTIQf1PsaIiTA= 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.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= 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/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/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= 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/getsentry/sentry-go v0.12.0/go.mod h1:NSap0JBYWzHND8oMbyi0+XZhUalc1TBdRL1M71JZW2c= -github.com/getsentry/sentry-go v0.17.0/go.mod h1:B82dxtBvxG0KaPD8/hfSV+VcHD+Lg/xUS4JuQn1P4cM= -github.com/ghemawat/stream v0.0.0-20171120220530-696b145b53b9/go.mod h1:106OIgooyS7OzLDOpUGgm9fA3bQENb/cFSyyBmMoJDs= 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.8.1 h1:4+fr/el88TOO3ewCmQr8cx/CtZ/umlIRIs5M4NTNjf8= github.com/gin-gonic/gin v1.8.1/go.mod h1:ji8BvRH1azfM+SYow9zQ6SZMvR8qOMZHmsCuWR9tTTk= 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-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= github.com/go-chi/chi/v5 v5.0.0/go.mod h1:BBug9lr0cqtdAhsu6R4AAdvufI0/XBzAQSsUqJpoZOs= -github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= 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= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= +github.com/go-kit/kit v0.12.0 h1:e4o3o3IsBfAKQh5Qbbiqyfu97Ku7jrO/JbohvztANh4= github.com/go-kit/kit v0.12.0/go.mod h1:lHd+EkCZPIwYItmGDDRdhinkzX2A1sj+M9biaEaizzs= +github.com/go-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU= github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4= github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= -github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= 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.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU= github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs= +github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho= github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA= github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos= +github.com/go-playground/validator/v10 v10.11.1 h1:prmOlTVv+YjZjmRmNSF3VmspqJIxJWXmqUsHwfTRRkQ= 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/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +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= +github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8= github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= +github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo= github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= +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/go.mod h1:S7rR8FRQyG3QFESeSv4l2WnsyzlCLG0CzBbUUo/mbic= -github.com/gogo/googleapis v0.0.0-20180223154316-0cd9801be74a/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= +github.com/gofrs/uuid v4.3.0+incompatible h1:CaSVZxm5B+7o45rtab4jC2G37WGYX1zQfuU2i6DSvnc= github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= +github.com/gogo/googleapis v1.4.1-0.20201022092350-68b0159b7869/go.mod h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c= +github.com/gogo/googleapis v1.4.1 h1:1Yx4Myt7BxzvUr5ldGSbwYiZG6t9wGBZ+8/fX3Wvtq0= github.com/gogo/googleapis v1.4.1/go.mod h1:2lpHqI5OcWCtVElxXnPt+s8oJvMpySlOyM6xDCrzib4= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/gogo/status v1.1.0/go.mod h1:BFv9nrluPLmrS0EmGVvLaPNmRosr9KapBYd5/hpY1WM= -github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang-jwt/jwt/v4 v4.3.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= github.com/golang-jwt/jwt/v4 v4.4.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= 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.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE= github.com/golang/glog v1.1.0/go.mod h1:pfYeQZ3JWZoXTV5sFc986z3HTpwQs9At6P4ImfuP3NQ= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= 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.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= @@ -359,6 +582,9 @@ github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt 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= @@ -375,17 +601,21 @@ 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/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.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/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= 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/flatbuffers v1.12.1 h1:MVlul7pQNoDzWRLTw5imwYsl+usrS1TXG2H4jg6ImGw= github.com/google/flatbuffers v1.12.1/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= @@ -398,15 +628,23 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ 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/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= 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/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= +github.com/google/martian/v3 v3.3.2 h1:IqNFLAmvJOgVlpdEBiQbDc2EwKW77amAycfTuWKdfvw= +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= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= @@ -418,37 +656,65 @@ 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-20210407192527-94a9f03dee38/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/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg= +github.com/googleapis/enterprise-certificate-proxy v0.2.3 h1:yk9/cqRKtT9wXZSsRH9aurXEpJX+U6FLtpYTdC3R06k= +github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= 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.5.1/go.mod h1:h6B0KMMFNtI2ddbGJn3T3ZbwkeT6yqEF02fYlzkUCyo= +github.com/googleapis/gax-go/v2 v2.6.0/go.mod h1:1mjbznJAPHFpesgE5ucqfYEscaz5kMdcIDwU/6+DDoY= +github.com/googleapis/gax-go/v2 v2.7.0 h1:IcsPKeInNvYi7eqSaDjiZqDDKu5rsmunY0Y1YupQSSQ= +github.com/googleapis/gax-go/v2 v2.7.0/go.mod h1:TEop28CZZQ2y+c0VxMUmu1lV+fQx57QpBWsYpwqHJx8= +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= +github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4= github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q= github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.1/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/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= github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= -github.com/grpc-ecosystem/grpc-gateway v1.8.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c h1:6rhixN/i8ZofjG1Y75iExal34USq5p+wiN1tpie8IrU= github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c/go.mod h1:NMPJylDgVpX0MLRlPy15sqSwOFv/U1GZ2m21JhFfek0= github.com/gtank/merlin v0.1.1-0.20191105220539-8318aed1a79f/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/bIQ+s= +github.com/gtank/merlin v0.1.1 h1:eQ90iG7K9pOhtereWsmyRJ6RAwcP4tHTDBHXNg+u5is= github.com/gtank/merlin v0.1.1/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/bIQ+s= +github.com/gtank/ristretto255 v0.1.2 h1:JEqUCPA1NvLq5DwYtuzigd7ss8fwbYay9fi4/5uMzcc= github.com/gtank/ristretto255 v0.1.2/go.mod h1:Ph5OpO6c7xKUGROZfWVLiJf9icMDwUeIvY4OmlYW69o= 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= @@ -456,42 +722,58 @@ github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brv 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.7.1 h1:SWiSWN/42qdpR0MdhaOc/bLR48PLuP1ZQtYLRlM69uY= +github.com/hashicorp/go-getter v1.7.1/go.mod h1:W7TalhMmbPmsSMdNjD0ZskARur/9GJ17cfHTRtXV744= 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= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= 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/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE= 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/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.1.0 h1:jtBwzzcHuTmFrQN6xQZn6CQEO/V9f7HsjsjeEZ6auqU= github.com/hdevalence/ed25519consensus v0.1.0/go.mod h1:w3BHWjwJbFU29IRHL1Iqkw3sus+7FctEyM4RqDxYNzo= 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/huandu/go-assert v1.1.5 h1:fjemmA7sSfYHJD7CUqs9qTwwfdNAx7/j2/ZlHXzNB3c= +github.com/huandu/go-assert v1.1.5/go.mod h1:yOLvuqZwmcHIC5rIzrBhT7D3Q9c3GFnd0JrPVhn/06U= +github.com/huandu/skiplist v1.2.0 h1:gox56QD77HzSC0w+Ws3MH3iie755GBJU1OER3h5VsYw= +github.com/huandu/skiplist v1.2.0/go.mod h1:7v3iFjLcSAzO4fN5B8dvebvo/qsfumiLiDXMrPiHF9w= github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= github.com/huin/goupnp v1.0.3-0.20220313090229-ca81a64b4204/go.mod h1:ZxNlw5WqJj6wSsRK5+YfflQGXYfccj5VgQsMNixHM7Y= github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= -github.com/hydrogen18/memlistener v0.0.0-20141126152155-54553eb933fb/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= -github.com/hydrogen18/memlistener v0.0.0-20200120041712-dcc25e7acd91/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= +github.com/iancoleman/orderedmap v0.2.0 h1:sq1N/TFpYH++aViPcaKjys3bDClUEU7s5B+z6jq8pNA= github.com/iancoleman/orderedmap v0.2.0/go.mod h1:N0Wam8K1arqPXNWjMo21EXnBPOPp36vB07FNRdD2geA= 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/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= +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.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/influxdata/flux v0.65.1/go.mod h1:J754/zds0vvpfwuq7Gc2wRdVwEodfpCFM7mYlOw2LqY= github.com/influxdata/influxdb v1.8.3/go.mod h1:JugdFhsvvI8gadxOI6noqNeeBHvWNTbfYGtiAn+2jhI= @@ -505,19 +787,17 @@ github.com/influxdata/promql/v2 v2.12.0/go.mod h1:fxOPu+DY0bqCTCECchSRtWfc+0X19y 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/iris-contrib/blackfriday v2.0.0+incompatible/go.mod h1:UzZ2bDEoaSGPbkg6SAB4att1aAwTmVIx/5gCVqeyUdI= -github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/+fafWORmlnuysV2EMP8MW+qe0= -github.com/iris-contrib/i18n v0.0.0-20171121225848-987a633949d0/go.mod h1:pMCz62A0xJL6I+umB2YTlFRwWXaDFA0jy+5HzGiJjqI= -github.com/iris-contrib/jade v1.1.3/go.mod h1:H/geBymxJhShH5kecoiOCSssPX7QWYH7UaeZTSWddIk= -github.com/iris-contrib/pongo2 v0.0.1/go.mod h1:Ssh+00+3GAZqSQb30AvBRNxBx7rf0GqwkjqxNd0u65g= -github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw= 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.13.1-0.20220928232736-101791cb1b4c h1:XImQJfpJLmGEEd8ll5yPVyL/aEvmgGHW4WYTyNseLOM= 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= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= @@ -527,44 +807,30 @@ github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/u github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= 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/juju/errors v0.0.0-20181118221551-089d3ea4e4d5/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q= -github.com/juju/loggo v0.0.0-20180524022052-584905176618/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U= -github.com/juju/testing v0.0.0-20180920084828-472a3e8b2073/go.mod h1:63prj8cnj0tU0S9OHjGJn+b1h0ZghCndfnbQolrYTwA= 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/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= github.com/karalabe/usb v0.0.2/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU= -github.com/kataras/golog v0.0.9/go.mod h1:12HJgwBIZFNGL0EJnMRhmvGA0PQGx8VFwrZtM4CqbAk= -github.com/kataras/golog v0.0.10/go.mod h1:yJ8YKCmyL+nWjERB90Qwn+bdyBZsaQwU3bTVFgkFIp8= -github.com/kataras/iris/v12 v12.0.1/go.mod h1:udK4vLQKkdDqMGJJVd/msuMtN6hpYJhg/lSzuxjhO+U= -github.com/kataras/iris/v12 v12.1.8/go.mod h1:LMYy4VlP67TQ3Zgriz8RE2h2kMZV2SgMYbq3UhfoFmE= -github.com/kataras/neffos v0.0.10/go.mod h1:ZYmJC07hQPW67eKuzlfY7SO3bC0mw83A3j6im82hfqw= -github.com/kataras/neffos v0.0.14/go.mod h1:8lqADm8PnbeFfL7CLXh1WHw53dG27MC3pgi2R1rmoTE= -github.com/kataras/pio v0.0.0-20190103105442-ea782b38602d/go.mod h1:NV88laa9UiiDuX9AhMbDPkGYSPugBOV6yTZB1l2K9Z0= -github.com/kataras/pio v0.0.2/go.mod h1:hAoW0t9UmXi4R5Oyq5Z4irTbaTsOemSrDGUtaTl7Dro= -github.com/kataras/sitemap v0.0.5/go.mod h1:KY2eugMKiPwsJgx7+U103YZehfvNGOXURubcGyk0Bz8= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= 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.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/compress v1.9.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/compress v1.9.7/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= 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.11/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= +github.com/klauspost/compress v1.16.3 h1:XuJt9zzcnaz6a16/OU53ZjWp/v7/42WcR5t2a0PcNQY= github.com/klauspost/compress v1.16.3/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/klauspost/cpuid v0.0.0-20170728055534-ae7887de9fa5/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= -github.com/klauspost/cpuid v1.2.1/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= @@ -574,37 +840,41 @@ github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFB 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.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= 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.1.11/go.mod h1:i541M3Fj6f76NZtHSj7TXnyM8n2gaodfvfxNnFqi74g= github.com/labstack/echo/v4 v4.2.1/go.mod h1:AA49e0DZ8kk5jTOOCKNuPR6oTnBS0dYiM4FW1e6jwpg= -github.com/labstack/echo/v4 v4.5.0/go.mod h1:czIriw4a0C1dFun+ObrXp7ok03xON0N1awStJ6ArI7Y= 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.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw= github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= -github.com/linxGnu/grocksdb v1.7.10/go.mod h1:0hTf+iA+GOr0jDX4CgIYyJZxqOH9XlBh6KVj8+zmF34= github.com/lucasjones/reggen v0.0.0-20180717132126-cdb49ff09d77/go.mod h1:5ELEyG+X8f+meRWHuqUOewBOhvHkl7M76pdGEansxW4= github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= 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/manifoldco/promptui v0.9.0 h1:3V4HzJk1TtXW1MTZMP7mdlwbBpIinw3HztaIlYthEiA= +github.com/manifoldco/promptui v0.9.0/go.mod h1:ka04sppxSGFAtxX0qhlYQjISsg9mR4GWtQEhdbn6Pgg= 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.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.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= 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-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= @@ -613,45 +883,52 @@ github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2y 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/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= github.com/mattn/go-isatty v0.0.17/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= 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/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= -github.com/mediocregopher/mediocre-go-lib v0.0.0-20181029021733-cb65787f37ed/go.mod h1:dSsfyI2zABAdhcbvkXqgxOxrCsbYeHCPgrZkku60dSg= -github.com/mediocregopher/radix/v3 v3.3.0/go.mod h1:EmfVyvspXz1uZEyPBMyGK+kjWiKQGvsUt6O3Pj+LDCQ= -github.com/mediocregopher/radix/v3 v3.4.2/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i4n7wVopoX3x7Bv8= -github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= 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= 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/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU= +github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8= 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.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= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= 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/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ= 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= +github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/grpc-proxy v0.0.0-20181017164139-0f1106ef9c76/go.mod h1:x5OoJHDHqxHS801UIuhqGl6QdSAEJvtausosHSdazIo= github.com/naoina/go-stringutil v0.1.0/go.mod h1:XJ2SJL9jCtBh+P9q5btrd/Ylo8XwT/h1USek5+NqSA0= @@ -659,15 +936,16 @@ github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416/go.mod h1:NBIhNtsFMo github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k= -github.com/nats-io/nats.go v1.8.1/go.mod h1:BrFz9vVn0fU3AcH9Vn4Kd7W0NpJ651tD5omQ3M8LwxM= github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= -github.com/nats-io/nkeys v0.0.2/go.mod h1:dab7URMsZm6Z/jp9Z5UGa87Uutgc2mVpXLC4B7TDb/4= 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/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/notional-labs/cosmos-sdk v0.47.2-0.20230424060617-ebc292e8de8b h1:ftj1UZ3/o5g/AkYq3WblQdAj3d9tYZNosRqnqvwu3lg= +github.com/notional-labs/cosmos-sdk v0.47.2-0.20230424060617-ebc292e8de8b/go.mod h1:IH/tRaPQEdWAbDuvtyNyPcfPz0DS/ESpmBRXOd5jCas= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= @@ -676,11 +954,10 @@ github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:v 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.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo v1.13.0/go.mod h1:+REjRxOmWfHCjfv9TTWB1jD1Frx4XydAD3zm1lskyM0= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= @@ -689,8 +966,12 @@ github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7J github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= +github.com/onsi/gomega v1.26.0 h1:03cDLK28U6hWvCAns6NeydX3zIm4SF3ci69ulidS32Q= 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= github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= @@ -700,33 +981,35 @@ github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxS 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/osmosis-labs/osmosis/osmoutils v0.0.3-rc0/go.mod h1:rO4YKI0ZQkS3o4UDhFuQFy+j4eM/as8GLvuBDNBStkQ= -github.com/osmosis-labs/osmosis/x/ibc-hooks v0.0.0-20230201151635-ef43e092d196/go.mod h1:eoSRNkeqi3ufOmvY8XcW8y0NgbbaPyBTEn7DTxq8XY4= +github.com/ory/dockertest v3.3.5+incompatible h1:iLLK6SQwIhcbrG783Dghaaa3WPzGc+4Emza6EbVUUGA= 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 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/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo= +github.com/pelletier/go-toml/v2 v2.0.6 h1:nrzqCb7j9cDFj2coyLNLaZuJTLjWjlaz6nvTvIwycIU= github.com/pelletier/go-toml/v2 v2.0.6/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek= 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/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o= +github.com/petermattis/goid v0.0.0-20221215004737-a150e88a970d h1:htwtWgtQo8YS6JFWWi2DNgY0RwSGJ1ruMoxY6CUUclk= github.com/petermattis/goid v0.0.0-20221215004737-a150e88a970d/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= 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= -github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +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= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= @@ -735,6 +1018,7 @@ github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5Fsn github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= +github.com/prometheus/client_golang v1.15.0 h1:5fCgGYogn0hFdhyhLbw7hEsWxufKtY9klyvdNfFlFhM= github.com/prometheus/client_golang v1.15.0/go.mod h1:e9yaBhRPU2pPNsZwE+JdQl0KEt1N9XgF6zxWmaC0xOk= 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= @@ -742,6 +1026,7 @@ github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1: 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/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= @@ -751,6 +1036,7 @@ github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt2 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= github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= +github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM= github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= @@ -758,12 +1044,15 @@ github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsT github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.3.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI= github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= github.com/prometheus/tsdb v0.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= +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/go.mod h1:jO0sVX6a1B36nmE8C9xBFXpNwWejXC7QqCOnH3O0+YM= +github.com/regen-network/gocuke v0.6.2 h1:pHviZ0kKAq2U2hN2q3smKNxct6hS0mGByFMHGnWA97M= 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= @@ -771,60 +1060,71 @@ github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6L github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= -github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o= -github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= +github.com/rs/cors v1.8.3 h1:O+qNyWn7Z+F9M0ILBHgMVPuB1xTOucVd5gtaYyXBpRo= github.com/rs/cors v1.8.3/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/rs/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= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= 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/ryanuber/columnize v2.1.0+incompatible/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.3.1 h1:sqv7fDNShgjcaxkO0JNcOAlr8B9+cV5Ey/OB71efZx0= github.com/sasha-s/go-deadlock v0.3.1/go.mod h1:F73l+cr82YSh10GxyRI6qZiCgK64VaZjwesgfQ1/iLM= -github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g= -github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw= 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/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= 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= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +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.3 h1:41FoI0fD7OR7mGcKE/aOiLkGreyf8ifIOQmJANWogMk= github.com/spf13/afero v1.9.3/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= 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.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= 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= github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +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.15.0 h1:js3yy885G8xwJa6iOISGFwd+qlUo5AvyXb7CiihdtiU= github.com/spf13/viper v1.15.0/go.mod h1:fFcTBJxvhhzSJiZy8n+PeW6t8l+KeT/uTARa0jHOQLA= github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4/go.mod h1:RZLeN1LMWmRsyYjvAu+I6Dm9QmlDaIIt+Y+4Kd7Tp+Q= +github.com/strangelove-ventures/async-icq/v7 v7.0.0-20230413165143-a3b65ccdc897 h1:lCTD5L1v1K1KC6KXjyt4o1X+yzV14RbbrPZaF29n8uI= +github.com/strangelove-ventures/async-icq/v7 v7.0.0-20230413165143-a3b65ccdc897/go.mod h1:ag05Q54Wkr0jVwfe+14sxnuWbw0gBOxtPQv9afBBnr0= +github.com/strangelove-ventures/packet-forward-middleware/v7 v7.0.0-20230412224111-136e94e98861 h1:amfLQujq8LwWjuadoMDX7lngka6NXcvk4ugkWZ4m7o0= +github.com/strangelove-ventures/packet-forward-middleware/v7 v7.0.0-20230412224111-136e94e98861/go.mod h1:DJNSVK8NCYHM+aZHCFkcAqPwjzwHYAjhjSMlhAGtJ3c= 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/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= @@ -837,12 +1137,20 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= +github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d h1:vfofYNRScrDdvS342BElfbETmL1Aiz3i2t0zfRj16Hs= github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d/go.mod h1:RRCYJbIwD5jmqPI9XoAFR0OcDxqUctll6zUj/+B4S48= +github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c h1:g+WoO5jjkqGAzHWCjJB1zZfXPIAaDpzXIEJ0eS6B5Ok= github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c/go.mod h1:ahpPrc7HpcfEWDQRZEmnXMzHY03mLDYMCxeDzy46i+8= +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/tm-db v0.6.8-0.20220506192307-f628bb5dc95b h1:Y3ZPG6gdDCAV2sdGkD759ji/09GzaNu1X3qKTmZIbTo= +github.com/tendermint/tm-db v0.6.8-0.20220506192307-f628bb5dc95b/go.mod h1:ADqbS9NOSnBRK9R2RtYC61CdsHmVMD/yXAzcMuPexbU= +github.com/tidwall/btree v1.6.0 h1:LDZfKfQIBHGHWSwckhXI0RPSXzlo+KYdjK7FWSqOzzg= github.com/tidwall/btree v1.6.0/go.mod h1:twD9XRA5jj9VUQGELzDO4HPQTNJsoWWfYEL+EUQ2cKY= github.com/tidwall/gjson v1.12.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/gjson v1.14.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= @@ -850,50 +1158,45 @@ github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JT 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= github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs= github.com/tyler-smith/go-bip39 v1.0.2/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs= -github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= +github.com/ugorji/go v1.2.7 h1:qYhyWUUd6WbiM+C6JZAUkIJt/1WrjzNHY9+KCIjVqTo= github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= -github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= +github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= +github.com/ulikunitz/xz v0.5.10/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= +github.com/ulikunitz/xz v0.5.11 h1:kpFauv27b6ynzBNT/Xy+1k+fK4WswhN/6PN5WhFAGw8= +github.com/ulikunitz/xz v0.5.11/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/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= 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/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= 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/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= -github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= 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/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= github.com/ybbus/jsonrpc v2.1.2+incompatible/go.mod h1:XJrh1eMSzdIYFbM08flv0wp5G35eRniyeGut1z+LSiE= -github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= -github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= -github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc= 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/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/zondax/hid v0.9.1 h1:gQe66rtmyZ8VeGFcOpbuH3r7erYtNEAezCAYu8LdkJo= github.com/zondax/hid v0.9.1/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= +github.com/zondax/ledger-go v0.14.1 h1:Pip65OOl4iJ84WTpA4BKChvOufMhhbxED3BaihoZN4c= github.com/zondax/ledger-go v0.14.1/go.mod h1:fZ3Dqg6qcdXWSOJFKMG8GCTnD7slO/RL2feOQv8K320= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/bbolt v1.3.7 h1:j+zJOnnEjF/kyHlDDgGnVL/AIqIJPq8UoB2GSNfkUfQ= go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= @@ -904,7 +1207,10 @@ 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/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= +go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= +go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= 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= @@ -926,7 +1232,6 @@ golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190909091759-094676da4a83/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -938,6 +1243,7 @@ golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/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.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A= golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= 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= @@ -953,7 +1259,7 @@ golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= -golang.org/x/exp v0.0.0-20200513190911-00229845015e/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= +golang.org/x/exp v0.0.0-20230321023759-10a507213a29 h1:ooxPy7fPvB4kwsA2h+iBNHkAbp/4JxTSwCmvdjEYmug= golang.org/x/exp v0.0.0-20230321023759-10a507213a29/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= 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= @@ -981,6 +1287,8 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8= 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-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -993,7 +1301,6 @@ golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -1003,7 +1310,6 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -1030,14 +1336,26 @@ golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v 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-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211008194852-3b03d305991f/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-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= +golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM= golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= 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= @@ -1048,6 +1366,24 @@ 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-20220622183110-fd043fe589d2/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= +golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.1.0/go.mod h1:G9FE4dLTsbXUu90h/Pf85g4w1D+SSAgR+q46nJZ8M4A= +golang.org/x/oauth2 v0.5.0 h1:HuArIo48skDwlrvM3sEdHXElYslAMsf3KwRkkW4MC4s= +golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I= 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= @@ -1059,6 +1395,9 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ 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/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/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-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1120,36 +1459,60 @@ golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210112080510-489259a85091/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-20210403161142-5e06dd20ab57/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-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-20210909193231-528a39cd75f3/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-20211007075335-d3039528d8ac/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-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-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220315194320-039c03cc5b86/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-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-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/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/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU= golang.org/x/sys v0.7.0/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.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.7.0 h1:BEvjmm5fURWqcfbSKTdpkDXYBrUS1c0m8agp14W48vQ= golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= 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= @@ -1160,6 +1523,8 @@ 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/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= 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= @@ -1172,14 +1537,12 @@ golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/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-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/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= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190327201419-c70d86f8b7cf/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= @@ -1221,7 +1584,6 @@ golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= -golang.org/x/tools v0.0.0-20201022035929-9cf592e881e9/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= @@ -1230,17 +1592,25 @@ 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/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.8.0 h1:vSDcovVPld282ceKgDimkRSC8kpaH1dgyc9UMzlt84Y= 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/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0= 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= @@ -1264,6 +1634,37 @@ 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.77.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.90.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw= +google.golang.org/api v0.93.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw= +google.golang.org/api v0.95.0/go.mod h1:eADj+UBuxkh5zlrSntJghuNeg8HwQ1w5lTKkuqaETEI= +google.golang.org/api v0.96.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= +google.golang.org/api v0.97.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= +google.golang.org/api v0.98.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= +google.golang.org/api v0.100.0/go.mod h1:ZE3Z2+ZOr87Rx7dqFsdRQkRBk36kDtp/h+QpHbB7a70= +google.golang.org/api v0.110.0 h1:l+rh0KYUooe9JGbGVx71tbFo4SMbMTXK3I3ia2QSEeU= +google.golang.org/api v0.110.0/go.mod h1:7FC4Vvx1Mooxh8C5HWjzZHcavuS2f6pmJpZx60ca7iI= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= 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= @@ -1271,8 +1672,8 @@ google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7 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-20180518175338-11a468237815/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= 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= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= @@ -1315,13 +1716,78 @@ 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-20220314164441-57ef72a4c106/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= +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-20220502173005-c8bf987b8c21/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +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-20220624142145-8cd45d7dbd1f/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220628213854-d9e0b6570c03/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220722212130-b98a9ff5e252/go.mod h1:GkXuJDJ6aQ7lnJcRF+SJVgFdQhypqgl3LB1C9vabdRE= +google.golang.org/genproto v0.0.0-20220801145646-83ce21fca29f/go.mod h1:iHe1svFLAZg9VWz891+QbRMwUv9O/1Ww+/mngYeThbc= +google.golang.org/genproto v0.0.0-20220815135757-37a418bb8959/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220817144833-d7fd3f11b9b1/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220822174746-9e6da59bd2fc/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220829144015-23454907ede3/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220829175752-36a9c930ecbf/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220913154956-18f8339a66a5/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220914142337-ca0e39ece12f/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220915135415-7fd63a7952de/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220916172020-2692e8806bfa/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220919141832-68c03719ef51/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220920201722-2b89144ce006/go.mod h1:ht8XFiar2npT/g4vkk7O0WYS1sHOHbdujxbEp7CJWbw= +google.golang.org/genproto v0.0.0-20220926165614-551eb538f295/go.mod h1:woMGP53BroOrRY3xTxlbr8Y3eB/nzAvvFM83q7kG2OI= +google.golang.org/genproto v0.0.0-20220926220553-6981cbe3cfce/go.mod h1:woMGP53BroOrRY3xTxlbr8Y3eB/nzAvvFM83q7kG2OI= +google.golang.org/genproto v0.0.0-20221010155953-15ba04fc1c0e/go.mod h1:3526vdqwhZAwq4wsRUaVG555sVgsNmIjRtO7t/JH29U= +google.golang.org/genproto v0.0.0-20221014173430-6e2ab493f96b/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= +google.golang.org/genproto v0.0.0-20221014213838-99cd37c6964a/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= +google.golang.org/genproto v0.0.0-20221025140454-527a21cfbd71/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= +google.golang.org/genproto v0.0.0-20230216225411-c8e22ba71e44 h1:EfLuoKW5WfkgVdDy7dTK8qSbH37AX5mj/MFh+bGPz14= google.golang.org/genproto v0.0.0-20230216225411-c8e22ba71e44/go.mod h1:8B0gmkoRebU8ukX6HP+4wrVQUY1+6PkQ44BSyIlflHA= -google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.19.1/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -1343,8 +1809,27 @@ google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTp google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= +google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= +google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= +google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= +google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= +google.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= +google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= +google.golang.org/grpc v1.54.0 h1:EhTqbhiYeixwWQtAEZAxmV9MGqcjEU2mFx52xCzNyag= google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g= +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= @@ -1357,25 +1842,29 @@ 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/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= google.golang.org/protobuf v1.30.0/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-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 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= -gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c= gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200619000410-60c24ae608a6/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/urfave/cli.v1 v1.20.0/go.mod h1:vuBzUtMdQeixQj8LVd+/98pzhxNGQoyuPBlsXHOQNO0= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= @@ -1387,12 +1876,15 @@ gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20191120175047-4206685974f2/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= +gotest.tools/v3 v3.4.0 h1:ZazjZUfuVeZGLAmlKKuyv3IKP5orXcwtOwDQH6YVr6o= honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -1403,11 +1895,16 @@ honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9 honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= nhooyr.io/websocket v1.8.6/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= +nhooyr.io/websocket v1.8.7 h1:usjR2uOr/zjjkVMy0lW+PPohFok7PCow5sDjLgX4P4g= nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= +pgregory.net/rapid v0.5.5 h1:jkgx1TjbQPD/feRoK+S/mXw9e1uj6WilpHrXJowi6oA= +pgregory.net/rapid v0.5.5/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04= 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 37005ad09d0f370c4523a7dbb6451248ed115462 Mon Sep 17 00:00:00 2001 From: Jacob Gadikian Date: Mon, 24 Apr 2023 14:01:57 +0700 Subject: [PATCH 019/131] tidy --- app/app.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/app.go b/app/app.go index 0a9ac3ffc..5caecc4bd 100644 --- a/app/app.go +++ b/app/app.go @@ -7,7 +7,6 @@ import ( "strconv" "strings" - "cosmossdk.io/simapp" "github.com/CosmosContracts/juno/v15/app/openapiconsole" "github.com/CosmosContracts/juno/v15/docs" dbm "github.com/cometbft/cometbft-db" @@ -20,6 +19,7 @@ import ( "github.com/cosmos/cosmos-sdk/client/grpc/tmservice" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/codec/types" + "github.com/cosmos/cosmos-sdk/runtime" "github.com/cosmos/cosmos-sdk/server/api" "github.com/cosmos/cosmos-sdk/server/config" servertypes "github.com/cosmos/cosmos-sdk/server/types" @@ -178,7 +178,7 @@ func getGovProposalHandlers() []govclient.ProposalHandler { } var ( - _ simapp.App = (*App)(nil) + _ runtime.AppI = (*App)(nil) _ servertypes.Application = (*App)(nil) ) From c8bfbe98116f935ce3ac1f8e550d30f7a1ce2e7e Mon Sep 17 00:00:00 2001 From: Jacob Gadikian Date: Mon, 24 Apr 2023 14:04:17 +0700 Subject: [PATCH 020/131] don't send needless params to setup --- app/apptesting/test_suite.go | 2 +- app/test_helpers.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/apptesting/test_suite.go b/app/apptesting/test_suite.go index 329a72ccc..783cc8f90 100644 --- a/app/apptesting/test_suite.go +++ b/app/apptesting/test_suite.go @@ -37,7 +37,7 @@ import ( type KeeperTestHelper struct { suite.Suite - App *app.TokenApp + App *app.App Ctx sdk.Context QueryHelper *baseapp.QueryServiceTestHelper TestAccs []sdk.AccAddress diff --git a/app/test_helpers.go b/app/test_helpers.go index 576871fc5..6a147e660 100644 --- a/app/test_helpers.go +++ b/app/test_helpers.go @@ -62,7 +62,7 @@ type EmptyAppOptions struct{} func (EmptyAppOptions) Get(_ string) interface{} { return nil } -func Setup(t *testing.T, _ bool, _ uint) *App { +func Setup(t *testing.T) *App { t.Helper() privVal := apphelpers.NewPV() From b9d1cabbd90306033616615242faec652e531ef8 Mon Sep 17 00:00:00 2001 From: Jacob Gadikian Date: Mon, 24 Apr 2023 14:05:17 +0700 Subject: [PATCH 021/131] fix RegisterTendermintService --- app/app.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/app/app.go b/app/app.go index 5caecc4bd..b3679b77e 100644 --- a/app/app.go +++ b/app/app.go @@ -282,7 +282,6 @@ func New( app.mm.SetOrderInitGenesis(orderInitBlockers()...) app.mm.RegisterInvariants(&app.CrisisKeeper) - app.mm.RegisterRoutes(app.Router(), app.QueryRouter(), encodingConfig.Amino) app.mm.RegisterServices(cfg) // initialize stores app.MountKVStores(app.GetKVStoreKey()) @@ -476,7 +475,12 @@ func (app *App) RegisterTxService(clientCtx client.Context) { // RegisterTendermintService implements the Application.RegisterTendermintService method. func (app *App) RegisterTendermintService(clientCtx client.Context) { - tmservice.RegisterTendermintService(app.BaseApp.GRPCQueryRouter(), clientCtx, app.interfaceRegistry) + tmservice.RegisterTendermintService( + clientCtx, + app.BaseApp.GRPCQueryRouter(), + app.interfaceRegistry, + app.Query, + ) } // configure store loader that checks if version == upgradeHeight and applies store upgrades From 7ad4ec808e048b2cdec5de50050f356206e52ef3 Mon Sep 17 00:00:00 2001 From: Jacob Gadikian Date: Mon, 24 Apr 2023 14:06:37 +0700 Subject: [PATCH 022/131] nodeservice --- app/app.go | 1 + 1 file changed, 1 insertion(+) diff --git a/app/app.go b/app/app.go index b3679b77e..b44921b54 100644 --- a/app/app.go +++ b/app/app.go @@ -16,6 +16,7 @@ import ( tmos "github.com/cometbft/cometbft/libs/os" "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/client" + nodeservice "github.com/cosmos/cosmos-sdk/client/grpc/node" "github.com/cosmos/cosmos-sdk/client/grpc/tmservice" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/codec/types" From b58641ef1cf9346bd5ed8ca66ddb18b7c4dc21a2 Mon Sep 17 00:00:00 2001 From: Jacob Gadikian Date: Mon, 24 Apr 2023 14:11:01 +0700 Subject: [PATCH 023/131] use a global for ModuleManager so we can access it --- app/app.go | 14 ++++++++------ app/export.go | 11 +++-------- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/app/app.go b/app/app.go index b44921b54..cdbcb3740 100644 --- a/app/app.go +++ b/app/app.go @@ -188,17 +188,19 @@ var ( // capabilities aren't needed for testing. type App struct { *baseapp.BaseApp - keepers.AppKeepers - - cdc *codec.LegacyAmino + legacyAmino *codec.LegacyAmino appCodec codec.Codec + txConfig client.TxConfig interfaceRegistry types.InterfaceRegistry - invCheckPeriod uint - // the module manager - mm *module.Manager + ModuleManager *module.Manager + + // simulation manager sm *module.SimulationManager + + // module configurator + configurator module.Configurator } // New returns a reference to an initialized Juno. diff --git a/app/export.go b/app/export.go index cfd94eb62..1e0fdff7b 100644 --- a/app/export.go +++ b/app/export.go @@ -15,9 +15,7 @@ import ( // ExportAppStateAndValidators exports the state of the application for a genesis // file. -func (app *App) ExportAppStateAndValidators( - forZeroHeight bool, jailAllowedAddrs []string, -) (servertypes.ExportedApp, error) { +func (app *App) ExportAppStateAndValidators(forZeroHeight bool, jailAllowedAddrs []string, modulesToExport []string) (servertypes.ExportedApp, error) { // as if they could withdraw from the start of the next block ctx := app.NewContext(true, tmproto.Header{Height: app.LastBlockHeight()}) @@ -29,22 +27,19 @@ func (app *App) ExportAppStateAndValidators( app.prepForZeroHeightGenesis(ctx, jailAllowedAddrs) } - genState := app.mm.ExportGenesis(ctx, app.appCodec) + genState := app.ModuleManager.ExportGenesisForModules(ctx, app.appCodec, modulesToExport) appState, err := json.MarshalIndent(genState, "", " ") if err != nil { return servertypes.ExportedApp{}, err } validators, err := staking.WriteValidators(ctx, app.StakingKeeper) - if err != nil { - return servertypes.ExportedApp{}, err - } return servertypes.ExportedApp{ AppState: appState, Validators: validators, Height: height, ConsensusParams: app.BaseApp.GetConsensusParams(ctx), - }, nil + }, err } // prepare for fresh start at zero height From 0eaa9516b575628c65f73c692f144eaffd350ca5 Mon Sep 17 00:00:00 2001 From: Jacob Gadikian Date: Mon, 24 Apr 2023 14:11:42 +0700 Subject: [PATCH 024/131] remove querier --- x/mint/module.go | 8 -------- 1 file changed, 8 deletions(-) diff --git a/x/mint/module.go b/x/mint/module.go index f7f2c7f9c..0eb3d4f0a 100644 --- a/x/mint/module.go +++ b/x/mint/module.go @@ -102,19 +102,11 @@ func (AppModule) Name() string { // RegisterInvariants registers the mint module invariants. func (am AppModule) RegisterInvariants(_ sdk.InvariantRegistry) {} -// Route returns the message routing key for the mint module. -func (AppModule) Route() sdk.Route { return sdk.Route{} } - // QuerierRoute returns the mint module's querier route name. func (AppModule) QuerierRoute() string { return types.QuerierRoute } -// LegacyQuerierHandler returns the mint module sdk.Querier. -func (am AppModule) LegacyQuerierHandler(legacyQuerierCdc *codec.LegacyAmino) sdk.Querier { - return keeper.NewQuerier(am.keeper, legacyQuerierCdc) -} - // RegisterServices registers a gRPC query service to respond to the // module-specific gRPC queries. func (am AppModule) RegisterServices(cfg module.Configurator) { From 6068e925aecbbe60967961215eda1ee5c2d77abd Mon Sep 17 00:00:00 2001 From: Jacob Gadikian Date: Mon, 24 Apr 2023 14:12:26 +0700 Subject: [PATCH 025/131] remove randomized parameters --- x/mint/module.go | 6 ------ 1 file changed, 6 deletions(-) diff --git a/x/mint/module.go b/x/mint/module.go index 0eb3d4f0a..530c7ba05 100644 --- a/x/mint/module.go +++ b/x/mint/module.go @@ -4,7 +4,6 @@ import ( "context" "encoding/json" "fmt" - "math/rand" abci "github.com/cometbft/cometbft/abci/types" "github.com/grpc-ecosystem/grpc-gateway/runtime" @@ -156,11 +155,6 @@ func (AppModule) ProposalContents(_ module.SimulationState) []simtypes.WeightedP return nil } -// RandomizedParams creates randomized mint param changes for the simulator. -func (AppModule) RandomizedParams(r *rand.Rand) []simtypes.ParamChange { - return simulation.ParamChanges(r) -} - // RegisterStoreDecoder registers a decoder for mint module's types. func (am AppModule) RegisterStoreDecoder(sdr sdk.StoreDecoderRegistry) { sdr[types.StoreKey] = simulation.NewDecodeStore(am.cdc) From d4ec85036188344e6f9db390bcbcc162bb109a84 Mon Sep 17 00:00:00 2001 From: Jacob Gadikian Date: Mon, 24 Apr 2023 14:13:17 +0700 Subject: [PATCH 026/131] remove x/mint/simulation/params.go --- x/mint/simulation/params.go | 29 ----------------------------- 1 file changed, 29 deletions(-) delete mode 100644 x/mint/simulation/params.go diff --git a/x/mint/simulation/params.go b/x/mint/simulation/params.go deleted file mode 100644 index 4711df242..000000000 --- a/x/mint/simulation/params.go +++ /dev/null @@ -1,29 +0,0 @@ -package simulation - -// DONTCOVER - -import ( - "fmt" - "math/rand" - - "github.com/cosmos/cosmos-sdk/x/simulation" - - "github.com/CosmosContracts/juno/v15/x/mint/types" - simtypes "github.com/cosmos/cosmos-sdk/types/simulation" -) - -const ( - keyBlocksPerYear = "BlocksPerYear" -) - -// ParamChanges defines the parameters that can be modified by param change proposals -// on the simulation -func ParamChanges(_ *rand.Rand) []simtypes.ParamChange { - return []simtypes.ParamChange{ - simulation.NewSimParamChange(types.ModuleName, keyBlocksPerYear, - func(r *rand.Rand) string { - return fmt.Sprintf("\"%d\"", GenBlocksPerYear(r)) - }, - ), - } -} From e11adf9100beb185f5d8745675ffb87443286638 Mon Sep 17 00:00:00 2001 From: Jacob Gadikian Date: Mon, 24 Apr 2023 14:14:55 +0700 Subject: [PATCH 027/131] use math.Int --- app/apptesting/test_suite.go | 3 ++- cmd/junod/cmd/balances_from_state_export.go | 5 +++-- go.mod | 2 +- osmoutils/cli_helpers.go | 5 +++-- osmoutils/osmocli/parsers.go | 5 +++-- osmoutils/osmocli/parsers_test.go | 4 ++-- osmoutils/sumtree/legacy/v101/tree.go | 3 ++- osmoutils/sumtree/node.go | 7 +++--- osmoutils/sumtree/tree.go | 25 +++++++++++---------- x/mint/keeper/keeper.go | 5 +++-- x/mint/types/expected_keepers.go | 3 ++- x/mint/types/minter.go | 9 ++++---- x/mint/types/minter_test.go | 9 ++++---- x/tokenfactory/bindings/types/msg.go | 22 +++++++++--------- 14 files changed, 59 insertions(+), 48 deletions(-) diff --git a/app/apptesting/test_suite.go b/app/apptesting/test_suite.go index 783cc8f90..5722b1f43 100644 --- a/app/apptesting/test_suite.go +++ b/app/apptesting/test_suite.go @@ -6,6 +6,7 @@ import ( "testing" "time" + "cosmossdk.io/math" "cosmossdk.io/simapp" abci "github.com/cometbft/cometbft/abci/types" "github.com/cometbft/cometbft/crypto/ed25519" @@ -201,7 +202,7 @@ func (s *KeeperTestHelper) EndBlock() { } // AllocateRewardsToValidator allocates reward tokens to a distribution module then allocates rewards to the validator address. -func (s *KeeperTestHelper) AllocateRewardsToValidator(valAddr sdk.ValAddress, rewardAmt sdk.Int) { +func (s *KeeperTestHelper) AllocateRewardsToValidator(valAddr sdk.ValAddress, rewardAmt math.Int) { validator, found := s.App.StakingKeeper.GetValidator(s.Ctx, valAddr) s.Require().True(found) diff --git a/cmd/junod/cmd/balances_from_state_export.go b/cmd/junod/cmd/balances_from_state_export.go index cab20517c..6da8f211a 100644 --- a/cmd/junod/cmd/balances_from_state_export.go +++ b/cmd/junod/cmd/balances_from_state_export.go @@ -11,6 +11,7 @@ import ( "os" "path/filepath" + "cosmossdk.io/math" tmjson "github.com/cometbft/cometbft/libs/json" tmtypes "github.com/cometbft/cometbft/types" "github.com/spf13/cobra" @@ -37,8 +38,8 @@ type DeriveSnapshot struct { type DerivedAccount struct { Address string `json:"address"` LiquidBalances sdk.Coins `json:"liquid_balance"` - Staked sdk.Int `json:"staked"` - UnbondingStake sdk.Int `json:"unbonding_stake"` + Staked math.Int `json:"staked"` + UnbondingStake math.Int `json:"unbonding_stake"` Bonded sdk.Coins `json:"bonded"` TotalBalances sdk.Coins `json:"total_balances"` } diff --git a/go.mod b/go.mod index 6962dae96..b82187446 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module github.com/CosmosContracts/juno/v15 go 1.19 require ( + cosmossdk.io/math v1.0.0 cosmossdk.io/simapp v0.0.0-20230224204036-a6adb0821462 github.com/CosmWasm/wasmd v0.40.0-rc.1.0.20230422061626-b85abcf1d7b8 github.com/CosmosContracts/juno/v15/osmoutils v0.0.0-00010101000000-000000000000 @@ -32,7 +33,6 @@ require ( cloud.google.com/go/iam v0.12.0 // indirect cloud.google.com/go/storage v1.29.0 // indirect cosmossdk.io/errors v1.0.0-beta.7 // indirect - cosmossdk.io/math v1.0.0 // indirect cosmossdk.io/tools/rosetta v0.2.1 // indirect github.com/aws/aws-sdk-go v1.44.203 // indirect github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect diff --git a/osmoutils/cli_helpers.go b/osmoutils/cli_helpers.go index 98f2d9acb..4368dea55 100644 --- a/osmoutils/cli_helpers.go +++ b/osmoutils/cli_helpers.go @@ -5,6 +5,7 @@ import ( "strconv" "strings" + "cosmossdk.io/math" "github.com/cometbft/cometbft/crypto/ed25519" "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/testutil/network" @@ -35,8 +36,8 @@ func ParseUint64SliceFromString(s string, separator string) ([]uint64, error) { return parsedInts, nil } -func ParseSdkIntFromString(s string, separator string) ([]sdk.Int, error) { - var parsedInts []sdk.Int +func ParseSdkIntFromString(s string, separator string) ([]math.Int, error) { + var parsedInts []math.Int for _, weightStr := range strings.Split(s, separator) { weightStr = strings.TrimSpace(weightStr) diff --git a/osmoutils/osmocli/parsers.go b/osmoutils/osmocli/parsers.go index 0ec5f4941..c8cba5ae6 100644 --- a/osmoutils/osmocli/parsers.go +++ b/osmoutils/osmocli/parsers.go @@ -7,6 +7,7 @@ import ( "strings" "time" + "cosmossdk.io/math" "github.com/cosmos/cosmos-sdk/client" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/spf13/pflag" @@ -326,10 +327,10 @@ func ParseCoins(arg string, fieldName string) (sdk.Coins, error) { } // TODO: This really shouldn't be getting used in the CLI, its misdesign on the CLI ux -func ParseSdkInt(arg string, fieldName string) (sdk.Int, error) { +func ParseSdkInt(arg string, fieldName string) (math.Int, error) { i, ok := sdk.NewIntFromString(arg) if !ok { - return sdk.Int{}, fmt.Errorf("could not parse %s as sdk.Int for field %s", arg, fieldName) + return math.Int{}, fmt.Errorf("could not parse %s as math.Int for field %s", arg, fieldName) } return i, nil } diff --git a/osmoutils/osmocli/parsers_test.go b/osmoutils/osmocli/parsers_test.go index 181af5174..904a4d07c 100644 --- a/osmoutils/osmocli/parsers_test.go +++ b/osmoutils/osmocli/parsers_test.go @@ -91,13 +91,13 @@ func TestParseFieldFromArg(t *testing.T) { }}, }, "Struct (sdk.Coin) change": { - testingStruct: testingStruct{Struct: sdk.NewCoin("bar", sdk.NewInt(10))}, // only supports sdk.Int, sdk.Coin or time.Time, other structs are not recognized + testingStruct: testingStruct{Struct: sdk.NewCoin("bar", sdk.NewInt(10))}, // only supports math.Int, sdk.Coin or time.Time, other structs are not recognized arg: "100bar", fieldIndex: 7, expectedStruct: testingStruct{Struct: sdk.NewCoin("bar", sdk.NewInt(10))}, }, "Unrecognizable struct": { - testingStruct: testingStruct{Struct: testingStruct{}}, // only supports sdk.Int, sdk.Coin or time.Time, other structs are not recognized + testingStruct: testingStruct{Struct: testingStruct{}}, // only supports math.Int, sdk.Coin or time.Time, other structs are not recognized arg: "whatever", fieldIndex: 7, expectingErr: true, diff --git a/osmoutils/sumtree/legacy/v101/tree.go b/osmoutils/sumtree/legacy/v101/tree.go index 22b22a2d0..e0fd73f2f 100644 --- a/osmoutils/sumtree/legacy/v101/tree.go +++ b/osmoutils/sumtree/legacy/v101/tree.go @@ -5,6 +5,7 @@ import ( "encoding/json" "fmt" + "cosmossdk.io/math" "github.com/gogo/protobuf/proto" stypes "github.com/cosmos/cosmos-sdk/store/types" @@ -15,7 +16,7 @@ import ( type Child struct { Index []byte - Acc sdk.Int + Acc math.Int } type Children []Child // branch nodes diff --git a/osmoutils/sumtree/node.go b/osmoutils/sumtree/node.go index fd62f6f3d..5ec02babd 100644 --- a/osmoutils/sumtree/node.go +++ b/osmoutils/sumtree/node.go @@ -3,12 +3,13 @@ package sumtree import ( "bytes" + "cosmossdk.io/math" "github.com/gogo/protobuf/proto" sdk "github.com/cosmos/cosmos-sdk/types" ) -func NewLeaf(key []byte, acc sdk.Int) *Leaf { +func NewLeaf(key []byte, acc math.Int) *Leaf { return &Leaf{Leaf: &Child{ Index: key, Accumulation: acc, @@ -208,7 +209,7 @@ func (ptr *ptr) pull(key []byte) { } } -func (node Node) accumulate() (res sdk.Int) { +func (node Node) accumulate() (res math.Int) { res = sdk.ZeroInt() for _, child := range node.Children { res = res.Add(child.Accumulation) @@ -237,7 +238,7 @@ func (node Node) find(key []byte) (idx int, match bool) { return len(node.Children), false } -func (node *Node) setAcc(idx int, acc sdk.Int) *Node { +func (node *Node) setAcc(idx int, acc math.Int) *Node { node.Children[idx] = &Child{node.Children[idx].Index, acc} return node } diff --git a/osmoutils/sumtree/tree.go b/osmoutils/sumtree/tree.go index 9db0c53ca..59d105888 100644 --- a/osmoutils/sumtree/tree.go +++ b/osmoutils/sumtree/tree.go @@ -7,6 +7,7 @@ import ( "encoding/binary" "fmt" + "cosmossdk.io/math" "github.com/gogo/protobuf/proto" store "github.com/cosmos/cosmos-sdk/store" @@ -37,7 +38,7 @@ func (t Tree) IsEmpty() bool { return !t.store.Has(t.leafKey(nil)) } -func (t Tree) Set(key []byte, acc sdk.Int) { +func (t Tree) Set(key []byte, acc math.Int) { ptr := t.ptrGet(0, key) leaf := NewLeaf(key, acc) ptr.setLeaf(leaf) @@ -55,12 +56,12 @@ func (t Tree) Remove(key []byte) { parent.pull(key) } -func (t Tree) Increase(key []byte, amt sdk.Int) { +func (t Tree) Increase(key []byte, amt math.Int) { value := t.Get(key) t.Set(key, value.Add(amt)) } -func (t Tree) Decrease(key []byte, amt sdk.Int) { +func (t Tree) Decrease(key []byte, amt math.Int) { t.Increase(key, amt.Neg()) } @@ -135,8 +136,8 @@ func (t Tree) root() *ptr { } } -// Get returns the (sdk.Int) accumulation value at a given leaf. -func (t Tree) Get(key []byte) sdk.Int { +// Get returns the (math.Int) accumulation value at a given leaf. +func (t Tree) Get(key []byte) math.Int { res := new(Leaf) keybz := t.leafKey(key) if !t.store.Has(keybz) { @@ -208,7 +209,7 @@ func (t Tree) ReverseIterator(begin, end []byte) store.Iterator { // exact: leaf with key = provided key // right: all leaves under nodePointer with key > provided key // Note that the equalities here are _exclusive_. -func (ptr *ptr) accumulationSplit(key []byte) (left sdk.Int, exact sdk.Int, right sdk.Int) { +func (ptr *ptr) accumulationSplit(key []byte) (left math.Int, exact math.Int, right math.Int) { left, exact, right = sdk.ZeroInt(), sdk.ZeroInt(), sdk.ZeroInt() if ptr.isLeaf() { var leaf Leaf @@ -243,12 +244,12 @@ func (ptr *ptr) accumulationSplit(key []byte) (left sdk.Int, exact sdk.Int, righ } // TotalAccumulatedValue returns the sum of the weights for all leaves. -func (t Tree) TotalAccumulatedValue() sdk.Int { +func (t Tree) TotalAccumulatedValue() math.Int { return t.SubsetAccumulation(nil, nil) } // Prefix sum returns the total weight of all leaves with keys <= to the provided key. -func (t Tree) PrefixSum(key []byte) sdk.Int { +func (t Tree) PrefixSum(key []byte) math.Int { return t.SubsetAccumulation(nil, key) } @@ -256,7 +257,7 @@ func (t Tree) PrefixSum(key []byte) sdk.Int { // between start and end (inclusive of both ends) // if start is nil, it is the beginning of the tree. // if end is nil, it is the end of the tree. -func (t Tree) SubsetAccumulation(start []byte, end []byte) sdk.Int { +func (t Tree) SubsetAccumulation(start []byte, end []byte) math.Int { if start == nil { left, exact, _ := t.root().accumulationSplit(end) return left.Add(exact) @@ -270,11 +271,11 @@ func (t Tree) SubsetAccumulation(start []byte, end []byte) sdk.Int { return leftexact.Add(leftrest).Sub(rightest) } -func (t Tree) SplitAcc(key []byte) (sdk.Int, sdk.Int, sdk.Int) { +func (t Tree) SplitAcc(key []byte) (math.Int, math.Int, math.Int) { return t.root().accumulationSplit(key) } -func (ptr *ptr) visualize(depth int, acc sdk.Int) { +func (ptr *ptr) visualize(depth int, acc math.Int) { if !ptr.exists() { return } @@ -291,5 +292,5 @@ func (ptr *ptr) visualize(depth int, acc sdk.Int) { // DebugVisualize prints the entire tree to stdout. func (t Tree) DebugVisualize() { - t.root().visualize(0, sdk.Int{}) + t.root().visualize(0, math.Int{}) } diff --git a/x/mint/keeper/keeper.go b/x/mint/keeper/keeper.go index 935c5d0d1..4de59a1e0 100644 --- a/x/mint/keeper/keeper.go +++ b/x/mint/keeper/keeper.go @@ -1,6 +1,7 @@ package keeper import ( + "cosmossdk.io/math" "github.com/cometbft/cometbft/libs/log" "github.com/CosmosContracts/juno/v15/x/mint/types" @@ -88,13 +89,13 @@ func (k Keeper) SetParams(ctx sdk.Context, params types.Params) { // StakingTokenSupply implements an alias call to the underlying staking keeper's // StakingTokenSupply to be used in BeginBlocker. -func (k Keeper) StakingTokenSupply(ctx sdk.Context) sdk.Int { +func (k Keeper) StakingTokenSupply(ctx sdk.Context) math.Int { return k.stakingKeeper.StakingTokenSupply(ctx) } // TokenSupply implements an alias call to the underlying bank keeper's // TokenSupply to be used in BeginBlocker. -func (k Keeper) TokenSupply(ctx sdk.Context, denom string) sdk.Int { +func (k Keeper) TokenSupply(ctx sdk.Context, denom string) math.Int { return k.bankKeeper.GetSupply(ctx, denom).Amount } diff --git a/x/mint/types/expected_keepers.go b/x/mint/types/expected_keepers.go index 6c18f3b07..ca96a4901 100644 --- a/x/mint/types/expected_keepers.go +++ b/x/mint/types/expected_keepers.go @@ -1,13 +1,14 @@ package types // noalias import ( + "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth/types" ) // StakingKeeper defines the expected staking keeper type StakingKeeper interface { - StakingTokenSupply(ctx sdk.Context) sdk.Int + StakingTokenSupply(ctx sdk.Context) math.Int BondedRatio(ctx sdk.Context) sdk.Dec } diff --git a/x/mint/types/minter.go b/x/mint/types/minter.go index d528be1ca..2a8d90671 100644 --- a/x/mint/types/minter.go +++ b/x/mint/types/minter.go @@ -3,12 +3,13 @@ package types import ( "fmt" + "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" ) // NewMinter returns a new Minter object with the given inflation and annual // provisions values. -func NewMinter(inflation, annualProvisions sdk.Dec, phase, startPhaseBlock uint64, targetSupply sdk.Int) Minter { +func NewMinter(inflation, annualProvisions sdk.Dec, phase, startPhaseBlock uint64, targetSupply math.Int) Minter { return Minter{ Inflation: inflation, AnnualProvisions: annualProvisions, @@ -72,7 +73,7 @@ func (m Minter) PhaseInflationRate(phase uint64) sdk.Dec { } // NextPhase returns the new phase. -func (m Minter) NextPhase(_ Params, currentSupply sdk.Int) uint64 { +func (m Minter) NextPhase(_ Params, currentSupply math.Int) uint64 { nonePhase := m.Phase == 0 if nonePhase { return 1 @@ -87,13 +88,13 @@ func (m Minter) NextPhase(_ Params, currentSupply sdk.Int) uint64 { // NextAnnualProvisions returns the annual provisions based on current total // supply and inflation rate. -func (m Minter) NextAnnualProvisions(_ Params, totalSupply sdk.Int) sdk.Dec { +func (m Minter) NextAnnualProvisions(_ Params, totalSupply math.Int) sdk.Dec { return m.Inflation.MulInt(totalSupply) } // BlockProvision returns the provisions for a block based on the annual // provisions rate. -func (m Minter) BlockProvision(params Params, totalSupply sdk.Int) sdk.Coin { +func (m Minter) BlockProvision(params Params, totalSupply math.Int) sdk.Coin { provisionAmt := m.AnnualProvisions.QuoInt(sdk.NewInt(int64(params.BlocksPerYear))) // Because of rounding, we might mint too many tokens in this phase, let's limit it diff --git a/x/mint/types/minter_test.go b/x/mint/types/minter_test.go index 4688ee9b1..718f6cbb7 100644 --- a/x/mint/types/minter_test.go +++ b/x/mint/types/minter_test.go @@ -4,6 +4,7 @@ import ( "math/rand" "testing" + "cosmossdk.io/math" "github.com/stretchr/testify/require" sdk "github.com/cosmos/cosmos-sdk/types" @@ -63,8 +64,8 @@ func TestNextPhase(t *testing.T) { blocksPerYear := uint64(100) tests := []struct { currentBlock, currentPhase, startPhaseBlock, blocksYear, expPhase uint64 - currentSupply sdk.Int - targetSupply sdk.Int + currentSupply math.Int + targetSupply math.Int }{ {1, 0, 0, blocksPerYear, 1, sdk.NewInt(10000), sdk.NewInt(14000)}, {50, 1, 1, blocksPerYear, 1, sdk.NewInt(12000), sdk.NewInt(14000)}, @@ -99,7 +100,7 @@ func TestBlockProvision(t *testing.T) { tests := []struct { annualProvisions int64 expProvisions int64 - totalSupply sdk.Int + totalSupply math.Int }{ {secondsPerYear / 5, 1, sdk.NewInt(1)}, {secondsPerYear/5 + 1, 1, sdk.NewInt(1)}, @@ -134,7 +135,7 @@ func TestBlockProvision(t *testing.T) { } // Benchmarking :) -// previously using sdk.Int operations: +// previously using math.Int operations: // BenchmarkBlockProvision-4 5000000 220 ns/op // // using sdk.Dec operations: (current implementation) diff --git a/x/tokenfactory/bindings/types/msg.go b/x/tokenfactory/bindings/types/msg.go index 4e2735472..538d42651 100644 --- a/x/tokenfactory/bindings/types/msg.go +++ b/x/tokenfactory/bindings/types/msg.go @@ -1,6 +1,6 @@ package types -import sdk "github.com/cosmos/cosmos-sdk/types" +import "cosmossdk.io/math" type TokenFactoryMsg struct { Token *TokenMsg `json:"token,omitempty"` @@ -44,15 +44,15 @@ type ChangeAdmin struct { } type MintTokens struct { - Denom string `json:"denom"` - Amount sdk.Int `json:"amount"` - MintToAddress string `json:"mint_to_address"` + Denom string `json:"denom"` + Amount math.Int `json:"amount"` + MintToAddress string `json:"mint_to_address"` } type BurnTokens struct { - Denom string `json:"denom"` - Amount sdk.Int `json:"amount"` - BurnFromAddress string `json:"burn_from_address"` + Denom string `json:"denom"` + Amount math.Int `json:"amount"` + BurnFromAddress string `json:"burn_from_address"` } type SetMetadata struct { @@ -61,8 +61,8 @@ type SetMetadata struct { } type ForceTransfer struct { - Denom string `json:"denom"` - Amount sdk.Int `json:"amount"` - FromAddress string `json:"from_address"` - ToAddress string `json:"to_address"` + Denom string `json:"denom"` + Amount math.Int `json:"amount"` + FromAddress string `json:"from_address"` + ToAddress string `json:"to_address"` } From da9ff57a5621481106a3743a5ff04b5c944f62aa Mon Sep 17 00:00:00 2001 From: Jacob Gadikian Date: Mon, 24 Apr 2023 14:31:13 +0700 Subject: [PATCH 028/131] errorsmod --- go.mod | 5 ++++- go.sum | 18 ++---------------- x/ibc-hooks/types/errors.go | 14 +++++++------- 3 files changed, 13 insertions(+), 24 deletions(-) diff --git a/go.mod b/go.mod index b82187446..811bc1681 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module github.com/CosmosContracts/juno/v15 go 1.19 require ( + cosmossdk.io/errors v1.0.0-beta.7 cosmossdk.io/math v1.0.0 cosmossdk.io/simapp v0.0.0-20230224204036-a6adb0821462 github.com/CosmWasm/wasmd v0.40.0-rc.1.0.20230422061626-b85abcf1d7b8 @@ -32,7 +33,6 @@ require ( cloud.google.com/go/compute/metadata v0.2.3 // indirect cloud.google.com/go/iam v0.12.0 // indirect cloud.google.com/go/storage v1.29.0 // indirect - cosmossdk.io/errors v1.0.0-beta.7 // indirect cosmossdk.io/tools/rosetta v0.2.1 // indirect github.com/aws/aws-sdk-go v1.44.203 // indirect github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect @@ -195,4 +195,7 @@ replace ( // temporary, need to fix, issue is at import of: github.com/cosmos/gogogateway github.com/gogo/protobuf v1.3.3 => github.com/gogo/protobuf v1.3.2 + + // pin the version of goleveldb to v1.0.1-0.20210819022825-2ae1ddf74ef7 + github.com/syndtr/goleveldb => github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 ) diff --git a/go.sum b/go.sum index 72e59e4a0..be730060e 100644 --- a/go.sum +++ b/go.sum @@ -495,7 +495,6 @@ github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2 github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= 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/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= @@ -538,7 +537,6 @@ github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5Nq 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/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= 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= github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8= @@ -658,7 +656,6 @@ github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLe 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-20210407192527-94a9f03dee38/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= @@ -946,7 +943,6 @@ github.com/notional-labs/cosmos-sdk v0.47.2-0.20230424060617-ebc292e8de8b h1:ftj github.com/notional-labs/cosmos-sdk v0.47.2-0.20230424060617-ebc292e8de8b/go.mod h1:IH/tRaPQEdWAbDuvtyNyPcfPz0DS/ESpmBRXOd5jCas= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= -github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= 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= @@ -956,16 +952,11 @@ github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W 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= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= -github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= -github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= -github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= +github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= -github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= github.com/onsi/gomega v1.26.0 h1:03cDLK28U6hWvCAns6NeydX3zIm4SF3ci69ulidS32Q= 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= @@ -1134,16 +1125,14 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5 github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= +github.com/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.20220721030215-126854af5e6d h1:vfofYNRScrDdvS342BElfbETmL1Aiz3i2t0zfRj16Hs= -github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d/go.mod h1:RRCYJbIwD5jmqPI9XoAFR0OcDxqUctll6zUj/+B4S48= github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c h1:g+WoO5jjkqGAzHWCjJB1zZfXPIAaDpzXIEJ0eS6B5Ok= github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c/go.mod h1:ahpPrc7HpcfEWDQRZEmnXMzHY03mLDYMCxeDzy46i+8= github.com/tendermint/go-amino v0.16.0 h1:GyhmgQKvqF82e2oZeuMSp9JTN0N09emoSZlb2lyGa2E= @@ -1338,7 +1327,6 @@ golang.org/x/net v0.0.0-20210220033124-5f55cee0dc0d/go.mod h1:m0MpNAwzfU5UDzcl9v 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-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= @@ -1456,7 +1444,6 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210112080510-489259a85091/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= @@ -1587,7 +1574,6 @@ golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82u golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= 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= diff --git a/x/ibc-hooks/types/errors.go b/x/ibc-hooks/types/errors.go index 9683d397f..6c85a3685 100644 --- a/x/ibc-hooks/types/errors.go +++ b/x/ibc-hooks/types/errors.go @@ -1,15 +1,15 @@ package types -import sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" +import errorsmod "cosmossdk.io/errors" var ( ErrBadMetadataFormatMsg = "wasm metadata not properly formatted for: '%v'. %s" ErrBadExecutionMsg = "cannot execute contract: %v" - ErrMsgValidation = sdkerrors.Register("wasm-hooks", 2, "error in wasmhook message validation") - ErrMarshaling = sdkerrors.Register("wasm-hooks", 3, "cannot marshal the ICS20 packet") - ErrInvalidPacket = sdkerrors.Register("wasm-hooks", 4, "invalid packet data") - ErrBadResponse = sdkerrors.Register("wasm-hooks", 5, "cannot create response") - ErrWasmError = sdkerrors.Register("wasm-hooks", 6, "wasm error") - ErrBadSender = sdkerrors.Register("wasm-hooks", 7, "bad sender") + ErrMsgValidation = errorsmod.Register("wasm-hooks", 2, "error in wasmhook message validation") + ErrMarshaling = errorsmod.Register("wasm-hooks", 3, "cannot marshal the ICS20 packet") + ErrInvalidPacket = errorsmod.Register("wasm-hooks", 4, "invalid packet data") + ErrBadResponse = errorsmod.Register("wasm-hooks", 5, "cannot create response") + ErrWasmError = errorsmod.Register("wasm-hooks", 6, "wasm error") + ErrBadSender = errorsmod.Register("wasm-hooks", 7, "bad sender") ) From bbad07f2bd38044997c5157676529bc496ff2929 Mon Sep 17 00:00:00 2001 From: Jacob Gadikian Date: Mon, 24 Apr 2023 14:33:22 +0700 Subject: [PATCH 029/131] errorsmod --- x/tokenfactory/module.go | 16 ---------------- x/tokenfactory/types/errors.go | 22 +++++++++++----------- 2 files changed, 11 insertions(+), 27 deletions(-) diff --git a/x/tokenfactory/module.go b/x/tokenfactory/module.go index e2a4f5e32..3f6bec93f 100644 --- a/x/tokenfactory/module.go +++ b/x/tokenfactory/module.go @@ -12,7 +12,6 @@ import ( "context" "encoding/json" "fmt" - "math/rand" abci "github.com/cometbft/cometbft/abci/types" "github.com/cosmos/cosmos-sdk/client" @@ -127,19 +126,9 @@ func (am AppModule) Name() string { return am.AppModuleBasic.Name() } -// Route returns the x/tokenfactory module's message routing key. -func (am AppModule) Route() sdk.Route { - return sdk.Route{} -} - // QuerierRoute returns the x/tokenfactory module's query routing key. func (AppModule) QuerierRoute() string { return types.QuerierRoute } -// LegacyQuerierHandler returns the x/tokenfactory module's Querier. -func (am AppModule) LegacyQuerierHandler(_ *codec.LegacyAmino) sdk.Querier { - return nil -} - // RegisterServices registers a GRPC query service to respond to the // module-specific GRPC queries. func (am AppModule) RegisterServices(cfg module.Configurator) { @@ -214,11 +203,6 @@ func (am AppModule) ProposalContents(_ module.SimulationState) []simtypes.Weight return nil } -// RandomizedParams creates randomized bank param changes for the simulator. -func (am AppModule) RandomizedParams(r *rand.Rand) []simtypes.ParamChange { - return simulation.ParamChanges(r) -} - // RegisterStoreDecoder registers a decoder for supply module's types func (am AppModule) RegisterStoreDecoder(_ sdk.StoreDecoderRegistry) { } diff --git a/x/tokenfactory/types/errors.go b/x/tokenfactory/types/errors.go index d5e09de19..5a3c587d0 100644 --- a/x/tokenfactory/types/errors.go +++ b/x/tokenfactory/types/errors.go @@ -5,19 +5,19 @@ package types import ( fmt "fmt" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + errorsmod "cosmossdk.io/errors" ) // x/tokenfactory module sentinel errors var ( - ErrDenomExists = sdkerrors.Register(ModuleName, 2, "attempting to create a denom that already exists (has bank metadata)") - ErrUnauthorized = sdkerrors.Register(ModuleName, 3, "unauthorized account") - ErrInvalidDenom = sdkerrors.Register(ModuleName, 4, "invalid denom") - ErrInvalidCreator = sdkerrors.Register(ModuleName, 5, "invalid creator") - ErrInvalidAuthorityMetadata = sdkerrors.Register(ModuleName, 6, "invalid authority metadata") - ErrInvalidGenesis = sdkerrors.Register(ModuleName, 7, "invalid genesis") - ErrSubdenomTooLong = sdkerrors.Register(ModuleName, 8, fmt.Sprintf("subdenom too long, max length is %d bytes", MaxSubdenomLength)) - ErrCreatorTooLong = sdkerrors.Register(ModuleName, 9, fmt.Sprintf("creator too long, max length is %d bytes", MaxCreatorLength)) - ErrDenomDoesNotExist = sdkerrors.Register(ModuleName, 10, "denom does not exist") - ErrCapabilityNotEnabled = sdkerrors.Register(ModuleName, 11, "this capability is not enabled on chain") + ErrDenomExists = errorsmod.Register(ModuleName, 2, "attempting to create a denom that already exists (has bank metadata)") + ErrUnauthorized = errorsmod.Register(ModuleName, 3, "unauthorized account") + ErrInvalidDenom = errorsmod.Register(ModuleName, 4, "invalid denom") + ErrInvalidCreator = errorsmod.Register(ModuleName, 5, "invalid creator") + ErrInvalidAuthorityMetadata = errorsmod.Register(ModuleName, 6, "invalid authority metadata") + ErrInvalidGenesis = errorsmod.Register(ModuleName, 7, "invalid genesis") + ErrSubdenomTooLong = errorsmod.Register(ModuleName, 8, fmt.Sprintf("subdenom too long, max length is %d bytes", MaxSubdenomLength)) + ErrCreatorTooLong = errorsmod.Register(ModuleName, 9, fmt.Sprintf("creator too long, max length is %d bytes", MaxCreatorLength)) + ErrDenomDoesNotExist = errorsmod.Register(ModuleName, 10, "denom does not exist") + ErrCapabilityNotEnabled = errorsmod.Register(ModuleName, 11, "this capability is not enabled on chain") ) From 4d3d350a12c409b6bc99f32d0f0cd466e0c6cd9f Mon Sep 17 00:00:00 2001 From: Jacob Gadikian Date: Mon, 24 Apr 2023 14:39:16 +0700 Subject: [PATCH 030/131] feeshare --- cmd/junod/main.go | 2 +- x/feeshare/keeper/msg_server.go | 9 +++++---- x/feeshare/module.go | 11 ----------- x/ibc-hooks/sdkmodule.go | 11 ----------- x/mint/module_test.go | 2 +- 5 files changed, 7 insertions(+), 28 deletions(-) diff --git a/cmd/junod/main.go b/cmd/junod/main.go index 915394b24..330c85a8b 100644 --- a/cmd/junod/main.go +++ b/cmd/junod/main.go @@ -14,7 +14,7 @@ func main() { app.SetAddressPrefixes() rootCmd, _ := cmd.NewRootCmd() - if err := svrcmd.Execute(rootCmd, app.DefaultNodeHome); err != nil { + if err := svrcmd.Execute(rootCmd, "JUNOD", app.DefaultNodeHome); err != nil { switch e := err.(type) { case server.ErrorCode: os.Exit(e.Code) diff --git a/x/feeshare/keeper/msg_server.go b/x/feeshare/keeper/msg_server.go index 675cbebbd..32103d287 100644 --- a/x/feeshare/keeper/msg_server.go +++ b/x/feeshare/keeper/msg_server.go @@ -3,6 +3,7 @@ package keeper import ( "context" + errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" @@ -90,18 +91,18 @@ func (k Keeper) RegisterFeeShare( // Get Contract contract, err := sdk.AccAddressFromBech32(msg.ContractAddress) if err != nil { - return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid contract address (%s)", err) + return nil, errorsmod.Wrapf(sdkerrors.ErrInvalidAddress, "invalid contract address (%s)", err) } // Check if contract is already registered if k.IsFeeShareRegistered(ctx, contract) { - return nil, sdkerrors.Wrapf(types.ErrFeeShareAlreadyRegistered, "contract is already registered %s", contract) + return nil, errorsmod.Wrapf(types.ErrFeeShareAlreadyRegistered, "contract is already registered %s", contract) } // Get the withdraw address of the contract withdrawer, err := sdk.AccAddressFromBech32(msg.WithdrawerAddress) if err != nil { - return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid withdrawer address %s", msg.WithdrawerAddress) + return nil, errorsmod.Wrapf(sdkerrors.ErrInvalidAddress, "invalid withdrawer address %s", msg.WithdrawerAddress) } var deployer sdk.AccAddress @@ -109,7 +110,7 @@ func (k Keeper) RegisterFeeShare( if k.GetIfContractWasCreatedFromFactory(ctx, contract, k.wasmKeeper.GetContractInfo(ctx, contract)) { // Anyone is allowed to register a contract to itself if it was created from a factory contract if msg.WithdrawerAddress != msg.ContractAddress { - return nil, sdkerrors.Wrapf(types.ErrFeeShareInvalidWithdrawer, "withdrawer address must be the same as the contract address if it is from a factory contract withdraw:%s contract:%s", msg.WithdrawerAddress, msg.ContractAddress) + return nil, errorsmod.Wrapf(types.ErrFeeShareInvalidWithdrawer, "withdrawer address must be the same as the contract address if it is from a factory contract withdraw:%s contract:%s", msg.WithdrawerAddress, msg.ContractAddress) } // set the deployer address to the contract address so it can self register diff --git a/x/feeshare/module.go b/x/feeshare/module.go index 73c3fab16..70f631206 100644 --- a/x/feeshare/module.go +++ b/x/feeshare/module.go @@ -4,7 +4,6 @@ import ( "context" "encoding/json" "fmt" - "math/rand" abci "github.com/cometbft/cometbft/abci/types" "github.com/cosmos/cosmos-sdk/client" @@ -127,11 +126,6 @@ func (am AppModule) NewHandler() sdk.Handler { return nil } -// Route returns the fees module's message routing key. -func (am AppModule) Route() sdk.Route { - return sdk.NewRoute(types.RouterKey, am.NewHandler()) -} - // QuerierRoute returns the claim module's query routing key. func (am AppModule) QuerierRoute() string { return types.RouterKey @@ -183,11 +177,6 @@ func (am AppModule) ProposalContents(_ module.SimulationState) []simtypes.Weight return []simtypes.WeightedProposalContent{} } -// RandomizedParams creates randomized fees param changes for the simulator. -func (am AppModule) RandomizedParams(_ *rand.Rand) []simtypes.ParamChange { - return []simtypes.ParamChange{} -} - // RegisterStoreDecoder registers a decoder for fees module's types. func (am AppModule) RegisterStoreDecoder(_ sdk.StoreDecoderRegistry) { } diff --git a/x/ibc-hooks/sdkmodule.go b/x/ibc-hooks/sdkmodule.go index 3f3e6f4ce..4bf1c6b17 100644 --- a/x/ibc-hooks/sdkmodule.go +++ b/x/ibc-hooks/sdkmodule.go @@ -2,7 +2,6 @@ package ibc_hooks import ( "encoding/json" - "fmt" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" @@ -94,21 +93,11 @@ func (AppModule) Name() string { // RegisterInvariants registers the ibc-hooks module invariants. func (am AppModule) RegisterInvariants(_ sdk.InvariantRegistry) {} -// Route returns the message routing key for the ibc-hooks module. -func (AppModule) Route() sdk.Route { return sdk.Route{} } - // QuerierRoute returns the module's querier route name. func (AppModule) QuerierRoute() string { return "" } -// LegacyQuerierHandler returns the x/ibc-hooks module's sdk.Querier. -func (am AppModule) LegacyQuerierHandler(legacyQuerierCdc *codec.LegacyAmino) sdk.Querier { - return func(sdk.Context, []string, abci.RequestQuery) ([]byte, error) { - return nil, fmt.Errorf("legacy querier not supported for the x/%s module", types.ModuleName) - } -} - // RegisterServices registers a gRPC query service to respond to the // module-specific gRPC queries. func (am AppModule) RegisterServices(cfg module.Configurator) { diff --git a/x/mint/module_test.go b/x/mint/module_test.go index 811dfc988..bbbd610b6 100644 --- a/x/mint/module_test.go +++ b/x/mint/module_test.go @@ -13,7 +13,7 @@ import ( ) func TestItCreatesModuleAccountOnInitBlock(t *testing.T) { - app := simapp.Setup(false) + app := simapp.Setup(t, false) ctx := app.BaseApp.NewContext(false, tmproto.Header{}) app.InitChain( From 229e32720f0a35f58aef3e98022d07fd95ea224e Mon Sep 17 00:00:00 2001 From: Jacob Gadikian Date: Mon, 24 Apr 2023 14:48:24 +0700 Subject: [PATCH 031/131] sdkerrors -> errorsmod --- app/ante.go | 2 +- app/apptesting/test_suite.go | 6 ++++-- app/test_helpers.go | 4 ++-- osmoutils/sumtree/legacy/v101/tree_test.go | 2 +- osmoutils/sumtree/tree_test.go | 2 +- x/feeshare/module.go | 4 ++-- x/tokenfactory/types/msgs.go | 5 +++-- 7 files changed, 14 insertions(+), 11 deletions(-) diff --git a/app/ante.go b/app/ante.go index 6adbe4035..35b7869ad 100644 --- a/app/ante.go +++ b/app/ante.go @@ -89,7 +89,7 @@ func NewAnteHandler(options HandlerOptions) (sdk.AnteHandler, error) { ante.NewSigGasConsumeDecorator(options.AccountKeeper, sigGasConsumer), ante.NewSigVerificationDecorator(options.AccountKeeper, options.SignModeHandler), ante.NewIncrementSequenceDecorator(options.AccountKeeper), - ibcante.NewAnteDecorator(options.IBCKeeper), + ibcante.NewRedundantRelayDecorator(options.IBCKeeper), } return sdk.ChainAnteDecorators(anteDecorators...), nil diff --git a/app/apptesting/test_suite.go b/app/apptesting/test_suite.go index 5722b1f43..02c005581 100644 --- a/app/apptesting/test_suite.go +++ b/app/apptesting/test_suite.go @@ -51,7 +51,8 @@ var ( // Setup sets up basic environment for suite (App, Ctx, and test accounts) func (s *KeeperTestHelper) Setup() { - s.App = app.Setup(false) + var t *testing.T + s.App = app.Setup(t) s.Ctx = s.App.BaseApp.NewContext(false, tmtypes.Header{Height: 1, ChainID: "osmosis-1", Time: time.Now().UTC()}) s.QueryHelper = &baseapp.QueryServiceTestHelper{ GRPCQueryRouter: s.App.GRPCQueryRouter(), @@ -61,8 +62,9 @@ func (s *KeeperTestHelper) Setup() { } func (s *KeeperTestHelper) SetupTestForInitGenesis() { + var t *testing.T // Setting to True, leads to init genesis not running - s.App = app.Setup(true) + s.App = app.Setup(t) s.Ctx = s.App.BaseApp.NewContext(true, tmtypes.Header{}) } diff --git a/app/test_helpers.go b/app/test_helpers.go index 6a147e660..f22aefcbc 100644 --- a/app/test_helpers.go +++ b/app/test_helpers.go @@ -41,8 +41,8 @@ func (ao EmptyBaseAppOptions) Get(_ string) interface{} { // DefaultConsensusParams defines the default Tendermint consensus params used // in junoApp testing. -var DefaultConsensusParams = &abci.ConsensusParams{ - Block: &abci.BlockParams{ +var DefaultConsensusParams = &tmproto.ConsensusParams{ + Block: &tmproto.BlockParams{ MaxBytes: 200000, MaxGas: 2000000, }, diff --git a/osmoutils/sumtree/legacy/v101/tree_test.go b/osmoutils/sumtree/legacy/v101/tree_test.go index d09b607bb..edf520b6e 100644 --- a/osmoutils/sumtree/legacy/v101/tree_test.go +++ b/osmoutils/sumtree/legacy/v101/tree_test.go @@ -13,7 +13,7 @@ import ( "github.com/cosmos/iavl" - dbm "github.com/tendermint/tm-db" + dbm "github.com/cometbft/cometbft-db" iavlstore "github.com/cosmos/cosmos-sdk/store/iavl" sdk "github.com/cosmos/cosmos-sdk/types" diff --git a/osmoutils/sumtree/tree_test.go b/osmoutils/sumtree/tree_test.go index bc54db386..56a009931 100644 --- a/osmoutils/sumtree/tree_test.go +++ b/osmoutils/sumtree/tree_test.go @@ -10,7 +10,7 @@ import ( "github.com/cosmos/iavl" - dbm "github.com/tendermint/tm-db" + dbm "github.com/cometbft/cometbft-db" iavlstore "github.com/cosmos/cosmos-sdk/store/iavl" sdk "github.com/cosmos/cosmos-sdk/types" diff --git a/x/feeshare/module.go b/x/feeshare/module.go index 70f631206..0978367fd 100644 --- a/x/feeshare/module.go +++ b/x/feeshare/module.go @@ -173,8 +173,8 @@ func (am AppModule) GenerateGenesisState(_ *module.SimulationState) { } // ProposalContents returns content functions for governance proposals. -func (am AppModule) ProposalContents(_ module.SimulationState) []simtypes.WeightedProposalContent { - return []simtypes.WeightedProposalContent{} +func (am AppModule) ProposalContents(_ module.SimulationState) []simtypes.WeightedProposalMsg { + return []simtypes.WeightedProposalMsg{} } // RegisterStoreDecoder registers a decoder for fees module's types. diff --git a/x/tokenfactory/types/msgs.go b/x/tokenfactory/types/msgs.go index be5e8a716..09c648f83 100644 --- a/x/tokenfactory/types/msgs.go +++ b/x/tokenfactory/types/msgs.go @@ -1,6 +1,7 @@ package types import ( + errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" @@ -31,12 +32,12 @@ func (m MsgCreateDenom) Type() string { return TypeMsgCreateDenom } func (m MsgCreateDenom) ValidateBasic() error { _, err := sdk.AccAddressFromBech32(m.Sender) if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "Invalid sender address (%s)", err) + return errorsmod.Wrapf(sdkerrors.ErrInvalidAddress, "Invalid sender address (%s)", err) } _, err = GetTokenDenom(m.Sender, m.Subdenom) if err != nil { - return sdkerrors.Wrap(ErrInvalidDenom, err.Error()) + return errorsmod.Wrap(ErrInvalidDenom, err.Error()) } return nil From 4ed89facf4a93452e1fc4c7e7849d070aaa4e67d Mon Sep 17 00:00:00 2001 From: Jacob Gadikian Date: Mon, 24 Apr 2023 14:57:33 +0700 Subject: [PATCH 032/131] errors module --- x/ibc-hooks/ibc_module.go | 11 ++++++++--- x/tokenfactory/types/msgs.go | 26 +++++++++++++------------- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/x/ibc-hooks/ibc_module.go b/x/ibc-hooks/ibc_module.go index 94e542ae0..fea66edbe 100644 --- a/x/ibc-hooks/ibc_module.go +++ b/x/ibc-hooks/ibc_module.go @@ -6,6 +6,7 @@ import ( capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" // ibc-go + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" porttypes "github.com/cosmos/ibc-go/v7/modules/core/05-port/types" ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" @@ -237,9 +238,13 @@ func (im IBCMiddleware) OnTimeoutPacket( func (im IBCMiddleware) SendPacket( ctx sdk.Context, chanCap *capabilitytypes.Capability, - packet ibcexported.PacketI, -) error { - return im.ICS4Middleware.SendPacket(ctx, chanCap, packet) + sourcePort string, + sourceChannel string, + timeoutHeight clienttypes.Height, + timeoutTimestamp uint64, + data []byte, +) (uint64, error) { + return im.ICS4Middleware.SendPacket(ctx, chanCap, sourcePort, sourceChannel, timeoutHeight, timeoutTimestamp, data) } // WriteAcknowledgement implements the ICS4 Wrapper interface diff --git a/x/tokenfactory/types/msgs.go b/x/tokenfactory/types/msgs.go index 09c648f83..5d8fc2bde 100644 --- a/x/tokenfactory/types/msgs.go +++ b/x/tokenfactory/types/msgs.go @@ -75,18 +75,18 @@ func (m MsgMint) Type() string { return TypeMsgMint } func (m MsgMint) ValidateBasic() error { _, err := sdk.AccAddressFromBech32(m.Sender) if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "Invalid sender address (%s)", err) + return errorsmod.Wrapf(sdkerrors.ErrInvalidAddress, "Invalid sender address (%s)", err) } if m.MintToAddress != "" { _, err = sdk.AccAddressFromBech32(m.MintToAddress) if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "Invalid mint to address (%s)", err) + return errorsmod.Wrapf(sdkerrors.ErrInvalidAddress, "Invalid mint to address (%s)", err) } } if !m.Amount.IsValid() || m.Amount.Amount.Equal(sdk.ZeroInt()) { - return sdkerrors.Wrap(sdkerrors.ErrInvalidCoins, m.Amount.String()) + return errorsmod.Wrap(sdkerrors.ErrInvalidCoins, m.Amount.String()) } return nil @@ -125,17 +125,17 @@ func (m MsgBurn) Type() string { return TypeMsgBurn } func (m MsgBurn) ValidateBasic() error { _, err := sdk.AccAddressFromBech32(m.Sender) if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "Invalid sender address (%s)", err) + return errorsmod.Wrapf(sdkerrors.ErrInvalidAddress, "Invalid sender address (%s)", err) } if !m.Amount.IsValid() || m.Amount.Amount.Equal(sdk.ZeroInt()) { - return sdkerrors.Wrap(sdkerrors.ErrInvalidCoins, m.Amount.String()) + return errorsmod.Wrap(sdkerrors.ErrInvalidCoins, m.Amount.String()) } if m.BurnFromAddress != "" { _, err = sdk.AccAddressFromBech32(m.BurnFromAddress) if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "Invalid burn from address (%s)", err) + return errorsmod.Wrapf(sdkerrors.ErrInvalidAddress, "Invalid burn from address (%s)", err) } } @@ -168,20 +168,20 @@ func (m MsgForceTransfer) Type() string { return TypeMsgForceTransfer } func (m MsgForceTransfer) ValidateBasic() error { _, err := sdk.AccAddressFromBech32(m.Sender) if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "Invalid sender address (%s)", err) + return errorsmod.Wrapf(sdkerrors.ErrInvalidAddress, "Invalid sender address (%s)", err) } _, err = sdk.AccAddressFromBech32(m.TransferFromAddress) if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "Invalid from address (%s)", err) + return errorsmod.Wrapf(sdkerrors.ErrInvalidAddress, "Invalid from address (%s)", err) } _, err = sdk.AccAddressFromBech32(m.TransferToAddress) if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "Invalid to address (%s)", err) + return errorsmod.Wrapf(sdkerrors.ErrInvalidAddress, "Invalid to address (%s)", err) } if !m.Amount.IsValid() { - return sdkerrors.Wrap(sdkerrors.ErrInvalidCoins, m.Amount.String()) + return errorsmod.Wrap(sdkerrors.ErrInvalidCoins, m.Amount.String()) } return nil @@ -212,12 +212,12 @@ func (m MsgChangeAdmin) Type() string { return TypeMsgChangeAdmin } func (m MsgChangeAdmin) ValidateBasic() error { _, err := sdk.AccAddressFromBech32(m.Sender) if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "Invalid sender address (%s)", err) + return errorsmod.Wrapf(sdkerrors.ErrInvalidAddress, "Invalid sender address (%s)", err) } _, err = sdk.AccAddressFromBech32(m.NewAdmin) if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "Invalid address (%s)", err) + return errorsmod.Wrapf(sdkerrors.ErrInvalidAddress, "Invalid address (%s)", err) } _, _, err = DeconstructDenom(m.Denom) @@ -252,7 +252,7 @@ func (m MsgSetDenomMetadata) Type() string { return TypeMsgSetDenomMetadata } func (m MsgSetDenomMetadata) ValidateBasic() error { _, err := sdk.AccAddressFromBech32(m.Sender) if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "Invalid sender address (%s)", err) + return errorsmod.Wrapf(sdkerrors.ErrInvalidAddress, "Invalid sender address (%s)", err) } err = m.Metadata.Validate() From d56bae1e0eefece1d1ce7f28fd3bcf5fc1eac9c7 Mon Sep 17 00:00:00 2001 From: Jacob Gadikian Date: Mon, 24 Apr 2023 14:59:34 +0700 Subject: [PATCH 033/131] use storetypes --- app/ante.go | 2 +- app/decorators/gov_filter.go | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/app/ante.go b/app/ante.go index 35b7869ad..eed209c6d 100644 --- a/app/ante.go +++ b/app/ante.go @@ -37,7 +37,7 @@ type HandlerOptions struct { IBCKeeper *ibckeeper.Keeper FeeShareKeeper feesharekeeper.Keeper BankKeeperFork feeshareante.BankKeeper - TxCounterStoreKey sdk.StoreKey + TxCounterStoreKey storetypes.StoreKey WasmConfig wasmTypes.WasmConfig Cdc codec.BinaryCodec StakingSubspace paramtypes.Subspace diff --git a/app/decorators/gov_filter.go b/app/decorators/gov_filter.go index e6f981482..fd2a03f08 100644 --- a/app/decorators/gov_filter.go +++ b/app/decorators/gov_filter.go @@ -1,6 +1,7 @@ package decorators import ( + errorsmod "cosmossdk.io/errors" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" @@ -62,7 +63,7 @@ func (gpsd GovPreventSpamDecorator) checkSpamSubmitProposalMsg(ctx sdk.Context, for _, v := range msg.Msgs { err := gpsd.cdc.UnpackAny(v, &innerMsg) if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrUnauthorized, "cannot unmarshal authz exec msgs") + return errorsmod.Wrapf(sdkerrors.ErrUnauthorized, "cannot unmarshal authz exec msgs") } err = validMsg(innerMsg) From 9b6f36d4c2ce7b73d32611b202465474bd9923f2 Mon Sep 17 00:00:00 2001 From: Jacob Gadikian Date: Mon, 24 Apr 2023 15:06:55 +0700 Subject: [PATCH 034/131] remove randomized params for token factory --- app/ante.go | 8 +++++--- app/decorators/gov_filter.go | 6 +++--- app/keepers/keys.go | 4 ++-- x/tokenfactory/simulation/params.go | 23 ----------------------- 4 files changed, 10 insertions(+), 31 deletions(-) delete mode 100644 x/tokenfactory/simulation/params.go diff --git a/app/ante.go b/app/ante.go index eed209c6d..75c318cff 100644 --- a/app/ante.go +++ b/app/ante.go @@ -1,6 +1,7 @@ package app import ( + errorsmod "cosmossdk.io/errors" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" @@ -15,6 +16,7 @@ import ( wasmTypes "github.com/CosmWasm/wasmd/x/wasm/types" decorators "github.com/CosmosContracts/juno/v15/app/decorators" + storetypes "github.com/cosmos/cosmos-sdk/store/types" feeshareante "github.com/CosmosContracts/juno/v15/x/feeshare/ante" feesharekeeper "github.com/CosmosContracts/juno/v15/x/feeshare/keeper" @@ -51,15 +53,15 @@ type HandlerOptions struct { // signer. func NewAnteHandler(options HandlerOptions) (sdk.AnteHandler, error) { if options.AccountKeeper == nil { - return nil, sdkerrors.Wrap(sdkerrors.ErrLogic, "account keeper is required for ante builder") + return nil, errorsmod.Wrap(sdkerrors.ErrLogic, "account keeper is required for ante builder") } if options.BankKeeper == nil { - return nil, sdkerrors.Wrap(sdkerrors.ErrLogic, "bank keeper is required for ante builder") + return nil, errorsmod.Wrap(sdkerrors.ErrLogic, "bank keeper is required for ante builder") } if options.SignModeHandler == nil { - return nil, sdkerrors.Wrap(sdkerrors.ErrLogic, "sign mode handler is required for ante builder") + return nil, errorsmod.Wrap(sdkerrors.ErrLogic, "sign mode handler is required for ante builder") } sigGasConsumer := options.SigGasConsumer diff --git a/app/decorators/gov_filter.go b/app/decorators/gov_filter.go index fd2a03f08..306e9cb8f 100644 --- a/app/decorators/gov_filter.go +++ b/app/decorators/gov_filter.go @@ -7,7 +7,7 @@ import ( sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/authz" govkeeper "github.com/cosmos/cosmos-sdk/x/gov/keeper" - govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + govv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" ) var MiniumInitialDepositRate = sdk.NewDecWithPrec(20, 2) @@ -44,12 +44,12 @@ func (gpsd GovPreventSpamDecorator) AnteHandle( func (gpsd GovPreventSpamDecorator) checkSpamSubmitProposalMsg(ctx sdk.Context, msgs []sdk.Msg) error { validMsg := func(m sdk.Msg) error { - if msg, ok := m.(*govtypes.MsgSubmitProposal); ok { + if msg, ok := m.(*govv1.MsgSubmitProposal); ok { // prevent spam gov msg depositParams := gpsd.govKeeper.GetDepositParams(ctx) miniumInitialDeposit := gpsd.calcMiniumInitialDeposit(depositParams.MinDeposit) if msg.InitialDeposit.IsAllLT(miniumInitialDeposit) { - return sdkerrors.Wrapf(sdkerrors.ErrUnauthorized, "not enough initial deposit. required: %v", miniumInitialDeposit) + return errorsmod.Wrapf(sdkerrors.ErrUnauthorized, "not enough initial deposit. required: %v", miniumInitialDeposit) } } return nil diff --git a/app/keepers/keys.go b/app/keepers/keys.go index cc4ce2f14..c11923756 100644 --- a/app/keepers/keys.go +++ b/app/keepers/keys.go @@ -24,7 +24,7 @@ import ( icahosttypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/host/types" ibcfeetypes "github.com/cosmos/ibc-go/v7/modules/apps/29-fee/types" ibctransfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" - ibchost "github.com/cosmos/ibc-go/v7/modules/core/24-host" + ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" icqtypes "github.com/strangelove-ventures/async-icq/v7/types" packetforwardtypes "github.com/strangelove-ventures/packet-forward-middleware/v7/router/types" ) @@ -33,7 +33,7 @@ func (appKeepers *AppKeepers) GenerateKeys() { appKeepers.keys = sdk.NewKVStoreKeys( authtypes.StoreKey, banktypes.StoreKey, stakingtypes.StoreKey, minttypes.StoreKey, distrtypes.StoreKey, slashingtypes.StoreKey, - govtypes.StoreKey, paramstypes.StoreKey, ibchost.StoreKey, upgradetypes.StoreKey, + govtypes.StoreKey, paramstypes.StoreKey, ibcexported.StoreKey, upgradetypes.StoreKey, evidencetypes.StoreKey, ibctransfertypes.StoreKey, capabilitytypes.StoreKey, authzkeeper.StoreKey, feegrant.StoreKey, icahosttypes.StoreKey, ibcfeetypes.StoreKey, tokenfactorytypes.StoreKey, feesharetypes.StoreKey, wasm.StoreKey, diff --git a/x/tokenfactory/simulation/params.go b/x/tokenfactory/simulation/params.go deleted file mode 100644 index f25901d8c..000000000 --- a/x/tokenfactory/simulation/params.go +++ /dev/null @@ -1,23 +0,0 @@ -package simulation - -import ( - "fmt" - "math/rand" - - "github.com/CosmosContracts/juno/v15/x/tokenfactory/types" - simtypes "github.com/cosmos/cosmos-sdk/types/simulation" - "github.com/cosmos/cosmos-sdk/x/simulation" -) - -func ParamChanges(_ *rand.Rand) []simtypes.ParamChange { - return []simtypes.ParamChange{ - simulation.NewSimParamChange( - types.ModuleName, - string(types.KeyDenomCreationFee), - func(r *rand.Rand) string { - amount := RandDenomCreationFeeParam(r) - return fmt.Sprintf("[{\"denom\":\"%v\",\"amount\":\"%v\"}]", amount[0].Denom, amount[0].Amount) - }, - ), - } -} From 269a0803d44e072085c17f439c9666722f0b959e Mon Sep 17 00:00:00 2001 From: Jacob Gadikian Date: Mon, 24 Apr 2023 15:07:59 +0700 Subject: [PATCH 035/131] storetypes for keys --- app/keepers/keys.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/keepers/keys.go b/app/keepers/keys.go index c11923756..ad17f2a57 100644 --- a/app/keepers/keys.go +++ b/app/keepers/keys.go @@ -60,20 +60,20 @@ func (appKeepers *AppKeepers) GetMemoryStoreKey() map[string]*storetypes.MemoryS // GetKey returns the KVStoreKey for the provided store key. // // NOTE: This is solely to be used for testing purposes. -func (appKeepers *AppKeepers) GetKey(storeKey string) *sdk.KVStoreKey { +func (appKeepers *AppKeepers) GetKey(storeKey string) *storetypes.KVStoreKey { return appKeepers.keys[storeKey] } // GetTKey returns the TransientStoreKey for the provided store key. // // NOTE: This is solely to be used for testing purposes. -func (appKeepers *AppKeepers) GetTKey(storeKey string) *sdk.TransientStoreKey { +func (appKeepers *AppKeepers) GetTKey(storeKey string) *storetypes.TransientStoreKey { return appKeepers.tkeys[storeKey] } // GetMemKey returns the MemStoreKey for the provided mem key. // // NOTE: This is solely used for testing purposes. -func (appKeepers *AppKeepers) GetMemKey(storeKey string) *sdk.MemoryStoreKey { +func (appKeepers *AppKeepers) GetMemKey(storeKey string) *storetypes.MemoryStoreKey { return appKeepers.memKeys[storeKey] } From 8b935e479f57be3addc62e7967db52ed92ad2921 Mon Sep 17 00:00:00 2001 From: Jacob Gadikian Date: Mon, 24 Apr 2023 15:13:08 +0700 Subject: [PATCH 036/131] add simulation params for token factory --- app/params/params.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 app/params/params.go diff --git a/app/params/params.go b/app/params/params.go new file mode 100644 index 000000000..eb88c5a26 --- /dev/null +++ b/app/params/params.go @@ -0,0 +1,15 @@ +package params + +// Simulation parameter constants +const ( + StakePerAccount = "stake_per_account" + InitiallyBondedValidators = "initially_bonded_validators" + + // Token Factory + DefaultWeightMsgCreateDenom int = 100 + DefaultWeightMsgMint int = 100 + DefaultWeightMsgBurn int = 100 + DefaultWeightMsgChangeAdmin int = 100 + DefaultWeightMsgSetDenomMetadata int = 100 + DefaultWeightMsgForceTransfer int = 100 +) From d23d590a26531e8d6a8c2a336777589b9fadaecc Mon Sep 17 00:00:00 2001 From: Jacob Gadikian Date: Tue, 25 Apr 2023 12:14:46 +0700 Subject: [PATCH 037/131] cleanup of imports --- app/ante.go | 4 ++-- app/app.go | 37 ++++++++++++++++++++------------ go.mod | 14 ++++-------- go.sum | 8 +++++-- osmoutils/osmocli/tx_cmd_wrap.go | 5 ++++- x/feeshare/keeper/keeper.go | 5 +++-- 6 files changed, 42 insertions(+), 31 deletions(-) diff --git a/app/ante.go b/app/ante.go index 75c318cff..82f4c69dd 100644 --- a/app/ante.go +++ b/app/ante.go @@ -74,7 +74,7 @@ func NewAnteHandler(options HandlerOptions) (sdk.AnteHandler, error) { decorators.NewMinCommissionDecorator(options.Cdc), wasmkeeper.NewLimitSimulationGasDecorator(options.WasmConfig.SimulationGasLimit), wasmkeeper.NewCountTXDecorator(options.TxCounterStoreKey), - ante.NewRejectExtensionOptionsDecorator(), + ante.NewExtensionOptionsDecorator(options.ExtensionOptionChecker), decorators.MsgFilterDecorator{}, decorators.NewGovPreventSpamDecorator(options.Cdc, options.GovKeeper), ante.NewMempoolFeeDecorator(), @@ -83,7 +83,7 @@ func NewAnteHandler(options HandlerOptions) (sdk.AnteHandler, error) { ante.NewValidateMemoDecorator(options.AccountKeeper), ante.NewConsumeGasForTxSizeDecorator(options.AccountKeeper), gaiafeeante.NewFeeDecorator(options.BypassMinFeeMsgTypes, options.GlobalFeeSubspace, options.StakingSubspace, maxBypassMinFeeMsgGasUsage), - ante.NewDeductFeeDecorator(options.AccountKeeper, options.BankKeeper, options.FeegrantKeeper), + ante.NewDeductFeeDecorator(options.AccountKeeper, options.BankKeeper, options.FeegrantKeeper, options.TxFeeChecker), feeshareante.NewFeeSharePayoutDecorator(options.BankKeeperFork, options.FeeShareKeeper), // SetPubKeyDecorator must be called before all signature verification decorators ante.NewSetPubKeyDecorator(options.AccountKeeper), diff --git a/app/app.go b/app/app.go index cdbcb3740..0658f25eb 100644 --- a/app/app.go +++ b/app/app.go @@ -24,6 +24,7 @@ import ( "github.com/cosmos/cosmos-sdk/server/api" "github.com/cosmos/cosmos-sdk/server/config" servertypes "github.com/cosmos/cosmos-sdk/server/types" + storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/address" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" @@ -193,6 +194,11 @@ type App struct { txConfig client.TxConfig interfaceRegistry types.InterfaceRegistry + // keys to access the substores + keys map[string]*storetypes.KVStoreKey + tkeys map[string]*storetypes.TransientStoreKey + memKeys map[string]*storetypes.MemoryStoreKey + // the module manager ModuleManager *module.Manager @@ -229,10 +235,13 @@ func New( app := &App{ BaseApp: bApp, - cdc: cdc, + legacyAmino: legacyAmino, appCodec: appCodec, + txConfig: txConfig, interfaceRegistry: interfaceRegistry, - invCheckPeriod: invCheckPeriod, + keys: keys, + tkeys: tkeys, + memKeys: memKeys, } // Setup keepers @@ -267,25 +276,25 @@ func New( // NOTE: Any module instantiated in the module manager that is later modified // must be passed by reference here. - app.mm = module.NewManager(appModules(app, encodingConfig, skipGenesisInvariants)...) + app.ModuleManager = module.NewManager(appModules(app, encodingConfig, skipGenesisInvariants)...) // During begin block slashing happens after distr.BeginBlocker so that // there is nothing left over in the validator fee pool, so as to keep the // CanWithdrawInvariant invariant. // NOTE: staking module is required if HistoricalEntries param > 0 - app.mm.SetOrderBeginBlockers(orderBeginBlockers()...) + app.ModuleManager.SetOrderBeginBlockers(orderBeginBlockers()...) - app.mm.SetOrderEndBlockers(orderEndBlockers()...) + app.ModuleManager.SetOrderEndBlockers(orderEndBlockers()...) // NOTE: The genutils module must occur after staking so that pools are // properly initialized with tokens from genesis accounts. // NOTE: Capability module must occur first so that it can initialize any capabilities // so that other modules that want to create or claim capabilities afterwards in InitChain // can do so safely. - app.mm.SetOrderInitGenesis(orderInitBlockers()...) + app.ModuleManager.SetOrderInitGenesis(orderInitBlockers()...) - app.mm.RegisterInvariants(&app.CrisisKeeper) - app.mm.RegisterServices(cfg) + app.ModuleManager.RegisterInvariants(&app.CrisisKeeper) + app.ModuleManager.RegisterServices(cfg) // initialize stores app.MountKVStores(app.GetKVStoreKey()) app.MountTransientStores(app.GetTransientStoreKey()) @@ -388,12 +397,12 @@ func (app *App) Name() string { // BeginBlocker application updates every begin block func (app *App) BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock) abci.ResponseBeginBlock { - return app.mm.BeginBlock(ctx, req) + return app.ModuleManager.BeginBlock(ctx, req) } // EndBlocker application updates every end block func (app *App) EndBlocker(ctx sdk.Context, req abci.RequestEndBlock) abci.ResponseEndBlock { - return app.mm.EndBlock(ctx, req) + return app.ModuleManager.EndBlock(ctx, req) } // InitChainer application update at chain initialization @@ -402,8 +411,8 @@ func (app *App) InitChainer(ctx sdk.Context, req abci.RequestInitChain) abci.Res if err := tmjson.Unmarshal(req.AppStateBytes, &genesisState); err != nil { panic(err) } - app.UpgradeKeeper.SetModuleVersionMap(ctx, app.mm.GetVersionMap()) - return app.mm.InitGenesis(ctx, app.appCodec, genesisState) + app.UpgradeKeeper.SetModuleVersionMap(ctx, app.ModuleManager.GetVersionMap()) + return app.ModuleManager.InitGenesis(ctx, app.appCodec, genesisState) } // LoadHeight loads a particular height @@ -426,7 +435,7 @@ func (app *App) ModuleAccountAddrs() map[string]bool { // NOTE: This is solely to be used for testing purposes as it may be desirable // for modules to register their own custom testing types. func (app *App) LegacyAmino() *codec.LegacyAmino { - return app.cdc + return app.legacyAmino } // AppCodec returns Juno's app codec. @@ -511,7 +520,7 @@ func (app *App) setupUpgradeHandlers(cfg module.Configurator) { app.UpgradeKeeper.SetUpgradeHandler( upgrade.UpgradeName, upgrade.CreateUpgradeHandler( - app.mm, + app.ModuleManager, cfg, &app.AppKeepers, ), diff --git a/go.mod b/go.mod index 811bc1681..d1d9933e9 100644 --- a/go.mod +++ b/go.mod @@ -5,21 +5,16 @@ go 1.19 require ( cosmossdk.io/errors v1.0.0-beta.7 cosmossdk.io/math v1.0.0 - cosmossdk.io/simapp v0.0.0-20230224204036-a6adb0821462 - github.com/CosmWasm/wasmd v0.40.0-rc.1.0.20230422061626-b85abcf1d7b8 - github.com/CosmosContracts/juno/v15/osmoutils v0.0.0-00010101000000-000000000000 + github.com/CosmWasm/wasmd v0.31.0-rc0 github.com/cometbft/cometbft v0.37.0 github.com/cometbft/cometbft-db v0.7.0 - github.com/cosmos/cosmos-sdk v0.47.1 - github.com/cosmos/ibc-go/v7 v7.0.0 + github.com/cosmos/cosmos-sdk v0.46.12 github.com/golang/protobuf v1.5.3 github.com/gorilla/mux v1.8.0 github.com/grpc-ecosystem/grpc-gateway v1.16.0 github.com/prometheus/client_golang v1.15.0 github.com/spf13/cast v1.5.0 github.com/spf13/cobra v1.7.0 - github.com/strangelove-ventures/async-icq/v7 v7.0.0-20230413165143-a3b65ccdc897 - github.com/strangelove-ventures/packet-forward-middleware/v7 v7.0.0-20230412224111-136e94e98861 github.com/stretchr/testify v1.8.2 github.com/tendermint/tm-db v0.6.8-0.20220506192307-f628bb5dc95b google.golang.org/genproto v0.0.0-20230216225411-c8e22ba71e44 @@ -33,7 +28,6 @@ require ( cloud.google.com/go/compute/metadata v0.2.3 // indirect cloud.google.com/go/iam v0.12.0 // indirect cloud.google.com/go/storage v1.29.0 // indirect - cosmossdk.io/tools/rosetta v0.2.1 // indirect github.com/aws/aws-sdk-go v1.44.203 // indirect github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect github.com/chzyer/readline v1.5.1 // indirect @@ -67,7 +61,7 @@ require ( require ( cosmossdk.io/api v0.3.1 // indirect - cosmossdk.io/core v0.5.1 // indirect + cosmossdk.io/core v0.3.2 // indirect cosmossdk.io/depinject v1.0.0-alpha.3 // indirect filippo.io/edwards25519 v1.0.0 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect @@ -185,7 +179,7 @@ replace ( github.com/CosmosContracts/juno/v15/osmoutils => ./osmoutils - github.com/cosmos/cosmos-sdk => github.com/notional-labs/cosmos-sdk v0.47.2-0.20230424060617-ebc292e8de8b + // github.com/cosmos/cosmos-sdk => github.com/notional-labs/cosmos-sdk v0.47.2-0.20230424060617-ebc292e8de8b // dgrijalva/jwt-go is deprecated and doesn't receive security updates. // TODO: remove it: https://github.com/cosmos/cosmos-sdk/issues/13134 github.com/dgrijalva/jwt-go => github.com/golang-jwt/jwt/v4 v4.4.2 diff --git a/go.sum b/go.sum index be730060e..148148015 100644 --- a/go.sum +++ b/go.sum @@ -194,6 +194,8 @@ cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoIS collectd.org v0.3.0/go.mod h1:A/8DzQBkF6abtvrT2j/AU/4tiBgJWYyh0y/oB/4MlWE= cosmossdk.io/api v0.3.1 h1:NNiOclKRR0AOlO4KIqeaG6PS6kswOMhHD0ir0SscNXE= cosmossdk.io/api v0.3.1/go.mod h1:DfHfMkiNA2Uhy8fj0JJlOCYOBp4eWUUJ1te5zBGNyIw= +cosmossdk.io/core v0.3.2 h1:KlQIufpJHJvOs7YLGTZsZcCo1WlkencDXepsr8STKZQ= +cosmossdk.io/core v0.3.2/go.mod h1:CO7vbe+evrBvHc0setFHL/u7nlY7HJGzdRSBkT/sirc= cosmossdk.io/core v0.5.1 h1:vQVtFrIYOQJDV3f7rw4pjjVqc1id4+mE0L9hHP66pyI= cosmossdk.io/core v0.5.1/go.mod h1:KZtwHCLjcFuo0nmDc24Xy6CRNEL9Vl/MeimQ2aC7NLE= cosmossdk.io/depinject v1.0.0-alpha.3 h1:6evFIgj//Y3w09bqOUOzEpFj5tsxBqdc5CfkO7z+zfw= @@ -222,6 +224,7 @@ 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/wasmd v0.31.0-rc0/go.mod h1:K7PYeURGa725BFo8z2VEmch+MVWtkEMrSEw1v/vpG94= github.com/CosmWasm/wasmd v0.40.0-rc.1.0.20230422061626-b85abcf1d7b8 h1:daJIcrTcYkpDtn1DXqbGhnQkCPSD93El6mXfv15VJRA= github.com/CosmWasm/wasmd v0.40.0-rc.1.0.20230422061626-b85abcf1d7b8/go.mod h1:uacdue6EGn9JA1TqBNHB3iCe4PCIChuFT23AzIl2VME= github.com/CosmWasm/wasmvm v1.2.3 h1:OKYlobwmVGbl0eSn0mXoAAjE5hIuXnQCLPjbNd91sVY= @@ -382,6 +385,9 @@ github.com/cosmos/btcutil v1.0.5 h1:t+ZFcX77LpKtDBhjucvnOH8C2l2ioGsBNEQ3jef8xFk= github.com/cosmos/btcutil v1.0.5/go.mod h1:IyB7iuqZMJlthe2tkIFL33xPyzbFYP0XVdS8P5lUPis= github.com/cosmos/cosmos-proto v1.0.0-beta.2 h1:X3OKvWgK9Gsejo0F1qs5l8Qn6xJV/AzgIWR2wZ8Nua8= github.com/cosmos/cosmos-proto v1.0.0-beta.2/go.mod h1:+XRCLJ14pr5HFEHIUcn51IKXD1Fy3rkEQqt4WqmN4V0= +github.com/cosmos/cosmos-sdk v0.46.12/go.mod h1:bG4AkW9bqc8ycrryyKGQEl3YV9BY2wr6HggGq8kvcgM= +github.com/cosmos/cosmos-sdk v0.47.1 h1:HnaCYtaAMWZp1SdlwwE1mPJ8kFlZ/TuEJ/ciNXH6Uno= +github.com/cosmos/cosmos-sdk v0.47.1/go.mod h1:14tO5KQaTrl2q3OxBnDRfue7TRN9zkXS0cLutrSqkOo= 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= @@ -939,8 +945,6 @@ github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxzi 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/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/notional-labs/cosmos-sdk v0.47.2-0.20230424060617-ebc292e8de8b h1:ftj1UZ3/o5g/AkYq3WblQdAj3d9tYZNosRqnqvwu3lg= -github.com/notional-labs/cosmos-sdk v0.47.2-0.20230424060617-ebc292e8de8b/go.mod h1:IH/tRaPQEdWAbDuvtyNyPcfPz0DS/ESpmBRXOd5jCas= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= diff --git a/osmoutils/osmocli/tx_cmd_wrap.go b/osmoutils/osmocli/tx_cmd_wrap.go index 48725fe9e..32f7b2dcf 100644 --- a/osmoutils/osmocli/tx_cmd_wrap.go +++ b/osmoutils/osmocli/tx_cmd_wrap.go @@ -76,7 +76,10 @@ func (desc TxCliDesc) BuildCommandCustomFn() *cobra.Command { return err } - txf := tx.NewFactoryCLI(clientCtx, cmd.Flags()).WithTxConfig(clientCtx.TxConfig).WithAccountRetriever(clientCtx.AccountRetriever) + txf, err := tx.NewFactoryCLI(clientCtx, cmd.Flags()).WithTxConfig(clientCtx.TxConfig).WithAccountRetriever(clientCtx.AccountRetriever) + if err != nil { + return err + } msg, err := desc.ParseAndBuildMsg(clientCtx, args, cmd.Flags()) if err != nil { diff --git a/x/feeshare/keeper/keeper.go b/x/feeshare/keeper/keeper.go index 773cdc5f3..825e315f5 100644 --- a/x/feeshare/keeper/keeper.go +++ b/x/feeshare/keeper/keeper.go @@ -3,6 +3,7 @@ package keeper import ( "fmt" + errorsmod "cosmossdk.io/errors" "github.com/cometbft/cometbft/libs/log" "github.com/cosmos/cosmos-sdk/codec" storetypes "github.com/cosmos/cosmos-sdk/store/types" @@ -54,7 +55,7 @@ func NewKeeper( // SendCoinsFromAccountToFeeCollector transfers amt to the fee collector account. func (k Keeper) SendCoinsFromAccountToFeeCollector(ctx sdk.Context, senderAddr sdk.AccAddress, amt sdk.Coins) error { if senderAddr.Empty() { - return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "senderAddr address cannot be empty") + return errorsmod.Wrap(sdkerrors.ErrInvalidAddress, "senderAddr address cannot be empty") } return k.bankKeeper.SendCoinsFromAccountToModule(ctx, senderAddr, k.feeCollectorName, amt) } @@ -62,7 +63,7 @@ func (k Keeper) SendCoinsFromAccountToFeeCollector(ctx sdk.Context, senderAddr s // SendCoinsFromFeeCollectorToAccount transfers amt from the fee collector account to the recipient. func (k Keeper) SendCoinsFromFeeCollectorToAccount(ctx sdk.Context, recipientAddr sdk.AccAddress, amt sdk.Coins) error { if recipientAddr.Empty() { - return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "recipient address cannot be empty") + return errorsmod.Wrap(sdkerrors.ErrInvalidAddress, "recipient address cannot be empty") } return k.bankKeeper.SendCoinsFromModuleToAccount(ctx, k.feeCollectorName, recipientAddr, amt) } From a920127d15b1235da22cdb0465dfac9b068b4113 Mon Sep 17 00:00:00 2001 From: Jacob Gadikian Date: Thu, 27 Apr 2023 13:26:48 +0700 Subject: [PATCH 038/131] pre-merge changes --- app/app.go | 26 +++++------ app/keepers/keepers.go | 103 ++++++++++++++++++++++++++--------------- go.mod | 12 +++-- go.sum | 4 -- 4 files changed, 86 insertions(+), 59 deletions(-) diff --git a/app/app.go b/app/app.go index 0658f25eb..15a775e00 100644 --- a/app/app.go +++ b/app/app.go @@ -54,7 +54,6 @@ import ( "github.com/CosmosContracts/juno/v15/x/globalfee" "github.com/CosmosContracts/juno/v15/app/keepers" - encparams "github.com/CosmosContracts/juno/v15/app/params" upgrades "github.com/CosmosContracts/juno/v15/app/upgrades" v10 "github.com/CosmosContracts/juno/v15/app/upgrades/v10" v11 "github.com/CosmosContracts/juno/v15/app/upgrades/v11" @@ -215,23 +214,22 @@ func New( db dbm.DB, traceStore io.Writer, loadLatest bool, - skipUpgradeHeights map[int64]bool, - homePath string, - invCheckPeriod uint, - encodingConfig encparams.EncodingConfig, enabledProposals []wasm.ProposalType, appOpts servertypes.AppOptions, wasmOpts []wasm.Option, baseAppOptions ...func(*baseapp.BaseApp), ) *App { - appCodec := encodingConfig.Marshaler - cdc := encodingConfig.Amino + encodingConfig := MakeEncodingConfig() + + appCodec, legacyAmino := encodingConfig.Marshaler, encodingConfig.Amino interfaceRegistry := encodingConfig.InterfaceRegistry + txConfig := encodingConfig.TxConfig - bApp := baseapp.NewBaseApp(Name, logger, db, encodingConfig.TxConfig.TxDecoder(), baseAppOptions...) + bApp := baseapp.NewBaseApp(Name, logger, db, txConfig.TxDecoder(), baseAppOptions...) bApp.SetCommitMultiStoreTracer(traceStore) bApp.SetVersion(version.Version) bApp.SetInterfaceRegistry(interfaceRegistry) + bApp.SetTxEncoder(txConfig.TxEncoder()) app := &App{ BaseApp: bApp, @@ -239,21 +237,15 @@ func New( appCodec: appCodec, txConfig: txConfig, interfaceRegistry: interfaceRegistry, - keys: keys, - tkeys: tkeys, - memKeys: memKeys, } // Setup keepers app.AppKeepers = keepers.NewAppKeepers( appCodec, bApp, - cdc, + legacyAmino, maccPerms, app.ModuleAccountAddrs(), - skipUpgradeHeights, - homePath, - invCheckPeriod, enabledProposals, appOpts, wasmOpts, @@ -495,6 +487,10 @@ func (app *App) RegisterTendermintService(clientCtx client.Context) { ) } +func (app *App) RegisterNodeService(clientCtx client.Context) { + nodeservice.RegisterNodeService(clientCtx, app.GRPCQueryRouter()) +} + // configure store loader that checks if version == upgradeHeight and applies store upgrades func (app *App) setupUpgradeStoreLoaders() { upgradeInfo, err := app.UpgradeKeeper.ReadUpgradeInfoFromDisk() diff --git a/app/keepers/keepers.go b/app/keepers/keepers.go index e7e414a5a..c2f353840 100644 --- a/app/keepers/keepers.go +++ b/app/keepers/keepers.go @@ -14,6 +14,7 @@ import ( "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/codec" servertypes "github.com/cosmos/cosmos-sdk/server/types" + storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" @@ -22,6 +23,8 @@ import ( banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" capabilitykeeper "github.com/cosmos/cosmos-sdk/x/capability/keeper" capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" + consensusparamkeeper "github.com/cosmos/cosmos-sdk/x/consensus/keeper" + consensusparamtypes "github.com/cosmos/cosmos-sdk/x/consensus/types" crisiskeeper "github.com/cosmos/cosmos-sdk/x/crisis/keeper" crisistypes "github.com/cosmos/cosmos-sdk/x/crisis/types" distr "github.com/cosmos/cosmos-sdk/x/distribution" @@ -54,7 +57,7 @@ import ( ibcclienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" ibcconnectiontypes "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" porttypes "github.com/cosmos/ibc-go/v7/modules/core/05-port/types" - ibchost "github.com/cosmos/ibc-go/v7/modules/core/24-host" + ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" ibckeeper "github.com/cosmos/ibc-go/v7/modules/core/keeper" packetforward "github.com/strangelove-ventures/packet-forward-middleware/v7/router" @@ -96,33 +99,34 @@ var ( type AppKeepers struct { // keys to access the substores - keys map[string]*sdk.KVStoreKey - tkeys map[string]*sdk.TransientStoreKey - memKeys map[string]*sdk.MemoryStoreKey + keys map[string]*storetypes.KVStoreKey + tkeys map[string]*storetypes.TransientStoreKey + memKeys map[string]*storetypes.MemoryStoreKey // keepers - AccountKeeper authkeeper.AccountKeeper - BankKeeper bankkeeper.BaseKeeper - CapabilityKeeper *capabilitykeeper.Keeper - StakingKeeper stakingkeeper.Keeper - SlashingKeeper slashingkeeper.Keeper - MintKeeper mintkeeper.Keeper - DistrKeeper distrkeeper.Keeper - GovKeeper govkeeper.Keeper - CrisisKeeper crisiskeeper.Keeper - UpgradeKeeper upgradekeeper.Keeper - ParamsKeeper paramskeeper.Keeper - IBCKeeper *ibckeeper.Keeper // IBC Keeper must be a pointer in the app, so we can SetRouter on it correctly - ICQKeeper icqkeeper.Keeper - IBCFeeKeeper ibcfeekeeper.Keeper - IBCHooksKeeper *ibchookskeeper.Keeper - PacketForwardKeeper *packetforwardkeeper.Keeper - EvidenceKeeper evidencekeeper.Keeper - TransferKeeper ibctransferkeeper.Keeper - AuthzKeeper authzkeeper.Keeper - FeeGrantKeeper feegrantkeeper.Keeper - FeeShareKeeper feesharekeeper.Keeper - ContractKeeper *wasmkeeper.PermissionedKeeper + AccountKeeper authkeeper.AccountKeeper + BankKeeper bankkeeper.BaseKeeper + CapabilityKeeper *capabilitykeeper.Keeper + StakingKeeper *stakingkeeper.Keeper + SlashingKeeper slashingkeeper.Keeper + MintKeeper mintkeeper.Keeper + DistrKeeper distrkeeper.Keeper + GovKeeper govkeeper.Keeper + CrisisKeeper *crisiskeeper.Keeper + UpgradeKeeper upgradekeeper.Keeper + ParamsKeeper paramskeeper.Keeper + IBCKeeper *ibckeeper.Keeper // IBC Keeper must be a pointer in the app, so we can SetRouter on it correctly + ICQKeeper icqkeeper.Keeper + IBCFeeKeeper ibcfeekeeper.Keeper + IBCHooksKeeper *ibchookskeeper.Keeper + PacketForwardKeeper *packetforwardkeeper.Keeper + EvidenceKeeper evidencekeeper.Keeper + TransferKeeper ibctransferkeeper.Keeper + ConsensusParamsKeeper consensusparamkeeper.Keeper + AuthzKeeper authzkeeper.Keeper + FeeGrantKeeper feegrantkeeper.Keeper + FeeShareKeeper feesharekeeper.Keeper + ContractKeeper *wasmkeeper.PermissionedKeeper ICAControllerKeeper icacontrollerkeeper.Keeper ICAHostKeeper icahostkeeper.Keeper @@ -150,9 +154,6 @@ func NewAppKeepers( cdc *codec.LegacyAmino, maccPerms map[string][]string, blockedAddress map[string]bool, - skipUpgradeHeights map[int64]bool, - homePath string, - invCheckPeriod uint, enabledProposals []wasm.ProposalType, appOpts servertypes.AppOptions, wasmOpts []wasm.Option, @@ -170,7 +171,7 @@ func NewAppKeepers( ) // set the BaseApp's parameter store - bApp.SetParamStore(appKeepers.ParamsKeeper.Subspace(baseapp.Paramspace).WithKeyTable(paramskeeper.ConsensusParamsKeyTable())) + appKeepers.ConsensusParamsKeeper = consensusparamkeeper.NewKeeper(appCodec, keys[consensusparamtypes.StoreKey], authtypes.NewModuleAddress(govtypes.ModuleName).String()) // add capability keeper and ScopeToModule for ibc module appKeepers.CapabilityKeeper = capabilitykeeper.NewKeeper( @@ -180,7 +181,7 @@ func NewAppKeepers( ) // grant capabilities for the ibc and ibc-transfer modules - scopedIBCKeeper := appKeepers.CapabilityKeeper.ScopeToModule(ibchost.ModuleName) + scopedIBCKeeper := appKeepers.CapabilityKeeper.ScopeToModule(ibcexported.ModuleName) scopedICAControllerKeeper := appKeepers.CapabilityKeeper.ScopeToModule(icacontrollertypes.SubModuleName) scopedICAHostKeeper := appKeepers.CapabilityKeeper.ScopeToModule(icahosttypes.SubModuleName) scopedICQKeeper := appKeepers.CapabilityKeeper.ScopeToModule(icqtypes.ModuleName) @@ -188,20 +189,23 @@ func NewAppKeepers( scopedWasmKeeper := appKeepers.CapabilityKeeper.ScopeToModule(wasm.ModuleName) // add keepers - appKeepers.AccountKeeper = authkeeper.NewAccountKeeper( + app.AccountKeeper = authkeeper.NewAccountKeeper( appCodec, - appKeepers.keys[authtypes.StoreKey], - appKeepers.GetSubspace(authtypes.ModuleName), + keys[authtypes.StoreKey], authtypes.ProtoBaseAccount, maccPerms, + Bech32Prefix, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), ) + appKeepers.BankKeeper = bankkeeper.NewBaseKeeper( appCodec, - appKeepers.keys[banktypes.StoreKey], + keys[banktypes.StoreKey], appKeepers.AccountKeeper, - appKeepers.GetSubspace(banktypes.ModuleName), - blockedAddress, + BlockedAddresses(), + authtypes.NewModuleAddress(govtypes.ModuleName).String(), ) + stakingKeeper := stakingkeeper.NewKeeper( appCodec, appKeepers.keys[stakingtypes.StoreKey], @@ -567,3 +571,28 @@ func (appKeepers *AppKeepers) GetScopedIBCKeeper() capabilitykeeper.ScopedKeeper func (appKeepers *AppKeepers) GetWasmKeeper() wasm.Keeper { return appKeepers.WasmKeeper } + +// BlockedAddresses returns all the app's blocked account addresses. +func BlockedAddresses() map[string]bool { + modAccAddrs := make(map[string]bool) + for acc := range GetMaccPerms() { + modAccAddrs[authtypes.NewModuleAddress(acc).String()] = true + } + + // allow the following addresses to receive funds + delete(modAccAddrs, authtypes.NewModuleAddress(govtypes.ModuleName).String()) + + return modAccAddrs +} + +// GetMaccPerms returns a copy of the module account permissions +// +// NOTE: This is solely to be used for testing purposes. +func GetMaccPerms() map[string][]string { + dupMaccPerms := make(map[string][]string) + for k, v := range maccPerms { + dupMaccPerms[k] = v + } + + return dupMaccPerms +} diff --git a/go.mod b/go.mod index d1d9933e9..ba538da49 100644 --- a/go.mod +++ b/go.mod @@ -5,16 +5,21 @@ go 1.19 require ( cosmossdk.io/errors v1.0.0-beta.7 cosmossdk.io/math v1.0.0 - github.com/CosmWasm/wasmd v0.31.0-rc0 + cosmossdk.io/simapp v0.0.0-20230224204036-a6adb0821462 + github.com/CosmWasm/wasmd v0.40.0-rc.1.0.20230422061626-b85abcf1d7b8 + github.com/CosmosContracts/juno/v15/osmoutils v0.0.0-00010101000000-000000000000 github.com/cometbft/cometbft v0.37.0 github.com/cometbft/cometbft-db v0.7.0 - github.com/cosmos/cosmos-sdk v0.46.12 + github.com/cosmos/cosmos-sdk v0.47.1 + github.com/cosmos/ibc-go/v7 v7.0.0 github.com/golang/protobuf v1.5.3 github.com/gorilla/mux v1.8.0 github.com/grpc-ecosystem/grpc-gateway v1.16.0 github.com/prometheus/client_golang v1.15.0 github.com/spf13/cast v1.5.0 github.com/spf13/cobra v1.7.0 + github.com/strangelove-ventures/async-icq/v7 v7.0.0-20230413165143-a3b65ccdc897 + github.com/strangelove-ventures/packet-forward-middleware/v7 v7.0.0-20230412224111-136e94e98861 github.com/stretchr/testify v1.8.2 github.com/tendermint/tm-db v0.6.8-0.20220506192307-f628bb5dc95b google.golang.org/genproto v0.0.0-20230216225411-c8e22ba71e44 @@ -28,6 +33,7 @@ require ( cloud.google.com/go/compute/metadata v0.2.3 // indirect cloud.google.com/go/iam v0.12.0 // indirect cloud.google.com/go/storage v1.29.0 // indirect + cosmossdk.io/tools/rosetta v0.2.1 // indirect github.com/aws/aws-sdk-go v1.44.203 // indirect github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect github.com/chzyer/readline v1.5.1 // indirect @@ -61,7 +67,7 @@ require ( require ( cosmossdk.io/api v0.3.1 // indirect - cosmossdk.io/core v0.3.2 // indirect + cosmossdk.io/core v0.5.1 // indirect cosmossdk.io/depinject v1.0.0-alpha.3 // indirect filippo.io/edwards25519 v1.0.0 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect diff --git a/go.sum b/go.sum index 148148015..8f5a386e6 100644 --- a/go.sum +++ b/go.sum @@ -194,8 +194,6 @@ cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoIS collectd.org v0.3.0/go.mod h1:A/8DzQBkF6abtvrT2j/AU/4tiBgJWYyh0y/oB/4MlWE= cosmossdk.io/api v0.3.1 h1:NNiOclKRR0AOlO4KIqeaG6PS6kswOMhHD0ir0SscNXE= cosmossdk.io/api v0.3.1/go.mod h1:DfHfMkiNA2Uhy8fj0JJlOCYOBp4eWUUJ1te5zBGNyIw= -cosmossdk.io/core v0.3.2 h1:KlQIufpJHJvOs7YLGTZsZcCo1WlkencDXepsr8STKZQ= -cosmossdk.io/core v0.3.2/go.mod h1:CO7vbe+evrBvHc0setFHL/u7nlY7HJGzdRSBkT/sirc= cosmossdk.io/core v0.5.1 h1:vQVtFrIYOQJDV3f7rw4pjjVqc1id4+mE0L9hHP66pyI= cosmossdk.io/core v0.5.1/go.mod h1:KZtwHCLjcFuo0nmDc24Xy6CRNEL9Vl/MeimQ2aC7NLE= cosmossdk.io/depinject v1.0.0-alpha.3 h1:6evFIgj//Y3w09bqOUOzEpFj5tsxBqdc5CfkO7z+zfw= @@ -224,7 +222,6 @@ 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/wasmd v0.31.0-rc0/go.mod h1:K7PYeURGa725BFo8z2VEmch+MVWtkEMrSEw1v/vpG94= github.com/CosmWasm/wasmd v0.40.0-rc.1.0.20230422061626-b85abcf1d7b8 h1:daJIcrTcYkpDtn1DXqbGhnQkCPSD93El6mXfv15VJRA= github.com/CosmWasm/wasmd v0.40.0-rc.1.0.20230422061626-b85abcf1d7b8/go.mod h1:uacdue6EGn9JA1TqBNHB3iCe4PCIChuFT23AzIl2VME= github.com/CosmWasm/wasmvm v1.2.3 h1:OKYlobwmVGbl0eSn0mXoAAjE5hIuXnQCLPjbNd91sVY= @@ -385,7 +382,6 @@ github.com/cosmos/btcutil v1.0.5 h1:t+ZFcX77LpKtDBhjucvnOH8C2l2ioGsBNEQ3jef8xFk= github.com/cosmos/btcutil v1.0.5/go.mod h1:IyB7iuqZMJlthe2tkIFL33xPyzbFYP0XVdS8P5lUPis= github.com/cosmos/cosmos-proto v1.0.0-beta.2 h1:X3OKvWgK9Gsejo0F1qs5l8Qn6xJV/AzgIWR2wZ8Nua8= github.com/cosmos/cosmos-proto v1.0.0-beta.2/go.mod h1:+XRCLJ14pr5HFEHIUcn51IKXD1Fy3rkEQqt4WqmN4V0= -github.com/cosmos/cosmos-sdk v0.46.12/go.mod h1:bG4AkW9bqc8ycrryyKGQEl3YV9BY2wr6HggGq8kvcgM= github.com/cosmos/cosmos-sdk v0.47.1 h1:HnaCYtaAMWZp1SdlwwE1mPJ8kFlZ/TuEJ/ciNXH6Uno= github.com/cosmos/cosmos-sdk v0.47.1/go.mod h1:14tO5KQaTrl2q3OxBnDRfue7TRN9zkXS0cLutrSqkOo= github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d/go.mod h1:tSxLoYXyBmiFeKpvmq4dzayMdCjCnu8uqmCysIGBT2Y= From d80493c2ffcbaef62f2e42bfd93de767171d0115 Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Fri, 28 Apr 2023 15:12:03 -0500 Subject: [PATCH 039/131] Fix some test, fix root.go InterceptConfigsPreRunHandler --- app/apptesting/test_suite.go | 2 +- app/upgrades/v10/upgrades.go | 5 +- app/upgrades/v11/upgrades.go | 5 +- app/upgrades/v13/upgrades.go | 5 +- cmd/junod/cmd/config.go | 21 ++- cmd/junod/cmd/root.go | 24 ++- cmd/junod/cmd/server_configs.go | 195 --------------------- go.mod | 13 +- go.sum | 28 +-- osmoutils/accum/accum_test.go | 2 +- osmoutils/export_test.go | 2 +- osmoutils/go.mod | 11 +- osmoutils/noapptest/ctx.go | 4 +- osmoutils/store_helper.go | 4 +- scripts/statesync.bash | 2 +- x/tokenfactory/bindings/custom_msg_test.go | 4 +- x/tokenfactory/simulation/operations.go | 3 +- x/tokenfactory/testhelpers/suite.go | 2 +- 18 files changed, 70 insertions(+), 262 deletions(-) delete mode 100644 cmd/junod/cmd/server_configs.go diff --git a/app/apptesting/test_suite.go b/app/apptesting/test_suite.go index 02c005581..e09eb4e82 100644 --- a/app/apptesting/test_suite.go +++ b/app/apptesting/test_suite.go @@ -27,7 +27,7 @@ import ( stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" - dbm "github.com/tendermint/tm-db" + dbm "github.com/cometbft/cometbft-db" authzcodec "github.com/CosmosContracts/juno/v15/x/tokenfactory/types/authzcodec" diff --git a/app/upgrades/v10/upgrades.go b/app/upgrades/v10/upgrades.go index 2b30d6f35..5bcc1eb8a 100644 --- a/app/upgrades/v10/upgrades.go +++ b/app/upgrades/v10/upgrades.go @@ -8,7 +8,6 @@ import ( "github.com/cosmos/cosmos-sdk/x/authz" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" distrtypes "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" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" icahosttypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/host/types" @@ -39,8 +38,8 @@ func CreateV10UpgradeHandler( sdk.MsgTypeURL(&distrtypes.MsgSetWithdrawAddress{}), sdk.MsgTypeURL(&distrtypes.MsgWithdrawValidatorCommission{}), sdk.MsgTypeURL(&distrtypes.MsgFundCommunityPool{}), - sdk.MsgTypeURL(&govtypes.MsgVote{}), - sdk.MsgTypeURL(&govtypes.MsgVoteWeighted{}), // required by quick + // sdk.MsgTypeURL(&govtypes.MsgVote{}), + // sdk.MsgTypeURL(&govtypes.MsgVoteWeighted{}), // required by quick sdk.MsgTypeURL(&authz.MsgExec{}), sdk.MsgTypeURL(&authz.MsgGrant{}), sdk.MsgTypeURL(&authz.MsgRevoke{}), diff --git a/app/upgrades/v11/upgrades.go b/app/upgrades/v11/upgrades.go index 0e05d3cf4..a7af76895 100644 --- a/app/upgrades/v11/upgrades.go +++ b/app/upgrades/v11/upgrades.go @@ -8,7 +8,6 @@ import ( "github.com/cosmos/cosmos-sdk/x/authz" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" distrtypes "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" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" icahosttypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/host/types" @@ -40,8 +39,8 @@ func CreateV11UpgradeHandler( sdk.MsgTypeURL(&distrtypes.MsgSetWithdrawAddress{}), sdk.MsgTypeURL(&distrtypes.MsgWithdrawValidatorCommission{}), sdk.MsgTypeURL(&distrtypes.MsgFundCommunityPool{}), - sdk.MsgTypeURL(&govtypes.MsgVote{}), - sdk.MsgTypeURL(&govtypes.MsgVoteWeighted{}), // added in v10 + // sdk.MsgTypeURL(&govtypes.MsgVote{}), + // sdk.MsgTypeURL(&govtypes.MsgVoteWeighted{}), // added in v10 sdk.MsgTypeURL(&authz.MsgExec{}), sdk.MsgTypeURL(&authz.MsgGrant{}), sdk.MsgTypeURL(&authz.MsgRevoke{}), diff --git a/app/upgrades/v13/upgrades.go b/app/upgrades/v13/upgrades.go index dad40ebe3..36eddaf44 100644 --- a/app/upgrades/v13/upgrades.go +++ b/app/upgrades/v13/upgrades.go @@ -12,7 +12,6 @@ import ( // ICA icacontrollertypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/types" icahosttypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/host/types" - icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" // types feesharetypes "github.com/CosmosContracts/juno/v15/x/feeshare/types" @@ -37,7 +36,7 @@ func CreateV13UpgradeHandler( logger.Info(fmt.Sprintf("With native denom %s", nativeDenom)) // ICA - https://github.com/CosmosContracts/juno/blob/integrate_ica_changes/app/app.go#L846-L885 - vm[icatypes.ModuleName] = mm.Modules[icatypes.ModuleName].ConsensusVersion() + // vm[icatypes.ModuleName] = mm.Modules[icatypes.ModuleName].ConsensusVersion() logger.Info("upgraded icatypes version") // Update ICS27 Host submodule params @@ -48,7 +47,7 @@ func CreateV13UpgradeHandler( } // IBCFee - vm[ibcfeetypes.ModuleName] = mm.Modules[ibcfeetypes.ModuleName].ConsensusVersion() + // vm[ibcfeetypes.ModuleName] = mm.Modules[ibcfeetypes.ModuleName].ConsensusVersion() logger.Info(fmt.Sprintf("ibcfee module version %s set", fmt.Sprint(vm[ibcfeetypes.ModuleName]))) // Run migrations diff --git a/cmd/junod/cmd/config.go b/cmd/junod/cmd/config.go index b2eb0c151..fd1d51a80 100644 --- a/cmd/junod/cmd/config.go +++ b/cmd/junod/cmd/config.go @@ -25,7 +25,8 @@ type JunoCustomClient struct { GasAdjustment string `mapstructure:"gas-adjustment" json:"gas-adjustment"` Fees string `mapstructure:"fees" json:"fees"` - FeeAccount string `mapstructure:"fee-account" json:"fee-account"` + FeeGranter string `mapstructure:"fee-granter" json:"fee-granter"` + FeePayer string `mapstructure:"fee-payer" json:"fee-payer"` Note string `mapstructure:"note" json:"note"` } @@ -58,7 +59,8 @@ func runConfigCmd(cmd *cobra.Command, args []string) error { os.Getenv("JUNOD_GAS_ADJUSTMENT"), os.Getenv("JUNOD_FEES"), - os.Getenv("JUNOD_FEE_ACCOUNT"), + os.Getenv("JUNOD_FEE_GRANTER"), + os.Getenv("JUNOD_FEE_PAYER"), os.Getenv("JUNOD_NOTE"), } @@ -97,8 +99,10 @@ func runConfigCmd(cmd *cobra.Command, args []string) error { cmd.Println(jcc.GasAdjustment) case flags.FlagFees: cmd.Println(jcc.Fees) - case flags.FlagFeeAccount: - cmd.Println(jcc.FeeAccount) + case flags.FlagFeeGranter: + cmd.Println(jcc.FeeGranter) + case flags.FlagFeePayer: + cmd.Println(jcc.FeePayer) case flags.FlagNote: cmd.Println(jcc.Note) default: @@ -131,8 +135,10 @@ func runConfigCmd(cmd *cobra.Command, args []string) error { case flags.FlagFees: jcc.Fees = value jcc.GasPrices = "" // resets since we can only use 1 at a time - case flags.FlagFeeAccount: - jcc.FeeAccount = value + case flags.FlagFeeGranter: + jcc.FeeGranter = value + case flags.FlagFeePayer: + jcc.FeePayer = value case flags.FlagNote: jcc.Note = value default: @@ -181,7 +187,8 @@ gas-adjustment = "{{ .GasAdjustment }}" # Fees to use instead of set gas prices fees = "{{ .Fees }}" -fee-account = "{{ .FeeAccount }}" +fee-granter = "{{ .FeeGranter }}" +fee-payer = "{{ .FeePayer }}" # Memo to include in your Transactions note = "{{ .Note }}" diff --git a/cmd/junod/cmd/root.go b/cmd/junod/cmd/root.go index fcd38414d..84aecb354 100644 --- a/cmd/junod/cmd/root.go +++ b/cmd/junod/cmd/root.go @@ -7,6 +7,8 @@ import ( "path/filepath" "time" + tmcfg "github.com/cometbft/cometbft/config" + "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/client" serverconfig "github.com/cosmos/cosmos-sdk/server/config" @@ -60,7 +62,7 @@ func NewRootCmd() (*cobra.Command, params.EncodingConfig) { WithLegacyAmino(encodingConfig.Amino). WithInput(os.Stdin). WithAccountRetriever(authtypes.AccountRetriever{}). - WithBroadcastMode(flags.BroadcastBlock). + WithBroadcastMode(flags.FlagBroadcastMode). WithHomeDir(app.DefaultNodeHome). WithViper("") @@ -91,10 +93,10 @@ func NewRootCmd() (*cobra.Command, params.EncodingConfig) { } customAppTemplate, customAppConfig := initAppConfig() - // return server.InterceptConfigsPreRunHandler(cmd, customAppTemplate, customAppConfig) + customTMConfig := initTendermintConfig() + + return server.InterceptConfigsPreRunHandler(cmd, customAppTemplate, customAppConfig, customTMConfig) - timeoutCommit := 3 * time.Second - return InterceptConfigsPreRunHandler(cmd, customAppTemplate, customAppConfig, timeoutCommit) }, } @@ -103,6 +105,20 @@ func NewRootCmd() (*cobra.Command, params.EncodingConfig) { return rootCmd, encodingConfig } +// initTendermintConfig helps to override default Tendermint Config values. +// return tmcfg.DefaultConfig if no custom configuration is required for the application. +func initTendermintConfig() *tmcfg.Config { + cfg := tmcfg.DefaultConfig() + + // these values put a higher strain on node memory + // cfg.P2P.MaxNumInboundPeers = 100 + // cfg.P2P.MaxNumOutboundPeers = 40 + + cfg.Consensus.TimeoutCommit = 3 * time.Second + + return cfg +} + // initAppConfig helps to override default appConfig template and configs. // return "", nil if no custom configuration is required for the application. func initAppConfig() (string, interface{}) { diff --git a/cmd/junod/cmd/server_configs.go b/cmd/junod/cmd/server_configs.go deleted file mode 100644 index 200935be7..000000000 --- a/cmd/junod/cmd/server_configs.go +++ /dev/null @@ -1,195 +0,0 @@ -package cmd - -import ( - "fmt" - "io" - "os" - "path" - "path/filepath" - "strings" - "time" - - tmcfg "github.com/cometbft/cometbft/config" - "github.com/rs/zerolog" - "github.com/spf13/cobra" - "github.com/spf13/pflag" - "github.com/spf13/viper" - - "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/server/config" - - server "github.com/cosmos/cosmos-sdk/server" -) - -// InterceptConfigsPreRunHandler performs a pre-run function for the root daemon -// application command. It will create a Viper literal and a default server -// Context. The server Tendermint configuration will either be read and parsed -// or created and saved to disk, where the server Context is updated to reflect -// the Tendermint configuration. It takes custom app config template and config -// settings to create a custom Tendermint configuration. If the custom template -// is empty, it uses default-template provided by the server. The Viper literal -// is used to read and parse the application configuration. Command handlers can -// fetch the server Context to get the Tendermint configuration or to get access -// to Viper. -func InterceptConfigsPreRunHandler(cmd *cobra.Command, customAppConfigTemplate string, customAppConfig interface{}, blockTimeout time.Duration) error { - serverCtx := server.NewDefaultContext() - - // Get the executable name and configure the viper instance so that environmental - // variables are checked based off that name. The underscore character is used - // as a separator - executableName, err := os.Executable() - if err != nil { - return err - } - - basename := path.Base(executableName) - - // Configure the viper instance - serverCtx.Viper.BindPFlags(cmd.Flags()) // nolint: errcheck - serverCtx.Viper.BindPFlags(cmd.PersistentFlags()) // nolint: errcheck - serverCtx.Viper.SetEnvPrefix(basename) - serverCtx.Viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_", "-", "_")) - serverCtx.Viper.AutomaticEnv() - - // intercept configuration files, using both Viper instances separately - config, err := interceptConfigs(serverCtx.Viper, customAppConfigTemplate, customAppConfig) - if err != nil { - return err - } - - // !IMPORTANT: This is the only modified part of the original functions from the SDK - config.Consensus.TimeoutCommit = blockTimeout - - // return value is a tendermint configuration object - serverCtx.Config = config - if err = bindFlags(basename, cmd, serverCtx.Viper); err != nil { - return err - } - - var logWriter io.Writer - if strings.ToLower(serverCtx.Viper.GetString(flags.FlagLogFormat)) == tmcfg.LogFormatPlain { - logWriter = zerolog.ConsoleWriter{Out: os.Stderr} - } else { - logWriter = os.Stderr - } - - logLvlStr := serverCtx.Viper.GetString(flags.FlagLogLevel) - logLvl, err := zerolog.ParseLevel(logLvlStr) - if err != nil { - return fmt.Errorf("failed to parse log level (%s): %w", logLvlStr, err) - } - - serverCtx.Logger = server.ZeroLogWrapper{Logger: zerolog.New(logWriter).Level(logLvl).With().Timestamp().Logger()} - - return server.SetCmdServerContext(cmd, serverCtx) -} - -// interceptConfigs parses and updates a Tendermint configuration file or -// creates a new one and saves it. It also parses and saves the application -// configuration file. The Tendermint configuration file is parsed given a root -// Viper object, whereas the application is parsed with the private package-aware -// viperCfg object. -func interceptConfigs(rootViper *viper.Viper, customAppTemplate string, customConfig interface{}) (*tmcfg.Config, error) { - rootDir := rootViper.GetString(flags.FlagHome) - configPath := filepath.Join(rootDir, "config") - tmCfgFile := filepath.Join(configPath, "config.toml") - - conf := tmcfg.DefaultConfig() - - switch _, err := os.Stat(tmCfgFile); { - case os.IsNotExist(err): - tmcfg.EnsureRoot(rootDir) - - if err = conf.ValidateBasic(); err != nil { - return nil, fmt.Errorf("error in config file: %v", err) - } - - conf.RPC.PprofListenAddress = "localhost:6060" - conf.P2P.RecvRate = 5120000 - conf.P2P.SendRate = 5120000 - conf.Consensus.TimeoutCommit = 5 * time.Second - tmcfg.WriteConfigFile(tmCfgFile, conf) - - case err != nil: - return nil, err - - default: - rootViper.SetConfigType("toml") - rootViper.SetConfigName("config") - rootViper.AddConfigPath(configPath) - - if err := rootViper.ReadInConfig(); err != nil { - return nil, fmt.Errorf("failed to read in %s: %w", tmCfgFile, err) - } - } - - // Read into the configuration whatever data the viper instance has for it. - // This may come from the configuration file above but also any of the other - // sources viper uses. - if err := rootViper.Unmarshal(conf); err != nil { - return nil, err - } - - conf.SetRoot(rootDir) - - appCfgFilePath := filepath.Join(configPath, "app.toml") - if _, err := os.Stat(appCfgFilePath); os.IsNotExist(err) { - if customAppTemplate != "" { - config.SetConfigTemplate(customAppTemplate) - - if err = rootViper.Unmarshal(&customConfig); err != nil { - return nil, fmt.Errorf("failed to parse %s: %w", appCfgFilePath, err) - } - - config.WriteConfigFile(appCfgFilePath, customConfig) - } else { - appConf, err := config.ParseConfig(rootViper) - if err != nil { - return nil, fmt.Errorf("failed to parse %s: %w", appCfgFilePath, err) - } - - config.WriteConfigFile(appCfgFilePath, appConf) - } - } - - rootViper.SetConfigType("toml") - rootViper.SetConfigName("app") - rootViper.AddConfigPath(configPath) - - if err := rootViper.MergeInConfig(); err != nil { - return nil, fmt.Errorf("failed to merge configuration: %w", err) - } - - return conf, nil -} - -func bindFlags(basename string, cmd *cobra.Command, v *viper.Viper) (err error) { - defer func() { - recover() // nolint: errcheck - }() - - cmd.Flags().VisitAll(func(f *pflag.Flag) { - // Environment variables can't have dashes in them, so bind them to their equivalent - // keys with underscores, e.g. --favorite-color to STING_FAVORITE_COLOR - err = v.BindEnv(f.Name, fmt.Sprintf("%s_%s", basename, strings.ToUpper(strings.ReplaceAll(f.Name, "-", "_")))) - if err != nil { - panic(err) - } - - err = v.BindPFlag(f.Name, f) - if err != nil { - panic(err) - } - - // Apply the viper config value to the flag when the flag is not set and viper has a value - if !f.Changed && v.IsSet(f.Name) { - val := v.Get(f.Name) - err = cmd.Flags().Set(f.Name, fmt.Sprintf("%v", val)) - if err != nil { - panic(err) - } - } - }) - - return -} diff --git a/go.mod b/go.mod index ba538da49..3da113770 100644 --- a/go.mod +++ b/go.mod @@ -8,9 +8,9 @@ require ( cosmossdk.io/simapp v0.0.0-20230224204036-a6adb0821462 github.com/CosmWasm/wasmd v0.40.0-rc.1.0.20230422061626-b85abcf1d7b8 github.com/CosmosContracts/juno/v15/osmoutils v0.0.0-00010101000000-000000000000 - github.com/cometbft/cometbft v0.37.0 - github.com/cometbft/cometbft-db v0.7.0 - github.com/cosmos/cosmos-sdk v0.47.1 + github.com/cometbft/cometbft v0.37.1 + github.com/cometbft/cometbft-db v0.8.0 + github.com/cosmos/cosmos-sdk v0.47.2 github.com/cosmos/ibc-go/v7 v7.0.0 github.com/golang/protobuf v1.5.3 github.com/gorilla/mux v1.8.0 @@ -21,7 +21,7 @@ require ( github.com/strangelove-ventures/async-icq/v7 v7.0.0-20230413165143-a3b65ccdc897 github.com/strangelove-ventures/packet-forward-middleware/v7 v7.0.0-20230412224111-136e94e98861 github.com/stretchr/testify v1.8.2 - github.com/tendermint/tm-db v0.6.8-0.20220506192307-f628bb5dc95b + // github.com/tendermint/tm-db v0.6.8-0.20220506192307-f628bb5dc95b google.golang.org/genproto v0.0.0-20230216225411-c8e22ba71e44 google.golang.org/grpc v1.54.0 gopkg.in/yaml.v2 v2.4.0 @@ -53,6 +53,7 @@ require ( github.com/hashicorp/go-version v1.6.0 // indirect github.com/huandu/skiplist v1.2.0 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect + github.com/linxGnu/grocksdb v1.7.16 // indirect github.com/manifoldco/promptui v0.9.0 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/go-testing-interface v1.14.1 // indirect @@ -87,7 +88,6 @@ require ( github.com/cosmos/cosmos-proto v1.0.0-beta.2 github.com/cosmos/go-bip39 v1.0.0 // indirect github.com/cosmos/gogoproto v1.4.8 - github.com/cosmos/gorocksdb v1.2.0 // indirect github.com/cosmos/iavl v0.20.0 // indirect github.com/cosmos/ledger-cosmos-go v0.12.2 // indirect github.com/creachadair/taskgroup v0.4.2 // indirect @@ -96,7 +96,6 @@ require ( github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect github.com/dgraph-io/badger/v2 v2.2007.4 // indirect - github.com/dgraph-io/badger/v3 v3.2103.2 // indirect github.com/dgraph-io/ristretto v0.1.1 // indirect github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect github.com/docker/distribution v2.8.1+incompatible // indirect @@ -112,7 +111,6 @@ require ( github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/snappy v0.0.4 // indirect github.com/google/btree v1.1.2 // indirect - github.com/google/flatbuffers v1.12.1 // indirect github.com/google/go-cmp v0.5.9 // indirect github.com/google/gofuzz v1.2.0 // indirect github.com/google/orderedcode v0.0.1 // indirect @@ -160,7 +158,6 @@ require ( github.com/spf13/viper v1.15.0 github.com/subosito/gotenv v1.4.2 // indirect github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d - github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c // indirect github.com/tendermint/go-amino v0.16.0 // indirect github.com/tidwall/btree v1.6.0 // indirect github.com/zondax/hid v0.9.1 // indirect diff --git a/go.sum b/go.sum index 8f5a386e6..0f4a2145e 100644 --- a/go.sum +++ b/go.sum @@ -361,10 +361,10 @@ github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE 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/cometbft/cometbft v0.37.0 h1:M005vBaSaugvYYmNZwJOopynQSjwLoDTwflnQ/I/eYk= -github.com/cometbft/cometbft v0.37.0/go.mod h1:Y2MMMN//O5K4YKd8ze4r9jmk4Y7h0ajqILXbH5JQFVs= -github.com/cometbft/cometbft-db v0.7.0 h1:uBjbrBx4QzU0zOEnU8KxoDl18dMNgDh+zZRUE0ucsbo= -github.com/cometbft/cometbft-db v0.7.0/go.mod h1:yiKJIm2WKrt6x8Cyxtq9YTEcIMPcEe4XPxhgX59Fzf0= +github.com/cometbft/cometbft v0.37.1 h1:KLxkQTK2hICXYq21U2hn1W5hOVYUdQgDQ1uB+90xPIg= +github.com/cometbft/cometbft v0.37.1/go.mod h1:Y2MMMN//O5K4YKd8ze4r9jmk4Y7h0ajqILXbH5JQFVs= +github.com/cometbft/cometbft-db v0.8.0 h1:vUMDaH3ApkX8m0KZvOFFy9b5DZHBAjsnEuo9AKVZpjo= +github.com/cometbft/cometbft-db v0.8.0/go.mod h1:6ASCP4pfhmrCBpfk01/9E1SI29nD3HfVHrY4PG8x5c0= github.com/confio/ics23/go v0.9.0 h1:cWs+wdbS2KRPZezoaaj+qBleXgUk5WOQFMP3CQFGTr4= github.com/confio/ics23/go v0.9.0/go.mod h1:4LPZ2NYqnYIVRklaozjNR1FScgDJ2s5Xrp+e/mYVRak= github.com/consensys/bavard v0.1.8-0.20210406032232-f3452dc9b572/go.mod h1:Bpd0/3mZuaj6Sj+PqrmIquiOKy397AKGThQPaGzNXAQ= @@ -382,8 +382,8 @@ github.com/cosmos/btcutil v1.0.5 h1:t+ZFcX77LpKtDBhjucvnOH8C2l2ioGsBNEQ3jef8xFk= github.com/cosmos/btcutil v1.0.5/go.mod h1:IyB7iuqZMJlthe2tkIFL33xPyzbFYP0XVdS8P5lUPis= github.com/cosmos/cosmos-proto v1.0.0-beta.2 h1:X3OKvWgK9Gsejo0F1qs5l8Qn6xJV/AzgIWR2wZ8Nua8= github.com/cosmos/cosmos-proto v1.0.0-beta.2/go.mod h1:+XRCLJ14pr5HFEHIUcn51IKXD1Fy3rkEQqt4WqmN4V0= -github.com/cosmos/cosmos-sdk v0.47.1 h1:HnaCYtaAMWZp1SdlwwE1mPJ8kFlZ/TuEJ/ciNXH6Uno= -github.com/cosmos/cosmos-sdk v0.47.1/go.mod h1:14tO5KQaTrl2q3OxBnDRfue7TRN9zkXS0cLutrSqkOo= +github.com/cosmos/cosmos-sdk v0.47.2 h1:9rSriCoiJD+4F+tEDobyM8V7HF5BtY5Ef4VYNig96s0= +github.com/cosmos/cosmos-sdk v0.47.2/go.mod h1:zYzgI8w8hhotXTSoGbbSOAKfpJTx4wOy4XgbaKhtRtc= 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= @@ -392,8 +392,6 @@ github.com/cosmos/gogogateway v1.2.0/go.mod h1:iQpLkGWxYcnCdz5iAdLcRBSw3h7NXeOkZ github.com/cosmos/gogoproto v1.4.2/go.mod h1:cLxOsn1ljAHSV527CHOtaIP91kK6cCrZETRBrkzItWU= github.com/cosmos/gogoproto v1.4.8 h1:BrHKc6WFZt8+jRV71vKSQE+JrfF+JAnzrKo2VP7wIZ4= github.com/cosmos/gogoproto v1.4.8/go.mod h1:hnb0DIEWTv+wdNzNcqus5xCQXq5+CXauq1FJuurRfVY= -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.20.0 h1:fTVznVlepH0KK8NyKq8w+U7c2L6jofa27aFX6YGlm38= github.com/cosmos/iavl v0.20.0/go.mod h1:WO7FyvaZJoH65+HFOsDir7xU9FWk2w9cHXNW1XHcl7A= github.com/cosmos/ibc-go/v7 v7.0.0 h1:j4kyywlG0hhDmT9FmSaR5iCIka7Pz7kJTxGWY1nlV9Q= @@ -436,11 +434,8 @@ github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f h1:U5y3Y5UE0w7amNe github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f/go.mod h1:xH/i4TFMt8koVQZ6WFms69WAsDWr2XsYL3Hkl7jkoLE= 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/badger/v3 v3.2103.2 h1:dpyM5eCJAtQCBcMCZcT4UBZchuTJgCywerHHgmxfxM8= -github.com/dgraph-io/badger/v3 v3.2103.2/go.mod h1:RHo4/GmYcKKh5Lxu63wLEMHJ70Pac2JqZRYGhlyAo2M= github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= github.com/dgraph-io/ristretto v0.0.3/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= -github.com/dgraph-io/ristretto v0.1.0/go.mod h1:fux0lOrBhrVCJd3lcTHsIJhq1T2rokOu6v9Vcb3Q9ug= github.com/dgraph-io/ristretto v0.1.1 h1:6CWw5tJNgpegArSHpNHJKldNeq03FQCwYvfMVWajOK8= github.com/dgraph-io/ristretto v0.1.1/go.mod h1:S1GPSBCYCIhmVNfcth17y2zZtQT6wzkzgwUve0VDWWA= github.com/dgryski/go-bitstream v0.0.0-20180413035011-3522498ce2c8/go.mod h1:VMaSuZ+SZcx/wljOQKvp5srsbCiKDEb6K2wC4+PiBmQ= @@ -481,9 +476,6 @@ github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go. github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/ethereum/go-ethereum v1.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.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= @@ -615,8 +607,6 @@ github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ 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/flatbuffers v1.12.1 h1:MVlul7pQNoDzWRLTw5imwYsl+usrS1TXG2H4jg6ImGw= -github.com/google/flatbuffers v1.12.1/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= @@ -857,6 +847,8 @@ github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6 github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= +github.com/linxGnu/grocksdb v1.7.16 h1:Q2co1xrpdkr5Hx3Fp+f+f7fRGhQFQhvi/+226dtLmA8= +github.com/linxGnu/grocksdb v1.7.16/go.mod h1:JkS7pl5qWpGpuVb3bPqTz8nC12X3YtPZT+Xq7+QfQo4= github.com/lucasjones/reggen v0.0.0-20180717132126-cdb49ff09d77/go.mod h1:5ELEyG+X8f+meRWHuqUOewBOhvHkl7M76pdGEansxW4= github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= @@ -1133,12 +1125,8 @@ github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8 github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= github.com/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/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c h1:g+WoO5jjkqGAzHWCjJB1zZfXPIAaDpzXIEJ0eS6B5Ok= -github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c/go.mod h1:ahpPrc7HpcfEWDQRZEmnXMzHY03mLDYMCxeDzy46i+8= 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/tm-db v0.6.8-0.20220506192307-f628bb5dc95b h1:Y3ZPG6gdDCAV2sdGkD759ji/09GzaNu1X3qKTmZIbTo= -github.com/tendermint/tm-db v0.6.8-0.20220506192307-f628bb5dc95b/go.mod h1:ADqbS9NOSnBRK9R2RtYC61CdsHmVMD/yXAzcMuPexbU= github.com/tidwall/btree v1.6.0 h1:LDZfKfQIBHGHWSwckhXI0RPSXzlo+KYdjK7FWSqOzzg= github.com/tidwall/btree v1.6.0/go.mod h1:twD9XRA5jj9VUQGELzDO4HPQTNJsoWWfYEL+EUQ2cKY= github.com/tidwall/gjson v1.12.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= diff --git a/osmoutils/accum/accum_test.go b/osmoutils/accum/accum_test.go index d771221be..5fe038bca 100644 --- a/osmoutils/accum/accum_test.go +++ b/osmoutils/accum/accum_test.go @@ -4,13 +4,13 @@ import ( "math/rand" "testing" + dbm "github.com/cometbft/cometbft-db" "github.com/cosmos/cosmos-sdk/store" iavlstore "github.com/cosmos/cosmos-sdk/store/iavl" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/iavl" "github.com/gogo/protobuf/proto" "github.com/stretchr/testify/suite" - dbm "github.com/tendermint/tm-db" "github.com/CosmosContracts/juno/v15/osmoutils" accumPackage "github.com/CosmosContracts/juno/v15/osmoutils/accum" diff --git a/osmoutils/export_test.go b/osmoutils/export_test.go index 3ae6a32c2..f6cfd341a 100644 --- a/osmoutils/export_test.go +++ b/osmoutils/export_test.go @@ -1,6 +1,6 @@ package osmoutils -import db "github.com/tendermint/tm-db" +import db "github.com/cometbft/cometbft-db" func GatherValuesFromIterator[T any](iterator db.Iterator, parseValue func([]byte) (T, error), stopFn func([]byte) bool) ([]T, error) { return gatherValuesFromIterator(iterator, parseValue, stopFn) diff --git a/osmoutils/go.mod b/osmoutils/go.mod index 6870dc93e..718b58aad 100644 --- a/osmoutils/go.mod +++ b/osmoutils/go.mod @@ -3,15 +3,15 @@ module github.com/osmosis-labs/osmosis/osmoutils go 1.20 require ( - github.com/cosmos/cosmos-sdk v0.47.1 + github.com/cosmos/cosmos-sdk v0.47.2 github.com/cosmos/iavl v0.19.5 github.com/cosmos/ibc-go/v4 v4.3.0 github.com/gogo/protobuf v1.3.3 github.com/spf13/cobra v1.7.0 github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.8.2 - github.com/tendermint/tendermint v0.34.26 - github.com/tendermint/tm-db v0.6.8-0.20220506192307-f628bb5dc95b + github.com/cometbft/cometbft v0.37.1 + github.com/cometbft/cometbft-db v0.8.0 golang.org/x/exp v0.0.0-20230131160201-f062dba9d201 ) @@ -135,11 +135,8 @@ require ( ) replace ( - // Our cosmos-sdk branch is: https://github.com/osmosis-labs/cosmos-sdk, current branch: v16.x. Direct commit link: https://github.com/osmosis-labs/cosmos-sdk/commit/43c58d9061e3b8e0f06c3d9efef8c728800ab554 - github.com/cosmos/cosmos-sdk => github.com/osmosis-labs/cosmos-sdk v0.45.1-0.20230326212251-7a2cf2993434 // use cosmos-compatible protobufs - github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 - github.com/tendermint/tendermint => github.com/informalsystems/tendermint v0.34.24 + github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 // use grpc compatible with cosmos protobufs google.golang.org/grpc => google.golang.org/grpc v1.33.2 ) diff --git a/osmoutils/noapptest/ctx.go b/osmoutils/noapptest/ctx.go index 2dfe2f36e..06243f20a 100644 --- a/osmoutils/noapptest/ctx.go +++ b/osmoutils/noapptest/ctx.go @@ -8,10 +8,10 @@ import ( "github.com/cosmos/cosmos-sdk/store" sdk "github.com/cosmos/cosmos-sdk/types" - dbm "github.com/tendermint/tm-db" + dbm "github.com/cometbft/cometbft-db" ) -func CtxWithStoreKeys(keys []sdk.StoreKey, header tmproto.Header, isCheckTx bool) sdk.Context { +func CtxWithStoreKeys(keys []sdk.Store, header tmproto.Header, isCheckTx bool) sdk.Context { db := dbm.NewMemDB() logger := log.NewNopLogger() cms := store.NewCommitMultiStore(db, logger) diff --git a/osmoutils/store_helper.go b/osmoutils/store_helper.go index 232815179..2205afa6a 100644 --- a/osmoutils/store_helper.go +++ b/osmoutils/store_helper.go @@ -4,8 +4,8 @@ import ( "errors" "fmt" + db "github.com/cometbft/cometbft-db" sdk "github.com/cosmos/cosmos-sdk/types" - db "github.com/tendermint/tm-db" "github.com/cosmos/cosmos-sdk/store" "github.com/gogo/protobuf/proto" @@ -85,7 +85,7 @@ func GetIterValuesWithStop[T any]( // HasAnyAtPrefix returns true if there is at least one value in the given prefix. func HasAnyAtPrefix[T any](storeObj store.KVStore, prefix []byte, parseValue func([]byte) (T, error)) (bool, error) { - _, err := GetFirstValueInRange(storeObj, prefix, sdk.PrefixEndBytes(prefix),false, parseValue) + _, err := GetFirstValueInRange(storeObj, prefix, sdk.PrefixEndBytes(prefix), false, parseValue) if err != nil { if err == ErrNoValuesInRange { return false, nil diff --git a/scripts/statesync.bash b/scripts/statesync.bash index 4c2996d00..09315f7d8 100644 --- a/scripts/statesync.bash +++ b/scripts/statesync.bash @@ -8,7 +8,7 @@ export GOPATH=~/go export PATH=$PATH:~/go/bin # Install Juno with pebbledb -go mod edit -replace github.com/tendermint/tm-db=github.com/notional-labs/tm-db@136c7b6 +# go mod edit -replace github.com/tendermint/tm-db=github.com/notional-labs/tm-db@136c7b6 go mod tidy go install -ldflags '-w -s -X github.com/cosmos/cosmos-sdk/types.DBBackend=pebbledb' -tags pebbledb ./... diff --git a/x/tokenfactory/bindings/custom_msg_test.go b/x/tokenfactory/bindings/custom_msg_test.go index afcf0a646..7535389e0 100644 --- a/x/tokenfactory/bindings/custom_msg_test.go +++ b/x/tokenfactory/bindings/custom_msg_test.go @@ -302,7 +302,7 @@ type ReflectSubMsgs struct { Msgs []wasmvmtypes.SubMsg `json:"msgs"` } -func executeCustom(t *testing.T, ctx sdk.Context, osmosis *app.TokenApp, contract sdk.AccAddress, sender sdk.AccAddress, msg bindings.TokenMsg, funds sdk.Coin) error { +func executeCustom(t *testing.T, ctx sdk.Context, junoapp *app.App, contract sdk.AccAddress, sender sdk.AccAddress, msg bindings.TokenMsg, funds sdk.Coin) error { wrapped := bindings.TokenFactoryMsg{ Token: &msg, } @@ -325,7 +325,7 @@ func executeCustom(t *testing.T, ctx sdk.Context, osmosis *app.TokenApp, contrac coins = sdk.Coins{funds} } - contractKeeper := keeper.NewDefaultPermissionKeeper(osmosis.WasmKeeper) + contractKeeper := keeper.NewDefaultPermissionKeeper(junoapp.ModuleManager) _, err = contractKeeper.Execute(ctx, contract, sender, reflectBz, coins) return err } diff --git a/x/tokenfactory/simulation/operations.go b/x/tokenfactory/simulation/operations.go index 74244cf67..cb9c35f51 100644 --- a/x/tokenfactory/simulation/operations.go +++ b/x/tokenfactory/simulation/operations.go @@ -3,6 +3,7 @@ package simulation import ( "math/rand" + simappparams "cosmossdk.io/simapp/params" "github.com/CosmosContracts/juno/v15/app/params" "github.com/CosmosContracts/juno/v15/x/tokenfactory/types" "github.com/cosmos/cosmos-sdk/baseapp" @@ -363,7 +364,7 @@ func SimulateMsgCreateDenom(tfKeeper TokenfactoryKeeper, ak types.AccountKeeper, // Check if sims account enough create fee createFee := tfKeeper.GetParams(ctx).DenomCreationFee balances := bk.GetAllBalances(ctx, simAccount.Address) - _, hasNeg := balances.SafeSub(createFee) + _, hasNeg := balances.SafeSub(createFee[0]) if hasNeg { return simtypes.NoOpMsg(types.ModuleName, types.MsgCreateDenom{}.Type(), "Creator not enough creation fee"), nil, nil } diff --git a/x/tokenfactory/testhelpers/suite.go b/x/tokenfactory/testhelpers/suite.go index 7df45ad15..b509a524d 100644 --- a/x/tokenfactory/testhelpers/suite.go +++ b/x/tokenfactory/testhelpers/suite.go @@ -41,7 +41,7 @@ func TestMessageAuthzSerialization(t *testing.T, msg sdk.Msg) { // Authz: Grant Msg typeURL := sdk.MsgTypeURL(msg) later := someDate.Add(time.Hour) - grant, err := authz.NewGrant(authz.NewGenericAuthorization(typeURL), later) + grant, err := authz.NewGrant(someDate, authz.NewGenericAuthorization(typeURL), &later) require.NoError(t, err) msgGrant := authz.MsgGrant{Granter: mockGranter, Grantee: mockGrantee, Grant: grant} From ed18a69d122d0966c2ead713a9c0aae32e2f13f9 Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Fri, 28 Apr 2023 15:15:57 -0500 Subject: [PATCH 040/131] Fix icagenesistypes --- cmd/junod/cmd/genica.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/cmd/junod/cmd/genica.go b/cmd/junod/cmd/genica.go index 84c58cf7a..fe6022061 100644 --- a/cmd/junod/cmd/genica.go +++ b/cmd/junod/cmd/genica.go @@ -7,6 +7,7 @@ import ( "github.com/spf13/cobra" icacontrollertypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/types" + icagenesistypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/genesis/types" icahosttypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/host/types" icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" @@ -37,18 +38,18 @@ func AddGenesisIcaCmd(defaultNodeHome string) *cobra.Command { return fmt.Errorf("failed to unmarshal genesis state: %w", err) } - controllerGenesisState := icatypes.DefaultControllerGenesis() + controllerGenesisState := icagenesistypes.DefaultControllerGenesis() // no params set in upgrade handler, no params set here controllerGenesisState.Params = icacontrollertypes.Params{} - hostGenesisState := icatypes.DefaultHostGenesis() + hostGenesisState := icagenesistypes.DefaultHostGenesis() // add the messages we want (from old upgrade handler) hostGenesisState.Params = icahosttypes.Params{ HostEnabled: true, AllowMessages: []string{"*"}, } - newIcaGenState := icatypes.NewGenesisState(controllerGenesisState, hostGenesisState) + newIcaGenState := icagenesistypes.NewGenesisState(controllerGenesisState, hostGenesisState) icaGenStateBz, err := clientCtx.Codec.MarshalJSON(newIcaGenState) if err != nil { From 62d5df514c0559d77de281ec02ac3471afdb8852 Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Fri, 28 Apr 2023 15:38:42 -0500 Subject: [PATCH 041/131] Fix root.go --- cmd/junod/cmd/genaccounts.go | 192 ----------------------------------- cmd/junod/cmd/root.go | 66 ++++-------- cmd/junod/main.go | 12 +-- go.mod | 8 +- go.sum | 15 +-- osmoutils/noapptest/ctx.go | 4 +- 6 files changed, 38 insertions(+), 259 deletions(-) delete mode 100644 cmd/junod/cmd/genaccounts.go diff --git a/cmd/junod/cmd/genaccounts.go b/cmd/junod/cmd/genaccounts.go deleted file mode 100644 index a463ce3aa..000000000 --- a/cmd/junod/cmd/genaccounts.go +++ /dev/null @@ -1,192 +0,0 @@ -package cmd - -import ( - "bufio" - "encoding/json" - "errors" - "fmt" - - "github.com/spf13/cobra" - - "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" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" - authvesting "github.com/cosmos/cosmos-sdk/x/auth/vesting/types" - 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" -) - -const ( - flagVestingStart = "vesting-start-time" - flagVestingEnd = "vesting-end-time" - flagVestingAmt = "vesting-amount" -) - -// AddGenesisAccountCmd returns add-genesis-account cobra Command. -func AddGenesisAccountCmd(defaultNodeHome string) *cobra.Command { - cmd := &cobra.Command{ - Use: "add-genesis-account [address_or_key_name] [coin][,[coin]]", - Short: "Add a genesis account to genesis.json", - Long: `Add a genesis account to genesis.json. The provided account must specify -the account address or key name and a list of initial coins. If a key name is given, -the address will be looked up in the local Keybase. The list of initial tokens must -contain valid denominations. Accounts may optionally be supplied with vesting parameters. -`, - Args: cobra.ExactArgs(2), - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx := client.GetClientContextFromCmd(cmd) - serverCtx := server.GetServerContextFromCmd(cmd) - config := serverCtx.Config - - config.SetRoot(clientCtx.HomeDir) - - var kr keyring.Keyring - addr, err := sdk.AccAddressFromBech32(args[0]) - if err != nil { - inBuf := bufio.NewReader(cmd.InOrStdin()) - keyringBackend, err := cmd.Flags().GetString(flags.FlagKeyringBackend) - if err != nil { - return fmt.Errorf("failed to parse keyring backend: %w", err) - } - if keyringBackend != "" && clientCtx.Keyring == nil { - var err error - kr, err = keyring.New(sdk.KeyringServiceName(), keyringBackend, clientCtx.HomeDir, inBuf) - if err != nil { - return err - } - } else { - kr = clientCtx.Keyring - } - - info, err := kr.Key(args[0]) - if err != nil { - return fmt.Errorf("failed to get address from Keyring: %w", err) - } - addr = info.GetAddress() - } - - coins, err := sdk.ParseCoinsNormalized(args[1]) - if err != nil { - return fmt.Errorf("failed to parse coins: %w", err) - } - - vestingStart, err := cmd.Flags().GetInt64(flagVestingStart) - if err != nil { - return fmt.Errorf("failed to parse vesting start: %w", err) - } - vestingEnd, err := cmd.Flags().GetInt64(flagVestingEnd) - if err != nil { - return fmt.Errorf("failed to parse vesting end: %w", err) - } - vestingAmtStr, err := cmd.Flags().GetString(flagVestingAmt) - if err != nil { - return fmt.Errorf("failed to parse vesting amount: %w", err) - } - - vestingAmt, err := sdk.ParseCoinsNormalized(vestingAmtStr) - if err != nil { - return fmt.Errorf("failed to parse vesting amount: %w", err) - } - - // create concrete account type based on input parameters - var genAccount authtypes.GenesisAccount - - balances := banktypes.Balance{Address: addr.String(), Coins: coins.Sort()} - baseAccount := authtypes.NewBaseAccount(addr, nil, 0, 0) - - if !vestingAmt.IsZero() { - baseVestingAccount := authvesting.NewBaseVestingAccount(baseAccount, vestingAmt.Sort(), vestingEnd) - - if (balances.Coins.IsZero() && !baseVestingAccount.OriginalVesting.IsZero()) || - baseVestingAccount.OriginalVesting.IsAnyGT(balances.Coins) { - return errors.New("vesting amount cannot be greater than total amount") - } - - switch { - case vestingStart != 0 && vestingEnd != 0: - genAccount = authvesting.NewContinuousVestingAccountRaw(baseVestingAccount, vestingStart) - - case vestingEnd != 0: - genAccount = authvesting.NewDelayedVestingAccountRaw(baseVestingAccount) - - default: - return errors.New("invalid vesting parameters; must supply start and end time or end time") - } - } else { - genAccount = baseAccount - } - - if err := genAccount.Validate(); err != nil { - return fmt.Errorf("failed to validate new genesis account: %w", err) - } - - genFile := config.GenesisFile() - appState, genDoc, err := genutiltypes.GenesisStateFromGenFile(genFile) - if err != nil { - return fmt.Errorf("failed to unmarshal genesis state: %w", err) - } - - authGenState := authtypes.GetGenesisStateFromAppState(clientCtx.Codec, appState) - - accs, err := authtypes.UnpackAccounts(authGenState.Accounts) - if err != nil { - return fmt.Errorf("failed to get accounts from any: %w", err) - } - - if accs.Contains(addr) { - return fmt.Errorf("cannot add account at existing address %s", addr) - } - - // Add the new account to the set of genesis accounts and sanitize the - // accounts afterwards. - accs = append(accs, genAccount) - accs = authtypes.SanitizeGenesisAccounts(accs) - - genAccs, err := authtypes.PackAccounts(accs) - if err != nil { - return fmt.Errorf("failed to convert accounts into any's: %w", err) - } - authGenState.Accounts = genAccs - - authGenStateBz, err := clientCtx.Codec.MarshalJSON(&authGenState) - if err != nil { - return fmt.Errorf("failed to marshal auth genesis state: %w", err) - } - - appState[authtypes.ModuleName] = authGenStateBz - - bankGenState := banktypes.GetGenesisStateFromAppState(clientCtx.Codec, appState) - bankGenState.Balances = append(bankGenState.Balances, balances) - bankGenState.Balances = banktypes.SanitizeGenesisBalances(bankGenState.Balances) - bankGenState.Supply = bankGenState.Supply.Add(balances.Coins...) - - bankGenStateBz, err := clientCtx.Codec.MarshalJSON(bankGenState) - if err != nil { - return fmt.Errorf("failed to marshal bank genesis state: %w", err) - } - - appState[banktypes.ModuleName] = bankGenStateBz - - appStateJSON, err := json.Marshal(appState) - if err != nil { - return fmt.Errorf("failed to marshal application genesis state: %w", err) - } - - genDoc.AppState = appStateJSON - return genutil.ExportGenesisFile(genDoc, genFile) - }, - } - - 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)") - cmd.Flags().String(flagVestingAmt, "", "amount of coins for vesting accounts") - cmd.Flags().Int64(flagVestingStart, 0, "schedule start time (unix epoch) for vesting accounts") - cmd.Flags().Int64(flagVestingEnd, 0, "schedule end time (unix epoch) for vesting accounts") - flags.AddQueryFlagsToCmd(cmd) - - return cmd -} diff --git a/cmd/junod/cmd/root.go b/cmd/junod/cmd/root.go index 84aecb354..4370bd171 100644 --- a/cmd/junod/cmd/root.go +++ b/cmd/junod/cmd/root.go @@ -8,8 +8,8 @@ import ( "time" tmcfg "github.com/cometbft/cometbft/config" + "github.com/prometheus/client_golang/prometheus" - "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/client" serverconfig "github.com/cosmos/cosmos-sdk/server/config" @@ -23,8 +23,6 @@ import ( "github.com/cosmos/cosmos-sdk/client/rpc" "github.com/cosmos/cosmos-sdk/server" servertypes "github.com/cosmos/cosmos-sdk/server/types" - "github.com/cosmos/cosmos-sdk/snapshots" - "github.com/cosmos/cosmos-sdk/store" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/version" authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli" @@ -32,7 +30,6 @@ import ( banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" "github.com/cosmos/cosmos-sdk/x/crisis" genutilcli "github.com/cosmos/cosmos-sdk/x/genutil/client/cli" - "github.com/prometheus/client_golang/prometheus" "github.com/spf13/cast" "github.com/spf13/cobra" @@ -208,12 +205,15 @@ func initRootCmd(rootCmd *cobra.Command, encodingConfig params.EncodingConfig) { encCfg: encodingConfig, } + // gentxModule := moduleBasics[genutiltypes.ModuleName].(genutil.AppModuleBasic) + rootCmd.AddCommand( genutilcli.InitCmd(app.ModuleBasics, app.DefaultNodeHome), - genutilcli.CollectGenTxsCmd(banktypes.GenesisBalancesIterator{}, app.DefaultNodeHome), + // TODO: + // genutilcli.CollectGenTxsCmd(banktypes.GenesisBalancesIterator{}, app.DefaultNodeHome, gentxModule.GenTxValidator), genutilcli.GenTxCmd(app.ModuleBasics, encodingConfig.TxConfig, banktypes.GenesisBalancesIterator{}, app.DefaultNodeHome), genutilcli.ValidateGenesisCmd(app.ModuleBasics), - AddGenesisAccountCmd(app.DefaultNodeHome), + genutilcli.AddGenesisAccountCmd(app.DefaultNodeHome), AddGenesisIcaCmd(app.DefaultNodeHome), tmcli.NewCompletionCmd(rootCmd, true), DebugCmd(), @@ -299,56 +299,29 @@ func (ac appCreator) newApp( traceStore io.Writer, appOpts servertypes.AppOptions, ) servertypes.Application { - var cache sdk.MultiStorePersistentCache - - if cast.ToBool(appOpts.Get(server.FlagInterBlockCache)) { - cache = store.NewCommitKVStoreCacheManager() - } - skipUpgradeHeights := make(map[int64]bool) for _, h := range cast.ToIntSlice(appOpts.Get(server.FlagUnsafeSkipUpgrades)) { skipUpgradeHeights[int64(h)] = true } - pruningOpts, err := server.GetPruningOptionsFromFlags(appOpts) - if err != nil { - panic(err) - } - - snapshotDir := filepath.Join(cast.ToString(appOpts.Get(flags.FlagHome)), "data", "snapshots") - snapshotDB, err := sdk.NewLevelDB("metadata", snapshotDir) - if err != nil { - panic(err) - } - snapshotStore, err := snapshots.NewStore(snapshotDB, snapshotDir) - if err != nil { - panic(err) - } var wasmOpts []wasm.Option if cast.ToBool(appOpts.Get("telemetry.enabled")) { wasmOpts = append(wasmOpts, wasmkeeper.WithVMCacheMetrics(prometheus.DefaultRegisterer)) } - return app.New(logger, db, traceStore, true, skipUpgradeHeights, - cast.ToString(appOpts.Get(flags.FlagHome)), - cast.ToUint(appOpts.Get(server.FlagInvCheckPeriod)), - ac.encCfg, + loadLatest := true + + baseappOptions := server.DefaultBaseappOptions(appOpts) + + return app.New( + logger, + db, + traceStore, + loadLatest, app.GetEnabledProposals(), appOpts, wasmOpts, - baseapp.SetPruning(pruningOpts), - baseapp.SetMinGasPrices(cast.ToString(appOpts.Get(server.FlagMinGasPrices))), - baseapp.SetHaltHeight(cast.ToUint64(appOpts.Get(server.FlagHaltHeight))), - baseapp.SetHaltTime(cast.ToUint64(appOpts.Get(server.FlagHaltTime))), - baseapp.SetMinRetainBlocks(cast.ToUint64(appOpts.Get(server.FlagMinRetainBlocks))), - baseapp.SetInterBlockCache(cache), - baseapp.SetTrace(cast.ToBool(appOpts.Get(server.FlagTrace))), - baseapp.SetIndexEvents(cast.ToStringSlice(appOpts.Get(server.FlagIndexEvents))), - baseapp.SetSnapshotStore(snapshotStore), - baseapp.SetSnapshotInterval(cast.ToUint64(appOpts.Get(server.FlagStateSyncSnapshotInterval))), - baseapp.SetSnapshotKeepRecent(cast.ToUint32(appOpts.Get(server.FlagStateSyncSnapshotKeepRecent))), - baseapp.SetIAVLCacheSize(cast.ToInt(appOpts.Get(server.FlagIAVLCacheSize))), - baseapp.SetIAVLDisableFastNode(cast.ToBool(appOpts.Get(server.FlagDisableIAVLFastNode))), + baseappOptions..., ) } @@ -360,6 +333,7 @@ func (ac appCreator) appExport( forZeroHeight bool, jailAllowedAddrs []string, appOpts servertypes.AppOptions, + modulesToExport []string, ) (servertypes.ExportedApp, error) { var junoApp *app.App homePath, ok := appOpts.Get(flags.FlagHome).(string) @@ -374,10 +348,6 @@ func (ac appCreator) appExport( db, traceStore, loadLatest, - map[int64]bool{}, - homePath, - cast.ToUint(appOpts.Get(server.FlagInvCheckPeriod)), - ac.encCfg, app.GetEnabledProposals(), appOpts, emptyWasmOpts, @@ -389,5 +359,5 @@ func (ac appCreator) appExport( } } - return junoApp.ExportAppStateAndValidators(forZeroHeight, jailAllowedAddrs) + return junoApp.ExportAppStateAndValidators(forZeroHeight, jailAllowedAddrs, modulesToExport) } diff --git a/cmd/junod/main.go b/cmd/junod/main.go index 330c85a8b..75250a328 100644 --- a/cmd/junod/main.go +++ b/cmd/junod/main.go @@ -3,9 +3,10 @@ package main import ( "os" + "cosmossdk.io/log" + "github.com/CosmosContracts/juno/v15/app" "github.com/CosmosContracts/juno/v15/cmd/junod/cmd" - "github.com/cosmos/cosmos-sdk/server" svrcmd "github.com/cosmos/cosmos-sdk/server/cmd" ) @@ -15,12 +16,7 @@ func main() { rootCmd, _ := cmd.NewRootCmd() if err := svrcmd.Execute(rootCmd, "JUNOD", app.DefaultNodeHome); err != nil { - switch e := err.(type) { - case server.ErrorCode: - os.Exit(e.Code) - - default: - os.Exit(1) - } + log.NewLogger(rootCmd.OutOrStderr()).Error("failure when running app", "err", err) + os.Exit(1) } } diff --git a/go.mod b/go.mod index 3da113770..f25975e04 100644 --- a/go.mod +++ b/go.mod @@ -27,6 +27,8 @@ require ( gopkg.in/yaml.v2 v2.4.0 ) +require cosmossdk.io/log v1.1.0 + require ( cloud.google.com/go v0.110.0 // indirect cloud.google.com/go/compute v1.18.0 // indirect @@ -133,7 +135,7 @@ require ( github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.17 // indirect + github.com/mattn/go-isatty v0.0.18 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0 // indirect github.com/minio/highwayhash v1.0.2 // indirect @@ -150,11 +152,11 @@ require ( github.com/rakyll/statik v0.1.7 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/rs/cors v1.8.3 // indirect - github.com/rs/zerolog v1.27.0 + github.com/rs/zerolog v1.29.1 // indirect github.com/sasha-s/go-deadlock v0.3.1 // indirect github.com/spf13/afero v1.9.3 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect - github.com/spf13/pflag v1.0.5 + github.com/spf13/pflag v1.0.5 // indirect github.com/spf13/viper v1.15.0 github.com/subosito/gotenv v1.4.2 // indirect github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d diff --git a/go.sum b/go.sum index 0f4a2145e..c45ac10a2 100644 --- a/go.sum +++ b/go.sum @@ -200,6 +200,8 @@ cosmossdk.io/depinject v1.0.0-alpha.3 h1:6evFIgj//Y3w09bqOUOzEpFj5tsxBqdc5CfkO7z cosmossdk.io/depinject v1.0.0-alpha.3/go.mod h1:eRbcdQ7MRpIPEM5YUJh8k97nxHpYbc3sMUnEtt8HPWU= 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/log v1.1.0 h1:v0ogPHYeTzPcBTcPR1A3j1hkei4pZama8kz8LKlCMv0= +cosmossdk.io/log v1.1.0/go.mod h1:6zjroETlcDs+mm62gd8Ig7mZ+N+fVOZS91V17H+M4N4= cosmossdk.io/math v1.0.0 h1:ro9w7eKx23om2tZz/VM2Pf+z2WAbGX1yDQQOJ6iGeJw= cosmossdk.io/math v1.0.0/go.mod h1:Ygz4wBHrgc7g0N+8+MrnTfS9LLn9aaTGa9hKopuym5k= cosmossdk.io/simapp v0.0.0-20230224204036-a6adb0821462 h1:g8muUHnXL8vhld2Sjilyhb1UQObc+x9GVuDK43TYZns= @@ -376,7 +378,7 @@ github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cosmos/btcutil v1.0.5 h1:t+ZFcX77LpKtDBhjucvnOH8C2l2ioGsBNEQ3jef8xFk= github.com/cosmos/btcutil v1.0.5/go.mod h1:IyB7iuqZMJlthe2tkIFL33xPyzbFYP0XVdS8P5lUPis= @@ -874,8 +876,8 @@ github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2y 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/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= -github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.18 h1:DOKFKCQ7FNG2L1rbrmstDN4QVRdS89Nkh85u68Uwp98= +github.com/mattn/go-isatty v0.0.18/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= 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= @@ -1047,9 +1049,9 @@ github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjR github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/rs/cors v1.8.3 h1:O+qNyWn7Z+F9M0ILBHgMVPuB1xTOucVd5gtaYyXBpRo= github.com/rs/cors v1.8.3/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= -github.com/rs/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= +github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/zerolog v1.29.1 h1:cO+d60CHkknCbvzEWxP0S9K6KqyTjrCNUy1LdQLCGPc= +github.com/rs/zerolog v1.29.1/go.mod h1:Le6ESbR7hc+DP6Lt1THiV8CQSdkkNrd3R0XbEgp3ZBU= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= @@ -1481,6 +1483,7 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= diff --git a/osmoutils/noapptest/ctx.go b/osmoutils/noapptest/ctx.go index 06243f20a..f73f692f4 100644 --- a/osmoutils/noapptest/ctx.go +++ b/osmoutils/noapptest/ctx.go @@ -12,9 +12,9 @@ import ( ) func CtxWithStoreKeys(keys []sdk.Store, header tmproto.Header, isCheckTx bool) sdk.Context { - db := dbm.NewMemDB() + db, _ := dbm.NewDB("test", dbm.GoLevelDBBackend, "") logger := log.NewNopLogger() - cms := store.NewCommitMultiStore(db, logger) + cms := store.NewCommitMultiStore(db) for _, key := range keys { cms.MountStoreWithDB(key, sdk.StoreTypeIAVL, nil) } From 4a164a69f8c80630a20d497ab626312b842aacb8 Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Fri, 28 Apr 2023 15:57:53 -0500 Subject: [PATCH 042/131] storetypes, ConsensusParams, test_helpers --- app/keepers/keepers.go | 7 +++++-- app/modules.go | 2 +- app/sim_test.go | 7 ++++--- app/test_helpers.go | 12 +++++------- app/upgrades/types.go | 10 ++++------ osmoutils/noapptest/ctx.go | 3 ++- osmoutils/store_helper_test.go | 5 +++-- x/ibc-hooks/keeper/keeper.go | 5 +++-- x/mint/keeper/keeper.go | 5 +++-- 9 files changed, 30 insertions(+), 26 deletions(-) diff --git a/app/keepers/keepers.go b/app/keepers/keepers.go index c2f353840..7339b9ee5 100644 --- a/app/keepers/keepers.go +++ b/app/keepers/keepers.go @@ -170,6 +170,8 @@ func NewAppKeepers( appKeepers.tkeys[paramstypes.TStoreKey], ) + keys := appKeepers.GetKVStoreKey() + // set the BaseApp's parameter store appKeepers.ConsensusParamsKeeper = consensusparamkeeper.NewKeeper(appCodec, keys[consensusparamtypes.StoreKey], authtypes.NewModuleAddress(govtypes.ModuleName).String()) @@ -189,7 +191,8 @@ func NewAppKeepers( scopedWasmKeeper := appKeepers.CapabilityKeeper.ScopeToModule(wasm.ModuleName) // add keepers - app.AccountKeeper = authkeeper.NewAccountKeeper( + Bech32Prefix := "juno" + appKeepers.AccountKeeper = authkeeper.NewAccountKeeper( appCodec, keys[authtypes.StoreKey], authtypes.ProtoBaseAccount, @@ -522,7 +525,7 @@ func NewAppKeepers( } // initParamsKeeper init params keeper and its subspaces -func initParamsKeeper(appCodec codec.BinaryCodec, legacyAmino *codec.LegacyAmino, key, tkey sdk.StoreKey) paramskeeper.Keeper { +func initParamsKeeper(appCodec codec.BinaryCodec, legacyAmino *codec.LegacyAmino, key, tkey storetypes.StoreKey) paramskeeper.Keeper { paramsKeeper := paramskeeper.NewKeeper(appCodec, legacyAmino, key, tkey) paramsKeeper.Subspace(authtypes.ModuleName) diff --git a/app/modules.go b/app/modules.go index 53c9d5071..bfe11487d 100644 --- a/app/modules.go +++ b/app/modules.go @@ -85,7 +85,7 @@ var ModuleBasics = module.NewBasicManager( staking.AppModuleBasic{}, mint.AppModuleBasic{}, distr.AppModuleBasic{}, - gov.NewAppModuleBasic(getGovProposalHandlers()...), + gov.NewAppModuleBasic(getGovProposalHandlers()), params.AppModuleBasic{}, crisis.AppModuleBasic{}, slashing.AppModuleBasic{}, diff --git a/app/sim_test.go b/app/sim_test.go index 47406feb7..06759d378 100644 --- a/app/sim_test.go +++ b/app/sim_test.go @@ -20,16 +20,17 @@ import ( "github.com/cosmos/cosmos-sdk/types/module" simtypes "github.com/cosmos/cosmos-sdk/types/simulation" "github.com/cosmos/cosmos-sdk/x/simulation" + storetypes "github.com/cosmos/cosmos-sdk/store/types" ) // Get flags every time the simulator is run func init() { - simapp.GetSimulatorFlags() + simcli.GetSimulatorFlags() } type StoreKeysPrefixes struct { - A sdk.StoreKey - B sdk.StoreKey + A storetypes.StoreKey + B storetypes.StoreKey Prefixes [][]byte } diff --git a/app/test_helpers.go b/app/test_helpers.go index f22aefcbc..44dfa963f 100644 --- a/app/test_helpers.go +++ b/app/test_helpers.go @@ -6,7 +6,7 @@ import ( "time" "github.com/CosmWasm/wasmd/x/wasm" - "github.com/CosmWasm/wasmd/x/wasm/keeper" + "github.com/CosmWasm/wasmd/x/wasm/keeper" apphelpers "github.com/CosmosContracts/juno/v15/app/helpers" appparams "github.com/CosmosContracts/juno/v15/app/params" dbm "github.com/cometbft/cometbft-db" @@ -129,12 +129,8 @@ func setup(withGenesis bool, invCheckPeriod uint) (*App, GenesisState) { db, nil, true, - map[int64]bool{}, - DefaultNodeHome, - invCheckPeriod, - encCdc, - GetEnabledProposals(), - EmptyBaseAppOptions{}, + wasm.EnableAllProposals, + EmptyAppOptions{}, emptyWasmOpts, ) if withGenesis { @@ -188,6 +184,7 @@ func genesisStateWithValSet(t *testing.T, defaultStParams.MaxEntries, defaultStParams.HistoricalEntries, appparams.BondDenom, + defaultStParams.MinCommissionRate, // 5% ) // set validators and delegations @@ -217,6 +214,7 @@ func genesisStateWithValSet(t *testing.T, balances, totalSupply, []banktypes.Metadata{}, + banktypes.DefaultGenesisState().SendEnabled, ) genesisState[banktypes.ModuleName] = app.AppCodec().MustMarshalJSON(bankGenesis) diff --git a/app/upgrades/types.go b/app/upgrades/types.go index f16387cf3..5d725e435 100644 --- a/app/upgrades/types.go +++ b/app/upgrades/types.go @@ -4,19 +4,17 @@ import ( "strings" "github.com/CosmosContracts/juno/v15/app/keepers" - abci "github.com/cometbft/cometbft/abci/types" store "github.com/cosmos/cosmos-sdk/store/types" - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" ) // BaseAppParamManager defines an interrace that BaseApp is expected to fullfil // that allows upgrade handlers to modify BaseApp parameters. -type BaseAppParamManager interface { - GetConsensusParams(ctx sdk.Context) *abci.ConsensusParams - StoreConsensusParams(ctx sdk.Context, cp *abci.ConsensusParams) -} +// type BaseAppParamManager interface { +// GetConsensusParams(ctx sdk.Context) *abci.ConsensusParams +// StoreConsensusParams(ctx sdk.Context, cp *abci.ConsensusParams) +// } // Upgrade defines a struct containing necessary fields that a SoftwareUpgradeProposal // must have written, in order for the state migration to go smoothly. diff --git a/osmoutils/noapptest/ctx.go b/osmoutils/noapptest/ctx.go index f73f692f4..e3c649300 100644 --- a/osmoutils/noapptest/ctx.go +++ b/osmoutils/noapptest/ctx.go @@ -9,6 +9,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" dbm "github.com/cometbft/cometbft-db" + storetypes "github.com/cosmos/cosmos-sdk/store/types" ) func CtxWithStoreKeys(keys []sdk.Store, header tmproto.Header, isCheckTx bool) sdk.Context { @@ -25,7 +26,7 @@ func CtxWithStoreKeys(keys []sdk.Store, header tmproto.Header, isCheckTx bool) s return sdk.NewContext(cms, header, isCheckTx, logger) } -func DefaultCtxWithStoreKeys(storeKeys []sdk.StoreKey) sdk.Context { +func DefaultCtxWithStoreKeys(storeKeys []storetypes.StoreKey) sdk.Context { header := tmproto.Header{Height: 1, ChainID: "osmoutils-test-1", Time: time.Now().UTC()} deliverTx := false return CtxWithStoreKeys(storeKeys, header, deliverTx) diff --git a/osmoutils/store_helper_test.go b/osmoutils/store_helper_test.go index bb7cace55..be6607ff6 100644 --- a/osmoutils/store_helper_test.go +++ b/osmoutils/store_helper_test.go @@ -19,6 +19,7 @@ import ( "github.com/CosmosContracts/juno/v15/osmoutils" "github.com/CosmosContracts/juno/v15/osmoutils/noapptest" "github.com/CosmosContracts/juno/v15/osmoutils/osmoassert" + storetypes "github.com/cosmos/cosmos-sdk/store/types" ) // We need to setup a test suite with account keeper @@ -30,7 +31,7 @@ type TestSuite struct { ctx sdk.Context store sdk.KVStore - authStoreKey sdk.StoreKey + authStoreKey storetypes.StoreKey accountKeeper authkeeper.AccountKeeperI } @@ -43,7 +44,7 @@ func (suite *TestSuite) SetupTest() { paramsKey := sdk.NewKVStoreKey(paramstypes.StoreKey) paramsTKey := sdk.NewKVStoreKey(paramstypes.TStoreKey) suite.ctx = noapptest.DefaultCtxWithStoreKeys( - []sdk.StoreKey{customStoreKey, suite.authStoreKey, paramsKey, paramsTKey}) + []storetypes.StoreKey{customStoreKey, suite.authStoreKey, paramsKey, paramsTKey}) suite.store = suite.ctx.KVStore(customStoreKey) // setup params (needed for auth) encConfig := noapptest.MakeTestEncodingConfig(auth.AppModuleBasic{}, params.AppModuleBasic{}) diff --git a/x/ibc-hooks/keeper/keeper.go b/x/ibc-hooks/keeper/keeper.go index c5d0757f6..b099a9acc 100644 --- a/x/ibc-hooks/keeper/keeper.go +++ b/x/ibc-hooks/keeper/keeper.go @@ -9,18 +9,19 @@ import ( "github.com/CosmosContracts/juno/v15/x/ibc-hooks/types" + storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" ) type ( Keeper struct { - storeKey sdk.StoreKey + storeKey storetypes.StoreKey } ) // NewKeeper returns a new instance of the x/ibchooks keeper func NewKeeper( - storeKey sdk.StoreKey, + storeKey storetypes.StoreKey, ) Keeper { return Keeper{ storeKey: storeKey, diff --git a/x/mint/keeper/keeper.go b/x/mint/keeper/keeper.go index 4de59a1e0..488996418 100644 --- a/x/mint/keeper/keeper.go +++ b/x/mint/keeper/keeper.go @@ -8,12 +8,13 @@ import ( "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" + sdktypes "github.com/cosmos/cosmos-sdk/types" ) // Keeper of the mint store type Keeper struct { cdc codec.BinaryCodec - storeKey sdk.StoreKey + storeKey sdktypes.StoreKey paramSpace paramtypes.Subspace stakingKeeper types.StakingKeeper bankKeeper types.BankKeeper @@ -22,7 +23,7 @@ type Keeper struct { // NewKeeper creates a new mint Keeper instance func NewKeeper( - cdc codec.BinaryCodec, key sdk.StoreKey, paramSpace paramtypes.Subspace, + cdc codec.BinaryCodec, key sdktypes.StoreKey, paramSpace paramtypes.Subspace, sk types.StakingKeeper, ak types.AccountKeeper, bk types.BankKeeper, feeCollectorName string, ) Keeper { From 21f594101c1a070eeb33f061f80fee2254fe7ca8 Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Fri, 28 Apr 2023 16:51:04 -0500 Subject: [PATCH 043/131] Fix keepers, add ibchost key --- app/app.go | 40 +++++++++++----------- app/keepers/keepers.go | 76 +++++++++++++++++++++++++++--------------- app/keepers/keys.go | 3 +- 3 files changed, 73 insertions(+), 46 deletions(-) diff --git a/app/app.go b/app/app.go index 15a775e00..a3a4f924f 100644 --- a/app/app.go +++ b/app/app.go @@ -198,6 +198,8 @@ type App struct { tkeys map[string]*storetypes.TransientStoreKey memKeys map[string]*storetypes.MemoryStoreKey + AppKeepers keepers.AppKeepers + // the module manager ModuleManager *module.Manager @@ -285,12 +287,12 @@ func New( // can do so safely. app.ModuleManager.SetOrderInitGenesis(orderInitBlockers()...) - app.ModuleManager.RegisterInvariants(&app.CrisisKeeper) + app.ModuleManager.RegisterInvariants(app.AppKeepers.CrisisKeeper) app.ModuleManager.RegisterServices(cfg) // initialize stores - app.MountKVStores(app.GetKVStoreKey()) - app.MountTransientStores(app.GetTransientStoreKey()) - app.MountMemoryStores(app.GetMemoryStoreKey()) + app.MountKVStores(app.AppKeepers.GetKVStoreKey()) + app.MountTransientStores(app.AppKeepers.GetTransientStoreKey()) + app.MountMemoryStores(app.AppKeepers.GetMemoryStoreKey()) // register upgrade app.setupUpgradeHandlers(cfg) @@ -303,18 +305,18 @@ func New( anteHandler, err := NewAnteHandler( HandlerOptions{ HandlerOptions: ante.HandlerOptions{ - AccountKeeper: app.AccountKeeper, - BankKeeper: app.BankKeeper, - FeegrantKeeper: app.FeeGrantKeeper, + AccountKeeper: app.AppKeepers.AccountKeeper, + BankKeeper: app.AppKeepers.BankKeeper, + FeegrantKeeper: app.AppKeepers.FeeGrantKeeper, SignModeHandler: encodingConfig.TxConfig.SignModeHandler(), SigGasConsumer: ante.DefaultSigVerificationGasConsumer, }, - GovKeeper: app.GovKeeper, - IBCKeeper: app.IBCKeeper, - FeeShareKeeper: app.FeeShareKeeper, - BankKeeperFork: app.BankKeeper, // since we need extra methods - TxCounterStoreKey: app.GetKey(wasm.StoreKey), + GovKeeper: app.AppKeepers.GovKeeper, + IBCKeeper: app.AppKeepers.IBCKeeper, + FeeShareKeeper: app.AppKeepers.FeeShareKeeper, + BankKeeperFork: app.AppKeepers.BankKeeper, // since we need extra methods + TxCounterStoreKey: app.AppKeepers.GetKey(wasm.StoreKey), WasmConfig: wasmConfig, Cdc: appCodec, StakingSubspace: app.GetSubspace(stakingtypes.ModuleName), @@ -335,7 +337,7 @@ func New( if manager := app.SnapshotManager(); manager != nil { err = manager.RegisterExtensions( - wasmkeeper.NewWasmSnapshotter(app.CommitMultiStore(), &app.WasmKeeper), + wasmkeeper.NewWasmSnapshotter(app.CommitMultiStore(), &app.AppKeepers.WasmKeeper), ) if err != nil { panic("failed to register snapshot extension: " + err.Error()) @@ -356,7 +358,7 @@ func New( // that in-memory capabilities get regenerated on app restart. // Note that since this reads from the store, we can only perform it when // `loadLatest` is set to true. - app.CapabilityKeeper.Seal() + app.AppKeepers.CapabilityKeeper.Seal() } // create the simulation manager and define the order of the modules for deterministic simulations @@ -403,7 +405,7 @@ func (app *App) InitChainer(ctx sdk.Context, req abci.RequestInitChain) abci.Res if err := tmjson.Unmarshal(req.AppStateBytes, &genesisState); err != nil { panic(err) } - app.UpgradeKeeper.SetModuleVersionMap(ctx, app.ModuleManager.GetVersionMap()) + app.AppKeepers.UpgradeKeeper.SetModuleVersionMap(ctx, app.ModuleManager.GetVersionMap()) return app.ModuleManager.InitGenesis(ctx, app.appCodec, genesisState) } @@ -447,7 +449,7 @@ func (app *App) InterfaceRegistry() types.InterfaceRegistry { // // NOTE: This is solely to be used for testing purposes. func (app *App) GetSubspace(moduleName string) paramstypes.Subspace { - subspace, _ := app.ParamsKeeper.GetSubspace(moduleName) + subspace, _ := app.AppKeepers.ParamsKeeper.GetSubspace(moduleName) return subspace } @@ -493,12 +495,12 @@ func (app *App) RegisterNodeService(clientCtx client.Context) { // configure store loader that checks if version == upgradeHeight and applies store upgrades func (app *App) setupUpgradeStoreLoaders() { - upgradeInfo, err := app.UpgradeKeeper.ReadUpgradeInfoFromDisk() + upgradeInfo, err := app.AppKeepers.UpgradeKeeper.ReadUpgradeInfoFromDisk() if err != nil { panic("failed to read upgrade info from disk" + err.Error()) } - if app.UpgradeKeeper.IsSkipHeight(upgradeInfo.Height) { + if app.AppKeepers.UpgradeKeeper.IsSkipHeight(upgradeInfo.Height) { return } @@ -513,7 +515,7 @@ func (app *App) setupUpgradeStoreLoaders() { func (app *App) setupUpgradeHandlers(cfg module.Configurator) { for _, upgrade := range Upgrades { - app.UpgradeKeeper.SetUpgradeHandler( + app.AppKeepers.UpgradeKeeper.SetUpgradeHandler( upgrade.UpgradeName, upgrade.CreateUpgradeHandler( app.ModuleManager, diff --git a/app/keepers/keepers.go b/app/keepers/keepers.go index 7339b9ee5..0d9db3cbb 100644 --- a/app/keepers/keepers.go +++ b/app/keepers/keepers.go @@ -4,6 +4,7 @@ import ( "path/filepath" ibchookstypes "github.com/CosmosContracts/juno/v15/x/ibc-hooks/types" + "github.com/spf13/cast" "github.com/CosmWasm/wasmd/x/wasm" wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" @@ -12,7 +13,9 @@ import ( mintkeeper "github.com/CosmosContracts/juno/v15/x/mint/keeper" minttypes "github.com/CosmosContracts/juno/v15/x/mint/types" "github.com/cosmos/cosmos-sdk/baseapp" + "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/server" servertypes "github.com/cosmos/cosmos-sdk/server/types" storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" @@ -27,7 +30,6 @@ import ( consensusparamtypes "github.com/cosmos/cosmos-sdk/x/consensus/types" crisiskeeper "github.com/cosmos/cosmos-sdk/x/crisis/keeper" crisistypes "github.com/cosmos/cosmos-sdk/x/crisis/types" - distr "github.com/cosmos/cosmos-sdk/x/distribution" distrkeeper "github.com/cosmos/cosmos-sdk/x/distribution/keeper" distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" evidencekeeper "github.com/cosmos/cosmos-sdk/x/evidence/keeper" @@ -36,6 +38,7 @@ import ( feegrantkeeper "github.com/cosmos/cosmos-sdk/x/feegrant/keeper" govkeeper "github.com/cosmos/cosmos-sdk/x/gov/keeper" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + govv1beta1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" "github.com/cosmos/cosmos-sdk/x/params" paramskeeper "github.com/cosmos/cosmos-sdk/x/params/keeper" paramstypes "github.com/cosmos/cosmos-sdk/x/params/types" @@ -57,6 +60,7 @@ import ( ibcclienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" ibcconnectiontypes "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" porttypes "github.com/cosmos/ibc-go/v7/modules/core/05-port/types" + ibchost "github.com/cosmos/ibc-go/v7/modules/core/24-host" ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" ibckeeper "github.com/cosmos/ibc-go/v7/modules/core/keeper" @@ -107,7 +111,7 @@ type AppKeepers struct { AccountKeeper authkeeper.AccountKeeper BankKeeper bankkeeper.BaseKeeper CapabilityKeeper *capabilitykeeper.Keeper - StakingKeeper *stakingkeeper.Keeper + StakingKeeper stakingkeeper.Keeper SlashingKeeper slashingkeeper.Keeper MintKeeper mintkeeper.Keeper DistrKeeper distrkeeper.Keeper @@ -122,11 +126,11 @@ type AppKeepers struct { PacketForwardKeeper *packetforwardkeeper.Keeper EvidenceKeeper evidencekeeper.Keeper TransferKeeper ibctransferkeeper.Keeper - ConsensusParamsKeeper consensusparamkeeper.Keeper AuthzKeeper authzkeeper.Keeper FeeGrantKeeper feegrantkeeper.Keeper FeeShareKeeper feesharekeeper.Keeper ContractKeeper *wasmkeeper.PermissionedKeeper + ConsensusParamsKeeper consensusparamkeeper.Keeper ICAControllerKeeper icacontrollerkeeper.Keeper ICAHostKeeper icahostkeeper.Keeper @@ -214,13 +218,13 @@ func NewAppKeepers( appKeepers.keys[stakingtypes.StoreKey], appKeepers.AccountKeeper, appKeepers.BankKeeper, - appKeepers.GetSubspace(stakingtypes.ModuleName), + authtypes.NewModuleAddress(govtypes.ModuleName).String(), ) appKeepers.MintKeeper = mintkeeper.NewKeeper( appCodec, appKeepers.keys[minttypes.StoreKey], appKeepers.GetSubspace(minttypes.ModuleName), - &stakingKeeper, + stakingKeeper, appKeepers.AccountKeeper, appKeepers.BankKeeper, authtypes.FeeCollectorName, @@ -228,43 +232,60 @@ func NewAppKeepers( appKeepers.DistrKeeper = distrkeeper.NewKeeper( appCodec, appKeepers.keys[distrtypes.StoreKey], - appKeepers.GetSubspace(distrtypes.ModuleName), appKeepers.AccountKeeper, appKeepers.BankKeeper, - &stakingKeeper, + stakingKeeper, authtypes.FeeCollectorName, - blockedAddress, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), ) appKeepers.SlashingKeeper = slashingkeeper.NewKeeper( appCodec, + cdc, appKeepers.keys[slashingtypes.StoreKey], - &stakingKeeper, - appKeepers.GetSubspace(slashingtypes.ModuleName), + stakingKeeper, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), ) + + invCheckPeriod := cast.ToUint(appOpts.Get(server.FlagInvCheckPeriod)) appKeepers.CrisisKeeper = crisiskeeper.NewKeeper( - appKeepers.GetSubspace(crisistypes.ModuleName), + appCodec, + keys[crisistypes.StoreKey], invCheckPeriod, appKeepers.BankKeeper, authtypes.FeeCollectorName, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), ) - appKeepers.UpgradeKeeper = upgradekeeper.NewKeeper(skipUpgradeHeights, + + skipUpgradeHeights := map[int64]bool{} + for _, h := range cast.ToIntSlice(appOpts.Get(server.FlagUnsafeSkipUpgrades)) { + skipUpgradeHeights[int64(h)] = true + } + homePath := cast.ToString(appOpts.Get(flags.FlagHome)) + + appKeepers.UpgradeKeeper = *upgradekeeper.NewKeeper( + skipUpgradeHeights, appKeepers.keys[upgradetypes.StoreKey], appCodec, homePath, - nil) + bApp, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) // register the staking hooks // NOTE: stakingKeeper above is passed by reference, so that it will contain these hooks - appKeepers.StakingKeeper = *stakingKeeper.SetHooks( - stakingtypes.NewMultiStakingHooks(appKeepers.DistrKeeper.Hooks(), appKeepers.SlashingKeeper.Hooks()), + stakingKeeper.SetHooks( + stakingtypes.NewMultiStakingHooks(appKeepers.DistrKeeper.Hooks(), + appKeepers.SlashingKeeper.Hooks()), ) + appKeepers.StakingKeeper = *stakingKeeper // ... other modules keepers // Create IBC Keeper appKeepers.IBCKeeper = ibckeeper.NewKeeper( - appCodec, appKeepers.keys[ibchost.StoreKey], - appKeepers.GetSubspace(ibchost.ModuleName), + appCodec, + appKeepers.keys[ibchost.SubModuleName], + appKeepers.GetSubspace(ibchost.SubModuleName), appKeepers.StakingKeeper, appKeepers.UpgradeKeeper, scopedIBCKeeper, @@ -279,14 +300,15 @@ func NewAppKeepers( appKeepers.keys[authzkeeper.StoreKey], appCodec, bApp.MsgServiceRouter(), + appKeepers.AccountKeeper, ) // register the proposal types - govRouter := govtypes.NewRouter() - govRouter.AddRoute(govtypes.RouterKey, govtypes.ProposalHandler). + govRouter := govv1beta1.NewRouter() + govRouter.AddRoute(govtypes.RouterKey, govv1beta1.ProposalHandler). AddRoute(paramproposal.RouterKey, params.NewParamChangeProposalHandler(appKeepers.ParamsKeeper)). - AddRoute(distrtypes.RouterKey, distr.NewCommunityPoolSpendProposalHandler(appKeepers.DistrKeeper)). - AddRoute(upgradetypes.RouterKey, upgrade.NewSoftwareUpgradeProposalHandler(appKeepers.UpgradeKeeper)). + AddRoute(upgradetypes.RouterKey, upgrade.NewSoftwareUpgradeProposalHandler(&appKeepers.UpgradeKeeper)). + // AddRoute(distrtypes.RouterKey, distr.NewCommunityPoolSpendProposalHandler(appKeepers.DistrKeeper)). AddRoute(ibcclienttypes.RouterKey, ibcclient.NewClientProposalHandler(appKeepers.IBCKeeper.ClientKeeper)) // Configure the hooks keeper @@ -316,8 +338,8 @@ func NewAppKeepers( ) appKeepers.IBCFeeKeeper = ibcfeekeeper.NewKeeper( - appCodec, appKeepers.keys[ibcfeetypes.StoreKey], - appKeepers.GetSubspace(ibcfeetypes.ModuleName), // this isn't even used in the keeper but is required? + appCodec, + appKeepers.keys[ibcfeetypes.StoreKey], appKeepers.HooksICS4Wrapper, // replaced with IBC middleware appKeepers.IBCKeeper.ChannelKeeper, &appKeepers.IBCKeeper.PortKeeper, @@ -381,7 +403,7 @@ func NewAppKeepers( // Create evidence Keeper for to register the IBC light client misbehaviour evidence route evidenceKeeper := evidencekeeper.NewKeeper( - appCodec, appKeepers.keys[evidencetypes.StoreKey], &appKeepers.StakingKeeper, appKeepers.SlashingKeeper, + appCodec, appKeepers.keys[evidencetypes.StoreKey], appKeepers.StakingKeeper, appKeepers.SlashingKeeper, ) // If evidence needs to be handled for the app, set routes in router here and seal appKeepers.EvidenceKeeper = *evidenceKeeper @@ -415,7 +437,7 @@ func NewAppKeepers( "/ibc.core.connection.v1.Query/Connection": &ibcconnectiontypes.QueryConnectionResponse{}, // governance - "/cosmos.gov.v1beta1.Query/Vote": &govtypes.QueryVoteResponse{}, + "/cosmos.gov.v1beta1.Query/Vote": &govv1beta1.QueryVoteResponse{}, // staking "/cosmos.staking.v1beta1.Query/Delegation": &stakingtypes.QueryDelegationResponse{}, @@ -534,8 +556,10 @@ func initParamsKeeper(appCodec codec.BinaryCodec, legacyAmino *codec.LegacyAmino paramsKeeper.Subspace(minttypes.ModuleName) paramsKeeper.Subspace(distrtypes.ModuleName) paramsKeeper.Subspace(slashingtypes.ModuleName) - paramsKeeper.Subspace(govtypes.ModuleName).WithKeyTable(govtypes.ParamKeyTable()) + paramsKeeper.Subspace(govtypes.ModuleName) paramsKeeper.Subspace(crisistypes.ModuleName) + + // custom paramsKeeper.Subspace(ibctransfertypes.ModuleName) paramsKeeper.Subspace(packetforwardtypes.ModuleName).WithKeyTable(packetforwardtypes.ParamKeyTable()) paramsKeeper.Subspace(ibchost.ModuleName) diff --git a/app/keepers/keys.go b/app/keepers/keys.go index ad17f2a57..75473ef4b 100644 --- a/app/keepers/keys.go +++ b/app/keepers/keys.go @@ -24,6 +24,7 @@ import ( icahosttypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/host/types" ibcfeetypes "github.com/cosmos/ibc-go/v7/modules/apps/29-fee/types" ibctransfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" + ibchost "github.com/cosmos/ibc-go/v7/modules/core/24-host" ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" icqtypes "github.com/strangelove-ventures/async-icq/v7/types" packetforwardtypes "github.com/strangelove-ventures/packet-forward-middleware/v7/router/types" @@ -38,7 +39,7 @@ func (appKeepers *AppKeepers) GenerateKeys() { authzkeeper.StoreKey, feegrant.StoreKey, icahosttypes.StoreKey, ibcfeetypes.StoreKey, tokenfactorytypes.StoreKey, feesharetypes.StoreKey, wasm.StoreKey, icacontrollertypes.StoreKey, ibchookstypes.StoreKey, packetforwardtypes.StoreKey, - icqtypes.StoreKey, + icqtypes.StoreKey, ibchost.SubModuleName, ) appKeepers.tkeys = sdk.NewTransientStoreKeys(paramstypes.TStoreKey) From af39cfd0e2582b07e8bf46d2f0c8869643f40268 Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Fri, 28 Apr 2023 17:00:21 -0500 Subject: [PATCH 044/131] Fix IBC-Hooks to match IBCv7 spec --- x/ibc-hooks/hooks.go | 7 +++--- x/ibc-hooks/ics4_middleware.go | 13 ++++++----- x/ibc-hooks/wasm_hook.go | 41 ++++++++++++++++++++++++++++++---- 3 files changed, 48 insertions(+), 13 deletions(-) diff --git a/x/ibc-hooks/hooks.go b/x/ibc-hooks/hooks.go index 1735a5af8..48e054b40 100644 --- a/x/ibc-hooks/hooks.go +++ b/x/ibc-hooks/hooks.go @@ -6,6 +6,7 @@ import ( capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" // ibc-go + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" ) @@ -112,13 +113,13 @@ type OnTimeoutPacketAfterHooks interface { // SendPacket Hooks type SendPacketOverrideHooks interface { - SendPacketOverride(i ICS4Middleware, ctx sdk.Context, chanCap *capabilitytypes.Capability, packet ibcexported.PacketI) error + SendPacketOverride(i ICS4Middleware, ctx sdk.Context, chanCap *capabilitytypes.Capability, sourcePort string, sourceChannel string, timeoutHeight clienttypes.Height, timeoutTimestamp uint64, data []byte) (uint64, error) } type SendPacketBeforeHooks interface { - SendPacketBeforeHook(ctx sdk.Context, chanCap *capabilitytypes.Capability, packet ibcexported.PacketI) + SendPacketBeforeHook(ctx sdk.Context, chanCap *capabilitytypes.Capability, sourcePort string, sourceChannel string, timeoutHeight clienttypes.Height, timeoutTimestamp uint64, data []byte) } type SendPacketAfterHooks interface { - SendPacketAfterHook(ctx sdk.Context, chanCap *capabilitytypes.Capability, packet ibcexported.PacketI, err error) + SendPacketAfterHook(ctx sdk.Context, chanCap *capabilitytypes.Capability, sourcePort string, sourceChannel string, timeoutHeight clienttypes.Height, timeoutTimestamp uint64, data []byte, err error) } // WriteAcknowledgement Hooks diff --git a/x/ibc-hooks/ics4_middleware.go b/x/ibc-hooks/ics4_middleware.go index 8e4f7307c..038ccd1d6 100644 --- a/x/ibc-hooks/ics4_middleware.go +++ b/x/ibc-hooks/ics4_middleware.go @@ -6,6 +6,7 @@ import ( capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" // ibc-go + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" porttypes "github.com/cosmos/ibc-go/v7/modules/core/05-port/types" ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" ) @@ -26,22 +27,22 @@ func NewICS4Middleware(channel porttypes.ICS4Wrapper, hooks Hooks) ICS4Middlewar } } -func (i ICS4Middleware) SendPacket(ctx sdk.Context, channelCap *capabilitytypes.Capability, packet ibcexported.PacketI) error { +func (i ICS4Middleware) SendPacket(ctx sdk.Context, channelCap *capabilitytypes.Capability, sourcePort string, sourceChannel string, timeoutHeight clienttypes.Height, timeoutTimestamp uint64, data []byte) (sequence uint64, err error) { if hook, ok := i.Hooks.(SendPacketOverrideHooks); ok { - return hook.SendPacketOverride(i, ctx, channelCap, packet) + return hook.SendPacketOverride(i, ctx, channelCap, sourceChannel, sourceChannel, timeoutHeight, timeoutTimestamp, data) } if hook, ok := i.Hooks.(SendPacketBeforeHooks); ok { - hook.SendPacketBeforeHook(ctx, channelCap, packet) + hook.SendPacketBeforeHook(ctx, channelCap, sourceChannel, sourceChannel, timeoutHeight, timeoutTimestamp, data) } - err := i.channel.SendPacket(ctx, channelCap, packet) + seq, err := i.channel.SendPacket(ctx, channelCap, sourceChannel, sourceChannel, timeoutHeight, timeoutTimestamp, data) if hook, ok := i.Hooks.(SendPacketAfterHooks); ok { - hook.SendPacketAfterHook(ctx, channelCap, packet, err) + hook.SendPacketAfterHook(ctx, channelCap, sourceChannel, sourceChannel, timeoutHeight, timeoutTimestamp, data, err) } - return err + return seq, err } func (i ICS4Middleware) WriteAcknowledgement(ctx sdk.Context, chanCap *capabilitytypes.Capability, packet ibcexported.PacketI, ack ibcexported.Acknowledgement) error { diff --git a/x/ibc-hooks/wasm_hook.go b/x/ibc-hooks/wasm_hook.go index e941f7808..be38c953c 100644 --- a/x/ibc-hooks/wasm_hook.go +++ b/x/ibc-hooks/wasm_hook.go @@ -15,6 +15,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" transfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" @@ -227,19 +228,45 @@ func ValidateAndParseMemo(memo string, receiver string) (isWasmRouted bool, cont } func (h WasmHooks) SendPacketOverride(i ICS4Middleware, ctx sdk.Context, chanCap *capabilitytypes.Capability, packet ibcexported.PacketI) error { + height := clienttypes.Height{ + RevisionNumber: packet.GetTimeoutHeight().GetRevisionHeight(), + RevisionHeight: packet.GetTimeoutHeight().GetRevisionHeight(), + } + concretePacket, ok := packet.(channeltypes.Packet) if !ok { - return i.channel.SendPacket(ctx, chanCap, packet) // continue + if _, err := i.channel.SendPacket(ctx, chanCap, + packet.GetSourcePort(), + packet.GetSourceChannel(), + height, + packet.GetTimeoutTimestamp(), + packet.GetData()); err != nil { + return err + } } isIcs20, data := isIcs20Packet(concretePacket) if !isIcs20 { - return i.channel.SendPacket(ctx, chanCap, packet) // continue + if _, err := i.channel.SendPacket(ctx, chanCap, + packet.GetSourcePort(), + packet.GetSourceChannel(), + height, + packet.GetTimeoutTimestamp(), + packet.GetData()); err != nil { + return err + } } isCallbackRouted, metadata := jsonStringHasKey(data.GetMemo(), types.IBCCallbackKey) if !isCallbackRouted { - return i.channel.SendPacket(ctx, chanCap, packet) // continue + if _, err := i.channel.SendPacket(ctx, chanCap, + packet.GetSourcePort(), + packet.GetSourceChannel(), + height, + packet.GetTimeoutTimestamp(), + packet.GetData()); err != nil { + return err + } } // We remove the callback metadata from the memo as it has already been processed. @@ -276,7 +303,13 @@ func (h WasmHooks) SendPacketOverride(i ICS4Middleware, ctx sdk.Context, chanCap TimeoutHeight: concretePacket.TimeoutHeight, } - err = i.channel.SendPacket(ctx, chanCap, packetWithoutCallbackMemo) + _, err = i.channel.SendPacket(ctx, chanCap, + packetWithoutCallbackMemo.GetSourcePort(), + packetWithoutCallbackMemo.GetSourceChannel(), + height, + packetWithoutCallbackMemo.GetTimeoutTimestamp(), + packetWithoutCallbackMemo.GetData(), + ) if err != nil { return err } From 2f0866e07cf3eaff75f6170ebbb5eff0965a2806 Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Fri, 28 Apr 2023 17:19:17 -0500 Subject: [PATCH 045/131] Fix 99% of tokenfactory module --- app/modules.go | 2 +- x/tokenfactory/bindings/custom_msg_test.go | 80 +++++++++---------- x/tokenfactory/bindings/custom_query_test.go | 10 +-- x/tokenfactory/bindings/helpers_test.go | 30 +++---- x/tokenfactory/bindings/validate_msg_test.go | 42 +++++----- .../bindings/validate_queries_test.go | 8 +- x/tokenfactory/client/cli/tx.go | 50 ++++++++++-- x/tokenfactory/keeper/admins_test.go | 18 ++--- x/tokenfactory/keeper/createdenom_test.go | 10 +-- x/tokenfactory/keeper/genesis_test.go | 12 +-- x/tokenfactory/keeper/keeper_test.go | 12 +-- x/tokenfactory/keeper/msg_server_test.go | 2 +- 12 files changed, 155 insertions(+), 121 deletions(-) diff --git a/app/modules.go b/app/modules.go index bfe11487d..e9c5ee927 100644 --- a/app/modules.go +++ b/app/modules.go @@ -137,7 +137,7 @@ func appModules( authzmodule.NewAppModule(appCodec, app.AuthzKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry), transfer.NewAppModule(app.TransferKeeper), ibcfee.NewAppModule(app.IBCFeeKeeper), - tokenfactory.NewAppModule(app.TokenFactoryKeeper, app.AccountKeeper, app.BankKeeper), + tokenfactory.NewAppModule(app.AppKeepers.TokenFactoryKeeper, app.AccountKeeper, app.BankKeeper), globalfee.NewAppModule(app.GetSubspace(globalfee.ModuleName)), feeshare.NewAppModule(app.FeeShareKeeper, app.AccountKeeper), wasm.NewAppModule(appCodec, &app.WasmKeeper, app.StakingKeeper, app.AccountKeeper, app.BankKeeper), diff --git a/x/tokenfactory/bindings/custom_msg_test.go b/x/tokenfactory/bindings/custom_msg_test.go index 7535389e0..3c37c85cd 100644 --- a/x/tokenfactory/bindings/custom_msg_test.go +++ b/x/tokenfactory/bindings/custom_msg_test.go @@ -18,20 +18,20 @@ import ( func TestCreateDenomMsg(t *testing.T) { creator := RandomAccountAddress() - osmosis, ctx := SetupCustomApp(t, creator) + junoapp, ctx := SetupCustomApp(t, creator) lucky := RandomAccountAddress() - reflect := instantiateReflectContract(t, ctx, osmosis, lucky) + reflect := instantiateReflectContract(t, ctx, junoapp, lucky) require.NotEmpty(t, reflect) // Fund reflect contract with 100 base denom creation fees reflectAmount := sdk.NewCoins(sdk.NewCoin(types.DefaultParams().DenomCreationFee[0].Denom, types.DefaultParams().DenomCreationFee[0].Amount.MulRaw(100))) - fundAccount(t, ctx, osmosis, reflect, reflectAmount) + fundAccount(t, ctx, junoapp, reflect, reflectAmount) msg := bindings.TokenMsg{CreateDenom: &bindings.CreateDenom{ Subdenom: "SUN", }} - err := executeCustom(t, ctx, osmosis, reflect, lucky, msg, sdk.Coin{}) + err := executeCustom(t, ctx, junoapp, reflect, lucky, msg, sdk.Coin{}) require.NoError(t, err) // query the denom and see if it matches @@ -42,32 +42,32 @@ func TestCreateDenomMsg(t *testing.T) { }, } resp := bindings.FullDenomResponse{} - queryCustom(t, ctx, osmosis, reflect, query, &resp) + queryCustom(t, ctx, junoapp, reflect, query, &resp) require.Equal(t, resp.Denom, fmt.Sprintf("factory/%s/SUN", reflect.String())) } func TestMintMsg(t *testing.T) { creator := RandomAccountAddress() - osmosis, ctx := SetupCustomApp(t, creator) + junoapp, ctx := SetupCustomApp(t, creator) lucky := RandomAccountAddress() - reflect := instantiateReflectContract(t, ctx, osmosis, lucky) + reflect := instantiateReflectContract(t, ctx, junoapp, lucky) require.NotEmpty(t, reflect) // Fund reflect contract with 100 base denom creation fees reflectAmount := sdk.NewCoins(sdk.NewCoin(types.DefaultParams().DenomCreationFee[0].Denom, types.DefaultParams().DenomCreationFee[0].Amount.MulRaw(100))) - fundAccount(t, ctx, osmosis, reflect, reflectAmount) + fundAccount(t, ctx, junoapp, reflect, reflectAmount) // lucky was broke - balances := osmosis.BankKeeper.GetAllBalances(ctx, lucky) + balances := junoapp.AppKeepers.BankKeeper.GetAllBalances(ctx, lucky) require.Empty(t, balances) // Create denom for minting msg := bindings.TokenMsg{CreateDenom: &bindings.CreateDenom{ Subdenom: "SUN", }} - err := executeCustom(t, ctx, osmosis, reflect, lucky, msg, sdk.Coin{}) + err := executeCustom(t, ctx, junoapp, reflect, lucky, msg, sdk.Coin{}) require.NoError(t, err) sunDenom := fmt.Sprintf("factory/%s/%s", reflect.String(), msg.CreateDenom.Subdenom) @@ -78,10 +78,10 @@ func TestMintMsg(t *testing.T) { Amount: amount, MintToAddress: lucky.String(), }} - err = executeCustom(t, ctx, osmosis, reflect, lucky, msg, sdk.Coin{}) + err = executeCustom(t, ctx, junoapp, reflect, lucky, msg, sdk.Coin{}) require.NoError(t, err) - balances = osmosis.BankKeeper.GetAllBalances(ctx, lucky) + balances = junoapp.AppKeepers.BankKeeper.GetAllBalances(ctx, lucky) require.Len(t, balances, 1) coin := balances[0] require.Equal(t, amount, coin.Amount) @@ -95,15 +95,15 @@ func TestMintMsg(t *testing.T) { }, } resp := bindings.FullDenomResponse{} - queryCustom(t, ctx, osmosis, reflect, query, &resp) + queryCustom(t, ctx, junoapp, reflect, query, &resp) require.Equal(t, resp.Denom, coin.Denom) // mint the same denom again - err = executeCustom(t, ctx, osmosis, reflect, lucky, msg, sdk.Coin{}) + err = executeCustom(t, ctx, junoapp, reflect, lucky, msg, sdk.Coin{}) require.NoError(t, err) - balances = osmosis.BankKeeper.GetAllBalances(ctx, lucky) + balances = junoapp.AppKeepers.BankKeeper.GetAllBalances(ctx, lucky) require.Len(t, balances, 1) coin = balances[0] require.Equal(t, amount.MulRaw(2), coin.Amount) @@ -117,7 +117,7 @@ func TestMintMsg(t *testing.T) { }, } resp = bindings.FullDenomResponse{} - queryCustom(t, ctx, osmosis, reflect, query, &resp) + queryCustom(t, ctx, junoapp, reflect, query, &resp) require.Equal(t, resp.Denom, coin.Denom) @@ -126,7 +126,7 @@ func TestMintMsg(t *testing.T) { msg = bindings.TokenMsg{CreateDenom: &bindings.CreateDenom{ Subdenom: "MOON", }} - err = executeCustom(t, ctx, osmosis, reflect, lucky, msg, sdk.Coin{}) + err = executeCustom(t, ctx, junoapp, reflect, lucky, msg, sdk.Coin{}) require.NoError(t, err) moonDenom := fmt.Sprintf("factory/%s/%s", reflect.String(), msg.CreateDenom.Subdenom) @@ -136,10 +136,10 @@ func TestMintMsg(t *testing.T) { Amount: amount, MintToAddress: lucky.String(), }} - err = executeCustom(t, ctx, osmosis, reflect, lucky, msg, sdk.Coin{}) + err = executeCustom(t, ctx, junoapp, reflect, lucky, msg, sdk.Coin{}) require.NoError(t, err) - balances = osmosis.BankKeeper.GetAllBalances(ctx, lucky) + balances = junoapp.AppKeepers.BankKeeper.GetAllBalances(ctx, lucky) require.Len(t, balances, 2) coin = balances[0] require.Equal(t, amount, coin.Amount) @@ -153,7 +153,7 @@ func TestMintMsg(t *testing.T) { }, } resp = bindings.FullDenomResponse{} - queryCustom(t, ctx, osmosis, reflect, query, &resp) + queryCustom(t, ctx, junoapp, reflect, query, &resp) require.Equal(t, resp.Denom, coin.Denom) @@ -170,33 +170,33 @@ func TestMintMsg(t *testing.T) { }, } resp = bindings.FullDenomResponse{} - queryCustom(t, ctx, osmosis, reflect, query, &resp) + queryCustom(t, ctx, junoapp, reflect, query, &resp) require.Equal(t, resp.Denom, coin.Denom) } func TestForceTransfer(t *testing.T) { creator := RandomAccountAddress() - osmosis, ctx := SetupCustomApp(t, creator) + junoapp, ctx := SetupCustomApp(t, creator) lucky := RandomAccountAddress() rcpt := RandomAccountAddress() - reflect := instantiateReflectContract(t, ctx, osmosis, lucky) + reflect := instantiateReflectContract(t, ctx, junoapp, lucky) require.NotEmpty(t, reflect) // Fund reflect contract with 100 base denom creation fees reflectAmount := sdk.NewCoins(sdk.NewCoin(types.DefaultParams().DenomCreationFee[0].Denom, types.DefaultParams().DenomCreationFee[0].Amount.MulRaw(100))) - fundAccount(t, ctx, osmosis, reflect, reflectAmount) + fundAccount(t, ctx, junoapp, reflect, reflectAmount) // lucky was broke - balances := osmosis.BankKeeper.GetAllBalances(ctx, lucky) + balances := junoapp.AppKeepers.BankKeeper.GetAllBalances(ctx, lucky) require.Empty(t, balances) // Create denom for minting msg := bindings.TokenMsg{CreateDenom: &bindings.CreateDenom{ Subdenom: "SUN", }} - err := executeCustom(t, ctx, osmosis, reflect, lucky, msg, sdk.Coin{}) + err := executeCustom(t, ctx, junoapp, reflect, lucky, msg, sdk.Coin{}) require.NoError(t, err) sunDenom := fmt.Sprintf("factory/%s/%s", reflect.String(), msg.CreateDenom.Subdenom) @@ -209,7 +209,7 @@ func TestForceTransfer(t *testing.T) { Amount: amount, MintToAddress: lucky.String(), }} - err = executeCustom(t, ctx, osmosis, reflect, lucky, msg, sdk.Coin{}) + err = executeCustom(t, ctx, junoapp, reflect, lucky, msg, sdk.Coin{}) require.NoError(t, err) // Force move 100 tokens from lucky to rcpt @@ -219,11 +219,11 @@ func TestForceTransfer(t *testing.T) { FromAddress: lucky.String(), ToAddress: rcpt.String(), }} - err = executeCustom(t, ctx, osmosis, reflect, lucky, msg, sdk.Coin{}) + err = executeCustom(t, ctx, junoapp, reflect, lucky, msg, sdk.Coin{}) require.NoError(t, err) // check the balance of rcpt - balances = osmosis.BankKeeper.GetAllBalances(ctx, rcpt) + balances = junoapp.AppKeepers.BankKeeper.GetAllBalances(ctx, rcpt) require.Len(t, balances, 1) coin := balances[0] require.Equal(t, sdk.NewInt(100), coin.Amount) @@ -231,25 +231,25 @@ func TestForceTransfer(t *testing.T) { func TestBurnMsg(t *testing.T) { creator := RandomAccountAddress() - osmosis, ctx := SetupCustomApp(t, creator) + junoapp, ctx := SetupCustomApp(t, creator) lucky := RandomAccountAddress() - reflect := instantiateReflectContract(t, ctx, osmosis, lucky) + reflect := instantiateReflectContract(t, ctx, junoapp, lucky) require.NotEmpty(t, reflect) // Fund reflect contract with 100 base denom creation fees reflectAmount := sdk.NewCoins(sdk.NewCoin(types.DefaultParams().DenomCreationFee[0].Denom, types.DefaultParams().DenomCreationFee[0].Amount.MulRaw(100))) - fundAccount(t, ctx, osmosis, reflect, reflectAmount) + fundAccount(t, ctx, junoapp, reflect, reflectAmount) // lucky was broke - balances := osmosis.BankKeeper.GetAllBalances(ctx, lucky) + balances := junoapp.AppKeepers.BankKeeper.GetAllBalances(ctx, lucky) require.Empty(t, balances) // Create denom for minting msg := bindings.TokenMsg{CreateDenom: &bindings.CreateDenom{ Subdenom: "SUN", }} - err := executeCustom(t, ctx, osmosis, reflect, lucky, msg, sdk.Coin{}) + err := executeCustom(t, ctx, junoapp, reflect, lucky, msg, sdk.Coin{}) require.NoError(t, err) sunDenom := fmt.Sprintf("factory/%s/%s", reflect.String(), msg.CreateDenom.Subdenom) @@ -261,7 +261,7 @@ func TestBurnMsg(t *testing.T) { Amount: amount, MintToAddress: lucky.String(), }} - err = executeCustom(t, ctx, osmosis, reflect, lucky, msg, sdk.Coin{}) + err = executeCustom(t, ctx, junoapp, reflect, lucky, msg, sdk.Coin{}) require.NoError(t, err) // can burn from different address with burnFrom @@ -272,12 +272,12 @@ func TestBurnMsg(t *testing.T) { Amount: amt, BurnFromAddress: lucky.String(), }} - err = executeCustom(t, ctx, osmosis, reflect, lucky, msg, sdk.Coin{}) + err = executeCustom(t, ctx, junoapp, reflect, lucky, msg, sdk.Coin{}) require.NoError(t, err) // lucky needs to send balance to reflect contract to burn it - luckyBalance := osmosis.BankKeeper.GetAllBalances(ctx, lucky) - err = osmosis.BankKeeper.SendCoins(ctx, lucky, reflect, luckyBalance) + luckyBalance := junoapp.AppKeepers.BankKeeper.GetAllBalances(ctx, lucky) + err = junoapp.AppKeepers.BankKeeper.SendCoins(ctx, lucky, reflect, luckyBalance) require.NoError(t, err) msg = bindings.TokenMsg{BurnTokens: &bindings.BurnTokens{ @@ -285,7 +285,7 @@ func TestBurnMsg(t *testing.T) { Amount: amount.Abs().Sub(sdk.NewInt(1)), BurnFromAddress: reflect.String(), }} - err = executeCustom(t, ctx, osmosis, reflect, lucky, msg, sdk.Coin{}) + err = executeCustom(t, ctx, junoapp, reflect, lucky, msg, sdk.Coin{}) require.NoError(t, err) } @@ -325,7 +325,7 @@ func executeCustom(t *testing.T, ctx sdk.Context, junoapp *app.App, contract sdk coins = sdk.Coins{funds} } - contractKeeper := keeper.NewDefaultPermissionKeeper(junoapp.ModuleManager) + contractKeeper := keeper.NewDefaultPermissionKeeper(junoapp.AppKeepers.WasmKeeper) _, err = contractKeeper.Execute(ctx, contract, sender, reflectBz, coins) return err } diff --git a/x/tokenfactory/bindings/custom_query_test.go b/x/tokenfactory/bindings/custom_query_test.go index 56a0cbc0f..3d60a32df 100644 --- a/x/tokenfactory/bindings/custom_query_test.go +++ b/x/tokenfactory/bindings/custom_query_test.go @@ -16,9 +16,9 @@ import ( func TestQueryFullDenom(t *testing.T) { actor := RandomAccountAddress() - tokenz, ctx := SetupCustomApp(t, actor) + junoapp, ctx := SetupCustomApp(t, actor) - reflect := instantiateReflectContract(t, ctx, tokenz, actor) + reflect := instantiateReflectContract(t, ctx, junoapp, actor) require.NotEmpty(t, reflect) // query full denom @@ -29,7 +29,7 @@ func TestQueryFullDenom(t *testing.T) { }, } resp := bindings.FullDenomResponse{} - queryCustom(t, ctx, tokenz, reflect, query, &resp) + queryCustom(t, ctx, junoapp, reflect, query, &resp) expected := fmt.Sprintf("factory/%s/ustart", reflect.String()) require.EqualValues(t, expected, resp.Denom) @@ -47,7 +47,7 @@ type ChainResponse struct { Data []byte `json:"data"` } -func queryCustom(t *testing.T, ctx sdk.Context, tokenz *app.TokenApp, contract sdk.AccAddress, request bindings.TokenQuery, response interface{}) { +func queryCustom(t *testing.T, ctx sdk.Context, junoapp *app.App, contract sdk.AccAddress, request bindings.TokenQuery, response interface{}) { wrapped := bindings.TokenFactoryQuery{ Token: &request, } @@ -64,7 +64,7 @@ func queryCustom(t *testing.T, ctx sdk.Context, tokenz *app.TokenApp, contract s require.NoError(t, err) fmt.Println(string(queryBz)) - resBz, err := tokenz.WasmKeeper.QuerySmart(ctx, contract, queryBz) + resBz, err := junoapp.AppKeepers.WasmKeeper.QuerySmart(ctx, contract, queryBz) require.NoError(t, err) var resp ChainResponse err = json.Unmarshal(resBz, &resp) diff --git a/x/tokenfactory/bindings/helpers_test.go b/x/tokenfactory/bindings/helpers_test.go index 969516642..c1136d72c 100644 --- a/x/tokenfactory/bindings/helpers_test.go +++ b/x/tokenfactory/bindings/helpers_test.go @@ -18,14 +18,14 @@ import ( "github.com/CosmosContracts/juno/v15/app" ) -func CreateTestInput() (*app.TokenApp, sdk.Context) { - osmosis := app.Setup(false) +func CreateTestInput(t *testing.T) (*app.App, sdk.Context) { + osmosis := app.Setup(t) ctx := osmosis.BaseApp.NewContext(false, tmproto.Header{Height: 1, ChainID: "osmosis-1", Time: time.Now().UTC()}) return osmosis, ctx } -func FundAccount(t *testing.T, ctx sdk.Context, osmosis *app.TokenApp, acct sdk.AccAddress) { - err := simapp.FundAccount(osmosis.BankKeeper, ctx, acct, sdk.NewCoins( +func FundAccount(t *testing.T, ctx sdk.Context, junoapp *app.App, acct sdk.AccAddress) { + err := simapp.FundAccount(junoapp.AppKeepers.BankKeeper, ctx, acct, sdk.NewCoins( sdk.NewCoin("uosmo", sdk.NewInt(10000000000)), )) require.NoError(t, err) @@ -48,20 +48,20 @@ func RandomBech32AccountAddress() string { return RandomAccountAddress().String() } -func storeReflectCode(t *testing.T, ctx sdk.Context, tokenz *app.TokenApp, addr sdk.AccAddress) uint64 { +func storeReflectCode(t *testing.T, ctx sdk.Context, junoapp *app.App, addr sdk.AccAddress) uint64 { wasmCode, err := os.ReadFile("./testdata/token_reflect.wasm") require.NoError(t, err) - contractKeeper := keeper.NewDefaultPermissionKeeper(tokenz.WasmKeeper) + contractKeeper := keeper.NewDefaultPermissionKeeper(junoapp.AppKeepers.WasmKeeper) codeID, _, err := contractKeeper.Create(ctx, addr, wasmCode, nil) require.NoError(t, err) return codeID } -func instantiateReflectContract(t *testing.T, ctx sdk.Context, tokenz *app.TokenApp, funder sdk.AccAddress) sdk.AccAddress { +func instantiateReflectContract(t *testing.T, ctx sdk.Context, junoapp *app.App, funder sdk.AccAddress) sdk.AccAddress { initMsgBz := []byte("{}") - contractKeeper := keeper.NewDefaultPermissionKeeper(tokenz.WasmKeeper) + contractKeeper := keeper.NewDefaultPermissionKeeper(junoapp.AppKeepers.WasmKeeper) codeID := uint64(1) addr, _, err := contractKeeper.Instantiate(ctx, codeID, funder, funder, initMsgBz, "demo contract", nil) require.NoError(t, err) @@ -69,9 +69,9 @@ func instantiateReflectContract(t *testing.T, ctx sdk.Context, tokenz *app.Token return addr } -func fundAccount(t *testing.T, ctx sdk.Context, tokenz *app.TokenApp, addr sdk.AccAddress, coins sdk.Coins) { +func fundAccount(t *testing.T, ctx sdk.Context, junoapp *app.App, addr sdk.AccAddress, coins sdk.Coins) { err := simapp.FundAccount( - tokenz.BankKeeper, + junoapp.AppKeepers.BankKeeper, ctx, addr, coins, @@ -79,14 +79,14 @@ func fundAccount(t *testing.T, ctx sdk.Context, tokenz *app.TokenApp, addr sdk.A require.NoError(t, err) } -func SetupCustomApp(t *testing.T, addr sdk.AccAddress) (*app.TokenApp, sdk.Context) { - tokenz, ctx := CreateTestInput() - wasmKeeper := tokenz.WasmKeeper +func SetupCustomApp(t *testing.T, addr sdk.AccAddress) (*app.App, sdk.Context) { + junoApp, ctx := CreateTestInput(t) + wasmKeeper := junoApp.AppKeepers.WasmKeeper - storeReflectCode(t, ctx, tokenz, addr) + storeReflectCode(t, ctx, junoApp, addr) cInfo := wasmKeeper.GetCodeInfo(ctx, 1) require.NotNil(t, cInfo) - return tokenz, ctx + return junoApp, ctx } diff --git a/x/tokenfactory/bindings/validate_msg_test.go b/x/tokenfactory/bindings/validate_msg_test.go index 430dc9da6..752ce9642 100644 --- a/x/tokenfactory/bindings/validate_msg_test.go +++ b/x/tokenfactory/bindings/validate_msg_test.go @@ -15,11 +15,11 @@ import ( func TestCreateDenom(t *testing.T) { actor := RandomAccountAddress() - tokenz, ctx := SetupCustomApp(t, actor) + junoapp, ctx := SetupCustomApp(t, actor) // Fund actor with 100 base denom creation fees actorAmount := sdk.NewCoins(sdk.NewCoin(types.DefaultParams().DenomCreationFee[0].Denom, types.DefaultParams().DenomCreationFee[0].Amount.MulRaw(100))) - fundAccount(t, ctx, tokenz, actor, actorAmount) + fundAccount(t, ctx, junoapp, actor, actorAmount) specs := map[string]struct { createDenom *bindings.CreateDenom @@ -50,7 +50,7 @@ func TestCreateDenom(t *testing.T) { for name, spec := range specs { t.Run(name, func(t *testing.T) { // when - _, gotErr := wasmbinding.PerformCreateDenom(&tokenz.TokenFactoryKeeper, &tokenz.BankKeeper, ctx, actor, spec.createDenom) + _, gotErr := wasmbinding.PerformCreateDenom(&junoapp.AppKeepers.TokenFactoryKeeper, &junoapp.AppKeepers.BankKeeper, ctx, actor, spec.createDenom) // then if spec.expErr { require.Error(t, gotErr) @@ -142,18 +142,18 @@ func TestChangeAdmin(t *testing.T) { for name, spec := range specs { t.Run(name, func(t *testing.T) { // Setup - tokenz, ctx := SetupCustomApp(t, tokenCreator) + junoapp, ctx := SetupCustomApp(t, tokenCreator) // Fund actor with 100 base denom creation fees actorAmount := sdk.NewCoins(sdk.NewCoin(types.DefaultParams().DenomCreationFee[0].Denom, types.DefaultParams().DenomCreationFee[0].Amount.MulRaw(100))) - fundAccount(t, ctx, tokenz, tokenCreator, actorAmount) + fundAccount(t, ctx, junoapp, tokenCreator, actorAmount) - _, err := wasmbinding.PerformCreateDenom(&tokenz.TokenFactoryKeeper, &tokenz.BankKeeper, ctx, tokenCreator, &bindings.CreateDenom{ + _, err := wasmbinding.PerformCreateDenom(&junoapp.AppKeepers.TokenFactoryKeeper, &junoapp.AppKeepers.BankKeeper, ctx, tokenCreator, &bindings.CreateDenom{ Subdenom: validDenom, }) require.NoError(t, err) - err = wasmbinding.ChangeAdmin(&tokenz.TokenFactoryKeeper, ctx, spec.actor, spec.changeAdmin) + err = wasmbinding.ChangeAdmin(&junoapp.AppKeepers.TokenFactoryKeeper, ctx, spec.actor, spec.changeAdmin) if len(spec.expErrMsg) > 0 { require.Error(t, err) actualErrMsg := err.Error() @@ -167,23 +167,23 @@ func TestChangeAdmin(t *testing.T) { func TestMint(t *testing.T) { creator := RandomAccountAddress() - tokenz, ctx := SetupCustomApp(t, creator) + junoapp, ctx := SetupCustomApp(t, creator) // Fund actor with 100 base denom creation fees tokenCreationFeeAmt := sdk.NewCoins(sdk.NewCoin(types.DefaultParams().DenomCreationFee[0].Denom, types.DefaultParams().DenomCreationFee[0].Amount.MulRaw(100))) - fundAccount(t, ctx, tokenz, creator, tokenCreationFeeAmt) + fundAccount(t, ctx, junoapp, creator, tokenCreationFeeAmt) // Create denoms for valid mint tests validDenom := bindings.CreateDenom{ Subdenom: "MOON", } - _, err := wasmbinding.PerformCreateDenom(&tokenz.TokenFactoryKeeper, &tokenz.BankKeeper, ctx, creator, &validDenom) + _, err := wasmbinding.PerformCreateDenom(&junoapp.AppKeepers.TokenFactoryKeeper, &junoapp.AppKeepers.BankKeeper, ctx, creator, &validDenom) require.NoError(t, err) emptyDenom := bindings.CreateDenom{ Subdenom: "", } - _, err = wasmbinding.PerformCreateDenom(&tokenz.TokenFactoryKeeper, &tokenz.BankKeeper, ctx, creator, &emptyDenom) + _, err = wasmbinding.PerformCreateDenom(&junoapp.AppKeepers.TokenFactoryKeeper, &junoapp.AppKeepers.BankKeeper, ctx, creator, &emptyDenom) require.NoError(t, err) validDenomStr := fmt.Sprintf("factory/%s/%s", creator.String(), validDenom.Subdenom) @@ -192,7 +192,7 @@ func TestMint(t *testing.T) { lucky := RandomAccountAddress() // lucky was broke - balances := tokenz.BankKeeper.GetAllBalances(ctx, lucky) + balances := junoapp.AppKeepers.BankKeeper.GetAllBalances(ctx, lucky) require.Empty(t, balances) amount, ok := sdk.NewIntFromString("8080") @@ -273,7 +273,7 @@ func TestMint(t *testing.T) { for name, spec := range specs { t.Run(name, func(t *testing.T) { // when - gotErr := wasmbinding.PerformMint(&tokenz.TokenFactoryKeeper, &tokenz.BankKeeper, ctx, creator, spec.mint) + gotErr := wasmbinding.PerformMint(&junoapp.AppKeepers.TokenFactoryKeeper, &junoapp.AppKeepers.BankKeeper, ctx, creator, spec.mint) // then if spec.expErr { require.Error(t, gotErr) @@ -286,29 +286,29 @@ func TestMint(t *testing.T) { func TestBurn(t *testing.T) { creator := RandomAccountAddress() - tokenz, ctx := SetupCustomApp(t, creator) + junoapp, ctx := SetupCustomApp(t, creator) // Fund actor with 100 base denom creation fees tokenCreationFeeAmt := sdk.NewCoins(sdk.NewCoin(types.DefaultParams().DenomCreationFee[0].Denom, types.DefaultParams().DenomCreationFee[0].Amount.MulRaw(100))) - fundAccount(t, ctx, tokenz, creator, tokenCreationFeeAmt) + fundAccount(t, ctx, junoapp, creator, tokenCreationFeeAmt) // Create denoms for valid burn tests validDenom := bindings.CreateDenom{ Subdenom: "MOON", } - _, err := wasmbinding.PerformCreateDenom(&tokenz.TokenFactoryKeeper, &tokenz.BankKeeper, ctx, creator, &validDenom) + _, err := wasmbinding.PerformCreateDenom(&junoapp.AppKeepers.TokenFactoryKeeper, &junoapp.AppKeepers.BankKeeper, ctx, creator, &validDenom) require.NoError(t, err) emptyDenom := bindings.CreateDenom{ Subdenom: "", } - _, err = wasmbinding.PerformCreateDenom(&tokenz.TokenFactoryKeeper, &tokenz.BankKeeper, ctx, creator, &emptyDenom) + _, err = wasmbinding.PerformCreateDenom(&junoapp.AppKeepers.TokenFactoryKeeper, &junoapp.AppKeepers.BankKeeper, ctx, creator, &emptyDenom) require.NoError(t, err) lucky := RandomAccountAddress() // lucky was broke - balances := tokenz.BankKeeper.GetAllBalances(ctx, lucky) + balances := junoapp.AppKeepers.BankKeeper.GetAllBalances(ctx, lucky) require.Empty(t, balances) validDenomStr := fmt.Sprintf("factory/%s/%s", creator.String(), validDenom.Subdenom) @@ -390,7 +390,7 @@ func TestBurn(t *testing.T) { Amount: mintAmount, MintToAddress: creator.String(), } - err := wasmbinding.PerformMint(&tokenz.TokenFactoryKeeper, &tokenz.BankKeeper, ctx, creator, mintBinding) + err := wasmbinding.PerformMint(&junoapp.AppKeepers.TokenFactoryKeeper, &junoapp.AppKeepers.BankKeeper, ctx, creator, mintBinding) require.NoError(t, err) emptyDenomMintBinding := &bindings.MintTokens{ @@ -398,11 +398,11 @@ func TestBurn(t *testing.T) { Amount: mintAmount, MintToAddress: creator.String(), } - err = wasmbinding.PerformMint(&tokenz.TokenFactoryKeeper, &tokenz.BankKeeper, ctx, creator, emptyDenomMintBinding) + err = wasmbinding.PerformMint(&junoapp.AppKeepers.TokenFactoryKeeper, &junoapp.AppKeepers.BankKeeper, ctx, creator, emptyDenomMintBinding) require.NoError(t, err) // when - gotErr := wasmbinding.PerformBurn(&tokenz.TokenFactoryKeeper, ctx, creator, spec.burn) + gotErr := wasmbinding.PerformBurn(&junoapp.AppKeepers.TokenFactoryKeeper, ctx, creator, spec.burn) // then if spec.expErr { require.Error(t, gotErr) diff --git a/x/tokenfactory/bindings/validate_queries_test.go b/x/tokenfactory/bindings/validate_queries_test.go index 5f0a4d9c2..2302b6d75 100644 --- a/x/tokenfactory/bindings/validate_queries_test.go +++ b/x/tokenfactory/bindings/validate_queries_test.go @@ -67,17 +67,17 @@ func TestDenomAdmin(t *testing.T) { app, ctx := SetupCustomApp(t, addr) // set token creation fee to zero to make testing easier - tfParams := app.TokenFactoryKeeper.GetParams(ctx) + tfParams := app.AppKeepers.TokenFactoryKeeper.GetParams(ctx) tfParams.DenomCreationFee = sdk.NewCoins() - app.TokenFactoryKeeper.SetParams(ctx, tfParams) + app.AppKeepers.TokenFactoryKeeper.SetParams(ctx, tfParams) // create a subdenom via the token factory admin := sdk.AccAddress([]byte("addr1_______________")) - tfDenom, err := app.TokenFactoryKeeper.CreateDenom(ctx, admin.String(), "subdenom") + tfDenom, err := app.AppKeepers.TokenFactoryKeeper.CreateDenom(ctx, admin.String(), "subdenom") require.NoError(t, err) require.NotEmpty(t, tfDenom) - queryPlugin := wasmbinding.NewQueryPlugin(&app.BankKeeper, &app.TokenFactoryKeeper) + queryPlugin := wasmbinding.NewQueryPlugin(&app.AppKeepers.BankKeeper, &app.AppKeepers.TokenFactoryKeeper) testCases := []struct { name string diff --git a/x/tokenfactory/client/cli/tx.go b/x/tokenfactory/client/cli/tx.go index 10acf32e5..10057d860 100644 --- a/x/tokenfactory/client/cli/tx.go +++ b/x/tokenfactory/client/cli/tx.go @@ -52,7 +52,12 @@ func NewCreateDenomCmd() *cobra.Command { return err } - txf := tx.NewFactoryCLI(clientCtx, cmd.Flags()).WithTxConfig(clientCtx.TxConfig).WithAccountRetriever(clientCtx.AccountRetriever) + txf, err := tx.NewFactoryCLI(clientCtx, cmd.Flags()) + if err != nil { + return err + } + + txf = txf.WithTxConfig(clientCtx.TxConfig).WithAccountRetriever(clientCtx.AccountRetriever) msg := types.NewMsgCreateDenom( clientCtx.GetFromAddress().String(), @@ -79,7 +84,12 @@ func NewMintCmd() *cobra.Command { return err } - txf := tx.NewFactoryCLI(clientCtx, cmd.Flags()).WithTxConfig(clientCtx.TxConfig).WithAccountRetriever(clientCtx.AccountRetriever) + txf, err := tx.NewFactoryCLI(clientCtx, cmd.Flags()) + if err != nil { + return err + } + + txf = txf.WithTxConfig(clientCtx.TxConfig).WithAccountRetriever(clientCtx.AccountRetriever) amount, err := sdk.ParseCoinNormalized(args[0]) if err != nil { @@ -111,7 +121,11 @@ func NewMintToCmd() *cobra.Command { return err } - txf := tx.NewFactoryCLI(clientCtx, cmd.Flags()).WithTxConfig(clientCtx.TxConfig).WithAccountRetriever(clientCtx.AccountRetriever) + txf, err := tx.NewFactoryCLI(clientCtx, cmd.Flags()) + if err != nil { + return err + } + txf = txf.WithTxConfig(clientCtx.TxConfig).WithAccountRetriever(clientCtx.AccountRetriever) toAddr, err := sdk.AccAddressFromBech32(args[0]) if err != nil { @@ -149,7 +163,11 @@ func NewBurnCmd() *cobra.Command { return err } - txf := tx.NewFactoryCLI(clientCtx, cmd.Flags()).WithTxConfig(clientCtx.TxConfig).WithAccountRetriever(clientCtx.AccountRetriever) + txf, err := tx.NewFactoryCLI(clientCtx, cmd.Flags()) + if err != nil { + return err + } + txf = txf.WithTxConfig(clientCtx.TxConfig).WithAccountRetriever(clientCtx.AccountRetriever) amount, err := sdk.ParseCoinNormalized(args[0]) if err != nil { @@ -181,7 +199,11 @@ func NewBurnFromCmd() *cobra.Command { return err } - txf := tx.NewFactoryCLI(clientCtx, cmd.Flags()).WithTxConfig(clientCtx.TxConfig).WithAccountRetriever(clientCtx.AccountRetriever) + txf, err := tx.NewFactoryCLI(clientCtx, cmd.Flags()) + if err != nil { + return err + } + txf = txf.WithTxConfig(clientCtx.TxConfig).WithAccountRetriever(clientCtx.AccountRetriever) fromAddr, err := sdk.AccAddressFromBech32(args[0]) if err != nil { @@ -219,7 +241,11 @@ func NewForceTransferCmd() *cobra.Command { return err } - txf := tx.NewFactoryCLI(clientCtx, cmd.Flags()).WithTxConfig(clientCtx.TxConfig).WithAccountRetriever(clientCtx.AccountRetriever) + txf, err := tx.NewFactoryCLI(clientCtx, cmd.Flags()) + if err != nil { + return err + } + txf = txf.WithTxConfig(clientCtx.TxConfig).WithAccountRetriever(clientCtx.AccountRetriever) amount, err := sdk.ParseCoinNormalized(args[0]) if err != nil { @@ -253,7 +279,11 @@ func NewChangeAdminCmd() *cobra.Command { return err } - txf := tx.NewFactoryCLI(clientCtx, cmd.Flags()).WithTxConfig(clientCtx.TxConfig).WithAccountRetriever(clientCtx.AccountRetriever) + txf, err := tx.NewFactoryCLI(clientCtx, cmd.Flags()) + if err != nil { + return err + } + txf = txf.WithTxConfig(clientCtx.TxConfig).WithAccountRetriever(clientCtx.AccountRetriever) msg := types.NewMsgChangeAdmin( clientCtx.GetFromAddress().String(), @@ -281,7 +311,11 @@ func NewModifyDenomMetadataCmd() *cobra.Command { return err } - txf := tx.NewFactoryCLI(clientCtx, cmd.Flags()).WithTxConfig(clientCtx.TxConfig).WithAccountRetriever(clientCtx.AccountRetriever) + txf, err := tx.NewFactoryCLI(clientCtx, cmd.Flags()) + if err != nil { + return err + } + txf = txf.WithTxConfig(clientCtx.TxConfig).WithAccountRetriever(clientCtx.AccountRetriever) fullDenom, ticker, desc := args[0], strings.ToUpper(args[1]), args[2] diff --git a/x/tokenfactory/keeper/admins_test.go b/x/tokenfactory/keeper/admins_test.go index b5436bf32..72c8068bb 100644 --- a/x/tokenfactory/keeper/admins_test.go +++ b/x/tokenfactory/keeper/admins_test.go @@ -13,7 +13,7 @@ func (suite *KeeperTestSuite) TestAdminMsgs() { addr0bal := int64(0) addr1bal := int64(0) - bankKeeper := suite.App.BankKeeper + bankKeeper := suite.App.AppKeepers.BankKeeper suite.CreateDefaultDenom() // Make sure that the admin is set correctly @@ -33,15 +33,15 @@ func (suite *KeeperTestSuite) TestAdminMsgs() { _, err = suite.msgServer.Mint(sdk.WrapSDKContext(suite.Ctx), types.NewMsgMintTo(suite.TestAccs[0].String(), sdk.NewInt64Coin(suite.defaultDenom, 10), suite.TestAccs[1].String())) addr1bal += 10 suite.Require().NoError(err) - suite.Require().True(suite.App.BankKeeper.GetBalance(suite.Ctx, suite.TestAccs[1], suite.defaultDenom).Amount.Int64() == addr1bal, suite.App.BankKeeper.GetBalance(suite.Ctx, suite.TestAccs[1], suite.defaultDenom)) + suite.Require().True(suite.App.AppKeepers.BankKeeper.GetBalance(suite.Ctx, suite.TestAccs[1], suite.defaultDenom).Amount.Int64() == addr1bal, suite.App.AppKeepers.BankKeeper.GetBalance(suite.Ctx, suite.TestAccs[1], suite.defaultDenom)) // Test force transferring _, err = suite.msgServer.ForceTransfer(sdk.WrapSDKContext(suite.Ctx), types.NewMsgForceTransfer(suite.TestAccs[0].String(), sdk.NewInt64Coin(suite.defaultDenom, 5), suite.TestAccs[1].String(), suite.TestAccs[0].String())) addr1bal -= 5 addr0bal += 5 suite.Require().NoError(err) - suite.Require().True(suite.App.BankKeeper.GetBalance(suite.Ctx, suite.TestAccs[0], suite.defaultDenom).Amount.Int64() == addr0bal, suite.App.BankKeeper.GetBalance(suite.Ctx, suite.TestAccs[0], suite.defaultDenom)) - suite.Require().True(suite.App.BankKeeper.GetBalance(suite.Ctx, suite.TestAccs[1], suite.defaultDenom).Amount.Int64() == addr1bal, suite.App.BankKeeper.GetBalance(suite.Ctx, suite.TestAccs[1], suite.defaultDenom)) + suite.Require().True(suite.App.AppKeepers.BankKeeper.GetBalance(suite.Ctx, suite.TestAccs[0], suite.defaultDenom).Amount.Int64() == addr0bal, suite.App.AppKeepers.BankKeeper.GetBalance(suite.Ctx, suite.TestAccs[0], suite.defaultDenom)) + suite.Require().True(suite.App.AppKeepers.BankKeeper.GetBalance(suite.Ctx, suite.TestAccs[1], suite.defaultDenom).Amount.Int64() == addr1bal, suite.App.AppKeepers.BankKeeper.GetBalance(suite.Ctx, suite.TestAccs[1], suite.defaultDenom)) // Test burning from own account _, err = suite.msgServer.Burn(sdk.WrapSDKContext(suite.Ctx), types.NewMsgBurn(suite.TestAccs[0].String(), sdk.NewInt64Coin(suite.defaultDenom, 5))) @@ -140,7 +140,7 @@ func (suite *KeeperTestSuite) TestMintDenom() { } mintToAddr, _ := sdk.AccAddressFromBech32(tc.mintMsg.MintToAddress) - bal := suite.App.BankKeeper.GetBalance(suite.Ctx, mintToAddr, suite.defaultDenom).Amount + bal := suite.App.AppKeepers.BankKeeper.GetBalance(suite.Ctx, mintToAddr, suite.defaultDenom).Amount suite.Require().Equal(bal.Int64(), balances[tc.mintMsg.MintToAddress]) }) } @@ -216,7 +216,7 @@ func (suite *KeeperTestSuite) TestBurnDenom() { } burnFromAddr, _ := sdk.AccAddressFromBech32(tc.burnMsg.BurnFromAddress) - bal := suite.App.BankKeeper.GetBalance(suite.Ctx, burnFromAddr, suite.defaultDenom).Amount + bal := suite.App.AppKeepers.BankKeeper.GetBalance(suite.Ctx, burnFromAddr, suite.defaultDenom).Amount suite.Require().Equal(bal.Int64(), balances[tc.burnMsg.BurnFromAddress]) }) } @@ -293,12 +293,12 @@ func (suite *KeeperTestSuite) TestForceTransferDenom() { fromAddr, err := sdk.AccAddressFromBech32(tc.forceTransferMsg.TransferFromAddress) suite.Require().NoError(err) - fromBal := suite.App.BankKeeper.GetBalance(suite.Ctx, fromAddr, suite.defaultDenom).Amount + fromBal := suite.App.AppKeepers.BankKeeper.GetBalance(suite.Ctx, fromAddr, suite.defaultDenom).Amount suite.Require().True(fromBal.Int64() == balances[tc.forceTransferMsg.TransferFromAddress]) toAddr, err := sdk.AccAddressFromBech32(tc.forceTransferMsg.TransferToAddress) suite.Require().NoError(err) - toBal := suite.App.BankKeeper.GetBalance(suite.Ctx, toAddr, suite.defaultDenom).Amount + toBal := suite.App.AppKeepers.BankKeeper.GetBalance(suite.Ctx, toAddr, suite.defaultDenom).Amount suite.Require().True(toBal.Int64() == balances[tc.forceTransferMsg.TransferToAddress]) }) } @@ -505,7 +505,7 @@ func (suite *KeeperTestSuite) TestSetDenomMetaData() { }, } { suite.Run(fmt.Sprintf("Case %s", tc.desc), func() { - bankKeeper := suite.App.BankKeeper + bankKeeper := suite.App.AppKeepers.BankKeeper res, err := suite.msgServer.SetDenomMetadata(sdk.WrapSDKContext(suite.Ctx), &tc.msgSetDenomMetadata) if tc.expectedPass { suite.Require().NoError(err) diff --git a/x/tokenfactory/keeper/createdenom_test.go b/x/tokenfactory/keeper/createdenom_test.go index f23c5b11f..fad6eea93 100644 --- a/x/tokenfactory/keeper/createdenom_test.go +++ b/x/tokenfactory/keeper/createdenom_test.go @@ -11,8 +11,8 @@ import ( func (suite *KeeperTestSuite) TestMsgCreateDenom() { var ( - tokenFactoryKeeper = suite.App.TokenFactoryKeeper - bankKeeper = suite.App.BankKeeper + tokenFactoryKeeper = suite.App.AppKeepers.TokenFactoryKeeper + bankKeeper = suite.App.AppKeepers.BankKeeper denomCreationFee = tokenFactoryKeeper.GetParams(suite.Ctx).DenomCreationFee ) @@ -130,8 +130,8 @@ func (suite *KeeperTestSuite) TestCreateDenom() { if tc.setup != nil { tc.setup() } - tokenFactoryKeeper := suite.App.TokenFactoryKeeper - bankKeeper := suite.App.BankKeeper + tokenFactoryKeeper := suite.App.AppKeepers.TokenFactoryKeeper + bankKeeper := suite.App.AppKeepers.BankKeeper // Set denom creation fee in params tokenFactoryKeeper.SetParams(suite.Ctx, tc.denomCreationFee) denomCreationFee := tokenFactoryKeeper.GetParams(suite.Ctx).DenomCreationFee @@ -143,7 +143,7 @@ func (suite *KeeperTestSuite) TestCreateDenom() { postCreateBalance := bankKeeper.GetAllBalances(suite.Ctx, suite.TestAccs[0]) if tc.valid { suite.Require().NoError(err) - suite.Require().True(preCreateBalance.Sub(postCreateBalance).IsEqual(denomCreationFee)) + suite.Require().True(preCreateBalance.Sub(postCreateBalance[0]).IsEqual(denomCreationFee)) // Make sure that the admin is set correctly queryRes, err := suite.queryClient.DenomAuthorityMetadata(suite.Ctx.Context(), &types.QueryDenomAuthorityMetadataRequest{ diff --git a/x/tokenfactory/keeper/genesis_test.go b/x/tokenfactory/keeper/genesis_test.go index 6569999ae..534990e41 100644 --- a/x/tokenfactory/keeper/genesis_test.go +++ b/x/tokenfactory/keeper/genesis_test.go @@ -38,22 +38,22 @@ func (suite *KeeperTestSuite) TestGenesis() { for i, denom := range genesisState.FactoryDenoms { // hacky, sets bank metadata to exist if i != 0, to cover both cases. if i != 0 { - app.BankKeeper.SetDenomMetaData(suite.Ctx, banktypes.Metadata{Base: denom.GetDenom()}) + app.AppKeepers.BankKeeper.SetDenomMetaData(suite.Ctx, banktypes.Metadata{Base: denom.GetDenom()}) } } // check before initGenesis that the module account is nil - tokenfactoryModuleAccount := app.AccountKeeper.GetAccount(suite.Ctx, app.AccountKeeper.GetModuleAddress(types.ModuleName)) + tokenfactoryModuleAccount := app.AppKeepers.AccountKeeper.GetAccount(suite.Ctx, app.AppKeepers.AccountKeeper.GetModuleAddress(types.ModuleName)) suite.Require().Nil(tokenfactoryModuleAccount) - app.TokenFactoryKeeper.SetParams(suite.Ctx, types.Params{DenomCreationFee: sdk.Coins{sdk.NewInt64Coin("uosmo", 100)}}) - app.TokenFactoryKeeper.InitGenesis(suite.Ctx, genesisState) + app.AppKeepers.TokenFactoryKeeper.SetParams(suite.Ctx, types.Params{DenomCreationFee: sdk.Coins{sdk.NewInt64Coin("uosmo", 100)}}) + app.AppKeepers.TokenFactoryKeeper.InitGenesis(suite.Ctx, genesisState) // check that the module account is now initialized - tokenfactoryModuleAccount = app.AccountKeeper.GetAccount(suite.Ctx, app.AccountKeeper.GetModuleAddress(types.ModuleName)) + tokenfactoryModuleAccount = app.AppKeepers.AccountKeeper.GetAccount(suite.Ctx, app.AppKeepers.AccountKeeper.GetModuleAddress(types.ModuleName)) suite.Require().NotNil(tokenfactoryModuleAccount) - exportedGenesis := app.TokenFactoryKeeper.ExportGenesis(suite.Ctx) + exportedGenesis := app.AppKeepers.TokenFactoryKeeper.ExportGenesis(suite.Ctx) suite.Require().NotNil(exportedGenesis) suite.Require().Equal(genesisState, *exportedGenesis) } diff --git a/x/tokenfactory/keeper/keeper_test.go b/x/tokenfactory/keeper/keeper_test.go index 5703d2767..863989342 100644 --- a/x/tokenfactory/keeper/keeper_test.go +++ b/x/tokenfactory/keeper/keeper_test.go @@ -35,7 +35,7 @@ func (suite *KeeperTestSuite) SetupTest() { } suite.queryClient = types.NewQueryClient(suite.QueryHelper) - suite.msgServer = keeper.NewMsgServerImpl(suite.App.TokenFactoryKeeper) + suite.msgServer = keeper.NewMsgServerImpl(suite.App.AppKeepers.TokenFactoryKeeper) } func (suite *KeeperTestSuite) CreateDefaultDenom() { @@ -47,18 +47,18 @@ func (suite *KeeperTestSuite) TestCreateModuleAccount() { app := suite.App // remove module account - tokenfactoryModuleAccount := app.AccountKeeper.GetAccount(suite.Ctx, app.AccountKeeper.GetModuleAddress(types.ModuleName)) - app.AccountKeeper.RemoveAccount(suite.Ctx, tokenfactoryModuleAccount) + tokenfactoryModuleAccount := app.AppKeepers.AccountKeeper.GetAccount(suite.Ctx, app.AppKeepers.AccountKeeper.GetModuleAddress(types.ModuleName)) + app.AppKeepers.AccountKeeper.RemoveAccount(suite.Ctx, tokenfactoryModuleAccount) // ensure module account was removed suite.Ctx = app.BaseApp.NewContext(false, tmproto.Header{}) - tokenfactoryModuleAccount = app.AccountKeeper.GetAccount(suite.Ctx, app.AccountKeeper.GetModuleAddress(types.ModuleName)) + tokenfactoryModuleAccount = app.AppKeepers.AccountKeeper.GetAccount(suite.Ctx, app.AppKeepers.AccountKeeper.GetModuleAddress(types.ModuleName)) suite.Require().Nil(tokenfactoryModuleAccount) // create module account - app.TokenFactoryKeeper.CreateModuleAccount(suite.Ctx) + app.AppKeepers.TokenFactoryKeeper.CreateModuleAccount(suite.Ctx) // check that the module account is now initialized - tokenfactoryModuleAccount = app.AccountKeeper.GetAccount(suite.Ctx, app.AccountKeeper.GetModuleAddress(types.ModuleName)) + tokenfactoryModuleAccount = app.AppKeepers.AccountKeeper.GetAccount(suite.Ctx, app.AppKeepers.AccountKeeper.GetModuleAddress(types.ModuleName)) suite.Require().NotNil(tokenfactoryModuleAccount) } diff --git a/x/tokenfactory/keeper/msg_server_test.go b/x/tokenfactory/keeper/msg_server_test.go index 749a140d3..b3658a5fd 100644 --- a/x/tokenfactory/keeper/msg_server_test.go +++ b/x/tokenfactory/keeper/msg_server_test.go @@ -115,7 +115,7 @@ func (suite *KeeperTestSuite) TestCreateDenomMsg() { } { suite.SetupTest() suite.Run(fmt.Sprintf("Case %s", tc.desc), func() { - tokenFactoryKeeper := suite.App.TokenFactoryKeeper + tokenFactoryKeeper := suite.App.AppKeepers.TokenFactoryKeeper ctx := suite.Ctx.WithEventManager(sdk.NewEventManager()) suite.Require().Equal(0, len(ctx.EventManager().Events())) // Set denom creation fee in params From 13a5ed47bdb5905bcf539a5a4c95b17dea9c879a Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Fri, 28 Apr 2023 17:54:07 -0500 Subject: [PATCH 046/131] Fix maccPerms, appModules&Simulation, ibcexported --- app/app.go | 13 +-- app/apptesting/test_suite.go | 10 +- app/export.go | 50 ++++----- app/keepers/keepers.go | 65 ++++++++--- app/modules.go | 115 +++++++++----------- x/feeshare/integration_test.go | 4 +- x/globalfee/ante/antetest/fee_test_setup.go | 4 +- x/mint/client/testutil/suite.go | 4 +- x/mint/keeper/grpc_query_test.go | 8 +- x/mint/keeper/integration_test.go | 22 ++-- x/mint/keeper/keeper.go | 6 +- x/mint/keeper/querier_test.go | 14 +-- x/mint/simulation/genesis_test.go | 3 +- 13 files changed, 164 insertions(+), 154 deletions(-) diff --git a/app/app.go b/app/app.go index a3a4f924f..c63259e9a 100644 --- a/app/app.go +++ b/app/app.go @@ -246,7 +246,7 @@ func New( appCodec, bApp, legacyAmino, - maccPerms, + keepers.GetMaccPerms(), app.ModuleAccountAddrs(), enabledProposals, appOpts, @@ -417,7 +417,7 @@ func (app *App) LoadHeight(height int64) error { // ModuleAccountAddrs returns all the app's module account addresses. func (app *App) ModuleAccountAddrs() map[string]bool { modAccAddrs := make(map[string]bool) - for acc := range maccPerms { + for acc := range keepers.GetMaccPerms() { modAccAddrs[authtypes.NewModuleAddress(acc).String()] = true } @@ -526,15 +526,6 @@ func (app *App) setupUpgradeHandlers(cfg module.Configurator) { } } -// GetMaccPerms returns a copy of the module account permissions -func GetMaccPerms() map[string][]string { - dupMaccPerms := make(map[string][]string) - for k, v := range maccPerms { - dupMaccPerms[k] = v - } - return dupMaccPerms -} - // SimulationManager implements the SimulationApp interface func (app *App) SimulationManager() *module.SimulationManager { return app.sm diff --git a/app/apptesting/test_suite.go b/app/apptesting/test_suite.go index e09eb4e82..55f1372b5 100644 --- a/app/apptesting/test_suite.go +++ b/app/apptesting/test_suite.go @@ -8,6 +8,7 @@ import ( "cosmossdk.io/math" "cosmossdk.io/simapp" + dbm "github.com/cometbft/cometbft-db" abci "github.com/cometbft/cometbft/abci/types" "github.com/cometbft/cometbft/crypto/ed25519" "github.com/cometbft/cometbft/libs/log" @@ -27,7 +28,6 @@ import ( stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" - dbm "github.com/cometbft/cometbft-db" authzcodec "github.com/CosmosContracts/juno/v15/x/tokenfactory/types/authzcodec" @@ -96,18 +96,18 @@ func (s *KeeperTestHelper) Commit() { // FundAcc funds target address with specified amount. func (s *KeeperTestHelper) FundAcc(acc sdk.AccAddress, amounts sdk.Coins) { - err := simapp.FundAccount(s.App.BankKeeper, s.Ctx, acc, amounts) + err := simapp.FundAccount(s.App.AppKeepers.BankKeeper, s.Ctx, acc, amounts) s.Require().NoError(err) } // FundModuleAcc funds target modules with specified amount. func (s *KeeperTestHelper) FundModuleAcc(moduleName string, amounts sdk.Coins) { - err := simapp.FundModuleAccount(s.App.BankKeeper, s.Ctx, moduleName, amounts) + err := simapp.FundModuleAccount(s.App.AppKeepers.BankKeeper, s.Ctx, moduleName, amounts) s.Require().NoError(err) } func (s *KeeperTestHelper) MintCoins(coins sdk.Coins) { - err := s.App.BankKeeper.MintCoins(s.Ctx, minttypes.ModuleName, coins) + err := s.App.AppKeepers.BankKeeper.MintCoins(s.Ctx, minttypes.ModuleName, coins) s.Require().NoError(err) } @@ -210,7 +210,7 @@ func (s *KeeperTestHelper) AllocateRewardsToValidator(valAddr sdk.ValAddress, re // allocate reward tokens to distribution module coins := sdk.Coins{sdk.NewCoin(sdk.DefaultBondDenom, rewardAmt)} - err := simapp.FundModuleAccount(s.App.BankKeeper, s.Ctx, distrtypes.ModuleName, coins) + err := simapp.FundModuleAccount(s.App.AppKeepers.BankKeeper, s.Ctx, distrtypes.ModuleName, coins) s.Require().NoError(err) // allocate rewards to validator diff --git a/app/export.go b/app/export.go index 1e0fdff7b..dd8bf400d 100644 --- a/app/export.go +++ b/app/export.go @@ -33,7 +33,7 @@ func (app *App) ExportAppStateAndValidators(forZeroHeight bool, jailAllowedAddrs return servertypes.ExportedApp{}, err } - validators, err := staking.WriteValidators(ctx, app.StakingKeeper) + validators, err := staking.WriteValidators(ctx, &app.AppKeepers.StakingKeeper) return servertypes.ExportedApp{ AppState: appState, Validators: validators, @@ -65,13 +65,13 @@ func (app *App) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs []str } /* Just to be safe, assert the invariants on current state. */ - app.CrisisKeeper.AssertInvariants(ctx) + app.AppKeepers.CrisisKeeper.AssertInvariants(ctx) /* Handle fee distribution state. */ // withdraw all validator commission - app.StakingKeeper.IterateValidators(ctx, func(_ int64, val stakingtypes.ValidatorI) (stop bool) { - _, err := app.DistrKeeper.WithdrawValidatorCommission(ctx, val.GetOperator()) + app.AppKeepers.StakingKeeper.IterateValidators(ctx, func(_ int64, val stakingtypes.ValidatorI) (stop bool) { + _, err := app.AppKeepers.DistrKeeper.WithdrawValidatorCommission(ctx, val.GetOperator()) if err != nil { panic(err) } @@ -79,40 +79,40 @@ func (app *App) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs []str }) // withdraw all delegator rewards - dels := app.StakingKeeper.GetAllDelegations(ctx) + dels := app.AppKeepers.StakingKeeper.GetAllDelegations(ctx) for _, delegation := range dels { - _, err := app.DistrKeeper.WithdrawDelegationRewards(ctx, delegation.GetDelegatorAddr(), delegation.GetValidatorAddr()) + _, err := app.AppKeepers.DistrKeeper.WithdrawDelegationRewards(ctx, delegation.GetDelegatorAddr(), delegation.GetValidatorAddr()) if err != nil { panic(err) } } // clear validator slash events - app.DistrKeeper.DeleteAllValidatorSlashEvents(ctx) + app.AppKeepers.DistrKeeper.DeleteAllValidatorSlashEvents(ctx) // clear validator historical rewards - app.DistrKeeper.DeleteAllValidatorHistoricalRewards(ctx) + app.AppKeepers.DistrKeeper.DeleteAllValidatorHistoricalRewards(ctx) // set context height to zero height := ctx.BlockHeight() ctx = ctx.WithBlockHeight(0) // reinitialize all validators - app.StakingKeeper.IterateValidators(ctx, func(_ int64, val stakingtypes.ValidatorI) (stop bool) { + app.AppKeepers.StakingKeeper.IterateValidators(ctx, func(_ int64, val stakingtypes.ValidatorI) (stop bool) { // donate any unwithdrawn outstanding reward fraction tokens to the community pool - scraps := app.DistrKeeper.GetValidatorOutstandingRewardsCoins(ctx, val.GetOperator()) - feePool := app.DistrKeeper.GetFeePool(ctx) + scraps := app.AppKeepers.DistrKeeper.GetValidatorOutstandingRewardsCoins(ctx, val.GetOperator()) + feePool := app.AppKeepers.DistrKeeper.GetFeePool(ctx) feePool.CommunityPool = feePool.CommunityPool.Add(scraps...) - app.DistrKeeper.SetFeePool(ctx, feePool) + app.AppKeepers.DistrKeeper.SetFeePool(ctx, feePool) - app.DistrKeeper.Hooks().AfterValidatorCreated(ctx, val.GetOperator()) + app.AppKeepers.DistrKeeper.Hooks().AfterValidatorCreated(ctx, val.GetOperator()) return false }) // reinitialize all delegations for _, del := range dels { - app.DistrKeeper.Hooks().BeforeDelegationCreated(ctx, del.GetDelegatorAddr(), del.GetValidatorAddr()) - app.DistrKeeper.Hooks().AfterDelegationModified(ctx, del.GetDelegatorAddr(), del.GetValidatorAddr()) + app.AppKeepers.DistrKeeper.Hooks().BeforeDelegationCreated(ctx, del.GetDelegatorAddr(), del.GetValidatorAddr()) + app.AppKeepers.DistrKeeper.Hooks().AfterDelegationModified(ctx, del.GetDelegatorAddr(), del.GetValidatorAddr()) } // reset context height @@ -121,32 +121,32 @@ func (app *App) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs []str /* Handle staking state. */ // iterate through redelegations, reset creation height - app.StakingKeeper.IterateRedelegations(ctx, func(_ int64, red stakingtypes.Redelegation) (stop bool) { + app.AppKeepers.StakingKeeper.IterateRedelegations(ctx, func(_ int64, red stakingtypes.Redelegation) (stop bool) { for i := range red.Entries { red.Entries[i].CreationHeight = 0 } - app.StakingKeeper.SetRedelegation(ctx, red) + app.AppKeepers.StakingKeeper.SetRedelegation(ctx, red) return false }) // iterate through unbonding delegations, reset creation height - app.StakingKeeper.IterateUnbondingDelegations(ctx, func(_ int64, ubd stakingtypes.UnbondingDelegation) (stop bool) { + app.AppKeepers.StakingKeeper.IterateUnbondingDelegations(ctx, func(_ int64, ubd stakingtypes.UnbondingDelegation) (stop bool) { for i := range ubd.Entries { ubd.Entries[i].CreationHeight = 0 } - app.StakingKeeper.SetUnbondingDelegation(ctx, ubd) + app.AppKeepers.StakingKeeper.SetUnbondingDelegation(ctx, ubd) return false }) // Iterate through validators by power descending, reset bond heights, and // update bond intra-tx counters. - store := ctx.KVStore(app.GetKey(stakingtypes.StoreKey)) + store := ctx.KVStore(app.AppKeepers.GetKey(stakingtypes.StoreKey)) iter := sdk.KVStoreReversePrefixIterator(store, stakingtypes.ValidatorsKey) counter := int16(0) for ; iter.Valid(); iter.Next() { addr := sdk.ValAddress(iter.Key()[1:]) - validator, found := app.StakingKeeper.GetValidator(ctx, addr) + validator, found := app.AppKeepers.StakingKeeper.GetValidator(ctx, addr) if !found { panic("expected validator, not found") } @@ -156,7 +156,7 @@ func (app *App) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs []str validator.Jailed = true } - app.StakingKeeper.SetValidator(ctx, validator) + app.AppKeepers.StakingKeeper.SetValidator(ctx, validator) counter++ } @@ -165,18 +165,18 @@ func (app *App) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs []str panic(err) } - if _, err := app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx); err != nil { + if _, err := app.AppKeepers.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx); err != nil { panic(err) } /* Handle slashing state. */ // reset start height on signing infos - app.SlashingKeeper.IterateValidatorSigningInfos( + app.AppKeepers.SlashingKeeper.IterateValidatorSigningInfos( ctx, func(addr sdk.ConsAddress, info slashingtypes.ValidatorSigningInfo) (stop bool) { info.StartHeight = 0 - app.SlashingKeeper.SetValidatorSigningInfo(ctx, addr, info) + app.AppKeepers.SlashingKeeper.SetValidatorSigningInfo(ctx, addr, info) return false }, ) diff --git a/app/keepers/keepers.go b/app/keepers/keepers.go index 0d9db3cbb..b3e300730 100644 --- a/app/keepers/keepers.go +++ b/app/keepers/keepers.go @@ -87,6 +87,7 @@ import ( icacontroller "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller" icacontrollerkeeper "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/keeper" icacontrollertypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/types" + icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" "github.com/CosmosContracts/juno/v15/x/globalfee" ) @@ -101,6 +102,22 @@ var ( } ) +// module account permissions +var maccPerms = map[string][]string{ + authtypes.FeeCollectorName: nil, + distrtypes.ModuleName: nil, + minttypes.ModuleName: {authtypes.Minter}, + stakingtypes.BondedPoolName: {authtypes.Burner, authtypes.Staking}, + stakingtypes.NotBondedPoolName: {authtypes.Burner, authtypes.Staking}, + govtypes.ModuleName: {authtypes.Burner}, + icqtypes.ModuleName: nil, + ibctransfertypes.ModuleName: {authtypes.Minter, authtypes.Burner}, + icatypes.ModuleName: nil, + ibcfeetypes.ModuleName: nil, + wasm.ModuleName: {authtypes.Burner}, + tokenfactorytypes.ModuleName: {authtypes.Minter, authtypes.Burner}, +} + type AppKeepers struct { // keys to access the substores keys map[string]*storetypes.KVStoreKey @@ -117,7 +134,7 @@ type AppKeepers struct { DistrKeeper distrkeeper.Keeper GovKeeper govkeeper.Keeper CrisisKeeper *crisiskeeper.Keeper - UpgradeKeeper upgradekeeper.Keeper + UpgradeKeeper *upgradekeeper.Keeper ParamsKeeper paramskeeper.Keeper IBCKeeper *ibckeeper.Keeper // IBC Keeper must be a pointer in the app, so we can SetRouter on it correctly ICQKeeper icqkeeper.Keeper @@ -262,7 +279,7 @@ func NewAppKeepers( } homePath := cast.ToString(appOpts.Get(flags.FlagHome)) - appKeepers.UpgradeKeeper = *upgradekeeper.NewKeeper( + appKeepers.UpgradeKeeper = upgradekeeper.NewKeeper( skipUpgradeHeights, appKeepers.keys[upgradetypes.StoreKey], appCodec, @@ -306,10 +323,26 @@ func NewAppKeepers( // register the proposal types govRouter := govv1beta1.NewRouter() govRouter.AddRoute(govtypes.RouterKey, govv1beta1.ProposalHandler). - AddRoute(paramproposal.RouterKey, params.NewParamChangeProposalHandler(appKeepers.ParamsKeeper)). - AddRoute(upgradetypes.RouterKey, upgrade.NewSoftwareUpgradeProposalHandler(&appKeepers.UpgradeKeeper)). - // AddRoute(distrtypes.RouterKey, distr.NewCommunityPoolSpendProposalHandler(appKeepers.DistrKeeper)). + AddRoute(paramproposal.RouterKey, params.NewParamChangeProposalHandler(appKeepers.ParamsKeeper)). // This should be removed. It is still in place to avoid failures of modules that have not yet been upgraded + AddRoute(upgradetypes.RouterKey, upgrade.NewSoftwareUpgradeProposalHandler(appKeepers.UpgradeKeeper)). AddRoute(ibcclienttypes.RouterKey, ibcclient.NewClientProposalHandler(appKeepers.IBCKeeper.ClientKeeper)) + // AddRoute(distrtypes.RouterKey, distr.NewCommunityPoolSpendProposalHandler(appKeepers.DistrKeeper)). + + govKeeper := govkeeper.NewKeeper( + appCodec, + appKeepers.keys[govtypes.StoreKey], + appKeepers.AccountKeeper, + appKeepers.BankKeeper, + appKeepers.StakingKeeper, + bApp.MsgServiceRouter(), + govtypes.DefaultConfig(), + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) + appKeepers.GovKeeper = *govKeeper.SetHooks( + govtypes.NewMultiGovHooks( + // register governance hooks + ), + ) // Configure the hooks keeper hooksKeeper := ibchookskeeper.NewKeeper( @@ -338,9 +371,9 @@ func NewAppKeepers( ) appKeepers.IBCFeeKeeper = ibcfeekeeper.NewKeeper( - appCodec, - appKeepers.keys[ibcfeetypes.StoreKey], - appKeepers.HooksICS4Wrapper, // replaced with IBC middleware + appCodec, + appKeepers.keys[ibcfeetypes.StoreKey], + appKeepers.HooksICS4Wrapper, // replaced with IBC middleware appKeepers.IBCKeeper.ChannelKeeper, &appKeepers.IBCKeeper.PortKeeper, appKeepers.AccountKeeper, @@ -379,6 +412,7 @@ func NewAppKeepers( appCodec, appKeepers.keys[icahosttypes.StoreKey], appKeepers.GetSubspace(icahosttypes.SubModuleName), + appKeepers.HooksICS4Wrapper, appKeepers.IBCKeeper.ChannelKeeper, &appKeepers.IBCKeeper.PortKeeper, appKeepers.AccountKeeper, @@ -460,11 +494,10 @@ func NewAppKeepers( appKeepers.WasmKeeper = wasm.NewKeeper( appCodec, appKeepers.keys[wasm.StoreKey], - appKeepers.GetSubspace(wasm.ModuleName), appKeepers.AccountKeeper, appKeepers.BankKeeper, appKeepers.StakingKeeper, - appKeepers.DistrKeeper, + distrkeeper.NewQuerier(appKeepers.DistrKeeper), appKeepers.IBCKeeper.ChannelKeeper, &appKeepers.IBCKeeper.PortKeeper, scopedWasmKeeper, @@ -474,6 +507,7 @@ func NewAppKeepers( wasmDir, wasmConfig, wasmCapabilities, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), wasmOpts..., ) @@ -491,6 +525,8 @@ func NewAppKeepers( if len(enabledProposals) != 0 { govRouter.AddRoute(wasm.RouterKey, wasm.NewWasmProposalHandler(appKeepers.WasmKeeper, enabledProposals)) } + // Set legacy router for backwards compatibility with gov v1beta1 + appKeepers.GovKeeper.SetLegacyRouter(govRouter) // Create Transfer Stack var transferStack porttypes.IBCModule @@ -527,11 +563,6 @@ func NewAppKeepers( appKeepers.IBCKeeper.SetRouter(ibcRouter) - appKeepers.GovKeeper = govkeeper.NewKeeper( - appCodec, appKeepers.keys[govtypes.StoreKey], appKeepers.GetSubspace(govtypes.ModuleName), appKeepers.AccountKeeper, appKeepers.BankKeeper, - &stakingKeeper, govRouter, - ) - appKeepers.ScopedIBCKeeper = scopedIBCKeeper appKeepers.ScopedTransferKeeper = scopedTransferKeeper appKeepers.ScopedICQKeeper = scopedICQKeeper @@ -562,7 +593,7 @@ func initParamsKeeper(appCodec codec.BinaryCodec, legacyAmino *codec.LegacyAmino // custom paramsKeeper.Subspace(ibctransfertypes.ModuleName) paramsKeeper.Subspace(packetforwardtypes.ModuleName).WithKeyTable(packetforwardtypes.ParamKeyTable()) - paramsKeeper.Subspace(ibchost.ModuleName) + paramsKeeper.Subspace(ibcexported.ModuleName) paramsKeeper.Subspace(icacontrollertypes.SubModuleName) paramsKeeper.Subspace(icahosttypes.SubModuleName) paramsKeeper.Subspace(wasm.ModuleName) @@ -613,8 +644,6 @@ func BlockedAddresses() map[string]bool { } // GetMaccPerms returns a copy of the module account permissions -// -// NOTE: This is solely to be used for testing purposes. func GetMaccPerms() map[string][]string { dupMaccPerms := make(map[string][]string) for k, v := range maccPerms { diff --git a/app/modules.go b/app/modules.go index e9c5ee927..2d29e2d46 100644 --- a/app/modules.go +++ b/app/modules.go @@ -2,6 +2,7 @@ package app import ( "github.com/CosmWasm/wasmd/x/wasm" + wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" encparams "github.com/CosmosContracts/juno/v15/app/params" feeshare "github.com/CosmosContracts/juno/v15/x/feeshare" feesharetypes "github.com/CosmosContracts/juno/v15/x/feeshare/types" @@ -51,29 +52,13 @@ import ( transfer "github.com/cosmos/ibc-go/v7/modules/apps/transfer" ibctransfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" ibc "github.com/cosmos/ibc-go/v7/modules/core" - ibchost "github.com/cosmos/ibc-go/v7/modules/core/24-host" + ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" icq "github.com/strangelove-ventures/async-icq/v7" icqtypes "github.com/strangelove-ventures/async-icq/v7/types" packetforward "github.com/strangelove-ventures/packet-forward-middleware/v7/router" packetforwardtypes "github.com/strangelove-ventures/packet-forward-middleware/v7/router/types" ) -// module account permissions -var maccPerms = map[string][]string{ - authtypes.FeeCollectorName: nil, - distrtypes.ModuleName: nil, - minttypes.ModuleName: {authtypes.Minter}, - stakingtypes.BondedPoolName: {authtypes.Burner, authtypes.Staking}, - stakingtypes.NotBondedPoolName: {authtypes.Burner, authtypes.Staking}, - govtypes.ModuleName: {authtypes.Burner}, - icqtypes.ModuleName: nil, - ibctransfertypes.ModuleName: {authtypes.Minter, authtypes.Burner}, - icatypes.ModuleName: nil, - ibcfeetypes.ModuleName: nil, - wasm.ModuleName: {authtypes.Burner}, - tokenfactorytypes.ModuleName: {authtypes.Minter, authtypes.Burner}, -} - // ModuleBasics defines the module BasicManager is in charge of setting up basic, // non-dependant module elements, such as codec registration // and genesis verification. @@ -116,36 +101,38 @@ func appModules( return []module.AppModule{ genutil.NewAppModule( - app.AccountKeeper, app.StakingKeeper, app.BaseApp.DeliverTx, + app.AppKeepers.AccountKeeper, + app.AppKeepers.StakingKeeper, + app.BaseApp.DeliverTx, encodingConfig.TxConfig, ), - auth.NewAppModule(appCodec, app.AccountKeeper, nil), - vesting.NewAppModule(app.AccountKeeper, app.BankKeeper), - bank.NewAppModule(appCodec, app.BankKeeper, app.AccountKeeper), - capability.NewAppModule(appCodec, *app.CapabilityKeeper), - crisis.NewAppModule(&app.CrisisKeeper, skipGenesisInvariants), - feegrantmodule.NewAppModule(appCodec, app.AccountKeeper, app.BankKeeper, app.FeeGrantKeeper, app.interfaceRegistry), - gov.NewAppModule(appCodec, app.GovKeeper, app.AccountKeeper, app.BankKeeper), - mint.NewAppModule(appCodec, app.MintKeeper, app.AccountKeeper), - slashing.NewAppModule(appCodec, app.SlashingKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper), - distr.NewAppModule(appCodec, app.DistrKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper), - staking.NewAppModule(appCodec, app.StakingKeeper, app.AccountKeeper, app.BankKeeper), - upgrade.NewAppModule(app.UpgradeKeeper), - evidence.NewAppModule(app.EvidenceKeeper), - ibc.NewAppModule(app.IBCKeeper), - params.NewAppModule(app.ParamsKeeper), - authzmodule.NewAppModule(appCodec, app.AuthzKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry), - transfer.NewAppModule(app.TransferKeeper), - ibcfee.NewAppModule(app.IBCFeeKeeper), - tokenfactory.NewAppModule(app.AppKeepers.TokenFactoryKeeper, app.AccountKeeper, app.BankKeeper), - globalfee.NewAppModule(app.GetSubspace(globalfee.ModuleName)), - feeshare.NewAppModule(app.FeeShareKeeper, app.AccountKeeper), - wasm.NewAppModule(appCodec, &app.WasmKeeper, app.StakingKeeper, app.AccountKeeper, app.BankKeeper), - ica.NewAppModule(&app.ICAControllerKeeper, &app.ICAHostKeeper), - ibchooks.NewAppModule(app.AccountKeeper), + auth.NewAppModule(appCodec, app.AppKeepers.AccountKeeper, nil, app.GetSubspace(authtypes.ModuleName)), + vesting.NewAppModule(app.AppKeepers.AccountKeeper, app.AppKeepers.BankKeeper), + bank.NewAppModule(appCodec, app.AppKeepers.BankKeeper, app.AppKeepers.AccountKeeper, app.GetSubspace(banktypes.ModuleName)), + capability.NewAppModule(appCodec, *app.AppKeepers.CapabilityKeeper, false), + feegrantmodule.NewAppModule(appCodec, app.AppKeepers.AccountKeeper, app.AppKeepers.BankKeeper, app.AppKeepers.FeeGrantKeeper, app.interfaceRegistry), + gov.NewAppModule(appCodec, &app.AppKeepers.GovKeeper, app.AppKeepers.AccountKeeper, app.AppKeepers.BankKeeper, app.GetSubspace(govtypes.ModuleName)), + mint.NewAppModule(appCodec, app.AppKeepers.MintKeeper, app.AppKeepers.AccountKeeper), + slashing.NewAppModule(appCodec, app.AppKeepers.SlashingKeeper, app.AppKeepers.AccountKeeper, app.AppKeepers.BankKeeper, app.AppKeepers.StakingKeeper, app.GetSubspace(slashingtypes.ModuleName)), + distr.NewAppModule(appCodec, app.AppKeepers.DistrKeeper, app.AppKeepers.AccountKeeper, app.AppKeepers.BankKeeper, app.AppKeepers.StakingKeeper, app.GetSubspace(distrtypes.ModuleName)), + staking.NewAppModule(appCodec, &app.AppKeepers.StakingKeeper, app.AppKeepers.AccountKeeper, app.AppKeepers.BankKeeper, app.GetSubspace(stakingtypes.ModuleName)), + upgrade.NewAppModule(app.AppKeepers.UpgradeKeeper), + evidence.NewAppModule(app.AppKeepers.EvidenceKeeper), + ibc.NewAppModule(app.AppKeepers.IBCKeeper), + params.NewAppModule(app.AppKeepers.ParamsKeeper), + authzmodule.NewAppModule(appCodec, app.AppKeepers.AuthzKeeper, app.AppKeepers.AccountKeeper, app.AppKeepers.BankKeeper, app.interfaceRegistry), + transfer.NewAppModule(app.AppKeepers.TransferKeeper), + ibcfee.NewAppModule(app.AppKeepers.IBCFeeKeeper), + tokenfactory.NewAppModule(app.AppKeepers.TokenFactoryKeeper, app.AppKeepers.AccountKeeper, app.AppKeepers.BankKeeper), + globalfee.NewAppModule(app.AppKeepers.GetSubspace(globalfee.ModuleName)), + feeshare.NewAppModule(app.AppKeepers.FeeShareKeeper, app.AppKeepers.AccountKeeper), + wasm.NewAppModule(appCodec, &app.AppKeepers.WasmKeeper, app.AppKeepers.StakingKeeper, app.AppKeepers.AccountKeeper, app.AppKeepers.BankKeeper, app.MsgServiceRouter(), app.GetSubspace(wasmtypes.ModuleName)), + ica.NewAppModule(&app.AppKeepers.ICAControllerKeeper, &app.AppKeepers.ICAHostKeeper), + ibchooks.NewAppModule(app.AppKeepers.AccountKeeper), + crisis.NewAppModule(app.AppKeepers.CrisisKeeper, skipGenesisInvariants, app.GetSubspace(crisistypes.ModuleName)), // IBC modules - icq.NewAppModule(app.ICQKeeper), - packetforward.NewAppModule(app.PacketForwardKeeper), + icq.NewAppModule(app.AppKeepers.ICQKeeper), + packetforward.NewAppModule(app.AppKeepers.PacketForwardKeeper), } } @@ -159,23 +146,23 @@ func simulationModules( appCodec := encodingConfig.Marshaler return []module.AppModuleSimulation{ - auth.NewAppModule(appCodec, app.AccountKeeper, authsims.RandomGenesisAccounts), - bank.NewAppModule(appCodec, app.BankKeeper, app.AccountKeeper), - capability.NewAppModule(appCodec, *app.CapabilityKeeper), - feegrantmodule.NewAppModule(appCodec, app.AccountKeeper, app.BankKeeper, app.FeeGrantKeeper, app.interfaceRegistry), - authzmodule.NewAppModule(appCodec, app.AuthzKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry), - gov.NewAppModule(appCodec, app.GovKeeper, app.AccountKeeper, app.BankKeeper), - mint.NewAppModule(appCodec, app.MintKeeper, app.AccountKeeper), - staking.NewAppModule(appCodec, app.StakingKeeper, app.AccountKeeper, app.BankKeeper), - distr.NewAppModule(appCodec, app.DistrKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper), - slashing.NewAppModule(appCodec, app.SlashingKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper), - params.NewAppModule(app.ParamsKeeper), - evidence.NewAppModule(app.EvidenceKeeper), - wasm.NewAppModule(appCodec, &app.WasmKeeper, app.StakingKeeper, app.AccountKeeper, app.BankKeeper), - ibc.NewAppModule(app.IBCKeeper), - transfer.NewAppModule(app.TransferKeeper), - feeshare.NewAppModule(app.FeeShareKeeper, app.AccountKeeper), - ibcfee.NewAppModule(app.IBCFeeKeeper), + auth.NewAppModule(appCodec, app.AppKeepers.AccountKeeper, authsims.RandomGenesisAccounts, app.GetSubspace(authtypes.ModuleName)), + bank.NewAppModule(appCodec, app.AppKeepers.BankKeeper, app.AppKeepers.AccountKeeper, app.GetSubspace(banktypes.ModuleName)), + capability.NewAppModule(appCodec, *app.AppKeepers.CapabilityKeeper, false), + feegrantmodule.NewAppModule(appCodec, app.AppKeepers.AccountKeeper, app.AppKeepers.BankKeeper, app.AppKeepers.FeeGrantKeeper, app.interfaceRegistry), + authzmodule.NewAppModule(appCodec, app.AppKeepers.AuthzKeeper, app.AppKeepers.AccountKeeper, app.AppKeepers.BankKeeper, app.interfaceRegistry), + gov.NewAppModule(appCodec, &app.AppKeepers.GovKeeper, app.AppKeepers.AccountKeeper, app.AppKeepers.BankKeeper, app.GetSubspace(govtypes.ModuleName)), + mint.NewAppModule(appCodec, app.AppKeepers.MintKeeper, app.AppKeepers.AccountKeeper), + staking.NewAppModule(appCodec, &app.AppKeepers.StakingKeeper, app.AppKeepers.AccountKeeper, app.AppKeepers.BankKeeper, app.GetSubspace(stakingtypes.ModuleName)), + distr.NewAppModule(appCodec, app.AppKeepers.DistrKeeper, app.AppKeepers.AccountKeeper, app.AppKeepers.BankKeeper, app.AppKeepers.StakingKeeper, app.GetSubspace(distrtypes.ModuleName)), + slashing.NewAppModule(appCodec, app.AppKeepers.SlashingKeeper, app.AppKeepers.AccountKeeper, app.AppKeepers.BankKeeper, app.AppKeepers.StakingKeeper, app.GetSubspace(stakingtypes.ModuleName)), + params.NewAppModule(app.AppKeepers.ParamsKeeper), + evidence.NewAppModule(app.AppKeepers.EvidenceKeeper), + wasm.NewAppModule(appCodec, &app.AppKeepers.WasmKeeper, app.AppKeepers.StakingKeeper, app.AppKeepers.AccountKeeper, app.AppKeepers.BankKeeper, app.MsgServiceRouter(), app.GetSubspace(wasmtypes.ModuleName)), + ibc.NewAppModule(app.AppKeepers.IBCKeeper), + transfer.NewAppModule(app.AppKeepers.TransferKeeper), + feeshare.NewAppModule(app.AppKeepers.FeeShareKeeper, app.AppKeepers.AccountKeeper), + ibcfee.NewAppModule(app.AppKeepers.IBCFeeKeeper), } } @@ -200,7 +187,7 @@ func orderBeginBlockers() []string { paramstypes.ModuleName, vestingtypes.ModuleName, // additional modules - ibchost.ModuleName, + ibcexported.ModuleName, ibctransfertypes.ModuleName, icatypes.ModuleName, packetforwardtypes.ModuleName, @@ -233,7 +220,7 @@ func orderEndBlockers() []string { upgradetypes.ModuleName, vestingtypes.ModuleName, // additional non simd modules - ibchost.ModuleName, + ibcexported.ModuleName, ibctransfertypes.ModuleName, icatypes.ModuleName, packetforwardtypes.ModuleName, @@ -266,7 +253,7 @@ func orderInitBlockers() []string { vestingtypes.ModuleName, feegrant.ModuleName, // additional non simd modules - ibchost.ModuleName, + ibcexported.ModuleName, ibctransfertypes.ModuleName, icatypes.ModuleName, packetforwardtypes.ModuleName, diff --git a/x/feeshare/integration_test.go b/x/feeshare/integration_test.go index 778b9a4d2..3487b69ac 100644 --- a/x/feeshare/integration_test.go +++ b/x/feeshare/integration_test.go @@ -20,8 +20,8 @@ func CreateTestApp(isCheckTx bool) (*junoapp.App, sdk.Context) { app := Setup(isCheckTx) ctx := app.BaseApp.NewContext(isCheckTx, tmproto.Header{}) - app.MintKeeper.SetParams(ctx, types.DefaultParams()) - app.MintKeeper.SetMinter(ctx, types.DefaultInitialMinter()) + app.AppKeepers.MintKeeper.SetParams(ctx, types.DefaultParams()) + app.AppKeepers.MintKeeper.SetMinter(ctx, types.DefaultInitialMinter()) return app, ctx } diff --git a/x/globalfee/ante/antetest/fee_test_setup.go b/x/globalfee/ante/antetest/fee_test_setup.go index f21c02a26..0c035d172 100644 --- a/x/globalfee/ante/antetest/fee_test_setup.go +++ b/x/globalfee/ante/antetest/fee_test_setup.go @@ -19,7 +19,7 @@ import ( gaiahelpers "github.com/CosmosContracts/juno/v15/app/helpers" gaiafeeante "github.com/CosmosContracts/juno/v15/x/globalfee/ante" - gaiaapp "github.com/CosmosContracts/juno/v15/app" + junoapp "github.com/CosmosContracts/juno/v15/app" "github.com/CosmosContracts/juno/v15/x/globalfee" globfeetypes "github.com/CosmosContracts/juno/v15/x/globalfee/types" ) @@ -27,7 +27,7 @@ import ( type IntegrationTestSuite struct { suite.Suite - app *gaiaapp.GaiaApp + app *junoapp.App ctx sdk.Context clientCtx client.Context txBuilder client.TxBuilder diff --git a/x/mint/client/testutil/suite.go b/x/mint/client/testutil/suite.go index a7638c36d..7fd881391 100644 --- a/x/mint/client/testutil/suite.go +++ b/x/mint/client/testutil/suite.go @@ -43,7 +43,9 @@ func (s *IntegrationTestSuite) SetupSuite() { genesisState[minttypes.ModuleName] = mintDataBz s.cfg.GenesisState = genesisState - s.network = network.New(s.T(), s.cfg) + baseDir := s.T().TempDir() + s.network, err = network.New(s.T(), baseDir, s.cfg) + s.Require().NoError(err) _, err = s.network.WaitForHeight(1) s.Require().NoError(err) diff --git a/x/mint/keeper/grpc_query_test.go b/x/mint/keeper/grpc_query_test.go index 8d22bf419..cc1765784 100644 --- a/x/mint/keeper/grpc_query_test.go +++ b/x/mint/keeper/grpc_query_test.go @@ -26,7 +26,7 @@ func (suite *MintTestSuite) SetupTest() { ctx := app.BaseApp.NewContext(false, tmproto.Header{}) queryHelper := baseapp.NewQueryServerTestHelper(ctx, app.InterfaceRegistry()) - types.RegisterQueryServer(queryHelper, app.MintKeeper) + types.RegisterQueryServer(queryHelper, app.AppKeepers.MintKeeper) queryClient := types.NewQueryClient(queryHelper) suite.app = app @@ -40,15 +40,15 @@ func (suite *MintTestSuite) TestGRPCParams() { params, err := queryClient.Params(gocontext.Background(), &types.QueryParamsRequest{}) suite.Require().NoError(err) - suite.Require().Equal(params.Params, app.MintKeeper.GetParams(ctx)) + suite.Require().Equal(params.Params, app.AppKeepers.MintKeeper.GetParams(ctx)) inflation, err := queryClient.Inflation(gocontext.Background(), &types.QueryInflationRequest{}) suite.Require().NoError(err) - suite.Require().Equal(inflation.Inflation, app.MintKeeper.GetMinter(ctx).Inflation) + suite.Require().Equal(inflation.Inflation, app.AppKeepers.MintKeeper.GetMinter(ctx).Inflation) annualProvisions, err := queryClient.AnnualProvisions(gocontext.Background(), &types.QueryAnnualProvisionsRequest{}) suite.Require().NoError(err) - suite.Require().Equal(annualProvisions.AnnualProvisions, app.MintKeeper.GetMinter(ctx).AnnualProvisions) + suite.Require().Equal(annualProvisions.AnnualProvisions, app.AppKeepers.MintKeeper.GetMinter(ctx).AnnualProvisions) } func TestMintTestSuite(t *testing.T) { diff --git a/x/mint/keeper/integration_test.go b/x/mint/keeper/integration_test.go index 36a630eb7..2c816b1d5 100644 --- a/x/mint/keeper/integration_test.go +++ b/x/mint/keeper/integration_test.go @@ -3,12 +3,13 @@ package keeper_test import ( "encoding/json" + "github.com/CosmWasm/wasmd/x/wasm" dbm "github.com/cometbft/cometbft-db" abci "github.com/cometbft/cometbft/abci/types" "github.com/cometbft/cometbft/libs/log" tmproto "github.com/cometbft/cometbft/proto/tendermint/types" + simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" - "cosmossdk.io/simapp" junoapp "github.com/CosmosContracts/juno/v15/app" "github.com/CosmosContracts/juno/v15/x/mint/types" @@ -20,8 +21,8 @@ func createTestApp(isCheckTx bool) (*junoapp.App, sdk.Context) { //nolint:unpara app := setup(isCheckTx) ctx := app.BaseApp.NewContext(isCheckTx, tmproto.Header{}) - app.MintKeeper.SetParams(ctx, types.DefaultParams()) - app.MintKeeper.SetMinter(ctx, types.DefaultInitialMinter()) + app.AppKeepers.MintKeeper.SetParams(ctx, types.DefaultParams()) + app.AppKeepers.MintKeeper.SetMinter(ctx, types.DefaultInitialMinter()) return app, ctx } @@ -39,7 +40,7 @@ func setup(isCheckTx bool) *junoapp.App { app.InitChain( abci.RequestInitChain{ Validators: []abci.ValidatorUpdate{}, - ConsensusParams: simapp.DefaultConsensusParams, + ConsensusParams: simtestutil.DefaultConsensusParams, AppStateBytes: stateBytes, }, ) @@ -51,18 +52,17 @@ func setup(isCheckTx bool) *junoapp.App { func genApp(withGenesis bool, invCheckPeriod uint) (*junoapp.App, junoapp.GenesisState) { db := dbm.NewMemDB() encCdc := junoapp.MakeEncodingConfig() + + var emptyWasmOpts []wasm.Option + app := junoapp.New( log.NewNopLogger(), db, nil, true, - map[int64]bool{}, - simapp.DefaultNodeHome, - invCheckPeriod, - encCdc, - junoapp.GetEnabledProposals(), - simapp.EmptyAppOptions{}, - junoapp.GetWasmOpts(simapp.EmptyAppOptions{}), + wasm.EnableAllProposals, + simtestutil.EmptyAppOptions{}, + emptyWasmOpts, ) if withGenesis { diff --git a/x/mint/keeper/keeper.go b/x/mint/keeper/keeper.go index 488996418..4a684c7d7 100644 --- a/x/mint/keeper/keeper.go +++ b/x/mint/keeper/keeper.go @@ -6,15 +6,15 @@ import ( "github.com/CosmosContracts/juno/v15/x/mint/types" "github.com/cosmos/cosmos-sdk/codec" + storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" - sdktypes "github.com/cosmos/cosmos-sdk/types" ) // Keeper of the mint store type Keeper struct { cdc codec.BinaryCodec - storeKey sdktypes.StoreKey + storeKey storetypes.StoreKey paramSpace paramtypes.Subspace stakingKeeper types.StakingKeeper bankKeeper types.BankKeeper @@ -23,7 +23,7 @@ type Keeper struct { // NewKeeper creates a new mint Keeper instance func NewKeeper( - cdc codec.BinaryCodec, key sdktypes.StoreKey, paramSpace paramtypes.Subspace, + cdc codec.BinaryCodec, key storetypes.StoreKey, paramSpace paramtypes.Subspace, sk types.StakingKeeper, ak types.AccountKeeper, bk types.BankKeeper, feeCollectorName string, ) Keeper { diff --git a/x/mint/keeper/querier_test.go b/x/mint/keeper/querier_test.go index 6bd8d8581..12bebbf06 100644 --- a/x/mint/keeper/querier_test.go +++ b/x/mint/keeper/querier_test.go @@ -17,7 +17,7 @@ import ( func TestNewQuerier(t *testing.T) { app, ctx := createTestApp(true) legacyQuerierCdc := codec.NewAminoCodec(app.LegacyAmino()) - querier := keep.NewQuerier(app.MintKeeper, legacyQuerierCdc.LegacyAmino) + querier := keep.NewQuerier(app.AppKeepers.MintKeeper, legacyQuerierCdc.LegacyAmino) query := abci.RequestQuery{ Path: "", @@ -40,7 +40,7 @@ func TestNewQuerier(t *testing.T) { func TestQueryParams(t *testing.T) { app, ctx := createTestApp(true) legacyQuerierCdc := codec.NewAminoCodec(app.LegacyAmino()) - querier := keep.NewQuerier(app.MintKeeper, legacyQuerierCdc.LegacyAmino) + querier := keep.NewQuerier(app.AppKeepers.MintKeeper, legacyQuerierCdc.LegacyAmino) var params types.Params @@ -50,13 +50,13 @@ func TestQueryParams(t *testing.T) { err := app.LegacyAmino().UnmarshalJSON(res, ¶ms) require.NoError(t, err) - require.Equal(t, app.MintKeeper.GetParams(ctx), params) + require.Equal(t, app.AppKeepers.MintKeeper.GetParams(ctx), params) } func TestQueryInflation(t *testing.T) { app, ctx := createTestApp(true) legacyQuerierCdc := codec.NewAminoCodec(app.LegacyAmino()) - querier := keep.NewQuerier(app.MintKeeper, legacyQuerierCdc.LegacyAmino) + querier := keep.NewQuerier(app.AppKeepers.MintKeeper, legacyQuerierCdc.LegacyAmino) var inflation sdk.Dec @@ -66,13 +66,13 @@ func TestQueryInflation(t *testing.T) { err := app.LegacyAmino().UnmarshalJSON(res, &inflation) require.NoError(t, err) - require.Equal(t, app.MintKeeper.GetMinter(ctx).Inflation, inflation) + require.Equal(t, app.AppKeepers.MintKeeper.GetMinter(ctx).Inflation, inflation) } func TestQueryAnnualProvisions(t *testing.T) { app, ctx := createTestApp(true) legacyQuerierCdc := codec.NewAminoCodec(app.LegacyAmino()) - querier := keep.NewQuerier(app.MintKeeper, legacyQuerierCdc.LegacyAmino) + querier := keep.NewQuerier(app.AppKeepers.MintKeeper, legacyQuerierCdc.LegacyAmino) var annualProvisions sdk.Dec @@ -82,5 +82,5 @@ func TestQueryAnnualProvisions(t *testing.T) { err := app.LegacyAmino().UnmarshalJSON(res, &annualProvisions) require.NoError(t, err) - require.Equal(t, app.MintKeeper.GetMinter(ctx).AnnualProvisions, annualProvisions) + require.Equal(t, app.AppKeepers.MintKeeper.GetMinter(ctx).AnnualProvisions, annualProvisions) } diff --git a/x/mint/simulation/genesis_test.go b/x/mint/simulation/genesis_test.go index 92e7bf2d1..21f81f8a6 100644 --- a/x/mint/simulation/genesis_test.go +++ b/x/mint/simulation/genesis_test.go @@ -5,6 +5,7 @@ import ( "math/rand" "testing" + "cosmossdk.io/math" "github.com/stretchr/testify/require" "github.com/CosmosContracts/juno/v15/x/mint/simulation" @@ -31,7 +32,7 @@ func TestRandomizedGenState(t *testing.T) { Rand: r, NumBonded: 3, Accounts: simtypes.RandomAccounts(r, 3), - InitialStake: 1000, + InitialStake: math.NewInt(1_000), GenState: make(map[string]json.RawMessage), } From 63b6db1a8d51c98594561dbc5b844a2cf2eb92c1 Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Fri, 28 Apr 2023 18:02:59 -0500 Subject: [PATCH 047/131] fix sim_test --- app/sim_test.go | 42 +++++++++++++++++++++++++++++------------- 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/app/sim_test.go b/app/sim_test.go index 06759d378..f4bbd5597 100644 --- a/app/sim_test.go +++ b/app/sim_test.go @@ -1,6 +1,7 @@ package app import ( + "encoding/json" "fmt" "os" "path/filepath" @@ -15,12 +16,14 @@ import ( dbm "github.com/cometbft/cometbft-db" "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/codec" + storetypes "github.com/cosmos/cosmos-sdk/store/types" + simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/kv" "github.com/cosmos/cosmos-sdk/types/module" simtypes "github.com/cosmos/cosmos-sdk/types/simulation" "github.com/cosmos/cosmos-sdk/x/simulation" - storetypes "github.com/cosmos/cosmos-sdk/store/types" + simcli "github.com/cosmos/cosmos-sdk/x/simulation/client/cli" ) // Get flags every time the simulator is run @@ -36,7 +39,10 @@ type StoreKeysPrefixes struct { // SetupSimulation wraps simapp.SetupSimulation in order to create any export directory if they do not exist yet func SetupSimulation(dirPrefix, dbName string) (simtypes.Config, dbm.DB, string, log.Logger, bool, error) { - config, db, dir, logger, skip, err := simapp.SetupSimulation(dirPrefix, dbName) + config := simcli.NewConfigFromFlags() + config.ChainID = SimAppChainID + + db, dir, logger, skip, err := simtestutil.SetupSimulation(config, "leveldb-app-sim", "Simulation", simcli.FlagVerboseValue, simcli.FlagEnabledValue) if err != nil { return simtypes.Config{}, nil, "", nil, false, err } @@ -94,10 +100,20 @@ func TestFullAppSimulation(t *testing.T) { db.Close() require.NoError(t, os.RemoveAll(dir)) }() - encConf := MakeEncodingConfig() + // encConf := MakeEncodingConfig() updateAppSimulationFlag(true) - app := New(logger, db, nil, true, map[int64]bool{}, t.TempDir(), simapp.FlagPeriodValue, encConf, - wasm.EnableAllProposals, simapp.EmptyAppOptions{}, nil, fauxMerkleModeOpt) + + var emptyWasmOption []wasm.Option + app := New( + logger, + db, + nil, + true, + wasm.EnableAllProposals, + simtestutil.EmptyAppOptions{}, + emptyWasmOption, + fauxMerkleModeOpt, + ) require.Equal(t, "juno", app.Name()) // run randomized simulation @@ -105,32 +121,32 @@ func TestFullAppSimulation(t *testing.T) { t, os.Stdout, app.BaseApp, - AppStateFn(app.appCodec, app.SimulationManager()), + AppStateFn(app.appCodec, app.SimulationManager(), NewDefaultGenesisState(app.appCodec)), simtypes.RandomAccounts, // Replace with own random account function if using keys other than secp256k1 - simapp.SimulationOperations(app, app.AppCodec(), config), + simtestutil.SimulationOperations(app, app.AppCodec(), config), app.ModuleAccountAddrs(), config, app.AppCodec(), ) // export state and simParams before the simulation error is checked - err = simapp.CheckExportSimulation(app, config, simParams) + err = simtestutil.CheckExportSimulation(app, config, simParams) require.NoError(t, err) require.NoError(t, simErr) if config.Commit { - simapp.PrintStats(db) + simtestutil.PrintStats(db) } } // AppStateFn returns the initial application state using a genesis or the simulation parameters. // It panics if the user provides files for both of them. // If a file is not given for the genesis or the sim params, it creates a randomized one. -func AppStateFn(codec codec.Codec, manager *module.SimulationManager) simtypes.AppStateFn { +func AppStateFn(codec codec.Codec, manager *module.SimulationManager, genesisState map[string]json.RawMessage) simtypes.AppStateFn { // quick hack to setup app state genesis with our app modules simapp.ModuleBasics = ModuleBasics - if simapp.FlagGenesisTimeValue == 0 { // always set to have a block time - simapp.FlagGenesisTimeValue = time.Now().Unix() + if simcli.FlagGenesisTimeValue == 0 { // always set to have a block time + simcli.FlagGenesisTimeValue = time.Now().Unix() } - return simapp.AppStateFn(codec, manager) + return simtestutil.AppStateFn(codec, manager, genesisState) } From 3aa2c875a1062a2fadc6bc0b1ed400b0af10d908 Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Fri, 28 Apr 2023 18:14:53 -0500 Subject: [PATCH 048/131] Fix test: encoding, appkeepers + simulation --- app/apptesting/test_suite.go | 26 ++++++++++----------- x/feeshare/genesis_test.go | 6 ++--- x/feeshare/integration_test.go | 18 +++++++------- x/feeshare/keeper/keeper_test.go | 10 ++++---- x/feeshare/keeper/msg_server_test.go | 8 +++---- x/globalfee/ante/antetest/fee_test_setup.go | 10 ++++---- x/globalfee/genesis_test.go | 7 +++--- x/tokenfactory/bindings/helpers_test.go | 6 ++--- x/tokenfactory/simulation/operations.go | 17 +++++++------- 9 files changed, 54 insertions(+), 54 deletions(-) diff --git a/app/apptesting/test_suite.go b/app/apptesting/test_suite.go index 55f1372b5..de6c27b9d 100644 --- a/app/apptesting/test_suite.go +++ b/app/apptesting/test_suite.go @@ -7,7 +7,6 @@ import ( "time" "cosmossdk.io/math" - "cosmossdk.io/simapp" dbm "github.com/cometbft/cometbft-db" abci "github.com/cometbft/cometbft/abci/types" "github.com/cometbft/cometbft/crypto/ed25519" @@ -22,6 +21,7 @@ import ( "github.com/cosmos/cosmos-sdk/types/tx/signing" authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing" "github.com/cosmos/cosmos-sdk/x/authz" + banktestutil "github.com/cosmos/cosmos-sdk/x/bank/testutil" distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" "github.com/cosmos/cosmos-sdk/x/staking" @@ -96,13 +96,13 @@ func (s *KeeperTestHelper) Commit() { // FundAcc funds target address with specified amount. func (s *KeeperTestHelper) FundAcc(acc sdk.AccAddress, amounts sdk.Coins) { - err := simapp.FundAccount(s.App.AppKeepers.BankKeeper, s.Ctx, acc, amounts) + err := banktestutil.FundAccount(s.App.AppKeepers.BankKeeper, s.Ctx, acc, amounts) s.Require().NoError(err) } // FundModuleAcc funds target modules with specified amount. func (s *KeeperTestHelper) FundModuleAcc(moduleName string, amounts sdk.Coins) { - err := simapp.FundModuleAccount(s.App.AppKeepers.BankKeeper, s.Ctx, moduleName, amounts) + err := banktestutil.FundModuleAccount(s.App.AppKeepers.BankKeeper, s.Ctx, moduleName, amounts) s.Require().NoError(err) } @@ -115,12 +115,12 @@ func (s *KeeperTestHelper) MintCoins(coins sdk.Coins) { func (s *KeeperTestHelper) SetupValidator(bondStatus stakingtypes.BondStatus) sdk.ValAddress { valPub := secp256k1.GenPrivKey().PubKey() valAddr := sdk.ValAddress(valPub.Address()) - bondDenom := s.App.StakingKeeper.GetParams(s.Ctx).BondDenom + bondDenom := s.App.AppKeepers.StakingKeeper.GetParams(s.Ctx).BondDenom selfBond := sdk.NewCoins(sdk.Coin{Amount: sdk.NewInt(100), Denom: bondDenom}) s.FundAcc(sdk.AccAddress(valAddr), selfBond) - stakingHandler := staking.NewHandler(s.App.StakingKeeper) + stakingHandler := staking.NewHandler(s.App.AppKeepers.StakingKeeper) stakingCoin := sdk.NewCoin(sdk.DefaultBondDenom, selfBond[0].Amount) ZeroCommission := stakingtypes.NewCommissionRates(sdk.ZeroDec(), sdk.ZeroDec(), sdk.ZeroDec()) msg, err := stakingtypes.NewMsgCreateValidator(valAddr, valPub, stakingCoin, stakingtypes.Description{}, ZeroCommission, sdk.OneInt()) @@ -129,11 +129,11 @@ func (s *KeeperTestHelper) SetupValidator(bondStatus stakingtypes.BondStatus) sd s.Require().NoError(err) s.Require().NotNil(res) - val, found := s.App.StakingKeeper.GetValidator(s.Ctx, valAddr) + val, found := s.App.AppKeepers.StakingKeeper.GetValidator(s.Ctx, valAddr) s.Require().True(found) val = val.UpdateStatus(bondStatus) - s.App.StakingKeeper.SetValidator(s.Ctx, val) + s.App.AppKeepers.StakingKeeper.SetValidator(s.Ctx, val) consAddr, err := val.GetConsAddr() s.Suite.Require().NoError(err) @@ -146,7 +146,7 @@ func (s *KeeperTestHelper) SetupValidator(bondStatus stakingtypes.BondStatus) sd false, 0, ) - s.App.SlashingKeeper.SetValidatorSigningInfo(s.Ctx, consAddr, signingInfo) + s.App.AppKeepers.SlashingKeeper.SetValidatorSigningInfo(s.Ctx, consAddr, signingInfo) return valAddr } @@ -155,14 +155,14 @@ func (s *KeeperTestHelper) SetupValidator(bondStatus stakingtypes.BondStatus) sd func (s *KeeperTestHelper) BeginNewBlock() { var valAddr []byte - validators := s.App.StakingKeeper.GetAllValidators(s.Ctx) + validators := s.App.AppKeepers.StakingKeeper.GetAllValidators(s.Ctx) if len(validators) >= 1 { valAddrFancy, err := validators[0].GetConsAddr() s.Require().NoError(err) valAddr = valAddrFancy.Bytes() } else { valAddrFancy := s.SetupValidator(stakingtypes.Bonded) - validator, _ := s.App.StakingKeeper.GetValidator(s.Ctx, valAddrFancy) + validator, _ := s.App.AppKeepers.StakingKeeper.GetValidator(s.Ctx, valAddrFancy) valAddr2, _ := validator.GetConsAddr() valAddr = valAddr2.Bytes() } @@ -172,7 +172,7 @@ func (s *KeeperTestHelper) BeginNewBlock() { // BeginNewBlockWithProposer begins a new block with a proposer. func (s *KeeperTestHelper) BeginNewBlockWithProposer(proposer sdk.ValAddress) { - validator, found := s.App.StakingKeeper.GetValidator(s.Ctx, proposer) + validator, found := s.App.AppKeepers.StakingKeeper.GetValidator(s.Ctx, proposer) s.Assert().True(found) valConsAddr, err := validator.GetConsAddr() @@ -205,12 +205,12 @@ func (s *KeeperTestHelper) EndBlock() { // AllocateRewardsToValidator allocates reward tokens to a distribution module then allocates rewards to the validator address. func (s *KeeperTestHelper) AllocateRewardsToValidator(valAddr sdk.ValAddress, rewardAmt math.Int) { - validator, found := s.App.StakingKeeper.GetValidator(s.Ctx, valAddr) + validator, found := s.App.AppKeepers.StakingKeeper.GetValidator(s.Ctx, valAddr) s.Require().True(found) // allocate reward tokens to distribution module coins := sdk.Coins{sdk.NewCoin(sdk.DefaultBondDenom, rewardAmt)} - err := simapp.FundModuleAccount(s.App.AppKeepers.BankKeeper, s.Ctx, distrtypes.ModuleName, coins) + err := banktestutil.FundModuleAccount(s.App.AppKeepers.BankKeeper, s.Ctx, distrtypes.ModuleName, coins) s.Require().NoError(err) // allocate rewards to validator diff --git a/x/feeshare/genesis_test.go b/x/feeshare/genesis_test.go index 797408d82..6568eada9 100644 --- a/x/feeshare/genesis_test.go +++ b/x/feeshare/genesis_test.go @@ -100,14 +100,14 @@ func (suite *GenesisTestSuite) TestFeeShareInitGenesis() { if tc.expPanic { suite.Require().Panics(func() { - feeshare.InitGenesis(suite.ctx, suite.app.FeeShareKeeper, tc.genesis) + feeshare.InitGenesis(suite.ctx, suite.app.AppKeepers.FeeShareKeeper, tc.genesis) }) } else { suite.Require().NotPanics(func() { - feeshare.InitGenesis(suite.ctx, suite.app.FeeShareKeeper, tc.genesis) + feeshare.InitGenesis(suite.ctx, suite.app.AppKeepers.FeeShareKeeper, tc.genesis) }) - params := suite.app.FeeShareKeeper.GetParams(suite.ctx) + params := suite.app.AppKeepers.FeeShareKeeper.GetParams(suite.ctx) suite.Require().Equal(tc.genesis.Params, params) } }) diff --git a/x/feeshare/integration_test.go b/x/feeshare/integration_test.go index 3487b69ac..50d3f9bed 100644 --- a/x/feeshare/integration_test.go +++ b/x/feeshare/integration_test.go @@ -3,15 +3,16 @@ package feeshare_test import ( "encoding/json" + "github.com/CosmWasm/wasmd/x/wasm" dbm "github.com/cometbft/cometbft-db" abci "github.com/cometbft/cometbft/abci/types" "github.com/cometbft/cometbft/libs/log" tmproto "github.com/cometbft/cometbft/proto/tendermint/types" - "cosmossdk.io/simapp" junoapp "github.com/CosmosContracts/juno/v15/app" "github.com/CosmosContracts/juno/v15/x/mint/types" + simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" sdk "github.com/cosmos/cosmos-sdk/types" ) @@ -39,7 +40,7 @@ func Setup(isCheckTx bool) *junoapp.App { app.InitChain( abci.RequestInitChain{ Validators: []abci.ValidatorUpdate{}, - ConsensusParams: simapp.DefaultConsensusParams, + ConsensusParams: simtestutil.DefaultConsensusParams, AppStateBytes: stateBytes, }, ) @@ -51,18 +52,17 @@ func Setup(isCheckTx bool) *junoapp.App { func GenApp(withGenesis bool, invCheckPeriod uint) (*junoapp.App, junoapp.GenesisState) { db := dbm.NewMemDB() encCdc := junoapp.MakeEncodingConfig() + + var emptyWasmOpts []wasm.Option + app := junoapp.New( log.NewNopLogger(), db, nil, true, - map[int64]bool{}, - simapp.DefaultNodeHome, - invCheckPeriod, - encCdc, - junoapp.GetEnabledProposals(), - simapp.EmptyAppOptions{}, - junoapp.GetWasmOpts(simapp.EmptyAppOptions{}), + wasm.EnableAllProposals, + simtestutil.EmptyAppOptions{}, + emptyWasmOpts, ) if withGenesis { diff --git a/x/feeshare/keeper/keeper_test.go b/x/feeshare/keeper/keeper_test.go index 054a74cd1..484346ed0 100644 --- a/x/feeshare/keeper/keeper_test.go +++ b/x/feeshare/keeper/keeper_test.go @@ -42,7 +42,7 @@ type IntegrationTestSuite struct { func (s *IntegrationTestSuite) SetupTest() { isCheckTx := false - s.app = app.Setup(s.T(), isCheckTx, 1) + s.app = app.Setup(s.T()) s.ctx = s.app.BaseApp.NewContext(isCheckTx, tmproto.Header{ ChainID: fmt.Sprintf("test-chain-%s", tmrand.Str(4)), @@ -51,12 +51,12 @@ func (s *IntegrationTestSuite) SetupTest() { }) queryHelper := baseapp.NewQueryServerTestHelper(s.ctx, s.app.InterfaceRegistry()) - types.RegisterQueryServer(queryHelper, keeper.NewQuerier(s.app.FeeShareKeeper)) + types.RegisterQueryServer(queryHelper, keeper.NewQuerier(s.app.AppKeepers.FeeShareKeeper)) s.queryClient = types.NewQueryClient(queryHelper) - s.bankKeeper = s.app.BankKeeper - s.accountKeeper = s.app.AccountKeeper - s.feeShareMsgServer = s.app.FeeShareKeeper + s.bankKeeper = s.app.AppKeepers.BankKeeper + s.accountKeeper = s.app.AppKeepers.AccountKeeper + s.feeShareMsgServer = s.app.AppKeepers.FeeShareKeeper s.wasmMsgServer = wasmkeeper.NewMsgServerImpl(wasmkeeper.NewDefaultPermissionKeeper(s.app.WasmKeeper)) } diff --git a/x/feeshare/keeper/msg_server_test.go b/x/feeshare/keeper/msg_server_test.go index e2182e04a..79ed56701 100644 --- a/x/feeshare/keeper/msg_server_test.go +++ b/x/feeshare/keeper/msg_server_test.go @@ -27,7 +27,7 @@ func (s *IntegrationTestSuite) StoreCode() { expHash := sha256.Sum256(wasmContract) s.Require().Equal(expHash[:], result.Checksum) // and - info := s.app.WasmKeeper.GetCodeInfo(s.ctx, 1) + info := s.app.AppKeepers.WasmKeeper.GetCodeInfo(s.ctx, 1) s.Require().NotNil(info) s.Require().Equal(expHash[:], info.CodeHash) s.Require().Equal(sender.String(), info.Creator) @@ -51,7 +51,7 @@ func (s *IntegrationTestSuite) InstantiateContract(sender string, admin string) s.Require().NoError(err) var result wasmtypes.MsgInstantiateContractResponse s.Require().NoError(s.app.AppCodec().Unmarshal(resp.Data, &result)) - contractInfo := s.app.WasmKeeper.GetContractInfo(s.ctx, sdk.MustAccAddressFromBech32(result.Address)) + contractInfo := s.app.AppKeepers.WasmKeeper.GetContractInfo(s.ctx, sdk.MustAccAddressFromBech32(result.Address)) s.Require().Equal(contractInfo.CodeID, uint64(1)) s.Require().Equal(contractInfo.Admin, admin) s.Require().Equal(contractInfo.Creator, sender) @@ -96,10 +96,10 @@ func (s *IntegrationTestSuite) TestGetContractAdminOrCreatorAddress() { tc := tc s.Run(tc.desc, func() { if !tc.shouldErr { - _, err := s.app.FeeShareKeeper.GetContractAdminOrCreatorAddress(s.ctx, sdk.MustAccAddressFromBech32(tc.contractAddress), tc.deployerAddress) + _, err := s.app.AppKeepers.FeeShareKeeper.GetContractAdminOrCreatorAddress(s.ctx, sdk.MustAccAddressFromBech32(tc.contractAddress), tc.deployerAddress) s.Require().NoError(err) } else { - _, err := s.app.FeeShareKeeper.GetContractAdminOrCreatorAddress(s.ctx, sdk.MustAccAddressFromBech32(tc.contractAddress), tc.deployerAddress) + _, err := s.app.AppKeepers.FeeShareKeeper.GetContractAdminOrCreatorAddress(s.ctx, sdk.MustAccAddressFromBech32(tc.contractAddress), tc.deployerAddress) s.Require().Error(err) } }) diff --git a/x/globalfee/ante/antetest/fee_test_setup.go b/x/globalfee/ante/antetest/fee_test_setup.go index 0c035d172..c28696243 100644 --- a/x/globalfee/ante/antetest/fee_test_setup.go +++ b/x/globalfee/ante/antetest/fee_test_setup.go @@ -16,10 +16,12 @@ import ( stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/stretchr/testify/suite" - gaiahelpers "github.com/CosmosContracts/juno/v15/app/helpers" + // gaiahelpers "github.com/CosmosContracts/juno/v15/app/helpers" + "github.com/CosmosContracts/juno/v15/app" gaiafeeante "github.com/CosmosContracts/juno/v15/x/globalfee/ante" junoapp "github.com/CosmosContracts/juno/v15/app" + appparams "github.com/CosmosContracts/juno/v15/app/params" "github.com/CosmosContracts/juno/v15/x/globalfee" globfeetypes "github.com/CosmosContracts/juno/v15/x/globalfee/types" ) @@ -39,13 +41,13 @@ var ( ) func (s *IntegrationTestSuite) SetupTest() { - app := gaiahelpers.Setup(s.T()) + app := app.Setup(s.T()) ctx := app.BaseApp.NewContext(false, tmproto.Header{ ChainID: fmt.Sprintf("test-chain-%s", tmrand.Str(4)), Height: 1, }) - encodingConfig := gaiaapp.MakeTestEncodingConfig() + encodingConfig := appparams.MakeEncodingConfig() encodingConfig.Amino.RegisterConcrete(&testdata.TestMsg{}, "testdata.TestMsg", nil) testdata.RegisterInterfaces(encodingConfig.InterfaceRegistry) @@ -65,7 +67,7 @@ func (s *IntegrationTestSuite) SetupTestGlobalFeeStoreAndMinGasPrice(minGasPrice stakingSubspace := s.SetupTestStakingSubspace(stakingParam) // build fee decorator - feeDecorator := gaiafeeante.NewFeeDecorator(gaiaapp.GetDefaultBypassFeeMessages(), subspace, stakingSubspace, uint64(1_000_000)) + feeDecorator := gaiafeeante.NewFeeDecorator(app.GetDefaultBypassFeeMessages(), subspace, stakingSubspace, uint64(1_000_000)) // chain fee decorator to antehandler antehandler := sdk.ChainAnteDecorators(feeDecorator) diff --git a/x/globalfee/genesis_test.go b/x/globalfee/genesis_test.go index fa2e624eb..c4f23a011 100644 --- a/x/globalfee/genesis_test.go +++ b/x/globalfee/genesis_test.go @@ -4,7 +4,6 @@ import ( "testing" "time" - "cosmossdk.io/simapp" appparams "github.com/CosmosContracts/juno/v15/app/params" dbm "github.com/cometbft/cometbft-db" "github.com/cometbft/cometbft/libs/log" @@ -21,13 +20,13 @@ import ( ) func TestDefaultGenesis(t *testing.T) { - encCfg := simapp.MakeTestEncodingConfig() + encCfg := appparams.MakeEncodingConfig() gotJSON := AppModuleBasic{}.DefaultGenesis(encCfg.Marshaler) assert.JSONEq(t, `{"params":{"minimum_gas_prices":[]}}`, string(gotJSON), string(gotJSON)) } func TestValidateGenesis(t *testing.T) { - encCfg := simapp.MakeTestEncodingConfig() + encCfg := appparams.MakeEncodingConfig() specs := map[string]struct { src string expErr bool @@ -110,7 +109,7 @@ func setupTestStore(t *testing.T) (sdk.Context, appparams.EncodingConfig, params t.Helper() db := dbm.NewMemDB() ms := store.NewCommitMultiStore(db) - encCfg := simapp.MakeTestEncodingConfig() + encCfg := appparams.MakeEncodingConfig() keyParams := sdk.NewKVStoreKey(paramstypes.StoreKey) tkeyParams := sdk.NewTransientStoreKey(paramstypes.TStoreKey) ms.MountStoreWithDB(keyParams, storetypes.StoreTypeIAVL, db) diff --git a/x/tokenfactory/bindings/helpers_test.go b/x/tokenfactory/bindings/helpers_test.go index c1136d72c..415a0c21b 100644 --- a/x/tokenfactory/bindings/helpers_test.go +++ b/x/tokenfactory/bindings/helpers_test.go @@ -10,8 +10,8 @@ import ( "github.com/cometbft/cometbft/crypto" "github.com/cometbft/cometbft/crypto/ed25519" tmproto "github.com/cometbft/cometbft/proto/tendermint/types" + banktestutil "github.com/cosmos/cosmos-sdk/x/bank/testutil" - "cosmossdk.io/simapp" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/CosmWasm/wasmd/x/wasm/keeper" @@ -25,7 +25,7 @@ func CreateTestInput(t *testing.T) (*app.App, sdk.Context) { } func FundAccount(t *testing.T, ctx sdk.Context, junoapp *app.App, acct sdk.AccAddress) { - err := simapp.FundAccount(junoapp.AppKeepers.BankKeeper, ctx, acct, sdk.NewCoins( + err := banktestutil.FundAccount(junoapp.AppKeepers.BankKeeper, ctx, acct, sdk.NewCoins( sdk.NewCoin("uosmo", sdk.NewInt(10000000000)), )) require.NoError(t, err) @@ -70,7 +70,7 @@ func instantiateReflectContract(t *testing.T, ctx sdk.Context, junoapp *app.App, } func fundAccount(t *testing.T, ctx sdk.Context, junoapp *app.App, addr sdk.AccAddress, coins sdk.Coins) { - err := simapp.FundAccount( + err := banktestutil.FundAccount( junoapp.AppKeepers.BankKeeper, ctx, addr, diff --git a/x/tokenfactory/simulation/operations.go b/x/tokenfactory/simulation/operations.go index cb9c35f51..0f3892c62 100644 --- a/x/tokenfactory/simulation/operations.go +++ b/x/tokenfactory/simulation/operations.go @@ -3,8 +3,7 @@ package simulation import ( "math/rand" - simappparams "cosmossdk.io/simapp/params" - "github.com/CosmosContracts/juno/v15/app/params" + appparams "github.com/CosmosContracts/juno/v15/app/params" "github.com/CosmosContracts/juno/v15/x/tokenfactory/types" "github.com/cosmos/cosmos-sdk/baseapp" sdk "github.com/cosmos/cosmos-sdk/types" @@ -56,32 +55,32 @@ func WeightedOperations( simstate.AppParams.GetOrGenerate(simstate.Cdc, OpWeightMsgCreateDenom, &weightMsgCreateDenom, nil, func(_ *rand.Rand) { - weightMsgCreateDenom = params.DefaultWeightMsgCreateDenom + weightMsgCreateDenom = appparams.DefaultWeightMsgCreateDenom }, ) simstate.AppParams.GetOrGenerate(simstate.Cdc, OpWeightMsgMint, &weightMsgMint, nil, func(_ *rand.Rand) { - weightMsgMint = params.DefaultWeightMsgMint + weightMsgMint = appparams.DefaultWeightMsgMint }, ) simstate.AppParams.GetOrGenerate(simstate.Cdc, OpWeightMsgBurn, &weightMsgBurn, nil, func(_ *rand.Rand) { - weightMsgBurn = params.DefaultWeightMsgBurn + weightMsgBurn = appparams.DefaultWeightMsgBurn }, ) simstate.AppParams.GetOrGenerate(simstate.Cdc, OpWeightMsgChangeAdmin, &weightMsgChangeAdmin, nil, func(_ *rand.Rand) { - weightMsgChangeAdmin = params.DefaultWeightMsgChangeAdmin + weightMsgChangeAdmin = appparams.DefaultWeightMsgChangeAdmin }, ) simstate.AppParams.GetOrGenerate(simstate.Cdc, OpWeightMsgSetDenomMetadata, &weightMsgSetDenomMetadata, nil, func(_ *rand.Rand) { - weightMsgSetDenomMetadata = params.DefaultWeightMsgSetDenomMetadata + weightMsgSetDenomMetadata = appparams.DefaultWeightMsgSetDenomMetadata }, ) simstate.AppParams.GetOrGenerate(simstate.Cdc, OpWeightMsgForceTransfer, &weightMsgForceTransfer, nil, func(_ *rand.Rand) { - weightMsgForceTransfer = params.DefaultWeightMsgForceTransfer + weightMsgForceTransfer = appparams.DefaultWeightMsgForceTransfer }, ) @@ -397,7 +396,7 @@ func BuildOperationInput( return simulation.OperationInput{ R: r, App: app, - TxGen: simappparams.MakeTestEncodingConfig().TxConfig, + TxGen: appparams.MakeEncodingConfig().TxConfig, Cdc: nil, Msg: msg, MsgType: msg.Type(), From 9e7f3f58f16c396cc21e5b5aa3cfff54bf1bad21 Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Fri, 28 Apr 2023 18:20:06 -0500 Subject: [PATCH 049/131] globalfee: rm Route & LegacyQuerierHandler --- x/globalfee/module.go | 8 -------- 1 file changed, 8 deletions(-) diff --git a/x/globalfee/module.go b/x/globalfee/module.go index 91072ce0b..18fb742a3 100644 --- a/x/globalfee/module.go +++ b/x/globalfee/module.go @@ -106,18 +106,10 @@ func (a AppModule) ExportGenesis(ctx sdk.Context, marshaler codec.JSONCodec) jso func (a AppModule) RegisterInvariants(_ sdk.InvariantRegistry) { } -func (a AppModule) Route() sdk.Route { - return sdk.Route{} -} - func (a AppModule) QuerierRoute() string { return types.QuerierRoute } -func (a AppModule) LegacyQuerierHandler(_ *codec.LegacyAmino) sdk.Querier { - return nil -} - func (a AppModule) RegisterServices(cfg module.Configurator) { types.RegisterQueryServer(cfg.QueryServer(), NewGrpcQuerier(a.paramSpace)) } From f8e13090040032610057acc3bff931540888c457 Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Fri, 28 Apr 2023 18:23:55 -0500 Subject: [PATCH 050/131] Fix gov spam filter --- app/decorators/gov_filter.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/app/decorators/gov_filter.go b/app/decorators/gov_filter.go index 306e9cb8f..d18ea2cc2 100644 --- a/app/decorators/gov_filter.go +++ b/app/decorators/gov_filter.go @@ -46,10 +46,12 @@ func (gpsd GovPreventSpamDecorator) checkSpamSubmitProposalMsg(ctx sdk.Context, validMsg := func(m sdk.Msg) error { if msg, ok := m.(*govv1.MsgSubmitProposal); ok { // prevent spam gov msg - depositParams := gpsd.govKeeper.GetDepositParams(ctx) + depositParams := gpsd.govKeeper.GetParams(ctx) miniumInitialDeposit := gpsd.calcMiniumInitialDeposit(depositParams.MinDeposit) - if msg.InitialDeposit.IsAllLT(miniumInitialDeposit) { - return errorsmod.Wrapf(sdkerrors.ErrUnauthorized, "not enough initial deposit. required: %v", miniumInitialDeposit) + for _, coin := range msg.InitialDeposit { + if coin.Amount.LT(miniumInitialDeposit.AmountOf(coin.Denom)) { + return errorsmod.Wrapf(sdkerrors.ErrUnauthorized, "not enough initial deposit. required: %v", miniumInitialDeposit) + } } } return nil From 320fa689c65a40a16cc14edc42968167fe47ec8e Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Fri, 28 Apr 2023 18:38:30 -0500 Subject: [PATCH 051/131] fix ibc-hooks wasm keeper + test --- app/ante.go | 1 - app/keepers/keepers.go | 4 ++-- app/test_helpers.go | 4 ++-- x/feeshare/keeper/keeper_test.go | 2 +- x/ibc-hooks/wasm_hook.go | 4 ++-- 5 files changed, 7 insertions(+), 8 deletions(-) diff --git a/app/ante.go b/app/ante.go index 82f4c69dd..69da4e06f 100644 --- a/app/ante.go +++ b/app/ante.go @@ -77,7 +77,6 @@ func NewAnteHandler(options HandlerOptions) (sdk.AnteHandler, error) { ante.NewExtensionOptionsDecorator(options.ExtensionOptionChecker), decorators.MsgFilterDecorator{}, decorators.NewGovPreventSpamDecorator(options.Cdc, options.GovKeeper), - ante.NewMempoolFeeDecorator(), ante.NewValidateBasicDecorator(), ante.NewTxTimeoutHeightDecorator(), ante.NewValidateMemoDecorator(options.AccountKeeper), diff --git a/app/keepers/keepers.go b/app/keepers/keepers.go index b3e300730..ef23c7375 100644 --- a/app/keepers/keepers.go +++ b/app/keepers/keepers.go @@ -146,7 +146,7 @@ type AppKeepers struct { AuthzKeeper authzkeeper.Keeper FeeGrantKeeper feegrantkeeper.Keeper FeeShareKeeper feesharekeeper.Keeper - ContractKeeper *wasmkeeper.PermissionedKeeper + ContractKeeper *wasmkeeper.Keeper ConsensusParamsKeeper consensusparamkeeper.Keeper ICAControllerKeeper icacontrollerkeeper.Keeper @@ -571,7 +571,7 @@ func NewAppKeepers( appKeepers.ScopedICAControllerKeeper = scopedICAControllerKeeper // set the contract keeper for the Ics20WasmHooks - appKeepers.ContractKeeper = wasmkeeper.NewDefaultPermissionKeeper(appKeepers.WasmKeeper) + appKeepers.ContractKeeper = &appKeepers.WasmKeeper appKeepers.Ics20WasmHooks.ContractKeeper = appKeepers.ContractKeeper return appKeepers diff --git a/app/test_helpers.go b/app/test_helpers.go index 44dfa963f..88cc9af70 100644 --- a/app/test_helpers.go +++ b/app/test_helpers.go @@ -6,7 +6,7 @@ import ( "time" "github.com/CosmWasm/wasmd/x/wasm" - "github.com/CosmWasm/wasmd/x/wasm/keeper" + "github.com/CosmWasm/wasmd/x/wasm/keeper" apphelpers "github.com/CosmosContracts/juno/v15/app/helpers" appparams "github.com/CosmosContracts/juno/v15/app/params" dbm "github.com/cometbft/cometbft-db" @@ -244,7 +244,7 @@ func ExecuteRawCustom(t *testing.T, ctx sdk.Context, app *App, contract sdk.AccA coins = sdk.Coins{funds} } - contractKeeper := keeper.NewDefaultPermissionKeeper(app.GetWasmKeeper()) + contractKeeper := keeper.NewDefaultPermissionKeeper(app.AppKeepers.WasmKeeper) _, err = contractKeeper.Execute(ctx, contract, sender, oracleBz, coins) return err } diff --git a/x/feeshare/keeper/keeper_test.go b/x/feeshare/keeper/keeper_test.go index 484346ed0..25325620a 100644 --- a/x/feeshare/keeper/keeper_test.go +++ b/x/feeshare/keeper/keeper_test.go @@ -57,7 +57,7 @@ func (s *IntegrationTestSuite) SetupTest() { s.bankKeeper = s.app.AppKeepers.BankKeeper s.accountKeeper = s.app.AppKeepers.AccountKeeper s.feeShareMsgServer = s.app.AppKeepers.FeeShareKeeper - s.wasmMsgServer = wasmkeeper.NewMsgServerImpl(wasmkeeper.NewDefaultPermissionKeeper(s.app.WasmKeeper)) + s.wasmMsgServer = wasmkeeper.NewMsgServerImpl((*wasmkeeper.Keeper)(wasmkeeper.NewDefaultPermissionKeeper(s.app.AppKeepers.WasmKeeper))) } func (s *IntegrationTestSuite) FundAccount(ctx sdk.Context, addr sdk.AccAddress, amounts sdk.Coins) error { diff --git a/x/ibc-hooks/wasm_hook.go b/x/ibc-hooks/wasm_hook.go index be38c953c..47d55b431 100644 --- a/x/ibc-hooks/wasm_hook.go +++ b/x/ibc-hooks/wasm_hook.go @@ -28,12 +28,12 @@ type ContractAck struct { } type WasmHooks struct { - ContractKeeper *wasmkeeper.PermissionedKeeper + ContractKeeper *wasmkeeper.Keeper ibcHooksKeeper *keeper.Keeper bech32PrefixAccAddr string } -func NewWasmHooks(ibcHooksKeeper *keeper.Keeper, contractKeeper *wasmkeeper.PermissionedKeeper, bech32PrefixAccAddr string) WasmHooks { +func NewWasmHooks(ibcHooksKeeper *keeper.Keeper, contractKeeper *wasmkeeper.Keeper, bech32PrefixAccAddr string) WasmHooks { return WasmHooks{ ContractKeeper: contractKeeper, ibcHooksKeeper: ibcHooksKeeper, From dbe6b10d416302c99d26265030a33f0fad20ac0c Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Fri, 28 Apr 2023 18:49:35 -0500 Subject: [PATCH 052/131] Remove Osmo Utils (keeping ibc.go file for ibc-hooks() --- go.mod | 4 +- go.sum | 16 +- osmoutils/accum/accum.go | 401 ----- osmoutils/accum/accum.pb.go | 860 --------- osmoutils/accum/accum_helpers.go | 61 - osmoutils/accum/accum_helpers_test.go | 50 - osmoutils/accum/accum_test.go | 1568 ----------------- osmoutils/accum/errors.go | 44 - osmoutils/accum/export_test.go | 77 - osmoutils/accum/module.go | 3 - osmoutils/accum/options.go | 20 - osmoutils/accum/options_test.go | 32 - osmoutils/accum/prefix.go | 30 - osmoutils/address.go | 12 - osmoutils/cache_ctx.go | 80 - osmoutils/cache_ctx_test.go | 59 - osmoutils/cli_helpers.go | 77 - osmoutils/coin_helper.go | 46 - osmoutils/coin_helper_test.go | 83 - osmoutils/conv_helper.go | 16 - osmoutils/cosmwasm/helpers.go | 223 --- osmoutils/encoding_helper.go | 25 - osmoutils/encoding_helper_test.go | 29 - osmoutils/export_test.go | 11 - osmoutils/generic_helper.go | 17 - osmoutils/go.mod | 142 -- osmoutils/go.sum | 1352 -------------- osmoutils/module_account.go | 86 - osmoutils/module_account_test.go | 66 - osmoutils/noapptest/cdc.go | 45 - osmoutils/noapptest/ctx.go | 33 - osmoutils/osmoassert/assertions.go | 60 - osmoutils/osmocli/cli_tester.go | 111 -- osmoutils/osmocli/flag_advice.go | 79 - osmoutils/osmocli/index_cmd.go | 31 - osmoutils/osmocli/parsers.go | 344 ---- osmoutils/osmocli/parsers_test.go | 166 -- osmoutils/osmocli/query_cmd_wrap.go | 181 -- osmoutils/osmocli/string_formatter.go | 49 - osmoutils/osmocli/tx_cmd_wrap.go | 102 -- osmoutils/parse.go | 71 - osmoutils/partialord/internal/dag/dag.go | 320 ---- osmoutils/partialord/internal/dag/dag_test.go | 154 -- osmoutils/partialord/internal/dag/module.go | 9 - osmoutils/partialord/module.go | 2 - osmoutils/partialord/partialord.go | 97 - osmoutils/partialord/partialord_test.go | 74 - osmoutils/slice_helper.go | 94 - osmoutils/slice_helper_test.go | 93 - osmoutils/store_helper.go | 194 -- osmoutils/store_helper_test.go | 1246 ------------- osmoutils/sumtree/README.md | 151 -- osmoutils/sumtree/constants.go | 13 - osmoutils/sumtree/legacy/v101/old_tree.json | 12 - osmoutils/sumtree/legacy/v101/tree.go | 102 -- osmoutils/sumtree/legacy/v101/tree_test.go | 147 -- osmoutils/sumtree/node.go | 262 --- osmoutils/sumtree/tree.go | 296 ---- osmoutils/sumtree/tree.pb.go | 737 -------- osmoutils/sumtree/tree_test.go | 136 -- x/ibc-hooks/sdkmodule.go | 6 +- 61 files changed, 13 insertions(+), 10894 deletions(-) delete mode 100644 osmoutils/accum/accum.go delete mode 100644 osmoutils/accum/accum.pb.go delete mode 100644 osmoutils/accum/accum_helpers.go delete mode 100644 osmoutils/accum/accum_helpers_test.go delete mode 100644 osmoutils/accum/accum_test.go delete mode 100644 osmoutils/accum/errors.go delete mode 100644 osmoutils/accum/export_test.go delete mode 100644 osmoutils/accum/module.go delete mode 100644 osmoutils/accum/options.go delete mode 100644 osmoutils/accum/options_test.go delete mode 100644 osmoutils/accum/prefix.go delete mode 100644 osmoutils/address.go delete mode 100644 osmoutils/cache_ctx.go delete mode 100644 osmoutils/cache_ctx_test.go delete mode 100644 osmoutils/cli_helpers.go delete mode 100644 osmoutils/coin_helper.go delete mode 100644 osmoutils/coin_helper_test.go delete mode 100644 osmoutils/conv_helper.go delete mode 100644 osmoutils/cosmwasm/helpers.go delete mode 100644 osmoutils/encoding_helper.go delete mode 100644 osmoutils/encoding_helper_test.go delete mode 100644 osmoutils/export_test.go delete mode 100644 osmoutils/generic_helper.go delete mode 100644 osmoutils/go.mod delete mode 100644 osmoutils/go.sum delete mode 100644 osmoutils/module_account.go delete mode 100644 osmoutils/module_account_test.go delete mode 100644 osmoutils/noapptest/cdc.go delete mode 100644 osmoutils/noapptest/ctx.go delete mode 100644 osmoutils/osmoassert/assertions.go delete mode 100644 osmoutils/osmocli/cli_tester.go delete mode 100644 osmoutils/osmocli/flag_advice.go delete mode 100644 osmoutils/osmocli/index_cmd.go delete mode 100644 osmoutils/osmocli/parsers.go delete mode 100644 osmoutils/osmocli/parsers_test.go delete mode 100644 osmoutils/osmocli/query_cmd_wrap.go delete mode 100644 osmoutils/osmocli/string_formatter.go delete mode 100644 osmoutils/osmocli/tx_cmd_wrap.go delete mode 100644 osmoutils/parse.go delete mode 100644 osmoutils/partialord/internal/dag/dag.go delete mode 100644 osmoutils/partialord/internal/dag/dag_test.go delete mode 100644 osmoutils/partialord/internal/dag/module.go delete mode 100644 osmoutils/partialord/module.go delete mode 100644 osmoutils/partialord/partialord.go delete mode 100644 osmoutils/partialord/partialord_test.go delete mode 100644 osmoutils/slice_helper.go delete mode 100644 osmoutils/slice_helper_test.go delete mode 100644 osmoutils/store_helper.go delete mode 100644 osmoutils/store_helper_test.go delete mode 100644 osmoutils/sumtree/README.md delete mode 100644 osmoutils/sumtree/constants.go delete mode 100644 osmoutils/sumtree/legacy/v101/old_tree.json delete mode 100644 osmoutils/sumtree/legacy/v101/tree.go delete mode 100644 osmoutils/sumtree/legacy/v101/tree_test.go delete mode 100644 osmoutils/sumtree/node.go delete mode 100644 osmoutils/sumtree/tree.go delete mode 100644 osmoutils/sumtree/tree.pb.go delete mode 100644 osmoutils/sumtree/tree_test.go diff --git a/go.mod b/go.mod index f25975e04..055cc46ae 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,6 @@ require ( cosmossdk.io/math v1.0.0 cosmossdk.io/simapp v0.0.0-20230224204036-a6adb0821462 github.com/CosmWasm/wasmd v0.40.0-rc.1.0.20230422061626-b85abcf1d7b8 - github.com/CosmosContracts/juno/v15/osmoutils v0.0.0-00010101000000-000000000000 github.com/cometbft/cometbft v0.37.1 github.com/cometbft/cometbft-db v0.8.0 github.com/cosmos/cosmos-sdk v0.47.2 @@ -182,7 +181,8 @@ replace ( // cosmos keyring github.com/99designs/keyring => github.com/cosmos/keyring v1.2.0 - github.com/CosmosContracts/juno/v15/osmoutils => ./osmoutils + // ibc hooks only requires the ibc.go file from osmoutils + // github.com/CosmosContracts/juno/v15/osmoutils => ./osmoutils // github.com/cosmos/cosmos-sdk => github.com/notional-labs/cosmos-sdk v0.47.2-0.20230424060617-ebc292e8de8b // dgrijalva/jwt-go is deprecated and doesn't receive security updates. diff --git a/go.sum b/go.sum index c45ac10a2..af7592e25 100644 --- a/go.sum +++ b/go.sum @@ -295,8 +295,8 @@ github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx2 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.22.1 h1:CnwP9LM/M9xuRrGSCGeMVs9iv09uMqwsVX7EeIpgV2c= github.com/btcsuite/btcd v0.22.1/go.mod h1:wqgTSL29+50LRkmOVknEdmt8ZojIzhuWvgu/iptuN7Y= -github.com/btcsuite/btcd v0.22.2 h1:vBZ+lGGd1XubpOWO67ITJpAEsICWhA0YzqkcpkgNBfo= github.com/btcsuite/btcd/btcec/v2 v2.1.2/go.mod h1:ctjw4H1kknNJmRN4iP1R7bTQ+v3GJkZBd6mui8ZsAZE= github.com/btcsuite/btcd/btcec/v2 v2.3.2 h1:5n0X6hX0Zk+6omWcihdYvdAlGf2DfasC0GMf7DClJ3U= github.com/btcsuite/btcd/btcec/v2 v2.3.2/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= @@ -488,7 +488,7 @@ github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/ 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.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= +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= @@ -540,7 +540,7 @@ github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6Wezm github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo= github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= -github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= +github.com/goccy/go-json v0.9.11 h1:/pAaQDLHEoCq/5FFmSKBswWmK6H0e8g4159Kc/X/nqk= 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= @@ -729,8 +729,8 @@ github.com/hashicorp/go-safetemp v1.0.0/go.mod h1:oaerMy3BhqiTbVye6QuFhFtIceqFoD 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-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE= 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= @@ -782,7 +782,7 @@ github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+ 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.13.1-0.20220928232736-101791cb1b4c h1:XImQJfpJLmGEEd8ll5yPVyL/aEvmgGHW4WYTyNseLOM= +github.com/jhump/protoreflect v1.12.1-0.20220721211354-060cc04fc18b h1:izTof8BKh/nE1wrKOrloNA5q4odOarjf+Xpe+4qow98= 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= @@ -951,7 +951,7 @@ github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5 github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.26.0 h1:03cDLK28U6hWvCAns6NeydX3zIm4SF3ci69ulidS32Q= +github.com/onsi/gomega v1.20.0 h1:8W0cWlwFkflGPLltQvLRB7ZVD5HuP6ng320w2IS245Q= 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= @@ -1045,7 +1045,7 @@ github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6L github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= -github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= +github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/rs/cors v1.8.3 h1:O+qNyWn7Z+F9M0ILBHgMVPuB1xTOucVd5gtaYyXBpRo= github.com/rs/cors v1.8.3/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= @@ -1575,7 +1575,7 @@ golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.8.0 h1:vSDcovVPld282ceKgDimkRSC8kpaH1dgyc9UMzlt84Y= +golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= 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= diff --git a/osmoutils/accum/accum.go b/osmoutils/accum/accum.go deleted file mode 100644 index ed25a7d2d..000000000 --- a/osmoutils/accum/accum.go +++ /dev/null @@ -1,401 +0,0 @@ -package accum - -import ( - "errors" - "fmt" - - "github.com/cosmos/cosmos-sdk/store" - sdk "github.com/cosmos/cosmos-sdk/types" - - "github.com/CosmosContracts/juno/v15/osmoutils" -) - -// We keep this object as a way to interface with the methods, even though -// only the Accumulator inside is stored in state -type AccumulatorObject struct { - // Store where accumulator is stored - store store.KVStore - - // Accumulator's name (pulled from AccumulatorContent) - name string - - // Accumulator's current value (pulled from AccumulatorContent) - value sdk.DecCoins - - // Accumulator's total shares across all positions - totalShares sdk.Dec -} - -// Makes a new accumulator at store/accum/{accumName} -// Returns error if already exists / theres some overlapping keys -func MakeAccumulator(accumStore store.KVStore, accumName string) error { - if accumStore.Has(formatAccumPrefixKey(accumName)) { - return errors.New("Accumulator with given name already exists in store") - } - - // New accumulator values start out at zero - // TODO: consider whether this should be a parameter instead of always zero - initAccumValue := sdk.NewDecCoins() - initTotalShares := sdk.ZeroDec() - - newAccum := AccumulatorObject{accumStore, accumName, initAccumValue, initTotalShares} - - // Stores accumulator in state - setAccumulator(newAccum, initAccumValue, initTotalShares) - - return nil -} - -// Makes a new accumulator at store/accum/{accumName} -// Returns error if already exists / theres some overlapping keys -func MakeAccumulatorWithValueAndShare(accumStore store.KVStore, accumName string, accumValue sdk.DecCoins, totalShares sdk.Dec) error { - if accumStore.Has(formatAccumPrefixKey(accumName)) { - return errors.New("Accumulator with given name already exists in store") - } - - newAccum := AccumulatorObject{accumStore, accumName, accumValue, totalShares} - - // Stores accumulator in state - setAccumulator(newAccum, accumValue, totalShares) - - return nil -} - -// Gets the current value of the accumulator corresponding to accumName in accumStore -func GetAccumulator(accumStore store.KVStore, accumName string) (AccumulatorObject, error) { - accumContent := AccumulatorContent{} - found, err := osmoutils.Get(accumStore, formatAccumPrefixKey(accumName), &accumContent) - if err != nil { - return AccumulatorObject{}, err - } - if !found { - return AccumulatorObject{}, AccumDoesNotExistError{AccumName: accumName} - } - - accum := AccumulatorObject{accumStore, accumName, accumContent.AccumValue, accumContent.TotalShares} - - return accum, nil -} - -// MustGetPosition returns the position associated with the given address. No errors in position retrieval are allowed. -func (accum AccumulatorObject) MustGetPosition(name string) Record { - position := Record{} - osmoutils.MustGet(accum.store, FormatPositionPrefixKey(accum.name, name), &position) - return position -} - -// GetPosition returns the position associated with the given address. If the position does not exist, returns an error. -func (accum AccumulatorObject) GetPosition(name string) (Record, error) { - position := Record{} - found, err := osmoutils.Get(accum.store, FormatPositionPrefixKey(accum.name, name), &position) - if err != nil { - return Record{}, err - } - - if !found { - return Record{}, fmt.Errorf("position with name %s does not exist", name) - } - return position, nil -} - -func setAccumulator(accum AccumulatorObject, value sdk.DecCoins, shares sdk.Dec) { - newAccum := AccumulatorContent{value, shares} - osmoutils.MustSet(accum.store, formatAccumPrefixKey(accum.name), &newAccum) -} - -// AddToAccumulator updates the accumulator's value by amt. -// It does so by increasing the value of the accumulator by -// the given amount. Persists to store. Mutates the receiver. -func (accum *AccumulatorObject) AddToAccumulator(amt sdk.DecCoins) { - accum.value = accum.value.Add(amt...) - setAccumulator(*accum, accum.value, accum.totalShares) -} - -// NewPosition creates a new position for the given name, with the given number of share units. -// The name can be an owner's address, or any other unique identifier for a position. -// It takes a snapshot of the current accumulator value, and sets the position's initial value to that. -// The position is initialized with empty unclaimed rewards -// If there is an existing position for the given address, it is overwritten. -func (accum AccumulatorObject) NewPosition(name string, numShareUnits sdk.Dec, options *Options) error { - return accum.NewPositionCustomAcc(name, numShareUnits, accum.value, options) -} - -// NewPositionCustomAcc creates a new position for the given name, with the given number of share units. -// The name can be an owner's address, or any other unique identifier for a position. -// It sets the position's accumulator to the given value of customAccumulatorValue. -// All custom accumulator values must be non-negative. -// The position is initialized with empty unclaimed rewards -// If there is an existing position for the given address, it is overwritten. -func (accum AccumulatorObject) NewPositionCustomAcc(name string, numShareUnits sdk.Dec, customAccumulatorValue sdk.DecCoins, options *Options) error { - if customAccumulatorValue.IsAnyNegative() { - return NegativeCustomAccError{customAccumulatorValue} - } - - if err := options.validate(); err != nil { - return err - } - - initOrUpdatePosition(accum, customAccumulatorValue, name, numShareUnits, sdk.NewDecCoins(), options) - - // Update total shares in accum (re-fetch accum from state to ensure it's up to date) - accum, err := GetAccumulator(accum.store, accum.name) - if err != nil { - return err - } - setAccumulator(accum, accum.value, accum.totalShares.Add(numShareUnits)) - - return nil -} - -// AddToPosition adds newShares of shares to an existing position with the given name. -// This is functionally equivalent to claiming rewards, closing down the position, and -// opening a fresh one with the new number of shares. We can represent this behavior by -// claiming rewards and moving up the accumulator start value to its current value. -// -// An alternative approach is to simply generate an additional position every time an -// address adds to its position. We do not pursue this path because we want to ensure -// that withdrawal and claiming functions remain constant time and do not scale with the -// number of times a user has added to their position. -// -// Returns nil on success. Returns error when: -// - newShares are negative or zero. -// - there is no existing position at the given address -// - other internal or database error occurs. -func (accum AccumulatorObject) AddToPosition(name string, newShares sdk.Dec) error { - return accum.AddToPositionCustomAcc(name, newShares, accum.value) -} - -// AddToPositionCustomAcc adds newShares of shares to an existing position with the given name. -// This is functionally equivalent to claiming rewards, closing down the position, and -// opening a fresh one with the new number of shares. We can represent this behavior by -// claiming rewards. The accumulator of the new position is set to given customAccumulatorValue. -// All custom accumulator values must be non-negative. They must also be a superset of the -// old accumulator value associated with the position. -// -// An alternative approach is to simply generate an additional position every time an -// address adds to its position. We do not pursue this path because we want to ensure -// that withdrawal and claiming functions remain constant time and do not scale with the -// number of times a user has added to their position. -// -// Returns nil on success. Returns error when: -// - newShares are negative or zero. -// - there is no existing position at the given address -// - other internal or database error occurs. -func (accum AccumulatorObject) AddToPositionCustomAcc(name string, newShares sdk.Dec, customAccumulatorValue sdk.DecCoins) error { - if !newShares.IsPositive() { - return errors.New("Attempted to add zero or negative number of shares to a position") - } - - // Get addr's current position - position, err := GetPosition(accum, name) - if err != nil { - return err - } - - // Save current number of shares and unclaimed rewards - unclaimedRewards := GetTotalRewards(accum, position) - oldNumShares, err := accum.GetPositionSize(name) - if err != nil { - return err - } - - // Update user's position with new number of shares while moving its unaccrued rewards - // into UnclaimedRewards. Starting accumulator value is moved up to accum'scurrent value - initOrUpdatePosition(accum, customAccumulatorValue, name, oldNumShares.Add(newShares), unclaimedRewards, position.Options) - - // Update total shares in accum (re-fetch accum from state to ensure it's up to date) - accum, err = GetAccumulator(accum.store, accum.name) - if err != nil { - return err - } - setAccumulator(accum, accum.value, accum.totalShares.Add(newShares)) - - return nil -} - -// RemovePosition removes the specified number of shares from a position. Specifically, it claims -// the unclaimed and newly accrued rewards and returns them alongside the redeemed shares. Then, it -// overwrites the position record with the updated number of shares. Since it accrues rewards, it -// also moves up the position's accumulator value to the current accum val. -func (accum AccumulatorObject) RemoveFromPosition(name string, numSharesToRemove sdk.Dec) error { - return accum.RemoveFromPositionCustomAcc(name, numSharesToRemove, accum.value) -} - -// RemovePositionCustomAcc removes the specified number of shares from a position. Specifically, it claims -// the unclaimed and newly accrued rewards and returns them alongside the redeemed shares. Then, it -// overwrites the position record with the updated number of shares. Since it accrues rewards, it -// also resets the position's accumulator value to the given customAccumulatorValue. -// All custom accumulator values must be non-negative. They must also be a superset of the -// old accumulator value associated with the position. -func (accum AccumulatorObject) RemoveFromPositionCustomAcc(name string, numSharesToRemove sdk.Dec, customAccumulatorValue sdk.DecCoins) error { - // Cannot remove zero or negative shares - if numSharesToRemove.LTE(sdk.ZeroDec()) { - return fmt.Errorf("Attempted to remove no/negative shares (%s)", numSharesToRemove) - } - - // Get addr's current position - position, err := GetPosition(accum, name) - if err != nil { - return err - } - - // Ensure not removing more shares than exist - if numSharesToRemove.GT(position.NumShares) { - return fmt.Errorf("Attempted to remove more shares (%s) than exist in the position (%s)", numSharesToRemove, position.NumShares) - } - - // Save current number of shares and unclaimed rewards - unclaimedRewards := GetTotalRewards(accum, position) - oldNumShares, err := accum.GetPositionSize(name) - if err != nil { - return err - } - - // Update user's position with new number of shares - initOrUpdatePosition(accum, customAccumulatorValue, name, oldNumShares.Sub(numSharesToRemove), unclaimedRewards, position.Options) - - // Update total shares in accum (re-fetch accum from state to ensure it's up to date) - accum, err = GetAccumulator(accum.store, accum.name) - if err != nil { - return err - } - setAccumulator(accum, accum.value, accum.totalShares.Sub(numSharesToRemove)) - - return nil -} - -// UpdatePosition updates the position with the given name by adding or removing -// the given number of shares. If numShares is positive, it is equivalent to calling -// AddToPosition. If numShares is negative, it is equivalent to calling RemoveFromPosition. -// Also, it moves up the position's accumulator value to the current accum value. -// Fails with error if numShares is zero. Returns nil on success. -func (accum AccumulatorObject) UpdatePosition(name string, numShares sdk.Dec) error { - return accum.UpdatePositionCustomAcc(name, numShares, accum.value) -} - -// UpdatePositionCustomAcc updates the position with the given name by adding or removing -// the given number of shares. If numShares is positive, it is equivalent to calling -// AddToPositionCustomAcc. If numShares is negative, it is equivalent to calling RemoveFromPositionCustomAcc. -// Fails with error if numShares is zero. Returns nil on success. -// It also resets the position's accumulator value to the given customAccumulatorValue. -// All custom accumulator values must be non-negative. They must also be a superset of the -// old accumulator value associated with the position. -func (accum AccumulatorObject) UpdatePositionCustomAcc(name string, numShares sdk.Dec, customAccumulatorValue sdk.DecCoins) error { - if numShares.Equal(sdk.ZeroDec()) { - return ZeroSharesError - } - - if numShares.IsNegative() { - return accum.RemoveFromPositionCustomAcc(name, numShares.Neg(), customAccumulatorValue) - } - - return accum.AddToPositionCustomAcc(name, numShares, customAccumulatorValue) -} - -// SetPositionCustomAcc sets the position's accumulator to the given value. -// Does not update shares or attempt to claim rewards. -// The new accumulator value must be greater than or equal to the old accumulator value. -// Returns nil on success, error otherwise. -func (accum AccumulatorObject) SetPositionCustomAcc(name string, customAccumulatorValue sdk.DecCoins) error { - // Get addr's current position - position, err := GetPosition(accum, name) - if err != nil { - return err - } - - // Update the user's position with the new accumulator value. The unclaimed rewards, options, and - // the number of shares stays the same as in the original position. - initOrUpdatePosition(accum, customAccumulatorValue, name, position.NumShares, position.UnclaimedRewards, position.Options) - - return nil -} - -func (accum AccumulatorObject) DeletePosition(name string) { - accum.store.Delete(FormatPositionPrefixKey(accum.name, name)) -} - -// GetPositionSize returns the number of shares the position corresponding to `addr` -// in accumulator `accum` has, or an error if no position exists. -func (accum AccumulatorObject) GetPositionSize(name string) (sdk.Dec, error) { - position, err := GetPosition(accum, name) - if err != nil { - return sdk.Dec{}, err - } - - return position.NumShares, nil -} - -// HasPosition returns true if a position with the given name exists, -// false otherwise. Returns error if internal database error occurs. -func (accum AccumulatorObject) HasPosition(name string) (bool, error) { - _, err := GetPosition(accum, name) - if err != nil { - isNoPositionError := errors.Is(err, NoPositionError{Name: name}) - if isNoPositionError { - return false, nil - } - return false, err - } - - return true, nil -} - -// GetValue returns the current value of the accumulator. -func (accum AccumulatorObject) GetName() string { - return accum.name -} - -// GetValue returns the current value of the accumulator. -func (accum AccumulatorObject) GetValue() sdk.DecCoins { - return accum.value -} - -// ClaimRewards claims the rewards for the given address, and returns the amount of rewards claimed. -// Upon claiming the rewards, the position at the current address is reset to have no -// unclaimed rewards. The position's accumulator is also set to the current accumulator value. -// Returns error if no position exists for the given address. Returns error if any -// database errors occur. -func (accum AccumulatorObject) ClaimRewards(positionName string) (sdk.Coins, sdk.DecCoins, error) { - position, err := GetPosition(accum, positionName) - if err != nil { - return sdk.Coins{}, sdk.DecCoins{}, NoPositionError{positionName} - } - - totalRewards := GetTotalRewards(accum, position) - - // Return the integer coins to the user - // The remaining change is thrown away. - // This is acceptable because we round in favour of the protocol. - truncatedRewards, dust := totalRewards.TruncateDecimal() - - // remove the position from state entirely if numShares = zero - if position.NumShares.Equal(sdk.ZeroDec()) { - accum.DeletePosition(positionName) - } else { // else, create a completely new position, with no rewards - initOrUpdatePosition(accum, accum.value, positionName, position.NumShares, sdk.NewDecCoins(), position.Options) - } - - return truncatedRewards, dust, nil -} - -// GetTotalShares returns the total number of shares in the accumulator -func (accum AccumulatorObject) GetTotalShares() (sdk.Dec, error) { - accum, err := GetAccumulator(accum.store, accum.name) - return accum.totalShares, err -} - -// AddToUnclaimedRewards adds the given amount of rewards to the unclaimed rewards -// for the given position. Returns error if no position exists for the given address. -// Returns error if any database errors occur. -func (accum AccumulatorObject) AddToUnclaimedRewards(positionName string, rewards sdk.DecCoins) error { - position, err := GetPosition(accum, positionName) - if err != nil { - return err - } - - // Update the user's position with the new unclaimed rewards. The accumulator, options, and - // the number of shares stays the same as in the original position. - initOrUpdatePosition(accum, accum.value, positionName, position.NumShares, position.UnclaimedRewards.Add(rewards...), position.Options) - - return nil -} diff --git a/osmoutils/accum/accum.pb.go b/osmoutils/accum/accum.pb.go deleted file mode 100644 index da7e46920..000000000 --- a/osmoutils/accum/accum.pb.go +++ /dev/null @@ -1,860 +0,0 @@ -// Code generated by protoc-gen-gogo. DO NOT EDIT. -// source: osmosis/accum/v1beta1/accum.proto - -package accum - -import ( - fmt "fmt" - github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types" - types "github.com/cosmos/cosmos-sdk/types" - _ "github.com/gogo/protobuf/gogoproto" - proto "github.com/gogo/protobuf/proto" - io "io" - math "math" - math_bits "math/bits" -) - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = 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 - -type AccumulatorContent struct { - AccumValue github_com_cosmos_cosmos_sdk_types.DecCoins `protobuf:"bytes,1,rep,name=accum_value,json=accumValue,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.DecCoins" json:"accum_value"` - TotalShares github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,2,opt,name=total_shares,json=totalShares,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"total_shares"` -} - -func (m *AccumulatorContent) Reset() { *m = AccumulatorContent{} } -func (m *AccumulatorContent) String() string { return proto.CompactTextString(m) } -func (*AccumulatorContent) ProtoMessage() {} -func (*AccumulatorContent) Descriptor() ([]byte, []int) { - return fileDescriptor_4866f7c74a169dc2, []int{0} -} -func (m *AccumulatorContent) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *AccumulatorContent) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_AccumulatorContent.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 *AccumulatorContent) XXX_Merge(src proto.Message) { - xxx_messageInfo_AccumulatorContent.Merge(m, src) -} -func (m *AccumulatorContent) XXX_Size() int { - return m.Size() -} -func (m *AccumulatorContent) XXX_DiscardUnknown() { - xxx_messageInfo_AccumulatorContent.DiscardUnknown(m) -} - -var xxx_messageInfo_AccumulatorContent proto.InternalMessageInfo - -func (m *AccumulatorContent) GetAccumValue() github_com_cosmos_cosmos_sdk_types.DecCoins { - if m != nil { - return m.AccumValue - } - return nil -} - -type Options struct { -} - -func (m *Options) Reset() { *m = Options{} } -func (m *Options) String() string { return proto.CompactTextString(m) } -func (*Options) ProtoMessage() {} -func (*Options) Descriptor() ([]byte, []int) { - return fileDescriptor_4866f7c74a169dc2, []int{1} -} -func (m *Options) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *Options) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_Options.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 *Options) XXX_Merge(src proto.Message) { - xxx_messageInfo_Options.Merge(m, src) -} -func (m *Options) XXX_Size() int { - return m.Size() -} -func (m *Options) XXX_DiscardUnknown() { - xxx_messageInfo_Options.DiscardUnknown(m) -} - -var xxx_messageInfo_Options proto.InternalMessageInfo - -type Record struct { - NumShares github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,1,opt,name=num_shares,json=numShares,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"num_shares"` - InitAccumValue github_com_cosmos_cosmos_sdk_types.DecCoins `protobuf:"bytes,2,rep,name=init_accum_value,json=initAccumValue,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.DecCoins" json:"init_accum_value"` - UnclaimedRewards github_com_cosmos_cosmos_sdk_types.DecCoins `protobuf:"bytes,3,rep,name=unclaimed_rewards,json=unclaimedRewards,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.DecCoins" json:"unclaimed_rewards"` - Options *Options `protobuf:"bytes,4,opt,name=options,proto3" json:"options,omitempty"` -} - -func (m *Record) Reset() { *m = Record{} } -func (m *Record) String() string { return proto.CompactTextString(m) } -func (*Record) ProtoMessage() {} -func (*Record) Descriptor() ([]byte, []int) { - return fileDescriptor_4866f7c74a169dc2, []int{2} -} -func (m *Record) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *Record) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_Record.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 *Record) XXX_Merge(src proto.Message) { - xxx_messageInfo_Record.Merge(m, src) -} -func (m *Record) XXX_Size() int { - return m.Size() -} -func (m *Record) XXX_DiscardUnknown() { - xxx_messageInfo_Record.DiscardUnknown(m) -} - -var xxx_messageInfo_Record proto.InternalMessageInfo - -func (m *Record) GetInitAccumValue() github_com_cosmos_cosmos_sdk_types.DecCoins { - if m != nil { - return m.InitAccumValue - } - return nil -} - -func (m *Record) GetUnclaimedRewards() github_com_cosmos_cosmos_sdk_types.DecCoins { - if m != nil { - return m.UnclaimedRewards - } - return nil -} - -func (m *Record) GetOptions() *Options { - if m != nil { - return m.Options - } - return nil -} - -func init() { - proto.RegisterType((*AccumulatorContent)(nil), "osmosis.accum.v1beta1.AccumulatorContent") - proto.RegisterType((*Options)(nil), "osmosis.accum.v1beta1.Options") - proto.RegisterType((*Record)(nil), "osmosis.accum.v1beta1.Record") -} - -func init() { proto.RegisterFile("osmosis/accum/v1beta1/accum.proto", fileDescriptor_4866f7c74a169dc2) } - -var fileDescriptor_4866f7c74a169dc2 = []byte{ - // 401 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x93, 0x41, 0xcb, 0xd3, 0x30, - 0x1c, 0xc6, 0x9b, 0x77, 0xf2, 0xbe, 0x2c, 0x15, 0x99, 0x45, 0xa1, 0x0c, 0xc9, 0xe6, 0x0e, 0x32, - 0x90, 0xa5, 0x6c, 0xbb, 0x78, 0xdd, 0xe6, 0xc5, 0x83, 0x88, 0x15, 0x3c, 0x78, 0x29, 0x69, 0x1a, - 0xb6, 0x60, 0x9b, 0x8c, 0x26, 0x99, 0x88, 0xe0, 0x47, 0x10, 0x3f, 0x87, 0x9f, 0x64, 0xc7, 0x1d, - 0x45, 0x61, 0xca, 0xf6, 0x45, 0xa4, 0x49, 0x3b, 0x77, 0xf0, 0x20, 0x2f, 0xec, 0x94, 0xa6, 0x7d, - 0xfa, 0xfb, 0x95, 0xa7, 0xff, 0xc0, 0xc7, 0x52, 0x15, 0x52, 0x71, 0x15, 0x11, 0x4a, 0x4d, 0x11, - 0x6d, 0xc6, 0x29, 0xd3, 0x64, 0xec, 0x76, 0x78, 0x5d, 0x4a, 0x2d, 0x83, 0x87, 0x75, 0x04, 0xbb, - 0x9b, 0x75, 0xa4, 0xfb, 0x60, 0x29, 0x97, 0xd2, 0x26, 0xa2, 0xea, 0xca, 0x85, 0xbb, 0x88, 0xda, - 0x74, 0x94, 0x12, 0xc5, 0x4e, 0x34, 0x2a, 0xb9, 0x70, 0xcf, 0x07, 0x3f, 0x01, 0x0c, 0x66, 0x15, - 0xc7, 0xe4, 0x44, 0xcb, 0x72, 0x21, 0x85, 0x66, 0x42, 0x07, 0x25, 0xf4, 0x2d, 0x3d, 0xd9, 0x90, - 0xdc, 0xb0, 0x10, 0xf4, 0x5b, 0x43, 0x7f, 0xf2, 0x08, 0x3b, 0x18, 0xae, 0x60, 0x8d, 0x17, 0x3f, - 0x67, 0x74, 0x21, 0xb9, 0x98, 0x4f, 0xb7, 0xfb, 0x9e, 0xf7, 0xed, 0x57, 0xef, 0xe9, 0x92, 0xeb, - 0x95, 0x49, 0x31, 0x95, 0x45, 0x54, 0xcb, 0xdd, 0x32, 0x52, 0xd9, 0xfb, 0x48, 0x7f, 0x5c, 0x33, - 0xd5, 0xbc, 0xa3, 0x62, 0x68, 0x2d, 0x6f, 0x2b, 0x49, 0xf0, 0x1a, 0xde, 0xd5, 0x52, 0x93, 0x3c, - 0x51, 0x2b, 0x52, 0x32, 0x15, 0x5e, 0xf5, 0xc1, 0xb0, 0x3d, 0xc7, 0x15, 0xf6, 0xc7, 0xbe, 0xf7, - 0xe4, 0xff, 0xb0, 0xb1, 0x6f, 0x19, 0x6f, 0x2c, 0x62, 0xd0, 0x86, 0x37, 0xaf, 0xd6, 0x9a, 0x4b, - 0xa1, 0x06, 0x5f, 0x5a, 0xf0, 0x3a, 0x66, 0x54, 0x96, 0x59, 0xf0, 0x12, 0x42, 0x61, 0x8a, 0x46, - 0x03, 0x6e, 0xa5, 0x69, 0x0b, 0x53, 0x38, 0x49, 0xf0, 0x09, 0x76, 0xb8, 0xe0, 0x3a, 0x39, 0x2f, - 0xec, 0xea, 0x52, 0x85, 0xdd, 0xab, 0x54, 0xb3, 0xbf, 0xa5, 0x7d, 0x86, 0xf7, 0x8d, 0xa0, 0x39, - 0xe1, 0x05, 0xcb, 0x92, 0x92, 0x7d, 0x20, 0x65, 0xa6, 0xc2, 0xd6, 0xa5, 0xec, 0x9d, 0x93, 0x2b, - 0x76, 0xaa, 0xe0, 0x19, 0xbc, 0x91, 0xae, 0xe1, 0xf0, 0x4e, 0x1f, 0x0c, 0xfd, 0x09, 0xc2, 0xff, - 0x1c, 0x4f, 0x5c, 0xff, 0x87, 0xb8, 0x89, 0xcf, 0x5f, 0x6c, 0x0f, 0x08, 0xec, 0x0e, 0x08, 0xfc, - 0x3e, 0x20, 0xf0, 0xf5, 0x88, 0xbc, 0xdd, 0x11, 0x79, 0xdf, 0x8f, 0xc8, 0x7b, 0x17, 0x9d, 0x7d, - 0x52, 0x0d, 0x1b, 0xe5, 0x24, 0x55, 0xcd, 0xc6, 0xae, 0x46, 0xf3, 0xbc, 0x3e, 0x25, 0xe9, 0xb5, - 0x9d, 0xe5, 0xe9, 0x9f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf3, 0xc0, 0x03, 0x44, 0x3d, 0x03, 0x00, - 0x00, -} - -func (m *AccumulatorContent) 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 *AccumulatorContent) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *AccumulatorContent) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - { - size := m.TotalShares.Size() - i -= size - if _, err := m.TotalShares.MarshalTo(dAtA[i:]); err != nil { - return 0, err - } - i = encodeVarintAccum(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - if len(m.AccumValue) > 0 { - for iNdEx := len(m.AccumValue) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.AccumValue[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintAccum(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - } - } - return len(dAtA) - i, nil -} - -func (m *Options) 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 *Options) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *Options) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - return len(dAtA) - i, nil -} - -func (m *Record) 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 *Record) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *Record) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.Options != nil { - { - size, err := m.Options.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintAccum(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x22 - } - if len(m.UnclaimedRewards) > 0 { - for iNdEx := len(m.UnclaimedRewards) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.UnclaimedRewards[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintAccum(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x1a - } - } - if len(m.InitAccumValue) > 0 { - for iNdEx := len(m.InitAccumValue) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.InitAccumValue[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintAccum(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - } - { - size := m.NumShares.Size() - i -= size - if _, err := m.NumShares.MarshalTo(dAtA[i:]); err != nil { - return 0, err - } - i = encodeVarintAccum(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - -func encodeVarintAccum(dAtA []byte, offset int, v uint64) int { - offset -= sovAccum(v) - base := offset - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ - } - dAtA[offset] = uint8(v) - return base -} -func (m *AccumulatorContent) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if len(m.AccumValue) > 0 { - for _, e := range m.AccumValue { - l = e.Size() - n += 1 + l + sovAccum(uint64(l)) - } - } - l = m.TotalShares.Size() - n += 1 + l + sovAccum(uint64(l)) - return n -} - -func (m *Options) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - return n -} - -func (m *Record) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = m.NumShares.Size() - n += 1 + l + sovAccum(uint64(l)) - if len(m.InitAccumValue) > 0 { - for _, e := range m.InitAccumValue { - l = e.Size() - n += 1 + l + sovAccum(uint64(l)) - } - } - if len(m.UnclaimedRewards) > 0 { - for _, e := range m.UnclaimedRewards { - l = e.Size() - n += 1 + l + sovAccum(uint64(l)) - } - } - if m.Options != nil { - l = m.Options.Size() - n += 1 + l + sovAccum(uint64(l)) - } - return n -} - -func sovAccum(x uint64) (n int) { - return (math_bits.Len64(x|1) + 6) / 7 -} -func sozAccum(x uint64) (n int) { - return sovAccum(uint64((x << 1) ^ uint64((int64(x) >> 63)))) -} -func (m *AccumulatorContent) 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 ErrIntOverflowAccum - } - 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: AccumulatorContent: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: AccumulatorContent: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AccumValue", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAccum - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthAccum - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthAccum - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.AccumValue = append(m.AccumValue, types.DecCoin{}) - if err := m.AccumValue[len(m.AccumValue)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field TotalShares", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAccum - } - 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 ErrInvalidLengthAccum - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthAccum - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.TotalShares.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipAccum(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthAccum - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *Options) 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 ErrIntOverflowAccum - } - 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: Options: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: Options: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - default: - iNdEx = preIndex - skippy, err := skipAccum(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthAccum - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *Record) 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 ErrIntOverflowAccum - } - 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: Record: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: Record: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field NumShares", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAccum - } - 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 ErrInvalidLengthAccum - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthAccum - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.NumShares.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field InitAccumValue", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAccum - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthAccum - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthAccum - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.InitAccumValue = append(m.InitAccumValue, types.DecCoin{}) - if err := m.InitAccumValue[len(m.InitAccumValue)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field UnclaimedRewards", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAccum - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthAccum - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthAccum - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.UnclaimedRewards = append(m.UnclaimedRewards, types.DecCoin{}) - if err := m.UnclaimedRewards[len(m.UnclaimedRewards)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Options", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAccum - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthAccum - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthAccum - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Options == nil { - m.Options = &Options{} - } - if err := m.Options.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipAccum(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthAccum - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func skipAccum(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, ErrIntOverflowAccum - } - 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, ErrIntOverflowAccum - } - 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, ErrIntOverflowAccum - } - 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, ErrInvalidLengthAccum - } - iNdEx += length - case 3: - depth++ - case 4: - if depth == 0 { - return 0, ErrUnexpectedEndOfGroupAccum - } - depth-- - case 5: - iNdEx += 4 - default: - return 0, fmt.Errorf("proto: illegal wireType %d", wireType) - } - if iNdEx < 0 { - return 0, ErrInvalidLengthAccum - } - if depth == 0 { - return iNdEx, nil - } - } - return 0, io.ErrUnexpectedEOF -} - -var ( - ErrInvalidLengthAccum = fmt.Errorf("proto: negative length found during unmarshaling") - ErrIntOverflowAccum = fmt.Errorf("proto: integer overflow") - ErrUnexpectedEndOfGroupAccum = fmt.Errorf("proto: unexpected end of group") -) diff --git a/osmoutils/accum/accum_helpers.go b/osmoutils/accum/accum_helpers.go deleted file mode 100644 index 3d2bbf7f8..000000000 --- a/osmoutils/accum/accum_helpers.go +++ /dev/null @@ -1,61 +0,0 @@ -package accum - -import ( - sdk "github.com/cosmos/cosmos-sdk/types" - - "github.com/CosmosContracts/juno/v15/osmoutils" -) - -var minusOne = sdk.NewDec(-1) - -// Creates a new position or override an existing position -// at accumulator's current value with a specific number of shares and unclaimed rewards -func initOrUpdatePosition(accum AccumulatorObject, accumulatorValue sdk.DecCoins, index string, numShareUnits sdk.Dec, unclaimedRewards sdk.DecCoins, options *Options) { - position := Record{ - NumShares: numShareUnits, - InitAccumValue: accumulatorValue, - UnclaimedRewards: unclaimedRewards, - Options: options, - } - osmoutils.MustSet(accum.store, FormatPositionPrefixKey(accum.name, index), &position) -} - -// Gets addr's current position from store -func GetPosition(accum AccumulatorObject, name string) (Record, error) { - position := Record{} - found, err := osmoutils.Get(accum.store, FormatPositionPrefixKey(accum.name, name), &position) - if err != nil { - return Record{}, err - } - if !found { - return Record{}, NoPositionError{name} - } - - return position, nil -} - -// Gets total unclaimed rewards, including existing and newly accrued unclaimed rewards -func GetTotalRewards(accum AccumulatorObject, position Record) sdk.DecCoins { - totalRewards := position.UnclaimedRewards - - // TODO: add a check that accum.value is greater than position.InitAccumValue - accumulatorRewards := accum.value.Sub(position.InitAccumValue).MulDec(position.NumShares) - totalRewards = totalRewards.Add(accumulatorRewards...) - - return totalRewards -} - -// validateAccumulatorValue validates the provided accumulator. -// All coins in custom accumulator value must be non-negative. -// Custom accumulator value must be a superset of the old accumulator value. -// Fails if any coin is negative. On success, returns nil. -func validateAccumulatorValue(customAccumulatorValue, oldPositionAccumulatorValue sdk.DecCoins) error { - if customAccumulatorValue.IsAnyNegative() { - return NegativeCustomAccError{customAccumulatorValue} - } - newValue, IsAnyNegative := customAccumulatorValue.SafeSub(oldPositionAccumulatorValue) - if IsAnyNegative { - return NegativeAccDifferenceError{newValue.MulDec(minusOne)} - } - return nil -} diff --git a/osmoutils/accum/accum_helpers_test.go b/osmoutils/accum/accum_helpers_test.go deleted file mode 100644 index 0bcd7a5a3..000000000 --- a/osmoutils/accum/accum_helpers_test.go +++ /dev/null @@ -1,50 +0,0 @@ -package accum_test - -import ( - sdk "github.com/cosmos/cosmos-sdk/types" - - "github.com/CosmosContracts/juno/v15/osmoutils/accum" -) - -func (suite *AccumTestSuite) TestValidateAccumulatorValue() { - tests := map[string]struct { - customAccumulatorValue sdk.DecCoins - oldPositionAccumulatorValue sdk.DecCoins - expectError error - }{ - "negative custom coins - error": { - customAccumulatorValue: initialCoinsDenomOne.MulDec(sdk.NewDec(-1)), - oldPositionAccumulatorValue: emptyCoins, - expectError: accum.NegativeCustomAccError{initialCoinsDenomOne.MulDec(sdk.NewDec(-1))}, - }, - "old accumulator coins are greater than new - error": { - customAccumulatorValue: initialCoinsDenomOne, - oldPositionAccumulatorValue: initialCoinsDenomOne.Add(sdk.NewDecCoin(initialCoinDenomOne.Denom, sdk.OneInt())), - expectError: accum.NegativeAccDifferenceError{sdk.NewDecCoins(sdk.NewDecCoin(initialCoinDenomOne.Denom, sdk.OneInt()))}, - }, - "old accumulator coins are a superset of new - error": { - customAccumulatorValue: initialCoinsDenomOne, - oldPositionAccumulatorValue: initialCoinsDenomOne.Add(initialCoinDenomTwo), - expectError: accum.NegativeAccDifferenceError{sdk.NewDecCoins(initialCoinDenomTwo)}, - }, - "new accumulator coins are a superset of old - success": { - customAccumulatorValue: initialCoinsDenomOne.Add(initialCoinDenomTwo), - oldPositionAccumulatorValue: initialCoinsDenomOne, - }, - } - - for name, tc := range tests { - suite.Run(name, func() { - suite.SetupTest() - - err := accum.ValidateAccumulatorValue(tc.customAccumulatorValue, tc.oldPositionAccumulatorValue) - - if tc.expectError != nil { - suite.Require().Error(err) - suite.Require().Equal(tc.expectError, err) - return - } - suite.Require().NoError(err) - }) - } -} diff --git a/osmoutils/accum/accum_test.go b/osmoutils/accum/accum_test.go deleted file mode 100644 index 5fe038bca..000000000 --- a/osmoutils/accum/accum_test.go +++ /dev/null @@ -1,1568 +0,0 @@ -package accum_test - -import ( - "math/rand" - "testing" - - dbm "github.com/cometbft/cometbft-db" - "github.com/cosmos/cosmos-sdk/store" - iavlstore "github.com/cosmos/cosmos-sdk/store/iavl" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/iavl" - "github.com/gogo/protobuf/proto" - "github.com/stretchr/testify/suite" - - "github.com/CosmosContracts/juno/v15/osmoutils" - accumPackage "github.com/CosmosContracts/juno/v15/osmoutils/accum" - "github.com/CosmosContracts/juno/v15/osmoutils/osmoassert" -) - -type AccumTestSuite struct { - suite.Suite - - store store.KVStore -} - -var ( - testAddressOne = sdk.AccAddress([]byte("addr1_______________")).String() - testAddressTwo = sdk.AccAddress([]byte("addr2_______________")).String() - testAddressThree = sdk.AccAddress([]byte("addr3_______________")).String() - - emptyPositionOptions = accumPackage.Options{} - testNameOne = "myaccumone" - testNameTwo = "myaccumtwo" - testNameThree = "myaccumthree" - denomOne = "denomone" - denomTwo = "denomtwo" - denomThree = "denomthree" - - emptyCoins = sdk.DecCoins(nil) - emptyDec = sdk.NewDec(0) - - initialValueOne = sdk.MustNewDecFromStr("100.1") - initialCoinDenomOne = sdk.NewDecCoinFromDec(denomOne, initialValueOne) - initialCoinDenomTwo = sdk.NewDecCoinFromDec(denomTwo, initialValueOne) - initialCoinDenomThree = sdk.NewDecCoinFromDec(denomThree, initialValueOne) - initialCoinsDenomOne = sdk.NewDecCoins(initialCoinDenomOne) - - positionOne = accumPackage.Record{ - NumShares: sdk.NewDec(100), - InitAccumValue: emptyCoins, - UnclaimedRewards: emptyCoins, - } - - positionOneV2 = accumPackage.Record{ - NumShares: sdk.NewDec(150), - InitAccumValue: emptyCoins, - UnclaimedRewards: emptyCoins, - } - - positionTwo = accumPackage.Record{ - NumShares: sdk.NewDec(200), - InitAccumValue: emptyCoins, - UnclaimedRewards: emptyCoins, - } - - positionThree = accumPackage.Record{ - NumShares: sdk.NewDec(300), - InitAccumValue: emptyCoins, - UnclaimedRewards: emptyCoins, - } -) - -func withInitialAccumValue(record accumPackage.Record, initialAccum sdk.DecCoins) accumPackage.Record { - record.InitAccumValue = initialAccum - return record -} - -func withUnclaimedRewards(record accumPackage.Record, unclaimedRewards sdk.DecCoins) accumPackage.Record { - record.UnclaimedRewards = unclaimedRewards - return record -} - -// Sets/resets KVStore to use for tests under `suite.store` -func (suite *AccumTestSuite) SetupTest() { - db := dbm.NewMemDB() - tree, err := iavl.NewMutableTree(db, 100, false) - suite.Require().NoError(err) - _, _, err = tree.SaveVersion() - suite.Require().Nil(err) - kvstore := iavlstore.UnsafeNewStore(tree) - suite.store = kvstore -} - -func TestAccumTestSuite(t *testing.T) { - suite.Run(t, new(AccumTestSuite)) -} - -func (suite *AccumTestSuite) TestMakeAndGetAccum() { - // We set up store once at beginning so we can test duplicates - suite.SetupTest() - - type testcase struct { - testName string - accumName string - expAccum accumPackage.AccumulatorObject - expSetPass bool - expGetPass bool - } - - tests := []testcase{ - { - testName: "create valid accumulator", - accumName: "fee-accumulator", - expSetPass: true, - expGetPass: true, - }, - { - testName: "create duplicate accumulator", - accumName: "fee-accumulator", - expSetPass: false, - expGetPass: true, - }, - } - - for _, tc := range tests { - tc := tc - suite.Run(tc.testName, func() { - // Creates raw accumulator object with test case's accum name and zero initial value - expAccum := accumPackage.MakeTestAccumulator(suite.store, tc.accumName, emptyCoins, emptyDec) - - err := accumPackage.MakeAccumulator(suite.store, tc.accumName) - - if !tc.expSetPass { - suite.Require().Error(err) - } - - retrievedAccum, err := accumPackage.GetAccumulator(suite.store, tc.accumName) - - if tc.expGetPass { - suite.Require().NoError(err) - suite.Require().Equal(expAccum, retrievedAccum) - } else { - suite.Require().Error(err) - } - }) - } -} - -func (suite *AccumTestSuite) TestMakeAccumulatorWithValueAndShares() { - // We set up store once at beginning so we can test duplicates - suite.SetupTest() - - type testcase struct { - testName string - accumName string - accumValue sdk.DecCoins - totalShares sdk.Dec - expAccum accumPackage.AccumulatorObject - expSetPass bool - expGetPass bool - } - - tests := []testcase{ - { - testName: "create valid accumulator", - accumName: "fee-accumulator", - accumValue: sdk.NewDecCoins(sdk.NewDecCoin("foo", sdk.NewInt(10)), sdk.NewDecCoin("bar", sdk.NewInt(20))), - totalShares: sdk.NewDec(30), - expSetPass: true, - expGetPass: true, - }, - { - testName: "create duplicate accumulator", - accumName: "fee-accumulator", - accumValue: sdk.NewDecCoins(sdk.NewDecCoin("foo", sdk.NewInt(10)), sdk.NewDecCoin("bar", sdk.NewInt(20))), - totalShares: sdk.NewDec(30), - expSetPass: false, - expGetPass: true, - }, - } - - for _, tc := range tests { - tc := tc - suite.Run(tc.testName, func() { - // Creates raw accumulator object with test case's accum name and zero initial value - expAccum := accumPackage.MakeTestAccumulator(suite.store, tc.accumName, emptyCoins, emptyDec) - - err := accumPackage.MakeAccumulatorWithValueAndShare(suite.store, tc.accumName, tc.accumValue, tc.totalShares) - - if !tc.expSetPass { - suite.Require().Error(err) - } - - retrievedAccum, err := accumPackage.GetAccumulator(suite.store, tc.accumName) - - if tc.expGetPass { - suite.Require().NoError(err) - suite.Require().Equal(expAccum, retrievedAccum) - } else { - suite.Require().Error(err) - } - }) - } -} - -func (suite *AccumTestSuite) TestNewPosition() { - // We setup store and accum - // once at beginning so we can test duplicate positions - suite.SetupTest() - - // Setup. - accObject := accumPackage.MakeTestAccumulator(suite.store, testNameOne, emptyCoins, emptyDec) - - tests := map[string]struct { - accObject accumPackage.AccumulatorObject - name string - numShareUnits sdk.Dec - options *accumPackage.Options - expectedPosition accumPackage.Record - }{ - "test address one - position created": { - accObject: accObject, - name: testAddressOne, - numShareUnits: positionOne.NumShares, - expectedPosition: positionOne, - }, - "test address two (non-nil options) - position created": { - accObject: accObject, - name: testAddressTwo, - numShareUnits: positionTwo.NumShares, - expectedPosition: positionTwo, - options: &emptyPositionOptions, - }, - "test address one - position overwritten": { - accObject: accObject, - name: testAddressOne, - numShareUnits: positionOneV2.NumShares, - expectedPosition: positionOneV2, - }, - "test address three - added": { - accObject: accObject, - name: testAddressThree, - numShareUnits: positionThree.NumShares, - expectedPosition: positionThree, - }, - "test address one with non-empty accumulator - position created": { - accObject: accumPackage.MakeTestAccumulator(suite.store, testNameTwo, initialCoinsDenomOne, emptyDec), - name: testAddressOne, - numShareUnits: positionOne.NumShares, - expectedPosition: withInitialAccumValue(positionOne, initialCoinsDenomOne), - }, - } - - for name, tc := range tests { - tc := tc - suite.Run(name, func() { - // System under test. - tc.accObject.NewPosition(tc.name, tc.numShareUnits, tc.options) - - // Assertions. - position := tc.accObject.MustGetPosition(tc.name) - - suite.Require().Equal(tc.expectedPosition.NumShares, position.NumShares) - suite.Require().Equal(tc.expectedPosition.InitAccumValue, position.InitAccumValue) - suite.Require().Equal(tc.expectedPosition.UnclaimedRewards, position.UnclaimedRewards) - - if tc.options == nil { - suite.Require().Nil(position.Options) - return - } - - suite.Require().Equal(*tc.options, *position.Options) - }) - } -} - -func (suite *AccumTestSuite) TestNewPositionCustomAcc() { - // We setup store and accum - // once at beginning so we can test duplicate positions - suite.SetupTest() - - // Setup. - accObject := accumPackage.MakeTestAccumulator(suite.store, testNameOne, initialCoinsDenomOne, emptyDec) - - tests := map[string]struct { - accObject accumPackage.AccumulatorObject - name string - numShareUnits sdk.Dec - customAcc sdk.DecCoins - options *accumPackage.Options - expectedPosition accumPackage.Record - expectedError error - }{ - "custom acc value equals to acc": { - accObject: accObject, - name: testAddressOne, - numShareUnits: positionOne.NumShares, - customAcc: accObject.GetValue(), - expectedPosition: accumPackage.Record{ - NumShares: positionOne.NumShares, - InitAccumValue: accObject.GetValue(), - UnclaimedRewards: emptyCoins, - }, - }, - "custom acc value does not equal to acc": { - accObject: accObject, - name: testAddressTwo, - numShareUnits: positionTwo.NumShares, - customAcc: accObject.GetValue().MulDec(sdk.NewDec(2)), - expectedPosition: accumPackage.Record{ - NumShares: positionTwo.NumShares, - InitAccumValue: accObject.GetValue().MulDec(sdk.NewDec(2)), - UnclaimedRewards: emptyCoins, - }, - options: &emptyPositionOptions, - }, - "negative acc value - error": { - accObject: accObject, - name: testAddressOne, - numShareUnits: positionOne.NumShares, - customAcc: accObject.GetValue().MulDec(sdk.NewDec(-1)), - expectedError: accumPackage.NegativeCustomAccError{accObject.GetValue().MulDec(sdk.NewDec(-1))}, - }, - } - - for name, tc := range tests { - tc := tc - suite.Run(name, func() { - // System under test. - err := tc.accObject.NewPositionCustomAcc(tc.name, tc.numShareUnits, tc.customAcc, tc.options) - - if tc.expectedError != nil { - suite.Require().Error(err) - suite.Require().Equal(tc.expectedError, err) - return - } - suite.Require().NoError(err) - - // Assertions. - position := tc.accObject.MustGetPosition(tc.name) - - suite.Require().Equal(tc.expectedPosition.NumShares, position.NumShares) - suite.Require().Equal(tc.expectedPosition.InitAccumValue, position.InitAccumValue) - suite.Require().Equal(tc.expectedPosition.UnclaimedRewards, position.UnclaimedRewards) - - if tc.options == nil { - suite.Require().Nil(position.Options) - return - } - - suite.Require().Equal(*tc.options, *position.Options) - }) - } -} - -func (suite *AccumTestSuite) TestClaimRewards() { - var ( - doubleCoinsDenomOne = sdk.NewDecCoinFromDec(denomOne, initialValueOne.MulInt64(2)) - - tripleDenomOneAndTwo = sdk.NewDecCoins( - sdk.NewDecCoinFromDec(denomOne, initialValueOne), - sdk.NewDecCoinFromDec(denomTwo, sdk.NewDec(3))) - ) - - // single output convenience wrapper. - toCoins := func(decCoins sdk.DecCoins) sdk.Coins { - coins, _ := decCoins.TruncateDecimal() - return coins - } - - // We setup store and accum - // once at beginning so we can test duplicate positions - suite.SetupTest() - - // Setup. - - // 1. No rewards, 2 position accumulator. - accumNoRewards := accumPackage.MakeTestAccumulator(suite.store, testNameOne, emptyCoins, emptyDec) - - // Create positions at testAddressOne and testAddressTwo. - accumNoRewards.NewPosition(testAddressOne, positionOne.NumShares, nil) - accumNoRewards.NewPosition(testAddressTwo, positionTwo.NumShares, nil) - - // 2. One accumulator reward coin, 1 position accumulator, no unclaimed rewards in position. - accumOneReward := accumPackage.MakeTestAccumulator(suite.store, testNameTwo, initialCoinsDenomOne, emptyDec) - - // Create position at testAddressThree. - accumOneReward = accumPackage.WithPosition(accumOneReward, testAddressThree, withInitialAccumValue(positionThree, initialCoinsDenomOne)) - - // Double the accumulator value. - accumOneReward.SetValue(sdk.NewDecCoins(doubleCoinsDenomOne)) - - // 3. Multi accumulator rewards, 2 position accumulator, some unclaimed rewards. - accumThreeRewards := accumPackage.MakeTestAccumulator(suite.store, testNameThree, sdk.NewDecCoins(), emptyDec) - - // Create positions at testAddressOne - // This position has unclaimed rewards set. - accumThreeRewards = accumPackage.WithPosition(accumThreeRewards, testAddressOne, withUnclaimedRewards(positionOne, initialCoinsDenomOne)) - - // Create positions at testAddressThree with no unclaimed rewards. - accumThreeRewards.NewPosition(testAddressTwo, positionTwo.NumShares, nil) - - // Triple the accumulator value. - accumThreeRewards.SetValue(tripleDenomOneAndTwo) - - tests := []struct { - testName string - accObject accumPackage.AccumulatorObject - accName string - expectedResult sdk.Coins - updateNumSharesToZero bool - expectError error - }{ - { - testName: "claim at testAddressOne with no rewards - success", - accObject: accumNoRewards, - accName: testAddressOne, - expectedResult: toCoins(emptyCoins), - }, - { - testName: "delete accum - claim at testAddressOne with no rewards - success", - accObject: accumNoRewards, - accName: testAddressOne, - updateNumSharesToZero: true, - expectedResult: toCoins(emptyCoins), - }, - { - testName: "claim at testAddressTwo with no rewards - success", - accObject: accumNoRewards, - accName: testAddressTwo, - expectedResult: toCoins(emptyCoins), - }, - { - testName: "claim at testAddressTwo with no rewards - error - no position", - accObject: accumNoRewards, - accName: testAddressThree, - expectError: accumPackage.NoPositionError{Name: testAddressThree}, - }, - { - testName: "claim at testAddressThree with single reward token - success", - accObject: accumOneReward, - accName: testAddressThree, - // denomOne: (200.2 - 100.1) * 300 (accum diff * share count) = 30030 - expectedResult: toCoins(initialCoinsDenomOne.MulDec(positionThree.NumShares)), - }, - { - testName: "claim at testAddressOne with multiple reward tokens and unclaimed rewards - success", - accObject: accumThreeRewards, - accName: testAddressOne, - // denomOne: (300.3 - 0) * 100 (accum diff * share count) + 100.1 (unclaimed rewards) = 30130.1 - // denomTwo: (3 - 0) * 100 (accum diff * share count) = 300 - expectedResult: toCoins(tripleDenomOneAndTwo.MulDec(positionOne.NumShares).Add(initialCoinDenomOne)), - }, - { - testName: "delete accum - claim at testAddressOne with multiple reward tokens and unclaimed rewards - success", - accObject: accumThreeRewards, - accName: testAddressOne, - updateNumSharesToZero: true, - // all claimed during the previous test - expectedResult: toCoins(emptyCoins), - }, - { - testName: "claim at testAddressTwo with multiple reward tokens and no unclaimed rewards - success", - accObject: accumThreeRewards, - accName: testAddressTwo, - // denomOne: (100.1 - 0) * 200 (accum diff * share count) = 200020 - // denomTwo: (3 - 0) * 200 (accum diff * share count) = 600 - expectedResult: toCoins(tripleDenomOneAndTwo.MulDec(positionTwo.NumShares)), - }, - } - - for _, tc := range tests { - tc := tc - suite.Run(tc.testName, func() { - if tc.updateNumSharesToZero { - positionSize, err := tc.accObject.GetPositionSize(tc.accName) - suite.Require().NoError(err) - err = tc.accObject.UpdatePosition(tc.accName, positionSize.Neg()) - suite.Require().NoError(err) - } - // System under test. - actualResult, _, err := tc.accObject.ClaimRewards(tc.accName) - - // Assertions. - - if tc.expectError != nil { - suite.Require().Error(err) - suite.Require().Equal(tc.expectError, err) - return - } - - suite.Require().NoError(err) - suite.Require().Equal(tc.expectedResult.String(), actualResult.String()) - - osmoassert.ConditionalPanic(suite.T(), tc.updateNumSharesToZero, func() { - finalPosition := tc.accObject.MustGetPosition(tc.accName) - suite.Require().NoError(err) - - // Unclaimed rewards are reset. - suite.Require().Equal(emptyCoins, finalPosition.UnclaimedRewards) - }) - }) - } -} - -func (suite *AccumTestSuite) TestAddToPosition() { - type testcase struct { - startingNumShares sdk.Dec - startingUnclaimedRewards sdk.DecCoins - newShares sdk.Dec - - // accumInit and expAccumDelta specify the initial accum value - // and how much it has changed since the position being added - // to was created - accumInit sdk.DecCoins - expAccumDelta sdk.DecCoins - - addrDoesNotExist bool - expPass bool - } - - tests := map[string]testcase{ - "zero shares with no new rewards": { - startingNumShares: sdk.ZeroDec(), - startingUnclaimedRewards: sdk.NewDecCoins(), - newShares: sdk.OneDec(), - accumInit: sdk.NewDecCoins(), - // unchanged accum value, so no unclaimed rewards - expAccumDelta: sdk.NewDecCoins(), - expPass: true, - }, - "non-zero shares with no new rewards": { - startingNumShares: initialValueOne, - startingUnclaimedRewards: sdk.NewDecCoins(), - newShares: sdk.NewDec(10), - accumInit: sdk.NewDecCoins(), - // unchanged accum value, so no unclaimed rewards - expAccumDelta: sdk.NewDecCoins(), - expPass: true, - }, - "non-zero shares with new rewards in one denom": { - startingNumShares: initialValueOne, - startingUnclaimedRewards: sdk.NewDecCoins(), - newShares: sdk.OneDec(), - accumInit: sdk.NewDecCoins(), - // unclaimed rewards since last update - expAccumDelta: sdk.NewDecCoins(initialCoinDenomOne), - expPass: true, - }, - "non-zero shares with new rewards in two denoms": { - startingNumShares: initialValueOne, - startingUnclaimedRewards: sdk.NewDecCoins(), - newShares: sdk.OneDec(), - accumInit: sdk.NewDecCoins(), - expAccumDelta: sdk.NewDecCoins(initialCoinDenomOne, initialCoinDenomTwo), - expPass: true, - }, - "non-zero shares with both existing and new rewards": { - startingNumShares: initialValueOne, - startingUnclaimedRewards: sdk.NewDecCoins(sdk.NewDecCoin(denomOne, sdk.NewInt(11)), sdk.NewDecCoin(denomTwo, sdk.NewInt(11))), - newShares: sdk.OneDec(), - accumInit: sdk.NewDecCoins(), - expAccumDelta: sdk.NewDecCoins(initialCoinDenomOne, initialCoinDenomTwo), - expPass: true, - }, - "non-zero shares with both existing (one denom) and new rewards (two denoms)": { - startingNumShares: initialValueOne, - startingUnclaimedRewards: sdk.NewDecCoins(initialCoinDenomOne), - newShares: sdk.OneDec(), - accumInit: sdk.NewDecCoins(), - expAccumDelta: sdk.NewDecCoins(initialCoinDenomOne, initialCoinDenomTwo), - expPass: true, - }, - "non-zero shares with both existing (one denom) and new rewards (two new denoms)": { - startingNumShares: initialValueOne, - startingUnclaimedRewards: sdk.NewDecCoins(initialCoinDenomOne), - newShares: sdk.OneDec(), - accumInit: sdk.NewDecCoins(), - expAccumDelta: sdk.NewDecCoins(initialCoinDenomTwo, initialCoinDenomThree), - expPass: true, - }, - "nonzero accumulator starting value, delta with same denoms": { - startingNumShares: initialValueOne, - startingUnclaimedRewards: sdk.NewDecCoins(initialCoinDenomOne), - newShares: sdk.OneDec(), - accumInit: sdk.NewDecCoins(initialCoinDenomOne, initialCoinDenomTwo), - expAccumDelta: sdk.NewDecCoins(initialCoinDenomOne, initialCoinDenomTwo), - expPass: true, - }, - "nonzero accumulator starting value, delta with new denoms": { - startingNumShares: initialValueOne, - startingUnclaimedRewards: sdk.NewDecCoins(initialCoinDenomOne), - newShares: sdk.OneDec(), - accumInit: sdk.NewDecCoins(initialCoinDenomOne, initialCoinDenomTwo), - expAccumDelta: sdk.NewDecCoins(initialCoinDenomTwo, initialCoinDenomThree), - expPass: true, - }, - "decimal shares with new rewards in two denoms": { - startingNumShares: initialValueOne, - startingUnclaimedRewards: sdk.NewDecCoins(), - newShares: sdk.NewDecWithPrec(983429874321, 5), - accumInit: sdk.NewDecCoins(), - expAccumDelta: sdk.NewDecCoins(initialCoinDenomOne, initialCoinDenomTwo), - expPass: true, - }, - - // error catching - "account does not exist": { - addrDoesNotExist: true, - expPass: false, - - startingNumShares: sdk.OneDec(), - startingUnclaimedRewards: emptyCoins, - newShares: sdk.OneDec(), - accumInit: emptyCoins, - expAccumDelta: sdk.NewDecCoins(), - }, - "attempt to add zero shares": { - startingNumShares: initialValueOne, - startingUnclaimedRewards: emptyCoins, - newShares: sdk.ZeroDec(), - accumInit: emptyCoins, - expAccumDelta: sdk.NewDecCoins(), - expPass: false, - }, - "attempt to add negative shares": { - startingNumShares: initialValueOne, - startingUnclaimedRewards: emptyCoins, - newShares: sdk.OneDec().Neg(), - accumInit: emptyCoins, - expAccumDelta: sdk.NewDecCoins(), - expPass: false, - }, - } - - for name, tc := range tests { - suite.Run(name, func() { - // We reset the store for each test - suite.SetupTest() - positionName := osmoutils.CreateRandomAccounts(1)[0].String() - - // Create a new accumulator with initial value specified by test case - curAccum := accumPackage.MakeTestAccumulator(suite.store, testNameOne, tc.accumInit, emptyDec) - - // Create new position in store (raw to minimize dependencies) - if !tc.addrDoesNotExist { - accumPackage.CreateRawPosition(curAccum, positionName, tc.startingNumShares, tc.startingUnclaimedRewards, nil) - } - - // Update accumulator with expAccumDelta (increasing position's rewards by a proportional amount) - curAccum = accumPackage.MakeTestAccumulator(suite.store, testNameOne, tc.accumInit.Add(tc.expAccumDelta...), emptyDec) - - // Add newShares to position - err := curAccum.AddToPosition(positionName, tc.newShares) - - if tc.expPass { - suite.Require().NoError(err) - - // Get updated position for comparison - newPosition, err := accumPackage.GetPosition(curAccum, positionName) - suite.Require().NoError(err) - - // Ensure position's accumulator value is moved up to init + delta - suite.Require().Equal(tc.accumInit.Add(tc.expAccumDelta...), newPosition.InitAccumValue) - - // Ensure accrued rewards are moved into UnclaimedRewards (both when it starts empty and not) - suite.Require().Equal(tc.startingUnclaimedRewards.Add(tc.expAccumDelta.MulDec(tc.startingNumShares)...), newPosition.UnclaimedRewards) - - // Ensure address's position properly reflects new number of shares - suite.Require().Equal(tc.startingNumShares.Add(tc.newShares), newPosition.NumShares) - - // Ensure a new position isn't created or removed from memory - allAccumPositions, err := curAccum.GetAllPositions() - suite.Require().NoError(err) - suite.Require().True(len(allAccumPositions) == 1) - } else { - suite.Require().Error(err) - - // Further checks to ensure state was not mutated upon error - if !tc.addrDoesNotExist { - // Get new position for comparison - newPosition, err := accumPackage.GetPosition(curAccum, positionName) - suite.Require().NoError(err) - - // Ensure that numShares, accumulator value, and unclaimed rewards are unchanged - suite.Require().Equal(tc.startingNumShares, newPosition.NumShares) - suite.Require().Equal(tc.accumInit, newPosition.InitAccumValue) - suite.Require().Equal(tc.startingUnclaimedRewards, newPosition.UnclaimedRewards) - } - } - }) - } -} - -// TestAddToPositionCustomAcc this test only focuses on testing the -// custom accumulator value functionality of adding to position. -func (suite *AccumTestSuite) TestAddToPositionCustomAcc() { - // We setup store and accum - // once at beginning so we can test duplicate positions - suite.SetupTest() - - // Setup. - accObject := accumPackage.MakeTestAccumulator(suite.store, testNameOne, initialCoinsDenomOne, emptyDec) - - tests := map[string]struct { - accObject accumPackage.AccumulatorObject - name string - numShareUnits sdk.Dec - customAcc sdk.DecCoins - expectedPosition accumPackage.Record - expectedError error - }{ - "custom acc value equals to acc": { - accObject: accObject, - name: testAddressOne, - numShareUnits: positionOne.NumShares, - customAcc: accObject.GetValue(), - expectedPosition: accumPackage.Record{ - NumShares: positionOne.NumShares, - InitAccumValue: accObject.GetValue(), - UnclaimedRewards: emptyCoins, - }, - }, - "custom acc value does not equal to acc": { - accObject: accObject, - name: testAddressTwo, - numShareUnits: positionTwo.NumShares, - customAcc: accObject.GetValue().MulDec(sdk.NewDec(2)), - expectedPosition: accumPackage.Record{ - NumShares: positionTwo.NumShares, - InitAccumValue: accObject.GetValue().MulDec(sdk.NewDec(2)), - UnclaimedRewards: emptyCoins, - }, - }, - } - - for name, tc := range tests { - tc := tc - suite.Run(name, func() { - // Setup - err := tc.accObject.NewPositionCustomAcc(tc.name, sdk.ZeroDec(), tc.accObject.GetValue(), nil) - suite.Require().NoError(err) - - // System under test. - err = tc.accObject.AddToPositionCustomAcc(tc.name, tc.numShareUnits, tc.customAcc) - - if tc.expectedError != nil { - suite.Require().Error(err) - suite.Require().Equal(tc.expectedError, err) - return - } - suite.Require().NoError(err) - - // Assertions. - position := tc.accObject.MustGetPosition(tc.name) - - suite.Require().Equal(tc.expectedPosition.NumShares, position.NumShares) - suite.Require().Equal(tc.expectedPosition.InitAccumValue, position.InitAccumValue) - suite.Require().Equal(tc.expectedPosition.UnclaimedRewards, position.UnclaimedRewards) - suite.Require().Nil(position.Options) - }) - } -} - -func (suite *AccumTestSuite) TestRemoveFromPosition() { - type testcase struct { - startingNumShares sdk.Dec - startingUnclaimedRewards sdk.DecCoins - removedShares sdk.Dec - - // accumInit and expAccumDelta specify the initial accum value - // and how much it has changed since the position being added - // to was created - accumInit sdk.DecCoins - expAccumDelta sdk.DecCoins - - addrDoesNotExist bool - expPass bool - } - - tests := map[string]testcase{ - "no new rewards": { - startingNumShares: initialValueOne, - startingUnclaimedRewards: sdk.NewDecCoins(), - removedShares: sdk.OneDec(), - accumInit: sdk.NewDecCoins(), - // unchanged accum value, so no unclaimed rewards - expAccumDelta: sdk.NewDecCoins(), - expPass: true, - }, - "new rewards in one denom": { - startingNumShares: initialValueOne, - startingUnclaimedRewards: sdk.NewDecCoins(), - removedShares: sdk.OneDec(), - accumInit: sdk.NewDecCoins(), - // unclaimed rewards since last update - expAccumDelta: sdk.NewDecCoins(initialCoinDenomOne), - expPass: true, - }, - "new rewards in two denoms": { - startingNumShares: initialValueOne, - startingUnclaimedRewards: sdk.NewDecCoins(), - removedShares: sdk.OneDec(), - accumInit: sdk.NewDecCoins(), - expAccumDelta: sdk.NewDecCoins(initialCoinDenomOne, initialCoinDenomTwo), - expPass: true, - }, - "both existing and new rewards": { - startingNumShares: initialValueOne, - startingUnclaimedRewards: sdk.NewDecCoins(sdk.NewDecCoin(denomOne, sdk.NewInt(11)), sdk.NewDecCoin(denomTwo, sdk.NewInt(11))), - removedShares: sdk.OneDec(), - accumInit: sdk.NewDecCoins(), - expAccumDelta: sdk.NewDecCoins(initialCoinDenomOne, initialCoinDenomTwo), - expPass: true, - }, - "both existing (one denom) and new rewards (two denoms, one overlapping)": { - startingNumShares: initialValueOne, - startingUnclaimedRewards: sdk.NewDecCoins(initialCoinDenomOne), - removedShares: sdk.OneDec(), - accumInit: sdk.NewDecCoins(), - expAccumDelta: sdk.NewDecCoins(initialCoinDenomOne, initialCoinDenomTwo), - expPass: true, - }, - "both existing (one denom) and new rewards (two new denoms)": { - startingNumShares: initialValueOne, - startingUnclaimedRewards: sdk.NewDecCoins(initialCoinDenomOne), - removedShares: sdk.OneDec(), - accumInit: sdk.NewDecCoins(), - expAccumDelta: sdk.NewDecCoins(initialCoinDenomTwo, initialCoinDenomThree), - expPass: true, - }, - "nonzero accumulator starting value, delta with same denoms": { - startingNumShares: initialValueOne, - startingUnclaimedRewards: sdk.NewDecCoins(initialCoinDenomOne), - removedShares: sdk.OneDec(), - accumInit: sdk.NewDecCoins(initialCoinDenomOne, initialCoinDenomTwo), - expAccumDelta: sdk.NewDecCoins(initialCoinDenomOne, initialCoinDenomTwo), - expPass: true, - }, - "nonzero accumulator starting value, delta with new denoms": { - startingNumShares: initialValueOne, - startingUnclaimedRewards: sdk.NewDecCoins(initialCoinDenomOne), - removedShares: sdk.OneDec(), - accumInit: sdk.NewDecCoins(initialCoinDenomOne, initialCoinDenomTwo), - expAccumDelta: sdk.NewDecCoins(initialCoinDenomTwo, initialCoinDenomThree), - expPass: true, - }, - "remove decimal shares with new rewards in two denoms": { - startingNumShares: sdk.NewDec(1000000), - startingUnclaimedRewards: sdk.NewDecCoins(), - removedShares: sdk.NewDecWithPrec(7489274134, 5), - accumInit: sdk.NewDecCoins(), - expAccumDelta: sdk.NewDecCoins(initialCoinDenomOne, initialCoinDenomTwo), - expPass: true, - }, - "attempt to remove exactly numShares": { - startingNumShares: sdk.OneDec(), - startingUnclaimedRewards: emptyCoins, - removedShares: sdk.OneDec(), - accumInit: emptyCoins, - expAccumDelta: sdk.NewDecCoins(), - expPass: true, - }, - - // error catching - "account does not exist": { - addrDoesNotExist: true, - expPass: false, - - startingNumShares: initialValueOne, - startingUnclaimedRewards: emptyCoins, - removedShares: sdk.OneDec(), - accumInit: emptyCoins, - expAccumDelta: sdk.NewDecCoins(), - }, - "attempt to remove zero shares": { - startingNumShares: initialValueOne, - startingUnclaimedRewards: emptyCoins, - removedShares: sdk.ZeroDec(), - accumInit: emptyCoins, - expAccumDelta: sdk.NewDecCoins(), - expPass: false, - }, - "attempt to remove negative shares": { - startingNumShares: sdk.OneDec(), - startingUnclaimedRewards: emptyCoins, - removedShares: sdk.OneDec().Neg(), - accumInit: emptyCoins, - expAccumDelta: sdk.NewDecCoins(), - expPass: false, - }, - } - - for name, tc := range tests { - suite.Run(name, func() { - // We reset the store for each test - suite.SetupTest() - positionName := osmoutils.CreateRandomAccounts(1)[0].String() - - // Create a new accumulator with initial value specified by test case - curAccum := accumPackage.MakeTestAccumulator(suite.store, testNameOne, tc.accumInit, emptyDec) - - // Create new position in store (raw to minimize dependencies) - if !tc.addrDoesNotExist { - accumPackage.CreateRawPosition(curAccum, positionName, tc.startingNumShares, tc.startingUnclaimedRewards, nil) - } - - // Update accumulator with expAccumDelta (increasing position's rewards by a proportional amount) - curAccum = accumPackage.MakeTestAccumulator(suite.store, testNameOne, tc.accumInit.Add(tc.expAccumDelta...), emptyDec) - - // Remove removedShares from position - err := curAccum.RemoveFromPosition(positionName, tc.removedShares) - - if tc.expPass { - suite.Require().NoError(err) - - // Get updated position for comparison - newPosition, err := accumPackage.GetPosition(curAccum, positionName) - suite.Require().NoError(err) - - // Ensure position's accumulator value is moved up to init + delta - suite.Require().Equal(tc.accumInit.Add(tc.expAccumDelta...), newPosition.InitAccumValue) - - // Ensure accrued rewards are moved into UnclaimedRewards (both when it starts empty and not) - suite.Require().Equal(tc.startingUnclaimedRewards.Add(tc.expAccumDelta.MulDec(tc.startingNumShares)...), newPosition.UnclaimedRewards) - - // Ensure address's position properly reflects new number of shares - if (tc.startingNumShares.Sub(tc.removedShares)).Equal(sdk.ZeroDec()) { - suite.Require().Equal(emptyDec, newPosition.NumShares) - } else { - suite.Require().Equal(tc.startingNumShares.Sub(tc.removedShares), newPosition.NumShares) - } - - // Ensure a new position isn't created in memory (only old one is overwritten) - allAccumPositions, err := curAccum.GetAllPositions() - suite.Require().NoError(err) - suite.Require().True(len(allAccumPositions) == 1) - } else { - suite.Require().Error(err) - - // Further checks to ensure state was not mutated upon error - if !tc.addrDoesNotExist { - // Get new position for comparison - newPosition, err := accumPackage.GetPosition(curAccum, positionName) - suite.Require().NoError(err) - - // Ensure that numShares, accumulator value, and unclaimed rewards are unchanged - suite.Require().Equal(tc.startingNumShares, newPosition.NumShares) - suite.Require().Equal(tc.accumInit, newPosition.InitAccumValue) - suite.Require().Equal(tc.startingUnclaimedRewards, newPosition.UnclaimedRewards) - } - } - }) - } -} - -// TestRemoveFromPositionCustomAcc this test only focuses on testing the -// custom accumulator value functionality of removing from a position. -func (suite *AccumTestSuite) TestRemoveFromPositionCustomAcc() { - // We setup store and accum - // once at beginning so we can test duplicate positions - suite.SetupTest() - - baseAccumValue := initialCoinsDenomOne - - // Setup. - accObject := accumPackage.MakeTestAccumulator(suite.store, testNameOne, baseAccumValue, emptyDec) - - tests := map[string]struct { - accObject accumPackage.AccumulatorObject - name string - numShareUnits sdk.Dec - customAcc sdk.DecCoins - expectedPosition accumPackage.Record - expectedError error - }{ - "custom acc value equals to acc": { - accObject: accObject, - name: testAddressOne, - numShareUnits: positionOne.NumShares, - customAcc: baseAccumValue, - expectedPosition: accumPackage.Record{ - NumShares: sdk.ZeroDec(), - InitAccumValue: baseAccumValue, - // base value - 0.5 * base = base value - UnclaimedRewards: baseAccumValue.MulDec(sdk.NewDecWithPrec(5, 1)).MulDec(positionOne.NumShares), - }, - }, - "custom acc value does not equal to acc": { - accObject: accObject, - name: testAddressTwo, - numShareUnits: positionTwo.NumShares, - customAcc: baseAccumValue.MulDec(sdk.NewDecWithPrec(75, 2)), - expectedPosition: accumPackage.Record{ - NumShares: sdk.ZeroDec(), - InitAccumValue: baseAccumValue.MulDec(sdk.NewDecWithPrec(75, 2)), - // base value - 0.75 * base = 0.25 * base - UnclaimedRewards: baseAccumValue.MulDec(sdk.NewDecWithPrec(25, 2)).MulDec(positionTwo.NumShares), - }, - }, - } - - for name, tc := range tests { - tc := tc - suite.Run(name, func() { - // Setup - - // Original position's accum is always set to 0.5 * base value. - err := tc.accObject.NewPositionCustomAcc(tc.name, tc.numShareUnits, initialCoinsDenomOne.MulDec(sdk.NewDecWithPrec(5, 1)), nil) - suite.Require().NoError(err) - - tc.accObject.SetValue(tc.customAcc) - - // System under test. - err = tc.accObject.RemoveFromPositionCustomAcc(tc.name, tc.numShareUnits, tc.customAcc) - - if tc.expectedError != nil { - suite.Require().Error(err) - suite.Require().Equal(tc.expectedError, err) - return - } - suite.Require().NoError(err) - - // Assertions. - position := tc.accObject.MustGetPosition(tc.name) - - suite.Require().Equal(tc.expectedPosition.NumShares, position.NumShares) - suite.Require().Equal(tc.expectedPosition.InitAccumValue, position.InitAccumValue) - suite.Require().Equal(tc.expectedPosition.UnclaimedRewards, position.UnclaimedRewards) - suite.Require().Nil(position.Options) - }) - } -} - -func (suite *AccumTestSuite) TestGetPositionSize() { - type testcase struct { - numShares sdk.Dec - changedShares sdk.Dec - - // accumInit and expAccumDelta specify the initial accum value - // and how much it has changed since the position being added - // to was created - accumInit sdk.DecCoins - expAccumDelta sdk.DecCoins - - addrDoesNotExist bool - expPass bool - } - - tests := map[string]testcase{ - "unchanged accumulator": { - numShares: sdk.OneDec(), - accumInit: sdk.NewDecCoins(), - expAccumDelta: sdk.NewDecCoins(), - changedShares: sdk.ZeroDec(), - expPass: true, - }, - "changed accumulator": { - numShares: sdk.OneDec(), - accumInit: sdk.NewDecCoins(), - expAccumDelta: sdk.NewDecCoins(initialCoinDenomOne, initialCoinDenomTwo), - changedShares: sdk.ZeroDec(), - expPass: true, - }, - "changed number of shares": { - numShares: sdk.OneDec(), - accumInit: sdk.NewDecCoins(), - expAccumDelta: sdk.NewDecCoins(), - changedShares: sdk.OneDec(), - expPass: true, - }, - "account does not exist": { - addrDoesNotExist: true, - expPass: false, - - numShares: sdk.OneDec(), - accumInit: sdk.NewDecCoins(), - expAccumDelta: sdk.NewDecCoins(), - changedShares: sdk.ZeroDec(), - }, - } - - for name, tc := range tests { - suite.Run(name, func() { - // We reset the store for each test - suite.SetupTest() - positionName := osmoutils.CreateRandomAccounts(1)[0].String() - - // Create a new accumulator with initial value specified by test case - curAccum := accumPackage.MakeTestAccumulator(suite.store, testNameOne, tc.accumInit, emptyDec) - - // Create new position in store (raw to minimize dependencies) - if !tc.addrDoesNotExist { - accumPackage.CreateRawPosition(curAccum, positionName, tc.numShares, sdk.NewDecCoins(), nil) - } - - // Update accumulator with expAccumDelta (increasing position's rewards by a proportional amount) - curAccum = accumPackage.MakeTestAccumulator(suite.store, testNameOne, tc.accumInit.Add(tc.expAccumDelta...), emptyDec) - - // Get position size from valid address (or from nonexistant if address does not exist) - positionSize, err := curAccum.GetPositionSize(positionName) - - if tc.changedShares.GT(sdk.ZeroDec()) { - accumPackage.CreateRawPosition(curAccum, positionName, tc.numShares.Add(tc.changedShares), sdk.NewDecCoins(), nil) - } - - positionSize, err = curAccum.GetPositionSize(positionName) - - if tc.expPass { - suite.Require().NoError(err) - suite.Require().Equal(tc.numShares.Add(tc.changedShares), positionSize) - - // Ensure nothing was added or removed from store - allAccumPositions, err := curAccum.GetAllPositions() - suite.Require().NoError(err) - suite.Require().True(len(allAccumPositions) == 1) - } else { - suite.Require().Error(err) - } - }) - } -} - -// TestMarhsalUnmarshalRecord displays that we may use Records without options -// For records with nil options, adding new fields to `Options`, should not -// require future migrations. -func (suite *AccumTestSuite) TestMarhsalUnmarshalRecord() { - suite.SetupTest() - - recordNoOptions := accumPackage.Record{ - NumShares: sdk.OneDec(), - InitAccumValue: sdk.NewDecCoins( - sdk.NewDecCoinFromDec(denomOne, sdk.OneDec()), - ), - UnclaimedRewards: sdk.NewDecCoins( - sdk.NewDecCoinFromDec(denomOne, sdk.OneDec()), - ), - } - - bz, err := proto.Marshal(&recordNoOptions) - suite.Require().NoError(err) - - var unmarshaledRecord accumPackage.Record - proto.Unmarshal(bz, &unmarshaledRecord) - // Options should be nil, not an empty struct - suite.Require().True(unmarshaledRecord.Options == nil) -} - -func (suite *AccumTestSuite) TestAddToAccumulator() { - tests := map[string]struct { - updateAmount sdk.DecCoins - - expectedValue sdk.DecCoins - }{ - "positive": { - updateAmount: initialCoinsDenomOne, - - expectedValue: initialCoinsDenomOne, - }, - "negative": { - updateAmount: initialCoinsDenomOne.MulDec(sdk.NewDec(-1)), - - expectedValue: initialCoinsDenomOne.MulDec(sdk.NewDec(-1)), - }, - "multiple coins": { - updateAmount: initialCoinsDenomOne.Add(initialCoinDenomTwo), - - expectedValue: initialCoinsDenomOne.Add(initialCoinDenomTwo), - }, - } - - for name, tc := range tests { - suite.Run(name, func() { - // Setup - suite.SetupTest() - - err := accumPackage.MakeAccumulator(suite.store, testNameOne) - suite.Require().NoError(err) - originalAccum, err := accumPackage.GetAccumulator(suite.store, testNameOne) - suite.Require().NoError(err) - - // System under test. - originalAccum.AddToAccumulator(tc.updateAmount) - - // Validations. - - // validate that the reciever is mutated. - suite.Require().Equal(tc.expectedValue, originalAccum.GetValue()) - - accumFromStore, err := accumPackage.GetAccumulator(suite.store, testNameOne) - suite.Require().NoError(err) - - // validate that store is updated. - suite.Require().Equal(tc.expectedValue, accumFromStore.GetValue()) - }) - } -} - -func (suite *AccumTestSuite) TestUpdatePosition() { - // Setup. - accObject := accumPackage.MakeTestAccumulator(suite.store, testNameOne, initialCoinsDenomOne, emptyDec) - - tests := map[string]struct { - name string - numShares sdk.Dec - expectedPosition accumPackage.Record - expectError error - }{ - "positive - acts as AddToPosition": { - name: testAddressOne, - numShares: sdk.OneDec(), - - expectedPosition: accumPackage.Record{ - NumShares: sdk.OneDec().MulInt64(2), - InitAccumValue: initialCoinsDenomOne, - UnclaimedRewards: emptyCoins, - }, - }, - "negative - acts as RemoveFromPosition": { - name: testAddressOne, - numShares: sdk.OneDec().Neg(), - - expectedPosition: accumPackage.Record{ - NumShares: sdk.ZeroDec(), - InitAccumValue: initialCoinsDenomOne, - UnclaimedRewards: emptyCoins, - }, - }, - "zero - error": { - name: testAddressOne, - numShares: sdk.ZeroDec(), - - expectError: accumPackage.ZeroSharesError, - }, - } - - for name, tc := range tests { - suite.Run(name, func() { - suite.SetupTest() - - err := accObject.NewPosition(tc.name, sdk.OneDec(), nil) - suite.Require().NoError(err) - - err = accObject.UpdatePosition(tc.name, tc.numShares) - - if tc.expectError != nil { - suite.Require().Error(err) - suite.Require().ErrorIs(err, tc.expectError) - return - } - suite.Require().NoError(err) - - updatedPosition := accObject.MustGetPosition(tc.name) - - // Assertions. - position := accObject.MustGetPosition(tc.name) - - suite.Require().Equal(tc.expectedPosition.NumShares, updatedPosition.NumShares) - suite.Require().Equal(tc.expectedPosition.InitAccumValue, updatedPosition.InitAccumValue) - suite.Require().Equal(tc.expectedPosition.UnclaimedRewards, updatedPosition.UnclaimedRewards) - suite.Require().Nil(position.Options) - }) - } -} - -// TestUpdatePositionCustomAcc this test only focuses on testing the -// custom accumulator value functionality of updating a position. -func (suite *AccumTestSuite) TestUpdatePositionCustomAcc() { - tests := []struct { - testName string - initialShares sdk.Dec - initialAccum sdk.DecCoins - accName string - numShareUnits sdk.Dec - customAcc sdk.DecCoins - expectedPosition accumPackage.Record - expectedError error - }{ - { - testName: "custom acc value equals to acc; positive shares -> acts as AddToPosition", - initialShares: sdk.ZeroDec(), - initialAccum: initialCoinsDenomOne, - accName: testAddressOne, - numShareUnits: positionOne.NumShares, - customAcc: initialCoinsDenomOne, - expectedPosition: accumPackage.Record{ - NumShares: positionOne.NumShares, - InitAccumValue: initialCoinsDenomOne, - UnclaimedRewards: emptyCoins, - }, - }, - { - testName: "custom acc value does not equal to acc; remove same amount -> acts as RemoveFromPosition", - initialShares: positionTwo.NumShares, - initialAccum: initialCoinsDenomOne, - accName: testAddressTwo, - numShareUnits: positionTwo.NumShares.Neg(), // note: negative shares - customAcc: initialCoinsDenomOne.MulDec(sdk.NewDec(2)), - expectedPosition: accumPackage.Record{ - NumShares: sdk.ZeroDec(), // results in 0 shares (200 - 200) - InitAccumValue: initialCoinsDenomOne.MulDec(sdk.NewDec(2)), - UnclaimedRewards: emptyCoins, - }, - }, - { - testName: "custom acc value does not equal to acc; remove diff amount -> acts as RemoveFromPosition", - initialShares: positionTwo.NumShares, - initialAccum: initialCoinsDenomOne, - accName: testAddressTwo, - numShareUnits: positionOne.NumShares.Neg(), // note: negative shares - customAcc: initialCoinsDenomOne.MulDec(sdk.NewDec(2)), - expectedPosition: accumPackage.Record{ - NumShares: positionOne.NumShares, // results in 100 shares (200 - 100) - InitAccumValue: initialCoinsDenomOne.MulDec(sdk.NewDec(2)), - UnclaimedRewards: emptyCoins, - }, - }, - } - - for _, tc := range tests { - tc := tc - suite.Run(tc.testName, func() { - suite.SetupTest() - - // make accumualtor based off of tc.accObject - err := accumPackage.MakeAccumulator(suite.store, testNameOne) - suite.Require().NoError(err) - - accumObject, err := accumPackage.GetAccumulator(suite.store, testNameOne) - suite.Require().NoError(err) - - // manually update accumulator value - accumObject.AddToAccumulator(initialCoinsDenomOne) - - // Setup - err = accumObject.NewPositionCustomAcc(tc.accName, tc.initialShares, tc.initialAccum, nil) - suite.Require().NoError(err) - - // System under test. - err = accumObject.UpdatePositionCustomAcc(tc.accName, tc.numShareUnits, tc.customAcc) - - if tc.expectedError != nil { - suite.Require().Error(err) - suite.Require().Equal(tc.expectedError, err) - return - } - suite.Require().NoError(err) - - accumObject, err = accumPackage.GetAccumulator(suite.store, testNameOne) - suite.Require().NoError(err) - - position := accumObject.MustGetPosition(tc.accName) - // Assertions. - - suite.Require().Equal(tc.expectedPosition.NumShares, position.NumShares) - suite.Require().Equal(tc.expectedPosition.InitAccumValue, position.InitAccumValue) - suite.Require().Equal(tc.expectedPosition.UnclaimedRewards, position.UnclaimedRewards) - suite.Require().Nil(position.Options) - }) - } -} - -func (suite *AccumTestSuite) TestHasPosition() { - // We setup store and accum - // once at beginning. - suite.SetupTest() - - const ( - defaultPositionName = "posname" - ) - - // Setup. - accObject := accumPackage.MakeTestAccumulator(suite.store, testNameOne, initialCoinsDenomOne, emptyDec) - - tests := []struct { - name string - preCreatePosition bool - }{ - { - name: "position does not exist -> false", - preCreatePosition: false, - }, - { - name: "position exists -> true", - preCreatePosition: true, - }, - } - - for _, tc := range tests { - tc := tc - suite.Run(tc.name, func() { - // Setup - if tc.preCreatePosition { - err := accObject.NewPosition(defaultPositionName, sdk.ZeroDec(), nil) - suite.Require().NoError(err) - } - - hasPosition, err := accObject.HasPosition(defaultPositionName) - suite.NoError(err) - - suite.Equal(tc.preCreatePosition, hasPosition) - }) - } -} - -func (suite *AccumTestSuite) TestSetPositionCustomAcc() { - // We setup store and accum - // once at beginning. - suite.SetupTest() - - // Setup. - var ( - accObject = accumPackage.MakeTestAccumulator(suite.store, testNameOne, initialCoinsDenomOne, emptyDec) - validPositionName = testAddressThree - invalidPositionName = testAddressTwo - ) - - tests := map[string]struct { - positionName string - customAccumulatorValue sdk.DecCoins - expectedError error - }{ - "valid update greater than initial value": { - positionName: validPositionName, - customAccumulatorValue: initialCoinsDenomOne.Add(initialCoinDenomOne), - }, - "valid update equal to the initial value": { - positionName: validPositionName, - customAccumulatorValue: initialCoinsDenomOne, - }, - "invalid position - different name": { - positionName: invalidPositionName, - expectedError: accumPackage.NoPositionError{Name: invalidPositionName}, - }, - } - - for name, tc := range tests { - suite.Run(name, func() { - // Setup - err := accObject.NewPositionCustomAcc(validPositionName, sdk.OneDec(), initialCoinsDenomOne, nil) - suite.Require().NoError(err) - - // System under test. - err = accObject.SetPositionCustomAcc(tc.positionName, tc.customAccumulatorValue) - - // Assertions. - if tc.expectedError != nil { - suite.Require().Error(err) - suite.Require().Equal(tc.expectedError, err) - return - } - suite.Require().NoError(err) - - position := accObject.MustGetPosition(tc.positionName) - suite.Require().Equal(tc.customAccumulatorValue, position.GetInitAccumValue()) - // unchanged - suite.Require().Equal(sdk.OneDec(), position.NumShares) - suite.Require().Equal(emptyCoins, position.GetUnclaimedRewards()) - }) - } -} - -// We run a series of partially random operations on two accumulators to ensure that total shares are properly tracked in state -func (suite *AccumTestSuite) TestGetTotalShares() { - suite.SetupTest() - - // Set seed to make tests deterministic - rand.Seed(1) - - // Set up two accumulators to ensure we can test all relevant behavior - err := accumPackage.MakeAccumulator(suite.store, testNameOne) - suite.Require().NoError(err) - err = accumPackage.MakeAccumulator(suite.store, testNameTwo) - suite.Require().NoError(err) - - // Fetch both accumulators for initial sanity tests - accumOne, err := accumPackage.GetAccumulator(suite.store, testNameOne) - suite.Require().NoError(err) - accumTwo, err := accumPackage.GetAccumulator(suite.store, testNameTwo) - suite.Require().NoError(err) - - // Ensure that both accums start at zero shares - accumOneShares, err := accumOne.GetTotalShares() - suite.Require().NoError(err) - accumTwoShares, err := accumTwo.GetTotalShares() - suite.Require().NoError(err) - suite.Require().Equal(sdk.ZeroDec(), accumOneShares) - suite.Require().Equal(sdk.ZeroDec(), accumTwoShares) - - // Create position on first accum and pull new accum objects from state - err = accumOne.NewPosition(testAddressOne, sdk.OneDec(), nil) - suite.Require().NoError(err) - accumOne, err = accumPackage.GetAccumulator(suite.store, testNameOne) - suite.Require().NoError(err) - accumTwo, err = accumPackage.GetAccumulator(suite.store, testNameTwo) - suite.Require().NoError(err) - - // Check that total shares for accum one has updated properly and accum two shares are unchanged - accumOneShares, err = accumOne.GetTotalShares() - suite.Require().NoError(err) - accumTwoShares, err = accumTwo.GetTotalShares() - suite.Require().NoError(err) - suite.Require().Equal(sdk.OneDec(), accumOneShares) - suite.Require().Equal(sdk.ZeroDec(), accumTwoShares) - - // Run a number of NewPosition, AddToPosition, and RemoveFromPosition operations on each accum - testAddresses := []string{testAddressOne, testAddressTwo, testAddressThree} - accums := []accumPackage.AccumulatorObject{accumOne, accumTwo} - expectedShares := []sdk.Dec{sdk.OneDec(), sdk.ZeroDec()} - - for i := 1; i <= 10; i++ { - // Cycle through accounts and accumulators - curAddr := testAddresses[i%3] - curAccum := accums[i%2] - - // We set a baseAmt that varies with the iteration to increase coverage - baseAmt := sdk.NewDec(int64(i)).Mul(sdk.NewDec(10)) - - // If addr doesn't have a position yet, we make one - positionExists, err := curAccum.HasPosition(curAddr) - suite.Require().NoError(err) - if !positionExists { - err = curAccum.NewPosition(curAddr, baseAmt, nil) - suite.Require().NoError(err) - } - - // We generate a random binary value (0 or 1) to determine - // whether we will add and/or remove liquidity this loop - addShares := sdk.NewDec(int64(rand.Int()) % 2) - removeShares := sdk.NewDec(int64(rand.Int()) % 2) - - // Half the time, we add to the new position - addAmt := baseAmt.Mul(addShares) - if addAmt.GT(sdk.ZeroDec()) { - err = curAccum.AddToPosition(curAddr, addAmt) - suite.Require().NoError(err) - } - - // Half the time, we remove one share from the position - amtToRemove := sdk.OneDec().Mul(removeShares) - if amtToRemove.GT(sdk.ZeroDec()) { - err = curAccum.RemoveFromPosition(curAddr, amtToRemove) - suite.Require().NoError(err) - } - - // Finally, we update our expected number of shares for the accumulator - // we targeted in this loop - if !positionExists { - // If a new position was created, we factor its new shares in - expectedShares[i%2] = expectedShares[i%2].Add(baseAmt) - } - expectedShares[i%2] = expectedShares[i%2].Add(addAmt).Sub(amtToRemove) - } - - // Get updated accums from state to validate results - accumOne, err = accumPackage.GetAccumulator(suite.store, testNameOne) - suite.Require().NoError(err) - accumTwo, err = accumPackage.GetAccumulator(suite.store, testNameTwo) - suite.Require().NoError(err) - - // Ensure that total shares in each accum matches our expected number of shares - accumOneShares, err = accumOne.GetTotalShares() - suite.Require().NoError(err) - accumTwoShares, err = accumTwo.GetTotalShares() - suite.Require().NoError(err) - suite.Require().Equal(expectedShares[0], accumOneShares) - suite.Require().Equal(expectedShares[1], accumTwoShares) -} diff --git a/osmoutils/accum/errors.go b/osmoutils/accum/errors.go deleted file mode 100644 index 397cdb407..000000000 --- a/osmoutils/accum/errors.go +++ /dev/null @@ -1,44 +0,0 @@ -package accum - -import ( - "errors" - "fmt" - - sdk "github.com/cosmos/cosmos-sdk/types" -) - -var ( - ZeroSharesError = errors.New("shares must be non-zero") -) - -type NoPositionError struct { - Name string -} - -func (e NoPositionError) Error() string { - return fmt.Sprintf("no position found for position key (%s)", e.Name) -} - -type NegativeCustomAccError struct { - CustomAccumulatorValue sdk.DecCoins -} - -func (e NegativeCustomAccError) Error() string { - return fmt.Sprintf("customAccumulatorValue must be non-negative, was (%s)", e.CustomAccumulatorValue) -} - -type NegativeAccDifferenceError struct { - AccumulatorDifference sdk.DecCoins -} - -func (e NegativeAccDifferenceError) Error() string { - return fmt.Sprintf("difference (%s) between the old and the new accumulator value is negative", e.AccumulatorDifference) -} - -type AccumDoesNotExistError struct { - AccumName string -} - -func (e AccumDoesNotExistError) Error() string { - return fmt.Sprintf("Accumulator name %s does not exist in store", e.AccumName) -} diff --git a/osmoutils/accum/export_test.go b/osmoutils/accum/export_test.go deleted file mode 100644 index 0a44d52d5..000000000 --- a/osmoutils/accum/export_test.go +++ /dev/null @@ -1,77 +0,0 @@ -package accum - -import ( - "errors" - - "github.com/gogo/protobuf/proto" - - "github.com/cosmos/cosmos-sdk/store" - sdk "github.com/cosmos/cosmos-sdk/types" - - "github.com/CosmosContracts/juno/v15/osmoutils" -) - -// GetAllPositions returns all positions associated with the receiver accumulator. -// Returns error if any database errors occur. -// This function is currently used for testing purposes only. -// If there is a need to use this function in production, it -// can be moved to a non-test file. -func (accum AccumulatorObject) GetAllPositions() ([]Record, error) { - return osmoutils.GatherValuesFromStorePrefix(accum.store, FormatPositionPrefixKey(accum.name, ""), parseRecordFromBz) -} - -// Creates an accumulator object for testing purposes -func MakeTestAccumulator(store store.KVStore, name string, value sdk.DecCoins, totalShares sdk.Dec) AccumulatorObject { - // We store an accumulator object in state even if unused in tests - // because position operations still require GetAccumulator to work - _ = MakeAccumulator(store, name) - return AccumulatorObject{ - store: store, - name: name, - value: value, - totalShares: totalShares, - } -} - -func CreateRawPosition(accum AccumulatorObject, name string, numShareUnits sdk.Dec, unclaimedRewards sdk.DecCoins, options *Options) { - initOrUpdatePosition(accum, accum.value, name, numShareUnits, unclaimedRewards, options) -} - -// Gets store from accumulator for testing purposes -func GetStore(accum AccumulatorObject) store.KVStore { - return accum.store -} - -// parseRecordFromBz parses a record from a byte slice. -// Returns error if fails to unmarshal or if the given bytes slice -// is empty. -func parseRecordFromBz(bz []byte) (record Record, err error) { - if len(bz) == 0 { - return Record{}, errors.New("record not found") - } - err = proto.Unmarshal(bz, &record) - if err != nil { - return Record{}, err - } - return record, nil -} - -func ValidateAccumulatorValue(customAccumulatorValue, oldPositionAccumulatorValue sdk.DecCoins) error { - return validateAccumulatorValue(customAccumulatorValue, oldPositionAccumulatorValue) -} - -// WithPosition is a decorator test function to append a position with the given name to the given accumulator. -func WithPosition(accum AccumulatorObject, name string, position Record) AccumulatorObject { - osmoutils.MustSet(accum.store, FormatPositionPrefixKey(accum.name, name), &position) - return accum -} - -// SetValue is a convinience test helper for updatung the value of an accumulator object -// in tests. -func (accum *AccumulatorObject) SetValue(value sdk.DecCoins) { - accum.value = value -} - -func (o *Options) Validate() error { - return o.validate() -} diff --git a/osmoutils/accum/module.go b/osmoutils/accum/module.go deleted file mode 100644 index 297d7feb3..000000000 --- a/osmoutils/accum/module.go +++ /dev/null @@ -1,3 +0,0 @@ -// package accumulator allows one to define an accumulator to accommodate constant-rate -// (linear) distribution mechanisms with constant runtime and linear memory -package accum diff --git a/osmoutils/accum/options.go b/osmoutils/accum/options.go deleted file mode 100644 index 51add520d..000000000 --- a/osmoutils/accum/options.go +++ /dev/null @@ -1,20 +0,0 @@ -package accum - -import ( - sdk "github.com/cosmos/cosmos-sdk/types" -) - -var one = sdk.OneDec() - -// validate returns nil if Options are valid. -// Error otherwise. Note, that, currently, -// options do not contain any fields. We -// create them to be able to extend in the -// future with auto-compounding logic. -// As a result, this always returns nil. -func (o *Options) validate() error { - if o == nil { - return nil - } - return nil -} diff --git a/osmoutils/accum/options_test.go b/osmoutils/accum/options_test.go deleted file mode 100644 index 7c85e4e6f..000000000 --- a/osmoutils/accum/options_test.go +++ /dev/null @@ -1,32 +0,0 @@ -package accum_test - -import "github.com/CosmosContracts/juno/v15/osmoutils/accum" - -// TestOptionsValidate tests that the options are validated correctly. -func (suite *AccumTestSuite) TestOptionsValidate() { - tests := map[string]struct { - options *accum.Options - expectError error - }{ - "nil options - success": { - options: nil, - }, - "non-nil options - success": { - options: &accum.Options{}, - }, - } - - for name, tc := range tests { - suite.Run(name, func() { - suite.SetupTest() - - err := tc.options.Validate() - - if tc.expectError != nil { - suite.Require().Error(err) - return - } - suite.Require().NoError(err) - }) - } -} diff --git a/osmoutils/accum/prefix.go b/osmoutils/accum/prefix.go deleted file mode 100644 index 4dea6af88..000000000 --- a/osmoutils/accum/prefix.go +++ /dev/null @@ -1,30 +0,0 @@ -package accum - -import "fmt" - -const ( - modulePrefix = "accum" - accumulatorPrefix = "acc" - positionPrefix = "pos" -) - -// formatAccumPrefix returns the key prefix used for any -// accum module values to be stored in the KVStore. -// Returns "accum/{key}" as bytes. -func formatModulePrefixKey(key string) []byte { - return []byte(fmt.Sprintf("%s/%s", modulePrefix, key)) -} - -// formatAccumPrefix returns the key prefix used -// specifically for accumulator values in the KVStore. -// Returns "accum/acc/{name}" as bytes. -func formatAccumPrefixKey(name string) []byte { - return formatModulePrefixKey(fmt.Sprintf("%s/%s", accumulatorPrefix, name)) -} - -// FormatPositionPrefixKey returns the key prefix used -// specifically for position values in the KVStore. -// Returns "accum/pos/{accumName}/{name}" as bytes. -func FormatPositionPrefixKey(accumName, name string) []byte { - return formatAccumPrefixKey(fmt.Sprintf("%s/%s/%s", positionPrefix, accumName, name)) -} diff --git a/osmoutils/address.go b/osmoutils/address.go deleted file mode 100644 index fb47d79da..000000000 --- a/osmoutils/address.go +++ /dev/null @@ -1,12 +0,0 @@ -package osmoutils - -import ( - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/address" -) - -// NewModuleAddressWithPrefix returns a new module address with the given prefix and identifier. -func NewModuleAddressWithPrefix(moduleName, prefix string, identifier []byte) sdk.AccAddress { - key := append([]byte(prefix), identifier...) - return address.Module(moduleName, key) -} diff --git a/osmoutils/cache_ctx.go b/osmoutils/cache_ctx.go deleted file mode 100644 index 0d4cbe680..000000000 --- a/osmoutils/cache_ctx.go +++ /dev/null @@ -1,80 +0,0 @@ -package osmoutils - -import ( - "errors" - "fmt" - "runtime" - "runtime/debug" - - "github.com/cosmos/cosmos-sdk/store/types" - sdk "github.com/cosmos/cosmos-sdk/types" -) - -// This function lets you run the function f, but if theres an error or panic -// drop the state machine change and log the error. -// If there is no error, proceeds as normal (but with some slowdown due to SDK store weirdness) -// Try to avoid usage of iterators in f. -// -// If its an out of gas panic, this function will also panic like in normal tx execution flow. -// This is still safe for beginblock / endblock code though, as they do not have out of gas panics. -func ApplyFuncIfNoError(ctx sdk.Context, f func(ctx sdk.Context) error) (err error) { - // Add a panic safeguard - defer func() { - if recoveryError := recover(); recoveryError != nil { - if isErr, _ := IsOutOfGasError(recoveryError); isErr { - // We panic with the same error, to replicate the normal tx execution flow. - panic(recoveryError) - } else { - PrintPanicRecoveryError(ctx, recoveryError) - err = errors.New("panic occurred during execution") - } - } - }() - // makes a new cache context, which all state changes get wrapped inside of. - cacheCtx, write := ctx.CacheContext() - err = f(cacheCtx) - if err != nil { - ctx.Logger().Error(err.Error()) - } else { - // no error, write the output of f - write() - ctx.EventManager().EmitEvents(cacheCtx.EventManager().Events()) - } - return err -} - -// Frustratingly, this has to return the error descriptor, not an actual error itself -// because the SDK errors here are not actually errors. (They don't implement error interface) -func IsOutOfGasError(err any) (bool, string) { - switch e := err.(type) { - case types.ErrorOutOfGas: - return true, e.Descriptor - case types.ErrorGasOverflow: - return true, e.Descriptor - default: - return false, "" - } -} - -// PrintPanicRecoveryError error logs the recoveryError, along with the stacktrace, if it can be parsed. -// If not emits them to stdout. -func PrintPanicRecoveryError(ctx sdk.Context, recoveryError interface{}) { - errStackTrace := string(debug.Stack()) - switch e := recoveryError.(type) { - case types.ErrorOutOfGas: - ctx.Logger().Debug("out of gas error inside panic recovery block: " + e.Descriptor) - return - case string: - ctx.Logger().Error("Recovering from (string) panic: " + e) - case runtime.Error: - ctx.Logger().Error("recovered (runtime.Error) panic: " + e.Error()) - case error: - ctx.Logger().Error("recovered (error) panic: " + e.Error()) - default: - ctx.Logger().Error("recovered (default) panic. Could not capture logs in ctx, see stdout") - fmt.Println("Recovering from panic ", recoveryError) - debug.PrintStack() - return - } - ctx.Logger().Error("stack trace: " + errStackTrace) -} diff --git a/osmoutils/cache_ctx_test.go b/osmoutils/cache_ctx_test.go deleted file mode 100644 index 93d70205b..000000000 --- a/osmoutils/cache_ctx_test.go +++ /dev/null @@ -1,59 +0,0 @@ -package osmoutils_test - -import ( - "github.com/cosmos/cosmos-sdk/store/types" - sdk "github.com/cosmos/cosmos-sdk/types" - - "github.com/CosmosContracts/juno/v15/osmoutils" -) - -var expectedOutOfGasError = types.ErrorOutOfGas{Descriptor: "my func"} - -func consumeGas(ctx sdk.Context, gas uint64, numTimes int) error { - for i := 0; i < numTimes; i++ { - ctx.GasMeter().ConsumeGas(gas, "my func") - } - return nil -} - -func (s *TestSuite) TestCacheCtxConsumeGas() { - // every test case adds 1k gas 10 times - testcases := map[string]struct { - gasLimit uint64 - gasUsedPreCtx uint64 - gasUsedPostCtx uint64 - expectPanic bool - }{ - "no gas limit hit": { - gasLimit: 15_000, - gasUsedPreCtx: 111, - gasUsedPostCtx: 111 + 10_000, - expectPanic: false, - }, - "gas limit hit": { - gasLimit: 10_000, - gasUsedPreCtx: 111, - gasUsedPostCtx: 111 + 10_000, - expectPanic: true, - }, - } - for name, tc := range testcases { - s.Run(name, func() { - ctx := s.ctx.WithGasMeter(sdk.NewGasMeter(tc.gasLimit)) - ctx.GasMeter().ConsumeGas(tc.gasUsedPreCtx, "pre ctx") - var err error - f := func() { - osmoutils.ApplyFuncIfNoError(ctx, func(c sdk.Context) error { - return consumeGas(c, 1000, 10) - }) - } - if tc.expectPanic { - s.PanicsWithValue(expectedOutOfGasError, f) - } else { - f() - s.Require().NoError(err) - } - s.Equal(tc.gasUsedPostCtx, ctx.GasMeter().GasConsumed()) - }) - } -} diff --git a/osmoutils/cli_helpers.go b/osmoutils/cli_helpers.go deleted file mode 100644 index 4368dea55..000000000 --- a/osmoutils/cli_helpers.go +++ /dev/null @@ -1,77 +0,0 @@ -package osmoutils - -import ( - "fmt" - "strconv" - "strings" - - "cosmossdk.io/math" - "github.com/cometbft/cometbft/crypto/ed25519" - "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/testutil/network" - sdk "github.com/cosmos/cosmos-sdk/types" -) - -func DefaultFeeString(cfg network.Config) string { - feeCoins := sdk.NewCoins(sdk.NewCoin(cfg.BondDenom, sdk.NewInt(10))) - return fmt.Sprintf("--%s=%s", flags.FlagFees, feeCoins.String()) -} - -const ( - base = 10 - bitlen = 64 -) - -func ParseUint64SliceFromString(s string, separator string) ([]uint64, error) { - var parsedInts []uint64 - for _, s := range strings.Split(s, separator) { - s = strings.TrimSpace(s) - - parsed, err := strconv.ParseUint(s, base, bitlen) - if err != nil { - return []uint64{}, err - } - parsedInts = append(parsedInts, parsed) - } - return parsedInts, nil -} - -func ParseSdkIntFromString(s string, separator string) ([]math.Int, error) { - var parsedInts []math.Int - for _, weightStr := range strings.Split(s, separator) { - weightStr = strings.TrimSpace(weightStr) - - parsed, err := strconv.ParseUint(weightStr, base, bitlen) - if err != nil { - return parsedInts, err - } - parsedInts = append(parsedInts, sdk.NewIntFromUint64(parsed)) - } - return parsedInts, nil -} - -func ParseSdkDecFromString(s string, separator string) ([]sdk.Dec, error) { - var parsedDec []sdk.Dec - for _, weightStr := range strings.Split(s, separator) { - weightStr = strings.TrimSpace(weightStr) - - parsed, err := sdk.NewDecFromStr(weightStr) - if err != nil { - return parsedDec, err - } - - parsedDec = append(parsedDec, parsed) - } - return parsedDec, nil -} - -// CreateRandomAccounts is a function return a list of randomly generated AccAddresses -func CreateRandomAccounts(numAccts int) []sdk.AccAddress { - testAddrs := make([]sdk.AccAddress, numAccts) - for i := 0; i < numAccts; i++ { - pk := ed25519.GenPrivKey().PubKey() - testAddrs[i] = sdk.AccAddress(pk.Address()) - } - - return testAddrs -} diff --git a/osmoutils/coin_helper.go b/osmoutils/coin_helper.go deleted file mode 100644 index 61f2fb195..000000000 --- a/osmoutils/coin_helper.go +++ /dev/null @@ -1,46 +0,0 @@ -package osmoutils - -import ( - "fmt" - - sdk "github.com/cosmos/cosmos-sdk/types" -) - -// TODO: Get this into the SDK https://github.com/cosmos/cosmos-sdk/issues/12538 -func CoinsDenoms(coins sdk.Coins) []string { - denoms := make([]string, len(coins)) - for i, coin := range coins { - denoms[i] = coin.Denom - } - return denoms -} - -// MinCoins returns the minimum of each denom between both coins. -// For now it assumes they have the same denoms. -// TODO: Replace with method in SDK once we update our version -func MinCoins(coinsA sdk.Coins, coinsB sdk.Coins) sdk.Coins { - resCoins := sdk.Coins{} - for i, coin := range coinsA { - if coinsB[i].Amount.GT(coin.Amount) { - resCoins = append(resCoins, coin) - } else { - resCoins = append(resCoins, coinsB[i]) - } - } - return resCoins -} - -// SubDecCoinArrays subtracts the contents of the second param from the first (decCoinsArrayA - decCoinsArrayB) -// Note that this takes in two _arrays_ of DecCoins, meaning that each term itself is of type DecCoins (i.e. an array of DecCoin). -func SubDecCoinArrays(decCoinsArrayA []sdk.DecCoins, decCoinsArrayB []sdk.DecCoins) ([]sdk.DecCoins, error) { - if len(decCoinsArrayA) != len(decCoinsArrayB) { - return []sdk.DecCoins{}, fmt.Errorf("DecCoin arrays must be of equal length to be subtracted") - } - - finalDecCoinArray := []sdk.DecCoins{} - for i := range decCoinsArrayA { - finalDecCoinArray = append(finalDecCoinArray, decCoinsArrayA[i].Sub(decCoinsArrayB[i])) - } - - return finalDecCoinArray, nil -} diff --git a/osmoutils/coin_helper_test.go b/osmoutils/coin_helper_test.go deleted file mode 100644 index 1d7ecf4c8..000000000 --- a/osmoutils/coin_helper_test.go +++ /dev/null @@ -1,83 +0,0 @@ -package osmoutils_test - -import ( - "testing" - - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/stretchr/testify/require" - - "github.com/CosmosContracts/juno/v15/osmoutils" -) - -func TestSubDecCoins(t *testing.T) { - var ( - emptyCoins = sdk.DecCoins(nil) - fiftyFooCoins = sdk.NewDecCoin("foo", sdk.NewInt(50)) - fiftyBarCoins = sdk.NewDecCoin("bar", sdk.NewInt(50)) - hundredFooCoins = sdk.NewDecCoin("foo", sdk.NewInt(100)) - hundredBarCoins = sdk.NewDecCoin("bar", sdk.NewInt(100)) - - fiftyEach = sdk.NewDecCoins(fiftyFooCoins, fiftyBarCoins) - hundredEach = sdk.NewDecCoins(hundredFooCoins, hundredBarCoins) - ) - - tests := map[string]struct { - firstInput []sdk.DecCoins - secondInput []sdk.DecCoins - - expectedOutput []sdk.DecCoins - expectError bool - }{ - "[[100foo, 100bar], [100foo, 100bar]] - [[50foo, 50bar], [50foo, 100bar]]": { - firstInput: []sdk.DecCoins{hundredEach, hundredEach}, - secondInput: []sdk.DecCoins{fiftyEach, hundredEach}, - - expectedOutput: []sdk.DecCoins{fiftyEach, emptyCoins}, - }, - "[[100bar, 100foo], [100foo, 100bar]] - [[50foo, 50bar], [50foo, 100bar]]": { - firstInput: []sdk.DecCoins{ - sdk.NewDecCoins(hundredBarCoins, hundredFooCoins), - hundredEach, - }, - secondInput: []sdk.DecCoins{fiftyEach, hundredEach}, - - expectedOutput: []sdk.DecCoins{fiftyEach, emptyCoins}, - }, - "both inputs empty": { - firstInput: []sdk.DecCoins{}, - secondInput: []sdk.DecCoins{}, - - expectedOutput: []sdk.DecCoins{}, - }, - "[[100foo]] - [[50foo]]": { - firstInput: []sdk.DecCoins{sdk.NewDecCoins(hundredFooCoins)}, - secondInput: []sdk.DecCoins{sdk.NewDecCoins(fiftyFooCoins)}, - - expectedOutput: []sdk.DecCoins{sdk.NewDecCoins(fiftyFooCoins)}, - }, - - // error catching - - "different length inputs": { - firstInput: []sdk.DecCoins{hundredEach, hundredEach, hundredEach}, - secondInput: []sdk.DecCoins{fiftyEach, hundredEach}, - - expectedOutput: []sdk.DecCoins{}, - expectError: true, - }, - } - for name, tc := range tests { - t.Run(name, func(t *testing.T) { - actualOutput, err := osmoutils.SubDecCoinArrays(tc.firstInput, tc.secondInput) - - if tc.expectError { - require.Error(t, err) - require.Equal(t, tc.expectedOutput, actualOutput) - return - } - - require.NoError(t, err) - require.Equal(t, tc.expectedOutput, actualOutput) - }) - } -} diff --git a/osmoutils/conv_helper.go b/osmoutils/conv_helper.go deleted file mode 100644 index bd675e481..000000000 --- a/osmoutils/conv_helper.go +++ /dev/null @@ -1,16 +0,0 @@ -package osmoutils - -import ( - "encoding/binary" - "strconv" -) - -func Uint64ToBytes(i uint64) []byte { - key := make([]byte, 8) - binary.LittleEndian.PutUint64(key, i) - return key -} - -func Uint64ToString(i uint64) string { - return strconv.FormatUint(i, 10) -} diff --git a/osmoutils/cosmwasm/helpers.go b/osmoutils/cosmwasm/helpers.go deleted file mode 100644 index 4ee9464bc..000000000 --- a/osmoutils/cosmwasm/helpers.go +++ /dev/null @@ -1,223 +0,0 @@ -package cosmwasm - -import ( - "encoding/json" - - sdk "github.com/cosmos/cosmos-sdk/types" -) - -// ContracKeeper defines the interface needed to be fulfilled for -// the ContractKeeper. -type ContractKeeper interface { - Instantiate( - ctx sdk.Context, - codeID uint64, - creator, admin sdk.AccAddress, - initMsg []byte, - label string, - deposit sdk.Coins, - ) (sdk.AccAddress, []byte, error) - - Sudo(ctx sdk.Context, contractAddress sdk.AccAddress, msg []byte) ([]byte, error) - - Execute(ctx sdk.Context, contractAddress sdk.AccAddress, caller sdk.AccAddress, msg []byte, coins sdk.Coins) ([]byte, error) -} - -// WasmKeeper defines the interface needed to be fulfilled for -// the WasmKeeper. -type WasmKeeper interface { - QuerySmart(ctx sdk.Context, contractAddress sdk.AccAddress, queryMsg []byte) ([]byte, error) -} - -// Query is a generic function to query a CosmWasm smart contract with the given request. -// The function marshals the request into JSON, performs a smart query using the Wasm keeper, and then -// unmarshals the response into the provided response type. -// It returns the response of the specified type and an error if the JSON marshaling, smart query, -// or JSON unmarshaling process fails. -// -// The function uses generics, and T and K represent the request and response types, respectively. -// -// Parameters: -// - ctx: The SDK context. -// - wasmKeeper: The Wasm keeper to query the smart contract. -// - contractAddress: The Bech32 address of the smart contract. -// - request: The request of type T to be sent to the smart contract. -// -// Returns: -// - response: The response of type K from the smart contract. -// - err: An error if the JSON marshaling, smart query, or JSON unmarshaling process fails; otherwise, nil. -func Query[T any, K any](ctx sdk.Context, wasmKeeper WasmKeeper, contractAddress string, request T) (response K, err error) { - bz, err := json.Marshal(request) - if err != nil { - return response, err - } - - responseBz, err := wasmKeeper.QuerySmart(ctx, sdk.MustAccAddressFromBech32(contractAddress), bz) - if err != nil { - return response, err - } - - if err := json.Unmarshal(responseBz, &response); err != nil { - return response, err - } - - return response, nil -} - -// MustQuery is a generic function to query a CosmWasm smart contract with the given request. -// It is similar to the Query function but panics if an error occurs during the query. -// The function uses the Query function to perform the smart query and panics if an error is returned. -// -// The function uses generics, and T and K represent the request and response types, respectively. -// -// Parameters: -// - ctx: The SDK context. -// - wasmKeeper: The Wasm keeper to query the smart contract. -// - contractAddress: The Bech32 address of the smart contract. -// - request: The request of type T to be sent to the smart contract. -// -// Returns: -// - response: The response of type K from the smart contract. -// -// Panics: -// - If an error occurs during the JSON marshaling, smart query, or JSON unmarshaling process. -func MustQuery[T any, K any](ctx sdk.Context, wasmKeeper WasmKeeper, contractAddress string, request T) (response K) { - response, err := Query[T, K](ctx, wasmKeeper, contractAddress, request) - if err != nil { - panic(err) - } - - return response -} - -// Sudo is a generic function to execute a sudo message on a CosmWasm smart contract with the given request. -// The function marshals the request into JSON, performs a sudo call using the contract keeper, and then -// unmarshals the response into the provided response type. -// It returns the response of the specified type and an error if the JSON marshaling, sudo call, -// or JSON unmarshaling process fails. -// -// The function uses generics, and T and K represent the request and response types, respectively. -// -// Parameters: -// - ctx: The SDK context. -// - contractKeeper: The Contract keeper to execute the sudo call on the smart contract. -// - contractAddress: The Bech32 address of the smart contract. -// - request: The request of type T to be sent to the smart contract. -// -// Returns: -// - response: The response of type K from the smart contract. -// - err: An error if the JSON marshaling, sudo call, or JSON unmarshaling process fails; otherwise, nil. -func Sudo[T any, K any](ctx sdk.Context, contractKeeper ContractKeeper, contractAddress string, request T) (response K, err error) { - bz, err := json.Marshal(request) - if err != nil { - return response, err - } - - responseBz, err := contractKeeper.Sudo(ctx, sdk.MustAccAddressFromBech32(contractAddress), bz) - if err != nil { - return response, err - } - - // valid empty response - if len(responseBz) == 0 { - return response, nil - } - - if err := json.Unmarshal(responseBz, &response); err != nil { - return response, err - } - - return response, nil -} - -// MustSudo is a generic function to execute a sudo message on a CosmWasm smart contract with the given request. -// It is similar to the Sudo function but panics if an error occurs during the sudo call. -// The function uses the Sudo function to perform the sudo call and panics if an error is returned. -// -// The function uses generics, and T and K represent the request and response types, respectively. -// -// Parameters: -// - ctx: The SDK context. -// - contractKeeper: The Contract keeper to execute the sudo call on the smart contract. -// - contractAddress: The Bech32 address of the smart contract. -// - request: The request of type T to be sent to the smart contract. -// -// Returns: -// - response: The response of type K from the smart contract. -// -// Panics: -// - If an error occurs during the JSON marshaling, sudo call, or JSON unmarshaling process. -func MustSudo[T any, K any](ctx sdk.Context, contractKeeper ContractKeeper, contractAddress string, request T) (response K) { - response, err := Sudo[T, K](ctx, contractKeeper, contractAddress, request) - if err != nil { - panic(err) - } - - return response -} - -// Execute is a generic function to execute a contract call on a given contract address with a specified request. -// It accepts a context, contract keeper, contract address, caller address, coins, and request data. -// This function works with any data type for the request and response (T and K). -// It marshals the request data into JSON format, executes the contract call, and then unmarshals the response -// data back into the specified response type (K). In case of any error, it returns the zero value of the response -// type along with the error. -// -// Parameters: -// - ctx: The SDK context. -// - contractKeeper: An instance of the contract keeper to manage contract interactions. -// - contractAddress: The bech32 address of the contract to be executed. -// - caller: The address of the account making the call. -// - coins: The coins to be transferred during the call. -// - request: The request data, can be of any data type. -// -// Returns: -// - response: The response data, can be of any data type (K). Returns the zero value of K in case of an error. -// - err: An error object that indicates any error during the contract execution or data marshalling/unmarshalling process. -func Execute[T any, K any](ctx sdk.Context, contractKeeper ContractKeeper, contractAddress string, caller sdk.AccAddress, coins sdk.Coins, request T) (response K, err error) { - bz, err := json.Marshal(request) - if err != nil { - return response, err - } - - responseBz, err := contractKeeper.Execute(ctx, sdk.MustAccAddressFromBech32(contractAddress), caller, bz, coins) - if err != nil { - return response, err - } - - // valid empty response - if len(responseBz) == 0 { - return response, nil - } - - if err := json.Unmarshal(responseBz, &response); err != nil { - return response, err - } - - return response, nil -} - -// MustExecute is a wrapper around the Execute function, which provides a more concise API for -// executing a contract call on a given contract address with a specified request. -// It works with any data type for the request and response (T and K). -// This function panics if an error occurs during the contract execution or data marshalling/unmarshalling process. -// Use this function when you're confident that the contract execution will not encounter any errors. -// -// Parameters: -// - ctx: The SDK context. -// - contractKeeper: An instance of the contract keeper to manage contract interactions. -// - contractAddress: The bech32 address of the contract to be executed. -// - caller: The address of the account making the call. -// - coins: The coins to be transferred during the call. -// - request: The request data, can be of any data type. -// -// Returns: -// - response: The response data, can be of any data type (K). -func MustExecute[T any, K any](ctx sdk.Context, contractKeeper ContractKeeper, contractAddress string, caller sdk.AccAddress, coins sdk.Coins, request T) (response K) { - response, err := Execute[T, K](ctx, contractKeeper, contractAddress, caller, coins, request) - if err != nil { - panic(err) - } - - return response -} diff --git a/osmoutils/encoding_helper.go b/osmoutils/encoding_helper.go deleted file mode 100644 index 8d81fb823..000000000 --- a/osmoutils/encoding_helper.go +++ /dev/null @@ -1,25 +0,0 @@ -package osmoutils - -import ( - "fmt" - "time" - - sdk "github.com/cosmos/cosmos-sdk/types" -) - -func FormatFixedLengthU64(d uint64) string { - return fmt.Sprintf("%0.20d", d) -} - -func FormatTimeString(t time.Time) string { - return t.UTC().Round(0).Format(sdk.SortableTimeFormat) -} - -// Parses a string encoded using FormatTimeString back into a time.Time -func ParseTimeString(s string) (time.Time, error) { - t, err := time.Parse(sdk.SortableTimeFormat, s) - if err != nil { - return t, err - } - return t.UTC().Round(0), nil -} diff --git a/osmoutils/encoding_helper_test.go b/osmoutils/encoding_helper_test.go deleted file mode 100644 index 35690501b..000000000 --- a/osmoutils/encoding_helper_test.go +++ /dev/null @@ -1,29 +0,0 @@ -package osmoutils - -import ( - "math" - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestFormatFixedLengthU64(t *testing.T) { - tests := map[string]struct { - d uint64 - want string - }{ - "0": {0, "00000000000000000000"}, - "1": {1, "00000000000000000001"}, - "9": {9, "00000000000000000009"}, - "10": {10, "00000000000000000010"}, - "123": {123, "00000000000000000123"}, - "max u64": {math.MaxUint64, "18446744073709551615"}, - } - for name, tt := range tests { - t.Run(name, func(t *testing.T) { - got := FormatFixedLengthU64(tt.d) - assert.Equal(t, tt.want, got) - assert.Equal(t, len(got), 20) - }) - } -} diff --git a/osmoutils/export_test.go b/osmoutils/export_test.go deleted file mode 100644 index f6cfd341a..000000000 --- a/osmoutils/export_test.go +++ /dev/null @@ -1,11 +0,0 @@ -package osmoutils - -import db "github.com/cometbft/cometbft-db" - -func GatherValuesFromIterator[T any](iterator db.Iterator, parseValue func([]byte) (T, error), stopFn func([]byte) bool) ([]T, error) { - return gatherValuesFromIterator(iterator, parseValue, stopFn) -} - -func NoStopFn(key []byte) bool { - return noStopFn(key) -} diff --git a/osmoutils/generic_helper.go b/osmoutils/generic_helper.go deleted file mode 100644 index 0a008afcb..000000000 --- a/osmoutils/generic_helper.go +++ /dev/null @@ -1,17 +0,0 @@ -package osmoutils - -import "reflect" - -// MakeNew makes a new instance of generic T. -// if T is a pointer, makes a new instance of the underlying struct via reflection, -// and then a pointer to it. -func MakeNew[T any]() T { - var v T - if typ := reflect.TypeOf(v); typ.Kind() == reflect.Ptr { - elem := typ.Elem() - //nolint:forcetypeassert - return reflect.New(elem).Interface().(T) // must use reflect - } else { - return *new(T) // v is not ptr, alloc with new - } -} diff --git a/osmoutils/go.mod b/osmoutils/go.mod deleted file mode 100644 index 718b58aad..000000000 --- a/osmoutils/go.mod +++ /dev/null @@ -1,142 +0,0 @@ -module github.com/osmosis-labs/osmosis/osmoutils - -go 1.20 - -require ( - github.com/cosmos/cosmos-sdk v0.47.2 - github.com/cosmos/iavl v0.19.5 - github.com/cosmos/ibc-go/v4 v4.3.0 - github.com/gogo/protobuf v1.3.3 - github.com/spf13/cobra v1.7.0 - github.com/spf13/pflag v1.0.5 - github.com/stretchr/testify v1.8.2 - github.com/cometbft/cometbft v0.37.1 - github.com/cometbft/cometbft-db v0.8.0 - golang.org/x/exp v0.0.0-20230131160201-f062dba9d201 -) - -require ( - 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.1 // indirect - github.com/beorn7/perks v1.0.1 // indirect - github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816 // indirect - github.com/btcsuite/btcd v0.22.2 // indirect - github.com/cenkalti/backoff/v4 v4.1.3 // indirect - github.com/cespare/xxhash v1.1.0 // indirect - github.com/cespare/xxhash/v2 v2.2.0 // indirect - github.com/coinbase/rosetta-sdk-go v0.7.9 // indirect - github.com/confio/ics23/go v0.9.0 // indirect - github.com/cosmos/btcutil v1.0.5 // indirect - github.com/cosmos/go-bip39 v1.0.0 // indirect - github.com/cosmos/gorocksdb v1.2.0 // indirect - github.com/cosmos/ledger-cosmos-go v0.12.2 // indirect - github.com/creachadair/taskgroup v0.3.2 // indirect - github.com/danieljoos/wincred v1.1.2 // indirect - github.com/davecgh/go-spew v1.1.1 // indirect - github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect - github.com/dgraph-io/badger/v3 v3.2103.2 // indirect - github.com/dgraph-io/ristretto v0.1.0 // indirect - github.com/dustin/go-humanize v1.0.1-0.20200219035652-afde56e7acac // indirect - github.com/dvsekhvalnov/jose2go v1.5.0 // indirect - github.com/felixge/httpsnoop v1.0.2 // indirect - github.com/frankban/quicktest v1.14.4 // indirect - github.com/fsnotify/fsnotify v1.6.0 // indirect - github.com/gin-gonic/gin v1.8.1 // 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/go-playground/validator/v10 v10.11.1 // indirect - github.com/goccy/go-json v0.10.2 // 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/protobuf v1.5.3 // indirect - github.com/golang/snappy v0.0.4 // indirect - github.com/google/btree v1.1.2 // indirect - github.com/google/flatbuffers v1.12.1 // indirect - github.com/google/gofuzz v1.2.0 // indirect - github.com/google/orderedcode v0.0.1 // indirect - github.com/gorilla/handlers v1.5.1 // indirect - github.com/gorilla/mux v1.8.0 // indirect - github.com/gorilla/websocket v1.5.0 // indirect - github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect - github.com/grpc-ecosystem/grpc-gateway v1.16.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-immutable-radix v1.3.1 // indirect - github.com/hashicorp/go-uuid v1.0.2 // 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-20220222234857-c00d1f31bab3 // indirect - github.com/improbable-eng/grpc-web v0.15.0 // indirect - github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/jhump/protoreflect v1.13.1-0.20220928232736-101791cb1b4c // indirect - github.com/jmhodges/levigo v1.0.0 // indirect - github.com/klauspost/compress v1.15.11 // indirect - github.com/lib/pq v1.10.7 // indirect - github.com/libp2p/go-buffer-pool v0.1.0 // indirect - github.com/magiconair/properties v1.8.7 // indirect - github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.17 // indirect - github.com/matttproud/golang_protobuf_extensions v1.0.4 // 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 - github.com/onsi/ginkgo v1.16.4 // indirect - github.com/onsi/gomega v1.26.0 // indirect - github.com/pelletier/go-toml/v2 v2.0.6 // indirect - github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 // indirect - github.com/pkg/errors v0.9.1 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/prometheus/client_golang v1.15.0 // indirect - github.com/prometheus/client_model v0.3.0 // indirect - github.com/prometheus/common v0.42.0 // indirect - github.com/prometheus/procfs v0.9.0 // indirect - github.com/rakyll/statik v0.1.7 // indirect - github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect - github.com/regen-network/cosmos-proto v0.3.1 // indirect - github.com/rogpeppe/go-internal v1.10.0 // indirect - 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.3 // indirect - github.com/spf13/cast v1.5.0 // indirect - github.com/spf13/jwalterweatherman v1.1.0 // indirect - github.com/spf13/viper v1.15.0 // indirect - github.com/subosito/gotenv v1.4.2 // indirect - github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // 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.1 // indirect - github.com/zondax/ledger-go v0.14.1 // indirect - go.etcd.io/bbolt v1.3.6 // indirect - go.opencensus.io v0.24.0 // indirect - golang.org/x/crypto v0.5.0 // indirect - golang.org/x/net v0.9.0 // indirect - golang.org/x/sys v0.7.0 // indirect - golang.org/x/term v0.7.0 // indirect - golang.org/x/text v0.9.0 // indirect - golang.org/x/tools v0.8.0 // indirect - google.golang.org/genproto v0.0.0-20230125152338-dcaf20b6aeaa // indirect - google.golang.org/grpc v1.53.0 // indirect - google.golang.org/protobuf v1.30.0 // indirect - gopkg.in/ini.v1 v1.67.0 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect - nhooyr.io/websocket v1.8.7 // indirect -) - -replace ( - // use cosmos-compatible protobufs - github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 - // use grpc compatible with cosmos protobufs - google.golang.org/grpc => google.golang.org/grpc v1.33.2 -) diff --git a/osmoutils/go.sum b/osmoutils/go.sum deleted file mode 100644 index 90d4d78d2..000000000 --- a/osmoutils/go.sum +++ /dev/null @@ -1,1352 +0,0 @@ -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= -cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= -cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= -cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= -cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= -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/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/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/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= -cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= -cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= -cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= -cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= -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= -collectd.org v0.3.0/go.mod h1:A/8DzQBkF6abtvrT2j/AU/4tiBgJWYyh0y/oB/4MlWE= -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= -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/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= -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/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/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= -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= -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/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= -github.com/Workiva/go-datastructures v1.0.53/go.mod h1:1yZL+zfsztete+ePzZz/Zb1/t5BnDuE2Ya2MMGhzP6A= -github.com/Zilliqa/gozilliqa-sdk v1.2.1-0.20201201074141-dd0ecada1be6/go.mod h1:eSYp2T6f0apnuW8TzhV3f6Aff2SE8Dwio++U4ha4yEM= -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/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= -github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA= -github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4= -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.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -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/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816 h1:41iFGWnSlI2gVpmOtVTJZNodLdLQLn/KsJqFvXwnd/s= -github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816/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-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.22.1/go.mod h1:wqgTSL29+50LRkmOVknEdmt8ZojIzhuWvgu/iptuN7Y= -github.com/btcsuite/btcd v0.22.2 h1:vBZ+lGGd1XubpOWO67ITJpAEsICWhA0YzqkcpkgNBfo= -github.com/btcsuite/btcd v0.22.2/go.mod h1:wqgTSL29+50LRkmOVknEdmt8ZojIzhuWvgu/iptuN7Y= -github.com/btcsuite/btcd/btcec/v2 v2.1.2/go.mod h1:ctjw4H1kknNJmRN4iP1R7bTQ+v3GJkZBd6mui8ZsAZE= -github.com/btcsuite/btcd/btcec/v2 v2.3.2 h1:5n0X6hX0Zk+6omWcihdYvdAlGf2DfasC0GMf7DClJ3U= -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-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= -github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= -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= -github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= -github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= -github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -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/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -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/confio/ics23/go v0.9.0 h1:cWs+wdbS2KRPZezoaaj+qBleXgUk5WOQFMP3CQFGTr4= -github.com/confio/ics23/go v0.9.0/go.mod h1:4LPZ2NYqnYIVRklaozjNR1FScgDJ2s5Xrp+e/mYVRak= -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= -github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= -github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= -github.com/cosmos/btcutil v1.0.5 h1:t+ZFcX77LpKtDBhjucvnOH8C2l2ioGsBNEQ3jef8xFk= -github.com/cosmos/btcutil v1.0.5/go.mod h1:IyB7iuqZMJlthe2tkIFL33xPyzbFYP0XVdS8P5lUPis= -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/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.5 h1:rGA3hOrgNxgRM5wYcSCxgQBap7fW82WZgY78V9po/iY= -github.com/cosmos/iavl v0.19.5/go.mod h1:X9PKD3J0iFxdmgNLa7b2LYWdsGd90ToV5cAONApkEPw= -github.com/cosmos/ibc-go/v4 v4.3.0 h1:yOzVsyZzsv4XPBux8gq+D0LhZn45yGWKjvT+6Vyo5no= -github.com/cosmos/ibc-go/v4 v4.3.0/go.mod h1:CcLvIoi9NNtIbNsxs4KjBGjYhlwqtsmXy1AKARKiMzQ= -github.com/cosmos/ledger-cosmos-go v0.12.2 h1:/XYaBlE2BJxtvpkHiBm97gFGSGmYGKunKyF3nNqAXZA= -github.com/cosmos/ledger-cosmos-go v0.12.2/go.mod h1:ZcqYgnfNJ6lAXe4HPtWgarNEY+B74i+2/8MhZw4ziiI= -github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= -github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -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 h1:YLtO71vCjJRCBcrPMtQ9nqBsqpA1m5sE92cU+pd5Mcc= -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.4/go.mod h1:vSw/ax2qojzbN6eXHIx6KPKtCSHJN/Uz0X0VPruTIhk= -github.com/dgraph-io/badger/v3 v3.2103.2 h1:dpyM5eCJAtQCBcMCZcT4UBZchuTJgCywerHHgmxfxM8= -github.com/dgraph-io/badger/v3 v3.2103.2/go.mod h1:RHo4/GmYcKKh5Lxu63wLEMHJ70Pac2JqZRYGhlyAo2M= -github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= -github.com/dgraph-io/ristretto v0.0.3/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= -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/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= -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/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/dustin/go-humanize v1.0.1-0.20200219035652-afde56e7acac h1:opbrjaN/L8gg6Xh5D04Tem+8xVcz6ajZlGCs49mQgyg= -github.com/dustin/go-humanize v1.0.1-0.20200219035652-afde56e7acac/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/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 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/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.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= -github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/felixge/httpsnoop v1.0.2 h1:+nS9g82KMXccJ/wp0zyRW9ZBHFETmMGtkk+2CTTrW4o= -github.com/felixge/httpsnoop v1.0.2/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/fjl/memsize v0.0.0-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.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= -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/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.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= -github.com/gin-gonic/gin v1.8.1 h1:4+fr/el88TOO3ewCmQr8cx/CtZ/umlIRIs5M4NTNjf8= -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= -github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= -github.com/go-kit/kit v0.12.0 h1:e4o3o3IsBfAKQh5Qbbiqyfu97Ku7jrO/JbohvztANh4= -github.com/go-kit/kit v0.12.0/go.mod h1:lHd+EkCZPIwYItmGDDRdhinkzX2A1sj+M9biaEaizzs= -github.com/go-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU= -github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= -github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= -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/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= -github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU= -github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= -github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho= -github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= -github.com/go-playground/validator/v10 v10.11.1 h1:prmOlTVv+YjZjmRmNSF3VmspqJIxJWXmqUsHwfTRRkQ= -github.com/go-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/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= -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= -github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8= -github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= -github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo= -github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= -github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= -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= -github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -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.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= -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= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= -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.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= -github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.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/flatbuffers v1.12.1 h1:MVlul7pQNoDzWRLTw5imwYsl+usrS1TXG2H4jg6ImGw= -github.com/google/flatbuffers v1.12.1/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= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -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.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= -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/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/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= -github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -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/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/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/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= -github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4= -github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q= -github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -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/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/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= -github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= -github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= -github.com/grpc-ecosystem/grpc-gateway v1.8.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= -github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c h1:6rhixN/i8ZofjG1Y75iExal34USq5p+wiN1tpie8IrU= -github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c/go.mod h1:NMPJylDgVpX0MLRlPy15sqSwOFv/U1GZ2m21JhFfek0= -github.com/gtank/merlin v0.1.1-0.20191105220539-8318aed1a79f/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/bIQ+s= -github.com/gtank/merlin v0.1.1 h1:eQ90iG7K9pOhtereWsmyRJ6RAwcP4tHTDBHXNg+u5is= -github.com/gtank/merlin v0.1.1/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/bIQ+s= -github.com/gtank/ristretto255 v0.1.2 h1:JEqUCPA1NvLq5DwYtuzigd7ss8fwbYay9fi4/5uMzcc= -github.com/gtank/ristretto255 v0.1.2/go.mod h1:Ph5OpO6c7xKUGROZfWVLiJf9icMDwUeIvY4OmlYW69o= -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-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= -github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= -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-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/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE= -github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-version v1.2.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/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/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/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/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= -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/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/informalsystems/tendermint v0.34.24 h1:2beNEg5tp+U5oj/Md+0xDBsMHGbdue31T3OrstS6xS0= -github.com/informalsystems/tendermint v0.34.24/go.mod h1:rXVrl4OYzmIa1I91av3iLv2HS0fGSiucyW9J4aMTpKI= -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/gopoet v0.0.0-20190322174617-17282ff210b3/go.mod h1:me9yfT6IJSlOL3FCfrg+L6yzUEZ+5jW6WHt4Sk+UPUI= -github.com/jhump/gopoet v0.1.0/go.mod h1:me9yfT6IJSlOL3FCfrg+L6yzUEZ+5jW6WHt4Sk+UPUI= -github.com/jhump/goprotoc v0.5.0/go.mod h1:VrbvcYrQOrTi3i0Vf+m+oqQWk9l72mjkJCYo7UvLHRQ= -github.com/jhump/protoreflect v1.11.0/go.mod h1:U7aMIjN0NWq9swDP7xDdoMfRHb35uiuTd3Z9nFXJf5E= -github.com/jhump/protoreflect v1.13.1-0.20220928232736-101791cb1b4c h1:XImQJfpJLmGEEd8ll5yPVyL/aEvmgGHW4WYTyNseLOM= -github.com/jhump/protoreflect v1.13.1-0.20220928232736-101791cb1b4c/go.mod h1:JytZfP5d0r8pVNLZvai7U/MCuTWITgrI4tTg7puQFKI= -github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= -github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= -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= -github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= -github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= -github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= -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.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/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.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.11 h1:Lcadnb3RKGin4FYM/orgq0qde+nc15E5Cbqg4B9Sx9c= -github.com/klauspost/compress v1.15.11/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= -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.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -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/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= -github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= -github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw= -github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= -github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= -github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= -github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= -github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= -github.com/lucasjones/reggen v0.0.0-20180717132126-cdb49ff09d77/go.mod h1:5ELEyG+X8f+meRWHuqUOewBOhvHkl7M76pdGEansxW4= -github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= -github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= -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.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-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.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/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= -github.com/mattn/go-isatty v0.0.17/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.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.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= -github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -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= -github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -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.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= -github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= -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= -github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU= -github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/mwitkow/grpc-proxy v0.0.0-20181017164139-0f1106ef9c76/go.mod h1:x5OoJHDHqxHS801UIuhqGl6QdSAEJvtausosHSdazIo= -github.com/naoina/go-stringutil v0.1.0/go.mod h1:XJ2SJL9jCtBh+P9q5btrd/Ylo8XwT/h1USek5+NqSA0= -github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416/go.mod h1:NBIhNtsFMo3G2szEBne+bO4gS192HuIYRqfvOWb4i1E= -github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= -github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= -github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k= -github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= -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/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= -github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= -github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= -github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= -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/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= -github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= -github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= -github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= -github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= -github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= -github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.26.0 h1:03cDLK28U6hWvCAns6NeydX3zIm4SF3ci69ulidS32Q= -github.com/onsi/gomega v1.26.0/go.mod h1:r+zV744Re+DiYCIPRlYOTxn0YkOLcAnW8k1xXdMPGhM= -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.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= -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/osmosis-labs/cosmos-sdk v0.45.1-0.20230326212251-7a2cf2993434 h1:RetElHdhDl6f00Tjj7ii2r+HX2aa/u+dhgwQb5hKv8Y= -github.com/osmosis-labs/cosmos-sdk v0.45.1-0.20230326212251-7a2cf2993434/go.mod h1:ss3tUfPTwaa6NsoPZrCR7xOqLqCK0LwoNbc2Q8Zs5/Y= -github.com/otiai10/copy v1.7.0 h1:hVoPiN+t+7d2nzzwMiDHPSOogsWAStewq3TwU05+clE= -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 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/v2 v2.0.6 h1:nrzqCb7j9cDFj2coyLNLaZuJTLjWjlaz6nvTvIwycIU= -github.com/pelletier/go-toml/v2 v2.0.6/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek= -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= -github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -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= -github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= -github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= -github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= -github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.15.0 h1:5fCgGYogn0hFdhyhLbw7hEsWxufKtY9klyvdNfFlFhM= -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/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= -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= -github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= -github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM= -github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= -github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.3.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI= -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= -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= -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.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= -github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= -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/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= -github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= -github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -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.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/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= -github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= -github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= -github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= -github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= -github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -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.3 h1:41FoI0fD7OR7mGcKE/aOiLkGreyf8ifIOQmJANWogMk= -github.com/spf13/afero v1.9.3/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= -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.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= -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= -github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -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.15.0 h1:js3yy885G8xwJa6iOISGFwd+qlUo5AvyXb7CiihdtiU= -github.com/spf13/viper v1.15.0/go.mod h1:fFcTBJxvhhzSJiZy8n+PeW6t8l+KeT/uTARa0jHOQLA= -github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4/go.mod h1:RZLeN1LMWmRsyYjvAu+I6Dm9QmlDaIIt+Y+4Kd7Tp+Q= -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/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= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -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/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= -github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= -github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= -github.com/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/tm-db v0.6.8-0.20220506192307-f628bb5dc95b h1:Y3ZPG6gdDCAV2sdGkD759ji/09GzaNu1X3qKTmZIbTo= -github.com/tendermint/tm-db v0.6.8-0.20220506192307-f628bb5dc95b/go.mod h1:ADqbS9NOSnBRK9R2RtYC61CdsHmVMD/yXAzcMuPexbU= -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= -github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs= -github.com/tyler-smith/go-bip39 v1.0.2/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs= -github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= -github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= -github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= -github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= -github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= -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/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.1 h1:gQe66rtmyZ8VeGFcOpbuH3r7erYtNEAezCAYu8LdkJo= -github.com/zondax/hid v0.9.1/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= -github.com/zondax/ledger-go v0.14.1 h1:Pip65OOl4iJ84WTpA4BKChvOufMhhbxED3BaihoZN4c= -github.com/zondax/ledger-go v0.14.1/go.mod h1:fZ3Dqg6qcdXWSOJFKMG8GCTnD7slO/RL2feOQv8K320= -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= -go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= -go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= -go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= -go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= -go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= -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.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= -go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -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= -golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190909091759-094676da4a83/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -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.5.0 h1:U/0M97KRkSFvyD/3FSmdP5W5swImpNgle/EHFhOsQPE= -golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU= -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-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= -golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= -golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= -golang.org/x/exp v0.0.0-20230131160201-f062dba9d201 h1:BEABXpNXLEz0WxtA+6CQIz2xkg80e+1zrhWyMcq8VzE= -golang.org/x/exp v0.0.0-20230131160201-f062dba9d201/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= -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= -golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= -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/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/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.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk= -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-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= -golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200421231249-e086a090c8fd/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -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-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-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/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.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM= -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= -golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -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/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= -golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -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/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= -golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -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= -golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -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= -golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -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= -golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -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-20200905004654-be1d3432aa8f/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= -golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210112080510-489259a85091/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-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210316164454-77fc1eacc6aa/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-20210615035016-665e8c7367d1/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-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-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-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU= -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.7.0 h1:BEvjmm5fURWqcfbSKTdpkDXYBrUS1c0m8agp14W48vQ= -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= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -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/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= -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= -golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200108203644-89082a384178/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-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= -golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= -golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= -golang.org/x/tools v0.0.0-20201022035929-9cf592e881e9/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -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.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.8.0 h1:vSDcovVPld282ceKgDimkRSC8kpaH1dgyc9UMzlt84Y= -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= -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= -google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= -google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= -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/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/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= -google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -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= -google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -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= -google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200324203455-a04cca1dde73/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= -google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= -google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -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-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20230125152338-dcaf20b6aeaa h1:qQPhfbPO23fwm/9lQr91L1u62Zo6cm+zI+slZT+uf+o= -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= -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= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= -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.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= -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/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/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= -gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= -gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c= -gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200619000410-60c24ae608a6/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns= -gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/urfave/cli.v1 v1.20.0/go.mod h1:vuBzUtMdQeixQj8LVd+/98pzhxNGQoyuPBlsXHOQNO0= -gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= -gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -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/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= -nhooyr.io/websocket v1.8.7 h1:usjR2uOr/zjjkVMy0lW+PPohFok7PCow5sDjLgX4P4g= -nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= -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= -sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= diff --git a/osmoutils/module_account.go b/osmoutils/module_account.go deleted file mode 100644 index 661047e94..000000000 --- a/osmoutils/module_account.go +++ /dev/null @@ -1,86 +0,0 @@ -package osmoutils - -import ( - "errors" - "fmt" - "reflect" - - sdk "github.com/cosmos/cosmos-sdk/types" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" - vestingtypes "github.com/cosmos/cosmos-sdk/x/auth/vesting/types" -) - -// OsmoUtilsExtraAccountTypes is a map of extra account types that can be overridden. -// This is defined as a global variable so it can be modified in the chain's app.go and used here without -// having to import the chain. Specifically, this is used for compatibility with Osmosis' Cosmos SDK fork -var OsmoUtilsExtraAccountTypes map[reflect.Type]struct{} - -type AccountKeeper interface { - NewAccount(sdk.Context, authtypes.AccountI) authtypes.AccountI - - GetAccount(ctx sdk.Context, addr sdk.AccAddress) authtypes.AccountI - SetAccount(ctx sdk.Context, acc authtypes.AccountI) -} - -// CanCreateModuleAccountAtAddr tells us if we can safely make a module account at -// a given address. By collision resistance of the address (given API safe construction), -// the only way for an account to be already be at this address is if its claimed by the same -// pre-image from the correct module, -// or some SDK command breaks assumptions and creates an account at designated address. -// This function checks if there is an account at that address, and runs some safety checks -// to be extra-sure its not a user account (e.g. non-zero sequence, pubkey, of fore-seen account types). -// If there is no account, or if we believe its not a user-spendable account, we allow module account -// creation at the address. -// else, we do not. -// -// TODO: This is generally from an SDK design flaw -// code based off wasmd code: https://github.com/CosmWasm/wasmd/pull/996 -// Its _mandatory_ that the caller do the API safe construction to generate a module account addr, -// namely, address.Module(ModuleName, {key}) -func CanCreateModuleAccountAtAddr(ctx sdk.Context, ak AccountKeeper, addr sdk.AccAddress) error { - existingAcct := ak.GetAccount(ctx, addr) - if existingAcct == nil { - return nil - } - if existingAcct.GetSequence() != 0 || existingAcct.GetPubKey() != nil { - return fmt.Errorf("cannot create module account %s, "+ - "due to an account at that address already existing & having sent txs", addr) - } - overrideAccountTypes := map[reflect.Type]struct{}{ - reflect.TypeOf(&authtypes.BaseAccount{}): {}, - reflect.TypeOf(&vestingtypes.DelayedVestingAccount{}): {}, - reflect.TypeOf(&vestingtypes.ContinuousVestingAccount{}): {}, - reflect.TypeOf(&vestingtypes.BaseVestingAccount{}): {}, - reflect.TypeOf(&vestingtypes.PeriodicVestingAccount{}): {}, - reflect.TypeOf(&vestingtypes.PermanentLockedAccount{}): {}, - } - for extraAccountType := range OsmoUtilsExtraAccountTypes { - overrideAccountTypes[extraAccountType] = struct{}{} - } - - if _, clear := overrideAccountTypes[reflect.TypeOf(existingAcct)]; clear { - return nil - } - return errors.New("cannot create module account %s, " + - "due to an account at that address already existing & not being an overrideable type") -} - -// CreateModuleAccount creates a module account at the provided address. -// It overrides an account if it exists at that address, with a non-zero sequence number & pubkey -// Contract: addr is derived from `address.Module(ModuleName, key)` -func CreateModuleAccount(ctx sdk.Context, ak AccountKeeper, addr sdk.AccAddress) error { - err := CanCreateModuleAccountAtAddr(ctx, ak, addr) - if err != nil { - return err - } - - acc := ak.NewAccount( - ctx, - authtypes.NewModuleAccount( - authtypes.NewBaseAccountWithAddress(addr), - addr.String(), - ), - ) - ak.SetAccount(ctx, acc) - return nil -} diff --git a/osmoutils/module_account_test.go b/osmoutils/module_account_test.go deleted file mode 100644 index 1119812ef..000000000 --- a/osmoutils/module_account_test.go +++ /dev/null @@ -1,66 +0,0 @@ -package osmoutils_test - -import ( - "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/address" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" - - "github.com/CosmosContracts/juno/v15/osmoutils" - "github.com/CosmosContracts/juno/v15/osmoutils/osmoassert" -) - -func (s *TestSuite) TestCreateModuleAccount() { - baseWithAddr := func(addr sdk.AccAddress) authtypes.AccountI { - acc := authtypes.ProtoBaseAccount() - acc.SetAddress(addr) - return acc - } - userAccViaSeqnum := func(addr sdk.AccAddress) authtypes.AccountI { - base := baseWithAddr(addr) - base.SetSequence(2) - return base - } - userAccViaPubkey := func(addr sdk.AccAddress) authtypes.AccountI { - base := baseWithAddr(addr) - base.SetPubKey(secp256k1.GenPrivKey().PubKey()) - return base - } - defaultModuleAccAddr := address.Module("dummy module", []byte{1}) - testcases := map[string]struct { - priorAccounts []authtypes.AccountI - moduleAccAddr sdk.AccAddress - expErr bool - }{ - "no prior acc": { - priorAccounts: []authtypes.AccountI{}, - moduleAccAddr: defaultModuleAccAddr, - expErr: false, - }, - "prior empty acc at addr": { - priorAccounts: []authtypes.AccountI{baseWithAddr(defaultModuleAccAddr)}, - moduleAccAddr: defaultModuleAccAddr, - expErr: false, - }, - "prior user acc at addr (sequence)": { - priorAccounts: []authtypes.AccountI{userAccViaSeqnum(defaultModuleAccAddr)}, - moduleAccAddr: defaultModuleAccAddr, - expErr: true, - }, - "prior user acc at addr (pubkey)": { - priorAccounts: []authtypes.AccountI{userAccViaPubkey(defaultModuleAccAddr)}, - moduleAccAddr: defaultModuleAccAddr, - expErr: true, - }, - } - for name, tc := range testcases { - s.Run(name, func() { - s.SetupTest() - for _, priorAcc := range tc.priorAccounts { - s.accountKeeper.SetAccount(s.ctx, priorAcc) - } - err := osmoutils.CreateModuleAccount(s.ctx, s.accountKeeper, tc.moduleAccAddr) - osmoassert.ConditionalError(s.T(), tc.expErr, err) - }) - } -} diff --git a/osmoutils/noapptest/cdc.go b/osmoutils/noapptest/cdc.go deleted file mode 100644 index 8f9a25905..000000000 --- a/osmoutils/noapptest/cdc.go +++ /dev/null @@ -1,45 +0,0 @@ -package noapptest - -// NOTE: This file is pulled from the SDK: -// https://github.com/cosmos/cosmos-sdk/blob/2eb51447494163bc9beef1b2cc8aa91c3691b2a7/types/module/testutil/codec.go#L23 -import ( - "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/codec" - "github.com/cosmos/cosmos-sdk/codec/types" - "github.com/cosmos/cosmos-sdk/std" - "github.com/cosmos/cosmos-sdk/types/module" - "github.com/cosmos/cosmos-sdk/x/auth/tx" -) - -// TestEncodingConfig defines an encoding configuration that is used for testing -// purposes. Note, MakeTestEncodingConfig takes a series of AppModuleBasic types -// which should only contain the relevant module being tested and any potential -// dependencies. -type TestEncodingConfig struct { - InterfaceRegistry types.InterfaceRegistry - Codec codec.Codec - TxConfig client.TxConfig - Amino *codec.LegacyAmino -} - -func MakeTestEncodingConfig(modules ...module.AppModuleBasic) TestEncodingConfig { - cdc := codec.NewLegacyAmino() - interfaceRegistry := types.NewInterfaceRegistry() - codec := codec.NewProtoCodec(interfaceRegistry) - - encCfg := TestEncodingConfig{ - InterfaceRegistry: interfaceRegistry, - Codec: codec, - TxConfig: tx.NewTxConfig(codec, tx.DefaultSignModes), - Amino: cdc, - } - - mb := module.NewBasicManager(modules...) - - std.RegisterLegacyAminoCodec(encCfg.Amino) - std.RegisterInterfaces(encCfg.InterfaceRegistry) - mb.RegisterLegacyAminoCodec(encCfg.Amino) - mb.RegisterInterfaces(encCfg.InterfaceRegistry) - - return encCfg -} diff --git a/osmoutils/noapptest/ctx.go b/osmoutils/noapptest/ctx.go deleted file mode 100644 index e3c649300..000000000 --- a/osmoutils/noapptest/ctx.go +++ /dev/null @@ -1,33 +0,0 @@ -package noapptest - -import ( - "time" - - "github.com/cometbft/cometbft/libs/log" - tmproto "github.com/cometbft/cometbft/proto/tendermint/types" - "github.com/cosmos/cosmos-sdk/store" - sdk "github.com/cosmos/cosmos-sdk/types" - - dbm "github.com/cometbft/cometbft-db" - storetypes "github.com/cosmos/cosmos-sdk/store/types" -) - -func CtxWithStoreKeys(keys []sdk.Store, header tmproto.Header, isCheckTx bool) sdk.Context { - db, _ := dbm.NewDB("test", dbm.GoLevelDBBackend, "") - logger := log.NewNopLogger() - cms := store.NewCommitMultiStore(db) - for _, key := range keys { - cms.MountStoreWithDB(key, sdk.StoreTypeIAVL, nil) - } - err := cms.LoadLatestVersion() - if err != nil { - panic(err) - } - return sdk.NewContext(cms, header, isCheckTx, logger) -} - -func DefaultCtxWithStoreKeys(storeKeys []storetypes.StoreKey) sdk.Context { - header := tmproto.Header{Height: 1, ChainID: "osmoutils-test-1", Time: time.Now().UTC()} - deliverTx := false - return CtxWithStoreKeys(storeKeys, header, deliverTx) -} diff --git a/osmoutils/osmoassert/assertions.go b/osmoutils/osmoassert/assertions.go deleted file mode 100644 index aad23e991..000000000 --- a/osmoutils/osmoassert/assertions.go +++ /dev/null @@ -1,60 +0,0 @@ -package osmoassert - -import ( - "fmt" - "testing" - - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/stretchr/testify/require" -) - -// ConditionalPanic checks if expectPanic is true, asserts that sut (system under test) -// panics. If expectPanic is false, asserts that sut does not panic. -// returns true if sut panics and false it it does not -func ConditionalPanic(t *testing.T, expectPanic bool, sut func()) { - if expectPanic { - require.Panics(t, sut) - return - } - require.NotPanics(t, sut) -} - -// ConditionalError checks if expectError is true, asserts that err is an error -// If expectError is false, asserts that err is nil -func ConditionalError(t *testing.T, expectError bool, err error) { - if expectError { - require.Error(t, err) - return - } - require.NoError(t, err) -} - -// DecApproxEq is a helper function to compare two decimals. -// It validates the two decimal are within a certain tolerance. -// If not, it fails with a message. -func DecApproxEq(t *testing.T, d1 sdk.Dec, d2 sdk.Dec, tol sdk.Dec, msgAndArgs ...interface{}) { - diff := d1.Sub(d2).Abs() - msg := messageFromMsgAndArgs(msgAndArgs...) - require.True(t, diff.LTE(tol), "expected |d1 - d2| <:\t%s\ngot |d1 - d2| = \t\t%s\nd1: %s, d2: %s\n%s", tol, diff, d1, d2, msg) -} - -func messageFromMsgAndArgs(msgAndArgs ...interface{}) string { - if len(msgAndArgs) == 0 || msgAndArgs == nil { - return "" - } - if len(msgAndArgs) == 1 { - msg := msgAndArgs[0] - if msgAsStr, ok := msg.(string); ok { - return msgAsStr - } - return fmt.Sprintf("%+v", msg) - } - if len(msgAndArgs) > 1 { - msgFormat, ok := msgAndArgs[0].(string) - if !ok { - return "error formatting additional arguments for DecApproxEq, please disregard." - } - return fmt.Sprintf(msgFormat, msgAndArgs[1:]...) - } - return "" -} diff --git a/osmoutils/osmocli/cli_tester.go b/osmoutils/osmocli/cli_tester.go deleted file mode 100644 index 4ef6aaf9b..000000000 --- a/osmoutils/osmocli/cli_tester.go +++ /dev/null @@ -1,111 +0,0 @@ -package osmocli - -import ( - "strings" - "testing" - - "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/client/flags" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/gogo/protobuf/proto" - "github.com/spf13/cobra" - "github.com/spf13/pflag" - "github.com/stretchr/testify/require" -) - -type TxCliTestCase[M sdk.Msg] struct { - Cmd string - ExpectedMsg M - ExpectedErr bool - OnlyCheckValidateBasic bool -} - -type QueryCliTestCase[Q proto.Message] struct { - Cmd string - ExpectedQuery Q - ExpectedErr bool -} - -func RunTxTestCases[M sdk.Msg](t *testing.T, desc *TxCliDesc, testcases map[string]TxCliTestCase[M]) { - for name, tc := range testcases { - t.Run(name, func(t *testing.T) { - RunTxTestCase(t, desc, &tc) - }) - } -} - -func RunQueryTestCases[Q proto.Message](t *testing.T, desc *QueryDescriptor, testcases map[string]QueryCliTestCase[Q]) { - for name, tc := range testcases { - t.Run(name, func(t *testing.T) { - RunQueryTestCase(t, desc, &tc) - }) - } -} - -func RunTxTestCase[M sdk.Msg](t *testing.T, desc *TxCliDesc, tc *TxCliTestCase[M]) { - cmd := BuildTxCli[M](desc) - err := resetCommandFlagValues(cmd) - require.NoError(t, err, "error in resetCommandFlagValues") - args := strings.Split(tc.Cmd, " ") - err = cmd.Flags().Parse(args) - require.NoError(t, err, "error in cmd.Flags().Parse(args)") - clientCtx := newClientContextWithFrom(t, cmd.Flags()) - - msg, err := desc.ParseAndBuildMsg(clientCtx, args, cmd.Flags()) - if tc.ExpectedErr { - require.Error(t, err) - return - } - require.NoError(t, err, "error in desc.ParseAndBuildMsg") - if tc.OnlyCheckValidateBasic { - require.NoError(t, msg.ValidateBasic()) - return - } - - require.Equal(t, tc.ExpectedMsg, msg) -} - -func RunQueryTestCase[Q proto.Message](t *testing.T, desc *QueryDescriptor, tc *QueryCliTestCase[Q]) { - cmd := BuildQueryCli[Q, int](desc, nil) - err := resetCommandFlagValues(cmd) - require.NoError(t, err, "error in resetCommandFlagValues") - args := strings.Split(tc.Cmd, " ") - err = cmd.Flags().Parse(args) - require.NoError(t, err, "error in cmd.Flags().Parse(args)") - - req, err := desc.ParseQuery(args, cmd.Flags()) - if tc.ExpectedErr { - require.Error(t, err) - return - } - require.NoError(t, err, "error in desc.ParseQuery") - require.Equal(t, tc.ExpectedQuery, req) -} - -// This logic is copied from the SDK, it should've just been publicly exposed. -// But instead its buried within a mega-method. -func newClientContextWithFrom(t *testing.T, fs *pflag.FlagSet) client.Context { - clientCtx := client.Context{} - from, _ := fs.GetString(flags.FlagFrom) - fromAddr, fromName, _, err := client.GetFromFields(nil, from, true) - require.NoError(t, err) - - clientCtx = clientCtx.WithFrom(from).WithFromAddress(fromAddr).WithFromName(fromName) - return clientCtx -} - -// taken from https://github.com/golang/debug/pull/8, -// due to no cobra command for resetting flag value -func resetCommandFlagValues(cmd *cobra.Command) error { - var retErr error = nil - cmd.Flags().VisitAll(func(f *pflag.Flag) { - if f.Changed { - err := f.Value.Set(f.DefValue) - if err != nil { - retErr = err - } - f.Changed = false - } - }) - return retErr -} diff --git a/osmoutils/osmocli/flag_advice.go b/osmoutils/osmocli/flag_advice.go deleted file mode 100644 index 11da922a3..000000000 --- a/osmoutils/osmocli/flag_advice.go +++ /dev/null @@ -1,79 +0,0 @@ -package osmocli - -import ( - "strings" - - "github.com/spf13/cobra" - "github.com/spf13/pflag" -) - -type FlagAdvice struct { - HasPagination bool - - // Map of FieldName -> FlagName - CustomFlagOverrides map[string]string - CustomFieldParsers map[string]CustomFieldParserFn - - // Tx sender value - IsTx bool - TxSenderFieldName string - FromValue string -} - -type FlagDesc struct { - RequiredFlags []*pflag.FlagSet - OptionalFlags []*pflag.FlagSet -} - -type FieldReadLocation = bool - -const ( - UsedArg FieldReadLocation = true - UsedFlag FieldReadLocation = false -) - -// CustomFieldParser function. -type CustomFieldParserFn = func(arg string, flags *pflag.FlagSet) (valueToSet any, usedArg FieldReadLocation, err error) - -func (f FlagAdvice) Sanitize() FlagAdvice { - // map CustomFlagOverrides & CustomFieldParser keys to lower-case - // initialize if uninitialized - newFlagOverrides := make(map[string]string, len(f.CustomFlagOverrides)) - for k, v := range f.CustomFlagOverrides { - newFlagOverrides[strings.ToLower(k)] = v - } - f.CustomFlagOverrides = newFlagOverrides - newFlagParsers := make(map[string]CustomFieldParserFn, len(f.CustomFieldParsers)) - for k, v := range f.CustomFieldParsers { - newFlagParsers[strings.ToLower(k)] = v - } - f.CustomFieldParsers = newFlagParsers - return f -} - -func FlagOnlyParser[v any](f func(fs *pflag.FlagSet) (v, error)) CustomFieldParserFn { - return func(_arg string, fs *pflag.FlagSet) (any, FieldReadLocation, error) { - t, err := f(fs) - return t, UsedFlag, err - } -} - -// AddFlags from desc to cmd. -// Required flags are marked as required. -func AddFlags(cmd *cobra.Command, desc FlagDesc) { - for i := 0; i < len(desc.OptionalFlags); i++ { - cmd.Flags().AddFlagSet(desc.OptionalFlags[i]) - } - for i := 0; i < len(desc.RequiredFlags); i++ { - fs := desc.RequiredFlags[i] - cmd.Flags().AddFlagSet(fs) - - // mark all these flags as required. - fs.VisitAll(func(flag *pflag.Flag) { - err := cmd.MarkFlagRequired(flag.Name) - if err != nil { - panic(err) - } - }) - } -} diff --git a/osmoutils/osmocli/index_cmd.go b/osmoutils/osmocli/index_cmd.go deleted file mode 100644 index b1d3f0da1..000000000 --- a/osmoutils/osmocli/index_cmd.go +++ /dev/null @@ -1,31 +0,0 @@ -package osmocli - -import ( - "fmt" - - "github.com/spf13/cobra" -) - -// Index command, but short is not set. That is left to caller. -func IndexCmd(moduleName string) *cobra.Command { - return &cobra.Command{ - Use: moduleName, - Short: fmt.Sprintf("Querying commands for the %s module", moduleName), - DisableFlagParsing: true, - SuggestionsMinimumDistance: 2, - RunE: indexRunCmd, - } -} - -func indexRunCmd(cmd *cobra.Command, args []string) error { - usageTemplate := `Usage:{{if .HasAvailableSubCommands}} - {{.CommandPath}} [command]{{end}} - -{{if .HasAvailableSubCommands}}Available Commands:{{range .Commands}}{{if .IsAvailableCommand}} - {{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}} - -Use "{{.CommandPath}} [command] --help" for more information about a command.{{end}} -` - cmd.SetUsageTemplate(usageTemplate) - return cmd.Help() -} diff --git a/osmoutils/osmocli/parsers.go b/osmoutils/osmocli/parsers.go deleted file mode 100644 index c8cba5ae6..000000000 --- a/osmoutils/osmocli/parsers.go +++ /dev/null @@ -1,344 +0,0 @@ -package osmocli - -import ( - "fmt" - "reflect" - "strconv" - "strings" - "time" - - "cosmossdk.io/math" - "github.com/cosmos/cosmos-sdk/client" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/spf13/pflag" - - "github.com/CosmosContracts/juno/v15/osmoutils" -) - -// Parses arguments 1-1 from args -// makes an exception, where it allows Pagination to come from flags. -func ParseFieldsFromFlagsAndArgs[reqP any](flagAdvice FlagAdvice, flags *pflag.FlagSet, args []string) (reqP, error) { - req := osmoutils.MakeNew[reqP]() - v := reflect.ValueOf(req).Elem() - t := v.Type() - - argIndexOffset := 0 - // Iterate over the fields in the struct - for i := 0; i < t.NumField(); i++ { - arg := "" - if len(args) > i+argIndexOffset { - arg = args[i+argIndexOffset] - } - usedArg, err := ParseField(v, t, i, arg, flagAdvice, flags) - if err != nil { - return req, err - } - if !usedArg { - argIndexOffset -= 1 - } - } - return req, nil -} - -func ParseNumFields[reqP any]() int { - req := osmoutils.MakeNew[reqP]() - v := reflect.ValueOf(req).Elem() - t := v.Type() - return t.NumField() -} - -func ParseExpectedQueryFnName[reqP any]() string { - req := osmoutils.MakeNew[reqP]() - v := reflect.ValueOf(req).Elem() - s := v.Type().String() - // handle some non-std queries - var prefixTrimmed string - if strings.Contains(s, "Query") { - prefixTrimmed = strings.Split(s, "Query")[1] - } else { - prefixTrimmed = strings.Split(s, ".")[1] - } - suffixTrimmed := strings.TrimSuffix(prefixTrimmed, "Request") - return suffixTrimmed -} - -func ParseHasPagination[reqP any]() bool { - req := osmoutils.MakeNew[reqP]() - t := reflect.ValueOf(req).Elem().Type() - for i := 0; i < t.NumField(); i++ { - fType := t.Field(i) - if fType.Type.String() == paginationType { - return true - } - } - return false -} - -const paginationType = "*query.PageRequest" - -// ParseField parses field #fieldIndex from either an arg or a flag. -// Returns true if it was parsed from an argument. -// Returns error if there was an issue in parsing this field. -func ParseField(v reflect.Value, t reflect.Type, fieldIndex int, arg string, flagAdvice FlagAdvice, flags *pflag.FlagSet) (bool, error) { - fVal := v.Field(fieldIndex) - fType := t.Field(fieldIndex) - // fmt.Printf("Field %d: %s %s %s\n", fieldIndex, fType.Name, fType.Type, fType.Type.Kind()) - - lowercaseFieldNameStr := strings.ToLower(fType.Name) - if parseFn, ok := flagAdvice.CustomFieldParsers[lowercaseFieldNameStr]; ok { - v, usedArg, err := parseFn(arg, flags) - if err == nil { - fVal.Set(reflect.ValueOf(v)) - } - return usedArg, err - } - - parsedFromFlag, err := ParseFieldFromFlag(fVal, fType, flagAdvice, flags) - if err != nil { - return false, err - } - if parsedFromFlag { - return false, nil - } - return true, ParseFieldFromArg(fVal, fType, arg) -} - -// ParseFieldFromFlag attempts to parses the value of a field in a struct from a flag. -// The field is identified by the provided `reflect.StructField`. -// The flag advice and `pflag.FlagSet` are used to determine the flag to parse the field from. -// If the field corresponds to a value from a flag, true is returned. -// Otherwise, `false` is returned. -// In the true case, the parsed value is set on the provided `reflect.Value`. -// An error is returned if there is an issue parsing the field from the flag. -func ParseFieldFromFlag(fVal reflect.Value, fType reflect.StructField, flagAdvice FlagAdvice, flags *pflag.FlagSet) (bool, error) { - lowercaseFieldNameStr := strings.ToLower(fType.Name) - if flagName, ok := flagAdvice.CustomFlagOverrides[lowercaseFieldNameStr]; ok { - return true, parseFieldFromDirectlySetFlag(fVal, fType, flagAdvice, flagName, flags) - } - - kind := fType.Type.Kind() - switch kind { - case reflect.String: - if flagAdvice.IsTx { - // matchesFieldName is true if lowercaseFieldNameStr is the same as TxSenderFieldName, - // or if TxSenderFieldName is left blank, then matches fields named "sender" or "owner" - matchesFieldName := (flagAdvice.TxSenderFieldName == lowercaseFieldNameStr) || - (flagAdvice.TxSenderFieldName == "" && (lowercaseFieldNameStr == "sender" || lowercaseFieldNameStr == "owner")) - if matchesFieldName { - fVal.SetString(flagAdvice.FromValue) - return true, nil - } - } - case reflect.Ptr: - if flagAdvice.HasPagination { - typeStr := fType.Type.String() - if typeStr == paginationType { - pageReq, err := client.ReadPageRequest(flags) - if err != nil { - return true, err - } - fVal.Set(reflect.ValueOf(pageReq)) - return true, nil - } - } - } - return false, nil -} - -func parseFieldFromDirectlySetFlag(fVal reflect.Value, fType reflect.StructField, flagAdvice FlagAdvice, flagName string, flags *pflag.FlagSet) error { - // get string. If its a string great, run through arg parser. Otherwise try setting directly - s, err := flags.GetString(flagName) - if err != nil { - flag := flags.Lookup(flagName) - if flag == nil { - return fmt.Errorf("Programmer set the flag name wrong. Flag %s does not exist", flagName) - } - t := flag.Value.Type() - if t == "uint64" { - u, err := flags.GetUint64(flagName) - if err != nil { - return err - } - fVal.SetUint(u) - return nil - } - } - return ParseFieldFromArg(fVal, fType, s) -} - -func ParseFieldFromArg(fVal reflect.Value, fType reflect.StructField, arg string) error { - // We cant pass in a negative number due to the way pflags works... - // This is an (extraordinarily ridiculous) workaround that checks if a negative int is encapsulated in square brackets, - // and if so, trims the square brackets - if strings.HasPrefix(arg, "[") && strings.HasSuffix(arg, "]") && arg[1] == '-' { - arg = strings.TrimPrefix(arg, "[") - arg = strings.TrimSuffix(arg, "]") - } - - switch fType.Type.Kind() { - // SetUint allows anyof type u8, u16, u32, u64, and uint - case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint: - u, err := ParseUint(arg, fType.Name) - if err != nil { - return err - } - fVal.SetUint(u) - return nil - // SetInt allows anyof type i8,i16,i32,i64 and int - case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int: - typeStr := fType.Type.String() - var i int64 - var err error - if typeStr == "time.Duration" { - dur, err2 := time.ParseDuration(arg) - i, err = int64(dur), err2 - } else { - i, err = ParseInt(arg, fType.Name) - } - if err != nil { - return err - } - fVal.SetInt(i) - return nil - case reflect.Float32, reflect.Float64: - typeStr := fType.Type.String() - f, err := ParseFloat(arg, typeStr) - if err != nil { - return err - } - fVal.SetFloat(f) - return nil - case reflect.String: - s, err := ParseDenom(arg, fType.Name) - if err != nil { - return err - } - fVal.SetString(s) - return nil - case reflect.Ptr: - case reflect.Slice: - typeStr := fType.Type.String() - if typeStr == "[]uint64" { - // Parse comma-separated uint64 values into []uint64 slice - strValues := strings.Split(arg, ",") - values := make([]uint64, len(strValues)) - for i, strValue := range strValues { - u, err := strconv.ParseUint(strValue, 10, 64) - if err != nil { - return err - } - values[i] = u - } - fVal.Set(reflect.ValueOf(values)) - return nil - } - if typeStr == "types.Coins" { - coins, err := ParseCoins(arg, fType.Name) - if err != nil { - return err - } - fVal.Set(reflect.ValueOf(coins)) - return nil - } - case reflect.Struct: - typeStr := fType.Type.String() - var v any - var err error - if typeStr == "types.Coin" { - v, err = ParseCoin(arg, fType.Name) - } else if typeStr == "types.Int" { - v, err = ParseSdkInt(arg, fType.Name) - } else if typeStr == "time.Time" { - v, err = ParseUnixTime(arg, fType.Name) - } else if typeStr == "types.Dec" { - v, err = ParseSdkDec(arg, fType.Name) - } else { - return fmt.Errorf("struct field type not recognized. Got type %v", fType) - } - - if err != nil { - return err - } - fVal.Set(reflect.ValueOf(v)) - return nil - } - fmt.Println(fType.Type.Kind().String()) - return fmt.Errorf("field type not recognized. Got type %v", fType) -} - -func ParseUint(arg string, fieldName string) (uint64, error) { - v, err := strconv.ParseUint(arg, 10, 64) - if err != nil { - return 0, fmt.Errorf("could not parse %s as uint for field %s: %w", arg, fieldName, err) - } - return v, nil -} - -func ParseFloat(arg string, fieldName string) (float64, error) { - v, err := strconv.ParseFloat(arg, 64) - if err != nil { - return 0, fmt.Errorf("could not parse %s as float for field %s: %w", arg, fieldName, err) - } - return v, nil -} - -func ParseInt(arg string, fieldName string) (int64, error) { - v, err := strconv.ParseInt(arg, 10, 64) - if err != nil { - return 0, fmt.Errorf("could not parse %s as int for field %s: %w", arg, fieldName, err) - } - return v, nil -} - -func ParseUnixTime(arg string, fieldName string) (time.Time, error) { - timeUnix, err := strconv.ParseInt(arg, 10, 64) - if err != nil { - parsedTime, err := time.Parse(sdk.SortableTimeFormat, arg) - if err != nil { - return time.Time{}, fmt.Errorf("could not parse %s as time for field %s: %w", arg, fieldName, err) - } - - return parsedTime, nil - } - startTime := time.Unix(timeUnix, 0) - return startTime, nil -} - -func ParseDenom(arg string, fieldName string) (string, error) { - return strings.TrimSpace(arg), nil -} - -// TODO: Make this able to read from some local alias file for denoms. -func ParseCoin(arg string, fieldName string) (sdk.Coin, error) { - coin, err := sdk.ParseCoinNormalized(arg) - if err != nil { - return sdk.Coin{}, fmt.Errorf("could not parse %s as sdk.Coin for field %s: %w", arg, fieldName, err) - } - return coin, nil -} - -// TODO: Make this able to read from some local alias file for denoms. -func ParseCoins(arg string, fieldName string) (sdk.Coins, error) { - coins, err := sdk.ParseCoinsNormalized(arg) - if err != nil { - return sdk.Coins{}, fmt.Errorf("could not parse %s as sdk.Coins for field %s: %w", arg, fieldName, err) - } - return coins, nil -} - -// TODO: This really shouldn't be getting used in the CLI, its misdesign on the CLI ux -func ParseSdkInt(arg string, fieldName string) (math.Int, error) { - i, ok := sdk.NewIntFromString(arg) - if !ok { - return math.Int{}, fmt.Errorf("could not parse %s as math.Int for field %s", arg, fieldName) - } - return i, nil -} - -func ParseSdkDec(arg, fieldName string) (sdk.Dec, error) { - i, err := sdk.NewDecFromStr(arg) - if err != nil { - return sdk.Dec{}, fmt.Errorf("could not parse %s as sdk.Dec for field %s: %w", arg, fieldName, err) - } - return i, nil -} diff --git a/osmoutils/osmocli/parsers_test.go b/osmoutils/osmocli/parsers_test.go deleted file mode 100644 index 904a4d07c..000000000 --- a/osmoutils/osmocli/parsers_test.go +++ /dev/null @@ -1,166 +0,0 @@ -package osmocli - -import ( - "reflect" - "testing" - "time" - - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/stretchr/testify/require" -) - -type testingStruct struct { - Int int64 - UInt uint64 - String string - Float float64 - Duration time.Duration - Pointer *testingStruct - Slice sdk.Coins - Struct interface{} - Dec sdk.Dec -} - -func TestParseFieldFromArg(t *testing.T) { - tests := map[string]struct { - testingStruct - arg string - fieldIndex int - - expectedStruct testingStruct - expectingErr bool - }{ - "Int value changes from -20 to 10": { - testingStruct: testingStruct{Int: -20}, - arg: "10", - fieldIndex: 0, - expectedStruct: testingStruct{Int: 10}, - }, - "Attempt to change Int value 20 to string value": { // does not return error, simply does not change the struct - testingStruct: testingStruct{Int: 20}, - arg: "hello", - fieldIndex: 0, - expectedStruct: testingStruct{Int: 20}, - }, - "UInt value changes from 20 to 10": { - testingStruct: testingStruct{UInt: 20}, - arg: "10", - fieldIndex: 1, - expectedStruct: testingStruct{UInt: 10}, - }, - "String value change": { - testingStruct: testingStruct{String: "hello"}, - arg: "world", - fieldIndex: 2, - expectedStruct: testingStruct{String: "world"}, - }, - "Changing unset value (simply sets the value)": { - testingStruct: testingStruct{Int: 20}, - arg: "hello", - fieldIndex: 2, - expectedStruct: testingStruct{Int: 20, String: "hello"}, - }, - "Float value change": { - testingStruct: testingStruct{Float: 20.0}, - arg: "30.0", - fieldIndex: 3, - expectedStruct: testingStruct{Float: 30.0}, - }, - "Duration value changes from .Hour to .Second": { - testingStruct: testingStruct{Duration: time.Hour}, - arg: "1s", - fieldIndex: 4, - expectedStruct: testingStruct{Duration: time.Second}, - }, - "Attempt to change pointer": { // for reflect.Ptr kind ParseFieldFromArg does nothing, hence no changes take place - testingStruct: testingStruct{Pointer: &testingStruct{}}, - arg: "*whatever", - fieldIndex: 5, - expectedStruct: testingStruct{Pointer: &testingStruct{}}, - }, - "Slice change": { - testingStruct: testingStruct{Slice: sdk.Coins{ - sdk.NewCoin("foo", sdk.NewInt(100)), - sdk.NewCoin("bar", sdk.NewInt(100)), - }}, - arg: "10foo,10bar", // Should be of a format suitable for ParseCoinsNormalized - fieldIndex: 6, - expectedStruct: testingStruct{Slice: sdk.Coins{ // swapped places due to lexicographic order - sdk.NewCoin("bar", sdk.NewInt(10)), - sdk.NewCoin("foo", sdk.NewInt(10)), - }}, - }, - "Struct (sdk.Coin) change": { - testingStruct: testingStruct{Struct: sdk.NewCoin("bar", sdk.NewInt(10))}, // only supports math.Int, sdk.Coin or time.Time, other structs are not recognized - arg: "100bar", - fieldIndex: 7, - expectedStruct: testingStruct{Struct: sdk.NewCoin("bar", sdk.NewInt(10))}, - }, - "Unrecognizable struct": { - testingStruct: testingStruct{Struct: testingStruct{}}, // only supports math.Int, sdk.Coin or time.Time, other structs are not recognized - arg: "whatever", - fieldIndex: 7, - expectingErr: true, - }, - "Multiple fields in struct are set": { - testingStruct: testingStruct{Int: 20, UInt: 10, String: "hello", Pointer: &testingStruct{}}, - arg: "world", - fieldIndex: 2, - expectedStruct: testingStruct{Int: 20, UInt: 10, String: "world", Pointer: &testingStruct{}}, - }, - "All fields in struct set": { - testingStruct: testingStruct{ - Int: 20, - UInt: 10, - String: "hello", - Float: 30.0, - Duration: time.Second, - Pointer: &testingStruct{}, - Slice: sdk.Coins{ - sdk.NewCoin("foo", sdk.NewInt(100)), - sdk.NewCoin("bar", sdk.NewInt(100)), - }, - Struct: sdk.NewCoin("bar", sdk.NewInt(10)), - }, - arg: "1foo,15bar", - fieldIndex: 6, - expectedStruct: testingStruct{ - Int: 20, - UInt: 10, - String: "hello", - Float: 30.0, - Duration: time.Second, - Pointer: &testingStruct{}, - Slice: sdk.Coins{ - sdk.NewCoin("bar", sdk.NewInt(15)), - sdk.NewCoin("foo", sdk.NewInt(1)), - }, - Struct: sdk.NewCoin("bar", sdk.NewInt(10)), - }, - }, - "Dec struct": { - testingStruct: testingStruct{Dec: sdk.MustNewDecFromStr("100")}, - arg: "10", - fieldIndex: 8, - expectedStruct: testingStruct{Dec: sdk.MustNewDecFromStr("10")}, - }, - } - - for name, tc := range tests { - t.Run(name, func(t *testing.T) { - val := reflect.ValueOf(&tc.testingStruct).Elem() - typ := reflect.TypeOf(&tc.testingStruct).Elem() - - fVal := val.Field(tc.fieldIndex) - fType := typ.Field(tc.fieldIndex) - - err := ParseFieldFromArg(fVal, fType, tc.arg) - - if !tc.expectingErr { - require.Equal(t, tc.expectedStruct, tc.testingStruct) - } else { - require.Error(t, err) - } - }) - } -} diff --git a/osmoutils/osmocli/query_cmd_wrap.go b/osmoutils/osmocli/query_cmd_wrap.go deleted file mode 100644 index 86c8e777b..000000000 --- a/osmoutils/osmocli/query_cmd_wrap.go +++ /dev/null @@ -1,181 +0,0 @@ -package osmocli - -import ( - "context" - "fmt" - "reflect" - "strings" - - "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/client/flags" - grpc1 "github.com/gogo/protobuf/grpc" - "github.com/gogo/protobuf/proto" - "github.com/spf13/cobra" - "github.com/spf13/pflag" -) - -// global variable set on index command. -// helps populate Longs, when not set in QueryDescriptor. -var lastQueryModuleName string - -type QueryDescriptor struct { - Use string - Short string - Long string - - HasPagination bool - - QueryFnName string - - Flags FlagDesc - // Map of FieldName -> FlagName - CustomFlagOverrides map[string]string - // Map of FieldName -> CustomParseFn - CustomFieldParsers map[string]CustomFieldParserFn - - ParseQuery func(args []string, flags *pflag.FlagSet) (proto.Message, error) - - ModuleName string - numArgs int -} - -func QueryIndexCmd(moduleName string) *cobra.Command { - cmd := IndexCmd(moduleName) - cmd.Short = fmt.Sprintf("Querying commands for the %s module", moduleName) - lastQueryModuleName = moduleName - return cmd -} - -func AddQueryCmd[Q proto.Message, querier any](cmd *cobra.Command, newQueryClientFn func(grpc1.ClientConn) querier, f func() (*QueryDescriptor, Q)) { - desc, _ := f() - subCmd := BuildQueryCli[Q](desc, newQueryClientFn) - cmd.AddCommand(subCmd) -} - -func (desc *QueryDescriptor) FormatLong(moduleName string) { - desc.Long = FormatLongDesc(desc.Long, NewLongMetadata(moduleName).WithShort(desc.Short)) -} - -func prepareDescriptor[reqP proto.Message](desc *QueryDescriptor) { - if !desc.HasPagination { - desc.HasPagination = ParseHasPagination[reqP]() - } - if desc.QueryFnName == "" { - desc.QueryFnName = ParseExpectedQueryFnName[reqP]() - } - if strings.Contains(desc.Long, "{") { - if desc.ModuleName == "" { - desc.ModuleName = lastQueryModuleName - } - desc.FormatLong(desc.ModuleName) - } - - desc.numArgs = ParseNumFields[reqP]() - len(desc.CustomFlagOverrides) - if desc.HasPagination { - desc.numArgs = desc.numArgs - 1 - } -} - -func BuildQueryCli[reqP proto.Message, querier any](desc *QueryDescriptor, newQueryClientFn func(grpc1.ClientConn) querier) *cobra.Command { - prepareDescriptor[reqP](desc) - if desc.ParseQuery == nil { - desc.ParseQuery = func(args []string, fs *pflag.FlagSet) (proto.Message, error) { - flagAdvice := FlagAdvice{ - HasPagination: desc.HasPagination, - CustomFlagOverrides: desc.CustomFlagOverrides, - CustomFieldParsers: desc.CustomFieldParsers, - }.Sanitize() - return ParseFieldsFromFlagsAndArgs[reqP](flagAdvice, fs, args) - } - } - - cmd := &cobra.Command{ - Use: desc.Use, - Short: desc.Short, - Long: desc.Long, - Args: cobra.ExactArgs(desc.numArgs), - RunE: queryLogic(desc, newQueryClientFn), - } - flags.AddQueryFlagsToCmd(cmd) - AddFlags(cmd, desc.Flags) - if desc.HasPagination { - cmdName := strings.Split(desc.Use, " ")[0] - flags.AddPaginationFlagsToCmd(cmd, cmdName) - } - - return cmd -} - -// SimpleQueryCmd builds a query, for the common, simple case. -// It detects that the querier function name is the same as the ProtoMessage name, -// with just the "Query" and "Request" args chopped off. -// It expects all proto fields to appear as arguments, in order. -func SimpleQueryCmd[reqP proto.Message, querier any](use string, short string, long string, - moduleName string, newQueryClientFn func(grpc1.ClientConn) querier, -) *cobra.Command { - desc := QueryDescriptor{ - Use: use, - Short: short, - Long: FormatLongDesc(long, NewLongMetadata(moduleName).WithShort(short)), - } - return BuildQueryCli[reqP](&desc, newQueryClientFn) -} - -func GetParams[reqP proto.Message, querier any](moduleName string, - newQueryClientFn func(grpc1.ClientConn) querier, -) *cobra.Command { - return BuildQueryCli[reqP](&QueryDescriptor{ - Use: "params [flags]", - Short: fmt.Sprintf("Get the params for the x/%s module", moduleName), - QueryFnName: "Params", - }, newQueryClientFn) -} - -func callQueryClientFn(ctx context.Context, fnName string, req proto.Message, q any) (res proto.Message, err error) { - qVal := reflect.ValueOf(q) - method := qVal.MethodByName(fnName) - if (method == reflect.Value{}) { - return nil, fmt.Errorf("Method %s does not exist on the querier."+ - " You likely need to override QueryFnName in your Query descriptor", fnName) - } - args := []reflect.Value{ - reflect.ValueOf(ctx), - reflect.ValueOf(req), - } - results := method.Call(args) - if len(results) != 2 { - panic("We got something wrong") - } - if !results[1].IsNil() { - //nolint:forcetypeassert - err = results[1].Interface().(error) - return res, err - } - //nolint:forcetypeassert - res = results[0].Interface().(proto.Message) - return res, nil -} - -func queryLogic[querier any](desc *QueryDescriptor, - newQueryClientFn func(grpc1.ClientConn) querier, -) func(cmd *cobra.Command, args []string) error { - return func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientQueryContext(cmd) - if err != nil { - return err - } - queryClient := newQueryClientFn(clientCtx) - - req, err := desc.ParseQuery(args, cmd.Flags()) - if err != nil { - return err - } - - res, err := callQueryClientFn(cmd.Context(), desc.QueryFnName, req, queryClient) - if err != nil { - return err - } - - return clientCtx.PrintProto(res) - } -} diff --git a/osmoutils/osmocli/string_formatter.go b/osmoutils/osmocli/string_formatter.go deleted file mode 100644 index 43c57725e..000000000 --- a/osmoutils/osmocli/string_formatter.go +++ /dev/null @@ -1,49 +0,0 @@ -package osmocli - -import ( - "fmt" - "strings" - "text/template" - - "github.com/cosmos/cosmos-sdk/version" -) - -type LongMetadata struct { - BinaryName string - CommandPrefix string - Short string - - // Newline Example: - ExampleHeader string -} - -func NewLongMetadata(moduleName string) *LongMetadata { - commandPrefix := fmt.Sprintf("$ %s q %s", version.AppName, moduleName) - return &LongMetadata{ - BinaryName: version.AppName, - CommandPrefix: commandPrefix, - } -} - -func (m *LongMetadata) WithShort(short string) *LongMetadata { - m.Short = short - return m -} - -func FormatLongDesc(longString string, meta *LongMetadata) string { - template, err := template.New("long_description").Parse(longString) - if err != nil { - panic("incorrectly configured long message") - } - bld := strings.Builder{} - meta.ExampleHeader = "\n\nExample:" - err = template.Execute(&bld, meta) - if err != nil { - panic("incorrectly configured long message") - } - return strings.TrimSpace(bld.String()) -} - -func FormatLongDescDirect(longString string, moduleName string) string { - return FormatLongDesc(longString, NewLongMetadata(moduleName)) -} diff --git a/osmoutils/osmocli/tx_cmd_wrap.go b/osmoutils/osmocli/tx_cmd_wrap.go deleted file mode 100644 index 32f7b2dcf..000000000 --- a/osmoutils/osmocli/tx_cmd_wrap.go +++ /dev/null @@ -1,102 +0,0 @@ -package osmocli - -import ( - "fmt" - "strings" - - "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/client/tx" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/spf13/cobra" - "github.com/spf13/pflag" -) - -func TxIndexCmd(moduleName string) *cobra.Command { - cmd := IndexCmd(moduleName) - cmd.Short = fmt.Sprintf("%s transactions subcommands", moduleName) - return cmd -} - -type TxCliDesc struct { - Use string - Short string - Long string - Example string - - NumArgs int - // Contract: len(args) = NumArgs - ParseAndBuildMsg func(clientCtx client.Context, args []string, flags *pflag.FlagSet) (sdk.Msg, error) - TxSignerFieldName string - - Flags FlagDesc - // Map of FieldName -> FlagName - CustomFlagOverrides map[string]string - // Map of FieldName -> CustomParseFn - CustomFieldParsers map[string]CustomFieldParserFn -} - -func AddTxCmd[M sdk.Msg](cmd *cobra.Command, f func() (*TxCliDesc, M)) { - desc, _ := f() - subCmd := BuildTxCli[M](desc) - cmd.AddCommand(subCmd) -} - -func BuildTxCli[M sdk.Msg](desc *TxCliDesc) *cobra.Command { - desc.TxSignerFieldName = strings.ToLower(desc.TxSignerFieldName) - if desc.NumArgs == 0 { - // NumArgs = NumFields - 1, since 1 field is from the msg - desc.NumArgs = ParseNumFields[M]() - 1 - len(desc.CustomFlagOverrides) - len(desc.CustomFieldParsers) - } - if desc.ParseAndBuildMsg == nil { - desc.ParseAndBuildMsg = func(clientCtx client.Context, args []string, flags *pflag.FlagSet) (sdk.Msg, error) { - flagAdvice := FlagAdvice{ - IsTx: true, - TxSenderFieldName: desc.TxSignerFieldName, - FromValue: clientCtx.GetFromAddress().String(), - CustomFlagOverrides: desc.CustomFlagOverrides, - CustomFieldParsers: desc.CustomFieldParsers, - }.Sanitize() - return ParseFieldsFromFlagsAndArgs[M](flagAdvice, flags, args) - } - } - return desc.BuildCommandCustomFn() -} - -// Creates a new cobra command given the description. -// Its up to then caller to add CLI flags, aside from `flags.AddTxFlagsToCmd(cmd)` -func (desc TxCliDesc) BuildCommandCustomFn() *cobra.Command { - cmd := &cobra.Command{ - Use: desc.Use, - Short: desc.Short, - Args: cobra.ExactArgs(desc.NumArgs), - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientTxContext(cmd) - if err != nil { - return err - } - - txf, err := tx.NewFactoryCLI(clientCtx, cmd.Flags()).WithTxConfig(clientCtx.TxConfig).WithAccountRetriever(clientCtx.AccountRetriever) - if err != nil { - return err - } - - msg, err := desc.ParseAndBuildMsg(clientCtx, args, cmd.Flags()) - if err != nil { - return err - } - - return tx.GenerateOrBroadcastTxWithFactory(clientCtx, txf, msg) - }, - } - if desc.Example != "" { - cmd.Example = desc.Example - } - if desc.Long != "" { - cmd.Long = desc.Long - } - - flags.AddTxFlagsToCmd(cmd) - AddFlags(cmd, desc.Flags) - return cmd -} diff --git a/osmoutils/parse.go b/osmoutils/parse.go deleted file mode 100644 index 808e3dcab..000000000 --- a/osmoutils/parse.go +++ /dev/null @@ -1,71 +0,0 @@ -package osmoutils - -import ( - "encoding/json" - "fmt" - "os" - - "github.com/cosmos/cosmos-sdk/x/gov/client/cli" - "github.com/spf13/pflag" -) - -type Proposal struct { - Title string - Description string - Deposit string -} - -var ProposalFlags = []string{ - cli.FlagTitle, - cli.FlagDescription, - cli.FlagDeposit, -} - -func (p Proposal) validate() error { - if p.Title == "" { - return fmt.Errorf("proposal title is required") - } - - if p.Description == "" { - return fmt.Errorf("proposal description is required") - } - return nil -} - -func ParseProposalFlags(fs *pflag.FlagSet) (*Proposal, error) { - proposal := &Proposal{} - proposalFile, _ := fs.GetString(cli.FlagProposal) - - if proposalFile == "" { - proposal.Title, _ = fs.GetString(cli.FlagTitle) - proposal.Description, _ = fs.GetString(cli.FlagDescription) - proposal.Deposit, _ = fs.GetString(cli.FlagDeposit) - if err := proposal.validate(); err != nil { - return nil, err - } - - return proposal, nil - } - - for _, flag := range ProposalFlags { - if v, _ := fs.GetString(flag); v != "" { - return nil, fmt.Errorf("--%s flag provided alongside --proposal, which is a noop", flag) - } - } - - contents, err := os.ReadFile(proposalFile) - if err != nil { - return nil, err - } - - err = json.Unmarshal(contents, proposal) - if err != nil { - return nil, err - } - - if err := proposal.validate(); err != nil { - return nil, err - } - - return proposal, nil -} diff --git a/osmoutils/partialord/internal/dag/dag.go b/osmoutils/partialord/internal/dag/dag.go deleted file mode 100644 index d33a0a63a..000000000 --- a/osmoutils/partialord/internal/dag/dag.go +++ /dev/null @@ -1,320 +0,0 @@ -package dag - -import ( - "fmt" - "sort" -) - -// DAG struct maintains a directed acyclic graph, using adjacency lists to track edges. -type DAG struct { - // there is a directed edge from u -> v, if directedEdgeList[u][v] = 1 - // there is a directed edge from v -> u, if directedEdgeList[u][v] = -1 - directedEdgeList []map[int]int8 - nodeNameToId map[string]int - idToNodeNames map[int]string -} - -func NewDAG(nodes []string) DAG { - nodeNameToId := make(map[string]int, len(nodes)) - idToNodeNames := make(map[int]string, len(nodes)) - directedEdgeList := make([]map[int]int8, len(nodes)) - for i, node := range nodes { - nodeNameToId[node] = i - idToNodeNames[i] = node - directedEdgeList[i] = map[int]int8{} - } - if len(nodeNameToId) != len(nodes) { - panic("provided multiple nodes with the same name") - } - return DAG{ - directedEdgeList: directedEdgeList, - nodeNameToId: nodeNameToId, - idToNodeNames: idToNodeNames, - } -} - -// Copy returns a new dag struct that is a copy of the original dag. -// Edges can be mutated in the copy, without altering the original. -func (dag DAG) Copy() DAG { - directedEdgeList := make([]map[int]int8, len(dag.nodeNameToId)) - for i := 0; i < len(dag.nodeNameToId); i++ { - originalEdgeList := dag.directedEdgeList[i] - directedEdgeList[i] = make(map[int]int8, len(originalEdgeList)) - for k, v := range originalEdgeList { - directedEdgeList[i][k] = v - } - } - // we re-use nodeNameToId and idToNodeNames as these are fixed at dag creation. - return DAG{ - directedEdgeList: directedEdgeList, - nodeNameToId: dag.nodeNameToId, - idToNodeNames: dag.idToNodeNames, - } -} - -func (dag DAG) hasDirectedEdge(u, v int) bool { - uAdjacencyList := dag.directedEdgeList[u] - _, exists := uAdjacencyList[v] - return exists -} - -// addEdge adds a directed edge from u -> v. -func (dag *DAG) addEdge(u, v int) error { - if u == v { - return fmt.Errorf("can't make self-edge") - } - if dag.hasDirectedEdge(v, u) { - return fmt.Errorf("dag has conflicting edge") - } - dag.directedEdgeList[u][v] = 1 - dag.directedEdgeList[v][u] = -1 - return nil -} - -// replaceEdge adds a directed edge from u -> v. -// it removes any edge that may already exist between the two. -func (dag *DAG) replaceEdge(u, v int) error { - if u == v { - return fmt.Errorf("can't make self-edge") - } - - dag.directedEdgeList[u][v] = 1 - dag.directedEdgeList[v][u] = -1 - return nil -} - -// resetEdges deletes all edges directed to or from node `u` -func (dag *DAG) resetEdges(u int) { - edges := dag.directedEdgeList[u] - for v := range edges { - delete(dag.directedEdgeList[v], u) - } - dag.directedEdgeList[u] = map[int]int8{} -} - -// deleteEdge deletes edges between u and v. -func (dag *DAG) deleteEdge(u, v int) { - delete(dag.directedEdgeList[u], v) - delete(dag.directedEdgeList[v], u) -} - -// AddEdge checks if either edge between u and v exists and adds a directed edge from u -> v -func (dag *DAG) AddEdge(u, v string) error { - uIndex, uExists := dag.nodeNameToId[u] - vIndex, vExists := dag.nodeNameToId[v] - if !uExists || !vExists { - return fmt.Errorf("one of %s, %s does not exist in dag", u, v) - } - return dag.addEdge(uIndex, vIndex) -} - -// ReplaceEdge adds a directed edge from u -> v. -// it removes any edge that may already exist between the two. -func (dag *DAG) ReplaceEdge(u, v string) error { - uIndex, uExists := dag.nodeNameToId[u] - vIndex, vExists := dag.nodeNameToId[v] - if !uExists || !vExists { - return fmt.Errorf("one of %s, %s does not exist in dag", u, v) - } - return dag.replaceEdge(uIndex, vIndex) -} - -// AddFirstElements sets the provided elements to be first in all orderings. -// So if were making an ordering over {A, B, C, D, E}, and elems provided is {D, B, A} -// then we are guaranteed that the total ordering will begin with {D, B, A} -func (dag *DAG) AddFirstElements(nodes ...string) error { - nodeIds, err := dag.namesToIds(nodes) - if err != nil { - return err - } - - return dag.addFirst(nodeIds) -} - -func (dag *DAG) addFirst(nodes []int) error { - nodeMap := map[int]bool{} - for i := 0; i < len(nodes); i++ { - nodeMap[nodes[i]] = true - } - // First we add an edge from nodes[-1] to every node in the graph aside from the provided first nodes. - // then we make nodes[-1] depend on nodes[-2], etc. - // We also clear all other edges from nodes[-2], to override previous settings. - lastOfFirstNodes := nodes[len(nodes)-1] - for i := 0; i < len(dag.nodeNameToId); i++ { - // skip any node in the 'first set' - _, inMap := nodeMap[i] - if inMap { - continue - } - // We make everything on `lastOfFirstNodes`, and therefore have an edge from `lastOfFirstNodes` to it - err := dag.replaceEdge(lastOfFirstNodes, i) - // can't happen by above check - if err != nil { - return err - } - } - - // Make nodes[i+1] depend on nodes[i] - for i := len(nodes) - 2; i >= 0; i-- { - dag.resetEdges(nodes[i]) - err := dag.replaceEdge(nodes[i], nodes[i+1]) - // can't happen by above check - if err != nil { - return err - } - } - return nil -} - -// AddLastElements sets the provided elements to be last in all orderings. -// So if were making an ordering over {A, B, C, D, E}, and elems provided is {D, B, A} -// then we are guaranteed that the total ordering will end with {D, B, A} -func (dag *DAG) AddLastElements(nodes ...string) error { - nodeIds, err := dag.namesToIds(nodes) - if err != nil { - return err - } - - return dag.addLast(nodeIds) -} - -func (dag *DAG) addLast(nodes []int) error { - nodeMap := map[int]bool{} - for i := 0; i < len(nodes); i++ { - nodeMap[nodes[i]] = true - } - // First we add an edge from every node in the graph aside from the provided last nodes, to nodes[0] - // then we make nodes[1] depend on nodes[0], etc. - // We also clear all other edges from nodes[1], to override previous settings. - firstOfLastNodes := nodes[0] - for i := 0; i < len(dag.nodeNameToId); i++ { - // skip any node in the 'last set' - _, inMap := nodeMap[i] - if inMap { - continue - } - // We make `firstOfLastNodes` depend on every node, and therefore have an edge from each node to `firstOfLastNodes` - err := dag.replaceEdge(i, firstOfLastNodes) - // can't happen by above check - if err != nil { - return err - } - } - - // Make nodes[i] depend on nodes[i-1], and clear all other edges from nodes[i] - for i := 1; i < len(nodes); i++ { - dag.resetEdges(nodes[i]) - err := dag.replaceEdge(nodes[i-1], nodes[i]) - // can't happen by above check - if err != nil { - return err - } - } - return nil -} - -func (dag DAG) hasEdges() bool { - for _, m := range dag.directedEdgeList { - if len(m) > 0 { - return true - } - } - return false -} - -func (dag *DAG) namesToIds(names []string) ([]int, error) { - nodeIds := []int{} - for _, name := range names { - nodeIndex, nodeExists := dag.nodeNameToId[name] - if !nodeExists { - return []int{}, fmt.Errorf("%s does not exist in dag", name) - } - nodeIds = append(nodeIds, nodeIndex) - } - return nodeIds, nil -} - -func (dag DAG) idsToNames(ids []int) []string { - sortedNames := make([]string, 0, len(ids)) - for i := 0; i < len(dag.nodeNameToId); i++ { - id := ids[i] - sortedNames = append(sortedNames, dag.idToNodeNames[id]) - } - return sortedNames -} - -func (dag DAG) hasIncomingEdge(u int) bool { - adjacencyList := dag.directedEdgeList[u] - for _, v := range adjacencyList { - if v == -1 { - return true - } - } - return false -} - -// returns nodes with no incoming edges. -func (dag *DAG) topologicalTopLevelNodes() []int { - topLevelNodes := []int{} - - for i := 0; i < len(dag.nodeNameToId); i++ { - if !dag.hasIncomingEdge(i) { - topLevelNodes = append(topLevelNodes, i) - } - } - - return topLevelNodes -} - -// Returns a Topological Sort of the DAG, using Kahn's algorithm. -// https://en.wikipedia.org/wiki/Topological_sorting#Kahn's_algorithm -func (dag DAG) TopologicalSort() []string { - // G is the mutable graph we work on, which we remove edges from. - G := dag.Copy() - // L in pseudocode - sortedIDs := make([]int, 0, len(dag.nodeNameToId)) - topLevelNodes := dag.topologicalTopLevelNodes() - - // while len(topLevelNodes) != 0 - for { - if len(topLevelNodes) == 0 { - break - } - // pop a node `n`` off of topLevelNodes - n := topLevelNodes[0] - topLevelNodes = topLevelNodes[1:] - // add it to the sorted list - sortedIDs = append(sortedIDs, n) - nEdgeList := G.directedEdgeList[n] - - // normally we'd do map iteration, but because we need cross-machine determinism, - // we gather all the nodes M for which there is an edge n -> m, sort that list, - // and then iterate over it. - nodesM := make([]int, 0, len(nEdgeList)) - for m, direction := range nEdgeList { - if direction != 1 { - panic("dag: topological sort correctness error. " + - "Popped node n was expected to have no incoming edges") - } - nodesM = append(nodesM, m) - } - - sort.Ints(nodesM) - - for _, m := range nodesM { - // remove edge from n -> m - G.deleteEdge(n, m) - // if m has no incomingEdges, add to topLevelNodes - if !G.hasIncomingEdge(m) { - topLevelNodes = append(topLevelNodes, m) - } - } - } - - if G.hasEdges() { - fmt.Println(G) - panic("dag: invalid construction, attempted to topologically sort a tree that is not a dag. A cycle exists") - } - - return dag.idsToNames(sortedIDs) -} diff --git a/osmoutils/partialord/internal/dag/dag_test.go b/osmoutils/partialord/internal/dag/dag_test.go deleted file mode 100644 index bae8bd6d1..000000000 --- a/osmoutils/partialord/internal/dag/dag_test.go +++ /dev/null @@ -1,154 +0,0 @@ -package dag_test - -import ( - "testing" - - "github.com/stretchr/testify/require" - - "github.com/CosmosContracts/juno/v15/osmoutils/partialord/internal/dag" -) - -type edge struct { - start, end string -} - -func TestTopologicalSort(t *testing.T) { - // Tests that topological sort works for various inputs. - // We hardcode the satisfying solution in the tests, even though it suffices - // to check that the partial ordering is sufficient. (and thats the only guarantee given externally) - // This is to ensure we catch differences in order between changes, and across machines. - simpleNodes := []string{"dog", "cat", "banana", "apple"} - simpleNodesRev := []string{"apple", "banana", "cat", "dog"} - tests := []struct { - nodes []string - edges []edge - expectedTopologicalOrder []string - }{ - { - // alphabetical ordering of simple nodes - nodes: simpleNodes, - edges: []edge{{"banana", "apple"}, {"cat", "banana"}, {"dog", "cat"}}, - expectedTopologicalOrder: simpleNodes, - }, - { - // apple > dog - nodes: simpleNodes, - edges: []edge{{"apple", "dog"}}, - expectedTopologicalOrder: []string{"cat", "banana", "apple", "dog"}, - }, - { - // apple > everything - nodes: simpleNodes, - edges: []edge{{"apple", "banana"}, {"apple", "cat"}, {"apple", "dog"}}, - expectedTopologicalOrder: []string{"apple", "dog", "cat", "banana"}, - }, - { - // apple > everything, on list with reversed initial order - nodes: simpleNodesRev, - edges: []edge{{"apple", "banana"}, {"apple", "cat"}, {"apple", "dog"}}, - expectedTopologicalOrder: []string{"apple", "banana", "cat", "dog"}, - }, - } - for _, tc := range tests { - dag := dag.NewDAG(tc.nodes) - for _, edge := range tc.edges { - err := dag.AddEdge(edge.start, edge.end) - require.NoError(t, err) - } - order := dag.TopologicalSort() - require.Equal(t, tc.expectedTopologicalOrder, order) - } -} - -func TestAddFirst(t *testing.T) { - simpleNodes := []string{"frog", "elephant", "dog", "cat", "banana", "apple"} - tests := []struct { - nodes []string - first []string - replaceEdges []edge - expectedTopologicalOrder []string - }{ - { - nodes: simpleNodes, - first: []string{"frog"}, - replaceEdges: []edge{{"banana", "apple"}, {"cat", "banana"}, {"dog", "cat"}}, - expectedTopologicalOrder: simpleNodes, - }, - { - nodes: simpleNodes, - first: []string{"elephant"}, - replaceEdges: []edge{{"banana", "apple"}, {"apple", "frog"}, {"dog", "cat"}}, - expectedTopologicalOrder: []string{"elephant", "dog", "banana", "cat", "apple", "frog"}, - }, - { - nodes: simpleNodes, - first: []string{"elephant", "frog"}, - replaceEdges: []edge{}, - expectedTopologicalOrder: []string{"elephant", "frog", "dog", "cat", "banana", "apple"}, - }, - { - // add three items in first, if implemented incorrectly could cause a cycle - nodes: simpleNodes, - first: []string{"dog", "elephant", "frog"}, - replaceEdges: []edge{}, - expectedTopologicalOrder: []string{"dog", "elephant", "frog", "cat", "banana", "apple"}, - }, - } - for _, tc := range tests { - dag := dag.NewDAG(tc.nodes) - dag.AddFirstElements(tc.first...) - for _, edge := range tc.replaceEdges { - err := dag.ReplaceEdge(edge.start, edge.end) - require.NoError(t, err) - } - order := dag.TopologicalSort() - require.Equal(t, tc.expectedTopologicalOrder, order) - } -} - -func TestAddLast(t *testing.T) { - simpleNodes := []string{"frog", "elephant", "dog", "cat", "banana", "apple"} - tests := []struct { - nodes []string - last []string - replaceEdges []edge - expectedTopologicalOrder []string - }{ - { - // causes no order change - nodes: simpleNodes, - last: []string{"apple"}, - replaceEdges: []edge{{"banana", "apple"}, {"cat", "banana"}, {"dog", "cat"}}, - expectedTopologicalOrder: simpleNodes, - }, - { - nodes: simpleNodes, - last: []string{"elephant"}, - replaceEdges: []edge{{"banana", "apple"}, {"apple", "frog"}, {"dog", "cat"}}, - expectedTopologicalOrder: []string{"dog", "banana", "cat", "apple", "frog", "elephant"}, - }, - { - nodes: simpleNodes, - last: []string{"elephant", "frog"}, - replaceEdges: []edge{}, - expectedTopologicalOrder: []string{"dog", "cat", "banana", "apple", "elephant", "frog"}, - }, - { - // add three items in last, if implemented incorrectly could cause a cycle - nodes: simpleNodes, - last: []string{"dog", "elephant", "frog"}, - replaceEdges: []edge{}, - expectedTopologicalOrder: []string{"cat", "banana", "apple", "dog", "elephant", "frog"}, - }, - } - for _, tc := range tests { - dag := dag.NewDAG(tc.nodes) - dag.AddLastElements(tc.last...) - for _, edge := range tc.replaceEdges { - err := dag.ReplaceEdge(edge.start, edge.end) - require.NoError(t, err) - } - order := dag.TopologicalSort() - require.Equal(t, tc.expectedTopologicalOrder, order) - } -} diff --git a/osmoutils/partialord/internal/dag/module.go b/osmoutils/partialord/internal/dag/module.go deleted file mode 100644 index 4b4bcd971..000000000 --- a/osmoutils/partialord/internal/dag/module.go +++ /dev/null @@ -1,9 +0,0 @@ -// Package dag implements a simple Directed Acyclical Graph (DAG) for deterministic topological sorts -// -// It should not be externally exposed, and is intended to be a very simple dag implementation -// utilizing adjacency lists to store edges. -// -// This package is intended to be used for small scales, where performance of the algorithms is not critical. -// (e.g. sub 10k entries) -// Thus none of the algorithms in here are benchmarked, and just have correctness checks. -package dag diff --git a/osmoutils/partialord/module.go b/osmoutils/partialord/module.go deleted file mode 100644 index 1d02c8665..000000000 --- a/osmoutils/partialord/module.go +++ /dev/null @@ -1,2 +0,0 @@ -// package partialord allows one to define partial orderings, and derive a total ordering -package partialord diff --git a/osmoutils/partialord/partialord.go b/osmoutils/partialord/partialord.go deleted file mode 100644 index 1b9a84348..000000000 --- a/osmoutils/partialord/partialord.go +++ /dev/null @@ -1,97 +0,0 @@ -package partialord - -import ( - "sort" - - "github.com/CosmosContracts/juno/v15/osmoutils/partialord/internal/dag" -) - -type PartialOrdering struct { - // underlying dag, the partial ordering is stored via a dag - // https://en.wikipedia.org/wiki/Topological_sorting#Relation_to_partial_orders - dag dag.DAG - // bools for sealing, to prevent repeated invocation of first or last methods. - firstSealed bool - lastSealed bool -} - -// NewPartialOrdering creates a new partial ordering over the set of provided elements. -func NewPartialOrdering(elements []string) PartialOrdering { - elementsCopy := make([]string, len(elements)) - copy(elementsCopy, elements) - sort.Strings(elementsCopy) - return PartialOrdering{ - dag: dag.NewDAG(elementsCopy), - firstSealed: false, - lastSealed: false, - } -} - -func handleDAGErr(err error) { - // all dag errors are logic errors that the intended users of this package should not make. - if err != nil { - panic(err) - } -} - -// After marks that A should come after B -func (ord *PartialOrdering) After(A string, B string) { - // Set that A depends on B / an edge from B -> A - err := ord.dag.AddEdge(B, A) - handleDAGErr(err) -} - -// After marks that A should come before B -func (ord *PartialOrdering) Before(A string, B string) { - // Set that B depends on A / an edge from A -> B - err := ord.dag.AddEdge(A, B) - handleDAGErr(err) -} - -// Sets elems to be the first elements in the ordering. -// So if were making an ordering over {A, B, C, D, E}, and elems provided is {D, B, A} -// then we are guaranteed that the total ordering will begin with {D, B, A} -func (ord *PartialOrdering) FirstElements(elems ...string) { - if ord.firstSealed { - panic("FirstElements has already been called") - } - // We make every node in the dag have a dependency on elems[-1] - // then we change elems[-1] to depend on elems[-2], and so forth. - err := ord.dag.AddFirstElements(elems...) - handleDAGErr(err) - ord.firstSealed = true -} - -// Sets elems to be the last elements in the ordering. -// So if were making an ordering over {A, B, C, D, E}, and elems provided is {D, B, A} -// then we are guaranteed that the total ordering will end with {D, B, A} -func (ord *PartialOrdering) LastElements(elems ...string) { - if ord.lastSealed { - panic("FirstElements has already been called") - } - // We make every node in the dag have a dependency on elems[0] - // then we make elems[1] depend on elems[0], and so forth. - err := ord.dag.AddLastElements(elems...) - handleDAGErr(err) - ord.lastSealed = true -} - -// Sequence sets a sequence of ordering constraints. -// So if were making an ordering over {A, B, C, D, E}, and elems provided is {D, B, A} -// then we are guaranteed that the total ordering will have D comes before B comes before A. -// (They're may be elements interspersed, e.g. {D, C, E, B, A} is a valid ordering) -func (ord *PartialOrdering) Sequence(seq ...string) { - // We make every node in the sequence have a prior node - for i := 0; i < (len(seq) - 1); i++ { - err := ord.dag.AddEdge(seq[i], seq[i+1]) - handleDAGErr(err) - } -} - -// TotalOrdering returns a deterministically chosen total ordering that satisfies all specified -// partial ordering constraints. -// -// Panics if no total ordering exists. -func (ord *PartialOrdering) TotalOrdering() []string { - return ord.dag.TopologicalSort() -} diff --git a/osmoutils/partialord/partialord_test.go b/osmoutils/partialord/partialord_test.go deleted file mode 100644 index 46ff28dfa..000000000 --- a/osmoutils/partialord/partialord_test.go +++ /dev/null @@ -1,74 +0,0 @@ -package partialord_test - -import ( - "testing" - - "github.com/stretchr/testify/require" - - "github.com/CosmosContracts/juno/v15/osmoutils/partialord" -) - -func TestAPI(t *testing.T) { - // begin block use case, we have a dozen modules, but only care about a couple orders. - // In practice this will be gotten from some API, e.g. app.AllModuleNames() - moduleNames := []string{ - "auth", "authz", "bank", "capabilities", - "staking", "distribution", "epochs", "mint", "upgrades", "wasm", "ibc", - "ibctransfers", - } - beginBlockOrd := partialord.NewPartialOrdering(moduleNames) - beginBlockOrd.FirstElements("upgrades", "epochs", "capabilities") - beginBlockOrd.After("ibctransfers", "ibc") - beginBlockOrd.Before("mint", "distribution") - // This is purely just to test last functionality, doesn't make sense in context - beginBlockOrd.LastElements("auth", "authz", "wasm") - - totalOrd := beginBlockOrd.TotalOrdering() - expTotalOrd := []string{ - "upgrades", "epochs", "capabilities", - "bank", "ibc", "mint", "staking", "ibctransfers", "distribution", - "auth", "authz", "wasm", - } - require.Equal(t, expTotalOrd, totalOrd) -} - -func TestNonStandardAPIOrder(t *testing.T) { - // This test uses direct ordering before First, and after Last - names := []string{"A", "B", "C", "D", "E", "F", "G"} - ord := partialord.NewPartialOrdering(names) - ord.After("A", "C") - ord.After("A", "D") - ord.After("E", "B") - // overrides the "A" after "C" & "A" after "D" constraints - ord.FirstElements("A", "B", "C") - expOrdering := []string{"A", "B", "C", "D", "E", "F", "G"} - require.Equal(t, expOrdering, ord.TotalOrdering()) - - ord.After("E", "D") - expOrdering = []string{"A", "B", "C", "D", "F", "G", "E"} - require.Equal(t, expOrdering, ord.TotalOrdering()) - - ord.LastElements("G") - ord.After("F", "E") - expOrdering = []string{"A", "B", "C", "D", "E", "F", "G"} - require.Equal(t, expOrdering, ord.TotalOrdering()) -} - -// This test ad-hocly tests combination of multiple sequences, first elements, and an After -// invokation. -func TestSequence(t *testing.T) { - // This test uses direct ordering before First, and after Last - names := []string{"A", "B", "C", "D", "E", "F", "G"} - ord := partialord.NewPartialOrdering(names) - // Make B A C a sequence - ord.Sequence("B", "A", "C") - // Make A G E a sub-sequence - ord.Sequence("A", "G", "E") - // make first elements D B F - ord.FirstElements("D", "B", "F") - // make C come after E - ord.After("C", "G") - - expOrdering := []string{"D", "B", "F", "A", "G", "C", "E"} - require.Equal(t, expOrdering, ord.TotalOrdering()) -} diff --git a/osmoutils/slice_helper.go b/osmoutils/slice_helper.go deleted file mode 100644 index 6263794c3..000000000 --- a/osmoutils/slice_helper.go +++ /dev/null @@ -1,94 +0,0 @@ -package osmoutils - -import ( - "reflect" - "sort" - - "golang.org/x/exp/constraints" -) - -// SortSlice sorts a slice of type T elements that implement constraints.Ordered. -// Mutates input slice s -func SortSlice[T constraints.Ordered](s []T) { - sort.Slice(s, func(i, j int) bool { - return s[i] < s[j] - }) -} - -func Filter[T interface{}](filter func(T) bool, s []T) []T { - filteredSlice := []T{} - for _, s := range s { - if filter(s) { - filteredSlice = append(filteredSlice, s) - } - } - return filteredSlice -} - -// ReverseSlice reverses the input slice in place. -// Does mutate argument. -func ReverseSlice[T any](s []T) []T { - maxIndex := len(s) - for i := 0; i < maxIndex/2; i++ { - temp := s[i] - s[i] = s[maxIndex-i-1] - s[maxIndex-1-i] = temp - } - return s -} - -// ContainsDuplicate checks if there are any duplicate -// elements in the slice. -func ContainsDuplicate[T any](arr []T) bool { - visited := make(map[any]bool, 0) - for i := 0; i < len(arr); i++ { - if visited[arr[i]] { - return true - } else { - visited[arr[i]] = true - } - } - return false -} - -// ContainsDuplicateDeepEqual returns true if there are duplicates -// in the slice by performing deep comparison. This is useful -// for comparing matrices or slices of pointers. -// Returns false if there are no deep equal duplicates. -func ContainsDuplicateDeepEqual[T any](multihops []T) bool { - for i := 0; i < len(multihops)-1; i++ { - if reflect.DeepEqual(multihops[i], multihops[i+1]) { - return true - } - } - return false -} - -type LessFunc[T any] func(a, b T) bool - -// MergeSlices efficiently merges two sorted slices into a single sorted slice. -// The resulting slice contains all elements from slice1 and slice2, sorted according to the less function. -// The input slices must be sorted in ascending order according to the less function. -// The less function takes two elements of type T and returns a boolean value indicating whether the first element is less than the second element. -// The function returns a new slice containing all elements from slice1 and slice2, sorted according to the less function. -// The function does not modify the input slices. -func MergeSlices[T any](slice1, slice2 []T, less LessFunc[T]) []T { - result := make([]T, 0, len(slice1)+len(slice2)) - i, j := 0, 0 - - for i < len(slice1) && j < len(slice2) { - if less(slice1[i], slice2[j]) { - result = append(result, slice1[i]) - i++ - } else { - result = append(result, slice2[j]) - j++ - } - } - - // Append any remaining elements from slice1 and slice2 - result = append(result, slice1[i:]...) - result = append(result, slice2[j:]...) - - return result -} diff --git a/osmoutils/slice_helper_test.go b/osmoutils/slice_helper_test.go deleted file mode 100644 index 72321b334..000000000 --- a/osmoutils/slice_helper_test.go +++ /dev/null @@ -1,93 +0,0 @@ -package osmoutils_test - -import ( - "reflect" - "testing" - - "github.com/stretchr/testify/require" - - "github.com/CosmosContracts/juno/v15/osmoutils" -) - -func TestReverseSlice(t *testing.T) { - tests := map[string]struct { - s []string - - expectedSolvedInput []string - }{ - "Even length array": {s: []string{"a", "b", "c", "d"}, expectedSolvedInput: []string{"d", "c", "b", "a"}}, - "Empty array": {s: []string{}, expectedSolvedInput: []string{}}, - "Odd length array": {s: []string{"a", "b", "c"}, expectedSolvedInput: []string{"c", "b", "a"}}, - "Single element array": {s: []string{"a"}, expectedSolvedInput: []string{"a"}}, - "Array with empty string": {s: []string{"a", "b", "c", "", "d"}, expectedSolvedInput: []string{"d", "", "c", "b", "a"}}, - "Array with numbers": {s: []string{"a", "b", "c", "1", "2", "3"}, expectedSolvedInput: []string{"3", "2", "1", "c", "b", "a"}}, - } - for name, tc := range tests { - t.Run(name, func(t *testing.T) { - actualSolvedInput := osmoutils.ReverseSlice(tc.s) - require.Equal(t, tc.expectedSolvedInput, actualSolvedInput) - }) - } -} - -func TestMergeSlices(t *testing.T) { - lessInt := func(a, b int) bool { - return a < b - } - testCases := []struct { - name string - slice1 []int - slice2 []int - less func(a, b int) bool - want []int - }{ - { - name: "basic merge", - slice1: []int{1, 3, 5}, - slice2: []int{2, 4, 6}, - less: lessInt, - want: []int{1, 2, 3, 4, 5, 6}, - }, - { - name: "Empty slice1", - slice1: []int{}, - slice2: []int{2, 4, 6}, - less: lessInt, - want: []int{2, 4, 6}, - }, - { - name: "Empty slice2", - slice1: []int{1, 3, 5}, - slice2: []int{}, - less: lessInt, - want: []int{1, 3, 5}, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - got := osmoutils.MergeSlices(tc.slice1, tc.slice2, lessInt) - if !reflect.DeepEqual(got, tc.want) { - t.Errorf("got: %v, want: %v", got, tc.want) - } - }) - } -} - -func TestContainsDuplicateDeepEqual(t *testing.T) { - tests := []struct { - input []interface{} - want bool - }{ - {[]interface{}{[]int{1, 2, 3}, []int{4, 5, 6}}, false}, - {[]interface{}{[]int{1, 2, 3}, []int{1, 2, 3}}, true}, - {[]interface{}{[]string{"hello", "world"}, []string{"goodbye", "world"}}, false}, - {[]interface{}{[]string{"hello", "world"}, []string{"hello", "world"}}, true}, - {[]interface{}{[][]int{{1, 2}, {3, 4}}, [][]int{{1, 2}, {3, 4}}}, true}, - } - - for _, tt := range tests { - got := osmoutils.ContainsDuplicateDeepEqual(tt.input) - require.Equal(t, tt.want, got) - } -} diff --git a/osmoutils/store_helper.go b/osmoutils/store_helper.go deleted file mode 100644 index 2205afa6a..000000000 --- a/osmoutils/store_helper.go +++ /dev/null @@ -1,194 +0,0 @@ -package osmoutils - -import ( - "errors" - "fmt" - - db "github.com/cometbft/cometbft-db" - sdk "github.com/cosmos/cosmos-sdk/types" - - "github.com/cosmos/cosmos-sdk/store" - "github.com/gogo/protobuf/proto" -) - -var ( - ErrNoValuesInRange = errors.New("No values in range") -) - -func GatherAllKeysFromStore(storeObj store.KVStore) []string { - iterator := storeObj.Iterator(nil, nil) - defer iterator.Close() - - keys := []string{} - for ; iterator.Valid(); iterator.Next() { - keys = append(keys, string(iterator.Key())) - } - return keys -} - -func GatherValuesFromStore[T any](storeObj store.KVStore, keyStart []byte, keyEnd []byte, parseValue func([]byte) (T, error)) ([]T, error) { - iterator := storeObj.Iterator(keyStart, keyEnd) - defer iterator.Close() - return gatherValuesFromIterator(iterator, parseValue, noStopFn) -} - -// GatherValuesFromStorePrefix is a decorator around GatherValuesFromStorePrefixWithKeyParser. It overwrites the parse function to -// disable parsing keys, only keeping values -func GatherValuesFromStorePrefix[T any](storeObj store.KVStore, prefix []byte, parseValue func([]byte) (T, error)) ([]T, error) { - // Replace a callback with the one that takes both key and value - // but ignores the key. - parseOnlyValue := func(_ []byte, value []byte) (T, error) { - return parseValue(value) - } - return GatherValuesFromStorePrefixWithKeyParser(storeObj, prefix, parseOnlyValue) -} - -// GatherValuesFromStorePrefixWithKeyParser is a helper function that gathers values from a given store prefix. While iterating through -// the entries, it parses both key and the value using the provided parse function to return the desired type. -// Returns error if: -// - the parse function returns an error. -// - internal database error -func GatherValuesFromStorePrefixWithKeyParser[T any](storeObj store.KVStore, prefix []byte, parse func(key []byte, value []byte) (T, error)) ([]T, error) { - iterator := sdk.KVStorePrefixIterator(storeObj, prefix) - defer iterator.Close() - return gatherValuesFromIteratorWithKeyParser(iterator, parse, noStopFn) -} - -func GetValuesUntilDerivedStop[T any](storeObj store.KVStore, keyStart []byte, stopFn func([]byte) bool, parseValue func([]byte) (T, error)) ([]T, error) { - // SDK iterator is broken for nil end time, and non-nil start time - // https://github.com/cosmos/cosmos-sdk/issues/12661 - // hence we use []byte{0xff} - keyEnd := []byte{0xff} - return GetIterValuesWithStop(storeObj, keyStart, keyEnd, false, stopFn, parseValue) -} - -func makeIterator(storeObj store.KVStore, keyStart []byte, keyEnd []byte, reverse bool) store.Iterator { - if reverse { - return storeObj.ReverseIterator(keyStart, keyEnd) - } - return storeObj.Iterator(keyStart, keyEnd) -} - -func GetIterValuesWithStop[T any]( - storeObj store.KVStore, - keyStart []byte, - keyEnd []byte, - reverse bool, - stopFn func([]byte) bool, - parseValue func([]byte) (T, error), -) ([]T, error) { - iter := makeIterator(storeObj, keyStart, keyEnd, reverse) - defer iter.Close() - - return gatherValuesFromIterator(iter, parseValue, stopFn) -} - -// HasAnyAtPrefix returns true if there is at least one value in the given prefix. -func HasAnyAtPrefix[T any](storeObj store.KVStore, prefix []byte, parseValue func([]byte) (T, error)) (bool, error) { - _, err := GetFirstValueInRange(storeObj, prefix, sdk.PrefixEndBytes(prefix), false, parseValue) - if err != nil { - if err == ErrNoValuesInRange { - return false, nil - } - return false, err - } - - return true, nil -} - -func GetFirstValueAfterPrefixInclusive[T any](storeObj store.KVStore, keyStart []byte, parseValue func([]byte) (T, error)) (T, error) { - // SDK iterator is broken for nil end time, and non-nil start time - // https://github.com/cosmos/cosmos-sdk/issues/12661 - // hence we use []byte{0xff} - return GetFirstValueInRange(storeObj, keyStart, []byte{0xff}, false, parseValue) -} - -func GetFirstValueInRange[T any](storeObj store.KVStore, keyStart []byte, keyEnd []byte, reverseIterate bool, parseValue func([]byte) (T, error)) (T, error) { - iterator := makeIterator(storeObj, keyStart, keyEnd, reverseIterate) - defer iterator.Close() - - if !iterator.Valid() { - var blankValue T - return blankValue, ErrNoValuesInRange - } - - return parseValue(iterator.Value()) -} - -func gatherValuesFromIterator[T any](iterator db.Iterator, parseValue func([]byte) (T, error), stopFn func([]byte) bool) ([]T, error) { - // Replace a callback with the one that takes both key and value - // but ignores the key. - parseKeyValue := func(_ []byte, value []byte) (T, error) { - return parseValue(value) - } - return gatherValuesFromIteratorWithKeyParser(iterator, parseKeyValue, stopFn) -} - -func gatherValuesFromIteratorWithKeyParser[T any](iterator db.Iterator, parse func(key []byte, value []byte) (T, error), stopFn func([]byte) bool) ([]T, error) { - values := []T{} - for ; iterator.Valid(); iterator.Next() { - if stopFn(iterator.Key()) { - break - } - val, err := parse(iterator.Key(), iterator.Value()) - if err != nil { - return nil, err - } - values = append(values, val) - } - return values, nil -} - -func noStopFn([]byte) bool { - return false -} - -// MustSet runs store.Set(key, proto.Marshal(value)) -// but panics on any error. -func MustSet(storeObj store.KVStore, key []byte, value proto.Message) { - bz, err := proto.Marshal(value) - if err != nil { - panic(err) - } - - storeObj.Set(key, bz) -} - -// MustGet gets key from store by mutating result -// Panics on any error. -func MustGet(store store.KVStore, key []byte, result proto.Message) { - b := store.Get(key) - if b == nil { - panic(fmt.Errorf("getting at key (%v) should not have been nil", key)) - } - if err := proto.Unmarshal(b, result); err != nil { - panic(err) - } -} - -// MustSetDec sets dec value to store at key. Panics on any error. -func MustSetDec(store store.KVStore, key []byte, value sdk.Dec) { - MustSet(store, key, &sdk.DecProto{ - Dec: value, - }) -} - -// MustGetDec gets dec value from store at key. Panics on any error. -func MustGetDec(store store.KVStore, key []byte) sdk.Dec { - result := &sdk.DecProto{} - MustGet(store, key, result) - return result.Dec -} - -// Get returns a value at key by mutating the result parameter. Returns true if the value was found and the -// result mutated correctly. If the value is not in the store, returns false. Returns error only when database or serialization errors occur. (And when an error occurs, returns false) -func Get(store store.KVStore, key []byte, result proto.Message) (found bool, err error) { - b := store.Get(key) - if b == nil { - return false, nil - } - if err := proto.Unmarshal(b, result); err != nil { - return true, err - } - return true, nil -} diff --git a/osmoutils/store_helper_test.go b/osmoutils/store_helper_test.go deleted file mode 100644 index be6607ff6..000000000 --- a/osmoutils/store_helper_test.go +++ /dev/null @@ -1,1246 +0,0 @@ -package osmoutils_test - -import ( - "errors" - "fmt" - "testing" - - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/gogo/protobuf/proto" - "github.com/stretchr/testify/suite" - - "github.com/cosmos/cosmos-sdk/x/auth" - authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" - "github.com/cosmos/cosmos-sdk/x/params" - paramskeeper "github.com/cosmos/cosmos-sdk/x/params/keeper" - paramstypes "github.com/cosmos/cosmos-sdk/x/params/types" - - "github.com/CosmosContracts/juno/v15/osmoutils" - "github.com/CosmosContracts/juno/v15/osmoutils/noapptest" - "github.com/CosmosContracts/juno/v15/osmoutils/osmoassert" - storetypes "github.com/cosmos/cosmos-sdk/store/types" -) - -// We need to setup a test suite with account keeper -// and a custom store setup. -// unfortunately setting up account implies setting up params -type TestSuite struct { - suite.Suite - - ctx sdk.Context - store sdk.KVStore - - authStoreKey storetypes.StoreKey - accountKeeper authkeeper.AccountKeeperI -} - -func (suite *TestSuite) SetupTest() { - // For the test suite, we manually wire a custom store "customStoreKey" - // Auth module (for module_account_test.go) which requires params module as well. - customStoreKey := sdk.NewKVStoreKey("osmoutil_store_test") - suite.authStoreKey = sdk.NewKVStoreKey(authtypes.StoreKey) - // setup ctx + stores - paramsKey := sdk.NewKVStoreKey(paramstypes.StoreKey) - paramsTKey := sdk.NewKVStoreKey(paramstypes.TStoreKey) - suite.ctx = noapptest.DefaultCtxWithStoreKeys( - []storetypes.StoreKey{customStoreKey, suite.authStoreKey, paramsKey, paramsTKey}) - suite.store = suite.ctx.KVStore(customStoreKey) - // setup params (needed for auth) - encConfig := noapptest.MakeTestEncodingConfig(auth.AppModuleBasic{}, params.AppModuleBasic{}) - paramsKeeper := paramskeeper.NewKeeper(encConfig.Codec, encConfig.Amino, paramsKey, paramsTKey) - paramsKeeper.Subspace(authtypes.ModuleName) - - // setup auth - maccPerms := map[string][]string{ - "fee_collector": nil, - "mint": {"minter"}, - } - authsubspace, _ := paramsKeeper.GetSubspace(authtypes.ModuleName) - suite.accountKeeper = authkeeper.NewAccountKeeper( - encConfig.Codec, - suite.authStoreKey, - authsubspace, - authtypes.ProtoBaseAccount, maccPerms) -} - -const ( - keyA = "a" - keyB = "b" - keyC = "c" - mockStopValue = "stop" - afterMockStopValue = mockStopValue + keyA - basePrefix = "base" - prefixOne = "one" - prefixTwo = "two" -) - -var ( - oneA = []string{prefixOne + keyA} - oneAB = []string{prefixOne + keyA, prefixOne + keyB} - twoAB = []string{prefixTwo + keyA, prefixTwo + keyB} - oneABC = []string{prefixOne + keyA, prefixOne + keyB, prefixOne + keyC} - oneBCA = []string{prefixOne + keyB, prefixOne + keyC, prefixOne + keyA} - oneABtwoAB = []string{prefixOne + keyA, prefixOne + keyB, prefixTwo + keyA, prefixTwo + keyB} - oneBtwoAoneAtwoB = []string{prefixOne + keyB, prefixTwo + keyA, prefixOne + keyA, prefixTwo + keyB} - oneAtwoAoneBtwoB = []string{prefixOne + keyA, prefixTwo + keyA, prefixOne + keyB, prefixTwo + keyB} - onetwoABCalternating = []string{prefixOne + keyA, prefixTwo + keyA, prefixOne + keyB, prefixTwo + keyB, prefixOne + keyC, prefixTwo + keyC} - mockError = errors.New("mock error") -) - -func TestOsmoUtilsTestSuite(t *testing.T) { - suite.Run(t, new(TestSuite)) -} - -func mockParseValue(b []byte) (string, error) { - return string(b), nil -} - -func mockParseValueWithError(b []byte) (string, error) { - return "", mockError -} - -func mockStop(b []byte) bool { - return string(b) == fmt.Sprintf("%s%s", prefixOne, mockStopValue) -} - -func mockParseWithKey(key []byte, value []byte) (string, error) { - return string(key) + string(value), nil -} - -func mockParseWithKeyError(key []byte, value []byte) (string, error) { - return "", mockError -} - -func (s *TestSuite) TestGatherAllKeysFromStore() { - testcases := map[string]struct { - preSetKeys []string - expectedValues []string - }{ - "multiple keys in lexicographic order": { - preSetKeys: oneABC, - expectedValues: oneABC, - }, - "multiple keys out of lexicographic order": { - preSetKeys: oneBCA, - // we expect output to be in ascending lexicographic order - expectedValues: oneABC, - }, - "no keys": { - preSetKeys: []string{}, - expectedValues: []string{}, - }, - } - - for name, tc := range testcases { - s.Run(name, func() { - s.SetupTest() - for i, key := range tc.preSetKeys { - s.store.Set([]byte(key), []byte(fmt.Sprintf("%v", i))) - } - - actualValues := osmoutils.GatherAllKeysFromStore(s.store) - - s.Require().Equal(tc.expectedValues, actualValues) - }) - } -} - -func (s *TestSuite) TestGatherValuesFromStore() { - testcases := map[string]struct { - preSetKeys []string - keyStart []byte - keyEnd []byte - parseFn func(b []byte) (string, error) - - expectedErr error - expectedValues []string - }{ - "common prefix, exclude end": { - preSetKeys: oneAB, - - keyStart: []byte(prefixOne + keyA), - keyEnd: []byte(prefixOne + keyB), - parseFn: mockParseValue, - - expectedValues: []string{"0"}, - }, - "common prefix, include end": { - preSetKeys: oneAB, - - keyStart: []byte(prefixOne + keyA), - keyEnd: []byte(prefixOne + keyC), - parseFn: mockParseValue, - - expectedValues: []string{"0", "1"}, - }, - "different prefix, inserted in lexicographic order": { - preSetKeys: oneABtwoAB, - - keyStart: []byte(prefixOne + keyA), - keyEnd: []byte(prefixTwo + keyA), - parseFn: mockParseValue, - - expectedValues: []string{"0", "1"}, - }, - "different prefix, inserted out of lexicographic order": { - preSetKeys: oneAtwoAoneBtwoB, - - keyStart: []byte(prefixOne + keyA), - keyEnd: []byte(prefixTwo + keyA), - parseFn: mockParseValue, - - // should get all prefixOne values as keys are stored in ascending lexicographic order - expectedValues: []string{"0", "2"}, - }, - "start key and end key same": { - preSetKeys: oneA, - - keyStart: []byte(prefixOne + keyA), - keyEnd: []byte(prefixOne + keyA), - parseFn: mockParseValue, - - expectedValues: []string{}, - }, - "start key after end key": { - preSetKeys: oneABC, - - keyStart: []byte(prefixOne + keyB), - keyEnd: []byte(prefixOne + keyA), - parseFn: mockParseValue, - - expectedValues: []string{}, - }, - "get all values": { - preSetKeys: oneABC, - - keyStart: nil, - keyEnd: nil, - parseFn: mockParseValue, - - expectedValues: []string{"0", "1", "2"}, - }, - "get all values after start key": { - // SDK iterator is broken for nil end byte, and non-nil start byte - // https://github.com/cosmos/cosmos-sdk/issues/12661 - // so we use []byte{0xff} - preSetKeys: oneABC, - - keyStart: []byte(prefixOne + keyB), - keyEnd: []byte{0xff}, - parseFn: mockParseValue, - - expectedValues: []string{"1", "2"}, - }, - "parse with error": { - preSetKeys: oneABC, - - keyStart: []byte(prefixOne + keyA), - keyEnd: []byte(prefixOne + keyC), - parseFn: mockParseValueWithError, - - expectedErr: mockError, - }, - } - - for name, tc := range testcases { - s.Run(name, func() { - s.SetupTest() - - for i, key := range tc.preSetKeys { - s.store.Set([]byte(key), []byte(fmt.Sprintf("%v", i))) - } - - actualValues, err := osmoutils.GatherValuesFromStore(s.store, tc.keyStart, tc.keyEnd, tc.parseFn) - - if tc.expectedErr != nil { - s.Require().ErrorContains(err, tc.expectedErr.Error()) - s.Require().Nil(actualValues) - return - } - - s.Require().NoError(err) - s.Require().Equal(tc.expectedValues, actualValues) - }) - } -} - -func (s *TestSuite) TestGatherValuesFromStorePrefix() { - testcases := map[string]struct { - prefix []byte - preSetKeys []string - parseFn func(b []byte) (string, error) - - expectedErr error - expectedValues []string - }{ - "common prefix": { - preSetKeys: oneABC, - prefix: []byte(prefixOne), - - parseFn: mockParseValue, - - expectedValues: []string{"0", "1", "2"}, - }, - "different prefixes in order, prefix one requested": { - preSetKeys: oneABtwoAB, - prefix: []byte(prefixOne), - parseFn: mockParseValue, - - expectedValues: []string{"0", "1"}, - }, - "different prefixes in order, prefix two requested": { - preSetKeys: oneABtwoAB, - prefix: []byte(prefixTwo), - parseFn: mockParseValue, - - expectedValues: []string{"2", "3"}, - }, - "different prefixes out of order, prefix one requested": { - preSetKeys: oneBtwoAoneAtwoB, - prefix: []byte(prefixOne), - parseFn: mockParseValue, - - // we expect the prefixOne values in ascending lexicographic order - expectedValues: []string{"2", "0"}, - }, - "different prefixes out of order, prefix two requested": { - preSetKeys: oneBtwoAoneAtwoB, - prefix: []byte(prefixTwo), - parseFn: mockParseValue, - - expectedValues: []string{"1", "3"}, - }, - "prefix doesn't exist, no keys": { - preSetKeys: []string{}, - prefix: []byte(prefixOne), - parseFn: mockParseValue, - - expectedValues: []string{}, - }, - "prefix doesn't exist, only keys with another prefix": { - preSetKeys: twoAB, - prefix: []byte(prefixOne), - parseFn: mockParseValue, - - expectedValues: []string{}, - }, - "parse with error": { - preSetKeys: oneABC, - prefix: []byte(prefixOne), - parseFn: mockParseValueWithError, - - expectedErr: mockError, - }, - } - - for name, tc := range testcases { - s.Run(name, func() { - s.SetupTest() - for i, key := range tc.preSetKeys { - s.store.Set([]byte(key), []byte(fmt.Sprintf("%v", i))) - } - - actualValues, err := osmoutils.GatherValuesFromStorePrefix(s.store, tc.prefix, tc.parseFn) - - if tc.expectedErr != nil { - s.Require().ErrorContains(err, tc.expectedErr.Error()) - s.Require().Nil(actualValues) - return - } - - s.Require().NoError(err) - s.Require().Equal(tc.expectedValues, actualValues) - }) - } -} - -func (s *TestSuite) TestGatherValuesFromStorePrefixWithKeyParser() { - testcases := map[string]struct { - prefix []byte - preSetKeys []string - parseFn func(key []byte, value []byte) (string, error) - - expectedErr error - expectedValues []string - }{ - "common prefix": { - preSetKeys: oneABC, - prefix: []byte(prefixOne), - - parseFn: mockParseWithKey, - - expectedValues: []string{oneABC[0] + "0", oneABC[1] + "1", oneABC[2] + "2"}, - }, - "different prefixes in order, prefix one requested": { - preSetKeys: oneABtwoAB, - prefix: []byte(prefixOne), - parseFn: mockParseWithKey, - - expectedValues: []string{oneABtwoAB[0] + "0", oneABtwoAB[1] + "1"}, - }, - "different prefixes in order, prefix two requested": { - preSetKeys: oneABtwoAB, - prefix: []byte(prefixTwo), - parseFn: mockParseWithKey, - - expectedValues: []string{oneABtwoAB[2] + "2", oneABtwoAB[3] + "3"}, - }, - "different prefixes out of order, prefix one requested": { - preSetKeys: oneBtwoAoneAtwoB, - prefix: []byte(prefixOne), - parseFn: mockParseWithKey, - - // we expect the prefixOne values in ascending lexicographic order - expectedValues: []string{oneBtwoAoneAtwoB[2] + "2", oneBtwoAoneAtwoB[0] + "0"}, - }, - "different prefixes out of order, prefix two requested": { - preSetKeys: oneBtwoAoneAtwoB, - prefix: []byte(prefixTwo), - parseFn: mockParseWithKey, - - expectedValues: []string{oneBtwoAoneAtwoB[1] + "1", oneBtwoAoneAtwoB[3] + "3"}, - }, - "prefix doesn't exist, no keys": { - preSetKeys: []string{}, - prefix: []byte(prefixOne), - parseFn: mockParseWithKey, - - expectedValues: []string{}, - }, - "prefix doesn't exist, only keys with another prefix": { - preSetKeys: twoAB, - prefix: []byte(prefixOne), - parseFn: mockParseWithKey, - - expectedValues: []string{}, - }, - "parse with error": { - preSetKeys: oneABC, - prefix: []byte(prefixOne), - parseFn: mockParseWithKeyError, - - expectedErr: mockError, - }, - } - - for name, tc := range testcases { - s.Run(name, func() { - s.SetupTest() - for i, key := range tc.preSetKeys { - s.store.Set([]byte(key), []byte(fmt.Sprintf("%v", i))) - } - - actualValues, err := osmoutils.GatherValuesFromStorePrefixWithKeyParser(s.store, tc.prefix, tc.parseFn) - - if tc.expectedErr != nil { - s.Require().ErrorContains(err, tc.expectedErr.Error()) - s.Require().Nil(actualValues) - return - } - - s.Require().NoError(err) - s.Require().Equal(tc.expectedValues, actualValues) - }) - } -} - -func (s *TestSuite) TestGetFirstValueAfterPrefixInclusive() { - testcases := map[string]struct { - prefix []byte - preSetKeys []string - parseFn func(b []byte) (string, error) - - expectedErr error - expectedValues string - }{ - "common prefix": { - preSetKeys: oneABC, - prefix: []byte(prefixOne), - - parseFn: mockParseValue, - - expectedValues: "0", - }, - "different prefixes in order, prefix one requested": { - preSetKeys: oneABtwoAB, - prefix: []byte(prefixOne), - parseFn: mockParseValue, - - expectedValues: "0", - }, - "different prefixes in order, prefix two requested": { - preSetKeys: oneABtwoAB, - prefix: []byte(prefixTwo), - parseFn: mockParseValue, - - expectedValues: "2", - }, - "different prefixes out of order, prefix one requested": { - preSetKeys: oneBtwoAoneAtwoB, - prefix: []byte(prefixOne), - parseFn: mockParseValue, - - // we expect the prefixOne values in ascending lexicographic order - expectedValues: "2", - }, - "different prefixes out of order, prefix two requested": { - preSetKeys: oneBtwoAoneAtwoB, - prefix: []byte(prefixTwo), - parseFn: mockParseValue, - - expectedValues: "1", - }, - "prefix doesn't exist, start key lexicographically before existing keys": { - preSetKeys: twoAB, - prefix: []byte(prefixOne), - parseFn: mockParseValue, - - // we expect the first value after the prefix, which is the value associated with the first valid key - expectedValues: "0", - }, - - // error catching - "prefix doesn't exist, no keys": { - preSetKeys: []string{}, - prefix: []byte(prefixOne), - parseFn: mockParseValue, - - expectedErr: errors.New("No values in range"), - expectedValues: "", - }, - "prefix doesn't exist, start key lexicographically after existing keys": { - preSetKeys: twoAB, - prefix: []byte{0xff}, - parseFn: mockParseValue, - - expectedErr: errors.New("No values in range"), - expectedValues: "", - }, - "parse with error": { - preSetKeys: oneABC, - prefix: []byte(prefixOne), - parseFn: mockParseValueWithError, - - expectedErr: mockError, - expectedValues: "", - }, - } - - for name, tc := range testcases { - s.Run(name, func() { - s.SetupTest() - for i, key := range tc.preSetKeys { - s.store.Set([]byte(key), []byte(fmt.Sprintf("%v", i))) - } - - actualValues, err := osmoutils.GetFirstValueAfterPrefixInclusive(s.store, tc.prefix, tc.parseFn) - - if tc.expectedErr != nil { - s.Require().ErrorContains(err, tc.expectedErr.Error()) - s.Require().Equal(tc.expectedValues, actualValues) - return - } - - s.Require().NoError(err) - s.Require().Equal(tc.expectedValues, actualValues) - }) - } -} - -func (s *TestSuite) TestGatherValuesFromIterator() { - testcases := map[string]struct { - // if prefix is set, startValue and endValue are ignored. - // we either create an iterator prefix or a range iterator. - prefix string - startValue string - endValue string - preSetKeys []string - isReverse bool - - expectedValues []string - expectedErr error - }{ - "prefix iterator, no stop": { - preSetKeys: oneABC, - - prefix: prefixOne, - - expectedValues: []string{"0", "1", "2"}, - }, - "prefix iterator, with stop": { - preSetKeys: []string{prefixOne + keyA, prefixOne + mockStopValue, prefixOne + mockStopValue + keyA}, - prefix: prefixOne, - - expectedValues: []string{"0"}, - }, - "prefix iterator, with stop, different insertion order": { - // keyB is lexicographically before mockStopValue so it is returned, but before c - preSetKeys: []string{prefixOne + keyA, prefixOne + mockStopValue, prefixOne + keyB, prefixOne + mockStopValue + keyA}, - prefix: prefixOne, - - expectedValues: []string{"0", "2"}, - }, - "range iterator, no end, no stop": { - preSetKeys: oneABC, - - startValue: prefixOne + keyB, - - expectedValues: []string{"1", "2"}, - }, - "range iterator, no start, no stop": { - preSetKeys: oneABC, - - endValue: prefixOne + keyB, - - expectedValues: []string{"0"}, - }, - "range iterator, no start no end, no stop": { - preSetKeys: oneABC, - expectedValues: []string{"0", "1", "2"}, - }, - "range iterator, with stop": { - preSetKeys: []string{prefixOne + keyA, prefixOne + mockStopValue, prefixOne + afterMockStopValue}, - - expectedValues: []string{"0"}, - }, - "range iterator, reverse": { - preSetKeys: oneABC, - isReverse: true, - - expectedValues: []string{"2", "1", "0"}, - }, - "range iterator, other prefix is excluded with end value": { - preSetKeys: onetwoABCalternating, - startValue: prefixOne + keyB, - endValue: prefixOne + "d", - isReverse: true, - - expectedValues: []string{"4", "2"}, - }, - "parse with error": { - preSetKeys: oneABC, - - prefix: prefixOne, - - expectedErr: mockError, - }, - } - - for name, tc := range testcases { - s.Run(name, func() { - s.SetupTest() - var iterator sdk.Iterator - - for i, key := range tc.preSetKeys { - s.store.Set([]byte(key), []byte(fmt.Sprintf("%v", i))) - } - - if tc.prefix != "" { - iterator = sdk.KVStorePrefixIterator(s.store, []byte(tc.prefix)) - } else { - var startValue, endValue []byte - if tc.startValue != "" { - startValue = []byte(tc.startValue) - } - if tc.endValue != "" { - endValue = []byte(tc.endValue) - } - - if tc.isReverse { - iterator = s.store.ReverseIterator(startValue, endValue) - } else { - iterator = s.store.Iterator(startValue, endValue) - } - defer iterator.Close() - } - - mockParseValueFn := mockParseValue - if tc.expectedErr != nil { - mockParseValueFn = mockParseValueWithError - } - - actualValues, err := osmoutils.GatherValuesFromIterator(iterator, mockParseValueFn, mockStop) - - if tc.expectedErr != nil { - s.Require().ErrorContains(err, tc.expectedErr.Error()) - s.Require().Nil(actualValues) - return - } - - s.Require().NoError(err) - - s.Require().Equal(tc.expectedValues, actualValues) - }) - } -} - -func (s *TestSuite) TestGetIterValuesWithStop() { - testcases := map[string]struct { - preSetKeys []string - keyStart []byte - keyEnd []byte - parseFn func(b []byte) (string, error) - stopFn func(b []byte) bool - isReverse bool - - expectedValues []string - expectedErr error - }{ - "prefix iterator, no stop but exclusive key end": { - preSetKeys: oneABC, - keyStart: []byte(prefixOne + keyA), - keyEnd: []byte(prefixOne + keyC), - parseFn: mockParseValue, - stopFn: mockStop, - isReverse: false, - - expectedValues: []string{"0", "1"}, - }, - "prefix iterator, no stop and inclusive key end": { - preSetKeys: oneAB, - keyStart: []byte(prefixOne + keyA), - keyEnd: []byte(prefixOne + keyC), - parseFn: mockParseValue, - stopFn: mockStop, - isReverse: false, - - expectedValues: []string{"0", "1"}, - }, - "prefix iterator, with stop before end key": { - preSetKeys: []string{prefixOne + keyA, prefixOne + mockStopValue, prefixOne + mockStopValue + keyA}, - keyStart: []byte(prefixOne + keyA), - keyEnd: []byte(prefixOne + keyC), - parseFn: mockParseValue, - stopFn: mockStop, - isReverse: false, - - expectedValues: []string{"0"}, - }, - "prefix iterator, with end key before stop": { - preSetKeys: []string{prefixOne + keyA, prefixOne + keyB, prefixOne + mockStopValue}, - keyStart: []byte(prefixOne + keyA), - keyEnd: []byte(prefixOne + keyB), - parseFn: mockParseValue, - stopFn: mockStop, - isReverse: false, - - expectedValues: []string{"0"}, - }, - "prefix iterator, with stop, different insertion order": { - // keyB is lexicographically before mockStopValue so we expect it to be returned before we hit the stopper - preSetKeys: []string{prefixOne + keyA, prefixOne + mockStopValue, prefixOne + keyB, prefixOne + mockStopValue + keyA}, - keyStart: []byte(prefixOne + keyA), - keyEnd: []byte{0xff}, - parseFn: mockParseValue, - stopFn: mockStop, - isReverse: false, - - expectedValues: []string{"0", "2"}, - }, - "prefix iterator with stop, different insertion order, and reversed iterator": { - preSetKeys: []string{prefixOne + keyA, prefixOne + mockStopValue, prefixOne + keyB, prefixOne + mockStopValue + keyA}, - keyStart: []byte(prefixOne + keyA), - keyEnd: []byte{0xff}, - parseFn: mockParseValue, - stopFn: mockStop, - isReverse: true, - - // only the last value in our preSetKeys should be on the other end of the stopper - expectedValues: []string{"3"}, - }, - "parse with error": { - preSetKeys: oneABC, - keyStart: []byte(prefixOne + keyA), - keyEnd: []byte{0xff}, - parseFn: mockParseValueWithError, - stopFn: mockStop, - isReverse: false, - - expectedErr: mockError, - }, - } - - for name, tc := range testcases { - s.Run(name, func() { - s.SetupTest() - - for i, key := range tc.preSetKeys { - s.store.Set([]byte(key), []byte(fmt.Sprintf("%v", i))) - } - - actualValues, err := osmoutils.GetIterValuesWithStop(s.store, tc.keyStart, tc.keyEnd, tc.isReverse, tc.stopFn, tc.parseFn) - - if tc.expectedErr != nil { - s.Require().ErrorContains(err, tc.expectedErr.Error()) - s.Require().Nil(actualValues) - return - } - - s.Require().NoError(err) - - s.Require().Equal(tc.expectedValues, actualValues) - }) - } -} - -func (s *TestSuite) TestGetValuesUntilDerivedStop() { - testcases := map[string]struct { - preSetKeys []string - keyStart []byte - parseFn func(b []byte) (string, error) - stopFn func(b []byte) bool - - expectedValues []string - expectedErr error - }{ - "prefix iterator, no stop": { - preSetKeys: oneABC, - keyStart: []byte(prefixOne + keyA), - parseFn: mockParseValue, - stopFn: mockStop, - - expectedValues: []string{"0", "1", "2"}, - }, - "prefix iterator, with stop": { - preSetKeys: []string{prefixOne + keyA, prefixOne + mockStopValue, prefixOne + mockStopValue + keyA}, - keyStart: []byte(prefixOne + keyA), - parseFn: mockParseValue, - stopFn: mockStop, - - expectedValues: []string{"0"}, - }, - "prefix iterator, with stop & different insertion order": { - // keyB is lexicographically before mockStopValue so we expect it to be returned before we hit the stopper - preSetKeys: []string{prefixOne + keyA, prefixOne + mockStopValue, prefixOne + keyB, prefixOne + mockStopValue + keyA}, - keyStart: []byte(prefixOne + keyA), - parseFn: mockParseValue, - stopFn: mockStop, - - expectedValues: []string{"0", "2"}, - }, - "parse with error": { - preSetKeys: oneABC, - keyStart: []byte(prefixOne + keyA), - parseFn: mockParseValueWithError, - stopFn: mockStop, - - expectedErr: mockError, - }, - } - - for name, tc := range testcases { - s.Run(name, func() { - s.SetupTest() - for i, key := range tc.preSetKeys { - s.store.Set([]byte(key), []byte(fmt.Sprintf("%v", i))) - } - - actualValues, err := osmoutils.GetValuesUntilDerivedStop(s.store, tc.keyStart, tc.stopFn, tc.parseFn) - - if tc.expectedErr != nil { - s.Require().ErrorContains(err, tc.expectedErr.Error()) - s.Require().Nil(actualValues) - return - } - - s.Require().NoError(err) - - s.Require().Equal(tc.expectedValues, actualValues) - }) - } -} - -func (s *TestSuite) TestNoStopFn_AlwaysFalse() { - s.Require().False(osmoutils.NoStopFn([]byte(keyA))) - s.Require().False(osmoutils.NoStopFn([]byte(keyB))) -} - -// TestMustGet tests that MustGet retrieves the correct -// values from the store and panics if an error is encountered. -func (s *TestSuite) TestMustGet() { - tests := map[string]struct { - // keys and values to preset - preSetKeyValues map[string]proto.Message - - // keys and values to attempt to get and validate - expectedGetKeyValues map[string]proto.Message - - actualResultProto proto.Message - - expectPanic bool - }{ - "basic valid test": { - preSetKeyValues: map[string]proto.Message{ - keyA: &sdk.DecProto{Dec: sdk.OneDec()}, - keyB: &sdk.DecProto{Dec: sdk.OneDec().Add(sdk.OneDec())}, - keyC: &sdk.DecProto{Dec: sdk.OneDec().Add(sdk.OneDec())}, - }, - - expectedGetKeyValues: map[string]proto.Message{ - keyA: &sdk.DecProto{Dec: sdk.OneDec()}, - keyB: &sdk.DecProto{Dec: sdk.OneDec().Add(sdk.OneDec())}, - keyC: &sdk.DecProto{Dec: sdk.OneDec().Add(sdk.OneDec())}, - }, - - actualResultProto: &sdk.DecProto{}, - }, - "attempt to get non-existent key - panic": { - preSetKeyValues: map[string]proto.Message{ - keyA: &sdk.DecProto{Dec: sdk.OneDec()}, - keyC: &sdk.DecProto{Dec: sdk.OneDec().Add(sdk.OneDec())}, - }, - - expectedGetKeyValues: map[string]proto.Message{ - keyB: &sdk.DecProto{Dec: sdk.OneDec().Add(sdk.OneDec())}, - }, - - actualResultProto: &sdk.DecProto{}, - - expectPanic: true, - }, - "invalid proto Dec vs AuthParams- error": { - preSetKeyValues: map[string]proto.Message{ - keyA: &sdk.DecProto{Dec: sdk.OneDec()}, - }, - - expectedGetKeyValues: map[string]proto.Message{ - keyA: &sdk.DecProto{Dec: sdk.OneDec()}, - }, - - actualResultProto: &authtypes.Params{}, - - expectPanic: true, - }, - } - - for name, tc := range tests { - s.Run(name, func() { - s.SetupTest() - // Setup - for key, value := range tc.preSetKeyValues { - osmoutils.MustSet(s.store, []byte(key), value) - } - - osmoassert.ConditionalPanic(s.T(), tc.expectPanic, func() { - for key, expectedValue := range tc.expectedGetKeyValues { - // System under test. - osmoutils.MustGet(s.store, []byte(key), tc.actualResultProto) - // Assertions. - s.Require().Equal(expectedValue.String(), tc.actualResultProto.String()) - } - }) - }) - } -} - -// TestGet tests that Get returns a boolean indicating -// whether value exists for the given key and error -func (s *TestSuite) TestGet() { - tests := map[string]struct { - // keys and values to preset - preSetKeyValues map[string]proto.Message - - // keys and values to attempt to get and validate - expectedGetKeyValues map[string]proto.Message - - actualResultProto proto.Message - - expectFound bool - - expectErr bool - }{ - "basic valid test": { - preSetKeyValues: map[string]proto.Message{ - keyA: &sdk.DecProto{Dec: sdk.OneDec()}, - keyB: &sdk.DecProto{Dec: sdk.OneDec().Add(sdk.OneDec())}, - keyC: &sdk.DecProto{Dec: sdk.OneDec().Add(sdk.OneDec())}, - }, - - expectedGetKeyValues: map[string]proto.Message{ - keyA: &sdk.DecProto{Dec: sdk.OneDec()}, - keyB: &sdk.DecProto{Dec: sdk.OneDec().Add(sdk.OneDec())}, - keyC: &sdk.DecProto{Dec: sdk.OneDec().Add(sdk.OneDec())}, - }, - - actualResultProto: &sdk.DecProto{}, - - expectFound: true, - }, - "attempt to get non-existent key - not found & no err return": { - preSetKeyValues: map[string]proto.Message{ - keyA: &sdk.DecProto{Dec: sdk.OneDec()}, - keyC: &sdk.DecProto{Dec: sdk.OneDec().Add(sdk.OneDec())}, - }, - - expectedGetKeyValues: map[string]proto.Message{ - keyB: &sdk.DecProto{Dec: sdk.OneDec().Add(sdk.OneDec())}, - }, - - actualResultProto: &sdk.DecProto{}, - - expectFound: false, - - expectErr: false, - }, - "invalid proto Dec vs AuthParams - found but Unmarshal err": { - preSetKeyValues: map[string]proto.Message{ - keyA: &sdk.DecProto{Dec: sdk.OneDec()}, - }, - - expectedGetKeyValues: map[string]proto.Message{ - keyA: &sdk.DecProto{Dec: sdk.OneDec()}, - }, - - actualResultProto: &authtypes.Params{}, - - expectFound: true, - - expectErr: true, - }, - } - - for name, tc := range tests { - s.Run(name, func() { - s.SetupTest() - // Setup - for key, value := range tc.preSetKeyValues { - osmoutils.MustSet(s.store, []byte(key), value) - } - - for key, expectedValue := range tc.expectedGetKeyValues { - // System under test. - found, err := osmoutils.Get(s.store, []byte(key), tc.actualResultProto) - // Assertions. - s.Require().Equal(found, tc.expectFound) - if tc.expectErr { - s.Require().Error(err) - } - // make sure found by key & Unmarshal successfully - if !tc.expectErr && tc.expectFound { - s.Require().Equal(expectedValue.String(), tc.actualResultProto.String()) - } - } - }) - } -} - -// TestMustSet tests that MustSet updates the store correctly -// and panics if an error is encountered. -func (s *TestSuite) TestMustSet() { - tests := map[string]struct { - // keys and values to preset - setKey string - setValue proto.Message - - // keys and values to attempt to get and validate - getKeyValues map[string]proto.Message - - actualResultProto proto.Message - - key []byte - result proto.Message - expectPanic bool - }{ - "basic valid Dec test": { - setKey: keyA, - setValue: &sdk.DecProto{ - Dec: sdk.OneDec(), - }, - - actualResultProto: &sdk.DecProto{}, - }, - "basic valid AuthParams test": { - setKey: keyA, - setValue: &authtypes.Params{ - MaxMemoCharacters: 600, - }, - - actualResultProto: &authtypes.Params{}, - }, - "invalid set value": { - setKey: keyA, - setValue: (*sdk.DecProto)(nil), - - expectPanic: true, - }, - } - - for name, tc := range tests { - s.Run(name, func() { - osmoassert.ConditionalPanic(s.T(), tc.expectPanic, func() { - osmoutils.MustSet(s.store, []byte(tc.setKey), tc.setValue) - }) - - if tc.expectPanic { - return - } - - osmoutils.MustGet(s.store, []byte(tc.setKey), tc.actualResultProto) - s.Require().Equal(tc.setValue.String(), tc.actualResultProto.String()) - }) - } -} - -// TestMustGetDec tests that MustGetDec retrieves the correct -// decimal values from the store and panics if an error is encountered. -func (s *TestSuite) TestMustGetDec() { - tests := map[string]struct { - // keys and values to preset - preSetKeyValues map[string]sdk.Dec - - // keys and values to attempt to get and validate - expectedGetKeyValues map[string]sdk.Dec - - expectPanic bool - }{ - "valid get": { - preSetKeyValues: map[string]sdk.Dec{ - keyA: sdk.OneDec(), - keyB: sdk.OneDec().Add(sdk.OneDec()), - keyC: sdk.OneDec().Add(sdk.OneDec()).Add(sdk.OneDec()), - }, - - expectedGetKeyValues: map[string]sdk.Dec{ - keyA: sdk.OneDec(), - keyB: sdk.OneDec().Add(sdk.OneDec()), - keyC: sdk.OneDec().Add(sdk.OneDec()).Add(sdk.OneDec()), - }, - }, - "attempt to get non-existent key - panic": { - preSetKeyValues: map[string]sdk.Dec{ - keyA: sdk.OneDec(), - keyC: sdk.OneDec().Add(sdk.OneDec()).Add(sdk.OneDec()), - }, - - expectedGetKeyValues: map[string]sdk.Dec{ - keyA: sdk.OneDec(), - keyB: {}, // this one panics - }, - - expectPanic: true, - }, - } - - for name, tc := range tests { - s.Run(name, func() { - s.SetupTest() - // Setup - for key, value := range tc.preSetKeyValues { - osmoutils.MustSetDec(s.store, []byte(key), value) - } - - osmoassert.ConditionalPanic(s.T(), tc.expectPanic, func() { - for key, expectedValue := range tc.expectedGetKeyValues { - // System under test. - actualDec := osmoutils.MustGetDec(s.store, []byte(key)) - // Assertions. - s.Require().Equal(expectedValue.String(), actualDec.String()) - } - }) - }) - } -} - -// TestMustSetDec tests that MustSetDec updates the store correctly -// with the right decimal value. -// N.B.: It is non-trivial to cause a panic -// by calling `MustSetDec` because it provides -// a valid proto argument to `MustSet` which will -// only panic if the proto argument is invalid. -// Therefore, we only test a success case here. -func (s *TestSuite) TestMustSetDec() { - originalDecValue := sdk.OneDec() - - // System under test. - osmoutils.MustSetDec(s.store, []byte(keyA), originalDecValue) - - // Assertions. - retrievedDecVaue := osmoutils.MustGetDec(s.store, []byte(keyA)) - s.Require().Equal(originalDecValue.String(), retrievedDecVaue.String()) -} - -func (s *TestSuite) TestHasAnyAtPrefix() { - testcases := map[string]struct { - // if prefix is set, startValue and endValue are ignored. - // we either create an iterator prefix or a range iterator. - prefix string - startValue string - endValue string - preSetKeys []string - isReverse bool - - expectedValue bool - expectedErr error - }{ - "has one": { - preSetKeys: oneA, - - prefix: prefixOne, - - expectedValue: true, - }, - "has multiple": { - preSetKeys: oneABC, - - prefix: prefixOne, - - expectedValue: true, - }, - "has none": { - preSetKeys: oneABC, - - prefix: prefixTwo, - - expectedValue: false, - }, - "prefix lexicogrpahically below existing - does not find correctly": { - preSetKeys: twoAB, - - prefix: prefixOne, - - expectedValue: false, - }, - "prefix lexicogrpahically above existing - does not find correctly": { - preSetKeys: twoAB, - - prefix: string(sdk.PrefixEndBytes([]byte(prefixTwo))), - - expectedValue: false, - }, - "parse with error": { - preSetKeys: oneABC, - - prefix: prefixOne, - - expectedErr: mockError, - }, - } - - for name, tc := range testcases { - s.Run(name, func() { - s.SetupTest() - - for i, key := range tc.preSetKeys { - s.store.Set([]byte(key), []byte(fmt.Sprintf("%v", i))) - } - - mockParseValueFn := mockParseValue - if tc.expectedErr != nil { - mockParseValueFn = mockParseValueWithError - } - - actualValue, err := osmoutils.HasAnyAtPrefix(s.store, []byte(tc.prefix), mockParseValueFn) - - if tc.expectedErr != nil { - s.Require().ErrorContains(err, tc.expectedErr.Error()) - s.Require().False(actualValue) - return - } - - s.Require().NoError(err) - - s.Require().Equal(tc.expectedValue, actualValue) - }) - } -} diff --git a/osmoutils/sumtree/README.md b/osmoutils/sumtree/README.md deleted file mode 100644 index d9aeb7abd..000000000 --- a/osmoutils/sumtree/README.md +++ /dev/null @@ -1,151 +0,0 @@ -# Prefix-Sum B-Tree specification - -This module implements a B-Tree suitable for efficiently computing a -random prefix sum of data, while allowing the data to be efficiently -updated. - -The prefix sums for N elements x\_1, x\_2, ... x\_N, each with a weight -field, is the sequence y\_1, y\_2, ... y\_N, where -`y_i = sum_{0 <= j <= i} x_j.weight`. This data structure allows one to -edit, insert, and delete entries in the x sequence efficiently, and -efficiently retrieve the prefix sum at any index, where efficiently is -`O(log(N))` state operations. (Note that in the cosmos SDK stack, a -state operation is itself liable to take `O(log(N))` time) - -This is built for the use-case of we have a series of data that is -sorted by time. Each given time has an associated weight field. We want -to be able to very quickly find the total weight for all leaves with -times less than or equal to `t`. The actual implementation is agnostic -to what is the field we sort by. - -## Data structure idea - -The idea underlying this can be decomposed into two parts: - -1. Do some extra (`O(log(N))`) work when modifying the data, to allow - efficiently computing any prefix sum -2. Allow the data entries to be inserted into and deleted from, while - remaining sorted - -The solution for 1. is to build a balanced tree on top of the data. -Every inner node in the tree will be augmented with an "accumulated -weight" field, which contains the sum of the weights of all entries -below it. Notice that upon updating the weight of any leaf, the weights -of all nodes that are "above" this node can be updated efficiently. (As -there ought to only be log(N) such nodes) Furthermore, the root of the -tree's augmented value is the sum of all weights in the tree. - -Then to query the jth prefix sum, you first identify the path to the jth -node in the tree. You keep a running tally of "prefix sum thus far", -which is initialized to the sum of all weights in the tree. Then as you -walk the path from the tree root to the jth leaf, whenever there are -siblings on the right, you subtract their weight from your running -total. The weight when you arrive at the leaf is then the prefix sum. - -Lets illustrate this with a binary tree. - -![binary -tree](https://user-images.githubusercontent.com/6440154/116960474-142bf980-ac66-11eb-9a07-af84ab6d0bfa.png) - -If we want the prefix sum for leaf `12` we compute it as -`1.weight - 7.weight - 13.weight`. (We took a subtraction every time we -took a left) - -Now notice that this solution works for any tree type, where efficiency -just depends on `number of siblings * depth` and as long as that is -parameterized to be `O(log(N))` we maintain our definition of efficient. - -Thus we immediately get a solution to 2., by using a tree that supports -efficient inserts, and deletions, while still maintaining log depth and -a constant number of siblings. We opt for using a B+ tree for this, as -it performs the task well and does not require rebalance operations. -(Which can be costly in an adversarial environment) - -```{=html} - -``` - -## Implementation Details - -The B-Tree implementation under `osmoutils/sumtree` is designed specifically -for allowing efficient computation of a random prefix sum, with the -underlying data being updatable as explained above. - -Every Leaf has a `Weight` field, and the address its stored at in state -is the key which we want to sort by. The implementation sorts leaves as -byteslices, Leafs are sorted under their byteslice key, and the branch -nodes have accumulation for each childs. - -A node is pointed by a `node` struct, used internally. - -``` {.go} -type node struct { - t Tree - level uint8 - key []byte -} -``` - -A `node` struct is a pointer to the key-value pair under -`nodeKey(node.level, node.key)` - -A leaf node is simply a `uint64` integer value stored under -`nodeKey(0, key)`. The key is arbitrary length of byte slice. - -``` {.go} -type Leaf struct { - Value uint64 -} -``` - -A branch node consists of keys and accumulation of the children nodes. - -``` {.go} -type Branch struct { - Children []Child -} - -type Child struct { - Key []byte - Acc uint64 -} -``` - -The following constraints are valid for all branch nodes: - -1. For `c` in `node.Branch().Children`, the node corresponding to `c` - is stored under `nodeKey(node.level-1, c.Key)`. -2. For `c` in `node.Branch().Children`, `c.Acc` is the sum of all - `c'.Acc` where `c'` is in `c.Children`. If `c'` is leaf node, - substitute `c'.Acc` to `Leaf.Value`. -3. For `c` in `node.Branch().Children`, `c.Key` is equal or greater - than `node.key` and lesser than `node.rightSibling().key`. -4. There are no duplicate child stored in more than one of node's - `.Children`. - -### Example - -Here is an example tree data: - - - Level 2 nil - - Level 1 0xaaaa - - Level 0 0xaaaa Value 10 - - Level 0 0xaaaa01 Value 20 - - Level 0 0xaabb Value 30 - - Level 1 0xbb44 - - Level 0 0xbb55 Value 100 - - Level 0 0xbe Value 200 - - Level 1 0xeeaaaa - - Level 0 0xef1234 Value 300 - - Level 0 0xffff Value 400 - -The branch nodes will have the following childrens: - -``` {.go} -require.Equal(sumtree.Get(nodeKey(2, nil)), Children{{0xaaaa, 60}, {0xbb44, 300}, {0xeeaaaa, 700}}) -require.Equal(sumtree.Get(nodeKey(1, 0xaaaa)), Children{{0xaaaa, 10}, {0xaaaa01, 20}, {0xaabb, 30}}) -require.Equal(sumtree.Get(nodeKey(1, 0xbb44)), Children{{0xbb55, 100}, {0xbe, 200}}) -require.Equal(sumtree.Get(nodeKey(1, 0xeeaaaa)), Children{{0xef1234, 300}, {0xffff, 400}}) -``` diff --git a/osmoutils/sumtree/constants.go b/osmoutils/sumtree/constants.go deleted file mode 100644 index ea5b72af2..000000000 --- a/osmoutils/sumtree/constants.go +++ /dev/null @@ -1,13 +0,0 @@ -package sumtree - -var nodeKeyPrefix []byte - -const nodeKeyPrefixLen = 5 - -func init() { - // nodeKeyPrefix is assumed to be 5 bytes - nodeKeyPrefix = []byte("node/") - if len(nodeKeyPrefix) != nodeKeyPrefixLen { - panic("Invalid constants in accumulation store") - } -} diff --git a/osmoutils/sumtree/legacy/v101/old_tree.json b/osmoutils/sumtree/legacy/v101/old_tree.json deleted file mode 100644 index b98e97c8e..000000000 --- a/osmoutils/sumtree/legacy/v101/old_tree.json +++ /dev/null @@ -1,12 +0,0 @@ -[ - ["bm9kZS8AAA==","Ijg0Ig=="], - ["bm9kZS8AABY/Xw+aYtHixkmBhVrYaB0NhtE=","IjU2NiI="], - ["bm9kZS8AAE8=","IjYyOSI="], - ["bm9kZS8AAHWSHmZo0tY=","IjY1MCI="], - ["bm9kZS8AAIPxX7loC058i3Y6Gx1J","Ijc5MCI="], - ["bm9kZS8AAJwWDwcC9QWY","IjE4NiI="], - ["bm9kZS8AAMUvUFTb2Wiw9xc=","IjM0NCI="], - ["bm9kZS8AANSVXIQhEQ==","Ijk1NiI="], - ["bm9kZS8AAOk2eVG6ov9s1HHE","IjMyMyI="], - ["bm9kZS8AAQ==","W3siSW5kZXgiOm51bGwsIkFjYyI6Ijg0In0seyJJbmRleCI6IkZqOWZENXBpMGVMR1NZR0ZXdGhvSFEyRzBRPT0iLCJBY2MiOiI1NjYifSx7IkluZGV4IjoiVHc9PSIsIkFjYyI6IjYyOSJ9LHsiSW5kZXgiOiJkWkllWm1qUzFnPT0iLCJBY2MiOiI2NTAifSx7IkluZGV4IjoiZy9GZnVXZ0xUbnlMZGpvYkhVaz0iLCJBY2MiOiI3OTAifSx7IkluZGV4IjoibkJZUEJ3TDFCWmc9IiwiQWNjIjoiMTg2In0seyJJbmRleCI6InhTOVFWTnZaYUxEM0Z3PT0iLCJBY2MiOiIzNDQifSx7IkluZGV4IjoiMUpWY2hDRVIiLCJBY2MiOiI5NTYifSx7IkluZGV4IjoiNlRaNVVicWkvMnpVY2NRPSIsIkFjYyI6IjMyMyJ9XQ=="] -] diff --git a/osmoutils/sumtree/legacy/v101/tree.go b/osmoutils/sumtree/legacy/v101/tree.go deleted file mode 100644 index e0fd73f2f..000000000 --- a/osmoutils/sumtree/legacy/v101/tree.go +++ /dev/null @@ -1,102 +0,0 @@ -package v101 - -import ( - "encoding/binary" - "encoding/json" - "fmt" - - "cosmossdk.io/math" - "github.com/gogo/protobuf/proto" - - stypes "github.com/cosmos/cosmos-sdk/store/types" - sdk "github.com/cosmos/cosmos-sdk/types" - - "github.com/CosmosContracts/juno/v15/osmoutils/sumtree" -) - -type Child struct { - Index []byte - Acc math.Int -} - -type Children []Child // branch nodes - -func migrateBranchValue(oldValueBz []byte) *sumtree.Node { - var oldValue Children - fmt.Println(string(oldValueBz)) - err := json.Unmarshal(oldValueBz, &oldValue) - if err != nil { - panic(err) - } - cs := make([]*sumtree.Child, len(oldValue)) - for i, oldChild := range oldValue { - cs[i] = &sumtree.Child{Index: oldChild.Index, Accumulation: oldChild.Acc} - } - return &sumtree.Node{Children: cs} -} - -func migrateLeafValue(index []byte, oldValueBz []byte) *sumtree.Leaf { - oldValue := sdk.ZeroInt() - err := json.Unmarshal(oldValueBz, &oldValue) - if err != nil { - panic(err) - } - return sumtree.NewLeaf(index, oldValue) -} - -func nodeKey(level uint16, key []byte) []byte { - bz := make([]byte, 2) - binary.BigEndian.PutUint16(bz, level) - return append(append([]byte("node/"), bz...), key...) -} - -func leafKey(key []byte) []byte { - return nodeKey(0, key) -} - -func migrateTreeNode(store sdk.KVStore, level uint16, key []byte) { - if level == 0 { - migrateTreeLeaf(store, key) - } else { - migrateTreeBranch(store, level, key) - } -} - -func migrateTreeBranch(store sdk.KVStore, level uint16, key []byte) { - keyBz := nodeKey(level, key) - oldValueBz := store.Get(keyBz) - fmt.Println("migrate", keyBz, string(oldValueBz), level) - newValue := migrateBranchValue(oldValueBz) - newValueBz, err := proto.Marshal(newValue) - if err != nil { - panic(err) - } - store.Set(keyBz, newValueBz) - - for _, child := range newValue.Children { - migrateTreeNode(store, level-1, child.Index) - } -} - -func migrateTreeLeaf(store sdk.KVStore, key []byte) { - keyBz := leafKey(key) - oldValueBz := store.Get(keyBz) - newValue := migrateLeafValue(key, oldValueBz) - newValueBz, err := proto.Marshal(newValue) - if err != nil { - panic(err) - } - store.Set(keyBz, newValueBz) -} - -func MigrateTree(store sdk.KVStore) { - iter := stypes.KVStoreReversePrefixIterator(store, []byte("node/")) - defer iter.Close() - if !iter.Valid() { - return - } - keybz := iter.Key()[5:] - level := binary.BigEndian.Uint16(keybz[:2]) - key := keybz[2:] - migrateTreeNode(store, level, key) -} diff --git a/osmoutils/sumtree/legacy/v101/tree_test.go b/osmoutils/sumtree/legacy/v101/tree_test.go deleted file mode 100644 index edf520b6e..000000000 --- a/osmoutils/sumtree/legacy/v101/tree_test.go +++ /dev/null @@ -1,147 +0,0 @@ -package v101_test - -import ( - "bytes" - "encoding/json" - "fmt" - "os" - "testing" - - "github.com/stretchr/testify/require" - - "github.com/gogo/protobuf/proto" - - "github.com/cosmos/iavl" - - dbm "github.com/cometbft/cometbft-db" - - iavlstore "github.com/cosmos/cosmos-sdk/store/iavl" - sdk "github.com/cosmos/cosmos-sdk/types" - - "github.com/CosmosContracts/juno/v15/osmoutils/sumtree" - v101 "github.com/CosmosContracts/juno/v15/osmoutils/sumtree/legacy/v101" -) - -func setupStore() sdk.KVStore { - db := dbm.NewMemDB() - tree, _ := iavl.NewMutableTree(db, 100, false) - _, _, err := tree.SaveVersion() - if err != nil { - panic(err) - } - kvstore := iavlstore.UnsafeNewStore(tree) - return kvstore -} - -func compareBranch(oldValueBz []byte, valueBz []byte) (err error) { - oldValue := v101.Children{} - value := sumtree.Node{} - err = json.Unmarshal(oldValueBz, &oldValue) - if err != nil { - return - } - err = proto.Unmarshal(valueBz, &value) - if err != nil { - return - } - - for i, c := range oldValue { - c2 := value.Children[i] - if !bytes.Equal(c.Index, c2.Index) || !c.Acc.Equal(c2.Accumulation) { - err = fmt.Errorf("branch value mismatch: %+v / %+v", oldValue, value) - return - } - } - return -} - -func compareLeaf(oldValueBz []byte, valueBz []byte) (err error) { - oldValue := sdk.ZeroInt() - value := sumtree.Leaf{} - err = json.Unmarshal(oldValueBz, &oldValue) - if err != nil { - return - } - err = proto.Unmarshal(valueBz, &value) - if err != nil { - return - } - - if !oldValue.Equal(value.Leaf.Accumulation) { - return fmt.Errorf("leaf value mismatch: %+v / %+v", oldValue, value) - } - return -} - -func comparePair(oldKeyBz, oldValueBz, keyBz, valueBz []byte) (err error) { - if !bytes.Equal(oldKeyBz, keyBz) { - err = fmt.Errorf("key bytes mismatch: %x / %x", oldKeyBz, keyBz) - } - - // TODO: properly select error - err = compareBranch(oldValueBz, valueBz) - if err == nil { - return nil - } - err = compareLeaf(oldValueBz, valueBz) - return err -} - -type kvPair struct { - key []byte - value []byte -} - -func pair(iter sdk.Iterator) kvPair { - res := kvPair{iter.Key(), iter.Value()} - iter.Next() - return res -} - -func extract(store sdk.KVStore) (res []kvPair) { - res = []kvPair{} - iter := store.Iterator(nil, nil) - defer iter.Close() - for iter.Valid() { - res = append(res, pair(iter)) - } - return -} - -func readold() []kvPair { - bz, err := os.ReadFile("./old_tree.json") - if err != nil { - panic(err) - } - var data [][][]byte - err = json.Unmarshal(bz, &data) - if err != nil { - panic(err) - } - res := make([]kvPair, len(data)) - for i, pair := range data { - res[i] = kvPair{pair[0], pair[1]} - } - return res -} - -func TestMigrate(t *testing.T) { - store := setupStore() - - oldpairs := readold() - for _, pair := range oldpairs { - fmt.Println("set", pair.key, pair.value) - store.Set(pair.key, pair.value) - } - - v101.MigrateTree(store) - - newpairs := extract(store) - - for i, oldpair := range oldpairs { - fmt.Println(i) - newpair := newpairs[i] - err := comparePair(oldpair.key, oldpair.value, newpair.key, newpair.value) - require.NoError(t, err) - } -} diff --git a/osmoutils/sumtree/node.go b/osmoutils/sumtree/node.go deleted file mode 100644 index 5ec02babd..000000000 --- a/osmoutils/sumtree/node.go +++ /dev/null @@ -1,262 +0,0 @@ -package sumtree - -import ( - "bytes" - - "cosmossdk.io/math" - "github.com/gogo/protobuf/proto" - - sdk "github.com/cosmos/cosmos-sdk/types" -) - -func NewLeaf(key []byte, acc math.Int) *Leaf { - return &Leaf{Leaf: &Child{ - Index: key, - Accumulation: acc, - }} -} - -func (ptr *ptr) isLeaf() bool { - return ptr.level == 0 -} - -func (ptr *ptr) node() (res *Node) { - res = new(Node) - bz := ptr.tree.store.Get(ptr.tree.nodeKey(ptr.level, ptr.key)) - if bz != nil { - if err := proto.Unmarshal(bz, res); err != nil { - panic(err) - } - } - return -} - -func (ptr *ptr) set(node *Node) { - bz, err := proto.Marshal(node) - if err != nil { - panic(err) - } - ptr.tree.store.Set(ptr.tree.nodeKey(ptr.level, ptr.key), bz) -} - -func (ptr *ptr) setLeaf(leaf *Leaf) { - if !ptr.isLeaf() { - panic("setLeaf should only be called on pointers to leaf nodes. This ptr is a branch") - } - bz, err := proto.Marshal(leaf) - if err != nil { - panic(err) - } - ptr.tree.store.Set(ptr.tree.leafKey(ptr.key), bz) -} - -func (ptr *ptr) delete() { - ptr.tree.store.Delete(ptr.tree.nodeKey(ptr.level, ptr.key)) -} - -func (ptr *ptr) leftSibling() *ptr { - iter := ptr.tree.ptrReverseIterator(ptr.level, nil, ptr.key) - defer iter.Close() - return iter.ptr() -} - -func (ptr *ptr) rightSibling() *ptr { - iter := ptr.tree.ptrIterator(ptr.level, ptr.key, nil) - defer iter.Close() - if !iter.Valid() { - return nil - } - if ptr.exists() { - // exclude ptr itself - iter.Next() - } - return iter.ptr() -} - -func (ptr *ptr) child(n uint16) *ptr { - // TODO: set end to prefix iterator end - iter := ptr.tree.ptrIterator(ptr.level-1, ptr.node().Children[n].Index, nil) - defer iter.Close() - return iter.ptr() -} - -// parent returns the parent of the provided pointer. -// Behavior is not well defined if the calling pointer does not exist in the tree. -func (ptr *ptr) parent() *ptr { - // See if there is a parent with the same 'key' as this ptr. - parent := ptr.tree.ptrGet(ptr.level+1, ptr.key) - if parent.exists() { - return parent - } - // If not, take the node in the above layer that is lexicographically the closest - // from the left of the key. - parent = parent.leftSibling() - if parent.exists() { - return parent - } - // If there is no such ptr (the parent is not in the tree), return nil - return ptr.tree.ptrGet(ptr.level+1, nil) -} - -// exists returns true if the calling pointer has a node in the tree. -func (ptr *ptr) exists() bool { - if ptr == nil { - return false - } - return ptr.tree.store.Has(ptr.tree.nodeKey(ptr.level, ptr.key)) -} - -// updateAccumulation changes the accumulation value of a ptr in the tree, -// and handles updating the accumulation for all of its parent's augmented data. -func (ptr *ptr) updateAccumulation(c *Child) { - if !ptr.exists() { - return // reached at the root - } - - node := ptr.node() - idx, match := node.find(c.Index) - if !match { - panic("non existing key pushed from the child") - } - node = node.setAcc(idx, c.Accumulation) - ptr.set(node) - ptr.parent().updateAccumulation(&Child{ptr.key, node.accumulate()}) -} - -func (ptr *ptr) push(c *Child) { - if !ptr.exists() { - ptr.create(NewNode(c)) - return - } - - cs := ptr.node() - idx, match := cs.find(c.Index) - - // setting already existing child, move to updateAccumulation - if match { - ptr.updateAccumulation(c) - return - } - - // inserting new child ptr - cs = cs.insert(idx, c) - parent := ptr.parent() - - // split and push-up if overflow - if len(cs.Children) > int(ptr.tree.m) { - split := ptr.tree.m/2 + 1 - leftnode, rightnode := cs.split(int(split)) - ptr.tree.ptrGet(ptr.level, cs.Children[split].Index).create(rightnode) - if !parent.exists() { - parent.create(NewNode( - &Child{ptr.key, leftnode.accumulate()}, - &Child{cs.Children[split].Index, rightnode.accumulate()}, - )) - ptr.set(leftnode) - return - } - // constructing right child - parent.push(&Child{cs.Children[split].Index, rightnode.accumulate()}) - cs = leftnode - parent = ptr.parent() // parent might be changed during the pushing process - } - - parent.updateAccumulation(&Child{ptr.key, cs.accumulate()}) - ptr.set(cs) -} - -func (ptr *ptr) pull(key []byte) { - if !ptr.exists() { - return // reached at the root - } - node := ptr.node() - idx, match := node.find(key) - - if !match { - panic("pulling non existing child") - } - - node = node.delete(idx) - // For sake of efficiently on our use case, we pull only when a ptr gets - // empty. - // if len(data.Index) >= int(ptr.tree.m/2) { - if len(node.Children) > 0 { - ptr.set(node) - ptr.parent().updateAccumulation(&Child{ptr.key, node.accumulate()}) - return - } - - // merge if possible - left := ptr.leftSibling() - right := ptr.rightSibling() - parent := ptr.parent() - ptr.delete() - parent.pull(ptr.key) - - if left.exists() && right.exists() { - // parent might be deleted, retrieve from left - parent = left.parent() - if bytes.Equal(parent.key, right.parent().key) { - leftnode := left.node() - rightnode := right.node() - if len(leftnode.Children)+len(rightnode.Children) < int(ptr.tree.m) { - left.set(leftnode.merge(rightnode)) - right.delete() - parent.pull(right.key) - parent.updateAccumulation(&Child{left.key, leftnode.accumulate()}) - } - } - } -} - -func (node Node) accumulate() (res math.Int) { - res = sdk.ZeroInt() - for _, child := range node.Children { - res = res.Add(child.Accumulation) - } - return -} - -func NewNode(cs ...*Child) *Node { - return &Node{Children: cs} -} - -// find returns the appropriate position that key should be inserted -// if match is true, idx is the exact position for the key -// if match is false, idx is the position where the key should be inserted. -func (node Node) find(key []byte) (idx int, match bool) { - for idx, child := range node.Children { - if bytes.Equal(child.Index, key) { - return idx, true - } - // Push new key to the appropriate position - if bytes.Compare(child.Index, key) > 0 { - return idx, false - } - } - - return len(node.Children), false -} - -func (node *Node) setAcc(idx int, acc math.Int) *Node { - node.Children[idx] = &Child{node.Children[idx].Index, acc} - return node -} - -func (node *Node) insert(idx int, c *Child) *Node { - arr := append(node.Children[:idx], append([]*Child{c}, node.Children[idx:]...)...) - return NewNode(arr...) -} - -func (node *Node) delete(idx int) *Node { - node = NewNode(append(node.Children[:idx], node.Children[idx+1:]...)...) - return node -} - -func (node *Node) split(idx int) (*Node, *Node) { - return NewNode(node.Children[:idx]...), NewNode(node.Children[idx:]...) -} - -func (node *Node) merge(node2 *Node) *Node { - return NewNode(append(node.Children, node2.Children...)...) -} diff --git a/osmoutils/sumtree/tree.go b/osmoutils/sumtree/tree.go deleted file mode 100644 index 59d105888..000000000 --- a/osmoutils/sumtree/tree.go +++ /dev/null @@ -1,296 +0,0 @@ -/// B+ tree implementation on KVStore - -package sumtree - -import ( - "bytes" - "encoding/binary" - "fmt" - - "cosmossdk.io/math" - "github.com/gogo/protobuf/proto" - - store "github.com/cosmos/cosmos-sdk/store" - stypes "github.com/cosmos/cosmos-sdk/store/types" - sdk "github.com/cosmos/cosmos-sdk/types" -) - -// Tree is an augmented B+ tree implementation. -// Branches have m sized key index slice. Each key index represents -// the starting index of the child node's index(inclusive), and the -// ending index of the previous node of the child node's index(exclusive). -// TODO: We should abstract out the leaves of this tree to allow more data aside from -// the accumulation value to go there. -type Tree struct { - store store.KVStore - m uint8 -} - -func NewTree(store store.KVStore, m uint8) Tree { - tree := Tree{store, m} - if tree.IsEmpty() { - tree.Set(nil, sdk.ZeroInt()) - } - return tree -} - -func (t Tree) IsEmpty() bool { - return !t.store.Has(t.leafKey(nil)) -} - -func (t Tree) Set(key []byte, acc math.Int) { - ptr := t.ptrGet(0, key) - leaf := NewLeaf(key, acc) - ptr.setLeaf(leaf) - - ptr.parent().push(leaf.Leaf) -} - -func (t Tree) Remove(key []byte) { - node := t.ptrGet(0, key) - if !node.exists() { - return - } - parent := node.parent() - node.delete() - parent.pull(key) -} - -func (t Tree) Increase(key []byte, amt math.Int) { - value := t.Get(key) - t.Set(key, value.Add(amt)) -} - -func (t Tree) Decrease(key []byte, amt math.Int) { - t.Increase(key, amt.Neg()) -} - -func (t Tree) Clear() { - iter := t.store.Iterator(nil, nil) - defer iter.Close() - for ; iter.Valid(); iter.Next() { - t.store.Delete(iter.Key()) - } -} - -// ptr is pointer to a specific node inside the tree. -type ptr struct { - tree Tree - level uint16 - key []byte - // XXX: cache stored value? -} - -// ptrIterator iterates over ptrs in a given level. It only iterates directly over the pointers -// to the nodes, not the actual nodes themselves, to save loading additional data into memory. -type ptrIterator struct { - tree Tree - level uint16 - store.Iterator -} - -func (iter ptrIterator) ptr() *ptr { - if !iter.Valid() { - return nil - } - res := ptr{ - tree: iter.tree, - level: iter.level, - key: iter.Key()[7:], - } - // ptrIterator becomes invalid once retrieve ptr - err := iter.Close() - if err != nil { - panic(err) - } - return &res -} - -// nodeKey takes in a nodes layer, and its key, and constructs the -// its key in the underlying datastore. -func (t Tree) nodeKey(level uint16, key []byte) []byte { - // node key prefix is of len 7 - bz := make([]byte, nodeKeyPrefixLen+2+len(key)) - copy(bz, nodeKeyPrefix) - binary.BigEndian.PutUint16(bz[5:], level) - copy(bz[nodeKeyPrefixLen+2:], key) - return bz -} - -// leafKey constructs a key for a node pointer representing a leaf node. -func (t Tree) leafKey(key []byte) []byte { - return t.nodeKey(0, key) -} - -func (t Tree) root() *ptr { - iter := stypes.KVStoreReversePrefixIterator(t.store, nodeKeyPrefix) - defer iter.Close() - if !iter.Valid() { - return nil - } - key := iter.Key()[5:] - return &ptr{ - tree: t, - level: binary.BigEndian.Uint16(key[:2]), - key: key[2:], - } -} - -// Get returns the (math.Int) accumulation value at a given leaf. -func (t Tree) Get(key []byte) math.Int { - res := new(Leaf) - keybz := t.leafKey(key) - if !t.store.Has(keybz) { - return sdk.ZeroInt() - } - bz := t.store.Get(keybz) - err := proto.Unmarshal(bz, res) - if err != nil { - panic(err) - } - return res.Leaf.Accumulation -} - -func (ptr *ptr) create(node *Node) { - keybz := ptr.tree.nodeKey(ptr.level, ptr.key) - bz, err := proto.Marshal(node) - if err != nil { - panic(err) - } - ptr.tree.store.Set(keybz, bz) -} - -func (t Tree) ptrGet(level uint16, key []byte) *ptr { - return &ptr{ - tree: t, - level: level, - key: key, - } -} - -func (t Tree) ptrIterator(level uint16, begin, end []byte) ptrIterator { - var endBytes []byte - if end != nil { - endBytes = t.nodeKey(level, end) - } else { - endBytes = stypes.PrefixEndBytes(t.nodeKey(level, nil)) - } - return ptrIterator{ - tree: t, - level: level, - Iterator: t.store.Iterator(t.nodeKey(level, begin), endBytes), - } -} - -func (t Tree) ptrReverseIterator(level uint16, begin, end []byte) ptrIterator { - var endBytes []byte - if end != nil { - endBytes = t.nodeKey(level, end) - } else { - endBytes = stypes.PrefixEndBytes(t.nodeKey(level, nil)) - } - return ptrIterator{ - tree: t, - level: level, - Iterator: t.store.ReverseIterator(t.nodeKey(level, begin), endBytes), - } -} - -func (t Tree) Iterator(begin, end []byte) store.Iterator { - return t.ptrIterator(0, begin, end) -} - -func (t Tree) ReverseIterator(begin, end []byte) store.Iterator { - return t.ptrReverseIterator(0, begin, end) -} - -// accumulationSplit returns the accumulated value for all of the following: -// left: all leaves under nodePointer with key < provided key -// exact: leaf with key = provided key -// right: all leaves under nodePointer with key > provided key -// Note that the equalities here are _exclusive_. -func (ptr *ptr) accumulationSplit(key []byte) (left math.Int, exact math.Int, right math.Int) { - left, exact, right = sdk.ZeroInt(), sdk.ZeroInt(), sdk.ZeroInt() - if ptr.isLeaf() { - var leaf Leaf - bz := ptr.tree.store.Get(ptr.tree.leafKey(ptr.key)) - err := proto.Unmarshal(bz, &leaf) - if err != nil { - panic(err) - } - // Check if the leaf key is to the left of the input key, - // if so this value is on the left. Similar for the other cases. - // Recall that all of the output arguments default to 0, if unset internally. - switch bytes.Compare(ptr.key, key) { - case -1: - left = leaf.Leaf.Accumulation - case 0: - exact = leaf.Leaf.Accumulation - case 1: - right = leaf.Leaf.Accumulation - } - return - } - - node := ptr.node() - idx, match := node.find(key) - if !match { - idx-- - } - left, exact, right = ptr.tree.ptrGet(ptr.level-1, node.Children[idx].Index).accumulationSplit(key) - left = left.Add(NewNode(node.Children[:idx]...).accumulate()) - right = right.Add(NewNode(node.Children[idx+1:]...).accumulate()) - return left, exact, right -} - -// TotalAccumulatedValue returns the sum of the weights for all leaves. -func (t Tree) TotalAccumulatedValue() math.Int { - return t.SubsetAccumulation(nil, nil) -} - -// Prefix sum returns the total weight of all leaves with keys <= to the provided key. -func (t Tree) PrefixSum(key []byte) math.Int { - return t.SubsetAccumulation(nil, key) -} - -// SubsetAccumulation returns the total value of all leaves with keys -// between start and end (inclusive of both ends) -// if start is nil, it is the beginning of the tree. -// if end is nil, it is the end of the tree. -func (t Tree) SubsetAccumulation(start []byte, end []byte) math.Int { - if start == nil { - left, exact, _ := t.root().accumulationSplit(end) - return left.Add(exact) - } - if end == nil { - _, exact, right := t.root().accumulationSplit(start) - return exact.Add(right) - } - _, leftexact, leftrest := t.root().accumulationSplit(start) - _, _, rightest := t.root().accumulationSplit(end) - return leftexact.Add(leftrest).Sub(rightest) -} - -func (t Tree) SplitAcc(key []byte) (math.Int, math.Int, math.Int) { - return t.root().accumulationSplit(key) -} - -func (ptr *ptr) visualize(depth int, acc math.Int) { - if !ptr.exists() { - return - } - for i := 0; i < depth; i++ { - fmt.Printf(" ") - } - fmt.Printf("- ") - fmt.Printf("{%d %+v %v}\n", ptr.level, ptr.key, acc) - for i, child := range ptr.node().Children { - childnode := ptr.child(uint16(i)) - childnode.visualize(depth+1, child.Accumulation) - } -} - -// DebugVisualize prints the entire tree to stdout. -func (t Tree) DebugVisualize() { - t.root().visualize(0, math.Int{}) -} diff --git a/osmoutils/sumtree/tree.pb.go b/osmoutils/sumtree/tree.pb.go deleted file mode 100644 index 4f007610f..000000000 --- a/osmoutils/sumtree/tree.pb.go +++ /dev/null @@ -1,737 +0,0 @@ -// Code generated by protoc-gen-gogo. DO NOT EDIT. -// source: osmosis/sumtree/v1beta1/tree.proto - -package sumtree - -import ( - fmt "fmt" - _ "github.com/cosmos/cosmos-sdk/types" - github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types" - _ "github.com/gogo/protobuf/gogoproto" - proto "github.com/gogo/protobuf/proto" - io "io" - math "math" - math_bits "math/bits" -) - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = 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 - -type Node struct { - Children []*Child `protobuf:"bytes,1,rep,name=children,proto3" json:"children,omitempty"` -} - -func (m *Node) Reset() { *m = Node{} } -func (m *Node) String() string { return proto.CompactTextString(m) } -func (*Node) ProtoMessage() {} -func (*Node) Descriptor() ([]byte, []int) { - return fileDescriptor_31a1c5f55b935f78, []int{0} -} -func (m *Node) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *Node) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_Node.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 *Node) XXX_Merge(src proto.Message) { - xxx_messageInfo_Node.Merge(m, src) -} -func (m *Node) XXX_Size() int { - return m.Size() -} -func (m *Node) XXX_DiscardUnknown() { - xxx_messageInfo_Node.DiscardUnknown(m) -} - -var xxx_messageInfo_Node proto.InternalMessageInfo - -func (m *Node) GetChildren() []*Child { - if m != nil { - return m.Children - } - return nil -} - -type Child struct { - Index []byte `protobuf:"bytes,1,opt,name=index,proto3" json:"index,omitempty"` - Accumulation github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,2,opt,name=accumulation,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"accumulation"` -} - -func (m *Child) Reset() { *m = Child{} } -func (m *Child) String() string { return proto.CompactTextString(m) } -func (*Child) ProtoMessage() {} -func (*Child) Descriptor() ([]byte, []int) { - return fileDescriptor_31a1c5f55b935f78, []int{1} -} -func (m *Child) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *Child) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_Child.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 *Child) XXX_Merge(src proto.Message) { - xxx_messageInfo_Child.Merge(m, src) -} -func (m *Child) XXX_Size() int { - return m.Size() -} -func (m *Child) XXX_DiscardUnknown() { - xxx_messageInfo_Child.DiscardUnknown(m) -} - -var xxx_messageInfo_Child proto.InternalMessageInfo - -func (m *Child) GetIndex() []byte { - if m != nil { - return m.Index - } - return nil -} - -type Leaf struct { - Leaf *Child `protobuf:"bytes,1,opt,name=leaf,proto3" json:"leaf,omitempty"` -} - -func (m *Leaf) Reset() { *m = Leaf{} } -func (m *Leaf) String() string { return proto.CompactTextString(m) } -func (*Leaf) ProtoMessage() {} -func (*Leaf) Descriptor() ([]byte, []int) { - return fileDescriptor_31a1c5f55b935f78, []int{2} -} -func (m *Leaf) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *Leaf) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_Leaf.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 *Leaf) XXX_Merge(src proto.Message) { - xxx_messageInfo_Leaf.Merge(m, src) -} -func (m *Leaf) XXX_Size() int { - return m.Size() -} -func (m *Leaf) XXX_DiscardUnknown() { - xxx_messageInfo_Leaf.DiscardUnknown(m) -} - -var xxx_messageInfo_Leaf proto.InternalMessageInfo - -func (m *Leaf) GetLeaf() *Child { - if m != nil { - return m.Leaf - } - return nil -} - -func init() { - proto.RegisterType((*Node)(nil), "osmosis.store.v1beta1.Node") - proto.RegisterType((*Child)(nil), "osmosis.store.v1beta1.Child") - proto.RegisterType((*Leaf)(nil), "osmosis.store.v1beta1.Leaf") -} - -func init() { - proto.RegisterFile("osmosis/sumtree/v1beta1/tree.proto", fileDescriptor_31a1c5f55b935f78) -} - -var fileDescriptor_31a1c5f55b935f78 = []byte{ - // 302 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x91, 0xb1, 0x4e, 0xeb, 0x30, - 0x18, 0x85, 0xe3, 0x7b, 0x53, 0x04, 0xa6, 0x53, 0x54, 0xa4, 0xa8, 0x42, 0x6e, 0x94, 0x01, 0x65, - 0xa9, 0x4d, 0x60, 0xe9, 0x88, 0xca, 0x84, 0x40, 0x0c, 0x19, 0xd9, 0x1c, 0xc7, 0x4d, 0x2d, 0x92, - 0xb8, 0xc4, 0x0e, 0x82, 0xb7, 0xe0, 0xb1, 0x3a, 0x76, 0x44, 0x0c, 0x15, 0x4a, 0x5e, 0x04, 0xc5, - 0x09, 0x05, 0x24, 0x24, 0xa6, 0xdf, 0xc7, 0xfe, 0x74, 0xce, 0x91, 0x7f, 0xe8, 0x4b, 0x95, 0x4b, - 0x25, 0x14, 0x51, 0x55, 0xae, 0x4b, 0xce, 0xc9, 0x63, 0x18, 0x73, 0x4d, 0x43, 0xd2, 0x0a, 0xbc, - 0x2a, 0xa5, 0x96, 0xce, 0x51, 0xcf, 0x60, 0xa5, 0x65, 0xc9, 0x71, 0x4f, 0x8c, 0x47, 0xa9, 0x4c, - 0xa5, 0x21, 0x48, 0x7b, 0xea, 0xe0, 0x31, 0x62, 0x86, 0x26, 0x31, 0x55, 0x5f, 0x66, 0x4c, 0x8a, - 0xa2, 0x7b, 0xf7, 0x2f, 0xa0, 0x7d, 0x2b, 0x13, 0xee, 0xcc, 0xe0, 0x3e, 0x5b, 0x8a, 0x2c, 0x29, - 0x79, 0xe1, 0x02, 0xef, 0x7f, 0x70, 0x78, 0x76, 0x8c, 0x7f, 0xcd, 0xc1, 0x97, 0x2d, 0x16, 0xed, - 0x68, 0xff, 0x01, 0x0e, 0xcc, 0x95, 0x33, 0x82, 0x03, 0x51, 0x24, 0xfc, 0xc9, 0x05, 0x1e, 0x08, - 0x86, 0x51, 0x27, 0x9c, 0x08, 0x0e, 0x29, 0x63, 0x55, 0x5e, 0x65, 0x54, 0x0b, 0x59, 0xb8, 0xff, - 0x3c, 0x10, 0x1c, 0xcc, 0xf1, 0x7a, 0x3b, 0xb1, 0xde, 0xb6, 0x93, 0x93, 0x54, 0xe8, 0x65, 0x15, - 0x63, 0x26, 0x73, 0xd2, 0x37, 0xed, 0xc6, 0x54, 0x25, 0xf7, 0x44, 0x3f, 0xaf, 0xb8, 0xc2, 0x57, - 0x85, 0x8e, 0x7e, 0x78, 0xf8, 0x33, 0x68, 0xdf, 0x70, 0xba, 0x70, 0x4e, 0xa1, 0x9d, 0x71, 0xba, - 0x30, 0x81, 0x7f, 0x15, 0x36, 0xe4, 0xfc, 0x7a, 0x5d, 0x23, 0xb0, 0xa9, 0x11, 0x78, 0xaf, 0x11, - 0x78, 0x69, 0x90, 0xb5, 0x69, 0x90, 0xf5, 0xda, 0x20, 0xeb, 0x2e, 0xfc, 0xd6, 0xa4, 0xf7, 0x99, - 0x66, 0x34, 0x56, 0x9f, 0xc2, 0xcc, 0x4a, 0x8b, 0x6c, 0xb7, 0x9b, 0x78, 0xcf, 0x7c, 0xe1, 0xf9, - 0x47, 0x00, 0x00, 0x00, 0xff, 0xff, 0x30, 0x34, 0x4b, 0x32, 0xb5, 0x01, 0x00, 0x00, -} - -func (m *Node) 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 *Node) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *Node) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Children) > 0 { - for iNdEx := len(m.Children) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.Children[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintTree(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - } - } - return len(dAtA) - i, nil -} - -func (m *Child) 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 *Child) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *Child) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - { - size := m.Accumulation.Size() - i -= size - if _, err := m.Accumulation.MarshalTo(dAtA[i:]); err != nil { - return 0, err - } - i = encodeVarintTree(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - if len(m.Index) > 0 { - i -= len(m.Index) - copy(dAtA[i:], m.Index) - i = encodeVarintTree(dAtA, i, uint64(len(m.Index))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func (m *Leaf) 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 *Leaf) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *Leaf) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.Leaf != nil { - { - size, err := m.Leaf.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintTree(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func encodeVarintTree(dAtA []byte, offset int, v uint64) int { - offset -= sovTree(v) - base := offset - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ - } - dAtA[offset] = uint8(v) - return base -} -func (m *Node) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if len(m.Children) > 0 { - for _, e := range m.Children { - l = e.Size() - n += 1 + l + sovTree(uint64(l)) - } - } - return n -} - -func (m *Child) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Index) - if l > 0 { - n += 1 + l + sovTree(uint64(l)) - } - l = m.Accumulation.Size() - n += 1 + l + sovTree(uint64(l)) - return n -} - -func (m *Leaf) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.Leaf != nil { - l = m.Leaf.Size() - n += 1 + l + sovTree(uint64(l)) - } - return n -} - -func sovTree(x uint64) (n int) { - return (math_bits.Len64(x|1) + 6) / 7 -} -func sozTree(x uint64) (n int) { - return sovTree(uint64((x << 1) ^ uint64((int64(x) >> 63)))) -} -func (m *Node) 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 ErrIntOverflowTree - } - 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: Node: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: Node: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Children", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTree - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthTree - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthTree - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Children = append(m.Children, &Child{}) - if err := m.Children[len(m.Children)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipTree(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthTree - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *Child) 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 ErrIntOverflowTree - } - 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: Child: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: Child: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Index", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTree - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLengthTree - } - postIndex := iNdEx + byteLen - if postIndex < 0 { - return ErrInvalidLengthTree - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Index = append(m.Index[:0], dAtA[iNdEx:postIndex]...) - if m.Index == nil { - m.Index = []byte{} - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Accumulation", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTree - } - 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 ErrInvalidLengthTree - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthTree - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.Accumulation.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipTree(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthTree - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *Leaf) 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 ErrIntOverflowTree - } - 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: Leaf: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: Leaf: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Leaf", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTree - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthTree - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthTree - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Leaf == nil { - m.Leaf = &Child{} - } - if err := m.Leaf.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipTree(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthTree - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func skipTree(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, ErrIntOverflowTree - } - 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, ErrIntOverflowTree - } - 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, ErrIntOverflowTree - } - 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, ErrInvalidLengthTree - } - iNdEx += length - case 3: - depth++ - case 4: - if depth == 0 { - return 0, ErrUnexpectedEndOfGroupTree - } - depth-- - case 5: - iNdEx += 4 - default: - return 0, fmt.Errorf("proto: illegal wireType %d", wireType) - } - if iNdEx < 0 { - return 0, ErrInvalidLengthTree - } - if depth == 0 { - return iNdEx, nil - } - } - return 0, io.ErrUnexpectedEOF -} - -var ( - ErrInvalidLengthTree = fmt.Errorf("proto: negative length found during unmarshaling") - ErrIntOverflowTree = fmt.Errorf("proto: integer overflow") - ErrUnexpectedEndOfGroupTree = fmt.Errorf("proto: unexpected end of group") -) diff --git a/osmoutils/sumtree/tree_test.go b/osmoutils/sumtree/tree_test.go deleted file mode 100644 index 56a009931..000000000 --- a/osmoutils/sumtree/tree_test.go +++ /dev/null @@ -1,136 +0,0 @@ -package sumtree_test - -import ( - "bytes" - "math/rand" - "sort" - "testing" - - "github.com/stretchr/testify/suite" - - "github.com/cosmos/iavl" - - dbm "github.com/cometbft/cometbft-db" - - iavlstore "github.com/cosmos/cosmos-sdk/store/iavl" - sdk "github.com/cosmos/cosmos-sdk/types" - - "github.com/CosmosContracts/juno/v15/osmoutils/sumtree" -) - -type TreeTestSuite struct { - suite.Suite - - tree sumtree.Tree -} - -func (suite *TreeTestSuite) SetupTest() { - db := dbm.NewMemDB() - tree, err := iavl.NewMutableTree(db, 100, false) - suite.Require().NoError(err) - _, _, err = tree.SaveVersion() - suite.Require().Nil(err) - kvstore := iavlstore.UnsafeNewStore(tree) - suite.tree = sumtree.NewTree(kvstore, 10) -} - -func TestTreeTestSuite(t *testing.T) { - suite.Run(t, new(TreeTestSuite)) -} - -type pair struct { - key []byte - value uint64 -} - -type pairs []pair - -var _ sort.Interface = pairs{} - -func (p pairs) Len() int { - return len(p) -} - -func (p pairs) Less(i, j int) bool { - return bytes.Compare(p[i].key, p[j].key) < 0 -} - -func (p pairs) Swap(i, j int) { - temp := p[i] - p[i] = p[j] - p[j] = temp -} - -func (p pairs) sum() (res uint64) { - for _, pair := range p { - res += pair.value - } - return -} - -func (suite *TreeTestSuite) TestTreeInvariants() { - suite.SetupTest() - - pairs := pairs{pair{[]byte("hello"), 100}} - suite.tree.Set([]byte("hello"), sdk.NewIntFromUint64(100)) - - // tested up to 2000 - for i := 0; i < 500; i++ { - // add a single element - key := make([]byte, rand.Int()%20) - value := rand.Uint64() % 100 - rand.Read(key) - idx := sort.Search(len(pairs), func(n int) bool { return bytes.Compare(pairs[n].key, key) >= 0 }) - if idx < len(pairs) { - if bytes.Equal(pairs[idx].key, key) { - pairs[idx] = pair{key, value} - } else { - pairs = append(pairs, pair{key, value}) - sort.Sort(pairs) - } - } else { - pairs = append(pairs, pair{key, value}) - } - - suite.tree.Set(key, sdk.NewIntFromUint64(value)) - - // check all is right - for _, pair := range pairs { - suite.Require().Equal(suite.tree.Get(pair.key).Uint64(), pair.value) - // XXX: check all branch nodes - } - - // check accumulation calc is alright - left, exact, right := uint64(0), pairs[0].value, pairs[1:].sum() - for idx, pair := range pairs { - tleft, texact, tright := suite.tree.SplitAcc(pair.key) - suite.Require().Equal(left, tleft.Uint64()) - suite.Require().Equal(exact, texact.Uint64()) - suite.Require().Equal(right, tright.Uint64()) - - key := append(pair.key, 0x00) - if idx == len(pairs)-1 { - break - } - if bytes.Equal(key, pairs[idx+1].key) { - break - } - - tleft, texact, tright = suite.tree.SplitAcc(key) - suite.Require().Equal(left+exact, tleft.Uint64()) - suite.Require().Equal(uint64(0), texact.Uint64()) - suite.Require().Equal(right, tright.Uint64()) - - left += exact - exact = pairs[idx+1].value - right -= exact - } - - if rand.Int()%2 == 0 { - idx := rand.Int() % len(pairs) - pair := pairs[idx] - pairs = append(pairs[:idx], pairs[idx+1:]...) - suite.tree.Remove(pair.key) - } - } -} diff --git a/x/ibc-hooks/sdkmodule.go b/x/ibc-hooks/sdkmodule.go index 4bf1c6b17..ea425bfae 100644 --- a/x/ibc-hooks/sdkmodule.go +++ b/x/ibc-hooks/sdkmodule.go @@ -15,7 +15,7 @@ import ( cdctypes "github.com/cosmos/cosmos-sdk/codec/types" - "github.com/CosmosContracts/juno/v15/osmoutils" + authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" abci "github.com/cometbft/cometbft/abci/types" sdk "github.com/cosmos/cosmos-sdk/types" @@ -74,11 +74,11 @@ func (AppModuleBasic) GetQueryCmd() *cobra.Command { type AppModule struct { AppModuleBasic - authKeeper osmoutils.AccountKeeper + authKeeper authkeeper.AccountKeeper } // NewAppModule creates a new AppModule object. -func NewAppModule(ak osmoutils.AccountKeeper) AppModule { +func NewAppModule(ak authkeeper.AccountKeeper) AppModule { return AppModule{ AppModuleBasic: AppModuleBasic{}, authKeeper: ak, From 42170c1e276db7c56c279df00cbc49932ae1ff5a Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Fri, 28 Apr 2023 18:57:45 -0500 Subject: [PATCH 053/131] Comment out legacy x/mint querier --- x/mint/keeper/querier.go | 123 ++++++++++++++++--------------- x/mint/simulation/params_test.go | 34 --------- 2 files changed, 63 insertions(+), 94 deletions(-) delete mode 100644 x/mint/simulation/params_test.go diff --git a/x/mint/keeper/querier.go b/x/mint/keeper/querier.go index bd4399a54..8e2ebb7b1 100644 --- a/x/mint/keeper/querier.go +++ b/x/mint/keeper/querier.go @@ -1,62 +1,65 @@ package keeper -import ( - abci "github.com/cometbft/cometbft/abci/types" - - "github.com/CosmosContracts/juno/v15/x/mint/types" - "github.com/cosmos/cosmos-sdk/codec" - sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" -) - -// NewQuerier returns a minting Querier handler. -func NewQuerier(k Keeper, legacyQuerierCdc *codec.LegacyAmino) sdk.Querier { - return func(ctx sdk.Context, path []string, _ abci.RequestQuery) ([]byte, error) { - switch path[0] { - case types.QueryParameters: - return queryParams(ctx, k, legacyQuerierCdc) - - case types.QueryInflation: - return queryInflation(ctx, k, legacyQuerierCdc) - - case types.QueryAnnualProvisions: - return queryAnnualProvisions(ctx, k, legacyQuerierCdc) - - default: - return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unknown query path: %s", path[0]) - } - } -} - -func queryParams(ctx sdk.Context, k Keeper, legacyQuerierCdc *codec.LegacyAmino) ([]byte, error) { - params := k.GetParams(ctx) - - res, err := codec.MarshalJSONIndent(legacyQuerierCdc, params) - if err != nil { - return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) - } - - return res, nil -} - -func queryInflation(ctx sdk.Context, k Keeper, legacyQuerierCdc *codec.LegacyAmino) ([]byte, error) { - minter := k.GetMinter(ctx) - - res, err := codec.MarshalJSONIndent(legacyQuerierCdc, minter.Inflation) - if err != nil { - return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) - } - - return res, nil -} - -func queryAnnualProvisions(ctx sdk.Context, k Keeper, legacyQuerierCdc *codec.LegacyAmino) ([]byte, error) { - minter := k.GetMinter(ctx) - - res, err := codec.MarshalJSONIndent(legacyQuerierCdc, minter.AnnualProvisions) - if err != nil { - return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) - } - - return res, nil -} +// TODO: Can not find anything in the docs which says we need this? the Route() was removed and seems this was apart of that. +// If so it does nothing now. + +// import ( +// abci "github.com/cometbft/cometbft/abci/types" + +// "github.com/CosmosContracts/juno/v15/x/mint/types" +// "github.com/cosmos/cosmos-sdk/codec" +// sdk "github.com/cosmos/cosmos-sdk/types" +// sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" +// ) + +// // NewQuerier returns a minting Querier handler. +// func NewQuerier(k Keeper, legacyQuerierCdc *codec.LegacyAmino) sdk.Querier { +// return func(ctx sdk.Context, path []string, _ abci.RequestQuery) ([]byte, error) { +// switch path[0] { +// case types.QueryParameters: +// return queryParams(ctx, k, legacyQuerierCdc) + +// case types.QueryInflation: +// return queryInflation(ctx, k, legacyQuerierCdc) + +// case types.QueryAnnualProvisions: +// return queryAnnualProvisions(ctx, k, legacyQuerierCdc) + +// default: +// return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unknown query path: %s", path[0]) +// } +// } +// } + +// func queryParams(ctx sdk.Context, k Keeper, legacyQuerierCdc *codec.LegacyAmino) ([]byte, error) { +// params := k.GetParams(ctx) + +// res, err := codec.MarshalJSONIndent(legacyQuerierCdc, params) +// if err != nil { +// return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) +// } + +// return res, nil +// } + +// func queryInflation(ctx sdk.Context, k Keeper, legacyQuerierCdc *codec.LegacyAmino) ([]byte, error) { +// minter := k.GetMinter(ctx) + +// res, err := codec.MarshalJSONIndent(legacyQuerierCdc, minter.Inflation) +// if err != nil { +// return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) +// } + +// return res, nil +// } + +// func queryAnnualProvisions(ctx sdk.Context, k Keeper, legacyQuerierCdc *codec.LegacyAmino) ([]byte, error) { +// minter := k.GetMinter(ctx) + +// res, err := codec.MarshalJSONIndent(legacyQuerierCdc, minter.AnnualProvisions) +// if err != nil { +// return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) +// } + +// return res, nil +// } diff --git a/x/mint/simulation/params_test.go b/x/mint/simulation/params_test.go deleted file mode 100644 index b6c21c3ed..000000000 --- a/x/mint/simulation/params_test.go +++ /dev/null @@ -1,34 +0,0 @@ -package simulation_test - -import ( - "math/rand" - "testing" - - "github.com/stretchr/testify/require" - - "github.com/CosmosContracts/juno/v15/x/mint/simulation" -) - -func TestParamChangest(t *testing.T) { - s := rand.NewSource(1) - r := rand.New(s) - - expected := []struct { - composedKey string - key string - simValue string - subspace string - }{ - {"mint/BlocksPerYear", "BlocksPerYear", "\"6311520\"", "mint"}, - } - - paramChanges := simulation.ParamChanges(r) - require.Len(t, paramChanges, 1) - - for i, p := range paramChanges { - require.Equal(t, expected[i].composedKey, p.ComposedKey()) - require.Equal(t, expected[i].key, p.Key()) - require.Equal(t, expected[i].simValue, p.SimValue()(r)) - require.Equal(t, expected[i].subspace, p.Subspace()) - } -} From a07c1e4635842187131c19d0f763ad10bb2768cb Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Fri, 28 Apr 2023 18:58:10 -0500 Subject: [PATCH 054/131] abci CommitInfo, wasmkeeper.NewMsgServerImpl --- app/apptesting/test_suite.go | 7 +- x/feeshare/keeper/keeper_test.go | 2 +- x/mint/keeper/querier_test.go | 118 +++++++++++++++---------------- 3 files changed, 64 insertions(+), 63 deletions(-) diff --git a/app/apptesting/test_suite.go b/app/apptesting/test_suite.go index de6c27b9d..13e04f7d5 100644 --- a/app/apptesting/test_suite.go +++ b/app/apptesting/test_suite.go @@ -185,7 +185,7 @@ func (s *KeeperTestHelper) BeginNewBlockWithProposer(proposer sdk.ValAddress) { header := tmtypes.Header{Height: s.Ctx.BlockHeight() + 1, Time: newBlockTime} newCtx := s.Ctx.WithBlockTime(newBlockTime).WithBlockHeight(s.Ctx.BlockHeight() + 1) s.Ctx = newCtx - lastCommitInfo := abci.LastCommitInfo{ + lastCommitInfo := abci.CommitInfo{ Votes: []abci.VoteInfo{{ Validator: abci.Validator{Address: valAddr, Power: 1000}, SignedLastBlock: true, @@ -216,7 +216,7 @@ func (s *KeeperTestHelper) AllocateRewardsToValidator(valAddr sdk.ValAddress, re // allocate rewards to validator s.Ctx = s.Ctx.WithBlockHeight(s.Ctx.BlockHeight() + 1) decTokens := sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: sdk.NewDec(20000)}} - s.App.DistrKeeper.AllocateTokensToValidator(s.Ctx, validator, decTokens) + s.App.AppKeepers.DistrKeeper.AllocateTokensToValidator(s.Ctx, validator, decTokens) } // BuildTx builds a transaction. @@ -266,7 +266,8 @@ func TestMessageAuthzSerialization(t *testing.T, msg sdk.Msg) { // Authz: Grant Msg typeURL := sdk.MsgTypeURL(msg) - grant, err := authz.NewGrant(authz.NewGenericAuthorization(typeURL), someDate.Add(time.Hour)) + later := someDate.Add(time.Hour) + grant, err := authz.NewGrant(someDate, authz.NewGenericAuthorization(typeURL), &later) require.NoError(t, err) msgGrant := authz.MsgGrant{Granter: mockGranter, Grantee: mockGrantee, Grant: grant} diff --git a/x/feeshare/keeper/keeper_test.go b/x/feeshare/keeper/keeper_test.go index 25325620a..12f84409e 100644 --- a/x/feeshare/keeper/keeper_test.go +++ b/x/feeshare/keeper/keeper_test.go @@ -57,7 +57,7 @@ func (s *IntegrationTestSuite) SetupTest() { s.bankKeeper = s.app.AppKeepers.BankKeeper s.accountKeeper = s.app.AppKeepers.AccountKeeper s.feeShareMsgServer = s.app.AppKeepers.FeeShareKeeper - s.wasmMsgServer = wasmkeeper.NewMsgServerImpl((*wasmkeeper.Keeper)(wasmkeeper.NewDefaultPermissionKeeper(s.app.AppKeepers.WasmKeeper))) + s.wasmMsgServer = wasmkeeper.NewMsgServerImpl(&s.app.AppKeepers.WasmKeeper) } func (s *IntegrationTestSuite) FundAccount(ctx sdk.Context, addr sdk.AccAddress, amounts sdk.Coins) error { diff --git a/x/mint/keeper/querier_test.go b/x/mint/keeper/querier_test.go index 12bebbf06..c7448af15 100644 --- a/x/mint/keeper/querier_test.go +++ b/x/mint/keeper/querier_test.go @@ -1,86 +1,86 @@ package keeper_test -import ( - "testing" +// import ( +// "testing" - "github.com/cosmos/cosmos-sdk/codec" +// "github.com/cosmos/cosmos-sdk/codec" - "github.com/stretchr/testify/require" +// "github.com/stretchr/testify/require" - keep "github.com/CosmosContracts/juno/v15/x/mint/keeper" - "github.com/CosmosContracts/juno/v15/x/mint/types" - sdk "github.com/cosmos/cosmos-sdk/types" +// keep "github.com/CosmosContracts/juno/v15/x/mint/keeper" +// "github.com/CosmosContracts/juno/v15/x/mint/types" +// sdk "github.com/cosmos/cosmos-sdk/types" - abci "github.com/cometbft/cometbft/abci/types" -) +// abci "github.com/cometbft/cometbft/abci/types" +// ) -func TestNewQuerier(t *testing.T) { - app, ctx := createTestApp(true) - legacyQuerierCdc := codec.NewAminoCodec(app.LegacyAmino()) - querier := keep.NewQuerier(app.AppKeepers.MintKeeper, legacyQuerierCdc.LegacyAmino) +// func TestNewQuerier(t *testing.T) { +// app, ctx := createTestApp(true) +// legacyQuerierCdc := codec.NewAminoCodec(app.LegacyAmino()) +// querier := keep.NewQuerier(app.AppKeepers.MintKeeper, legacyQuerierCdc.LegacyAmino) - query := abci.RequestQuery{ - Path: "", - Data: []byte{}, - } +// query := abci.RequestQuery{ +// Path: "", +// Data: []byte{}, +// } - _, err := querier(ctx, []string{types.QueryParameters}, query) - require.NoError(t, err) +// _, err := querier(ctx, []string{types.QueryParameters}, query) +// require.NoError(t, err) - _, err = querier(ctx, []string{types.QueryInflation}, query) - require.NoError(t, err) +// _, err = querier(ctx, []string{types.QueryInflation}, query) +// require.NoError(t, err) - _, err = querier(ctx, []string{types.QueryAnnualProvisions}, query) - require.NoError(t, err) +// _, err = querier(ctx, []string{types.QueryAnnualProvisions}, query) +// require.NoError(t, err) - _, err = querier(ctx, []string{"foo"}, query) - require.Error(t, err) -} +// _, err = querier(ctx, []string{"foo"}, query) +// require.Error(t, err) +// } -func TestQueryParams(t *testing.T) { - app, ctx := createTestApp(true) - legacyQuerierCdc := codec.NewAminoCodec(app.LegacyAmino()) - querier := keep.NewQuerier(app.AppKeepers.MintKeeper, legacyQuerierCdc.LegacyAmino) +// func TestQueryParams(t *testing.T) { +// app, ctx := createTestApp(true) +// legacyQuerierCdc := codec.NewAminoCodec(app.LegacyAmino()) +// querier := keep.NewQuerier(app.AppKeepers.MintKeeper, legacyQuerierCdc.LegacyAmino) - var params types.Params +// var params types.Params - res, sdkErr := querier(ctx, []string{types.QueryParameters}, abci.RequestQuery{}) - require.NoError(t, sdkErr) +// res, sdkErr := querier(ctx, []string{types.QueryParameters}, abci.RequestQuery{}) +// require.NoError(t, sdkErr) - err := app.LegacyAmino().UnmarshalJSON(res, ¶ms) - require.NoError(t, err) +// err := app.LegacyAmino().UnmarshalJSON(res, ¶ms) +// require.NoError(t, err) - require.Equal(t, app.AppKeepers.MintKeeper.GetParams(ctx), params) -} +// require.Equal(t, app.AppKeepers.MintKeeper.GetParams(ctx), params) +// } -func TestQueryInflation(t *testing.T) { - app, ctx := createTestApp(true) - legacyQuerierCdc := codec.NewAminoCodec(app.LegacyAmino()) - querier := keep.NewQuerier(app.AppKeepers.MintKeeper, legacyQuerierCdc.LegacyAmino) +// func TestQueryInflation(t *testing.T) { +// app, ctx := createTestApp(true) +// legacyQuerierCdc := codec.NewAminoCodec(app.LegacyAmino()) +// querier := keep.NewQuerier(app.AppKeepers.MintKeeper, legacyQuerierCdc.LegacyAmino) - var inflation sdk.Dec +// var inflation sdk.Dec - res, sdkErr := querier(ctx, []string{types.QueryInflation}, abci.RequestQuery{}) - require.NoError(t, sdkErr) +// res, sdkErr := querier(ctx, []string{types.QueryInflation}, abci.RequestQuery{}) +// require.NoError(t, sdkErr) - err := app.LegacyAmino().UnmarshalJSON(res, &inflation) - require.NoError(t, err) +// err := app.LegacyAmino().UnmarshalJSON(res, &inflation) +// require.NoError(t, err) - require.Equal(t, app.AppKeepers.MintKeeper.GetMinter(ctx).Inflation, inflation) -} +// require.Equal(t, app.AppKeepers.MintKeeper.GetMinter(ctx).Inflation, inflation) +// } -func TestQueryAnnualProvisions(t *testing.T) { - app, ctx := createTestApp(true) - legacyQuerierCdc := codec.NewAminoCodec(app.LegacyAmino()) - querier := keep.NewQuerier(app.AppKeepers.MintKeeper, legacyQuerierCdc.LegacyAmino) +// func TestQueryAnnualProvisions(t *testing.T) { +// app, ctx := createTestApp(true) +// legacyQuerierCdc := codec.NewAminoCodec(app.LegacyAmino()) +// querier := keep.NewQuerier(app.AppKeepers.MintKeeper, legacyQuerierCdc.LegacyAmino) - var annualProvisions sdk.Dec +// var annualProvisions sdk.Dec - res, sdkErr := querier(ctx, []string{types.QueryAnnualProvisions}, abci.RequestQuery{}) - require.NoError(t, sdkErr) +// res, sdkErr := querier(ctx, []string{types.QueryAnnualProvisions}, abci.RequestQuery{}) +// require.NoError(t, sdkErr) - err := app.LegacyAmino().UnmarshalJSON(res, &annualProvisions) - require.NoError(t, err) +// err := app.LegacyAmino().UnmarshalJSON(res, &annualProvisions) +// require.NoError(t, err) - require.Equal(t, app.AppKeepers.MintKeeper.GetMinter(ctx).AnnualProvisions, annualProvisions) -} +// require.Equal(t, app.AppKeepers.MintKeeper.GetMinter(ctx).AnnualProvisions, annualProvisions) +// } From 593bfe13c767c4de2f500ed5fa805c4d6ce65ce4 Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Fri, 28 Apr 2023 19:17:37 -0500 Subject: [PATCH 055/131] Upgrade ictest to v7 (main) - WIP --- tests/interchaintest/chain_upgrade_test.go | 1 + tests/interchaintest/go.mod | 217 ++-- tests/interchaintest/go.sum | 1270 +++++++++++++------- tests/interchaintest/ibc_transfer_test.go | 4 + tests/interchaintest/setup.go | 11 +- 5 files changed, 999 insertions(+), 504 deletions(-) diff --git a/tests/interchaintest/chain_upgrade_test.go b/tests/interchaintest/chain_upgrade_test.go index 2c0a640bd..c4a80f6a7 100644 --- a/tests/interchaintest/chain_upgrade_test.go +++ b/tests/interchaintest/chain_upgrade_test.go @@ -95,6 +95,7 @@ func CosmosChainUpgradeTest(t *testing.T, chainName, initialVersion, upgradeBran // or just create a function to modify as a fork of cosmos.ModifyGenesisProposalTime. This should really be a builder yea? // !IMPORTANT: V15 - Query the current minting parameters + // param, _ := chain.QueryParam(ctx, "mint", "BlocksPerYear") param, _ := chain.QueryParam(ctx, "mint", "BlocksPerYear") require.NoError(t, err, "error querying blocks per year") require.Equal(t, param.Value, "\"6311520\"") // mainnet it is 5048093, but we are just ensuring the upgrade applies correctly from default. diff --git a/tests/interchaintest/go.mod b/tests/interchaintest/go.mod index 46741cd1a..03584a9c0 100644 --- a/tests/interchaintest/go.mod +++ b/tests/interchaintest/go.mod @@ -3,75 +3,102 @@ module github.com/CosmosContracts/juno/tests/interchaintest go 1.19 require ( - github.com/cosmos/cosmos-sdk v0.47.1 + cosmossdk.io/simapp v0.0.0-20230224204036-a6adb0821462 github.com/cosmos/ibc-go/v7 v7.0.0 + github.com/strangelove-ventures/interchaintest/v7 v7.0.0-20230428012002-db902d82df33 github.com/stretchr/testify v1.8.2 - go.uber.org/zap v1.23.0 + go.uber.org/zap v1.24.0 + ) require ( - filippo.io/edwards25519 v1.0.0-rc.1 // indirect + cloud.google.com/go v0.110.0 // indirect + cloud.google.com/go/compute v1.18.0 // indirect + cloud.google.com/go/compute/metadata v0.2.3 // indirect + cloud.google.com/go/iam v0.12.0 // indirect + cloud.google.com/go/storage v1.29.0 // indirect + cosmossdk.io/api v0.3.1 // indirect + cosmossdk.io/core v0.5.1 // indirect + cosmossdk.io/depinject v1.0.0-alpha.3 // indirect + cosmossdk.io/errors v1.0.0-beta.7 // indirect + cosmossdk.io/math v1.0.0 // indirect + cosmossdk.io/tools/rosetta v0.2.1 // indirect + filippo.io/edwards25519 v1.0.0 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect - github.com/99designs/keyring v1.2.1 // indirect + github.com/99designs/keyring v1.2.2 // indirect github.com/BurntSushi/toml v1.2.1 // indirect github.com/ChainSafe/go-schnorrkel v1.0.0 // indirect github.com/ChainSafe/go-schnorrkel/1 v0.0.0-00010101000000-000000000000 // indirect - github.com/CosmWasm/wasmd v0.31.0 // indirect - github.com/CosmWasm/wasmvm v1.2.1 // indirect + github.com/ComposableFi/go-subkey/v2 v2.0.0-tm03420 // indirect + github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e // indirect + github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec // indirect github.com/Microsoft/go-winio v0.6.0 // indirect github.com/StirlingMarketingGroup/go-namecase v1.0.0 // indirect - github.com/armon/go-metrics v0.4.0 // indirect - github.com/avast/retry-go/v4 v4.0.4 // indirect + github.com/armon/go-metrics v0.4.1 // indirect + github.com/avast/retry-go/v4 v4.3.4 // indirect + github.com/aws/aws-sdk-go v1.44.203 // indirect github.com/benbjohnson/clock v1.3.0 // 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.1-0.20220910012023-760eaf8b6816 // indirect - github.com/btcsuite/btcd v0.23.0 // indirect github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect - github.com/centrifuge/go-substrate-rpc-client/v4 v4.0.4 // indirect + github.com/cenkalti/backoff/v4 v4.1.3 // indirect github.com/cespare/xxhash v1.1.0 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/chzyer/readline v1.5.1 // indirect + github.com/coinbase/rosetta-sdk-go/types v1.0.0 // indirect + github.com/cometbft/cometbft v0.37.1 // indirect + github.com/cometbft/cometbft-db v0.7.0 // indirect github.com/confio/ics23/go v0.9.0 // indirect github.com/cosmos/btcutil v1.0.5 // indirect github.com/cosmos/cosmos-proto v1.0.0-beta.2 // indirect + github.com/cosmos/cosmos-sdk v0.47.1 // indirect github.com/cosmos/go-bip39 v1.0.0 // indirect - github.com/cosmos/gogoproto v1.4.6 // indirect - github.com/cosmos/gorocksdb v1.2.0 // indirect - github.com/cosmos/iavl v0.19.5 // indirect - github.com/cosmos/interchain-security v1.0.0 // indirect - github.com/cosmos/ledger-cosmos-go v0.12.2 // indirect + github.com/cosmos/gogogateway v1.2.0 // indirect + github.com/cosmos/gogoproto v1.4.8 // indirect + github.com/cosmos/iavl v0.20.0 // indirect + github.com/cosmos/ics23/go v0.9.1-0.20221207100636-b1abd8678aab // indirect + github.com/cosmos/ledger-cosmos-go v0.12.1 // indirect + github.com/cosmos/rosetta-sdk-go v0.10.0 // indirect + github.com/creachadair/taskgroup v0.4.2 // indirect github.com/danieljoos/wincred v1.1.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/deckarep/golang-set v1.8.0 // indirect - github.com/decred/base58 v1.0.3 // indirect + github.com/decred/base58 v1.0.4 // indirect github.com/decred/dcrd/crypto/blake256 v1.0.0 // indirect github.com/decred/dcrd/dcrec/secp256k1/v2 v2.0.0 // indirect - github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect - github.com/dgraph-io/badger/v3 v3.2103.2 // indirect - github.com/dgraph-io/ristretto v0.1.0 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect + github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect + github.com/dgraph-io/badger/v2 v2.2007.4 // indirect + github.com/dgraph-io/ristretto v0.1.1 // indirect + github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect github.com/docker/distribution v2.8.1+incompatible // indirect github.com/docker/docker v20.10.19+incompatible // indirect github.com/docker/go-connections v0.4.0 // indirect github.com/docker/go-units v0.5.0 // indirect - github.com/dustin/go-humanize v1.0.1-0.20200219035652-afde56e7acac // indirect + github.com/dustin/go-humanize v1.0.1 // indirect github.com/dvsekhvalnov/jose2go v1.5.0 // indirect - github.com/ethereum/go-ethereum v1.10.17 // indirect + github.com/ethereum/go-ethereum v1.10.20 // indirect github.com/felixge/httpsnoop v1.0.2 // 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/go-logfmt/logfmt v0.6.0 // indirect github.com/go-stack/stack v1.8.1 // indirect github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect - github.com/gogo/gateway v1.1.0 // indirect + github.com/gogo/googleapis v1.4.1 // indirect github.com/gogo/protobuf v1.3.3 // indirect - github.com/golang/glog v1.0.0 // indirect + github.com/golang/glog v1.1.0 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/golang/protobuf v1.5.2 // indirect + github.com/golang/mock v1.6.0 // indirect + github.com/golang/protobuf v1.5.3 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/google/btree v1.1.2 // indirect - github.com/google/flatbuffers v1.12.1 // indirect github.com/google/go-cmp v0.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.3 // indirect + github.com/googleapis/gax-go/v2 v2.7.0 // indirect github.com/gorilla/handlers v1.5.1 // indirect github.com/gorilla/mux v1.8.0 // indirect github.com/gorilla/websocket v1.5.0 // indirect @@ -80,119 +107,137 @@ require ( 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.7.0 // 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/hcl v1.0.0 // indirect - github.com/hdevalence/ed25519consensus v0.0.0-20220222234857-c00d1f31bab3 // indirect + github.com/hdevalence/ed25519consensus v0.1.0 // indirect + github.com/huandu/skiplist v1.2.0 // indirect github.com/icza/dyno v0.0.0-20220812133438-f0b6f8a18845 // indirect - github.com/inconshreveable/mousetrap v1.0.1 // indirect - github.com/ipfs/go-cid v0.0.7 // indirect + github.com/improbable-eng/grpc-web v0.15.0 // indirect + github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/ipfs/go-cid v0.2.0 // indirect + github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/jmhodges/levigo v1.0.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect - github.com/klauspost/compress v1.15.11 // indirect - github.com/klauspost/cpuid/v2 v2.0.9 // indirect + github.com/klauspost/compress v1.16.3 // indirect + github.com/klauspost/cpuid/v2 v2.2.3 // indirect + github.com/lib/pq v1.10.7 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect - github.com/libp2p/go-libp2p-core v0.15.1 // indirect - github.com/libp2p/go-openssl v0.0.7 // indirect + github.com/libp2p/go-libp2p v0.22.0 // indirect + github.com/libp2p/go-openssl v0.1.0 // indirect github.com/magiconair/properties v1.8.7 // 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-20210601165009-122bf33a46e0 // indirect - github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 // indirect + github.com/manifoldco/promptui v0.9.0 // indirect + github.com/mattn/go-isatty v0.0.17 // indirect + github.com/mattn/go-pointer v0.0.1 // indirect + github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect + github.com/mimoo/StrobeGo v0.0.0-20220103164710-9a04d6ca976b // indirect + github.com/minio/highwayhash v1.0.2 // indirect github.com/minio/sha256-simd v1.0.0 // indirect + github.com/misko9/go-substrate-rpc-client/v4 v4.0.0-20230413215336-5bd2aea337ae // indirect + github.com/mitchellh/go-homedir v1.1.0 // indirect + github.com/mitchellh/go-testing-interface v1.14.1 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect github.com/mr-tron/base58 v1.2.0 // indirect github.com/mtibben/percent v0.2.1 // indirect - github.com/multiformats/go-base32 v0.0.3 // indirect + github.com/multiformats/go-base32 v0.0.4 // indirect github.com/multiformats/go-base36 v0.1.0 // indirect - github.com/multiformats/go-multiaddr v0.4.1 // indirect - github.com/multiformats/go-multibase v0.0.3 // indirect - github.com/multiformats/go-multicodec v0.4.1 // indirect - github.com/multiformats/go-multihash v0.1.0 // indirect + github.com/multiformats/go-multiaddr v0.6.0 // indirect + github.com/multiformats/go-multibase v0.1.1 // indirect + github.com/multiformats/go-multicodec v0.5.0 // indirect + github.com/multiformats/go-multihash v0.2.1 // indirect github.com/multiformats/go-varint v0.0.6 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.1.0-rc2 // indirect - github.com/pelletier/go-toml/v2 v2.0.6 // indirect - github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 // indirect + github.com/pelletier/go-toml v1.9.5 // indirect + github.com/pelletier/go-toml/v2 v2.0.7 // indirect + github.com/petermattis/goid v0.0.0-20221215004737-a150e88a970d // indirect github.com/pierrec/xxHash v0.1.5 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/client_golang v1.14.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/prometheus/common v0.40.0 // indirect + github.com/prometheus/procfs v0.9.0 // indirect github.com/rakyll/statik v0.1.7 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect - github.com/regen-network/cosmos-proto v0.3.1 // indirect - github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 // indirect - github.com/rs/cors v1.8.2 // indirect + github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect + github.com/rs/cors v1.8.3 // indirect github.com/sasha-s/go-deadlock v0.3.1 // indirect github.com/sirupsen/logrus v1.9.0 // indirect github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect github.com/spf13/afero v1.9.3 // indirect github.com/spf13/cast v1.5.0 // indirect - github.com/spf13/cobra v1.6.1 // indirect + github.com/spf13/cobra v1.7.0 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/spf13/viper v1.15.0 // indirect github.com/subosito/gotenv v1.4.2 // indirect - github.com/syndtr/goleveldb v1.0.1-0.20220614013038-64ee5596c38a // indirect + github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect + github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c // indirect github.com/tendermint/go-amino v0.16.0 // indirect - github.com/tendermint/tendermint v0.34.26 // indirect - github.com/tendermint/tm-db v0.6.8-0.20220506192307-f628bb5dc95b // indirect - github.com/tidwall/btree v1.5.0 // indirect - github.com/vedhavyas/go-subkey v1.0.3 // indirect + github.com/tidwall/btree v1.6.0 // indirect + github.com/tyler-smith/go-bip32 v1.0.0 // indirect + github.com/tyler-smith/go-bip39 v1.1.0 // indirect + github.com/ulikunitz/xz v0.5.11 // indirect github.com/zondax/hid v0.9.1 // indirect github.com/zondax/ledger-go v0.14.1 // indirect - go.etcd.io/bbolt v1.3.6 // indirect + go.etcd.io/bbolt v1.3.7 // indirect go.opencensus.io v0.24.0 // indirect go.uber.org/atomic v1.10.0 // indirect go.uber.org/multierr v1.8.0 // indirect - golang.org/x/crypto v0.5.0 // indirect - golang.org/x/exp v0.0.0-20230131160201-f062dba9d201 // indirect - golang.org/x/mod v0.8.0 // indirect - golang.org/x/net v0.7.0 // indirect + golang.org/x/crypto v0.8.0 // indirect + golang.org/x/exp v0.0.0-20230321023759-10a507213a29 // indirect + golang.org/x/mod v0.10.0 // indirect + golang.org/x/net v0.9.0 // indirect + golang.org/x/oauth2 v0.5.0 // indirect golang.org/x/sync v0.1.0 // indirect - golang.org/x/sys v0.5.0 // indirect - golang.org/x/term v0.5.0 // indirect - golang.org/x/text v0.7.0 // indirect - golang.org/x/tools v0.6.0 // indirect - google.golang.org/genproto v0.0.0-20230125152338-dcaf20b6aeaa // indirect - google.golang.org/grpc v1.53.0 // indirect - google.golang.org/protobuf v1.28.2-0.20220831092852-f930b1dc76e8 // indirect + golang.org/x/sys v0.7.0 // indirect + golang.org/x/term v0.7.0 // indirect + golang.org/x/text v0.9.0 // indirect + golang.org/x/tools v0.8.0 // indirect + golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect + google.golang.org/api v0.110.0 // indirect + google.golang.org/appengine v1.6.7 // indirect + google.golang.org/genproto v0.0.0-20230216225411-c8e22ba71e44 // indirect + google.golang.org/grpc v1.54.0 // indirect + google.golang.org/protobuf v1.30.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - lukechampine.com/blake3 v1.1.6 // indirect - lukechampine.com/uint128 v1.1.1 // indirect - modernc.org/cc/v3 v3.36.0 // indirect - modernc.org/ccgo/v3 v3.16.6 // indirect - modernc.org/libc v1.16.7 // indirect - modernc.org/mathutil v1.4.1 // indirect - modernc.org/memory v1.1.1 // indirect - modernc.org/opt v0.1.1 // indirect - modernc.org/sqlite v1.17.3 // indirect - modernc.org/strutil v1.1.1 // indirect - modernc.org/token v1.0.0 // indirect + lukechampine.com/blake3 v1.1.7 // indirect + lukechampine.com/uint128 v1.2.0 // indirect + modernc.org/cc/v3 v3.40.0 // indirect + modernc.org/ccgo/v3 v3.16.13 // indirect + modernc.org/libc v1.22.4 // indirect + modernc.org/mathutil v1.5.0 // indirect + modernc.org/memory v1.5.0 // indirect + modernc.org/opt v0.1.3 // indirect + modernc.org/sqlite v1.22.0 // indirect + modernc.org/strutil v1.1.3 // indirect + modernc.org/token v1.0.1 // indirect + nhooyr.io/websocket v1.8.6 // indirect + pgregory.net/rapid v0.5.5 // indirect + sigs.k8s.io/yaml v1.3.0 // indirect ) replace ( + + // interchaintest supports ICS features so we need this for now + // github.com/cosmos/cosmos-sdk => github.com/cosmos/cosmos-sdk v0.45.13-ics github.com/ChainSafe/go-schnorrkel => github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d github.com/ChainSafe/go-schnorrkel/1 => github.com/ChainSafe/go-schnorrkel v1.0.0 - // For this nested module, you always want to replace the parent reference with the current worktree. github.com/CosmosContracts/juno => ../../ github.com/btcsuite/btcd => github.com/btcsuite/btcd v0.22.2 //indirect - - // interchaintest supports ICS features so we need this for now - github.com/cosmos/cosmos-sdk => github.com/cosmos/cosmos-sdk v0.45.13-ics github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 - - // use informal system fork of tendermint - github.com/tendermint/tendermint => github.com/informalsystems/tendermint v0.34.26 - github.com/vedhavyas/go-subkey => github.com/strangelove-ventures/go-subkey v1.0.7 ) diff --git a/tests/interchaintest/go.sum b/tests/interchaintest/go.sum index ebf06eba6..6df600f95 100644 --- a/tests/interchaintest/go.sum +++ b/tests/interchaintest/go.sum @@ -1,14 +1,12 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= 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= @@ -19,36 +17,198 @@ 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/go.mod h1:OO6xxXdJyvuJPcEPBLN9BJPD+jep5G1+2U5B5gkRYtA= +cloud.google.com/go v0.110.0 h1:Zc8gqp3+a9/Eyph2KDmcGaPtbKRIoqq4YTlL4NMD0Ys= +cloud.google.com/go v0.110.0/go.mod h1:SJnCLqQ0FCFGSZMUNUf84MV3Aia54kn7pi8st7tMzaY= +cloud.google.com/go/aiplatform v1.22.0/go.mod h1:ig5Nct50bZlzV6NvKaTwmplLLddFx0YReh9WfTO5jKw= +cloud.google.com/go/aiplatform v1.24.0/go.mod h1:67UUvRBKG6GTayHKV8DBv2RtR1t93YRu5B1P3x99mYY= +cloud.google.com/go/analytics v0.11.0/go.mod h1:DjEWCu41bVbYcKyvlws9Er60YE4a//bK6mnhWvQeFNI= +cloud.google.com/go/analytics v0.12.0/go.mod h1:gkfj9h6XRf9+TS4bmuhPEShsh3hH8PAZzm/41OOhQd4= +cloud.google.com/go/area120 v0.5.0/go.mod h1:DE/n4mp+iqVyvxHN41Vf1CR602GiHQjFPusMFW6bGR4= +cloud.google.com/go/area120 v0.6.0/go.mod h1:39yFJqWVgm0UZqWTOdqkLhjoC7uFfgXRC8g/ZegeAh0= +cloud.google.com/go/artifactregistry v1.6.0/go.mod h1:IYt0oBPSAGYj/kprzsBjZ/4LnG/zOcHyFHjWPCi6SAQ= +cloud.google.com/go/artifactregistry v1.7.0/go.mod h1:mqTOFOnGZx8EtSqK/ZWcsm/4U8B77rbcLP6ruDU2Ixk= +cloud.google.com/go/asset v1.5.0/go.mod h1:5mfs8UvcM5wHhqtSv8J1CtxxaQq3AdBxxQi2jGW/K4o= +cloud.google.com/go/asset v1.7.0/go.mod h1:YbENsRK4+xTiL+Ofoj5Ckf+O17kJtgp3Y3nn4uzZz5s= +cloud.google.com/go/asset v1.8.0/go.mod h1:mUNGKhiqIdbr8X7KNayoYvyc4HbbFO9URsjbytpUaW0= +cloud.google.com/go/assuredworkloads v1.5.0/go.mod h1:n8HOZ6pff6re5KYfBXcFvSViQjDwxFkAkmUFffJRbbY= +cloud.google.com/go/assuredworkloads v1.6.0/go.mod h1:yo2YOk37Yc89Rsd5QMVECvjaMKymF9OP+QXWlKXUkXw= +cloud.google.com/go/assuredworkloads v1.7.0/go.mod h1:z/736/oNmtGAyU47reJgGN+KVoYoxeLBoj4XkKYscNI= +cloud.google.com/go/automl v1.5.0/go.mod h1:34EjfoFGMZ5sgJ9EoLsRtdPSNZLcfflJR39VbVNS2M0= +cloud.google.com/go/automl v1.6.0/go.mod h1:ugf8a6Fx+zP0D59WLhqgTDsQI9w07o64uf/Is3Nh5p8= 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/bigquery v1.42.0/go.mod h1:8dRTJxhtG+vwBKzE5OseQn/hiydoQN3EedCaOdYmxRA= +cloud.google.com/go/billing v1.4.0/go.mod h1:g9IdKBEFlItS8bTtlrZdVLWSSdSyFUZKXNS02zKMOZY= +cloud.google.com/go/billing v1.5.0/go.mod h1:mztb1tBc3QekhjSgmpf/CV4LzWXLzCArwpLmP2Gm88s= +cloud.google.com/go/binaryauthorization v1.1.0/go.mod h1:xwnoWu3Y84jbuHa0zd526MJYmtnVXn0syOjaJgy4+dM= +cloud.google.com/go/binaryauthorization v1.2.0/go.mod h1:86WKkJHtRcv5ViNABtYMhhNWRrD1Vpi//uKEy7aYEfI= +cloud.google.com/go/cloudtasks v1.5.0/go.mod h1:fD92REy1x5woxkKEkLdvavGnPJGEn8Uic9nWuLzqCpY= +cloud.google.com/go/cloudtasks v1.6.0/go.mod h1:C6Io+sxuke9/KNRkbQpihnW93SWDU3uXt92nu85HkYI= +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.10.0/go.mod h1:ER5CLbMxl90o2jtNbGSbtfOpQKR0t15FOtRsugnLrlU= +cloud.google.com/go/compute v1.18.0 h1:FEigFqoDbys2cvFkZ9Fjq4gnHBP55anJ0yQyau2f9oY= +cloud.google.com/go/compute v1.18.0/go.mod h1:1X7yHxec2Ga+Ss6jPyjxRxpu2uu7PLgsOVXvgU0yacs= +cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= +cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= +cloud.google.com/go/containeranalysis v0.5.1/go.mod h1:1D92jd8gRR/c0fGMlymRgxWD3Qw9C1ff6/T7mLgVL8I= +cloud.google.com/go/containeranalysis v0.6.0/go.mod h1:HEJoiEIu+lEXM+k7+qLCci0h33lX3ZqoYFdmPcoO7s4= +cloud.google.com/go/datacatalog v1.3.0/go.mod h1:g9svFY6tuR+j+hrTw3J2dNcmI0dzmSiyOzm8kpLq0a0= +cloud.google.com/go/datacatalog v1.5.0/go.mod h1:M7GPLNQeLfWqeIm3iuiruhPzkt65+Bx8dAKvScX8jvs= +cloud.google.com/go/datacatalog v1.6.0/go.mod h1:+aEyF8JKg+uXcIdAmmaMUmZ3q1b/lKLtXCmXdnc0lbc= +cloud.google.com/go/dataflow v0.6.0/go.mod h1:9QwV89cGoxjjSR9/r7eFDqqjtvbKxAK2BaYU6PVk9UM= +cloud.google.com/go/dataflow v0.7.0/go.mod h1:PX526vb4ijFMesO1o202EaUmouZKBpjHsTlCtB4parQ= +cloud.google.com/go/dataform v0.3.0/go.mod h1:cj8uNliRlHpa6L3yVhDOBrUXH+BPAO1+KFMQQNSThKo= +cloud.google.com/go/dataform v0.4.0/go.mod h1:fwV6Y4Ty2yIFL89huYlEkwUPtS7YZinZbzzj5S9FzCE= +cloud.google.com/go/datalabeling v0.5.0/go.mod h1:TGcJ0G2NzcsXSE/97yWjIZO0bXj0KbVlINXMG9ud42I= +cloud.google.com/go/datalabeling v0.6.0/go.mod h1:WqdISuk/+WIGeMkpw/1q7bK/tFEZxsrFJOJdY2bXvTQ= +cloud.google.com/go/dataqna v0.5.0/go.mod h1:90Hyk596ft3zUQ8NkFfvICSIfHFh1Bc7C4cK3vbhkeo= +cloud.google.com/go/dataqna v0.6.0/go.mod h1:1lqNpM7rqNLVgWBJyk5NF6Uen2PHym0jtVJonplVsDA= 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/datastream v1.2.0/go.mod h1:i/uTP8/fZwgATHS/XFu0TcNUhuA0twZxxQ3EyCUQMwo= +cloud.google.com/go/datastream v1.3.0/go.mod h1:cqlOX8xlyYF/uxhiKn6Hbv6WjwPPuI9W2M9SAXwaLLQ= +cloud.google.com/go/dialogflow v1.15.0/go.mod h1:HbHDWs33WOGJgn6rfzBW1Kv807BE3O1+xGbn59zZWI4= +cloud.google.com/go/dialogflow v1.16.1/go.mod h1:po6LlzGfK+smoSmTBnbkIZY2w8ffjz/RcGSS+sh1el0= +cloud.google.com/go/dialogflow v1.17.0/go.mod h1:YNP09C/kXA1aZdBgC/VtXX74G/TKn7XVCcVumTflA+8= +cloud.google.com/go/documentai v1.7.0/go.mod h1:lJvftZB5NRiFSX4moiye1SMxHx0Bc3x1+p9e/RfXYiU= +cloud.google.com/go/documentai v1.8.0/go.mod h1:xGHNEB7CtsnySCNrCFdCyyMz44RhFEEX2Q7UD0c5IhU= +cloud.google.com/go/domains v0.6.0/go.mod h1:T9Rz3GasrpYk6mEGHh4rymIhjlnIuB4ofT1wTxDeT4Y= +cloud.google.com/go/domains v0.7.0/go.mod h1:PtZeqS1xjnXuRPKE/88Iru/LdfoRyEHYA9nFQf4UKpg= +cloud.google.com/go/edgecontainer v0.1.0/go.mod h1:WgkZ9tp10bFxqO8BLPqv2LlfmQF1X8lZqwW4r1BTajk= +cloud.google.com/go/edgecontainer v0.2.0/go.mod h1:RTmLijy+lGpQ7BXuTDa4C4ssxyXT34NIuHIgKuP4s5w= +cloud.google.com/go/functions v1.6.0/go.mod h1:3H1UA3qiIPRWD7PeZKLvHZ9SaQhR26XIJcC0A5GbvAk= +cloud.google.com/go/functions v1.7.0/go.mod h1:+d+QBcWM+RsrgZfV9xo6KfA1GlzJfxcfZcRPEhDDfzg= +cloud.google.com/go/gaming v1.5.0/go.mod h1:ol7rGcxP/qHTRQE/RO4bxkXq+Fix0j6D4LFPzYTIrDM= +cloud.google.com/go/gaming v1.6.0/go.mod h1:YMU1GEvA39Qt3zWGyAVA9bpYz/yAhTvaQ1t2sK4KPUA= +cloud.google.com/go/gkeconnect v0.5.0/go.mod h1:c5lsNAg5EwAy7fkqX/+goqFsU1Da/jQFqArp+wGNr/o= +cloud.google.com/go/gkeconnect v0.6.0/go.mod h1:Mln67KyU/sHJEBY8kFZ0xTeyPtzbq9StAVvEULYK16A= +cloud.google.com/go/gkehub v0.9.0/go.mod h1:WYHN6WG8w9bXU0hqNxt8rm5uxnk8IH+lPY9J2TV7BK0= +cloud.google.com/go/gkehub v0.10.0/go.mod h1:UIPwxI0DsrpsVoWpLB0stwKCP+WFVG9+y977wO+hBH0= +cloud.google.com/go/grafeas v0.2.0/go.mod h1:KhxgtF2hb0P191HlY5besjYm6MqTSTj3LSI+M+ByZHc= +cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY= +cloud.google.com/go/iam v0.5.0/go.mod h1:wPU9Vt0P4UmCux7mqtRu6jcpPAb74cP1fh50J3QpkUc= +cloud.google.com/go/iam v0.12.0 h1:DRtTY29b75ciH6Ov1PHb4/iat2CLCvrOm40Q0a6DFpE= +cloud.google.com/go/iam v0.12.0/go.mod h1:knyHGviacl11zrtZUoDuYpDgLjvr28sLQaG0YB2GYAY= +cloud.google.com/go/language v1.4.0/go.mod h1:F9dRpNFQmJbkaop6g0JhSBXCNlO90e1KWx5iDdxbWic= +cloud.google.com/go/language v1.6.0/go.mod h1:6dJ8t3B+lUYfStgls25GusK04NLh3eDLQnWM3mdEbhI= +cloud.google.com/go/lifesciences v0.5.0/go.mod h1:3oIKy8ycWGPUyZDR/8RNnTOYevhaMLqh5vLUXs9zvT8= +cloud.google.com/go/lifesciences v0.6.0/go.mod h1:ddj6tSX/7BOnhxCSd3ZcETvtNr8NZ6t/iPhY2Tyfu08= +cloud.google.com/go/longrunning v0.3.0 h1:NjljC+FYPV3uh5/OwWT6pVU+doBqMg2x/rZlE+CamDs= +cloud.google.com/go/mediatranslation v0.5.0/go.mod h1:jGPUhGTybqsPQn91pNXw0xVHfuJ3leR1wj37oU3y1f4= +cloud.google.com/go/mediatranslation v0.6.0/go.mod h1:hHdBCTYNigsBxshbznuIMFNe5QXEowAuNmmC7h8pu5w= +cloud.google.com/go/memcache v1.4.0/go.mod h1:rTOfiGZtJX1AaFUrOgsMHX5kAzaTQ8azHiuDoTPzNsE= +cloud.google.com/go/memcache v1.5.0/go.mod h1:dk3fCK7dVo0cUU2c36jKb4VqKPS22BTkf81Xq617aWM= +cloud.google.com/go/metastore v1.5.0/go.mod h1:2ZNrDcQwghfdtCwJ33nM0+GrBGlVuh8rakL3vdPY3XY= +cloud.google.com/go/metastore v1.6.0/go.mod h1:6cyQTls8CWXzk45G55x57DVQ9gWg7RiH65+YgPsNh9s= +cloud.google.com/go/networkconnectivity v1.4.0/go.mod h1:nOl7YL8odKyAOtzNX73/M5/mGZgqqMeryi6UPZTk/rA= +cloud.google.com/go/networkconnectivity v1.5.0/go.mod h1:3GzqJx7uhtlM3kln0+x5wyFvuVH1pIBJjhCpjzSt75o= +cloud.google.com/go/networksecurity v0.5.0/go.mod h1:xS6fOCoqpVC5zx15Z/MqkfDwH4+m/61A3ODiDV1xmiQ= +cloud.google.com/go/networksecurity v0.6.0/go.mod h1:Q5fjhTr9WMI5mbpRYEbiexTzROf7ZbDzvzCrNl14nyU= +cloud.google.com/go/notebooks v1.2.0/go.mod h1:9+wtppMfVPUeJ8fIWPOq1UnATHISkGXGqTkxeieQ6UY= +cloud.google.com/go/notebooks v1.3.0/go.mod h1:bFR5lj07DtCPC7YAAJ//vHskFBxA5JzYlH68kXVdk34= +cloud.google.com/go/osconfig v1.7.0/go.mod h1:oVHeCeZELfJP7XLxcBGTMBvRO+1nQ5tFG9VQTmYS2Fs= +cloud.google.com/go/osconfig v1.8.0/go.mod h1:EQqZLu5w5XA7eKizepumcvWx+m8mJUhEwiPqWiZeEdg= +cloud.google.com/go/oslogin v1.4.0/go.mod h1:YdgMXWRaElXz/lDk1Na6Fh5orF7gvmJ0FGLIs9LId4E= +cloud.google.com/go/oslogin v1.5.0/go.mod h1:D260Qj11W2qx/HVF29zBg+0fd6YCSjSqLUkY/qEenQU= +cloud.google.com/go/phishingprotection v0.5.0/go.mod h1:Y3HZknsK9bc9dMi+oE8Bim0lczMU6hrX0UpADuMefr0= +cloud.google.com/go/phishingprotection v0.6.0/go.mod h1:9Y3LBLgy0kDTcYET8ZH3bq/7qni15yVUoAxiFxnlSUA= +cloud.google.com/go/privatecatalog v0.5.0/go.mod h1:XgosMUvvPyxDjAVNDYxJ7wBW8//hLDDYmnsNcMGq1K0= +cloud.google.com/go/privatecatalog v0.6.0/go.mod h1:i/fbkZR0hLN29eEWiiwue8Pb+GforiEIBnV9yrRUOKI= 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= cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/recaptchaenterprise v1.3.1/go.mod h1:OdD+q+y4XGeAlxRaMn1Y7/GveP6zmq76byL6tjPE7d4= +cloud.google.com/go/recaptchaenterprise/v2 v2.1.0/go.mod h1:w9yVqajwroDNTfGuhmOjPDN//rZGySaf6PtFVcSCa7o= +cloud.google.com/go/recaptchaenterprise/v2 v2.2.0/go.mod h1:/Zu5jisWGeERrd5HnlS3EUGb/D335f9k51B/FVil0jk= +cloud.google.com/go/recaptchaenterprise/v2 v2.3.0/go.mod h1:O9LwGCjrhGHBQET5CA7dd5NwwNQUErSgEDit1DLNTdo= +cloud.google.com/go/recommendationengine v0.5.0/go.mod h1:E5756pJcVFeVgaQv3WNpImkFP8a+RptV6dDLGPILjvg= +cloud.google.com/go/recommendationengine v0.6.0/go.mod h1:08mq2umu9oIqc7tDy8sx+MNJdLG0fUi3vaSVbztHgJ4= +cloud.google.com/go/recommender v1.5.0/go.mod h1:jdoeiBIVrJe9gQjwd759ecLJbxCDED4A6p+mqoqDvTg= +cloud.google.com/go/recommender v1.6.0/go.mod h1:+yETpm25mcoiECKh9DEScGzIRyDKpZ0cEhWGo+8bo+c= +cloud.google.com/go/redis v1.7.0/go.mod h1:V3x5Jq1jzUcg+UNsRvdmsfuFnit1cfe3Z/PGyq/lm4Y= +cloud.google.com/go/redis v1.8.0/go.mod h1:Fm2szCDavWzBk2cDKxrkmWBqoCiL1+Ctwq7EyqBCA/A= +cloud.google.com/go/retail v1.8.0/go.mod h1:QblKS8waDmNUhghY2TI9O3JLlFk8jybHeV4BF19FrE4= +cloud.google.com/go/retail v1.9.0/go.mod h1:g6jb6mKuCS1QKnH/dpu7isX253absFl6iE92nHwlBUY= +cloud.google.com/go/scheduler v1.4.0/go.mod h1:drcJBmxF3aqZJRhmkHQ9b3uSSpQoltBPGPxGAWROx6s= +cloud.google.com/go/scheduler v1.5.0/go.mod h1:ri073ym49NW3AfT6DZi21vLZrG07GXr5p3H1KxN5QlI= +cloud.google.com/go/secretmanager v1.6.0/go.mod h1:awVa/OXF6IiyaU1wQ34inzQNc4ISIDIrId8qE5QGgKA= +cloud.google.com/go/security v1.5.0/go.mod h1:lgxGdyOKKjHL4YG3/YwIL2zLqMFCKs0UbQwgyZmfJl4= +cloud.google.com/go/security v1.7.0/go.mod h1:mZklORHl6Bg7CNnnjLH//0UlAlaXqiG7Lb9PsPXLfD0= +cloud.google.com/go/security v1.8.0/go.mod h1:hAQOwgmaHhztFhiQ41CjDODdWP0+AE1B3sX4OFlq+GU= +cloud.google.com/go/securitycenter v1.13.0/go.mod h1:cv5qNAqjY84FCN6Y9z28WlkKXyWsgLO832YiWwkCWcU= +cloud.google.com/go/securitycenter v1.14.0/go.mod h1:gZLAhtyKv85n52XYWt6RmeBdydyxfPeTrpToDPw4Auc= +cloud.google.com/go/servicedirectory v1.4.0/go.mod h1:gH1MUaZCgtP7qQiI+F+A+OpeKF/HQWgtAddhTbhL2bs= +cloud.google.com/go/servicedirectory v1.5.0/go.mod h1:QMKFL0NUySbpZJ1UZs3oFAmdvVxhhxB6eJ/Vlp73dfg= +cloud.google.com/go/speech v1.6.0/go.mod h1:79tcr4FHCimOp56lwC01xnt/WPJZc4v3gzyT7FoBkCM= +cloud.google.com/go/speech v1.7.0/go.mod h1:KptqL+BAQIhMsj1kOP2la5DSEEerPDuOP/2mmkhHhZQ= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= 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= -collectd.org v0.3.0/go.mod h1:A/8DzQBkF6abtvrT2j/AU/4tiBgJWYyh0y/oB/4MlWE= +cloud.google.com/go/storage v1.22.1/go.mod h1:S8N1cAStu7BOeFfE8KAQzmyyLkK8p/vmRq6kuBTW58Y= +cloud.google.com/go/storage v1.23.0/go.mod h1:vOEEDNFnciUMhBeT6hsJIn3ieU5cFRmzeLgDvXzfIXc= +cloud.google.com/go/storage v1.27.0/go.mod h1:x9DOL8TK/ygDUMieqwfhdpQryTeEkhGKMi80i/iqR2s= +cloud.google.com/go/storage v1.29.0 h1:6weCgzRvMg7lzuUurI4697AqIRPU1SvzHhynwpW31jI= +cloud.google.com/go/storage v1.29.0/go.mod h1:4puEjyTKnku6gfKoTfNOU/W+a9JyuVNxjpS5GBrB8h4= +cloud.google.com/go/talent v1.1.0/go.mod h1:Vl4pt9jiHKvOgF9KoZo6Kob9oV4lwd/ZD5Cto54zDRw= +cloud.google.com/go/talent v1.2.0/go.mod h1:MoNF9bhFQbiJ6eFD3uSsg0uBALw4n4gaCaEjBw9zo8g= +cloud.google.com/go/videointelligence v1.6.0/go.mod h1:w0DIDlVRKtwPCn/C4iwZIJdvC69yInhW0cfi+p546uU= +cloud.google.com/go/videointelligence v1.7.0/go.mod h1:k8pI/1wAhjznARtVT9U1llUaFNPh7muw8QyOUpavru4= +cloud.google.com/go/vision v1.2.0/go.mod h1:SmNwgObm5DpFBme2xpyOyasvBc1aPdjvMk2bBk0tKD0= +cloud.google.com/go/vision/v2 v2.2.0/go.mod h1:uCdV4PpN1S0jyCyq8sIM42v2Y6zOLkZs+4R9LrGYwFo= +cloud.google.com/go/vision/v2 v2.3.0/go.mod h1:UO61abBx9QRMFkNBbf1D8B1LXdS2cGiiCRx0vSpZoUo= +cloud.google.com/go/webrisk v1.4.0/go.mod h1:Hn8X6Zr+ziE2aNd8SliSDWpEnSS1u4R9+xXZmFiHmGE= +cloud.google.com/go/webrisk v1.5.0/go.mod h1:iPG6fr52Tv7sGk0H6qUFzmL3HHZev1htXuWDEEsqMTg= +cloud.google.com/go/workflows v1.6.0/go.mod h1:6t9F5h/unJz41YqfBmqSASJSXccBLtD1Vwf+KmJENM0= +cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoISEXH2bcHC3M= +cosmossdk.io/api v0.3.1 h1:NNiOclKRR0AOlO4KIqeaG6PS6kswOMhHD0ir0SscNXE= +cosmossdk.io/api v0.3.1/go.mod h1:DfHfMkiNA2Uhy8fj0JJlOCYOBp4eWUUJ1te5zBGNyIw= +cosmossdk.io/core v0.5.1 h1:vQVtFrIYOQJDV3f7rw4pjjVqc1id4+mE0L9hHP66pyI= +cosmossdk.io/core v0.5.1/go.mod h1:KZtwHCLjcFuo0nmDc24Xy6CRNEL9Vl/MeimQ2aC7NLE= +cosmossdk.io/depinject v1.0.0-alpha.3 h1:6evFIgj//Y3w09bqOUOzEpFj5tsxBqdc5CfkO7z+zfw= +cosmossdk.io/depinject v1.0.0-alpha.3/go.mod h1:eRbcdQ7MRpIPEM5YUJh8k97nxHpYbc3sMUnEtt8HPWU= +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 h1:ro9w7eKx23om2tZz/VM2Pf+z2WAbGX1yDQQOJ6iGeJw= +cosmossdk.io/math v1.0.0/go.mod h1:Ygz4wBHrgc7g0N+8+MrnTfS9LLn9aaTGa9hKopuym5k= +cosmossdk.io/simapp v0.0.0-20230224204036-a6adb0821462 h1:g8muUHnXL8vhld2Sjilyhb1UQObc+x9GVuDK43TYZns= +cosmossdk.io/simapp v0.0.0-20230224204036-a6adb0821462/go.mod h1:4Dd3NLoLYoN90kZ0uyHoTHzVVk9+J0v4HhZRBNTAq2c= +cosmossdk.io/tools/rosetta v0.2.1 h1:ddOMatOH+pbxWbrGJKRAawdBkPYLfKXutK9IETnjYxw= +cosmossdk.io/tools/rosetta v0.2.1/go.mod h1:Pqdc1FdvkNV3LcNIkYWt2RQY6IP1ge6YWZk8MhhO9Hw= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -filippo.io/edwards25519 v1.0.0-rc.1 h1:m0VOOB23frXZvAOK44usCgLWvtsxIoMCTBGJZlpmGfU= -filippo.io/edwards25519 v1.0.0-rc.1/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns= +filippo.io/edwards25519 v1.0.0 h1:0wAIcmJUqRdI8IJ/3eGi5/HwXZWPujYXXlkrQogz0Ek= +filippo.io/edwards25519 v1.0.0/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns= 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/99designs/keyring v1.2.2 h1:pZd3neh/EmUzWONb35LxQfvuY7kiSXAq3HQd97+XBn0= +github.com/99designs/keyring v1.2.2/go.mod h1:wes/FrByc8j7lFOAGLGSNEg8f/PaI3cgTBqhFkHUrPk= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak= @@ -58,185 +218,214 @@ github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d h1:nalkkPQ github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d/go.mod h1:URdX5+vg25ts3aCh8H5IFZybJYKWhJHYMTnf+ULtoC4= github.com/ChainSafe/go-schnorrkel v1.0.0 h1:3aDA67lAykLaG1y3AOjs88dMxC88PgUuHRrLeDnvGIM= github.com/ChainSafe/go-schnorrkel v1.0.0/go.mod h1:dpzHYVxLZcp8pjlV+O+UR8K0Hp/z7vcchBSbMBEhCw4= -github.com/CosmWasm/wasmd v0.31.0 h1:xACf6A/SkCeGWQWrKGsR4X9PQb5G4XYuNfnrl+HQ1mE= -github.com/CosmWasm/wasmd v0.31.0/go.mod h1:VcyDGk/ISVlMUeW+1GGL0zdHWBS2FPwLEV2qZ86l7l8= -github.com/CosmWasm/wasmvm v1.2.1 h1:si0tRsRDdUShV0k51Wn6zRKlmj3/WWP9Yr4cLmDTf+8= -github.com/CosmWasm/wasmvm v1.2.1/go.mod h1:vW/E3h8j9xBQs9bCoijDuawKo9kCtxOaS8N8J7KFtkc= -github.com/CosmosContracts/juno/v13 v13.0.0 h1:/1pikuWzkT9a3WN+o7JBgwvgzWFDF5cIpzJoXoHdHYo= -github.com/CosmosContracts/juno/v13 v13.0.0/go.mod h1:Woy1aY09yjO04m+9DQuNUOy10NTyLT0RcoysqfZGCyM= -github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= +github.com/ComposableFi/go-subkey/v2 v2.0.0-tm03420 h1:oknQF/iIhf5lVjbwjsVDzDByupRhga8nhA3NAmwyHDA= +github.com/ComposableFi/go-subkey/v2 v2.0.0-tm03420/go.mod h1:KYkiMX5AbOlXXYfxkrYPrRPV6EbVUALTQh5ptUOJzu8= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= +github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e h1:ahyvB3q25YnZWly5Gq1ekg6jcmWaGj/vG/MhF4aisoc= +github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:kGUqhHd//musdITWjFvNTHn90WG9bMLBEPQZ17Cmlpw= +github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec h1:1Qb69mGp/UtRPn422BH4/Y4Q3SLUrD9KHuDkm8iodFc= +github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec/go.mod h1:CD8UlnlLDiqb36L110uqiP2iSflVjx9g/3U9hCI4q2U= +github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg= github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE= +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= +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 h1:fLjPD/aNc3UIOA6tDi6QXUemppXK3P9BI7mr2hd6gx8= -github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= github.com/StirlingMarketingGroup/go-namecase v1.0.0 h1:2CzaNtCzc4iNHirR+5ru9OzGg8rQp860gqLBFqRI02Y= github.com/StirlingMarketingGroup/go-namecase v1.0.0/go.mod h1:ZsoSKcafcAzuBx+sndbxHu/RjDcDTrEdT4UvhniHfio= -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/Workiva/go-datastructures v1.0.53 h1:J6Y/52yX10Xc5JjXmGtWoSSxs3mZnGSaq37xZZh7Yig= -github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= +github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= +github.com/adlio/schema v1.3.3 h1:oBJn8I02PyTB466pZO1UZEn1TV5XLlifBSyMrmHl/1I= +github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= +github.com/alecthomas/participle/v2 v2.0.0-alpha7 h1:cK4vjj0VSgb3lN1nuKA5F7dw+1s1pWBe5bx7nNCnN+c= 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/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.4.0 h1:yCQqn7dwca4ITXb+CbubHmedzaQYHhNhrEXLYUeEe8Q= -github.com/armon/go-metrics v0.4.0/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4= -github.com/avast/retry-go/v4 v4.0.4 h1:38hLf0DsRXh+hOF6HbTni0+5QGTNdw9zbaMD7KAO830= -github.com/avast/retry-go/v4 v4.0.4/go.mod h1:HqmLvS2VLdStPCGDFjSuZ9pzlTqVRldCI4w2dO4m1Ms= -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/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= +github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA= +github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4= +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/avast/retry-go/v4 v4.3.4 h1:pHLkL7jvCvP317I8Ge+Km2Yhntv3SdkJm7uekkqbKhM= +github.com/avast/retry-go/v4 v4.3.4/go.mod h1:rv+Nla6Vk3/ilU0H51VHddWHiwimzX66yZ0JT6T+UvE= +github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= +github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/aws/aws-sdk-go v1.44.122/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= +github.com/aws/aws-sdk-go v1.44.203 h1:pcsP805b9acL3wUqa4JR2vg1k2wnItkDYNvfmcy6F+U= +github.com/aws/aws-sdk-go v1.44.203/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= +github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= 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/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816 h1:41iFGWnSlI2gVpmOtVTJZNodLdLQLn/KsJqFvXwnd/s= github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816/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.22.2 h1:vBZ+lGGd1XubpOWO67ITJpAEsICWhA0YzqkcpkgNBfo= -github.com/btcsuite/btcd v0.22.2/go.mod h1:wqgTSL29+50LRkmOVknEdmt8ZojIzhuWvgu/iptuN7Y= -github.com/btcsuite/btcd/btcec/v2 v2.1.2/go.mod h1:ctjw4H1kknNJmRN4iP1R7bTQ+v3GJkZBd6mui8ZsAZE= github.com/btcsuite/btcd/btcec/v2 v2.3.2 h1:5n0X6hX0Zk+6omWcihdYvdAlGf2DfasC0GMf7DClJ3U= github.com/btcsuite/btcd/btcec/v2 v2.3.2/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= github.com/btcsuite/btcd/btcutil v1.1.2 h1:XLMbX8JQEiwMcYft2EGi8zPUkoa0abKIU6/BJSRsjzQ= -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/btcutil v1.0.3-0.20201208143702-a53e38424cce h1:YtWJF7RHm2pYCvA5t0RPmAaLUhREsKuKd+SLhxFbFeQ= -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/centrifuge/go-substrate-rpc-client/v4 v4.0.4 h1:G2kCJurlIkguX0oxxI9sPPENuQqMVhIhV9RVkh/dpDg= -github.com/centrifuge/go-substrate-rpc-client/v4 v4.0.4/go.mod h1:5g1oM4Zu3BOaLpsKQ+O8PAv2kNuq+kPcA1VzFbsSqxE= -github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/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/logex v1.2.1 h1:XHDu3E6q+gdHgsdTPH6ImJMIp436vR6MPtH8gP05QzM= +github.com/chzyer/logex v1.2.1/go.mod h1:JLbx6lG2kDbNRFnfkgvh4eRJRPX1QCoOIWomwysCBrQ= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/readline v1.5.1 h1:upd/6fQk4src78LMRzh5vItIt361/o4uq553V8B5sGI= +github.com/chzyer/readline v1.5.1/go.mod h1:Eh+b79XXUwfKfcPLepksvw2tcLE/Ct21YObkaSkeBlk= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/chzyer/test v1.0.0 h1:p3BQDXSxOhOG0P9z6/hGnII4LGiEPOYBhs8asl/fC04= +github.com/chzyer/test v1.0.0/go.mod h1:2JlltgoNkt4TW/z9V/IzDdFaMTM2JPIi26O1pF38GC8= 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/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cloudflare/cloudflare-go v0.14.0/go.mod h1:EnwdgGMaFOruiPZRFSgn+TsQ3hQ7C/YWzIGLeu5c304= +github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e h1:0XBUw73chJ1VYSsfvcPvVT7auykAJce9FpRr10L6Qhw= +github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:P13beTBKr5Q18lJe1rIoLUqjM+CB1zYrRg44ZqGuQSA= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/coinbase/rosetta-sdk-go v0.7.9 h1:lqllBjMnazTjIqYrOGv8h8jxjg9+hJazIGZr9ZvoCcA= +github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= +github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cockroachdb/apd/v2 v2.0.2 h1:weh8u7Cneje73dDh+2tEVLUvyBc89iwepWCD8b8034E= +github.com/cockroachdb/apd/v3 v3.1.0 h1:MK3Ow7LH0W8zkd5GMKA1PvS9qG3bWFI95WaVNfyZJ/w= +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/types v1.0.0 h1:jpVIwLcPoOeCR6o1tU+Xv7r5bMONNbHU7MuEHboiFuA= +github.com/coinbase/rosetta-sdk-go/types v1.0.0/go.mod h1:eq7W2TMRH22GTW0N0beDnN931DW0/WOI1R2sdHNHG4c= +github.com/cometbft/cometbft v0.37.1 h1:KLxkQTK2hICXYq21U2hn1W5hOVYUdQgDQ1uB+90xPIg= +github.com/cometbft/cometbft v0.37.1/go.mod h1:Y2MMMN//O5K4YKd8ze4r9jmk4Y7h0ajqILXbH5JQFVs= +github.com/cometbft/cometbft-db v0.7.0 h1:uBjbrBx4QzU0zOEnU8KxoDl18dMNgDh+zZRUE0ucsbo= +github.com/cometbft/cometbft-db v0.7.0/go.mod h1:yiKJIm2WKrt6x8Cyxtq9YTEcIMPcEe4XPxhgX59Fzf0= github.com/confio/ics23/go v0.9.0 h1:cWs+wdbS2KRPZezoaaj+qBleXgUk5WOQFMP3CQFGTr4= github.com/confio/ics23/go v0.9.0/go.mod h1:4LPZ2NYqnYIVRklaozjNR1FScgDJ2s5Xrp+e/mYVRak= -github.com/consensys/bavard v0.1.8-0.20210406032232-f3452dc9b572/go.mod h1:Bpd0/3mZuaj6Sj+PqrmIquiOKy397AKGThQPaGzNXAQ= -github.com/consensys/gnark-crypto v0.4.1-0.20210426202927-39ac3d4b3f1f/go.mod h1:815PAHg3wvysy0SyIqanF8gZ0Y1wjk/hrDHD/iT88+Q= +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= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cosmos/btcutil v1.0.5 h1:t+ZFcX77LpKtDBhjucvnOH8C2l2ioGsBNEQ3jef8xFk= github.com/cosmos/btcutil v1.0.5/go.mod h1:IyB7iuqZMJlthe2tkIFL33xPyzbFYP0XVdS8P5lUPis= github.com/cosmos/cosmos-proto v1.0.0-beta.2 h1:X3OKvWgK9Gsejo0F1qs5l8Qn6xJV/AzgIWR2wZ8Nua8= github.com/cosmos/cosmos-proto v1.0.0-beta.2/go.mod h1:+XRCLJ14pr5HFEHIUcn51IKXD1Fy3rkEQqt4WqmN4V0= -github.com/cosmos/cosmos-sdk v0.45.13-ics h1:EuBiwr9UO/s+dcjCXrrmwrZPowEhBYguIdMcr5fH3dg= -github.com/cosmos/cosmos-sdk v0.45.13-ics/go.mod h1:tpDFgc98sgRcLLRiosBSyos8EZoDHv1xab9HPLGLQJ4= +github.com/cosmos/cosmos-sdk v0.47.1 h1:HnaCYtaAMWZp1SdlwwE1mPJ8kFlZ/TuEJ/ciNXH6Uno= +github.com/cosmos/cosmos-sdk v0.47.1/go.mod h1:14tO5KQaTrl2q3OxBnDRfue7TRN9zkXS0cLutrSqkOo= 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.6 h1:Ee7z15dWJaGlgM2rWrK8N2IX7PQcuccu8oG68jp5RL4= -github.com/cosmos/gogoproto v1.4.6/go.mod h1:VS/ASYmPgv6zkPKLjR9EB91lwbLHOzaGCirmKKhncfI= -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.5 h1:rGA3hOrgNxgRM5wYcSCxgQBap7fW82WZgY78V9po/iY= -github.com/cosmos/iavl v0.19.5/go.mod h1:X9PKD3J0iFxdmgNLa7b2LYWdsGd90ToV5cAONApkEPw= -github.com/cosmos/ibc-go/v7 v4.3.0 h1:yOzVsyZzsv4XPBux8gq+D0LhZn45yGWKjvT+6Vyo5no= -github.com/cosmos/ibc-go/v7 v4.3.0/go.mod h1:CcLvIoi9NNtIbNsxs4KjBGjYhlwqtsmXy1AKARKiMzQ= -github.com/cosmos/interchain-security v1.0.0 h1:xNQjjigqH3mzEKSGQhAhKy8I0TA8XR2z5rRTxRBKK3o= -github.com/cosmos/interchain-security v1.0.0/go.mod h1:J9SbXUJT1GSe+mZy+MDCxtuAfbhwCKBEJRYnfjXsE8Q= -github.com/cosmos/ledger-cosmos-go v0.12.2 h1:/XYaBlE2BJxtvpkHiBm97gFGSGmYGKunKyF3nNqAXZA= -github.com/cosmos/ledger-cosmos-go v0.12.2/go.mod h1:ZcqYgnfNJ6lAXe4HPtWgarNEY+B74i+2/8MhZw4ziiI= +github.com/cosmos/gogogateway v1.2.0 h1:Ae/OivNhp8DqBi/sh2A8a1D0y638GpL3tkmLQAiKxTE= +github.com/cosmos/gogogateway v1.2.0/go.mod h1:iQpLkGWxYcnCdz5iAdLcRBSw3h7NXeOkZ4GUkT+tbFI= +github.com/cosmos/gogoproto v1.4.2/go.mod h1:cLxOsn1ljAHSV527CHOtaIP91kK6cCrZETRBrkzItWU= +github.com/cosmos/gogoproto v1.4.8 h1:BrHKc6WFZt8+jRV71vKSQE+JrfF+JAnzrKo2VP7wIZ4= +github.com/cosmos/gogoproto v1.4.8/go.mod h1:hnb0DIEWTv+wdNzNcqus5xCQXq5+CXauq1FJuurRfVY= +github.com/cosmos/iavl v0.20.0 h1:fTVznVlepH0KK8NyKq8w+U7c2L6jofa27aFX6YGlm38= +github.com/cosmos/iavl v0.20.0/go.mod h1:WO7FyvaZJoH65+HFOsDir7xU9FWk2w9cHXNW1XHcl7A= +github.com/cosmos/ibc-go/v7 v7.0.0 h1:j4kyywlG0hhDmT9FmSaR5iCIka7Pz7kJTxGWY1nlV9Q= +github.com/cosmos/ibc-go/v7 v7.0.0/go.mod h1:BFh8nKWjr5zeR2OZfhkzdgDzj1+KjRn3aJLpwapStj8= +github.com/cosmos/ics23/go v0.9.1-0.20221207100636-b1abd8678aab h1:I9ialKTQo7248V827Bba4OuKPmk+FPzmTVHsLXaIJWw= +github.com/cosmos/ics23/go v0.9.1-0.20221207100636-b1abd8678aab/go.mod h1:2CwqasX5dSD7Hbp/9b6lhK6BwoBDCBldx7gPKRukR60= +github.com/cosmos/ledger-cosmos-go v0.12.1 h1:sMBxza5p/rNK/06nBSNmsI/WDqI0pVJFVNihy1Y984w= +github.com/cosmos/ledger-cosmos-go v0.12.1/go.mod h1:dhO6kj+Y+AHIOgAe4L9HL/6NDdyyth4q238I9yFpD2g= +github.com/cosmos/rosetta-sdk-go v0.10.0 h1:E5RhTruuoA7KTIXUcMicL76cffyeoyvNybzUGSKFTcM= +github.com/cosmos/rosetta-sdk-go v0.10.0/go.mod h1:SImAZkb96YbwvoRkzSMQB6noNJXFgWl/ENIznEoYQI4= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/creachadair/taskgroup v0.3.2 h1:zlfutDS+5XG40AOxcHDSThxKzns8Tnr9jnr6VqkYlkM= -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/creachadair/taskgroup v0.4.2 h1:jsBLdAJE42asreGss2xZGZ8fJra7WtwnHWeJFxv2Li8= +github.com/creachadair/taskgroup v0.4.2/go.mod h1:qiXUOSrbwAY3u0JPGTzObbE3yf9hcXHDKBZ2ZjpCbgM= +github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= +github.com/cucumber/common/gherkin/go/v22 v22.0.0 h1:4K8NqptbvdOrjL9DEea6HFjSpbdT9+Q5kgLpmmsHYl0= +github.com/cucumber/common/messages/go/v17 v17.1.1 h1:RNqopvIFyLWnKv0LfATh34SWBhXeoFTJnSrgm9cT/Ts= 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 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 h1:sk9/l/KqpunDwP7pSjUg0keiOOLEnOBHzykLrsPppp4= github.com/deckarep/golang-set v1.8.0/go.mod h1:5nI87KwE7wgsBU1F4GKAw2Qod7p5kyS383rP6+o6qqo= -github.com/decred/base58 v1.0.3 h1:KGZuh8d1WEMIrK0leQRM47W85KqCAdl2N+uagbctdDI= -github.com/decred/base58 v1.0.3/go.mod h1:pXP9cXCfM2sFLb2viz2FNIdeMWmZDBKG3ZBYbiSM78E= +github.com/decred/base58 v1.0.4 h1:QJC6B0E0rXOPA8U/kw2rP+qiRJsUaE2Er+pYb3siUeA= +github.com/decred/base58 v1.0.4/go.mod h1:jJswKPEdvpFpvf7dsDvFZyLT22xZ9lWqEByX38oGd9E= github.com/decred/dcrd/chaincfg/chainhash v1.0.2 h1:rt5Vlq/jM3ZawwiacWjPa+smINyLRN07EO0cNBV6DGU= github.com/decred/dcrd/chaincfg/chainhash v1.0.2/go.mod h1:BpbrGgrPTr3YJYRN3Bm+D9NuaFd+zGyNeIKgrhCXK60= github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= github.com/decred/dcrd/dcrec/secp256k1/v2 v2.0.0 h1:3GIJYXQDAKpLEFriGFN8SbSffak10UXHGdIcFaMPykY= github.com/decred/dcrd/dcrec/secp256k1/v2 v2.0.0/go.mod h1:3s92l0paYkZoIHuj4X93Teg/HB7eGM9x/zokGw+u4mY= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 h1:YLtO71vCjJRCBcrPMtQ9nqBsqpA1m5sE92cU+pd5Mcc= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= -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/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 h1:HbphB4TFFXpv7MNrT52FGrrgVXF1owhMVTHFZIlnvd4= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0/go.mod h1:DZGJHZMqrU4JJqFAWUS2UO1+lbSKsdiOoYi9Zzey7Fc= github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f h1:U5y3Y5UE0w7amNe7Z5G/twsBW0KEalRQXZzf8ufSh9I= -github.com/dgraph-io/badger/v3 v3.2103.2 h1:dpyM5eCJAtQCBcMCZcT4UBZchuTJgCywerHHgmxfxM8= -github.com/dgraph-io/badger/v3 v3.2103.2/go.mod h1:RHo4/GmYcKKh5Lxu63wLEMHJ70Pac2JqZRYGhlyAo2M= -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/desertbit/timer v0.0.0-20180107155436-c41aec40b27f/go.mod h1:xH/i4TFMt8koVQZ6WFms69WAsDWr2XsYL3Hkl7jkoLE= +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= +github.com/dgraph-io/ristretto v0.1.1 h1:6CWw5tJNgpegArSHpNHJKldNeq03FQCwYvfMVWajOK8= +github.com/dgraph-io/ristretto v0.1.1/go.mod h1:S1GPSBCYCIhmVNfcth17y2zZtQT6wzkzgwUve0VDWWA= 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-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/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= 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/docker v20.10.19+incompatible h1:lzEmjivyNHFHMNAFLXORMBXyGIhw/UP4DvJwvyKYq64= github.com/docker/docker v20.10.19+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/dop251/goja v0.0.0-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/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/dustin/go-humanize v1.0.1-0.20200219035652-afde56e7acac h1:opbrjaN/L8gg6Xh5D04Tem+8xVcz6ajZlGCs49mQgyg= -github.com/dustin/go-humanize v1.0.1-0.20200219035652-afde56e7acac/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= +github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= 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/eclipse/paho.mqtt.golang v1.2.0/go.mod h1:H9keYFcgq3Qr5OUJm/JZI/i6U7joQ8SYLhZwfeOo6Ts= +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 v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= +github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= +github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= +github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/ethereum/go-ethereum v1.10.17 h1:XEcumY+qSr1cZQaWsQs5Kck3FHB0V2RiMHPdTBJ+oT8= -github.com/ethereum/go-ethereum v1.10.17/go.mod h1:Lt5WzjM07XlXc95YzrhosmR4J9Ahd6X2wyEV2SvGhk0= +github.com/ethereum/go-ethereum v1.10.20 h1:75IW830ClSS40yrQC1ZCMZCt5I+zU16oqId2SiQwdQ4= +github.com/ethereum/go-ethereum v1.10.20/go.mod h1:LWUN82TCHGpxB3En5HVmLLzPD7YSrEUFmFfN1nKkVN0= 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= @@ -244,59 +433,66 @@ github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5Kwzbycv github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/felixge/httpsnoop v1.0.2 h1:+nS9g82KMXccJ/wp0zyRW9ZBHFETmMGtkk+2CTTrW4o= github.com/felixge/httpsnoop v1.0.2/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/fjl/memsize v0.0.0-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/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/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/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.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= +github.com/gin-gonic/gin v1.8.1 h1:4+fr/el88TOO3ewCmQr8cx/CtZ/umlIRIs5M4NTNjf8= 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= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= github.com/go-kit/kit v0.12.0 h1:e4o3o3IsBfAKQh5Qbbiqyfu97Ku7jrO/JbohvztANh4= github.com/go-kit/kit v0.12.0/go.mod h1:lHd+EkCZPIwYItmGDDRdhinkzX2A1sj+M9biaEaizzs= -github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= -github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= github.com/go-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU= github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= -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 h1:2lOsA72HgjxAuMlKpFiCbHTvu44PIVkZ5hqm3RSdI/E= -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-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= -github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4= +github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= +github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= +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= +github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no= +github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= +github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= +github.com/go-playground/validator/v10 v10.11.1 h1:prmOlTVv+YjZjmRmNSF3VmspqJIxJWXmqUsHwfTRRkQ= +github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw= github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +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= +github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8= +github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= +github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo= +github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= +github.com/goccy/go-json v0.9.11 h1:/pAaQDLHEoCq/5FFmSKBswWmK6H0e8g4159Kc/X/nqk= 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/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/gofrs/uuid v4.3.0+incompatible h1:CaSVZxm5B+7o45rtab4jC2G37WGYX1zQfuU2i6DSvnc= +github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= +github.com/gogo/googleapis v1.4.1-0.20201022092350-68b0159b7869/go.mod h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c= +github.com/gogo/googleapis v1.4.1 h1:1Yx4Myt7BxzvUr5ldGSbwYiZG6t9wGBZ+8/fX3Wvtq0= +github.com/gogo/googleapis v1.4.1/go.mod h1:2lpHqI5OcWCtVElxXnPt+s8oJvMpySlOyM6xDCrzib4= 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= +github.com/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE= +github.com/golang/glog v1.1.0/go.mod h1:pfYeQZ3JWZoXTV5sFc986z3HTpwQs9At6P4ImfuP3NQ= +github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= 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= @@ -309,7 +505,9 @@ github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt 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= @@ -326,20 +524,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.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.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/flatbuffers v1.12.1 h1:MVlul7pQNoDzWRLTw5imwYsl+usrS1TXG2H4jg6ImGw= -github.com/google/flatbuffers v1.12.1/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= @@ -351,16 +547,22 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ 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/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/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= +github.com/google/martian/v3 v3.3.2 h1:IqNFLAmvJOgVlpdEBiQbDc2EwKW77amAycfTuWKdfvw= 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= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= @@ -371,27 +573,54 @@ 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-20210407192527-94a9f03dee38/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/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbuBVKCudVG457BR2GZFIz3uw3hQ= 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.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/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg= +github.com/googleapis/enterprise-certificate-proxy v0.2.3 h1:yk9/cqRKtT9wXZSsRH9aurXEpJX+U6FLtpYTdC3R06k= +github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= 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.5.1/go.mod h1:h6B0KMMFNtI2ddbGJn3T3ZbwkeT6yqEF02fYlzkUCyo= +github.com/googleapis/gax-go/v2 v2.6.0/go.mod h1:1mjbznJAPHFpesgE5ucqfYEscaz5kMdcIDwU/6+DDoY= +github.com/googleapis/gax-go/v2 v2.7.0 h1:IcsPKeInNvYi7eqSaDjiZqDDKu5rsmunY0Y1YupQSSQ= +github.com/googleapis/gax-go/v2 v2.7.0/go.mod h1:TEop28CZZQ2y+c0VxMUmu1lV+fQx57QpBWsYpwqHJx8= +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= github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4= github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q= +github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= 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 v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gorilla/websocket v1.4.1/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/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= github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= -github.com/grpc-ecosystem/grpc-gateway v1.8.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= +github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c h1:6rhixN/i8ZofjG1Y75iExal34USq5p+wiN1tpie8IrU= @@ -401,308 +630,333 @@ github.com/gtank/merlin v0.1.1 h1:eQ90iG7K9pOhtereWsmyRJ6RAwcP4tHTDBHXNg+u5is= github.com/gtank/merlin v0.1.1/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/bIQ+s= github.com/gtank/ristretto255 v0.1.2 h1:JEqUCPA1NvLq5DwYtuzigd7ss8fwbYay9fi4/5uMzcc= github.com/gtank/ristretto255 v0.1.2/go.mod h1:Ph5OpO6c7xKUGROZfWVLiJf9icMDwUeIvY4OmlYW69o= -github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0= +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-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.7.0 h1:bzrYP+qu/gMrL1au7/aDvkoOVGUJpeKBgbqRHACAFDY= +github.com/hashicorp/go-getter v1.7.0/go.mod h1:W7TalhMmbPmsSMdNjD0ZskARur/9GJ17cfHTRtXV744= 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= +github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +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.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/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -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/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.1.0 h1:jtBwzzcHuTmFrQN6xQZn6CQEO/V9f7HsjsjeEZ6auqU= +github.com/hdevalence/ed25519consensus v0.1.0/go.mod h1:w3BHWjwJbFU29IRHL1Iqkw3sus+7FctEyM4RqDxYNzo= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -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/huandu/go-assert v1.1.5 h1:fjemmA7sSfYHJD7CUqs9qTwwfdNAx7/j2/ZlHXzNB3c= +github.com/huandu/go-assert v1.1.5/go.mod h1:yOLvuqZwmcHIC5rIzrBhT7D3Q9c3GFnd0JrPVhn/06U= +github.com/huandu/skiplist v1.2.0 h1:gox56QD77HzSC0w+Ws3MH3iie755GBJU1OER3h5VsYw= +github.com/huandu/skiplist v1.2.0/go.mod h1:7v3iFjLcSAzO4fN5B8dvebvo/qsfumiLiDXMrPiHF9w= +github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= github.com/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/icza/dyno v0.0.0-20220812133438-f0b6f8a18845 h1:H+uM0Bv88eur3ZSsd2NGKg3YIiuXxwxtlN7HjE66UTU= github.com/icza/dyno v0.0.0-20220812133438-f0b6f8a18845/go.mod h1:c1tRKs5Tx7E2+uHGSyyncziFjvGpgv4H2HrqXeUQ/Uk= 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/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/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/informalsystems/tendermint v0.34.26 h1:89XvVexAy62geGWxmDmdmmJvfindx+Su2oTuwfSWMeU= -github.com/informalsystems/tendermint v0.34.26/go.mod h1:q3uAZ/t5+MblQhFuHSd4flqaLDx7iUtWpwWbwvHAFhs= -github.com/ipfs/go-cid v0.0.7 h1:ysQJVJA3fNDF1qigJbsSQOdjhVLsOEoPdh0+R97k3jY= -github.com/ipfs/go-cid v0.0.7/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I= -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/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= +github.com/ipfs/go-cid v0.2.0 h1:01JTiihFq9en9Vz0lc0VDWvZe/uBonGpzo4THP0vcQ0= +github.com/ipfs/go-cid v0.2.0/go.mod h1:P+HXFDF4CVhaVayiEb4wkAy7zBHxBwsJyt0Y5U6MLro= +github.com/jhump/protoreflect v1.12.1-0.20220721211354-060cc04fc18b h1:izTof8BKh/nE1wrKOrloNA5q4odOarjf+Xpe+4qow98= +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= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= 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.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/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= 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/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.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.11 h1:Lcadnb3RKGin4FYM/orgq0qde+nc15E5Cbqg4B9Sx9c= github.com/klauspost/compress v1.15.11/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= -github.com/klauspost/cpuid v0.0.0-20170728055534-ae7887de9fa5/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= +github.com/klauspost/compress v1.16.3 h1:XuJt9zzcnaz6a16/OU53ZjWp/v7/42WcR5t2a0PcNQY= +github.com/klauspost/compress v1.16.3/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -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/klauspost/cpuid/v2 v2.2.3 h1:sxCkb+qR91z4vsqw4vGGZlDgPz3G7gjaLyK3V8y70BU= +github.com/klauspost/cpuid/v2 v2.2.3/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= 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.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= 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/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/lib/pq v1.10.6 h1:jbk+ZieJ0D7EVGJYpL9QTz7/YW6UHbmdnZWYyK5cdBs= +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.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw= +github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= -github.com/libp2p/go-libp2p-core v0.15.1 h1:0RY+Mi/ARK9DgG1g9xVQLb8dDaaU8tCePMtGALEfBnM= -github.com/libp2p/go-libp2p-core v0.15.1/go.mod h1:agSaboYM4hzB1cWekgVReqV5M4g5M+2eNNejV+1EEhs= -github.com/libp2p/go-openssl v0.0.7 h1:eCAzdLejcNVBzP/iZM9vqHnQm+XyCEbSSIheIPRGNsw= -github.com/libp2p/go-openssl v0.0.7/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc= +github.com/libp2p/go-libp2p v0.22.0 h1:2Tce0kHOp5zASFKJbNzRElvh0iZwdtG5uZheNW8chIw= +github.com/libp2p/go-libp2p v0.22.0/go.mod h1:UDolmweypBSjQb2f7xutPnwZ/fxioLbMBxSjRksxxU4= +github.com/libp2p/go-openssl v0.1.0 h1:LBkKEcUv6vtZIQLVTegAil8jbNpJErQ9AnT+bWV+Ooo= +github.com/libp2p/go-openssl v0.1.0/go.mod h1:OiOxwPpL3n4xlenjx2h7AwSGaFSC/KZvf6gNdOBQMtc= +github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= +github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= +github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= -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/manifoldco/promptui v0.9.0 h1:3V4HzJk1TtXW1MTZMP7mdlwbBpIinw3HztaIlYthEiA= +github.com/manifoldco/promptui v0.9.0/go.mod h1:ka04sppxSGFAtxX0qhlYQjISsg9mR4GWtQEhdbn6Pgg= 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.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +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.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -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.3/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-sqlite3 v1.14.12 h1:TJ1bhYJPV44phC+IMu1u2K/i5RriLTPe+yc68XDJ1Z0= -github.com/mattn/go-sqlite3 v1.14.12/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= -github.com/mattn/go-tty v0.0.0-20180907095812-13ff1204f104/go.mod h1:XPvLUNfbS4fJH25nqRHfWLMa1ONC8Amw+mIA639KxkE= +github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= +github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-pointer v0.0.1 h1:n+XhsuGeVO6MEAp7xyEukFINEa+Quek5psIR/ylA6o0= +github.com/mattn/go-pointer v0.0.1/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc= +github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y= 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= +github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= +github.com/matttproud/golang_protobuf_extensions v1.0.4/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/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/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= -github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/mimoo/StrobeGo v0.0.0-20220103164710-9a04d6ca976b h1:QrHweqAtyJ9EwCaGHBu1fghwxIPiopAHV06JlXrMHjk= +github.com/mimoo/StrobeGo v0.0.0-20220103164710-9a04d6ca976b/go.mod h1:xxLb2ip6sSUts3g1irPVHyk/DGslwQsNOo9I7smJfNU= github.com/minio/highwayhash v1.0.2 h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA/g= -github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= +github.com/minio/highwayhash v1.0.2/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY= github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g= github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM= +github.com/misko9/go-substrate-rpc-client/v4 v4.0.0-20230413215336-5bd2aea337ae h1:ZYbJh4TLwfSuSQe6DT/1982SfNNBcmvzrX5FycfSrmo= +github.com/misko9/go-substrate-rpc-client/v4 v4.0.0-20230413215336-5bd2aea337ae/go.mod h1:XexEkZgpnQ3sqUYz84DFoVUcDake6G/tYHrwdbdERhM= +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/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU= +github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8= +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.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/moby/term v0.0.0-20220808134915-39b0c02b01ae h1:O4SWKdcHVCvYqyDV+9CJA1fcDN2L11Bule0iFy3YlAI= 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= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= 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/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= -github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= -github.com/mr-tron/base58 v1.1.3/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= -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/multiformats/go-base32 v0.0.3 h1:tw5+NhuwaOjJCC5Pp82QuXbrmLzWg7uxlMFp8Nq/kkI= -github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= +github.com/multiformats/go-base32 v0.0.4 h1:+qMh4a2f37b4xTNs6mqitDinryCI+tfO2dRVMN9mjSE= +github.com/multiformats/go-base32 v0.0.4/go.mod h1:jNLFzjPZtp3aIARHbJRZIaPuspdH0J6q39uUM5pnABM= github.com/multiformats/go-base36 v0.1.0 h1:JR6TyF7JjGd3m6FbLU2cOxhC0Li8z8dLNGQ89tUg4F4= github.com/multiformats/go-base36 v0.1.0/go.mod h1:kFGE83c6s80PklsHO9sRn2NCoffoRdUUOENyW/Vv6sM= -github.com/multiformats/go-multiaddr v0.4.1 h1:Pq37uLx3hsyNlTDir7FZyU8+cFCTqd5y1KiM2IzOutI= -github.com/multiformats/go-multiaddr v0.4.1/go.mod h1:3afI9HfVW8csiF8UZqtpYRiDyew8pRX7qLIGHu9FLuM= -github.com/multiformats/go-multibase v0.0.3 h1:l/B6bJDQjvQ5G52jw4QGSYeOTZoAwIO77RblWplfIqk= -github.com/multiformats/go-multibase v0.0.3/go.mod h1:5+1R4eQrT3PkYZ24C3W2Ue2tPwIdYQD509ZjSb5y9Oc= -github.com/multiformats/go-multicodec v0.4.1 h1:BSJbf+zpghcZMZrwTYBGwy0CPcVZGWiC72Cp8bBd4R4= -github.com/multiformats/go-multicodec v0.4.1/go.mod h1:1Hj/eHRaVWSXiSNNfcEPcwZleTmdNP81xlxDLnWU9GQ= -github.com/multiformats/go-multihash v0.0.13/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= -github.com/multiformats/go-multihash v0.0.14/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= -github.com/multiformats/go-multihash v0.1.0 h1:CgAgwqk3//SVEw3T+6DqI4mWMyRuDwZtOWcJT0q9+EA= -github.com/multiformats/go-multihash v0.1.0/go.mod h1:RJlXsxt6vHGaia+S8We0ErjhojtKzPP2AH4+kYM7k84= -github.com/multiformats/go-varint v0.0.5/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= +github.com/multiformats/go-multiaddr v0.6.0 h1:qMnoOPj2s8xxPU5kZ57Cqdr0hHhARz7mFsPMIiYNqzg= +github.com/multiformats/go-multiaddr v0.6.0/go.mod h1:F4IpaKZuPP360tOMn2Tpyu0At8w23aRyVqeK0DbFeGM= +github.com/multiformats/go-multibase v0.1.1 h1:3ASCDsuLX8+j4kx58qnJ4YFq/JWTJpCyDW27ztsVTOI= +github.com/multiformats/go-multibase v0.1.1/go.mod h1:ZEjHE+IsUrgp5mhlEAYjMtZwK1k4haNkcaPg9aoe1a8= +github.com/multiformats/go-multicodec v0.5.0 h1:EgU6cBe/D7WRwQb1KmnBvU7lrcFGMggZVTPtOW9dDHs= +github.com/multiformats/go-multicodec v0.5.0/go.mod h1:DiY2HFaEp5EhEXb/iYzVAunmyX/aSFMxq2KMKfWEues= +github.com/multiformats/go-multihash v0.2.1 h1:aem8ZT0VA2nCHHk7bPJ1BjUbHNciqZC/d16Vve9l108= +github.com/multiformats/go-multihash v0.2.1/go.mod h1:WxoMcYG85AZVQUyRyo9s4wULvW5qrI9vb2Lt6evduFc= github.com/multiformats/go-varint v0.0.6 h1:gk85QWKxh3TazbLxED/NlDVv8+q+ReFJk7Y2W/KhfNY= github.com/multiformats/go-varint v0.0.6/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/naoina/go-stringutil v0.1.0/go.mod h1:XJ2SJL9jCtBh+P9q5btrd/Ylo8XwT/h1USek5+NqSA0= -github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416/go.mod h1:NBIhNtsFMo3G2szEBne+bO4gS192HuIYRqfvOWb4i1E= +github.com/mwitkow/grpc-proxy v0.0.0-20181017164139-0f1106ef9c76/go.mod h1:x5OoJHDHqxHS801UIuhqGl6QdSAEJvtausosHSdazIo= +github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= +github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= +github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k= +github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= +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/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= -github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= -github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= +github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= +github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= +github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/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= -github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= -github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw= github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= +github.com/onsi/gomega v1.20.0 h1:8W0cWlwFkflGPLltQvLRB7ZVD5HuP6ng320w2IS245Q= +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/image-spec v1.1.0-rc2/go.mod h1:3OVijpioIKYWTqjiG0zfF6wvoJ4fAXGbjdZuI2NgsRQ= +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= 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/otiai10/copy v1.6.0 h1:IinKAryFFuPONZ7cm6T6E2QX/vcJwSnlaA5lfoaXIiQ= -github.com/oxyno-zeta/gomock-extra-matcher v1.1.0 h1:Yyk5ov0ZPKBXtVEeIWtc4J2XVrHuNoIK+0F2BUJgtsc= +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/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 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/v2 v2.0.6 h1:nrzqCb7j9cDFj2coyLNLaZuJTLjWjlaz6nvTvIwycIU= -github.com/pelletier/go-toml/v2 v2.0.6/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek= -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/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= +github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= +github.com/pelletier/go-toml/v2 v2.0.7 h1:muncTPStnKRos5dpVKULv2FVd4bMOhNePj9CjgDb8Us= +github.com/pelletier/go-toml/v2 v2.0.7/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek= +github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= 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/petermattis/goid v0.0.0-20221215004737-a150e88a970d h1:htwtWgtQo8YS6JFWWi2DNgY0RwSGJ1ruMoxY6CUUclk= +github.com/petermattis/goid v0.0.0-20221215004737-a150e88a970d/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= +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= github.com/pierrec/xxHash v0.1.5 h1:n/jBpwTHiER4xYvK3/CdPVnLDPchj8eTJFFLUb4QHBo= github.com/pierrec/xxHash v0.1.5/go.mod h1:w2waW5Zoa/Wc4Yqe0wgrIYAGKqRMf7czn2HNKXmuL+I= -github.com/pierrre/gotestcover v0.0.0-20160517101806-924dca7d15f0/go.mod h1:4xpMLz7RBWyB+ElzHu8Llua96TRCB3YwX+l5EP1wmHk= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 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= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= 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.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/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= -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= -github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= -github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= -github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE= -github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= +github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= +github.com/prometheus/common v0.40.0 h1:Afz7EVRqGg2Mqqf4JuF9vdvp1pi220m55Pi9T2JnO4Q= +github.com/prometheus/common v0.40.0/go.mod h1:L65ZJPSmfn/UBWLQIHV7dBrKFidB/wPlF1y5TlSt9OE= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -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/procfs v0.3.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI= +github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= github.com/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-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/gocuke v0.6.2 h1:pHviZ0kKAq2U2hN2q3smKNxct6hS0mGByFMHGnWA97M= 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/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6OkFY5QxjkYwrChwuRruF69c169dPK26NUlk= github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= -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/robertkrimen/godocdown v0.0.0-20130622164427-0bfa04905481/go.mod h1:C9WhFzY47SzYBIvzFqSvHIR6ROgDo4TtdTuRaOMjF/s= +github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= +github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= 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.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= 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/zerolog v1.27.0 h1:1T7qCieN22GVc8S4Q2yuexzBb1EqjbgjSH9RohbMjKs= +github.com/rs/cors v1.8.3 h1:O+qNyWn7Z+F9M0ILBHgMVPuB1xTOucVd5gtaYyXBpRo= +github.com/rs/cors v1.8.3/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= 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.3.1 h1:sqv7fDNShgjcaxkO0JNcOAlr8B9+cV5Ey/OB71efZx0= github.com/sasha-s/go-deadlock v0.3.1/go.mod h1:F73l+cr82YSh10GxyRI6qZiCgK64VaZjwesgfQ1/iLM= -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/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible h1:Bn1aCHHRnjv4Bl16T8rcaFjYSrGrIZvpiGO6P3Q4GpU= -github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= github.com/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= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 h1:RC6RW7j+1+HkWaX/Yh71Ee5ZHaHYt7ZP4sQgUrm6cDU= github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= @@ -716,28 +970,29 @@ 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.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA= -github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY= +github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= +github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= 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= +github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= 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.15.0 h1:js3yy885G8xwJa6iOISGFwd+qlUo5AvyXb7CiihdtiU= github.com/spf13/viper v1.15.0/go.mod h1:fFcTBJxvhhzSJiZy8n+PeW6t8l+KeT/uTARa0jHOQLA= -github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4/go.mod h1:RZLeN1LMWmRsyYjvAu+I6Dm9QmlDaIIt+Y+4Kd7Tp+Q= -github.com/strangelove-ventures/go-subkey v1.0.7 h1:cOP/Lajg3uxV/tvspu0m6+0Cu+DJgygkEAbx/s+f35I= -github.com/strangelove-ventures/go-subkey v1.0.7/go.mod h1:E34izOIEm+sZ1YmYawYRquqBQWeZBjVB4pF7bMuhc1c= -github.com/strangelove-ventures/interchaintest/v4 v4.0.0-20230331040355-5d08aab13017 h1:ipXOC0b0g2652lmTn+E453sbWtpzqPrGa+jP50ymR3A= -github.com/strangelove-ventures/interchaintest/v4 v4.0.0-20230331040355-5d08aab13017/go.mod h1:Na9KNE38VWqOKMSTpbIzXCICDkazn+6kFf4BG0ublCk= +github.com/strangelove-ventures/interchaintest/v7 v7.0.0-20230428012002-db902d82df33 h1:QG9pAXSiNhCBiYoiImCtMsY0oI3vG7B/vltQJyarfEU= +github.com/strangelove-ventures/interchaintest/v7 v7.0.0-20230428012002-db902d82df33/go.mod h1:iX6tg3V6mH64h37ZvLuJa7lp9GbmFixTMlVu6Gilb/Q= +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/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.1.5-0.20170601210322-f6abca593680/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= @@ -752,85 +1007,94 @@ github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= -github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= -github.com/syndtr/goleveldb v1.0.1-0.20220614013038-64ee5596c38a h1:1ur3QoCqvE5fl+nylMaIr9PVV1w343YRDtsy+Rwu7XI= -github.com/syndtr/goleveldb v1.0.1-0.20220614013038-64ee5596c38a/go.mod h1:RRCYJbIwD5jmqPI9XoAFR0OcDxqUctll6zUj/+B4S48= +github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d h1:vfofYNRScrDdvS342BElfbETmL1Aiz3i2t0zfRj16Hs= +github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d/go.mod h1:RRCYJbIwD5jmqPI9XoAFR0OcDxqUctll6zUj/+B4S48= +github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c h1:g+WoO5jjkqGAzHWCjJB1zZfXPIAaDpzXIEJ0eS6B5Ok= +github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c/go.mod h1:ahpPrc7HpcfEWDQRZEmnXMzHY03mLDYMCxeDzy46i+8= 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/tm-db v0.6.8-0.20220506192307-f628bb5dc95b h1:Y3ZPG6gdDCAV2sdGkD759ji/09GzaNu1X3qKTmZIbTo= -github.com/tendermint/tm-db v0.6.8-0.20220506192307-f628bb5dc95b/go.mod h1:ADqbS9NOSnBRK9R2RtYC61CdsHmVMD/yXAzcMuPexbU= -github.com/tidwall/btree v1.5.0 h1:iV0yVY/frd7r6qGBXfEYs7DH0gTDgrKTrDjS7xt/IyQ= -github.com/tidwall/btree v1.5.0/go.mod h1:LGm8L/DZjPLmeWGjv5kFrY8dL4uVhMmzmmLYmsObdKE= -github.com/tinylib/msgp v1.0.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= -github.com/tklauser/go-sysconf v0.3.5 h1:uu3Xl4nkLzQfXNsWn15rPc/HQCJKObbt1dKJeWp3vU4= -github.com/tklauser/go-sysconf v0.3.5/go.mod h1:MkWzOF4RMCshBAMXuhXJs64Rte09mITnppBXY/rYEFI= -github.com/tklauser/numcpus v0.2.2 h1:oyhllyrScuYI6g+h/zUvNXNp1wy7x8qQy3t/piefldA= -github.com/tklauser/numcpus v0.2.2/go.mod h1:x3qojaO3uyYt0i56EW/VUYs7uBvdl2fkfZFu0T9wgjM= +github.com/tidwall/btree v1.6.0 h1:LDZfKfQIBHGHWSwckhXI0RPSXzlo+KYdjK7FWSqOzzg= +github.com/tidwall/btree v1.6.0/go.mod h1:twD9XRA5jj9VUQGELzDO4HPQTNJsoWWfYEL+EUQ2cKY= +github.com/tklauser/go-sysconf v0.3.10 h1:IJ1AZGZRWbY8T5Vfk04D9WOA5WSejdflXxP03OUqALw= +github.com/tklauser/numcpus v0.4.0 h1:E53Dm1HjH1/R2/aoCtXtPgzmElmn51aOkhCFSuZq//o= +github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= -github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs= +github.com/tyler-smith/go-bip32 v1.0.0 h1:sDR9juArbUgX+bO/iblgZnMPeWY1KZMUC2AFUJdv5KE= +github.com/tyler-smith/go-bip32 v1.0.0/go.mod h1:onot+eHknzV4BVPwrzqY5OoVpyCvnwD7lMawL5aQupE= +github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= +github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= +github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= +github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= -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/willf/bitset v1.1.3/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= -github.com/xlab/treeprint v0.0.0-20180616005107-d6fb6747feb6/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg= +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.10/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= +github.com/ulikunitz/xz v0.5.11 h1:kpFauv27b6ynzBNT/Xy+1k+fK4WswhN/6PN5WhFAGw8= +github.com/ulikunitz/xz v0.5.11/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/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= 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.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/zondax/hid v0.9.1 h1:gQe66rtmyZ8VeGFcOpbuH3r7erYtNEAezCAYu8LdkJo= github.com/zondax/hid v0.9.1/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= github.com/zondax/ledger-go v0.14.1 h1:Pip65OOl4iJ84WTpA4BKChvOufMhhbxED3BaihoZN4c= github.com/zondax/ledger-go v0.14.1/go.mod h1:fZ3Dqg6qcdXWSOJFKMG8GCTnD7slO/RL2feOQv8K320= -go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU= -go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4= +go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/bbolt v1.3.7 h1:j+zJOnnEjF/kyHlDDgGnVL/AIqIJPq8UoB2GSNfkUfQ= +go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= +go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= +go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= +go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= 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/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= +go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= 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/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA= 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/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8= go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= -go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -go.uber.org/zap v1.23.0 h1:OjGQ5KQDEUawVHxNwQgPpiypGHOxo2mNZsOqTak4fFY= -go.uber.org/zap v1.23.0/go.mod h1:D+nX8jyLsMHMYrln8A0rJjFt/T/9/bGgIhAqxv5URuY= +go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= +go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= +go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= +golang.org/x/crypto v0.0.0-20170613210332-850760c427c5/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190909091759-094676da4a83/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 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-20210220033148-5ea612d1eb83/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-20210921155107-089bfa567519/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.5.0 h1:U/0M97KRkSFvyD/3FSmdP5W5swImpNgle/EHFhOsQPE= -golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU= -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/crypto v0.8.0 h1:pd9TJtTueMTVQXzk8E2XESSMQDj/U7OUu0PqJqPXQjQ= +golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= 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-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= @@ -840,9 +1104,9 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20230131160201-f062dba9d201 h1:BEABXpNXLEz0WxtA+6CQIz2xkg80e+1zrhWyMcq8VzE= -golang.org/x/exp v0.0.0-20230131160201-f062dba9d201/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= -golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= +golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= +golang.org/x/exp v0.0.0-20230321023759-10a507213a29 h1:ooxPy7fPvB4kwsA2h+iBNHkAbp/4JxTSwCmvdjEYmug= +golang.org/x/exp v0.0.0-20230321023759-10a507213a29/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= 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-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -856,6 +1120,7 @@ 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/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= @@ -867,14 +1132,18 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8= -golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk= +golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/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= golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -885,6 +1154,7 @@ golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -892,6 +1162,7 @@ golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200421231249-e086a090c8fd/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= @@ -899,26 +1170,33 @@ golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/ golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= 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-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-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -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-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/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.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= -golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.0.0-20220617184016-355a448f1bc9/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= +golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM= +golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= 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= @@ -928,8 +1206,24 @@ 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-20220622183110-fd043fe589d2/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= +golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.1.0/go.mod h1:G9FE4dLTsbXUu90h/Pf85g4w1D+SSAgR+q46nJZ8M4A= +golang.org/x/oauth2 v0.5.0 h1:HuArIo48skDwlrvM3sEdHXElYslAMsf3KwRkkW4MC4s= +golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I= 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= @@ -941,16 +1235,22 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ 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/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= golang.org/x/sync v0.1.0/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-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 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= @@ -960,16 +1260,16 @@ 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= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +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= @@ -979,53 +1279,71 @@ golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 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-20200905004654-be1d3432aa8f/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= golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/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-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210316164454-77fc1eacc6aa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210420205809-ac73e9fd8988/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-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/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-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +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-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-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211107104306-e0b2ad06fe42/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-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-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220315194320-039c03cc5b86/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-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-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/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/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= -golang.org/x/sys v0.5.0/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-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU= +golang.org/x/sys v0.7.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.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY= -golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.7.0 h1:BEvjmm5fURWqcfbSKTdpkDXYBrUS1c0m8agp14W48vQ= +golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= 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= @@ -1035,18 +1353,17 @@ 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/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +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/time v0.1.0 h1:xYY+Bajn2a7VBmTM5GikTmnK8ZuX8YgnQCqZpbBNtmA= -golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/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-20190114222345-bf090417da8b/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,6 +1378,8 @@ golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgw golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -1068,7 +1387,7 @@ golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200108203644-89082a384178/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-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,7 +1409,6 @@ golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= @@ -1098,20 +1416,24 @@ 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.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= -golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= -golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +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/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.8.0 h1:vSDcovVPld282ceKgDimkRSC8kpaH1dgyc9UMzlt84Y= +golang.org/x/tools v0.8.0/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4= 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= -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-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= +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= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= @@ -1131,12 +1453,45 @@ 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.77.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.90.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw= +google.golang.org/api v0.93.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw= +google.golang.org/api v0.95.0/go.mod h1:eADj+UBuxkh5zlrSntJghuNeg8HwQ1w5lTKkuqaETEI= +google.golang.org/api v0.96.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= +google.golang.org/api v0.97.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= +google.golang.org/api v0.98.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= +google.golang.org/api v0.100.0/go.mod h1:ZE3Z2+ZOr87Rx7dqFsdRQkRBk36kDtp/h+QpHbB7a70= +google.golang.org/api v0.110.0 h1:l+rh0KYUooe9JGbGVx71tbFo4SMbMTXK3I3ia2QSEeU= +google.golang.org/api v0.110.0/go.mod h1:7FC4Vvx1Mooxh8C5HWjzZHcavuS2f6pmJpZx60ca7iI= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +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= @@ -1144,7 +1499,7 @@ google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRn google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= 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-20190716160619-c506a9f90610/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= 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= @@ -1152,7 +1507,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= @@ -1179,14 +1533,86 @@ google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 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-20230125152338-dcaf20b6aeaa h1:qQPhfbPO23fwm/9lQr91L1u62Zo6cm+zI+slZT+uf+o= -google.golang.org/genproto v0.0.0-20230125152338-dcaf20b6aeaa/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +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-20220314164441-57ef72a4c106/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= +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-20220502173005-c8bf987b8c21/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +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-20220624142145-8cd45d7dbd1f/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220628213854-d9e0b6570c03/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220722212130-b98a9ff5e252/go.mod h1:GkXuJDJ6aQ7lnJcRF+SJVgFdQhypqgl3LB1C9vabdRE= +google.golang.org/genproto v0.0.0-20220801145646-83ce21fca29f/go.mod h1:iHe1svFLAZg9VWz891+QbRMwUv9O/1Ww+/mngYeThbc= +google.golang.org/genproto v0.0.0-20220815135757-37a418bb8959/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220817144833-d7fd3f11b9b1/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220822174746-9e6da59bd2fc/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220829144015-23454907ede3/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220829175752-36a9c930ecbf/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220913154956-18f8339a66a5/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220914142337-ca0e39ece12f/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220915135415-7fd63a7952de/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220916172020-2692e8806bfa/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220919141832-68c03719ef51/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220920201722-2b89144ce006/go.mod h1:ht8XFiar2npT/g4vkk7O0WYS1sHOHbdujxbEp7CJWbw= +google.golang.org/genproto v0.0.0-20220926165614-551eb538f295/go.mod h1:woMGP53BroOrRY3xTxlbr8Y3eB/nzAvvFM83q7kG2OI= +google.golang.org/genproto v0.0.0-20220926220553-6981cbe3cfce/go.mod h1:woMGP53BroOrRY3xTxlbr8Y3eB/nzAvvFM83q7kG2OI= +google.golang.org/genproto v0.0.0-20221010155953-15ba04fc1c0e/go.mod h1:3526vdqwhZAwq4wsRUaVG555sVgsNmIjRtO7t/JH29U= +google.golang.org/genproto v0.0.0-20221014173430-6e2ab493f96b/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= +google.golang.org/genproto v0.0.0-20221014213838-99cd37c6964a/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= +google.golang.org/genproto v0.0.0-20221025140454-527a21cfbd71/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= +google.golang.org/genproto v0.0.0-20230216225411-c8e22ba71e44 h1:EfLuoKW5WfkgVdDy7dTK8qSbH37AX5mj/MFh+bGPz14= +google.golang.org/genproto v0.0.0-20230216225411-c8e22ba71e44/go.mod h1:8B0gmkoRebU8ukX6HP+4wrVQUY1+6PkQ44BSyIlflHA= +google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.19.1/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= @@ -1196,12 +1622,32 @@ google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3Iji google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.32.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.53.0 h1:LAv2ds7cmFV/XTS3XG1NneeENYrXGmorPxsBbptIjNc= -google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= +google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= +google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= +google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= +google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= +google.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= +google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= +google.golang.org/grpc v1.54.0 h1:EhTqbhiYeixwWQtAEZAxmV9MGqcjEU2mFx52xCzNyag= +google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g= +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= @@ -1214,26 +1660,30 @@ 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.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= +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/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= +google.golang.org/protobuf v1.30.0/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/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= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce h1:+JknDZhAj8YMt7GC73Ei8pv4MzjDUNPHgQWJdtMAaDU= gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c= -gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200619000410-60c24ae608a6/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/urfave/cli.v1 v1.20.0/go.mod h1:vuBzUtMdQeixQj8LVd+/98pzhxNGQoyuPBlsXHOQNO0= +gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -1249,8 +1699,8 @@ gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= -gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= gotest.tools/v3 v3.4.0 h1:ZazjZUfuVeZGLAmlKKuyv3IKP5orXcwtOwDQH6YVr6o= +honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -1258,46 +1708,42 @@ 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= -lukechampine.com/blake3 v1.1.6 h1:H3cROdztr7RCfoaTpGZFQsrqvweFLrqS73j7L7cmR5c= -lukechampine.com/blake3 v1.1.6/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= -lukechampine.com/uint128 v1.1.1 h1:pnxCASz787iMf+02ssImqk6OLt+Z5QHMoZyUXR4z6JU= -lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= -modernc.org/cc/v3 v3.36.0 h1:0kmRkTmqNidmu3c7BNDSdVHCxXCkWLmWmCIVX4LUboo= -modernc.org/cc/v3 v3.36.0/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI= -modernc.org/ccgo/v3 v3.0.0-20220428102840-41399a37e894/go.mod h1:eI31LL8EwEBKPpNpA4bU1/i+sKOwOrQy8D87zWUcRZc= -modernc.org/ccgo/v3 v3.0.0-20220430103911-bc99d88307be/go.mod h1:bwdAnOoaIt8Ax9YdWGjxWsdkPcZyRPHqrOvJxaKAKGw= -modernc.org/ccgo/v3 v3.16.4/go.mod h1:tGtX0gE9Jn7hdZFeU88slbTh1UtCYKusWOoCJuvkWsQ= -modernc.org/ccgo/v3 v3.16.6 h1:3l18poV+iUemQ98O3X5OMr97LOqlzis+ytivU4NqGhA= -modernc.org/ccgo/v3 v3.16.6/go.mod h1:tGtX0gE9Jn7hdZFeU88slbTh1UtCYKusWOoCJuvkWsQ= +launchpad.net/gocheck v0.0.0-20140225173054-000000000087 h1:Izowp2XBH6Ya6rv+hqbceQyw/gSGoXfH/UPoTGduL54= +launchpad.net/gocheck v0.0.0-20140225173054-000000000087/go.mod h1:hj7XX3B/0A+80Vse0e+BUHsHMTEhd0O4cpUHr/e/BUM= +lukechampine.com/blake3 v1.1.7 h1:GgRMhmdsuK8+ii6UZFDL8Nb+VyMwadAgcJyfYHxG6n0= +lukechampine.com/blake3 v1.1.7/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= +lukechampine.com/uint128 v1.2.0 h1:mBi/5l91vocEN8otkC5bDLhi2KdCticRiwbdB0O+rjI= +lukechampine.com/uint128 v1.2.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= +modernc.org/cc/v3 v3.40.0 h1:P3g79IUS/93SYhtoeaHW+kRCIrYaxJ27MFPv+7kaTOw= +modernc.org/cc/v3 v3.40.0/go.mod h1:/bTg4dnWkSXowUO6ssQKnOV0yMVxDYNIsIrzqTFDGH0= +modernc.org/ccgo/v3 v3.16.13 h1:Mkgdzl46i5F/CNR/Kj80Ri59hC8TKAhZrYSaqvkwzUw= +modernc.org/ccgo/v3 v3.16.13/go.mod h1:2Quk+5YgpImhPjv2Qsob1DnZ/4som1lJTodubIcoUkY= modernc.org/ccorpus v1.11.6 h1:J16RXiiqiCgua6+ZvQot4yUuUy8zxgqbqEEUuGPlISk= -modernc.org/ccorpus v1.11.6/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ= modernc.org/httpfs v1.0.6 h1:AAgIpFZRXuYnkjftxTAZwMIiwEqAfk8aVB2/oA6nAeM= -modernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM= -modernc.org/libc v0.0.0-20220428101251-2d5f3daf273b/go.mod h1:p7Mg4+koNjc8jkqwcoFBJx7tXkpj00G77X7A72jXPXA= -modernc.org/libc v1.16.0/go.mod h1:N4LD6DBE9cf+Dzf9buBlzVJndKr/iJHG97vGLHYnb5A= -modernc.org/libc v1.16.1/go.mod h1:JjJE0eu4yeK7tab2n4S1w8tlWd9MxXLRzheaRnAKymU= -modernc.org/libc v1.16.7 h1:qzQtHhsZNpVPpeCu+aMIQldXeV1P0vRhSqCL0nOIJOA= -modernc.org/libc v1.16.7/go.mod h1:hYIV5VZczAmGZAnG15Vdngn5HSF5cSkbvfz2B7GRuVU= -modernc.org/mathutil v1.2.2/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= -modernc.org/mathutil v1.4.1 h1:ij3fYGe8zBF4Vu+g0oT7mB06r8sqGWKuJu1yXeR4by8= -modernc.org/mathutil v1.4.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= -modernc.org/memory v1.1.1 h1:bDOL0DIDLQv7bWhP3gMvIrnoFw+Eo6F7a2QK9HPDiFU= -modernc.org/memory v1.1.1/go.mod h1:/0wo5ibyrQiaoUoH7f9D8dnglAmILJ5/cxZlRECf+Nw= -modernc.org/opt v0.1.1 h1:/0RX92k9vwVeDXj+Xn23DKp2VJubL7k8qNffND6qn3A= -modernc.org/opt v0.1.1/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= -modernc.org/sqlite v1.17.3 h1:iE+coC5g17LtByDYDWKpR6m2Z9022YrSh3bumwOnIrI= -modernc.org/sqlite v1.17.3/go.mod h1:10hPVYar9C0kfXuTWGz8s0XtB8uAGymUy51ZzStYe3k= -modernc.org/strutil v1.1.1 h1:xv+J1BXY3Opl2ALrBwyfEikFAj8pmqcpnfmuwUwcozs= -modernc.org/strutil v1.1.1/go.mod h1:DE+MQQ/hjKBZS2zNInV5hhcipt5rLPWkmpbGeW5mmdw= -modernc.org/tcl v1.13.1 h1:npxzTwFTZYM8ghWicVIX1cRWzj7Nd8i6AqqX2p+IYao= -modernc.org/tcl v1.13.1/go.mod h1:XOLfOwzhkljL4itZkK6T72ckMgvj0BDsnKNdZVUOecw= -modernc.org/token v1.0.0 h1:a0jaWiNMDhDUtqOj09wvjWWAqd3q7WpBulmL9H2egsk= -modernc.org/token v1.0.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= -modernc.org/z v1.5.1 h1:RTNHdsrOpeoSeOF4FbzTo8gBYByaJ5xT7NgZ9ZqRiJM= -modernc.org/z v1.5.1/go.mod h1:eWFB510QWW5Th9YGZT81s+LwvaAs3Q2yr4sP0rmLkv8= -nhooyr.io/websocket v1.8.7 h1:usjR2uOr/zjjkVMy0lW+PPohFok7PCow5sDjLgX4P4g= +modernc.org/libc v1.22.4 h1:wymSbZb0AlrjdAVX3cjreCHTPCpPARbQXNz6BHPzdwQ= +modernc.org/libc v1.22.4/go.mod h1:jj+Z7dTNX8fBScMVNRAYZ/jF91K8fdT2hYMThc3YjBY= +modernc.org/mathutil v1.5.0 h1:rV0Ko/6SfM+8G+yKiyI830l3Wuz1zRutdslNoQ0kfiQ= +modernc.org/mathutil v1.5.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= +modernc.org/memory v1.5.0 h1:N+/8c5rE6EqugZwHii4IFsaJ7MUhoWX07J5tC/iI5Ds= +modernc.org/memory v1.5.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU= +modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4= +modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= +modernc.org/sqlite v1.22.0 h1:Uo+wEWePCspy4SAu0w2VbzUHEftOs7yoaWX/cYjsq84= +modernc.org/sqlite v1.22.0/go.mod h1:cxbLkB5WS32DnQqeH4h4o1B0eMr8W/y8/RGuxQ3JsC0= +modernc.org/strutil v1.1.3 h1:fNMm+oJklMGYfU9Ylcywl0CO5O6nTfaowNsh2wpPjzY= +modernc.org/strutil v1.1.3/go.mod h1:MEHNA7PdEnEwLvspRMtWTNnp2nnyvMfkimT1NKNAGbw= +modernc.org/tcl v1.15.1 h1:mOQwiEK4p7HruMZcwKTZPw/aqtGM4aY00uzWhlKKYws= +modernc.org/token v1.0.1 h1:A3qvTqOwexpfZZeyI0FeGPDlSWX5pjZu9hF4lU+EKWg= +modernc.org/token v1.0.1/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= +modernc.org/z v1.7.0 h1:xkDw/KepgEjeizO2sNco+hqYkU12taxQFqPEmgm1GWE= +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.5 h1:jkgx1TjbQPD/feRoK+S/mXw9e1uj6WilpHrXJowi6oA= +pgregory.net/rapid v0.5.5/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04= 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= +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= diff --git a/tests/interchaintest/ibc_transfer_test.go b/tests/interchaintest/ibc_transfer_test.go index c96bbc203..ddad77fae 100644 --- a/tests/interchaintest/ibc_transfer_test.go +++ b/tests/interchaintest/ibc_transfer_test.go @@ -107,9 +107,13 @@ func TestJunoGaiaIBCTransfer(t *testing.T) { // Get our Bech32 encoded user addresses junoUser, gaiaUser := users[0], users[1] + + junoUserAddr := junoUser.Bech32Address(juno.Config().Bech32Prefix) gaiaUserAddr := gaiaUser.Bech32Address(gaia.Config().Bech32Prefix) + + // Get original account balances junoOrigBal, err := juno.GetBalance(ctx, junoUserAddr, juno.Config().Denom) require.NoError(t, err) diff --git a/tests/interchaintest/setup.go b/tests/interchaintest/setup.go index d7335ab52..ec8230d51 100644 --- a/tests/interchaintest/setup.go +++ b/tests/interchaintest/setup.go @@ -1,8 +1,9 @@ package interchaintest import ( - simappparams "cosmossdk.io/simapp/params" - feesharetypes "github.com/CosmosContracts/juno/v13/x/feeshare/types" + + // feesharetypes "github.com/CosmosContracts/juno/v15/x/feeshare/types" + "github.com/cosmos/cosmos-sdk/types/module/testutil" "github.com/strangelove-ventures/interchaintest/v7/chain/cosmos" "github.com/strangelove-ventures/interchaintest/v7/ibc" ) @@ -32,8 +33,6 @@ var ( GasAdjustment: 1.1, TrustingPeriod: "112h", NoHostMount: false, - SkipGenTx: false, - PreGenesis: nil, ModifyGenesis: nil, ConfigFileOverrides: nil, EncodingConfig: junoEncoding(), @@ -45,11 +44,11 @@ var ( // junoEncoding registers the Juno specific module codecs so that the associated types and msgs // will be supported when writing to the blocksdb sqlite database. -func junoEncoding() *simappparams.EncodingConfig { +func junoEncoding() *testutil.TestEncodingConfig { cfg := cosmos.DefaultEncoding() // register custom types - feesharetypes.RegisterInterfaces(cfg.InterfaceRegistry) + // feesharetypes.RegisterInterfaces(cfg.InterfaceRegistry) return &cfg } From c8339170d76c01868aba003cc5c9e1d6ac7dd5a3 Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Fri, 28 Apr 2023 20:10:55 -0500 Subject: [PATCH 056/131] Fix app.go + test-suite stakingHandler --- app/app.go | 13 +++- app/apptesting/test_suite.go | 12 ++-- go.mod | 16 ++++- go.sum | 117 ++++++++++++++++++++++++++++++++--- 4 files changed, 141 insertions(+), 17 deletions(-) diff --git a/app/app.go b/app/app.go index c63259e9a..51958f3b9 100644 --- a/app/app.go +++ b/app/app.go @@ -24,6 +24,7 @@ import ( "github.com/cosmos/cosmos-sdk/server/api" "github.com/cosmos/cosmos-sdk/server/config" servertypes "github.com/cosmos/cosmos-sdk/server/types" + "github.com/cosmos/cosmos-sdk/store/streaming" storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/address" @@ -33,6 +34,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/auth/ante" authtx "github.com/cosmos/cosmos-sdk/x/auth/tx" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" "github.com/cosmos/cosmos-sdk/x/crisis" govclient "github.com/cosmos/cosmos-sdk/x/gov/client" paramsclient "github.com/cosmos/cosmos-sdk/x/params/client" @@ -239,6 +241,8 @@ func New( appCodec: appCodec, txConfig: txConfig, interfaceRegistry: interfaceRegistry, + tkeys: sdk.NewTransientStoreKeys(paramstypes.TStoreKey), + memKeys: sdk.NewMemoryStoreKeys(capabilitytypes.MemStoreKey), } // Setup keepers @@ -252,6 +256,13 @@ func New( appOpts, wasmOpts, ) + app.keys = app.AppKeepers.GetKVStoreKey() + + // load state streaming if enabled + if _, _, err := streaming.LoadStreamingServices(bApp, appOpts, appCodec, logger, app.keys); err != nil { + logger.Error("failed to load state streaming", "err", err) + os.Exit(1) + } if maxSize := os.Getenv("MAX_WASM_SIZE"); maxSize != "" { // https://github.com/CosmWasm/wasmd#compile-time-parameters @@ -290,7 +301,7 @@ func New( app.ModuleManager.RegisterInvariants(app.AppKeepers.CrisisKeeper) app.ModuleManager.RegisterServices(cfg) // initialize stores - app.MountKVStores(app.AppKeepers.GetKVStoreKey()) + app.MountKVStores(app.keys) app.MountTransientStores(app.AppKeepers.GetTransientStoreKey()) app.MountMemoryStores(app.AppKeepers.GetMemoryStoreKey()) diff --git a/app/apptesting/test_suite.go b/app/apptesting/test_suite.go index 13e04f7d5..5820cb31d 100644 --- a/app/apptesting/test_suite.go +++ b/app/apptesting/test_suite.go @@ -24,7 +24,6 @@ import ( banktestutil "github.com/cosmos/cosmos-sdk/x/bank/testutil" distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" - "github.com/cosmos/cosmos-sdk/x/staking" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" @@ -120,14 +119,14 @@ func (s *KeeperTestHelper) SetupValidator(bondStatus stakingtypes.BondStatus) sd s.FundAcc(sdk.AccAddress(valAddr), selfBond) - stakingHandler := staking.NewHandler(s.App.AppKeepers.StakingKeeper) + // stakingHandler := staking.NewHandler(s.App.AppKeepers.StakingKeeper) stakingCoin := sdk.NewCoin(sdk.DefaultBondDenom, selfBond[0].Amount) ZeroCommission := stakingtypes.NewCommissionRates(sdk.ZeroDec(), sdk.ZeroDec(), sdk.ZeroDec()) - msg, err := stakingtypes.NewMsgCreateValidator(valAddr, valPub, stakingCoin, stakingtypes.Description{}, ZeroCommission, sdk.OneInt()) + _, err := stakingtypes.NewMsgCreateValidator(valAddr, valPub, stakingCoin, stakingtypes.Description{}, ZeroCommission, sdk.OneInt()) s.Require().NoError(err) - res, err := stakingHandler(s.Ctx, msg) - s.Require().NoError(err) - s.Require().NotNil(res) + // res, err := stakingHandler(s.Ctx, msg) + // s.Require().NoError(err) + // s.Require().NotNil(res) val, found := s.App.AppKeepers.StakingKeeper.GetValidator(s.Ctx, valAddr) s.Require().True(found) @@ -190,6 +189,7 @@ func (s *KeeperTestHelper) BeginNewBlockWithProposer(proposer sdk.ValAddress) { Validator: abci.Validator{Address: valAddr, Power: 1000}, SignedLastBlock: true, }}, + Round: 0, } reqBeginBlock := abci.RequestBeginBlock{Header: header, LastCommitInfo: lastCommitInfo} diff --git a/go.mod b/go.mod index 055cc46ae..48b6676bd 100644 --- a/go.mod +++ b/go.mod @@ -21,7 +21,7 @@ require ( github.com/strangelove-ventures/packet-forward-middleware/v7 v7.0.0-20230412224111-136e94e98861 github.com/stretchr/testify v1.8.2 // github.com/tendermint/tm-db v0.6.8-0.20220506192307-f628bb5dc95b - google.golang.org/genproto v0.0.0-20230216225411-c8e22ba71e44 + google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 google.golang.org/grpc v1.54.0 gopkg.in/yaml.v2 v2.4.0 ) @@ -35,13 +35,21 @@ require ( cloud.google.com/go/iam v0.12.0 // indirect cloud.google.com/go/storage v1.29.0 // indirect cosmossdk.io/tools/rosetta v0.2.1 // indirect + github.com/DataDog/zstd v1.5.2 // indirect github.com/aws/aws-sdk-go v1.44.203 // indirect github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect github.com/chzyer/readline v1.5.1 // indirect github.com/cockroachdb/apd/v2 v2.0.2 // indirect + github.com/cockroachdb/errors v1.9.1 // indirect + github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect + github.com/cockroachdb/pebble v0.0.0-20230226194802-02d779ffbc46 // indirect + github.com/cockroachdb/redact v1.1.3 // indirect + github.com/cosmos/cosmos-db v1.0.0-rc.1 // indirect github.com/cosmos/gogogateway v1.2.0 // indirect github.com/cosmos/ics23/go v0.9.1-0.20221207100636-b1abd8678aab // indirect github.com/cosmos/rosetta-sdk-go v0.10.0 // indirect + github.com/emicklei/dot v1.4.2 // indirect + github.com/getsentry/sentry-go v0.18.0 // indirect github.com/gogo/googleapis v1.4.1 // indirect github.com/gogo/protobuf v1.3.3 // indirect github.com/golang/mock v1.6.0 // indirect @@ -53,11 +61,15 @@ require ( github.com/hashicorp/go-safetemp v1.0.0 // indirect github.com/hashicorp/go-version v1.6.0 // indirect github.com/huandu/skiplist v1.2.0 // indirect + github.com/jhump/protoreflect v1.15.1 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect + github.com/kr/pretty v0.3.1 // indirect + github.com/kr/text v0.2.0 // indirect github.com/linxGnu/grocksdb v1.7.16 // indirect github.com/manifoldco/promptui v0.9.0 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/go-testing-interface v1.14.1 // indirect + github.com/rogpeppe/go-internal v1.9.0 // indirect github.com/ulikunitz/xz v0.5.11 // indirect golang.org/x/oauth2 v0.5.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect @@ -89,7 +101,7 @@ require ( github.com/cosmos/cosmos-proto v1.0.0-beta.2 github.com/cosmos/go-bip39 v1.0.0 // indirect github.com/cosmos/gogoproto v1.4.8 - github.com/cosmos/iavl v0.20.0 // indirect + github.com/cosmos/iavl v1.0.0-alpha.2 // indirect github.com/cosmos/ledger-cosmos-go v0.12.2 // indirect github.com/creachadair/taskgroup v0.4.2 // indirect github.com/danieljoos/wincred v1.1.2 // indirect diff --git a/go.sum b/go.sum index af7592e25..11210846f 100644 --- a/go.sum +++ b/go.sum @@ -120,7 +120,7 @@ cloud.google.com/go/language v1.4.0/go.mod h1:F9dRpNFQmJbkaop6g0JhSBXCNlO90e1KWx cloud.google.com/go/language v1.6.0/go.mod h1:6dJ8t3B+lUYfStgls25GusK04NLh3eDLQnWM3mdEbhI= cloud.google.com/go/lifesciences v0.5.0/go.mod h1:3oIKy8ycWGPUyZDR/8RNnTOYevhaMLqh5vLUXs9zvT8= cloud.google.com/go/lifesciences v0.6.0/go.mod h1:ddj6tSX/7BOnhxCSd3ZcETvtNr8NZ6t/iPhY2Tyfu08= -cloud.google.com/go/longrunning v0.3.0 h1:NjljC+FYPV3uh5/OwWT6pVU+doBqMg2x/rZlE+CamDs= +cloud.google.com/go/longrunning v0.4.1 h1:v+yFJOfKC3yZdY6ZUI933pIYdhyhV8S3NpWrXWmg7jM= cloud.google.com/go/mediatranslation v0.5.0/go.mod h1:jGPUhGTybqsPQn91pNXw0xVHfuJ3leR1wj37oU3y1f4= cloud.google.com/go/mediatranslation v0.6.0/go.mod h1:hHdBCTYNigsBxshbznuIMFNe5QXEowAuNmmC7h8pu5w= cloud.google.com/go/memcache v1.4.0/go.mod h1:rTOfiGZtJX1AaFUrOgsMHX5kAzaTQ8azHiuDoTPzNsE= @@ -216,6 +216,7 @@ git.sr.ht/~sircmpwn/getopt v0.0.0-20191230200459-23622cc906b3/go.mod h1:wMEGFFFN 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/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= 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= @@ -224,6 +225,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/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno= +github.com/CloudyKit/jet/v3 v3.0.0/go.mod h1:HKQPgSJmdK8hdoAbKUUWajkHyHo4RaU5rMdUywE7VMo= github.com/CosmWasm/wasmd v0.40.0-rc.1.0.20230422061626-b85abcf1d7b8 h1:daJIcrTcYkpDtn1DXqbGhnQkCPSD93El6mXfv15VJRA= github.com/CosmWasm/wasmd v0.40.0-rc.1.0.20230422061626-b85abcf1d7b8/go.mod h1:uacdue6EGn9JA1TqBNHB3iCe4PCIChuFT23AzIl2VME= github.com/CosmWasm/wasmvm v1.2.3 h1:OKYlobwmVGbl0eSn0mXoAAjE5hIuXnQCLPjbNd91sVY= @@ -231,11 +234,15 @@ github.com/CosmWasm/wasmvm v1.2.3/go.mod h1:vW/E3h8j9xBQs9bCoijDuawKo9kCtxOaS8N8 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.5.2 h1:vUG4lAyuPCXO0TLbXvPv7EB7cNK1QV/luu55UHLrrn8= +github.com/DataDog/zstd v1.5.2/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= +github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= 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= +github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= 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= @@ -246,6 +253,7 @@ 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/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= github.com/alecthomas/participle/v2 v2.0.0-alpha7 h1:cK4vjj0VSgb3lN1nuKA5F7dw+1s1pWBe5bx7nNCnN+c= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= @@ -281,6 +289,7 @@ github.com/aws/aws-sdk-go-v2/service/route53 v1.1.1/go.mod h1:rLiOUrPLW/Er5kRcQ7 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/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= 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= @@ -316,6 +325,7 @@ 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/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA= 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= @@ -359,7 +369,19 @@ github.com/cockroachdb/apd/v2 v2.0.2 h1:weh8u7Cneje73dDh+2tEVLUvyBc89iwepWCD8b80 github.com/cockroachdb/apd/v2 v2.0.2/go.mod h1:DDxRlzC2lo3/vSlmSoS7JkqbbrARPuFOGr0B9pvN3Gw= github.com/cockroachdb/apd/v3 v3.1.0 h1:MK3Ow7LH0W8zkd5GMKA1PvS9qG3bWFI95WaVNfyZJ/w= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= +github.com/cockroachdb/datadriven v1.0.2 h1:H9MtNqVoVhvd9nCBwOyDjUEdZCREqbIdCJD93PBm/jA= +github.com/cockroachdb/datadriven v1.0.2/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= +github.com/cockroachdb/errors v1.9.1 h1:yFVvsI0VxmRShfawbt/laCIDy/mtTqqnvoNgiy5bEV8= +github.com/cockroachdb/errors v1.9.1/go.mod h1:2sxOtL2WIc096WSZqZ5h8fa17rdDq9HZOZLBCor4mBk= +github.com/cockroachdb/logtags v0.0.0-20211118104740-dabe8e521a4f/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= +github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE= +github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= +github.com/cockroachdb/pebble v0.0.0-20230226194802-02d779ffbc46 h1:yMaoO76pV9knZ6bzEwzPSHnPSCTnrJohwkIQirmii70= +github.com/cockroachdb/pebble v0.0.0-20230226194802-02d779ffbc46/go.mod h1:9lRMC4XN3/BLPtIp6kAKwIaHu369NOf2rMucPzipz50= +github.com/cockroachdb/redact v1.1.3 h1:AKZds10rFSIj7qADf0g46UixK8NNLwWTNdCIGS5wfSQ= +github.com/cockroachdb/redact v1.1.3/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= +github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= 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= @@ -382,6 +404,8 @@ github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSV github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cosmos/btcutil v1.0.5 h1:t+ZFcX77LpKtDBhjucvnOH8C2l2ioGsBNEQ3jef8xFk= github.com/cosmos/btcutil v1.0.5/go.mod h1:IyB7iuqZMJlthe2tkIFL33xPyzbFYP0XVdS8P5lUPis= +github.com/cosmos/cosmos-db v1.0.0-rc.1 h1:SjnT8B6WKMW9WEIX32qMhnEEKcI7ZP0+G1Sa9HD3nmY= +github.com/cosmos/cosmos-db v1.0.0-rc.1/go.mod h1:Dnmk3flSf5lkwCqvvjNpoxjpXzhxnCAFzKHlbaForso= github.com/cosmos/cosmos-proto v1.0.0-beta.2 h1:X3OKvWgK9Gsejo0F1qs5l8Qn6xJV/AzgIWR2wZ8Nua8= github.com/cosmos/cosmos-proto v1.0.0-beta.2/go.mod h1:+XRCLJ14pr5HFEHIUcn51IKXD1Fy3rkEQqt4WqmN4V0= github.com/cosmos/cosmos-sdk v0.47.2 h1:9rSriCoiJD+4F+tEDobyM8V7HF5BtY5Ef4VYNig96s0= @@ -394,8 +418,8 @@ github.com/cosmos/gogogateway v1.2.0/go.mod h1:iQpLkGWxYcnCdz5iAdLcRBSw3h7NXeOkZ github.com/cosmos/gogoproto v1.4.2/go.mod h1:cLxOsn1ljAHSV527CHOtaIP91kK6cCrZETRBrkzItWU= github.com/cosmos/gogoproto v1.4.8 h1:BrHKc6WFZt8+jRV71vKSQE+JrfF+JAnzrKo2VP7wIZ4= github.com/cosmos/gogoproto v1.4.8/go.mod h1:hnb0DIEWTv+wdNzNcqus5xCQXq5+CXauq1FJuurRfVY= -github.com/cosmos/iavl v0.20.0 h1:fTVznVlepH0KK8NyKq8w+U7c2L6jofa27aFX6YGlm38= -github.com/cosmos/iavl v0.20.0/go.mod h1:WO7FyvaZJoH65+HFOsDir7xU9FWk2w9cHXNW1XHcl7A= +github.com/cosmos/iavl v1.0.0-alpha.2 h1:aBJc1Y7u7/RhYtuUuMW8PaJKUcsuS2HG6ZBbgq9Vf3E= +github.com/cosmos/iavl v1.0.0-alpha.2/go.mod h1:OCWycs/BT5Qom9A4zjP7txeApQ7FfQBX+hdLXNnk2rk= github.com/cosmos/ibc-go/v7 v7.0.0 h1:j4kyywlG0hhDmT9FmSaR5iCIka7Pz7kJTxGWY1nlV9Q= github.com/cosmos/ibc-go/v7 v7.0.0/go.mod h1:BFh8nKWjr5zeR2OZfhkzdgDzj1+KjRn3aJLpwapStj8= github.com/cosmos/ics23/go v0.9.1-0.20221207100636-b1abd8678aab h1:I9ialKTQo7248V827Bba4OuKPmk+FPzmTVHsLXaIJWw= @@ -434,6 +458,7 @@ github.com/deepmap/oapi-codegen v1.6.0/go.mod h1:ryDa9AgbELGeB+YEXE1dR53yAjHwFvE 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 v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= 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= @@ -466,6 +491,9 @@ github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1 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 v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= +github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= +github.com/emicklei/dot v1.4.2 h1:UbK6gX4yvrpHKlxuUQicwoAis4zl8Dzwit9SnbBAXWw= +github.com/emicklei/dot v1.4.2/go.mod h1:DeV7GvQtIw4h2u73RKBkkFdvVAz0D9fzeJrgPW6gy/s= github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -477,9 +505,12 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.m github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw= github.com/ethereum/go-ethereum v1.10.17/go.mod h1:Lt5WzjM07XlXc95YzrhosmR4J9Ahd6X2wyEV2SvGhk0= +github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= 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/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/felixge/httpsnoop v1.0.2 h1:+nS9g82KMXccJ/wp0zyRW9ZBHFETmMGtkk+2CTTrW4o= github.com/felixge/httpsnoop v1.0.2/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= @@ -493,9 +524,13 @@ github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMo 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/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= 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/getsentry/sentry-go v0.12.0/go.mod h1:NSap0JBYWzHND8oMbyi0+XZhUalc1TBdRL1M71JZW2c= +github.com/getsentry/sentry-go v0.18.0 h1:MtBW5H9QgdcJabtZcuJG80BMOwaBpkRDZkxRkNC1sN0= +github.com/getsentry/sentry-go v0.18.0/go.mod h1:Kgon4Mby+FJ7ZWHFUAZgVaIa8sxHtnRJRLTXZr51aKQ= 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= @@ -503,7 +538,10 @@ github.com/gin-gonic/gin v1.8.1 h1:4+fr/el88TOO3ewCmQr8cx/CtZ/umlIRIs5M4NTNjf8= github.com/gin-gonic/gin v1.8.1/go.mod h1:ji8BvRH1azfM+SYow9zQ6SZMvR8qOMZHmsCuWR9tTTk= 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-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= github.com/go-chi/chi/v5 v5.0.0/go.mod h1:BBug9lr0cqtdAhsu6R4AAdvufI0/XBzAQSsUqJpoZOs= +github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= +github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= 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= @@ -519,6 +557,7 @@ github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4= github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= +github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= 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= @@ -546,6 +585,7 @@ github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2/go.mod h1:bBOAhwG1umN6 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/gofrs/uuid v4.3.0+incompatible h1:CaSVZxm5B+7o45rtab4jC2G37WGYX1zQfuU2i6DSvnc= +github.com/gogo/googleapis v0.0.0-20180223154316-0cd9801be74a/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/googleapis v1.4.1-0.20201022092350-68b0159b7869/go.mod h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c= github.com/gogo/googleapis v1.4.1 h1:1Yx4Myt7BxzvUr5ldGSbwYiZG6t9wGBZ+8/fX3Wvtq0= @@ -556,6 +596,8 @@ github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zV github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/gogo/status v1.1.0/go.mod h1:BFv9nrluPLmrS0EmGVvLaPNmRosr9KapBYd5/hpY1WM= +github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang-jwt/jwt/v4 v4.3.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= github.com/golang-jwt/jwt/v4 v4.4.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= @@ -604,6 +646,7 @@ github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEW 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/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= 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= @@ -625,6 +668,7 @@ github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8 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/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= 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= @@ -757,10 +801,12 @@ github.com/huandu/skiplist v1.2.0/go.mod h1:7v3iFjLcSAzO4fN5B8dvebvo/qsfumiLiDXM 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/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= +github.com/hydrogen18/memlistener v0.0.0-20200120041712-dcc25e7acd91/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= github.com/iancoleman/orderedmap v0.2.0 h1:sq1N/TFpYH++aViPcaKjys3bDClUEU7s5B+z6jq8pNA= github.com/iancoleman/orderedmap v0.2.0/go.mod h1:N0Wam8K1arqPXNWjMo21EXnBPOPp36vB07FNRdD2geA= 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/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= 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= @@ -778,11 +824,17 @@ github.com/influxdata/promql/v2 v2.12.0/go.mod h1:fxOPu+DY0bqCTCECchSRtWfc+0X19y 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/iris-contrib/blackfriday v2.0.0+incompatible/go.mod h1:UzZ2bDEoaSGPbkg6SAB4att1aAwTmVIx/5gCVqeyUdI= +github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/+fafWORmlnuysV2EMP8MW+qe0= +github.com/iris-contrib/jade v1.1.3/go.mod h1:H/geBymxJhShH5kecoiOCSssPX7QWYH7UaeZTSWddIk= +github.com/iris-contrib/pongo2 v0.0.1/go.mod h1:Ssh+00+3GAZqSQb30AvBRNxBx7rf0GqwkjqxNd0u65g= +github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw= 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/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c= +github.com/jhump/protoreflect v1.15.1/go.mod h1:jD/2GMKKE6OqX8qTjhADU1e6DShO+gavG9e0Q693nKo= 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= @@ -808,13 +860,21 @@ github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7V 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/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= github.com/karalabe/usb v0.0.2/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU= +github.com/kataras/golog v0.0.10/go.mod h1:yJ8YKCmyL+nWjERB90Qwn+bdyBZsaQwU3bTVFgkFIp8= +github.com/kataras/iris/v12 v12.1.8/go.mod h1:LMYy4VlP67TQ3Zgriz8RE2h2kMZV2SgMYbq3UhfoFmE= +github.com/kataras/neffos v0.0.14/go.mod h1:8lqADm8PnbeFfL7CLXh1WHw53dG27MC3pgi2R1rmoTE= +github.com/kataras/pio v0.0.2/go.mod h1:hAoW0t9UmXi4R5Oyq5Z4irTbaTsOemSrDGUtaTl7Dro= +github.com/kataras/sitemap v0.0.5/go.mod h1:KY2eugMKiPwsJgx7+U103YZehfvNGOXURubcGyk0Bz8= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= 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.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/compress v1.9.7/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= 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= @@ -822,6 +882,7 @@ github.com/klauspost/compress v1.15.11/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrD github.com/klauspost/compress v1.16.3 h1:XuJt9zzcnaz6a16/OU53ZjWp/v7/42WcR5t2a0PcNQY= github.com/klauspost/compress v1.16.3/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/klauspost/cpuid v0.0.0-20170728055534-ae7887de9fa5/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= +github.com/klauspost/cpuid v1.2.1/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= @@ -832,12 +893,14 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= 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/echo/v4 v4.5.0/go.mod h1:czIriw4a0C1dFun+ObrXp7ok03xON0N1awStJ6ArI7Y= 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.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= @@ -866,6 +929,7 @@ github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVc 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.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= 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= @@ -884,9 +948,12 @@ github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzp 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/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/mediocregopher/radix/v3 v3.4.2/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i4n7wVopoX3x7Bv8= +github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= 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= @@ -917,6 +984,7 @@ github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3Rllmb 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/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ= 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= @@ -944,6 +1012,7 @@ github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:v 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.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= @@ -986,6 +1055,8 @@ github.com/petermattis/goid v0.0.0-20221215004737-a150e88a970d/go.mod h1:pxMtw7c github.com/philhofer/fwd v1.0.0/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= +github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= +github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -1045,7 +1116,9 @@ github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6L github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= +github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/rs/cors v1.8.3 h1:O+qNyWn7Z+F9M0ILBHgMVPuB1xTOucVd5gtaYyXBpRo= github.com/rs/cors v1.8.3/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= @@ -1056,9 +1129,11 @@ github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= 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/ryanuber/columnize v2.1.0+incompatible/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.3.1 h1:sqv7fDNShgjcaxkO0JNcOAlr8B9+cV5Ey/OB71efZx0= github.com/sasha-s/go-deadlock v0.3.1/go.mod h1:F73l+cr82YSh10GxyRI6qZiCgK64VaZjwesgfQ1/iLM= +github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g= 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= @@ -1143,9 +1218,11 @@ github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1 github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs= github.com/tyler-smith/go-bip39 v1.0.2/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs= +github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go v1.2.7 h1:qYhyWUUd6WbiM+C6JZAUkIJt/1WrjzNHY9+KCIjVqTo= github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= github.com/ulikunitz/xz v0.5.10/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= @@ -1154,16 +1231,26 @@ github.com/ulikunitz/xz v0.5.11/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0o 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/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= 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/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= 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/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= +github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= 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/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= github.com/ybbus/jsonrpc v2.1.2+incompatible/go.mod h1:XJrh1eMSzdIYFbM08flv0wp5G35eRniyeGut1z+LSiE= +github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= +github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= +github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc= 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= @@ -1211,6 +1298,7 @@ golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190909091759-094676da4a83/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -1267,7 +1355,7 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8= +golang.org/x/mod v0.9.0 h1:KENHtAZL2y3NLMYZeHY9DW8HW8V+kQyJsY/V9JlKvCs= 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-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1280,6 +1368,7 @@ golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -1289,6 +1378,7 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -1320,6 +1410,7 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211008194852-3b03d305991f/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= @@ -1376,6 +1467,7 @@ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1444,6 +1536,7 @@ golang.org/x/sys v0.0.0-20210316164454-77fc1eacc6aa/go.mod h1:h1NjWce9XRLGQEsW7w 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-20210403161142-5e06dd20ab57/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= @@ -1460,6 +1553,7 @@ golang.org/x/sys v0.0.0-20210819135213-f52c844e1c1c/go.mod h1:oPkhp1MJrh7nUepCBc 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-20211007075335-d3039528d8ac/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= @@ -1515,12 +1609,14 @@ golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/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-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/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= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190327201419-c70d86f8b7cf/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= @@ -1575,7 +1671,7 @@ golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= +golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4= 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= @@ -1651,6 +1747,7 @@ google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCID 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-20180518175338-11a468237815/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= 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= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= @@ -1761,8 +1858,9 @@ google.golang.org/genproto v0.0.0-20221010155953-15ba04fc1c0e/go.mod h1:3526vdqw google.golang.org/genproto v0.0.0-20221014173430-6e2ab493f96b/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= google.golang.org/genproto v0.0.0-20221014213838-99cd37c6964a/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= google.golang.org/genproto v0.0.0-20221025140454-527a21cfbd71/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= -google.golang.org/genproto v0.0.0-20230216225411-c8e22ba71e44 h1:EfLuoKW5WfkgVdDy7dTK8qSbH37AX5mj/MFh+bGPz14= -google.golang.org/genproto v0.0.0-20230216225411-c8e22ba71e44/go.mod h1:8B0gmkoRebU8ukX6HP+4wrVQUY1+6PkQ44BSyIlflHA= +google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 h1:DdoeryqhaXp1LtT/emMP1BRJPHHKFi5akj/nbx/zNTA= +google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s= +google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= @@ -1836,8 +1934,10 @@ gopkg.in/cheggaaa/pb.v1 v1.0.27/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qS 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= +gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c= gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200619000410-60c24ae608a6/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= @@ -1855,6 +1955,7 @@ gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20191120175047-4206685974f2/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= From e034a2e645c5d682b1ffee1b38e4443ed011c414 Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Fri, 28 Apr 2023 20:28:47 -0500 Subject: [PATCH 057/131] Fix CollectGenTxsCmd (+script), sort keys --- app/keepers/keepers.go | 8 +-- app/keepers/keys.go | 24 +++++--- cmd/junod/cmd/root.go | 4 +- go.mod | 19 ++----- go.sum | 122 +++++------------------------------------ scripts/test_node.sh | 2 +- 6 files changed, 40 insertions(+), 139 deletions(-) diff --git a/app/keepers/keepers.go b/app/keepers/keepers.go index ef23c7375..e69b6432f 100644 --- a/app/keepers/keepers.go +++ b/app/keepers/keepers.go @@ -592,14 +592,14 @@ func initParamsKeeper(appCodec codec.BinaryCodec, legacyAmino *codec.LegacyAmino // custom paramsKeeper.Subspace(ibctransfertypes.ModuleName) - paramsKeeper.Subspace(packetforwardtypes.ModuleName).WithKeyTable(packetforwardtypes.ParamKeyTable()) paramsKeeper.Subspace(ibcexported.ModuleName) - paramsKeeper.Subspace(icacontrollertypes.SubModuleName) paramsKeeper.Subspace(icahosttypes.SubModuleName) - paramsKeeper.Subspace(wasm.ModuleName) + paramsKeeper.Subspace(packetforwardtypes.ModuleName) + paramsKeeper.Subspace(icacontrollertypes.SubModuleName) + paramsKeeper.Subspace(globalfee.ModuleName) paramsKeeper.Subspace(tokenfactorytypes.ModuleName) paramsKeeper.Subspace(feesharetypes.ModuleName) - paramsKeeper.Subspace(globalfee.ModuleName) + paramsKeeper.Subspace(wasm.ModuleName) return paramsKeeper } diff --git a/app/keepers/keys.go b/app/keepers/keys.go index 75473ef4b..12cced65f 100644 --- a/app/keepers/keys.go +++ b/app/keepers/keys.go @@ -12,6 +12,8 @@ import ( authzkeeper "github.com/cosmos/cosmos-sdk/x/authz/keeper" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" + consensusparamtypes "github.com/cosmos/cosmos-sdk/x/consensus/types" + crisistypes "github.com/cosmos/cosmos-sdk/x/crisis/types" distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" evidencetypes "github.com/cosmos/cosmos-sdk/x/evidence/types" "github.com/cosmos/cosmos-sdk/x/feegrant" @@ -24,7 +26,6 @@ import ( icahosttypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/host/types" ibcfeetypes "github.com/cosmos/ibc-go/v7/modules/apps/29-fee/types" ibctransfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" - ibchost "github.com/cosmos/ibc-go/v7/modules/core/24-host" ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" icqtypes "github.com/strangelove-ventures/async-icq/v7/types" packetforwardtypes "github.com/strangelove-ventures/packet-forward-middleware/v7/router/types" @@ -32,14 +33,21 @@ import ( func (appKeepers *AppKeepers) GenerateKeys() { appKeepers.keys = sdk.NewKVStoreKeys( - authtypes.StoreKey, banktypes.StoreKey, stakingtypes.StoreKey, + // authtypes.StoreKey, banktypes.StoreKey, stakingtypes.StoreKey, + // minttypes.StoreKey, distrtypes.StoreKey, slashingtypes.StoreKey, + // govtypes.StoreKey, paramstypes.StoreKey, ibcexported.StoreKey, upgradetypes.StoreKey, + // evidencetypes.StoreKey, capabilitytypes.StoreKey, + // authzkeeper.StoreKey, feegrant.StoreKey, + authtypes.StoreKey, banktypes.StoreKey, stakingtypes.StoreKey, crisistypes.StoreKey, minttypes.StoreKey, distrtypes.StoreKey, slashingtypes.StoreKey, - govtypes.StoreKey, paramstypes.StoreKey, ibcexported.StoreKey, upgradetypes.StoreKey, - evidencetypes.StoreKey, ibctransfertypes.StoreKey, capabilitytypes.StoreKey, - authzkeeper.StoreKey, feegrant.StoreKey, icahosttypes.StoreKey, ibcfeetypes.StoreKey, - tokenfactorytypes.StoreKey, feesharetypes.StoreKey, wasm.StoreKey, - icacontrollertypes.StoreKey, ibchookstypes.StoreKey, packetforwardtypes.StoreKey, - icqtypes.StoreKey, ibchost.SubModuleName, + govtypes.StoreKey, paramstypes.StoreKey, consensusparamtypes.StoreKey, upgradetypes.StoreKey, feegrant.StoreKey, + evidencetypes.StoreKey, capabilitytypes.StoreKey, + authzkeeper.StoreKey, + + // non sdk store keys + ibcexported.StoreKey, ibctransfertypes.StoreKey, ibcfeetypes.StoreKey, + wasm.StoreKey, icahosttypes.StoreKey, + icacontrollertypes.StoreKey, icqtypes.StoreKey, packetforwardtypes.StoreKey, ibchookstypes.StoreKey, tokenfactorytypes.StoreKey, feesharetypes.StoreKey, ) appKeepers.tkeys = sdk.NewTransientStoreKeys(paramstypes.TStoreKey) diff --git a/cmd/junod/cmd/root.go b/cmd/junod/cmd/root.go index 4370bd171..86ac31a7a 100644 --- a/cmd/junod/cmd/root.go +++ b/cmd/junod/cmd/root.go @@ -30,6 +30,7 @@ import ( banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" "github.com/cosmos/cosmos-sdk/x/crisis" genutilcli "github.com/cosmos/cosmos-sdk/x/genutil/client/cli" + "github.com/cosmos/cosmos-sdk/x/genutil/types" "github.com/spf13/cast" "github.com/spf13/cobra" @@ -209,8 +210,7 @@ func initRootCmd(rootCmd *cobra.Command, encodingConfig params.EncodingConfig) { rootCmd.AddCommand( genutilcli.InitCmd(app.ModuleBasics, app.DefaultNodeHome), - // TODO: - // genutilcli.CollectGenTxsCmd(banktypes.GenesisBalancesIterator{}, app.DefaultNodeHome, gentxModule.GenTxValidator), + genutilcli.CollectGenTxsCmd(banktypes.GenesisBalancesIterator{}, app.DefaultNodeHome, types.DefaultMessageValidator), genutilcli.GenTxCmd(app.ModuleBasics, encodingConfig.TxConfig, banktypes.GenesisBalancesIterator{}, app.DefaultNodeHome), genutilcli.ValidateGenesisCmd(app.ModuleBasics), genutilcli.AddGenesisAccountCmd(app.DefaultNodeHome), diff --git a/go.mod b/go.mod index 48b6676bd..455d45620 100644 --- a/go.mod +++ b/go.mod @@ -8,8 +8,9 @@ require ( cosmossdk.io/simapp v0.0.0-20230224204036-a6adb0821462 github.com/CosmWasm/wasmd v0.40.0-rc.1.0.20230422061626-b85abcf1d7b8 github.com/cometbft/cometbft v0.37.1 - github.com/cometbft/cometbft-db v0.8.0 + github.com/cometbft/cometbft-db v0.7.0 github.com/cosmos/cosmos-sdk v0.47.2 + github.com/cosmos/iavl v0.20.0 // indirect github.com/cosmos/ibc-go/v7 v7.0.0 github.com/golang/protobuf v1.5.3 github.com/gorilla/mux v1.8.0 @@ -35,21 +36,13 @@ require ( cloud.google.com/go/iam v0.12.0 // indirect cloud.google.com/go/storage v1.29.0 // indirect cosmossdk.io/tools/rosetta v0.2.1 // indirect - github.com/DataDog/zstd v1.5.2 // indirect github.com/aws/aws-sdk-go v1.44.203 // indirect github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect github.com/chzyer/readline v1.5.1 // indirect github.com/cockroachdb/apd/v2 v2.0.2 // indirect - github.com/cockroachdb/errors v1.9.1 // indirect - github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect - github.com/cockroachdb/pebble v0.0.0-20230226194802-02d779ffbc46 // indirect - github.com/cockroachdb/redact v1.1.3 // indirect - github.com/cosmos/cosmos-db v1.0.0-rc.1 // indirect github.com/cosmos/gogogateway v1.2.0 // indirect - github.com/cosmos/ics23/go v0.9.1-0.20221207100636-b1abd8678aab // indirect + github.com/cosmos/ics23/go v0.10.0 // indirect github.com/cosmos/rosetta-sdk-go v0.10.0 // indirect - github.com/emicklei/dot v1.4.2 // indirect - github.com/getsentry/sentry-go v0.18.0 // indirect github.com/gogo/googleapis v1.4.1 // indirect github.com/gogo/protobuf v1.3.3 // indirect github.com/golang/mock v1.6.0 // indirect @@ -63,13 +56,10 @@ require ( github.com/huandu/skiplist v1.2.0 // indirect github.com/jhump/protoreflect v1.15.1 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect - github.com/kr/pretty v0.3.1 // indirect - github.com/kr/text v0.2.0 // indirect - github.com/linxGnu/grocksdb v1.7.16 // indirect github.com/manifoldco/promptui v0.9.0 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/go-testing-interface v1.14.1 // indirect - github.com/rogpeppe/go-internal v1.9.0 // indirect + github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c // indirect github.com/ulikunitz/xz v0.5.11 // indirect golang.org/x/oauth2 v0.5.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect @@ -101,7 +91,6 @@ require ( github.com/cosmos/cosmos-proto v1.0.0-beta.2 github.com/cosmos/go-bip39 v1.0.0 // indirect github.com/cosmos/gogoproto v1.4.8 - github.com/cosmos/iavl v1.0.0-alpha.2 // indirect github.com/cosmos/ledger-cosmos-go v0.12.2 // indirect github.com/creachadair/taskgroup v0.4.2 // indirect github.com/danieljoos/wincred v1.1.2 // indirect diff --git a/go.sum b/go.sum index 11210846f..8640a669b 100644 --- a/go.sum +++ b/go.sum @@ -216,7 +216,6 @@ git.sr.ht/~sircmpwn/getopt v0.0.0-20191230200459-23622cc906b3/go.mod h1:wMEGFFFN 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/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= 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= @@ -225,8 +224,6 @@ 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/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno= -github.com/CloudyKit/jet/v3 v3.0.0/go.mod h1:HKQPgSJmdK8hdoAbKUUWajkHyHo4RaU5rMdUywE7VMo= github.com/CosmWasm/wasmd v0.40.0-rc.1.0.20230422061626-b85abcf1d7b8 h1:daJIcrTcYkpDtn1DXqbGhnQkCPSD93El6mXfv15VJRA= github.com/CosmWasm/wasmd v0.40.0-rc.1.0.20230422061626-b85abcf1d7b8/go.mod h1:uacdue6EGn9JA1TqBNHB3iCe4PCIChuFT23AzIl2VME= github.com/CosmWasm/wasmvm v1.2.3 h1:OKYlobwmVGbl0eSn0mXoAAjE5hIuXnQCLPjbNd91sVY= @@ -234,15 +231,11 @@ github.com/CosmWasm/wasmvm v1.2.3/go.mod h1:vW/E3h8j9xBQs9bCoijDuawKo9kCtxOaS8N8 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.5.2 h1:vUG4lAyuPCXO0TLbXvPv7EB7cNK1QV/luu55UHLrrn8= -github.com/DataDog/zstd v1.5.2/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= -github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= 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= -github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= 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= @@ -253,7 +246,6 @@ 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/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= github.com/alecthomas/participle/v2 v2.0.0-alpha7 h1:cK4vjj0VSgb3lN1nuKA5F7dw+1s1pWBe5bx7nNCnN+c= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= @@ -289,7 +281,6 @@ github.com/aws/aws-sdk-go-v2/service/route53 v1.1.1/go.mod h1:rLiOUrPLW/Er5kRcQ7 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/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= 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= @@ -369,26 +360,14 @@ github.com/cockroachdb/apd/v2 v2.0.2 h1:weh8u7Cneje73dDh+2tEVLUvyBc89iwepWCD8b80 github.com/cockroachdb/apd/v2 v2.0.2/go.mod h1:DDxRlzC2lo3/vSlmSoS7JkqbbrARPuFOGr0B9pvN3Gw= github.com/cockroachdb/apd/v3 v3.1.0 h1:MK3Ow7LH0W8zkd5GMKA1PvS9qG3bWFI95WaVNfyZJ/w= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= -github.com/cockroachdb/datadriven v1.0.2 h1:H9MtNqVoVhvd9nCBwOyDjUEdZCREqbIdCJD93PBm/jA= -github.com/cockroachdb/datadriven v1.0.2/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= -github.com/cockroachdb/errors v1.9.1 h1:yFVvsI0VxmRShfawbt/laCIDy/mtTqqnvoNgiy5bEV8= -github.com/cockroachdb/errors v1.9.1/go.mod h1:2sxOtL2WIc096WSZqZ5h8fa17rdDq9HZOZLBCor4mBk= -github.com/cockroachdb/logtags v0.0.0-20211118104740-dabe8e521a4f/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= -github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE= -github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= -github.com/cockroachdb/pebble v0.0.0-20230226194802-02d779ffbc46 h1:yMaoO76pV9knZ6bzEwzPSHnPSCTnrJohwkIQirmii70= -github.com/cockroachdb/pebble v0.0.0-20230226194802-02d779ffbc46/go.mod h1:9lRMC4XN3/BLPtIp6kAKwIaHu369NOf2rMucPzipz50= -github.com/cockroachdb/redact v1.1.3 h1:AKZds10rFSIj7qADf0g46UixK8NNLwWTNdCIGS5wfSQ= -github.com/cockroachdb/redact v1.1.3/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= -github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= 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/cometbft/cometbft v0.37.1 h1:KLxkQTK2hICXYq21U2hn1W5hOVYUdQgDQ1uB+90xPIg= github.com/cometbft/cometbft v0.37.1/go.mod h1:Y2MMMN//O5K4YKd8ze4r9jmk4Y7h0ajqILXbH5JQFVs= -github.com/cometbft/cometbft-db v0.8.0 h1:vUMDaH3ApkX8m0KZvOFFy9b5DZHBAjsnEuo9AKVZpjo= -github.com/cometbft/cometbft-db v0.8.0/go.mod h1:6ASCP4pfhmrCBpfk01/9E1SI29nD3HfVHrY4PG8x5c0= +github.com/cometbft/cometbft-db v0.7.0 h1:uBjbrBx4QzU0zOEnU8KxoDl18dMNgDh+zZRUE0ucsbo= +github.com/cometbft/cometbft-db v0.7.0/go.mod h1:yiKJIm2WKrt6x8Cyxtq9YTEcIMPcEe4XPxhgX59Fzf0= github.com/confio/ics23/go v0.9.0 h1:cWs+wdbS2KRPZezoaaj+qBleXgUk5WOQFMP3CQFGTr4= github.com/confio/ics23/go v0.9.0/go.mod h1:4LPZ2NYqnYIVRklaozjNR1FScgDJ2s5Xrp+e/mYVRak= github.com/consensys/bavard v0.1.8-0.20210406032232-f3452dc9b572/go.mod h1:Bpd0/3mZuaj6Sj+PqrmIquiOKy397AKGThQPaGzNXAQ= @@ -404,8 +383,6 @@ github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSV github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cosmos/btcutil v1.0.5 h1:t+ZFcX77LpKtDBhjucvnOH8C2l2ioGsBNEQ3jef8xFk= github.com/cosmos/btcutil v1.0.5/go.mod h1:IyB7iuqZMJlthe2tkIFL33xPyzbFYP0XVdS8P5lUPis= -github.com/cosmos/cosmos-db v1.0.0-rc.1 h1:SjnT8B6WKMW9WEIX32qMhnEEKcI7ZP0+G1Sa9HD3nmY= -github.com/cosmos/cosmos-db v1.0.0-rc.1/go.mod h1:Dnmk3flSf5lkwCqvvjNpoxjpXzhxnCAFzKHlbaForso= github.com/cosmos/cosmos-proto v1.0.0-beta.2 h1:X3OKvWgK9Gsejo0F1qs5l8Qn6xJV/AzgIWR2wZ8Nua8= github.com/cosmos/cosmos-proto v1.0.0-beta.2/go.mod h1:+XRCLJ14pr5HFEHIUcn51IKXD1Fy3rkEQqt4WqmN4V0= github.com/cosmos/cosmos-sdk v0.47.2 h1:9rSriCoiJD+4F+tEDobyM8V7HF5BtY5Ef4VYNig96s0= @@ -418,12 +395,12 @@ github.com/cosmos/gogogateway v1.2.0/go.mod h1:iQpLkGWxYcnCdz5iAdLcRBSw3h7NXeOkZ github.com/cosmos/gogoproto v1.4.2/go.mod h1:cLxOsn1ljAHSV527CHOtaIP91kK6cCrZETRBrkzItWU= github.com/cosmos/gogoproto v1.4.8 h1:BrHKc6WFZt8+jRV71vKSQE+JrfF+JAnzrKo2VP7wIZ4= github.com/cosmos/gogoproto v1.4.8/go.mod h1:hnb0DIEWTv+wdNzNcqus5xCQXq5+CXauq1FJuurRfVY= -github.com/cosmos/iavl v1.0.0-alpha.2 h1:aBJc1Y7u7/RhYtuUuMW8PaJKUcsuS2HG6ZBbgq9Vf3E= -github.com/cosmos/iavl v1.0.0-alpha.2/go.mod h1:OCWycs/BT5Qom9A4zjP7txeApQ7FfQBX+hdLXNnk2rk= +github.com/cosmos/iavl v0.20.0 h1:fTVznVlepH0KK8NyKq8w+U7c2L6jofa27aFX6YGlm38= +github.com/cosmos/iavl v0.20.0/go.mod h1:WO7FyvaZJoH65+HFOsDir7xU9FWk2w9cHXNW1XHcl7A= github.com/cosmos/ibc-go/v7 v7.0.0 h1:j4kyywlG0hhDmT9FmSaR5iCIka7Pz7kJTxGWY1nlV9Q= github.com/cosmos/ibc-go/v7 v7.0.0/go.mod h1:BFh8nKWjr5zeR2OZfhkzdgDzj1+KjRn3aJLpwapStj8= -github.com/cosmos/ics23/go v0.9.1-0.20221207100636-b1abd8678aab h1:I9ialKTQo7248V827Bba4OuKPmk+FPzmTVHsLXaIJWw= -github.com/cosmos/ics23/go v0.9.1-0.20221207100636-b1abd8678aab/go.mod h1:2CwqasX5dSD7Hbp/9b6lhK6BwoBDCBldx7gPKRukR60= +github.com/cosmos/ics23/go v0.10.0 h1:iXqLLgp2Lp+EdpIuwXTYIQU+AiHj9mOC2X9ab++bZDM= +github.com/cosmos/ics23/go v0.10.0/go.mod h1:ZfJSmng/TBNTBkFemHHHj5YY7VAU/MBU980F4VU1NG0= github.com/cosmos/keyring v1.2.0 h1:8C1lBP9xhImmIabyXW4c3vFjjLiBdGCmfLUfeZlV1Yo= github.com/cosmos/keyring v1.2.0/go.mod h1:fc+wB5KTk9wQ9sDx0kFXB3A0MaeGHM9AwRStKOQ5vOA= github.com/cosmos/ledger-cosmos-go v0.12.2 h1:/XYaBlE2BJxtvpkHiBm97gFGSGmYGKunKyF3nNqAXZA= @@ -458,7 +435,6 @@ github.com/deepmap/oapi-codegen v1.6.0/go.mod h1:ryDa9AgbELGeB+YEXE1dR53yAjHwFvE 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 v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= 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= @@ -491,9 +467,6 @@ github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1 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 v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= -github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= -github.com/emicklei/dot v1.4.2 h1:UbK6gX4yvrpHKlxuUQicwoAis4zl8Dzwit9SnbBAXWw= -github.com/emicklei/dot v1.4.2/go.mod h1:DeV7GvQtIw4h2u73RKBkkFdvVAz0D9fzeJrgPW6gy/s= github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -505,12 +478,12 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.m github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw= github.com/ethereum/go-ethereum v1.10.17/go.mod h1:Lt5WzjM07XlXc95YzrhosmR4J9Ahd6X2wyEV2SvGhk0= -github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= +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.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= -github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/felixge/httpsnoop v1.0.2 h1:+nS9g82KMXccJ/wp0zyRW9ZBHFETmMGtkk+2CTTrW4o= github.com/felixge/httpsnoop v1.0.2/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= @@ -524,13 +497,9 @@ github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMo 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/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= 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/getsentry/sentry-go v0.12.0/go.mod h1:NSap0JBYWzHND8oMbyi0+XZhUalc1TBdRL1M71JZW2c= -github.com/getsentry/sentry-go v0.18.0 h1:MtBW5H9QgdcJabtZcuJG80BMOwaBpkRDZkxRkNC1sN0= -github.com/getsentry/sentry-go v0.18.0/go.mod h1:Kgon4Mby+FJ7ZWHFUAZgVaIa8sxHtnRJRLTXZr51aKQ= 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= @@ -538,10 +507,7 @@ github.com/gin-gonic/gin v1.8.1 h1:4+fr/el88TOO3ewCmQr8cx/CtZ/umlIRIs5M4NTNjf8= github.com/gin-gonic/gin v1.8.1/go.mod h1:ji8BvRH1azfM+SYow9zQ6SZMvR8qOMZHmsCuWR9tTTk= 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-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= github.com/go-chi/chi/v5 v5.0.0/go.mod h1:BBug9lr0cqtdAhsu6R4AAdvufI0/XBzAQSsUqJpoZOs= -github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= -github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= 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= @@ -557,7 +523,6 @@ github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4= github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= -github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= 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= @@ -585,7 +550,6 @@ github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2/go.mod h1:bBOAhwG1umN6 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/gofrs/uuid v4.3.0+incompatible h1:CaSVZxm5B+7o45rtab4jC2G37WGYX1zQfuU2i6DSvnc= -github.com/gogo/googleapis v0.0.0-20180223154316-0cd9801be74a/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/googleapis v1.4.1-0.20201022092350-68b0159b7869/go.mod h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c= github.com/gogo/googleapis v1.4.1 h1:1Yx4Myt7BxzvUr5ldGSbwYiZG6t9wGBZ+8/fX3Wvtq0= @@ -596,8 +560,6 @@ github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zV github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/gogo/status v1.1.0/go.mod h1:BFv9nrluPLmrS0EmGVvLaPNmRosr9KapBYd5/hpY1WM= -github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang-jwt/jwt/v4 v4.3.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= github.com/golang-jwt/jwt/v4 v4.4.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= @@ -646,7 +608,6 @@ github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEW 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/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= 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= @@ -668,7 +629,6 @@ github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8 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/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= 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= @@ -801,12 +761,10 @@ github.com/huandu/skiplist v1.2.0/go.mod h1:7v3iFjLcSAzO4fN5B8dvebvo/qsfumiLiDXM 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/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= -github.com/hydrogen18/memlistener v0.0.0-20200120041712-dcc25e7acd91/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= github.com/iancoleman/orderedmap v0.2.0 h1:sq1N/TFpYH++aViPcaKjys3bDClUEU7s5B+z6jq8pNA= github.com/iancoleman/orderedmap v0.2.0/go.mod h1:N0Wam8K1arqPXNWjMo21EXnBPOPp36vB07FNRdD2geA= 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/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= 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= @@ -824,11 +782,6 @@ github.com/influxdata/promql/v2 v2.12.0/go.mod h1:fxOPu+DY0bqCTCECchSRtWfc+0X19y 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/iris-contrib/blackfriday v2.0.0+incompatible/go.mod h1:UzZ2bDEoaSGPbkg6SAB4att1aAwTmVIx/5gCVqeyUdI= -github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/+fafWORmlnuysV2EMP8MW+qe0= -github.com/iris-contrib/jade v1.1.3/go.mod h1:H/geBymxJhShH5kecoiOCSssPX7QWYH7UaeZTSWddIk= -github.com/iris-contrib/pongo2 v0.0.1/go.mod h1:Ssh+00+3GAZqSQb30AvBRNxBx7rf0GqwkjqxNd0u65g= -github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw= 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= @@ -860,21 +813,13 @@ github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7V 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/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= github.com/karalabe/usb v0.0.2/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU= -github.com/kataras/golog v0.0.10/go.mod h1:yJ8YKCmyL+nWjERB90Qwn+bdyBZsaQwU3bTVFgkFIp8= -github.com/kataras/iris/v12 v12.1.8/go.mod h1:LMYy4VlP67TQ3Zgriz8RE2h2kMZV2SgMYbq3UhfoFmE= -github.com/kataras/neffos v0.0.14/go.mod h1:8lqADm8PnbeFfL7CLXh1WHw53dG27MC3pgi2R1rmoTE= -github.com/kataras/pio v0.0.2/go.mod h1:hAoW0t9UmXi4R5Oyq5Z4irTbaTsOemSrDGUtaTl7Dro= -github.com/kataras/sitemap v0.0.5/go.mod h1:KY2eugMKiPwsJgx7+U103YZehfvNGOXURubcGyk0Bz8= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= 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.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/compress v1.9.7/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= 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= @@ -882,7 +827,6 @@ github.com/klauspost/compress v1.15.11/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrD github.com/klauspost/compress v1.16.3 h1:XuJt9zzcnaz6a16/OU53ZjWp/v7/42WcR5t2a0PcNQY= github.com/klauspost/compress v1.16.3/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/klauspost/cpuid v0.0.0-20170728055534-ae7887de9fa5/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= -github.com/klauspost/cpuid v1.2.1/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= @@ -893,14 +837,12 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= 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/echo/v4 v4.5.0/go.mod h1:czIriw4a0C1dFun+ObrXp7ok03xON0N1awStJ6ArI7Y= 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.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= @@ -912,8 +854,6 @@ github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6 github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= -github.com/linxGnu/grocksdb v1.7.16 h1:Q2co1xrpdkr5Hx3Fp+f+f7fRGhQFQhvi/+226dtLmA8= -github.com/linxGnu/grocksdb v1.7.16/go.mod h1:JkS7pl5qWpGpuVb3bPqTz8nC12X3YtPZT+Xq7+QfQo4= github.com/lucasjones/reggen v0.0.0-20180717132126-cdb49ff09d77/go.mod h1:5ELEyG+X8f+meRWHuqUOewBOhvHkl7M76pdGEansxW4= github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= @@ -929,7 +869,6 @@ github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVc 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.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= 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= @@ -948,12 +887,9 @@ github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzp 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/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= -github.com/mediocregopher/radix/v3 v3.4.2/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i4n7wVopoX3x7Bv8= -github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= 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= @@ -984,7 +920,6 @@ github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3Rllmb 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/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ= 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= @@ -1012,7 +947,6 @@ github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:v 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.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= @@ -1055,8 +989,6 @@ github.com/petermattis/goid v0.0.0-20221215004737-a150e88a970d/go.mod h1:pxMtw7c github.com/philhofer/fwd v1.0.0/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= -github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= -github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -1116,9 +1048,7 @@ github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6L github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= -github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= -github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/rs/cors v1.8.3 h1:O+qNyWn7Z+F9M0ILBHgMVPuB1xTOucVd5gtaYyXBpRo= github.com/rs/cors v1.8.3/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= @@ -1129,11 +1059,9 @@ github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= 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/ryanuber/columnize v2.1.0+incompatible/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.3.1 h1:sqv7fDNShgjcaxkO0JNcOAlr8B9+cV5Ey/OB71efZx0= github.com/sasha-s/go-deadlock v0.3.1/go.mod h1:F73l+cr82YSh10GxyRI6qZiCgK64VaZjwesgfQ1/iLM= -github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g= 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= @@ -1202,6 +1130,8 @@ github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8 github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= github.com/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/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c h1:g+WoO5jjkqGAzHWCjJB1zZfXPIAaDpzXIEJ0eS6B5Ok= +github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c/go.mod h1:ahpPrc7HpcfEWDQRZEmnXMzHY03mLDYMCxeDzy46i+8= 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/tidwall/btree v1.6.0 h1:LDZfKfQIBHGHWSwckhXI0RPSXzlo+KYdjK7FWSqOzzg= @@ -1218,11 +1148,9 @@ github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1 github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs= github.com/tyler-smith/go-bip39 v1.0.2/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs= -github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go v1.2.7 h1:qYhyWUUd6WbiM+C6JZAUkIJt/1WrjzNHY9+KCIjVqTo= github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= -github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= github.com/ulikunitz/xz v0.5.10/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= @@ -1231,26 +1159,16 @@ github.com/ulikunitz/xz v0.5.11/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0o 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/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= 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/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= 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/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= -github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= 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/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= github.com/ybbus/jsonrpc v2.1.2+incompatible/go.mod h1:XJrh1eMSzdIYFbM08flv0wp5G35eRniyeGut1z+LSiE= -github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= -github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= -github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc= 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= @@ -1298,7 +1216,6 @@ golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190909091759-094676da4a83/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -1355,7 +1272,7 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.9.0 h1:KENHtAZL2y3NLMYZeHY9DW8HW8V+kQyJsY/V9JlKvCs= +golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8= 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-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1368,7 +1285,6 @@ golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -1378,7 +1294,6 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -1410,7 +1325,6 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211008194852-3b03d305991f/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= @@ -1467,7 +1381,6 @@ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1536,7 +1449,6 @@ golang.org/x/sys v0.0.0-20210316164454-77fc1eacc6aa/go.mod h1:h1NjWce9XRLGQEsW7w 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-20210403161142-5e06dd20ab57/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= @@ -1553,7 +1465,6 @@ golang.org/x/sys v0.0.0-20210819135213-f52c844e1c1c/go.mod h1:oPkhp1MJrh7nUepCBc 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-20211007075335-d3039528d8ac/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= @@ -1609,14 +1520,12 @@ golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/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-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/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= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190327201419-c70d86f8b7cf/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= @@ -1671,7 +1580,7 @@ golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4= +golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= 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= @@ -1747,7 +1656,6 @@ google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCID 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-20180518175338-11a468237815/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= 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= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= @@ -1860,7 +1768,6 @@ google.golang.org/genproto v0.0.0-20221014213838-99cd37c6964a/go.mod h1:1vXfmgAz google.golang.org/genproto v0.0.0-20221025140454-527a21cfbd71/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 h1:DdoeryqhaXp1LtT/emMP1BRJPHHKFi5akj/nbx/zNTA= google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s= -google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= @@ -1934,10 +1841,8 @@ gopkg.in/cheggaaa/pb.v1 v1.0.27/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qS 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= -gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c= gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200619000410-60c24ae608a6/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= @@ -1955,7 +1860,6 @@ gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20191120175047-4206685974f2/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= diff --git a/scripts/test_node.sh b/scripts/test_node.sh index e00e0dfde..fbe57e61c 100755 --- a/scripts/test_node.sh +++ b/scripts/test_node.sh @@ -66,7 +66,7 @@ from_scratch () { update_test_genesis '.app_state["globalfee"]["params"]["minimum_gas_prices"]=[{"amount":"0.002500000000000000","denom":"ujuno"}]' update_test_genesis '.app_state["staking"]["params"]["bond_denom"]="ujuno"' - update_test_genesis '.app_state["bank"]["params"]["send_enabled"]=[{"denom": "ujuno","enabled": true}]' + # update_test_genesis '.app_state["bank"]["params"]["send_enabled"]=[{"denom": "ujuno","enabled": true}]' # update_test_genesis '.app_state["staking"]["params"]["min_commission_rate"]="0.100000000000000000"' # sdk 46 only update_test_genesis '.app_state["mint"]["params"]["mint_denom"]="ujuno"' From 0a475b1614e5649a3b9c5063dc855fd38c888a41 Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Fri, 28 Apr 2023 20:57:37 -0500 Subject: [PATCH 058/131] wasmtypes.WasmConfig --- cmd/junod/cmd/root.go | 45 +++++++++++++++---------------------------- 1 file changed, 15 insertions(+), 30 deletions(-) diff --git a/cmd/junod/cmd/root.go b/cmd/junod/cmd/root.go index 86ac31a7a..27ba8262f 100644 --- a/cmd/junod/cmd/root.go +++ b/cmd/junod/cmd/root.go @@ -27,10 +27,8 @@ import ( "github.com/cosmos/cosmos-sdk/version" authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" - banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" "github.com/cosmos/cosmos-sdk/x/crisis" genutilcli "github.com/cosmos/cosmos-sdk/x/genutil/client/cli" - "github.com/cosmos/cosmos-sdk/x/genutil/types" "github.com/spf13/cast" "github.com/spf13/cobra" @@ -120,42 +118,24 @@ func initTendermintConfig() *tmcfg.Config { // initAppConfig helps to override default appConfig template and configs. // return "", nil if no custom configuration is required for the application. func initAppConfig() (string, interface{}) { - // The following code snippet is just for reference. - - // WASMConfig defines configuration for the wasm module. - type WASMConfig struct { - // This is the maximum sdk gas (wasm and storage) that we allow for any x/wasm "smart" queries - QueryGasLimit uint64 `mapstructure:"query_gas_limit"` - - // Address defines the gRPC-web server to listen on - LruSize uint64 `mapstructure:"lru_size"` - } type CustomAppConfig struct { serverconfig.Config - WASM WASMConfig `mapstructure:"wasm"` + Wasm wasmtypes.WasmConfig `mapstructure:"wasm"` } // Optionally allow the chain developer to overwrite the SDK's default // server config. srvCfg := serverconfig.DefaultConfig() + // srvCfg.MinGasPrices = "0.0025ujuno,0.0025ujunox" customAppConfig := CustomAppConfig{ Config: *srvCfg, - WASM: WASMConfig{ - LruSize: 0, - QueryGasLimit: 300000, - }, + Wasm: wasmtypes.DefaultWasmConfig(), } - customAppTemplate := serverconfig.DefaultConfigTemplate + ` -[wasm] -# This is the maximum sdk gas (wasm and storage) that we allow for any x/wasm "smart" queries -query_gas_limit = 300000 -# This is the number of wasm vm instances we keep cached in memory for speed-up -# Warning: this is currently unstable and may lead to crashes, best to keep for 0 unless testing locally -lru_size = 0` + customAppTemplate := serverconfig.DefaultConfigTemplate + wasmtypes.DefaultConfigTemplate() return customAppTemplate, customAppConfig } @@ -206,14 +186,8 @@ func initRootCmd(rootCmd *cobra.Command, encodingConfig params.EncodingConfig) { encCfg: encodingConfig, } - // gentxModule := moduleBasics[genutiltypes.ModuleName].(genutil.AppModuleBasic) - rootCmd.AddCommand( genutilcli.InitCmd(app.ModuleBasics, app.DefaultNodeHome), - genutilcli.CollectGenTxsCmd(banktypes.GenesisBalancesIterator{}, app.DefaultNodeHome, types.DefaultMessageValidator), - genutilcli.GenTxCmd(app.ModuleBasics, encodingConfig.TxConfig, banktypes.GenesisBalancesIterator{}, app.DefaultNodeHome), - genutilcli.ValidateGenesisCmd(app.ModuleBasics), - genutilcli.AddGenesisAccountCmd(app.DefaultNodeHome), AddGenesisIcaCmd(app.DefaultNodeHome), tmcli.NewCompletionCmd(rootCmd, true), DebugCmd(), @@ -226,6 +200,7 @@ func initRootCmd(rootCmd *cobra.Command, encodingConfig params.EncodingConfig) { // add keybase, auxiliary RPC, query, and tx child commands rootCmd.AddCommand( rpc.StatusCommand(), + genesisCommand(encodingConfig), queryCommand(), txCommand(), keys.Commands(app.DefaultNodeHome), @@ -238,6 +213,16 @@ func addModuleInitFlags(startCmd *cobra.Command) { wasm.AddModuleInitFlags(startCmd) } +// genesisCommand builds genesis-related `simd genesis` command. Users may provide application specific commands as a parameter +func genesisCommand(encodingConfig params.EncodingConfig, cmds ...*cobra.Command) *cobra.Command { + cmd := genutilcli.GenesisCoreCommand(encodingConfig.TxConfig, app.ModuleBasics, app.DefaultNodeHome) + + for _, subCmd := range cmds { + cmd.AddCommand(subCmd) + } + return cmd +} + func queryCommand() *cobra.Command { cmd := &cobra.Command{ Use: "query", From c47ccb61988a41e95bcc6ae41ed061ada537ecba Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Fri, 28 Apr 2023 20:58:06 -0500 Subject: [PATCH 059/131] Consensus Module, StakingKeeper pointer, test_node genesis cmds --- app/export.go | 2 +- app/keepers/keepers.go | 17 +++++++++-------- app/modules.go | 30 ++++++++++++++++++++---------- scripts/test_node.sh | 10 +++++----- 4 files changed, 35 insertions(+), 24 deletions(-) diff --git a/app/export.go b/app/export.go index dd8bf400d..dabf5b8a7 100644 --- a/app/export.go +++ b/app/export.go @@ -33,7 +33,7 @@ func (app *App) ExportAppStateAndValidators(forZeroHeight bool, jailAllowedAddrs return servertypes.ExportedApp{}, err } - validators, err := staking.WriteValidators(ctx, &app.AppKeepers.StakingKeeper) + validators, err := staking.WriteValidators(ctx, app.AppKeepers.StakingKeeper) return servertypes.ExportedApp{ AppState: appState, Validators: validators, diff --git a/app/keepers/keepers.go b/app/keepers/keepers.go index e69b6432f..396d49662 100644 --- a/app/keepers/keepers.go +++ b/app/keepers/keepers.go @@ -128,7 +128,7 @@ type AppKeepers struct { AccountKeeper authkeeper.AccountKeeper BankKeeper bankkeeper.BaseKeeper CapabilityKeeper *capabilitykeeper.Keeper - StakingKeeper stakingkeeper.Keeper + StakingKeeper *stakingkeeper.Keeper SlashingKeeper slashingkeeper.Keeper MintKeeper mintkeeper.Keeper DistrKeeper distrkeeper.Keeper @@ -183,18 +183,19 @@ func NewAppKeepers( // Set keys KVStoreKey, TransientStoreKey, MemoryStoreKey appKeepers.GenerateKeys() + keys := appKeepers.GetKVStoreKey() + tkeys := appKeepers.GetTransientStoreKey() appKeepers.ParamsKeeper = initParamsKeeper( appCodec, cdc, - appKeepers.keys[paramstypes.StoreKey], - appKeepers.tkeys[paramstypes.TStoreKey], + keys[paramstypes.StoreKey], + tkeys[paramstypes.TStoreKey], ) - keys := appKeepers.GetKVStoreKey() - // set the BaseApp's parameter store appKeepers.ConsensusParamsKeeper = consensusparamkeeper.NewKeeper(appCodec, keys[consensusparamtypes.StoreKey], authtypes.NewModuleAddress(govtypes.ModuleName).String()) + bApp.SetParamStore(&appKeepers.ConsensusParamsKeeper) // add capability keeper and ScopeToModule for ibc module appKeepers.CapabilityKeeper = capabilitykeeper.NewKeeper( @@ -278,7 +279,7 @@ func NewAppKeepers( skipUpgradeHeights[int64(h)] = true } homePath := cast.ToString(appOpts.Get(flags.FlagHome)) - + // set the governance module account as the authority for conducting upgrades appKeepers.UpgradeKeeper = upgradekeeper.NewKeeper( skipUpgradeHeights, appKeepers.keys[upgradetypes.StoreKey], @@ -294,7 +295,7 @@ func NewAppKeepers( stakingtypes.NewMultiStakingHooks(appKeepers.DistrKeeper.Hooks(), appKeepers.SlashingKeeper.Hooks()), ) - appKeepers.StakingKeeper = *stakingKeeper + appKeepers.StakingKeeper = stakingKeeper // ... other modules keepers @@ -611,7 +612,7 @@ func (appKeepers *AppKeepers) GetSubspace(moduleName string) paramstypes.Subspac } // GetStakingKeeper implements the TestingApp interface. -func (appKeepers *AppKeepers) GetStakingKeeper() stakingkeeper.Keeper { +func (appKeepers *AppKeepers) GetStakingKeeper() *stakingkeeper.Keeper { return appKeepers.StakingKeeper } diff --git a/app/modules.go b/app/modules.go index 2d29e2d46..a3b417ca0 100644 --- a/app/modules.go +++ b/app/modules.go @@ -25,6 +25,8 @@ import ( banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" "github.com/cosmos/cosmos-sdk/x/capability" capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" + "github.com/cosmos/cosmos-sdk/x/consensus" + consensusparamtypes "github.com/cosmos/cosmos-sdk/x/consensus/types" "github.com/cosmos/cosmos-sdk/x/crisis" crisistypes "github.com/cosmos/cosmos-sdk/x/crisis/types" distr "github.com/cosmos/cosmos-sdk/x/distribution" @@ -53,6 +55,7 @@ import ( ibctransfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" ibc "github.com/cosmos/ibc-go/v7/modules/core" ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" + ibctm "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" icq "github.com/strangelove-ventures/async-icq/v7" icqtypes "github.com/strangelove-ventures/async-icq/v7/types" packetforward "github.com/strangelove-ventures/packet-forward-middleware/v7/router" @@ -64,7 +67,7 @@ import ( // and genesis verification. var ModuleBasics = module.NewBasicManager( auth.AppModuleBasic{}, - genutil.AppModuleBasic{}, + genutil.NewAppModuleBasic(genutiltypes.DefaultMessageValidator), bank.AppModuleBasic{}, capability.AppModuleBasic{}, staking.AppModuleBasic{}, @@ -74,18 +77,21 @@ var ModuleBasics = module.NewBasicManager( params.AppModuleBasic{}, crisis.AppModuleBasic{}, slashing.AppModuleBasic{}, - ibc.AppModuleBasic{}, - ibcfee.AppModuleBasic{}, - icq.AppModuleBasic{}, - feegrantmodule.AppModuleBasic{}, upgrade.AppModuleBasic{}, evidence.AppModuleBasic{}, - transfer.AppModuleBasic{}, - vesting.AppModuleBasic{}, authzmodule.AppModuleBasic{}, - tokenfactory.AppModuleBasic{}, + vesting.AppModuleBasic{}, + consensus.AppModuleBasic{}, + // non sdk modules wasm.AppModuleBasic{}, + ibc.AppModuleBasic{}, + ibctm.AppModuleBasic{}, + transfer.AppModuleBasic{}, ica.AppModuleBasic{}, + ibcfee.AppModuleBasic{}, + icq.AppModuleBasic{}, + feegrantmodule.AppModuleBasic{}, + tokenfactory.AppModuleBasic{}, feeshare.AppModuleBasic{}, globalfee.AppModuleBasic{}, ibchooks.AppModuleBasic{}, @@ -115,12 +121,13 @@ func appModules( mint.NewAppModule(appCodec, app.AppKeepers.MintKeeper, app.AppKeepers.AccountKeeper), slashing.NewAppModule(appCodec, app.AppKeepers.SlashingKeeper, app.AppKeepers.AccountKeeper, app.AppKeepers.BankKeeper, app.AppKeepers.StakingKeeper, app.GetSubspace(slashingtypes.ModuleName)), distr.NewAppModule(appCodec, app.AppKeepers.DistrKeeper, app.AppKeepers.AccountKeeper, app.AppKeepers.BankKeeper, app.AppKeepers.StakingKeeper, app.GetSubspace(distrtypes.ModuleName)), - staking.NewAppModule(appCodec, &app.AppKeepers.StakingKeeper, app.AppKeepers.AccountKeeper, app.AppKeepers.BankKeeper, app.GetSubspace(stakingtypes.ModuleName)), + staking.NewAppModule(appCodec, app.AppKeepers.StakingKeeper, app.AppKeepers.AccountKeeper, app.AppKeepers.BankKeeper, app.GetSubspace(stakingtypes.ModuleName)), upgrade.NewAppModule(app.AppKeepers.UpgradeKeeper), evidence.NewAppModule(app.AppKeepers.EvidenceKeeper), ibc.NewAppModule(app.AppKeepers.IBCKeeper), params.NewAppModule(app.AppKeepers.ParamsKeeper), authzmodule.NewAppModule(appCodec, app.AppKeepers.AuthzKeeper, app.AppKeepers.AccountKeeper, app.AppKeepers.BankKeeper, app.interfaceRegistry), + consensus.NewAppModule(appCodec, app.AppKeepers.ConsensusParamsKeeper), transfer.NewAppModule(app.AppKeepers.TransferKeeper), ibcfee.NewAppModule(app.AppKeepers.IBCFeeKeeper), tokenfactory.NewAppModule(app.AppKeepers.TokenFactoryKeeper, app.AppKeepers.AccountKeeper, app.AppKeepers.BankKeeper), @@ -153,7 +160,7 @@ func simulationModules( authzmodule.NewAppModule(appCodec, app.AppKeepers.AuthzKeeper, app.AppKeepers.AccountKeeper, app.AppKeepers.BankKeeper, app.interfaceRegistry), gov.NewAppModule(appCodec, &app.AppKeepers.GovKeeper, app.AppKeepers.AccountKeeper, app.AppKeepers.BankKeeper, app.GetSubspace(govtypes.ModuleName)), mint.NewAppModule(appCodec, app.AppKeepers.MintKeeper, app.AppKeepers.AccountKeeper), - staking.NewAppModule(appCodec, &app.AppKeepers.StakingKeeper, app.AppKeepers.AccountKeeper, app.AppKeepers.BankKeeper, app.GetSubspace(stakingtypes.ModuleName)), + staking.NewAppModule(appCodec, app.AppKeepers.StakingKeeper, app.AppKeepers.AccountKeeper, app.AppKeepers.BankKeeper, app.GetSubspace(stakingtypes.ModuleName)), distr.NewAppModule(appCodec, app.AppKeepers.DistrKeeper, app.AppKeepers.AccountKeeper, app.AppKeepers.BankKeeper, app.AppKeepers.StakingKeeper, app.GetSubspace(distrtypes.ModuleName)), slashing.NewAppModule(appCodec, app.AppKeepers.SlashingKeeper, app.AppKeepers.AccountKeeper, app.AppKeepers.BankKeeper, app.AppKeepers.StakingKeeper, app.GetSubspace(stakingtypes.ModuleName)), params.NewAppModule(app.AppKeepers.ParamsKeeper), @@ -186,6 +193,7 @@ func orderBeginBlockers() []string { feegrant.ModuleName, paramstypes.ModuleName, vestingtypes.ModuleName, + consensusparamtypes.ModuleName, // additional modules ibcexported.ModuleName, ibctransfertypes.ModuleName, @@ -219,6 +227,7 @@ func orderEndBlockers() []string { paramstypes.ModuleName, upgradetypes.ModuleName, vestingtypes.ModuleName, + consensusparamtypes.ModuleName, // additional non simd modules ibcexported.ModuleName, ibctransfertypes.ModuleName, @@ -252,6 +261,7 @@ func orderInitBlockers() []string { upgradetypes.ModuleName, vestingtypes.ModuleName, feegrant.ModuleName, + consensusparamtypes.ModuleName, // additional non simd modules ibcexported.ModuleName, ibctransfertypes.ModuleName, diff --git a/scripts/test_node.sh b/scripts/test_node.sh index fbe57e61c..711df88bf 100755 --- a/scripts/test_node.sh +++ b/scripts/test_node.sh @@ -80,16 +80,16 @@ from_scratch () { update_test_genesis '.app_state["feeshare"]["params"]["allowed_denoms"]=["ujuno"]' # Allocate genesis accounts - BINARY add-genesis-account $KEY 10000000ujuno,1000utest --keyring-backend $KEYRING - BINARY add-genesis-account feeacc 1000000ujuno,1000utest --keyring-backend $KEYRING + BINARY genesis add-genesis-account $KEY 10000000ujuno,1000utest --keyring-backend $KEYRING + BINARY genesis add-genesis-account feeacc 1000000ujuno,1000utest --keyring-backend $KEYRING - BINARY gentx $KEY 1000000ujuno --keyring-backend $KEYRING --chain-id $CHAIN_ID + BINARY genesis gentx $KEY 1000000ujuno --keyring-backend $KEYRING --chain-id $CHAIN_ID # Collect genesis tx - BINARY collect-gentxs + BINARY genesis collect-gentxs # Run this to ensure junorything worked and that the genesis file is setup correctly - BINARY validate-genesis + BINARY genesis validate-genesis } # check if CLEAN is not set to false From 149fd5c0e159ea0cb6100c6089bf514f43e8c693 Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Fri, 28 Apr 2023 21:01:51 -0500 Subject: [PATCH 060/131] Fix IBC Keeper (ibcexported type) --- app/keepers/keepers.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/app/keepers/keepers.go b/app/keepers/keepers.go index 396d49662..e3b98e466 100644 --- a/app/keepers/keepers.go +++ b/app/keepers/keepers.go @@ -60,7 +60,6 @@ import ( ibcclienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" ibcconnectiontypes "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" porttypes "github.com/cosmos/ibc-go/v7/modules/core/05-port/types" - ibchost "github.com/cosmos/ibc-go/v7/modules/core/24-host" ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" ibckeeper "github.com/cosmos/ibc-go/v7/modules/core/keeper" @@ -302,8 +301,8 @@ func NewAppKeepers( // Create IBC Keeper appKeepers.IBCKeeper = ibckeeper.NewKeeper( appCodec, - appKeepers.keys[ibchost.SubModuleName], - appKeepers.GetSubspace(ibchost.SubModuleName), + appKeepers.keys[ibcexported.StoreKey], + appKeepers.GetSubspace(ibcexported.ModuleName), appKeepers.StakingKeeper, appKeepers.UpgradeKeeper, scopedIBCKeeper, From 534101140af08b3a4ef3d8a5d739bb254c7ba63c Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Fri, 28 Apr 2023 21:05:30 -0500 Subject: [PATCH 061/131] Add icqtypes to params keeper --- app/keepers/keepers.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/keepers/keepers.go b/app/keepers/keepers.go index e3b98e466..f3ac3e2cf 100644 --- a/app/keepers/keepers.go +++ b/app/keepers/keepers.go @@ -594,8 +594,9 @@ func initParamsKeeper(appCodec codec.BinaryCodec, legacyAmino *codec.LegacyAmino paramsKeeper.Subspace(ibctransfertypes.ModuleName) paramsKeeper.Subspace(ibcexported.ModuleName) paramsKeeper.Subspace(icahosttypes.SubModuleName) - paramsKeeper.Subspace(packetforwardtypes.ModuleName) paramsKeeper.Subspace(icacontrollertypes.SubModuleName) + paramsKeeper.Subspace(icqtypes.ModuleName) + paramsKeeper.Subspace(packetforwardtypes.ModuleName) paramsKeeper.Subspace(globalfee.ModuleName) paramsKeeper.Subspace(tokenfactorytypes.ModuleName) paramsKeeper.Subspace(feesharetypes.ModuleName) From d55d91a9b2f172aedec676cae345e9020534dcd0 Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Fri, 28 Apr 2023 21:07:01 -0500 Subject: [PATCH 062/131] Staking WithKeyTable for GlobalFee --- app/keepers/keepers.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/keepers/keepers.go b/app/keepers/keepers.go index f3ac3e2cf..fd040b2b6 100644 --- a/app/keepers/keepers.go +++ b/app/keepers/keepers.go @@ -583,7 +583,7 @@ func initParamsKeeper(appCodec codec.BinaryCodec, legacyAmino *codec.LegacyAmino paramsKeeper.Subspace(authtypes.ModuleName) paramsKeeper.Subspace(banktypes.ModuleName) - paramsKeeper.Subspace(stakingtypes.ModuleName) + paramsKeeper.Subspace(stakingtypes.ModuleName).WithKeyTable(stakingtypes.ParamKeyTable()) // Used for GlobalFee paramsKeeper.Subspace(minttypes.ModuleName) paramsKeeper.Subspace(distrtypes.ModuleName) paramsKeeper.Subspace(slashingtypes.ModuleName) From 8ee0735a6a92bfb59f7fe17067a55bbb1016ac1c Mon Sep 17 00:00:00 2001 From: Jacob Gadikian Date: Sat, 29 Apr 2023 11:35:46 +0700 Subject: [PATCH 063/131] golangci-lint run ./... --fix --- app/app.go | 4 ++-- cmd/junod/cmd/root.go | 2 -- x/ibc-hooks/keeper/keeper.go | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/app/app.go b/app/app.go index 51958f3b9..33307584b 100644 --- a/app/app.go +++ b/app/app.go @@ -209,7 +209,7 @@ type App struct { sm *module.SimulationManager // module configurator - configurator module.Configurator + // configurator module.Configurator // TODO: I think we need to do something with this... } // New returns a reference to an initialized Juno. @@ -466,7 +466,7 @@ func (app *App) GetSubspace(moduleName string) paramstypes.Subspace { // RegisterAPIRoutes registers all application module routes with the provided // API server. -func (app *App) RegisterAPIRoutes(apiSvr *api.Server, apiConfig config.APIConfig) { +func (app *App) RegisterAPIRoutes(apiSvr *api.Server, _ config.APIConfig) { clientCtx := apiSvr.ClientCtx // Register new tx routes from grpc-gateway. authtx.RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCGatewayRouter) diff --git a/cmd/junod/cmd/root.go b/cmd/junod/cmd/root.go index 27ba8262f..19d3adfc2 100644 --- a/cmd/junod/cmd/root.go +++ b/cmd/junod/cmd/root.go @@ -92,7 +92,6 @@ func NewRootCmd() (*cobra.Command, params.EncodingConfig) { customTMConfig := initTendermintConfig() return server.InterceptConfigsPreRunHandler(cmd, customAppTemplate, customAppConfig, customTMConfig) - }, } @@ -118,7 +117,6 @@ func initTendermintConfig() *tmcfg.Config { // initAppConfig helps to override default appConfig template and configs. // return "", nil if no custom configuration is required for the application. func initAppConfig() (string, interface{}) { - type CustomAppConfig struct { serverconfig.Config diff --git a/x/ibc-hooks/keeper/keeper.go b/x/ibc-hooks/keeper/keeper.go index b099a9acc..9118f04cb 100644 --- a/x/ibc-hooks/keeper/keeper.go +++ b/x/ibc-hooks/keeper/keeper.go @@ -58,6 +58,6 @@ func (k Keeper) DeletePacketCallback(ctx sdk.Context, channel string, packetSequ func DeriveIntermediateSender(channel, originalSender, bech32Prefix string) (string, error) { senderStr := fmt.Sprintf("%s/%s", channel, originalSender) senderHash32 := address.Hash(types.SenderPrefix, []byte(senderStr)) - sender := sdk.AccAddress(senderHash32[:]) + sender := sdk.AccAddress(senderHash32) return sdk.Bech32ifyAddressBytes(bech32Prefix, sender) } From 6fa642910373dfdc90f9081321c38fb1bc00077f Mon Sep 17 00:00:00 2001 From: Jacob Gadikian Date: Sat, 29 Apr 2023 12:32:26 +0700 Subject: [PATCH 064/131] comply with golangci-lint --- app/app.go | 8 ++++---- app/decorators/min_commission.go | 7 ++++--- app/export.go | 15 +++++++++++---- app/keepers/keepers.go | 1 - app/test_helpers.go | 4 ++-- x/feeshare/integration_test.go | 4 ++-- x/feeshare/types/errors.go | 14 +++++++------- x/feeshare/types/feeshare.go | 3 ++- x/feeshare/types/msg.go | 7 ++++--- x/globalfee/ante/antetest/fee_test_setup.go | 3 +-- x/ibc-hooks/client/cli/query.go | 2 +- x/ibc-hooks/sdkmodule.go | 18 +++++++++--------- x/ibc-hooks/wasm_hook.go | 4 ++-- x/mint/keeper/integration_test.go | 19 ++----------------- x/mint/module.go | 2 +- x/tokenfactory/bindings/message_plugin.go | 13 +++++++------ x/tokenfactory/module.go | 2 +- x/tokenfactory/types/denoms.go | 8 ++++---- 18 files changed, 64 insertions(+), 70 deletions(-) diff --git a/app/app.go b/app/app.go index 33307584b..292c75e40 100644 --- a/app/app.go +++ b/app/app.go @@ -48,6 +48,7 @@ import ( ibcchanneltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" "github.com/spf13/cast" + errorsmod "cosmossdk.io/errors" "github.com/CosmWasm/wasmd/x/wasm" wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" @@ -122,16 +123,16 @@ func SetAddressPrefixes() { // source: https://github.com/cosmos/cosmos-sdk/blob/v0.43.0-beta1/types/address.go#L141 config.SetAddressVerifier(func(bytes []byte) error { if len(bytes) == 0 { - return sdkerrors.Wrap(sdkerrors.ErrUnknownAddress, "addresses cannot be empty") + return errorsmod.Wrap(sdkerrors.ErrUnknownAddress, "addresses cannot be empty") } if len(bytes) > address.MaxAddrLen { - return sdkerrors.Wrapf(sdkerrors.ErrUnknownAddress, "address max length is %d, got %d", address.MaxAddrLen, len(bytes)) + return errorsmod.Wrapf(sdkerrors.ErrUnknownAddress, "address max length is %d, got %d", address.MaxAddrLen, len(bytes)) } // TODO: Do we want to allow addresses of lengths other than 20 and 32 bytes? if len(bytes) != 20 && len(bytes) != 32 { - return sdkerrors.Wrapf(sdkerrors.ErrUnknownAddress, "address length must be 20 or 32 bytes, got %d", len(bytes)) + return errorsmod.Wrapf(sdkerrors.ErrUnknownAddress, "address length must be 20 or 32 bytes, got %d", len(bytes)) } return nil @@ -251,7 +252,6 @@ func New( bApp, legacyAmino, keepers.GetMaccPerms(), - app.ModuleAccountAddrs(), enabledProposals, appOpts, wasmOpts, diff --git a/app/decorators/min_commission.go b/app/decorators/min_commission.go index ec330a489..fd8833b28 100644 --- a/app/decorators/min_commission.go +++ b/app/decorators/min_commission.go @@ -1,6 +1,7 @@ package decorators import ( + errorsmod "cosmossdk.io/errors" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" @@ -35,7 +36,7 @@ func (min MinCommissionDecorator) AnteHandle( // commission set below 5% c := msg.Commission if c.Rate.LT(minCommissionRate) { - return sdkerrors.Wrap(sdkerrors.ErrUnauthorized, "commission can't be lower than 5%") + return errorsmod.Wrap(sdkerrors.ErrUnauthorized, "commission can't be lower than 5%") } case *stakingtypes.MsgEditValidator: // if commission rate is nil, it means only @@ -44,7 +45,7 @@ func (min MinCommissionDecorator) AnteHandle( break } if msg.CommissionRate.LT(minCommissionRate) { - return sdkerrors.Wrap(sdkerrors.ErrUnauthorized, "commission can't be lower than 5%") + return errorsmod.Wrap(sdkerrors.ErrUnauthorized, "commission can't be lower than 5%") } } @@ -56,7 +57,7 @@ func (min MinCommissionDecorator) AnteHandle( var innerMsg sdk.Msg err := min.cdc.UnpackAny(v, &innerMsg) if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrUnauthorized, "cannot unmarshal authz exec msgs") + return errorsmod.Wrapf(sdkerrors.ErrUnauthorized, "cannot unmarshal authz exec msgs") } err = validMsg(innerMsg) diff --git a/app/export.go b/app/export.go index dabf5b8a7..ae91730c8 100644 --- a/app/export.go +++ b/app/export.go @@ -105,14 +105,21 @@ func (app *App) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs []str feePool.CommunityPool = feePool.CommunityPool.Add(scraps...) app.AppKeepers.DistrKeeper.SetFeePool(ctx, feePool) - app.AppKeepers.DistrKeeper.Hooks().AfterValidatorCreated(ctx, val.GetOperator()) - return false + err := app.AppKeepers.DistrKeeper.Hooks().AfterValidatorCreated(ctx, val.GetOperator()) + + return err != nil }) // reinitialize all delegations for _, del := range dels { - app.AppKeepers.DistrKeeper.Hooks().BeforeDelegationCreated(ctx, del.GetDelegatorAddr(), del.GetValidatorAddr()) - app.AppKeepers.DistrKeeper.Hooks().AfterDelegationModified(ctx, del.GetDelegatorAddr(), del.GetValidatorAddr()) + err := app.AppKeepers.DistrKeeper.Hooks().BeforeDelegationCreated(ctx, del.GetDelegatorAddr(), del.GetValidatorAddr()) + if err != nil { + panic(err) + } + err = app.AppKeepers.DistrKeeper.Hooks().AfterDelegationModified(ctx, del.GetDelegatorAddr(), del.GetValidatorAddr()) + if err != nil { + panic(err) + } } // reset context height diff --git a/app/keepers/keepers.go b/app/keepers/keepers.go index fd040b2b6..81e65a6e9 100644 --- a/app/keepers/keepers.go +++ b/app/keepers/keepers.go @@ -173,7 +173,6 @@ func NewAppKeepers( bApp *baseapp.BaseApp, cdc *codec.LegacyAmino, maccPerms map[string][]string, - blockedAddress map[string]bool, enabledProposals []wasm.ProposalType, appOpts servertypes.AppOptions, wasmOpts []wasm.Option, diff --git a/app/test_helpers.go b/app/test_helpers.go index 88cc9af70..0a4b8eb97 100644 --- a/app/test_helpers.go +++ b/app/test_helpers.go @@ -92,7 +92,7 @@ func Setup(t *testing.T) *App { func SetupWithGenesisValSet(t *testing.T, valSet *tmtypes.ValidatorSet, genAccs []authtypes.GenesisAccount, balances ...banktypes.Balance) *App { t.Helper() - junoApp, genesisState := setup(true, 5) + junoApp, genesisState := setup(true) genesisState = genesisStateWithValSet(t, junoApp, genesisState, valSet, genAccs, balances...) stateBytes, err := json.MarshalIndent(genesisState, "", " ") @@ -119,7 +119,7 @@ func SetupWithGenesisValSet(t *testing.T, valSet *tmtypes.ValidatorSet, genAccs return junoApp } -func setup(withGenesis bool, invCheckPeriod uint) (*App, GenesisState) { +func setup(withGenesis bool) (*App, GenesisState) { db := dbm.NewMemDB() encCdc := MakeEncodingConfig() var emptyWasmOpts []wasm.Option diff --git a/x/feeshare/integration_test.go b/x/feeshare/integration_test.go index 50d3f9bed..bcf8891d2 100644 --- a/x/feeshare/integration_test.go +++ b/x/feeshare/integration_test.go @@ -28,7 +28,7 @@ func CreateTestApp(isCheckTx bool) (*junoapp.App, sdk.Context) { } func Setup(isCheckTx bool) *junoapp.App { - app, genesisState := GenApp(!isCheckTx, 5) + app, genesisState := GenApp(!isCheckTx) if !isCheckTx { // init chain must be called to stop deliverState from being nil stateBytes, err := json.MarshalIndent(genesisState, "", " ") @@ -49,7 +49,7 @@ func Setup(isCheckTx bool) *junoapp.App { return app } -func GenApp(withGenesis bool, invCheckPeriod uint) (*junoapp.App, junoapp.GenesisState) { +func GenApp(withGenesis bool) (*junoapp.App, junoapp.GenesisState) { db := dbm.NewMemDB() encCdc := junoapp.MakeEncodingConfig() diff --git a/x/feeshare/types/errors.go b/x/feeshare/types/errors.go index 1984d89d1..231c8557e 100644 --- a/x/feeshare/types/errors.go +++ b/x/feeshare/types/errors.go @@ -1,15 +1,15 @@ package types import ( - sdkerrrors "github.com/cosmos/cosmos-sdk/types/errors" + errorsmod "cosmossdk.io/errors" ) // errors var ( - ErrFeeShareDisabled = sdkerrrors.Register(ModuleName, 1, "feeshare module is disabled by governance") - ErrFeeShareAlreadyRegistered = sdkerrrors.Register(ModuleName, 2, "feeshare already exists for given contract") - ErrFeeShareNoContractDeployed = sdkerrrors.Register(ModuleName, 3, "no contract deployed") - ErrFeeShareContractNotRegistered = sdkerrrors.Register(ModuleName, 4, "no feeshare registered for contract") - ErrFeeSharePayment = sdkerrrors.Register(ModuleName, 5, "feeshare payment error") - ErrFeeShareInvalidWithdrawer = sdkerrrors.Register(ModuleName, 6, "invalid withdrawer address") + ErrFeeShareDisabled = errorsmod.Register(ModuleName, 1, "feeshare module is disabled by governance") + ErrFeeShareAlreadyRegistered = errorsmod.Register(ModuleName, 2, "feeshare already exists for given contract") + ErrFeeShareNoContractDeployed = errorsmod.Register(ModuleName, 3, "no contract deployed") + ErrFeeShareContractNotRegistered = errorsmod.Register(ModuleName, 4, "no feeshare registered for contract") + ErrFeeSharePayment = errorsmod.Register(ModuleName, 5, "feeshare payment error") + ErrFeeShareInvalidWithdrawer = errorsmod.Register(ModuleName, 6, "invalid withdrawer address") ) diff --git a/x/feeshare/types/feeshare.go b/x/feeshare/types/feeshare.go index 03804cc65..188b54138 100644 --- a/x/feeshare/types/feeshare.go +++ b/x/feeshare/types/feeshare.go @@ -1,6 +1,7 @@ package types import ( + errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" sdkerror "github.com/cosmos/cosmos-sdk/types/errors" ) @@ -53,7 +54,7 @@ func (fs FeeShare) Validate() error { } if fs.WithdrawerAddress == "" { - return sdkerror.Wrap(sdkerror.ErrInvalidAddress, "withdrawer address cannot be empty") + return errorsmod.Wrap(sdkerror.ErrInvalidAddress, "withdrawer address cannot be empty") } if _, err := sdk.AccAddressFromBech32(fs.WithdrawerAddress); err != nil { diff --git a/x/feeshare/types/msg.go b/x/feeshare/types/msg.go index 4b64323e3..e7dd282b5 100644 --- a/x/feeshare/types/msg.go +++ b/x/feeshare/types/msg.go @@ -1,6 +1,7 @@ package types import ( + errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) @@ -134,15 +135,15 @@ func (msg MsgUpdateFeeShare) Type() string { return TypeMsgUpdateFeeShare } // ValidateBasic runs stateless checks on the message func (msg MsgUpdateFeeShare) ValidateBasic() error { if _, err := sdk.AccAddressFromBech32(msg.DeployerAddress); err != nil { - return sdkerrors.Wrapf(err, "invalid deployer address %s", msg.DeployerAddress) + return errorsmod.Wrapf(err, "invalid deployer address %s", msg.DeployerAddress) } if _, err := sdk.AccAddressFromBech32(msg.ContractAddress); err != nil { - return sdkerrors.Wrapf(err, "invalid contract address %s", msg.ContractAddress) + return errorsmod.Wrapf(err, "invalid contract address %s", msg.ContractAddress) } if _, err := sdk.AccAddressFromBech32(msg.WithdrawerAddress); err != nil { - return sdkerrors.Wrapf(err, "invalid withdraw address %s", msg.WithdrawerAddress) + return errorsmod.Wrapf(err, "invalid withdraw address %s", msg.WithdrawerAddress) } return nil diff --git a/x/globalfee/ante/antetest/fee_test_setup.go b/x/globalfee/ante/antetest/fee_test_setup.go index c28696243..b1505d343 100644 --- a/x/globalfee/ante/antetest/fee_test_setup.go +++ b/x/globalfee/ante/antetest/fee_test_setup.go @@ -20,7 +20,6 @@ import ( "github.com/CosmosContracts/juno/v15/app" gaiafeeante "github.com/CosmosContracts/juno/v15/x/globalfee/ante" - junoapp "github.com/CosmosContracts/juno/v15/app" appparams "github.com/CosmosContracts/juno/v15/app/params" "github.com/CosmosContracts/juno/v15/x/globalfee" globfeetypes "github.com/CosmosContracts/juno/v15/x/globalfee/types" @@ -29,7 +28,7 @@ import ( type IntegrationTestSuite struct { suite.Suite - app *junoapp.App + app *app.App ctx sdk.Context clientCtx client.Context txBuilder client.TxBuilder diff --git a/x/ibc-hooks/client/cli/query.go b/x/ibc-hooks/client/cli/query.go index 82f58282a..6a0121537 100644 --- a/x/ibc-hooks/client/cli/query.go +++ b/x/ibc-hooks/client/cli/query.go @@ -13,7 +13,7 @@ import ( "github.com/CosmosContracts/juno/v15/x/ibc-hooks/types" ) -func indexRunCmd(cmd *cobra.Command, args []string) error { +func indexRunCmd(cmd *cobra.Command, _ []string) error { usageTemplate := `Usage:{{if .HasAvailableSubCommands}} {{.CommandPath}} [command]{{end}} diff --git a/x/ibc-hooks/sdkmodule.go b/x/ibc-hooks/sdkmodule.go index ea425bfae..2d4959b08 100644 --- a/x/ibc-hooks/sdkmodule.go +++ b/x/ibc-hooks/sdkmodule.go @@ -37,28 +37,28 @@ func (AppModuleBasic) Name() string { } // RegisterLegacyAminoCodec registers the ibc-hooks module's types on the given LegacyAmino codec. -func (AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) {} +func (AppModuleBasic) RegisterLegacyAminoCodec(_ *codec.LegacyAmino) {} // RegisterInterfaces registers the module's interface types. func (b AppModuleBasic) RegisterInterfaces(_ cdctypes.InterfaceRegistry) {} // DefaultGenesis returns default genesis state as raw bytes for the // module. -func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage { +func (AppModuleBasic) DefaultGenesis(_ codec.JSONCodec) json.RawMessage { emptyString := "{}" return []byte(emptyString) } // ValidateGenesis performs genesis state validation for the ibc-hooks module. -func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, config client.TxEncodingConfig, bz json.RawMessage) error { +func (AppModuleBasic) ValidateGenesis(_ codec.JSONCodec, _ client.TxEncodingConfig, _ json.RawMessage) error { return nil } // RegisterRESTRoutes registers the REST routes for the ibc-hooks module. -func (AppModuleBasic) RegisterRESTRoutes(clientCtx client.Context, rtr *mux.Router) {} +func (AppModuleBasic) RegisterRESTRoutes(_ client.Context, _ *mux.Router) {} // RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the ibc-hooks module. -func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) {} +func (AppModuleBasic) RegisterGRPCGatewayRoutes(_ client.Context, _ *runtime.ServeMux) {} // GetTxCmd returns no root tx command for the ibc-hooks module. func (AppModuleBasic) GetTxCmd() *cobra.Command { return nil } @@ -100,21 +100,21 @@ func (AppModule) QuerierRoute() string { // RegisterServices registers a gRPC query service to respond to the // module-specific gRPC queries. -func (am AppModule) RegisterServices(cfg module.Configurator) { +func (am AppModule) RegisterServices(_ module.Configurator) { } // InitGenesis performs genesis initialization for the ibc-hooks module. It returns // no validator updates. -func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, data json.RawMessage) []abci.ValidatorUpdate { +func (am AppModule) InitGenesis(_ sdk.Context, _ codec.JSONCodec, _ json.RawMessage) []abci.ValidatorUpdate { return []abci.ValidatorUpdate{} } -func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.RawMessage { +func (am AppModule) ExportGenesis(_ sdk.Context, _ codec.JSONCodec) json.RawMessage { return json.RawMessage([]byte("{}")) } // BeginBlock returns the begin blocker for the ibc-hooks module. -func (am AppModule) BeginBlock(ctx sdk.Context, _ abci.RequestBeginBlock) { +func (am AppModule) BeginBlock(_ sdk.Context, _ abci.RequestBeginBlock) { } // EndBlock returns the end blocker for the ibc-hooks module. It returns no validator diff --git a/x/ibc-hooks/wasm_hook.go b/x/ibc-hooks/wasm_hook.go index 47d55b431..1755a931b 100644 --- a/x/ibc-hooks/wasm_hook.go +++ b/x/ibc-hooks/wasm_hook.go @@ -356,7 +356,7 @@ func (h WasmHooks) OnAcknowledgementPacketOverride(im IBCMiddleware, ctx sdk.Con } // Notify the sender that the ack has been received - ackAsJson, err := json.Marshal(acknowledgement) + ackAsJSON, err := json.Marshal(acknowledgement) if err != nil { // If the ack is not a json object, error return err @@ -364,7 +364,7 @@ func (h WasmHooks) OnAcknowledgementPacketOverride(im IBCMiddleware, ctx sdk.Con sudoMsg := []byte(fmt.Sprintf( `{"ibc_lifecycle_complete": {"ibc_ack": {"channel": "%s", "sequence": %d, "ack": %s, "success": %s}}}`, - packet.SourceChannel, packet.Sequence, ackAsJson, success)) + packet.SourceChannel, packet.Sequence, ackAsJSON, success)) _, err = h.ContractKeeper.Sudo(ctx, contractAddr, sudoMsg) if err != nil { // error processing the callback diff --git a/x/mint/keeper/integration_test.go b/x/mint/keeper/integration_test.go index 2c816b1d5..4d9fd513a 100644 --- a/x/mint/keeper/integration_test.go +++ b/x/mint/keeper/integration_test.go @@ -7,28 +7,13 @@ import ( dbm "github.com/cometbft/cometbft-db" abci "github.com/cometbft/cometbft/abci/types" "github.com/cometbft/cometbft/libs/log" - tmproto "github.com/cometbft/cometbft/proto/tendermint/types" simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" junoapp "github.com/CosmosContracts/juno/v15/app" - - "github.com/CosmosContracts/juno/v15/x/mint/types" - sdk "github.com/cosmos/cosmos-sdk/types" ) -// returns context and an app with updated mint keeper -func createTestApp(isCheckTx bool) (*junoapp.App, sdk.Context) { //nolint:unparam - app := setup(isCheckTx) - - ctx := app.BaseApp.NewContext(isCheckTx, tmproto.Header{}) - app.AppKeepers.MintKeeper.SetParams(ctx, types.DefaultParams()) - app.AppKeepers.MintKeeper.SetMinter(ctx, types.DefaultInitialMinter()) - - return app, ctx -} - func setup(isCheckTx bool) *junoapp.App { - app, genesisState := genApp(!isCheckTx, 5) + app, genesisState := genApp(!isCheckTx) if !isCheckTx { // init chain must be called to stop deliverState from being nil stateBytes, err := json.MarshalIndent(genesisState, "", " ") @@ -49,7 +34,7 @@ func setup(isCheckTx bool) *junoapp.App { return app } -func genApp(withGenesis bool, invCheckPeriod uint) (*junoapp.App, junoapp.GenesisState) { +func genApp(withGenesis bool) (*junoapp.App, junoapp.GenesisState) { db := dbm.NewMemDB() encCdc := junoapp.MakeEncodingConfig() diff --git a/x/mint/module.go b/x/mint/module.go index 530c7ba05..22e584691 100644 --- a/x/mint/module.go +++ b/x/mint/module.go @@ -151,7 +151,7 @@ func (AppModule) GenerateGenesisState(simState *module.SimulationState) { } // ProposalContents doesn't return any content functions for governance proposals. -func (AppModule) ProposalContents(_ module.SimulationState) []simtypes.WeightedProposalContent { +func (AppModule) ProposalContents(_ module.SimulationState) []simtypes.WeightedProposalContent { //nolint:staticcheck // we need this to satisfy the upstream interface return nil } diff --git a/x/tokenfactory/bindings/message_plugin.go b/x/tokenfactory/bindings/message_plugin.go index 8431b0473..9e3c00a31 100644 --- a/x/tokenfactory/bindings/message_plugin.go +++ b/x/tokenfactory/bindings/message_plugin.go @@ -3,6 +3,7 @@ package bindings import ( "encoding/json" + errorsmod "cosmossdk.io/errors" wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" wasmvmtypes "github.com/CosmWasm/wasmvm/types" sdk "github.com/cosmos/cosmos-sdk/types" @@ -41,10 +42,10 @@ func (m *CustomMessenger) DispatchMsg(ctx sdk.Context, contractAddr sdk.AccAddre // leave everything else for the wrapped version var contractMsg bindingstypes.TokenFactoryMsg if err := json.Unmarshal(msg.Custom, &contractMsg); err != nil { - return nil, nil, sdkerrors.Wrap(err, "token factory msg") + return nil, nil, errorsmod.Wrap(err, "token factory msg") } if contractMsg.Token == nil { - return nil, nil, sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, "nil token field") + return nil, nil, errorsmod.Wrap(sdkerrors.ErrUnknownRequest, "nil token field") } tokenMsg := contractMsg.Token @@ -74,7 +75,7 @@ func (m *CustomMessenger) DispatchMsg(ctx sdk.Context, contractAddr sdk.AccAddre func (m *CustomMessenger) createDenom(ctx sdk.Context, contractAddr sdk.AccAddress, createDenom *bindingstypes.CreateDenom) ([]sdk.Event, [][]byte, error) { bz, err := PerformCreateDenom(m.tokenFactory, m.bank, ctx, contractAddr, createDenom) if err != nil { - return nil, nil, sdkerrors.Wrap(err, "perform create denom") + return nil, nil, errorsmod.Wrap(err, "perform create denom") } // TODO: double check how this is all encoded to the contract return nil, [][]byte{bz}, nil @@ -91,7 +92,7 @@ func PerformCreateDenom(f *tokenfactorykeeper.Keeper, b *bankkeeper.BaseKeeper, msgCreateDenom := tokenfactorytypes.NewMsgCreateDenom(contractAddr.String(), createDenom.Subdenom) if err := msgCreateDenom.ValidateBasic(); err != nil { - return nil, sdkerrors.Wrap(err, "failed validating MsgCreateDenom") + return nil, errorsmod.Wrap(err, "failed validating MsgCreateDenom") } // Create denom @@ -100,14 +101,14 @@ func PerformCreateDenom(f *tokenfactorykeeper.Keeper, b *bankkeeper.BaseKeeper, msgCreateDenom, ) if err != nil { - return nil, sdkerrors.Wrap(err, "creating denom") + return nil, errorsmod.Wrap(err, "creating denom") } if createDenom.Metadata != nil { newDenom := resp.NewTokenDenom err := PerformSetMetadata(f, b, ctx, contractAddr, newDenom, *createDenom.Metadata) if err != nil { - return nil, sdkerrors.Wrap(err, "setting metadata") + return nil, errorsmod.Wrap(err, "setting metadata") } } diff --git a/x/tokenfactory/module.go b/x/tokenfactory/module.go index 3f6bec93f..f14648494 100644 --- a/x/tokenfactory/module.go +++ b/x/tokenfactory/module.go @@ -199,7 +199,7 @@ func (AppModule) GenerateGenesisState(simState *module.SimulationState) { } // GenerateGenesisState creates a randomized GenState of the bank module. -func (am AppModule) ProposalContents(_ module.SimulationState) []simtypes.WeightedProposalContent { +func (am AppModule) ProposalContents(_ module.SimulationState) []simtypes.WeightedProposalMsg { return nil } diff --git a/x/tokenfactory/types/denoms.go b/x/tokenfactory/types/denoms.go index 7a9f2f9e9..658399856 100644 --- a/x/tokenfactory/types/denoms.go +++ b/x/tokenfactory/types/denoms.go @@ -3,8 +3,8 @@ package types import ( "strings" + errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) const ( @@ -46,17 +46,17 @@ func DeconstructDenom(denom string) (creator string, subdenom string, err error) strParts := strings.Split(denom, "/") if len(strParts) < 3 { - return "", "", sdkerrors.Wrapf(ErrInvalidDenom, "not enough parts of denom %s", denom) + return "", "", errorsmod.Wrapf(ErrInvalidDenom, "not enough parts of denom %s", denom) } if strParts[0] != ModuleDenomPrefix { - return "", "", sdkerrors.Wrapf(ErrInvalidDenom, "denom prefix is incorrect. Is: %s. Should be: %s", strParts[0], ModuleDenomPrefix) + return "", "", errorsmod.Wrapf(ErrInvalidDenom, "denom prefix is incorrect. Is: %s. Should be: %s", strParts[0], ModuleDenomPrefix) } creator = strParts[1] creatorAddr, err := sdk.AccAddressFromBech32(creator) if err != nil { - return "", "", sdkerrors.Wrapf(ErrInvalidDenom, "Invalid creator address (%s)", err) + return "", "", errorsmod.Wrapf(ErrInvalidDenom, "Invalid creator address (%s)", err) } // Handle the case where a denom has a slash in its subdenom. For example, From f428ee48e97dfc97aeaaaffc0f428163d59e3eb0 Mon Sep 17 00:00:00 2001 From: Jacob Gadikian Date: Sat, 29 Apr 2023 12:54:21 +0700 Subject: [PATCH 065/131] pass the linter --- .golangci.yml | 3 ++ app/keepers/keepers.go | 6 ++-- app/keepers/keys.go | 2 +- app/modules.go | 4 +-- app/sim_test.go | 4 +-- app/upgrades/v13/constants.go | 2 +- app/upgrades/v14/constants.go | 2 +- x/feeshare/ante/ante.go | 7 +++-- x/feeshare/keeper/msg_server.go | 24 ++++++++-------- x/feeshare/types/msg.go | 11 ++++---- x/feeshare/types/query.go | 8 +++--- x/globalfee/ante/fee.go | 9 +++--- x/globalfee/module.go | 4 +-- x/globalfee/types/genesis.go | 4 +-- x/globalfee/types/params.go | 3 +- x/{ibc-hooks => ibchooks}/.cargo/config | 0 x/{ibc-hooks => ibchooks}/README.md | 0 x/{ibc-hooks => ibchooks}/client/cli/query.go | 4 +-- x/{ibc-hooks => ibchooks}/hooks.go | 2 +- x/{ibc-hooks => ibchooks}/ibc_module.go | 2 +- x/{ibc-hooks => ibchooks}/ics4_middleware.go | 4 +-- x/{ibc-hooks => ibchooks}/keeper/keeper.go | 2 +- x/{ibc-hooks => ibchooks}/sdkmodule.go | 6 ++-- x/{ibc-hooks => ibchooks}/types/errors.go | 0 x/{ibc-hooks => ibchooks}/types/keys.go | 0 x/{ibc-hooks => ibchooks}/wasm_hook.go | 18 ++++++------ x/tokenfactory/bindings/message_plugin.go | 28 +++++++++---------- x/tokenfactory/bindings/query_plugin.go | 9 +++--- x/tokenfactory/types/genesis.go | 6 ++-- 29 files changed, 90 insertions(+), 84 deletions(-) rename x/{ibc-hooks => ibchooks}/.cargo/config (100%) rename x/{ibc-hooks => ibchooks}/README.md (100%) rename x/{ibc-hooks => ibchooks}/client/cli/query.go (94%) rename x/{ibc-hooks => ibchooks}/hooks.go (99%) rename x/{ibc-hooks => ibchooks}/ibc_module.go (99%) rename x/{ibc-hooks => ibchooks}/ics4_middleware.go (93%) rename x/{ibc-hooks => ibchooks}/keeper/keeper.go (97%) rename x/{ibc-hooks => ibchooks}/sdkmodule.go (96%) rename x/{ibc-hooks => ibchooks}/types/errors.go (100%) rename x/{ibc-hooks => ibchooks}/types/keys.go (100%) rename x/{ibc-hooks => ibchooks}/wasm_hook.go (96%) diff --git a/.golangci.yml b/.golangci.yml index 8eeca2d1c..41c3bcf27 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -33,3 +33,6 @@ linters-settings: gosec: excludes: - G404 + +issues: + max-issues-per-linter: 0 diff --git a/app/keepers/keepers.go b/app/keepers/keepers.go index 81e65a6e9..059c8f425 100644 --- a/app/keepers/keepers.go +++ b/app/keepers/keepers.go @@ -3,13 +3,13 @@ package keepers import ( "path/filepath" - ibchookstypes "github.com/CosmosContracts/juno/v15/x/ibc-hooks/types" + ibchookstypes "github.com/CosmosContracts/juno/v15/x/ibchooks/types" "github.com/spf13/cast" "github.com/CosmWasm/wasmd/x/wasm" wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" - ibchooks "github.com/CosmosContracts/juno/v15/x/ibc-hooks" - ibchookskeeper "github.com/CosmosContracts/juno/v15/x/ibc-hooks/keeper" + ibchooks "github.com/CosmosContracts/juno/v15/x/ibchooks" + ibchookskeeper "github.com/CosmosContracts/juno/v15/x/ibchooks/keeper" mintkeeper "github.com/CosmosContracts/juno/v15/x/mint/keeper" minttypes "github.com/CosmosContracts/juno/v15/x/mint/types" "github.com/cosmos/cosmos-sdk/baseapp" diff --git a/app/keepers/keys.go b/app/keepers/keys.go index 12cced65f..13440be4e 100644 --- a/app/keepers/keys.go +++ b/app/keepers/keys.go @@ -3,7 +3,7 @@ package keepers import ( "github.com/CosmWasm/wasmd/x/wasm" feesharetypes "github.com/CosmosContracts/juno/v15/x/feeshare/types" - ibchookstypes "github.com/CosmosContracts/juno/v15/x/ibc-hooks/types" + ibchookstypes "github.com/CosmosContracts/juno/v15/x/ibchooks/types" minttypes "github.com/CosmosContracts/juno/v15/x/mint/types" tokenfactorytypes "github.com/CosmosContracts/juno/v15/x/tokenfactory/types" storetypes "github.com/cosmos/cosmos-sdk/store/types" diff --git a/app/modules.go b/app/modules.go index a3b417ca0..f464167fe 100644 --- a/app/modules.go +++ b/app/modules.go @@ -7,8 +7,8 @@ import ( feeshare "github.com/CosmosContracts/juno/v15/x/feeshare" feesharetypes "github.com/CosmosContracts/juno/v15/x/feeshare/types" "github.com/CosmosContracts/juno/v15/x/globalfee" - ibchooks "github.com/CosmosContracts/juno/v15/x/ibc-hooks" - ibchookstypes "github.com/CosmosContracts/juno/v15/x/ibc-hooks/types" + ibchooks "github.com/CosmosContracts/juno/v15/x/ibchooks" + ibchookstypes "github.com/CosmosContracts/juno/v15/x/ibchooks/types" "github.com/CosmosContracts/juno/v15/x/mint" minttypes "github.com/CosmosContracts/juno/v15/x/mint/types" "github.com/CosmosContracts/juno/v15/x/tokenfactory" diff --git a/app/sim_test.go b/app/sim_test.go index f4bbd5597..afe21ef5c 100644 --- a/app/sim_test.go +++ b/app/sim_test.go @@ -38,7 +38,7 @@ type StoreKeysPrefixes struct { } // SetupSimulation wraps simapp.SetupSimulation in order to create any export directory if they do not exist yet -func SetupSimulation(dirPrefix, dbName string) (simtypes.Config, dbm.DB, string, log.Logger, bool, error) { +func SetupSimulation() (simtypes.Config, dbm.DB, string, log.Logger, bool, error) { config := simcli.NewConfigFromFlags() config.ChainID = SimAppChainID @@ -90,7 +90,7 @@ func fauxMerkleModeOpt(bapp *baseapp.BaseApp) { } func TestFullAppSimulation(t *testing.T) { - config, db, dir, logger, skip, err := SetupSimulation("leveldb-app-sim", "Simulation") + config, db, dir, logger, skip, err := SetupSimulation() if skip { t.Skip("skipping application simulation") } diff --git a/app/upgrades/v13/constants.go b/app/upgrades/v13/constants.go index 3e51991c4..0d2dd95aa 100644 --- a/app/upgrades/v13/constants.go +++ b/app/upgrades/v13/constants.go @@ -3,7 +3,7 @@ package v13 import ( "github.com/CosmosContracts/juno/v15/app/upgrades" feesharetypes "github.com/CosmosContracts/juno/v15/x/feeshare/types" - ibchookstypes "github.com/CosmosContracts/juno/v15/x/ibc-hooks/types" + ibchookstypes "github.com/CosmosContracts/juno/v15/x/ibchooks/types" tokenfactorytypes "github.com/CosmosContracts/juno/v15/x/tokenfactory/types" store "github.com/cosmos/cosmos-sdk/store/types" icacontrollertypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/types" diff --git a/app/upgrades/v14/constants.go b/app/upgrades/v14/constants.go index 89fa9c6d2..d4505ae3c 100644 --- a/app/upgrades/v14/constants.go +++ b/app/upgrades/v14/constants.go @@ -3,7 +3,7 @@ package v14 import ( "github.com/CosmosContracts/juno/v15/app/upgrades" "github.com/CosmosContracts/juno/v15/x/globalfee" - ibchookstypes "github.com/CosmosContracts/juno/v15/x/ibc-hooks/types" + ibchookstypes "github.com/CosmosContracts/juno/v15/x/ibchooks/types" store "github.com/cosmos/cosmos-sdk/store/types" ) diff --git a/x/feeshare/ante/ante.go b/x/feeshare/ante/ante.go index 653471b7e..4a8f86931 100644 --- a/x/feeshare/ante/ante.go +++ b/x/feeshare/ante/ante.go @@ -1,6 +1,7 @@ package ante import ( + errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" @@ -26,12 +27,12 @@ func NewFeeSharePayoutDecorator(bk BankKeeper, fs FeeShareKeeper) FeeSharePayout func (fsd FeeSharePayoutDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) { feeTx, ok := tx.(sdk.FeeTx) if !ok { - return ctx, sdkerrors.Wrap(sdkerrors.ErrTxDecode, "Tx must be a FeeTx") + return ctx, errorsmod.Wrap(sdkerrors.ErrTxDecode, "Tx must be a FeeTx") } err = FeeSharePayout(ctx, fsd.bankKeeper, feeTx.GetFee(), fsd.feesharekeeper, tx.GetMsgs()) if err != nil { - return ctx, sdkerrors.Wrapf(sdkerrors.ErrInsufficientFunds, err.Error()) + return ctx, errorsmod.Wrapf(sdkerrors.ErrInsufficientFunds, err.Error()) } return next(ctx, tx, simulate) @@ -108,7 +109,7 @@ func FeeSharePayout(ctx sdk.Context, bankKeeper BankKeeper, totalFees sdk.Coins, for _, withdrawAddr := range toPay { err := bankKeeper.SendCoinsFromModuleToAccount(ctx, authtypes.FeeCollectorName, withdrawAddr, splitFees) if err != nil { - return sdkerrors.Wrapf(feeshare.ErrFeeSharePayment, "failed to pay fees to contract developer: %s", err.Error()) + return errorsmod.Wrapf(feeshare.ErrFeeSharePayment, "failed to pay fees to contract developer: %s", err.Error()) } } } diff --git a/x/feeshare/keeper/msg_server.go b/x/feeshare/keeper/msg_server.go index 32103d287..dc6e13bc3 100644 --- a/x/feeshare/keeper/msg_server.go +++ b/x/feeshare/keeper/msg_server.go @@ -44,7 +44,7 @@ func (k Keeper) GetContractAdminOrCreatorAddress(ctx sdk.Context, contract sdk.A // Ensures deployer String is valid _, err := sdk.AccAddressFromBech32(deployer) if err != nil { - return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid deployer address %s", deployer) + return nil, errorsmod.Wrapf(sdkerrors.ErrInvalidAddress, "invalid deployer address %s", deployer) } info := k.wasmKeeper.GetContractInfo(ctx, contract) @@ -52,23 +52,23 @@ func (k Keeper) GetContractAdminOrCreatorAddress(ctx sdk.Context, contract sdk.A if len(info.Admin) == 0 { // no admin, see if they are the creator of the contract if info.Creator != deployer { - return nil, sdkerrors.Wrapf(sdkerrors.ErrUnauthorized, "you are not the creator of this contract %s", info.Creator) + return nil, errorsmod.Wrapf(sdkerrors.ErrUnauthorized, "you are not the creator of this contract %s", info.Creator) } creatorAddr, err := sdk.AccAddressFromBech32(info.Creator) if err != nil { - return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid creator address %s", info.Creator) + return nil, errorsmod.Wrapf(sdkerrors.ErrInvalidAddress, "invalid creator address %s", info.Creator) } controllingAccount = creatorAddr } else { // Admin is set, so we check if the deployer is the admin if info.Admin != deployer { - return nil, sdkerrors.Wrapf(sdkerrors.ErrUnauthorized, "you are not an admin of this contract %s", deployer) + return nil, errorsmod.Wrapf(sdkerrors.ErrUnauthorized, "you are not an admin of this contract %s", deployer) } adminAddr, err := sdk.AccAddressFromBech32(info.Admin) if err != nil { - return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid admin address %s", info.Admin) + return nil, errorsmod.Wrapf(sdkerrors.ErrInvalidAddress, "invalid admin address %s", info.Admin) } controllingAccount = adminAddr } @@ -169,7 +169,7 @@ func (k Keeper) UpdateFeeShare( contract, err := sdk.AccAddressFromBech32(msg.ContractAddress) if err != nil { - return nil, sdkerrors.Wrapf( + return nil, errorsmod.Wrapf( sdkerrors.ErrInvalidAddress, "invalid contract address (%s)", err, ) @@ -177,7 +177,7 @@ func (k Keeper) UpdateFeeShare( feeshare, found := k.GetFeeShare(ctx, contract) if !found { - return nil, sdkerrors.Wrapf( + return nil, errorsmod.Wrapf( types.ErrFeeShareContractNotRegistered, "contract %s is not registered", msg.ContractAddress, ) @@ -185,7 +185,7 @@ func (k Keeper) UpdateFeeShare( // feeshare with the given withdraw address is already registered if msg.WithdrawerAddress == feeshare.WithdrawerAddress { - return nil, sdkerrors.Wrapf(types.ErrFeeShareAlreadyRegistered, "feeshare with withdraw address %s is already registered", msg.WithdrawerAddress) + return nil, errorsmod.Wrapf(types.ErrFeeShareAlreadyRegistered, "feeshare with withdraw address %s is already registered", msg.WithdrawerAddress) } // Check that the person who signed the message is the wasm contract admin, if so return the deployer address @@ -196,14 +196,14 @@ func (k Keeper) UpdateFeeShare( withdrawAddr, err := sdk.AccAddressFromBech32(feeshare.WithdrawerAddress) if err != nil { - return nil, sdkerrors.Wrapf( + return nil, errorsmod.Wrapf( sdkerrors.ErrInvalidAddress, "invalid withdrawer address (%s)", err, ) } newWithdrawAddr, err := sdk.AccAddressFromBech32(msg.WithdrawerAddress) if err != nil { - return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid WithdrawerAddress %s", msg.WithdrawerAddress) + return nil, errorsmod.Wrapf(sdkerrors.ErrInvalidAddress, "invalid WithdrawerAddress %s", msg.WithdrawerAddress) } k.DeleteWithdrawerMap(ctx, withdrawAddr, contract) @@ -241,12 +241,12 @@ func (k Keeper) CancelFeeShare( contract, err := sdk.AccAddressFromBech32(msg.ContractAddress) if err != nil { - return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid contract address (%s)", err) + return nil, errorsmod.Wrapf(sdkerrors.ErrInvalidAddress, "invalid contract address (%s)", err) } fee, found := k.GetFeeShare(ctx, contract) if !found { - return nil, sdkerrors.Wrapf(types.ErrFeeShareContractNotRegistered, "contract %s is not registered", msg.ContractAddress) + return nil, errorsmod.Wrapf(types.ErrFeeShareContractNotRegistered, "contract %s is not registered", msg.ContractAddress) } // Check that the person who signed the message is the wasm contract admin, if so return the deployer address diff --git a/x/feeshare/types/msg.go b/x/feeshare/types/msg.go index e7dd282b5..636065e89 100644 --- a/x/feeshare/types/msg.go +++ b/x/feeshare/types/msg.go @@ -3,7 +3,6 @@ package types import ( errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) var ( @@ -45,16 +44,16 @@ func (msg MsgRegisterFeeShare) Type() string { return TypeMsgRegisterFeeShare } // ValidateBasic runs stateless checks on the message func (msg MsgRegisterFeeShare) ValidateBasic() error { if _, err := sdk.AccAddressFromBech32(msg.DeployerAddress); err != nil { - return sdkerrors.Wrapf(err, "invalid deployer address %s", msg.DeployerAddress) + return errorsmod.Wrapf(err, "invalid deployer address %s", msg.DeployerAddress) } if _, err := sdk.AccAddressFromBech32(msg.ContractAddress); err != nil { - return sdkerrors.Wrapf(err, "invalid contract address %s", msg.ContractAddress) + return errorsmod.Wrapf(err, "invalid contract address %s", msg.ContractAddress) } if msg.WithdrawerAddress != "" { if _, err := sdk.AccAddressFromBech32(msg.WithdrawerAddress); err != nil { - return sdkerrors.Wrapf(err, "invalid withdraw address %s", msg.WithdrawerAddress) + return errorsmod.Wrapf(err, "invalid withdraw address %s", msg.WithdrawerAddress) } } @@ -92,11 +91,11 @@ func (msg MsgCancelFeeShare) Type() string { return TypeMsgCancelFeeShare } // ValidateBasic runs stateless checks on the message func (msg MsgCancelFeeShare) ValidateBasic() error { if _, err := sdk.AccAddressFromBech32(msg.DeployerAddress); err != nil { - return sdkerrors.Wrapf(err, "invalid deployer address %s", msg.DeployerAddress) + return errorsmod.Wrapf(err, "invalid deployer address %s", msg.DeployerAddress) } if _, err := sdk.AccAddressFromBech32(msg.ContractAddress); err != nil { - return sdkerrors.Wrapf(err, "invalid deployer address %s", msg.DeployerAddress) + return errorsmod.Wrapf(err, "invalid deployer address %s", msg.DeployerAddress) } return nil diff --git a/x/feeshare/types/query.go b/x/feeshare/types/query.go index e58cd133d..33c1b67c5 100644 --- a/x/feeshare/types/query.go +++ b/x/feeshare/types/query.go @@ -1,14 +1,14 @@ package types import ( + errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) // ValidateBasic runs stateless checks on the query requests func (q QueryFeeShareRequest) ValidateBasic() error { if _, err := sdk.AccAddressFromBech32(q.ContractAddress); err != nil { - return sdkerrors.Wrapf(err, "invalid contract address %s", q.ContractAddress) + return errorsmod.Wrapf(err, "invalid contract address %s", q.ContractAddress) } return nil @@ -17,7 +17,7 @@ func (q QueryFeeShareRequest) ValidateBasic() error { // ValidateBasic runs stateless checks on the query requests func (q QueryDeployerFeeSharesRequest) ValidateBasic() error { if _, err := sdk.AccAddressFromBech32(q.DeployerAddress); err != nil { - return sdkerrors.Wrapf(err, "invalid deployer address %s", q.DeployerAddress) + return errorsmod.Wrapf(err, "invalid deployer address %s", q.DeployerAddress) } return nil @@ -26,7 +26,7 @@ func (q QueryDeployerFeeSharesRequest) ValidateBasic() error { // ValidateBasic runs stateless checks on the query requests func (q QueryWithdrawerFeeSharesRequest) ValidateBasic() error { if _, err := sdk.AccAddressFromBech32(q.WithdrawerAddress); err != nil { - return sdkerrors.Wrapf(err, "invalid withdraw address %s", q.WithdrawerAddress) + return errorsmod.Wrapf(err, "invalid withdraw address %s", q.WithdrawerAddress) } return nil diff --git a/x/globalfee/ante/fee.go b/x/globalfee/ante/fee.go index b2fea43be..d11e91014 100644 --- a/x/globalfee/ante/fee.go +++ b/x/globalfee/ante/fee.go @@ -3,6 +3,7 @@ package ante import ( "errors" + errorsmod "cosmossdk.io/errors" tmstrings "github.com/cometbft/cometbft/libs/strings" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" @@ -54,7 +55,7 @@ func NewFeeDecorator(bypassMsgTypes []string, globalfeeSubspace, stakingSubspace func (mfd FeeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) { feeTx, ok := tx.(sdk.FeeTx) if !ok { - return ctx, sdkerrors.Wrap(sdkerrors.ErrTxDecode, "Tx must implement the sdk.FeeTx interface") + return ctx, errorsmod.Wrap(sdkerrors.ErrTxDecode, "Tx must implement the sdk.FeeTx interface") } // Only check for minimum fees and global fee if the execution mode is CheckTx @@ -80,7 +81,7 @@ func (mfd FeeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, ne // global fee is set to its default value, i.e. 0uatom, if empty combinedFeeRequirement := CombinedFeeRequirement(requiredGlobalFees, localFees) if len(combinedFeeRequirement) == 0 { - return ctx, sdkerrors.Wrapf(sdkerrors.ErrNotFound, "required fees are not setup.") + return ctx, errorsmod.Wrapf(sdkerrors.ErrNotFound, "required fees are not setup.") } nonZeroCoinFeesReq, zeroCoinFeesDenomReq := getNonZeroFees(combinedFeeRequirement) @@ -95,7 +96,7 @@ func (mfd FeeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, ne // if feeCoinsNoZeroDenom=[], DenomsSubsetOf returns true // if feeCoinsNoZeroDenom is not empty, but nonZeroCoinFeesReq empty, return false if !feeCoinsNonZeroDenom.DenomsSubsetOf(nonZeroCoinFeesReq) { - return ctx, sdkerrors.Wrapf(sdkerrors.ErrInsufficientFee, "fee is not a subset of required fees; got %s, required: %s", feeCoins, combinedFeeRequirement) + return ctx, errorsmod.Wrapf(sdkerrors.ErrInsufficientFee, "fee is not a subset of required fees; got %s, required: %s", feeCoins, combinedFeeRequirement) } // Accept zero fee transactions only if both of the following statements are true: @@ -132,7 +133,7 @@ func (mfd FeeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, ne // because when nonZeroCoinFeesReq empty, and DenomsSubsetOf check passed, // the tx should already passed before) if !feeCoinsNonZeroDenom.IsAnyGTE(nonZeroCoinFeesReq) { - return ctx, sdkerrors.Wrapf(sdkerrors.ErrInsufficientFee, "insufficient fees; got: %s required: %s", feeCoins, combinedFeeRequirement) + return ctx, errorsmod.Wrapf(sdkerrors.ErrInsufficientFee, "insufficient fees; got: %s required: %s", feeCoins, combinedFeeRequirement) } } diff --git a/x/globalfee/module.go b/x/globalfee/module.go index 18fb742a3..64c963fa8 100644 --- a/x/globalfee/module.go +++ b/x/globalfee/module.go @@ -4,12 +4,12 @@ import ( "context" "encoding/json" + errorsmod "cosmossdk.io/errors" abci "github.com/cometbft/cometbft/abci/types" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" codectypes "github.com/cosmos/cosmos-sdk/codec/types" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/types/module" paramstypes "github.com/cosmos/cosmos-sdk/x/params/types" "github.com/gorilla/mux" @@ -46,7 +46,7 @@ func (a AppModuleBasic) ValidateGenesis(marshaler codec.JSONCodec, _ client.TxEn return err } if err := data.Params.ValidateBasic(); err != nil { - return sdkerrors.Wrap(err, "params") + return errorsmod.Wrap(err, "params") } return nil } diff --git a/x/globalfee/types/genesis.go b/x/globalfee/types/genesis.go index a87d8d989..253df889c 100644 --- a/x/globalfee/types/genesis.go +++ b/x/globalfee/types/genesis.go @@ -3,8 +3,8 @@ package types import ( "encoding/json" + errorsmod "cosmossdk.io/errors" "github.com/cosmos/cosmos-sdk/codec" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) // NewGenesisState - Create a new genesis state @@ -33,7 +33,7 @@ func GetGenesisStateFromAppState(cdc codec.Codec, appState map[string]json.RawMe func ValidateGenesis(data GenesisState) error { if err := data.Params.ValidateBasic(); err != nil { - return sdkerrors.Wrap(err, "globalfee params") + return errorsmod.Wrap(err, "globalfee params") } return nil diff --git a/x/globalfee/types/params.go b/x/globalfee/types/params.go index 7161b2c3e..a223cdd1c 100644 --- a/x/globalfee/types/params.go +++ b/x/globalfee/types/params.go @@ -3,6 +3,7 @@ package types import ( "fmt" + errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" @@ -38,7 +39,7 @@ func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs { func validateMinimumGasPrices(i interface{}) error { v, ok := i.(sdk.DecCoins) if !ok { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidType, "type: %T, expected sdk.DecCoins", i) + return errorsmod.Wrapf(sdkerrors.ErrInvalidType, "type: %T, expected sdk.DecCoins", i) } dec := DecCoins(v) diff --git a/x/ibc-hooks/.cargo/config b/x/ibchooks/.cargo/config similarity index 100% rename from x/ibc-hooks/.cargo/config rename to x/ibchooks/.cargo/config diff --git a/x/ibc-hooks/README.md b/x/ibchooks/README.md similarity index 100% rename from x/ibc-hooks/README.md rename to x/ibchooks/README.md diff --git a/x/ibc-hooks/client/cli/query.go b/x/ibchooks/client/cli/query.go similarity index 94% rename from x/ibc-hooks/client/cli/query.go rename to x/ibchooks/client/cli/query.go index 6a0121537..9bbe53f30 100644 --- a/x/ibc-hooks/client/cli/query.go +++ b/x/ibchooks/client/cli/query.go @@ -4,13 +4,13 @@ import ( "fmt" "strings" - "github.com/CosmosContracts/juno/v15/x/ibc-hooks/keeper" + "github.com/CosmosContracts/juno/v15/x/ibchooks/keeper" "github.com/cosmos/cosmos-sdk/client/flags" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/version" "github.com/spf13/cobra" - "github.com/CosmosContracts/juno/v15/x/ibc-hooks/types" + "github.com/CosmosContracts/juno/v15/x/ibchooks/types" ) func indexRunCmd(cmd *cobra.Command, _ []string) error { diff --git a/x/ibc-hooks/hooks.go b/x/ibchooks/hooks.go similarity index 99% rename from x/ibc-hooks/hooks.go rename to x/ibchooks/hooks.go index 48e054b40..6058df0e3 100644 --- a/x/ibc-hooks/hooks.go +++ b/x/ibchooks/hooks.go @@ -1,4 +1,4 @@ -package ibc_hooks +package ibchooks import ( // external libraries diff --git a/x/ibc-hooks/ibc_module.go b/x/ibchooks/ibc_module.go similarity index 99% rename from x/ibc-hooks/ibc_module.go rename to x/ibchooks/ibc_module.go index fea66edbe..32a5911dd 100644 --- a/x/ibc-hooks/ibc_module.go +++ b/x/ibchooks/ibc_module.go @@ -1,4 +1,4 @@ -package ibc_hooks +package ibchooks import ( // external libraries diff --git a/x/ibc-hooks/ics4_middleware.go b/x/ibchooks/ics4_middleware.go similarity index 93% rename from x/ibc-hooks/ics4_middleware.go rename to x/ibchooks/ics4_middleware.go index 038ccd1d6..bb12b4de1 100644 --- a/x/ibc-hooks/ics4_middleware.go +++ b/x/ibchooks/ics4_middleware.go @@ -1,4 +1,4 @@ -package ibc_hooks +package ibchooks import ( // external libraries @@ -27,7 +27,7 @@ func NewICS4Middleware(channel porttypes.ICS4Wrapper, hooks Hooks) ICS4Middlewar } } -func (i ICS4Middleware) SendPacket(ctx sdk.Context, channelCap *capabilitytypes.Capability, sourcePort string, sourceChannel string, timeoutHeight clienttypes.Height, timeoutTimestamp uint64, data []byte) (sequence uint64, err error) { +func (i ICS4Middleware) SendPacket(ctx sdk.Context, channelCap *capabilitytypes.Capability, _ string, sourceChannel string, timeoutHeight clienttypes.Height, timeoutTimestamp uint64, data []byte) (sequence uint64, err error) { if hook, ok := i.Hooks.(SendPacketOverrideHooks); ok { return hook.SendPacketOverride(i, ctx, channelCap, sourceChannel, sourceChannel, timeoutHeight, timeoutTimestamp, data) } diff --git a/x/ibc-hooks/keeper/keeper.go b/x/ibchooks/keeper/keeper.go similarity index 97% rename from x/ibc-hooks/keeper/keeper.go rename to x/ibchooks/keeper/keeper.go index 9118f04cb..37afba275 100644 --- a/x/ibc-hooks/keeper/keeper.go +++ b/x/ibchooks/keeper/keeper.go @@ -7,7 +7,7 @@ import ( "github.com/cometbft/cometbft/libs/log" - "github.com/CosmosContracts/juno/v15/x/ibc-hooks/types" + "github.com/CosmosContracts/juno/v15/x/ibchooks/types" storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" diff --git a/x/ibc-hooks/sdkmodule.go b/x/ibchooks/sdkmodule.go similarity index 96% rename from x/ibc-hooks/sdkmodule.go rename to x/ibchooks/sdkmodule.go index 2d4959b08..22bb9ebc2 100644 --- a/x/ibc-hooks/sdkmodule.go +++ b/x/ibchooks/sdkmodule.go @@ -1,4 +1,4 @@ -package ibc_hooks +package ibchooks import ( "encoding/json" @@ -10,8 +10,8 @@ import ( "github.com/grpc-ecosystem/grpc-gateway/runtime" "github.com/spf13/cobra" - "github.com/CosmosContracts/juno/v15/x/ibc-hooks/client/cli" - "github.com/CosmosContracts/juno/v15/x/ibc-hooks/types" + "github.com/CosmosContracts/juno/v15/x/ibchooks/client/cli" + "github.com/CosmosContracts/juno/v15/x/ibchooks/types" cdctypes "github.com/cosmos/cosmos-sdk/codec/types" diff --git a/x/ibc-hooks/types/errors.go b/x/ibchooks/types/errors.go similarity index 100% rename from x/ibc-hooks/types/errors.go rename to x/ibchooks/types/errors.go diff --git a/x/ibc-hooks/types/keys.go b/x/ibchooks/types/keys.go similarity index 100% rename from x/ibc-hooks/types/keys.go rename to x/ibchooks/types/keys.go diff --git a/x/ibc-hooks/wasm_hook.go b/x/ibchooks/wasm_hook.go similarity index 96% rename from x/ibc-hooks/wasm_hook.go rename to x/ibchooks/wasm_hook.go index 1755a931b..cb0aeceb1 100644 --- a/x/ibc-hooks/wasm_hook.go +++ b/x/ibchooks/wasm_hook.go @@ -1,25 +1,25 @@ -package ibc_hooks +package ibchooks import ( "encoding/json" "fmt" wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" - "github.com/CosmosContracts/juno/v15/x/ibc-hooks/keeper" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/CosmosContracts/juno/v15/x/ibchooks/keeper" capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" "github.com/CosmosContracts/juno/v15/osmoutils" + errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" transfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" - "github.com/CosmosContracts/juno/v15/x/ibc-hooks/types" + "github.com/CosmosContracts/juno/v15/x/ibchooks/types" ) type ContractAck struct { @@ -279,7 +279,7 @@ func (h WasmHooks) SendPacketOverride(i ICS4Middleware, ctx sdk.Context, chanCap delete(metadata, types.IBCCallbackKey) bzMetadata, err := json.Marshal(metadata) if err != nil { - return sdkerrors.Wrap(err, "Send packet with callback error") + return errorsmod.Wrap(err, "Send packet with callback error") } stringMetadata := string(bzMetadata) if stringMetadata == "{}" { @@ -289,7 +289,7 @@ func (h WasmHooks) SendPacketOverride(i ICS4Middleware, ctx sdk.Context, chanCap } dataBytes, err := json.Marshal(data) if err != nil { - return sdkerrors.Wrap(err, "Send packet with callback error") + return errorsmod.Wrap(err, "Send packet with callback error") } packetWithoutCallbackMemo := channeltypes.Packet{ @@ -347,7 +347,7 @@ func (h WasmHooks) OnAcknowledgementPacketOverride(im IBCMiddleware, ctx sdk.Con contractAddr, err := sdk.AccAddressFromBech32(contract) if err != nil { - return sdkerrors.Wrap(err, "Ack callback error") // The callback configured is not a bech32. Error out + return errorsmod.Wrap(err, "Ack callback error") // The callback configured is not a bech32. Error out } success := "false" @@ -369,7 +369,7 @@ func (h WasmHooks) OnAcknowledgementPacketOverride(im IBCMiddleware, ctx sdk.Con if err != nil { // error processing the callback // ToDo: Open Question: Should we also delete the callback here? - return sdkerrors.Wrap(err, "Ack callback error") + return errorsmod.Wrap(err, "Ack callback error") } h.ibcHooksKeeper.DeletePacketCallback(ctx, packet.GetSourceChannel(), packet.GetSequence()) return nil @@ -394,7 +394,7 @@ func (h WasmHooks) OnTimeoutPacketOverride(im IBCMiddleware, ctx sdk.Context, pa contractAddr, err := sdk.AccAddressFromBech32(contract) if err != nil { - return sdkerrors.Wrap(err, "Timeout callback error") // The callback configured is not a bech32. Error out + return errorsmod.Wrap(err, "Timeout callback error") // The callback configured is not a bech32. Error out } sudoMsg := []byte(fmt.Sprintf( diff --git a/x/tokenfactory/bindings/message_plugin.go b/x/tokenfactory/bindings/message_plugin.go index 9e3c00a31..835035059 100644 --- a/x/tokenfactory/bindings/message_plugin.go +++ b/x/tokenfactory/bindings/message_plugin.go @@ -119,7 +119,7 @@ func PerformCreateDenom(f *tokenfactorykeeper.Keeper, b *bankkeeper.BaseKeeper, func (m *CustomMessenger) mintTokens(ctx sdk.Context, contractAddr sdk.AccAddress, mint *bindingstypes.MintTokens) ([]sdk.Event, [][]byte, error) { err := PerformMint(m.tokenFactory, m.bank, ctx, contractAddr, mint) if err != nil { - return nil, nil, sdkerrors.Wrap(err, "perform mint") + return nil, nil, errorsmod.Wrap(err, "perform mint") } return nil, nil, nil } @@ -145,16 +145,16 @@ func PerformMint(f *tokenfactorykeeper.Keeper, b *bankkeeper.BaseKeeper, ctx sdk msgServer := tokenfactorykeeper.NewMsgServerImpl(*f) _, err = msgServer.Mint(sdk.WrapSDKContext(ctx), sdkMsg) if err != nil { - return sdkerrors.Wrap(err, "minting coins from message") + return errorsmod.Wrap(err, "minting coins from message") } if b.BlockedAddr(rcpt) { - return sdkerrors.Wrapf(err, "minting coins to blocked address %s", rcpt.String()) + return errorsmod.Wrapf(err, "minting coins to blocked address %s", rcpt.String()) } err = b.SendCoins(ctx, contractAddr, rcpt, sdk.NewCoins(coin)) if err != nil { - return sdkerrors.Wrap(err, "sending newly minted coins from message") + return errorsmod.Wrap(err, "sending newly minted coins from message") } return nil } @@ -163,7 +163,7 @@ func PerformMint(f *tokenfactorykeeper.Keeper, b *bankkeeper.BaseKeeper, ctx sdk func (m *CustomMessenger) changeAdmin(ctx sdk.Context, contractAddr sdk.AccAddress, changeAdmin *bindingstypes.ChangeAdmin) ([]sdk.Event, [][]byte, error) { err := ChangeAdmin(m.tokenFactory, ctx, contractAddr, changeAdmin) if err != nil { - return nil, nil, sdkerrors.Wrap(err, "failed to change admin") + return nil, nil, errorsmod.Wrap(err, "failed to change admin") } return nil, nil, nil } @@ -186,7 +186,7 @@ func ChangeAdmin(f *tokenfactorykeeper.Keeper, ctx sdk.Context, contractAddr sdk msgServer := tokenfactorykeeper.NewMsgServerImpl(*f) _, err = msgServer.ChangeAdmin(sdk.WrapSDKContext(ctx), changeAdminMsg) if err != nil { - return sdkerrors.Wrap(err, "failed changing admin from message") + return errorsmod.Wrap(err, "failed changing admin from message") } return nil } @@ -195,7 +195,7 @@ func ChangeAdmin(f *tokenfactorykeeper.Keeper, ctx sdk.Context, contractAddr sdk func (m *CustomMessenger) burnTokens(ctx sdk.Context, contractAddr sdk.AccAddress, burn *bindingstypes.BurnTokens) ([]sdk.Event, [][]byte, error) { err := PerformBurn(m.tokenFactory, ctx, contractAddr, burn) if err != nil { - return nil, nil, sdkerrors.Wrap(err, "perform burn") + return nil, nil, errorsmod.Wrap(err, "perform burn") } return nil, nil, nil } @@ -220,7 +220,7 @@ func PerformBurn(f *tokenfactorykeeper.Keeper, ctx sdk.Context, contractAddr sdk msgServer := tokenfactorykeeper.NewMsgServerImpl(*f) _, err := msgServer.Burn(sdk.WrapSDKContext(ctx), sdkMsg) if err != nil { - return sdkerrors.Wrap(err, "burning coins from message") + return errorsmod.Wrap(err, "burning coins from message") } return nil } @@ -229,7 +229,7 @@ func PerformBurn(f *tokenfactorykeeper.Keeper, ctx sdk.Context, contractAddr sdk func (m *CustomMessenger) forceTransfer(ctx sdk.Context, contractAddr sdk.AccAddress, forcetransfer *bindingstypes.ForceTransfer) ([]sdk.Event, [][]byte, error) { err := PerformForceTransfer(m.tokenFactory, ctx, contractAddr, forcetransfer) if err != nil { - return nil, nil, sdkerrors.Wrap(err, "perform force transfer") + return nil, nil, errorsmod.Wrap(err, "perform force transfer") } return nil, nil, nil } @@ -261,7 +261,7 @@ func PerformForceTransfer(f *tokenfactorykeeper.Keeper, ctx sdk.Context, contrac msgServer := tokenfactorykeeper.NewMsgServerImpl(*f) _, err = msgServer.ForceTransfer(sdk.WrapSDKContext(ctx), sdkMsg) if err != nil { - return sdkerrors.Wrap(err, "force transferring from message") + return errorsmod.Wrap(err, "force transferring from message") } return nil } @@ -270,7 +270,7 @@ func PerformForceTransfer(f *tokenfactorykeeper.Keeper, ctx sdk.Context, contrac func (m *CustomMessenger) setMetadata(ctx sdk.Context, contractAddr sdk.AccAddress, setMetadata *bindingstypes.SetMetadata) ([]sdk.Event, [][]byte, error) { err := PerformSetMetadata(m.tokenFactory, m.bank, ctx, contractAddr, setMetadata.Denom, setMetadata.Metadata) if err != nil { - return nil, nil, sdkerrors.Wrap(err, "perform create denom") + return nil, nil, errorsmod.Wrap(err, "perform create denom") } return nil, nil, nil } @@ -313,7 +313,7 @@ func GetFullDenom(contract string, subDenom string) (string, error) { } fullDenom, err := tokenfactorytypes.GetTokenDenom(contract, subDenom) if err != nil { - return "", sdkerrors.Wrap(err, "validate sub-denom") + return "", errorsmod.Wrap(err, "validate sub-denom") } return fullDenom, nil @@ -323,11 +323,11 @@ func GetFullDenom(contract string, subDenom string) (string, error) { func parseAddress(addr string) (sdk.AccAddress, error) { parsed, err := sdk.AccAddressFromBech32(addr) if err != nil { - return nil, sdkerrors.Wrap(err, "address from bech32") + return nil, errorsmod.Wrap(err, "address from bech32") } err = sdk.VerifyAddressFormat(parsed) if err != nil { - return nil, sdkerrors.Wrap(err, "verify address format") + return nil, errorsmod.Wrap(err, "verify address format") } return parsed, nil } diff --git a/x/tokenfactory/bindings/query_plugin.go b/x/tokenfactory/bindings/query_plugin.go index 706fc07e9..aed114758 100644 --- a/x/tokenfactory/bindings/query_plugin.go +++ b/x/tokenfactory/bindings/query_plugin.go @@ -4,6 +4,7 @@ import ( "encoding/json" "fmt" + errorsmod "cosmossdk.io/errors" wasmvmtypes "github.com/CosmWasm/wasmvm/types" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" @@ -16,10 +17,10 @@ func CustomQuerier(qp *QueryPlugin) func(ctx sdk.Context, request json.RawMessag return func(ctx sdk.Context, request json.RawMessage) ([]byte, error) { var contractQuery bindingstypes.TokenFactoryQuery if err := json.Unmarshal(request, &contractQuery); err != nil { - return nil, sdkerrors.Wrap(err, "osmosis query") + return nil, errorsmod.Wrap(err, "osmosis query") } if contractQuery.Token == nil { - return nil, sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, "nil token field") + return nil, errorsmod.Wrap(sdkerrors.ErrUnknownRequest, "nil token field") } tokenQuery := contractQuery.Token @@ -30,7 +31,7 @@ func CustomQuerier(qp *QueryPlugin) func(ctx sdk.Context, request json.RawMessag fullDenom, err := GetFullDenom(creator, subdenom) if err != nil { - return nil, sdkerrors.Wrap(err, "osmo full denom query") + return nil, errorsmod.Wrap(err, "osmo full denom query") } res := bindingstypes.FullDenomResponse{ @@ -39,7 +40,7 @@ func CustomQuerier(qp *QueryPlugin) func(ctx sdk.Context, request json.RawMessag bz, err := json.Marshal(res) if err != nil { - return nil, sdkerrors.Wrap(err, "failed to marshal FullDenomResponse") + return nil, errorsmod.Wrap(err, "failed to marshal FullDenomResponse") } return bz, nil diff --git a/x/tokenfactory/types/genesis.go b/x/tokenfactory/types/genesis.go index b1ba181fa..aef9370cc 100644 --- a/x/tokenfactory/types/genesis.go +++ b/x/tokenfactory/types/genesis.go @@ -1,8 +1,8 @@ package types import ( + errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) // this line is used by starport scaffolding # genesis/types/import @@ -30,7 +30,7 @@ func (gs GenesisState) Validate() error { for _, denom := range gs.GetFactoryDenoms() { if seenDenoms[denom.GetDenom()] { - return sdkerrors.Wrapf(ErrInvalidGenesis, "duplicate denom: %s", denom.GetDenom()) + return errorsmod.Wrapf(ErrInvalidGenesis, "duplicate denom: %s", denom.GetDenom()) } seenDenoms[denom.GetDenom()] = true @@ -42,7 +42,7 @@ func (gs GenesisState) Validate() error { if denom.AuthorityMetadata.Admin != "" { _, err = sdk.AccAddressFromBech32(denom.AuthorityMetadata.Admin) if err != nil { - return sdkerrors.Wrapf(ErrInvalidAuthorityMetadata, "Invalid admin address (%s)", err) + return errorsmod.Wrapf(ErrInvalidAuthorityMetadata, "Invalid admin address (%s)", err) } } } From 0c0c7f0f37d264cfc9396dd305a5fc5e36955ea8 Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Mon, 1 May 2023 21:24:07 -0500 Subject: [PATCH 066/131] Cleanup old comments, Fix make TM_VERSION build flag --- Makefile | 4 ++-- app/app.go | 8 ++------ app/keepers/keys.go | 5 ----- app/upgrades/types.go | 10 ++++++---- app/upgrades/v10/upgrades.go | 5 +++-- app/upgrades/v11/upgrades.go | 5 +++-- cmd/junod/cmd/root.go | 5 +++-- 7 files changed, 19 insertions(+), 23 deletions(-) diff --git a/Makefile b/Makefile index 9ba3aee32..05485cd3d 100644 --- a/Makefile +++ b/Makefile @@ -17,7 +17,7 @@ endif PACKAGES_SIMTEST=$(shell go list ./... | grep '/simulation') LEDGER_ENABLED ?= true SDK_PACK := $(shell go list -m github.com/cosmos/cosmos-sdk | sed 's/ /\@/g') -TM_VERSION := $(shell go list -m github.com/tendermint/tendermint | sed 's:.* ::') # grab everything after the space in "github.com/tendermint/tendermint v0.34.7" +BFT_VERSION := $(shell go list -m github.com/cometbft/cometbft | sed 's:.* ::') # grab everything after the space in "github.com/tendermint/tendermint v0.34.7" DOCKER := $(shell which docker) DOCKER_BUF := $(DOCKER) run --rm -v $(CURDIR):/workspace --workdir /workspace bufbuild/buf:1.0.0-rc8 BUILDDIR ?= $(CURDIR)/build @@ -68,7 +68,7 @@ ldflags = -X github.com/cosmos/cosmos-sdk/version.Name=juno \ -X github.com/cosmos/cosmos-sdk/version.Version=$(VERSION) \ -X github.com/cosmos/cosmos-sdk/version.Commit=$(COMMIT) \ -X "github.com/cosmos/cosmos-sdk/version.BuildTags=$(build_tags_comma_sep)" \ - -X github.com/tendermint/tendermint/version.TMCoreSemVer=$(TM_VERSION) + -X github.com/cometbft/cometbft/version.TMCoreSemVer=$(BFT_VERSION) ifeq (cleveldb,$(findstring cleveldb,$(JUNO_BUILD_OPTIONS))) ldflags += -X github.com/cosmos/cosmos-sdk/types.DBBackend=cleveldb diff --git a/app/app.go b/app/app.go index 292c75e40..f51fed62d 100644 --- a/app/app.go +++ b/app/app.go @@ -168,17 +168,13 @@ func GetWasmOpts(appOpts servertypes.AppOptions) []wasm.Option { } func getGovProposalHandlers() []govclient.ProposalHandler { - var govProposalHandlers []govclient.ProposalHandler - - govProposalHandlers = append(govProposalHandlers, + return []govclient.ProposalHandler{ paramsclient.ProposalHandler, upgradeclient.LegacyProposalHandler, upgradeclient.LegacyCancelProposalHandler, ibcclientclient.UpdateClientProposalHandler, ibcclientclient.UpgradeProposalHandler, - ) - - return govProposalHandlers + } } var ( diff --git a/app/keepers/keys.go b/app/keepers/keys.go index 13440be4e..2a47e7008 100644 --- a/app/keepers/keys.go +++ b/app/keepers/keys.go @@ -33,11 +33,6 @@ import ( func (appKeepers *AppKeepers) GenerateKeys() { appKeepers.keys = sdk.NewKVStoreKeys( - // authtypes.StoreKey, banktypes.StoreKey, stakingtypes.StoreKey, - // minttypes.StoreKey, distrtypes.StoreKey, slashingtypes.StoreKey, - // govtypes.StoreKey, paramstypes.StoreKey, ibcexported.StoreKey, upgradetypes.StoreKey, - // evidencetypes.StoreKey, capabilitytypes.StoreKey, - // authzkeeper.StoreKey, feegrant.StoreKey, authtypes.StoreKey, banktypes.StoreKey, stakingtypes.StoreKey, crisistypes.StoreKey, minttypes.StoreKey, distrtypes.StoreKey, slashingtypes.StoreKey, govtypes.StoreKey, paramstypes.StoreKey, consensusparamtypes.StoreKey, upgradetypes.StoreKey, feegrant.StoreKey, diff --git a/app/upgrades/types.go b/app/upgrades/types.go index 5d725e435..04824060a 100644 --- a/app/upgrades/types.go +++ b/app/upgrades/types.go @@ -4,17 +4,19 @@ import ( "strings" "github.com/CosmosContracts/juno/v15/app/keepers" + tmproto "github.com/cometbft/cometbft/proto/tendermint/types" store "github.com/cosmos/cosmos-sdk/store/types" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" ) // BaseAppParamManager defines an interrace that BaseApp is expected to fullfil // that allows upgrade handlers to modify BaseApp parameters. -// type BaseAppParamManager interface { -// GetConsensusParams(ctx sdk.Context) *abci.ConsensusParams -// StoreConsensusParams(ctx sdk.Context, cp *abci.ConsensusParams) -// } +type BaseAppParamManager interface { + GetConsensusParams(ctx sdk.Context) *tmproto.ConsensusParams + StoreConsensusParams(ctx sdk.Context, cp *tmproto.ConsensusParams) +} // Upgrade defines a struct containing necessary fields that a SoftwareUpgradeProposal // must have written, in order for the state migration to go smoothly. diff --git a/app/upgrades/v10/upgrades.go b/app/upgrades/v10/upgrades.go index 5bcc1eb8a..c4bccc9c6 100644 --- a/app/upgrades/v10/upgrades.go +++ b/app/upgrades/v10/upgrades.go @@ -8,6 +8,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/authz" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" + govv1beta1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" icahosttypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/host/types" @@ -38,8 +39,8 @@ func CreateV10UpgradeHandler( sdk.MsgTypeURL(&distrtypes.MsgSetWithdrawAddress{}), sdk.MsgTypeURL(&distrtypes.MsgWithdrawValidatorCommission{}), sdk.MsgTypeURL(&distrtypes.MsgFundCommunityPool{}), - // sdk.MsgTypeURL(&govtypes.MsgVote{}), - // sdk.MsgTypeURL(&govtypes.MsgVoteWeighted{}), // required by quick + sdk.MsgTypeURL(&govv1beta1.MsgVote{}), + sdk.MsgTypeURL(&govv1beta1.MsgVoteWeighted{}), // required by quick sdk.MsgTypeURL(&authz.MsgExec{}), sdk.MsgTypeURL(&authz.MsgGrant{}), sdk.MsgTypeURL(&authz.MsgRevoke{}), diff --git a/app/upgrades/v11/upgrades.go b/app/upgrades/v11/upgrades.go index a7af76895..48482748f 100644 --- a/app/upgrades/v11/upgrades.go +++ b/app/upgrades/v11/upgrades.go @@ -8,6 +8,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/authz" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" + govv1beta1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" icahosttypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/host/types" @@ -39,8 +40,8 @@ func CreateV11UpgradeHandler( sdk.MsgTypeURL(&distrtypes.MsgSetWithdrawAddress{}), sdk.MsgTypeURL(&distrtypes.MsgWithdrawValidatorCommission{}), sdk.MsgTypeURL(&distrtypes.MsgFundCommunityPool{}), - // sdk.MsgTypeURL(&govtypes.MsgVote{}), - // sdk.MsgTypeURL(&govtypes.MsgVoteWeighted{}), // added in v10 + sdk.MsgTypeURL(&govv1beta1.MsgVote{}), + sdk.MsgTypeURL(&govv1beta1.MsgVoteWeighted{}), // added in v10 sdk.MsgTypeURL(&authz.MsgExec{}), sdk.MsgTypeURL(&authz.MsgGrant{}), sdk.MsgTypeURL(&authz.MsgRevoke{}), diff --git a/cmd/junod/cmd/root.go b/cmd/junod/cmd/root.go index 19d3adfc2..8acb171a2 100644 --- a/cmd/junod/cmd/root.go +++ b/cmd/junod/cmd/root.go @@ -109,7 +109,8 @@ func initTendermintConfig() *tmcfg.Config { // cfg.P2P.MaxNumInboundPeers = 100 // cfg.P2P.MaxNumOutboundPeers = 40 - cfg.Consensus.TimeoutCommit = 3 * time.Second + // 2 seconds + 1 second tendermint = 3 second blocks (v15 upgrade) + cfg.Consensus.TimeoutCommit = 2 * time.Second return cfg } @@ -126,7 +127,7 @@ func initAppConfig() (string, interface{}) { // Optionally allow the chain developer to overwrite the SDK's default // server config. srvCfg := serverconfig.DefaultConfig() - // srvCfg.MinGasPrices = "0.0025ujuno,0.0025ujunox" + // srvCfg.MinGasPrices = "0ujuno,0ujunox" // GlobalFee handles customAppConfig := CustomAppConfig{ Config: *srvCfg, From cc2988bf8252bbf122e04f71dd0e1a306443455e Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Fri, 5 May 2023 15:51:15 -0500 Subject: [PATCH 067/131] Allow gov contracts to be self registered --- app/keepers/keepers.go | 1 + x/feeshare/keeper/keeper.go | 7 +++++-- x/feeshare/keeper/msg_server.go | 11 ++++++++++- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/app/keepers/keepers.go b/app/keepers/keepers.go index 881357924..5021d1352 100644 --- a/app/keepers/keepers.go +++ b/app/keepers/keepers.go @@ -437,6 +437,7 @@ func NewAppKeepers( appKeepers.GetSubspace(feesharetypes.ModuleName), appKeepers.BankKeeper, appKeepers.WasmKeeper, + appKeepers.AccountKeeper, authtypes.FeeCollectorName, ) diff --git a/x/feeshare/keeper/keeper.go b/x/feeshare/keeper/keeper.go index 557af3995..71430c39e 100644 --- a/x/feeshare/keeper/keeper.go +++ b/x/feeshare/keeper/keeper.go @@ -21,8 +21,9 @@ type Keeper struct { cdc codec.BinaryCodec paramstore paramtypes.Subspace - bankKeeper revtypes.BankKeeper - wasmKeeper wasmkeeper.Keeper + bankKeeper revtypes.BankKeeper + wasmKeeper wasmkeeper.Keeper + accountKeeper revtypes.AccountKeeper feeCollectorName string } @@ -34,6 +35,7 @@ func NewKeeper( ps paramtypes.Subspace, bk revtypes.BankKeeper, wk wasmkeeper.Keeper, + ak revtypes.AccountKeeper, feeCollector string, ) Keeper { // set KeyTable if it has not already been set @@ -47,6 +49,7 @@ func NewKeeper( paramstore: ps, bankKeeper: bk, wasmKeeper: wk, + accountKeeper: ak, feeCollectorName: feeCollector, } } diff --git a/x/feeshare/keeper/msg_server.go b/x/feeshare/keeper/msg_server.go index 675cbebbd..3f0085c43 100644 --- a/x/feeshare/keeper/msg_server.go +++ b/x/feeshare/keeper/msg_server.go @@ -8,6 +8,7 @@ import ( wasmTypes "github.com/CosmWasm/wasmd/x/wasm/types" "github.com/CosmosContracts/juno/v15/x/feeshare/types" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" ) var _ types.MsgServer = &Keeper{} @@ -16,20 +17,28 @@ func (k Keeper) GetIfContractWasCreatedFromFactory(ctx sdk.Context, _ sdk.AccAdd // This will allow ANYONE to register FeeShare funds to its own contract if it was created from a factory contract // Note: if there is no admin but a creator made it, then the creator can register it how they wish + govAddress := k.accountKeeper.GetModuleAddress(govtypes.ModuleName).String() + creator, err := sdk.AccAddressFromBech32(info.Creator) if err != nil { return false } - isFactoryContract := false + // If the admin is the gov module (ex: some subDAOs, its a factory contract. Allow register to itself) + if info.Admin == govAddress { + return true + } + isFactoryContract := false if len(info.Admin) == 0 { + // if there is no admin & the creator is a contract, then its a factory contract isFactoryContract = k.wasmKeeper.HasContractInfo(ctx, creator) } else { admin, err := sdk.AccAddressFromBech32(info.Admin) if err != nil { return false } + // if there is an admin & the admin is a contract, then its a factory contract isFactoryContract = k.wasmKeeper.HasContractInfo(ctx, admin) } From 623074dc9400ebcab75b2eb5e98b9e55df554771 Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Wed, 10 May 2023 15:01:31 -0500 Subject: [PATCH 068/131] Squashed commit of the following: commit 641c8315742103182b3786104c4f1a7a821c74f1 Author: Reece Williams Date: Fri May 5 19:08:20 2023 -0500 Patch swagger gen bash file for new TF location (local repo) commit 3e70212229d18d587dfff6b79c3ac1a0ec203783 Author: Reece Williams Date: Fri May 5 18:28:40 2023 -0500 Add Tokenfactory Bindings test (contract) commit c4aadbe1cde3d6717dc63046bb95ceaa26220bc8 Author: Reece Williams Date: Fri May 5 18:28:17 2023 -0500 remove duplicaet go.mod replace commit e8af80c140dc2bfa8ebe9551411cb45f57c04a7d Author: Reece Williams Date: Fri May 5 16:18:08 2023 -0500 mod tidy ictest commit 354d9521585398fbde85bf30e4b4761cfe3c585f Author: Reece Williams Date: Fri May 5 16:11:15 2023 -0500 ictest: checkout before go install (use cache) commit 74c306c6221cd1dcbd560cbf433185d491cd2b28 Merge: 72f387a ae4319e Author: Reece Williams Date: Fri May 5 16:09:47 2023 -0500 Merge branch 'main' into reece/v15-tokenfactory commit 72f387a63c4b172a26374b173850b031efe2deb7 Author: Reece Williams Date: Fri May 5 16:03:40 2023 -0500 Squashed commit of the following: commit ae4319e99ae6af84e46c4803e97914d95acf41fc Merge: 9f115e0 1dd7111 Author: Jacob Gadikian Date: Sat May 6 03:20:25 2023 +0700 Merge pull request #634 from CosmosContracts/reece/v15-initial [v15] Upgrade, Faster Blocks, TF ConsumeGas commit 1dd7111dde3103d4e9e43817033a2de778bdaea8 Merge: b2d2b40 9f115e0 Author: Jacob Gadikian Date: Fri May 5 23:05:45 2023 +0700 Merge branch 'main' into reece/v15-initial commit b2d2b4030d883a486af5320225ed691be3b45136 Author: Reece Williams Date: Mon May 1 21:38:59 2023 -0500 Run ictest file on yml changes commit e057943e6efa5cf833aae5f577d1409e18cee6dd Author: Reece Williams Date: Mon May 1 21:37:04 2023 -0500 Speed up ICtest with parent go cache commit 19e774af3be61ea9ad335d42e416251d442a7776 Author: Reece Williams Date: Mon May 1 21:29:59 2023 -0500 gomod: minor version bumps commit a657696ec8b7502dc0dea8061af2f3ef77aa16a2 Merge: 99ec351 e3fed4d Author: Reece Williams <31943163+Reecepbcups@users.noreply.github.com> Date: Fri Apr 28 10:06:52 2023 -0500 Merge branch 'main' into reece/v15-initial commit 99ec3516161dce93ed784d40aca382c562896fc2 Author: Reece Williams Date: Mon Apr 24 19:28:11 2023 -0500 Cleanup v15 Upgrade handler commit fe1f6ad8d13be4c7ce4ca868dc32e55b1ed8efa3 Author: Reece Williams Date: Mon Apr 24 18:05:00 2023 -0500 timeoutCommit := 2 seconds commit 0f024c9c59f13a734e9874b82d3610a3aff71227 Author: Reece Williams Date: Mon Apr 24 17:42:53 2023 -0500 fix test to use defaults commit f52495c84b0c64099f508ef8a72dd87a82656aa6 Author: Reece Williams Date: Mon Apr 24 15:08:15 2023 -0500 Double slashing window to 20,000 blocks commit a400d8ca62918f46e6e455405c40e3d6798a4efe Author: Reece Williams Date: Sat Apr 22 12:13:16 2023 -0500 Be explicit with enabled TF Capabilities commit 1ace8d14672182b24fd11844824e1a92d501e6cc Merge: 86ca361 e57bc00 Author: Reece Williams Date: Sat Apr 22 08:11:28 2023 -0500 Merge branch 'main' into reece/v15-initial commit 86ca3614e8af6898c9cb55a3f1335a7aee96070e Author: Reece Williams Date: Sat Apr 22 08:10:33 2023 -0500 bump token-factory to better create_denom logic commit f8596ea98d36ec1cf0f37176946b16d7139a2930 Merge: c49e1e8 9885a8c Author: Jacob Gadikian Date: Wed Apr 12 02:19:24 2023 +0700 Merge branch 'main' into reece/v15-initial commit c49e1e8d86d4adb597df1818cba7ad66ebefd0c5 Merge: 286849a 7033eb5 Author: Jacob Gadikian Date: Mon Apr 10 22:30:46 2023 +0700 Merge pull request #635 from CosmosContracts/reece/v15-upgraded-tf [v15] TokenFactory DenomCreation: GasConsume commit 7033eb582b3b36f5e0d4d044249e594045a5d79b Merge: b27e762 286849a Author: Jacob Gadikian Date: Mon Apr 10 22:25:46 2023 +0700 Merge branch 'reece/v15-initial' into reece/v15-upgraded-tf commit 286849ae538958b858b1fa5eac421ec4f6ddfeec Merge: 9aa1bca 5d5160a Author: Jacob Gadikian Date: Mon Apr 10 22:20:53 2023 +0700 Merge pull request #637 from CosmosContracts/reece/v15-faster-block-times [v15] Forced Faster Block Times (3 seconds) commit 5d5160a2791580b3d7ebc35d2d9270baec0a321e Merge: d187c49 9aa1bca Author: Jacob Gadikian Date: Mon Apr 10 22:19:01 2023 +0700 Merge branch 'reece/v15-initial' into reece/v15-faster-block-times commit 9aa1bcaf31d62e00ca671c53fd421869369def5d Author: Reece Williams Date: Sun Apr 9 17:29:16 2023 -0500 Updates v15 ROADMAP commit b27e762f9420bec10cae98751dd89cc082505d89 Author: Reece Williams Date: Sat Apr 8 18:04:13 2023 -0500 Auto bumps swagger version based off go.mod (v15) commit 792661c20172e42b2dbd2b9589e2ce710d171ec5 Author: Reece Williams Date: Sat Apr 8 18:03:35 2023 -0500 Adds protoc swagger install instructions commit 9478c164388fac58b101cb8dcd0c7e507b381ea3 Author: Reece Williams Date: Sat Apr 8 17:45:47 2023 -0500 regen swagger commit 86db8546fd779546f2ea9bf5d8d0effb9cfe3a04 Author: Reece Williams Date: Sat Apr 8 13:03:16 2023 -0500 Switch back to osmosis proto schem for `osmosisstd` lib commit 0e5c437ea8e49a2e9f5194cc662096411b490b56 Merge: 9ddc12f 0b27af1 Author: Reece Williams <31943163+Reecepbcups@users.noreply.github.com> Date: Sat Apr 8 12:10:48 2023 -0500 Merge branch 'reece/v15-initial' into reece/v15-upgraded-tf commit d187c49d475b1bc1b26b7870651140ca4ff0428c Author: Reece Williams Date: Sat Apr 8 12:10:03 2023 -0500 remove testing commit 44f889dd30ecce4a7eb37c813ec5b24c802a5617 Author: Reece Williams Date: Sat Apr 8 12:07:29 2023 -0500 Ignore lint for pulled out SDK func errcheck commit a0c65846dcba91d8e8e8bfd32ddfe1121f9a87e2 Author: Reece Williams Date: Sat Apr 8 12:02:40 2023 -0500 Forces 3 second block timeout. `Not pretty but its honest work` commit 0b27af1d4fd464df21f91983ca45530f6edaba51 Author: Reece Williams Date: Sat Apr 8 11:49:35 2023 -0500 minor: fix test_node script commit 38ba7b5d19a8d180b1e78b3209946a4c49e55f43 Merge: 2a91d0f cd0e46c Author: Reece Williams Date: Sat Apr 8 09:13:11 2023 -0500 Merge branch 'main' into reece/v15-initial commit 9ddc12fa0598a8f83e7f1789d4950331fec0e1f6 Author: Reece Williams Date: Fri Apr 7 10:26:10 2023 -0500 Add tokenFactoryCapabilities (all enabled) commit 8a7f77c9d83b347d7d17edc764cd027650a436b7 Author: Reece Williams Date: Fri Apr 7 01:07:50 2023 -0500 set DenomCreationGasConsume param directly commit d3e3137b50ec1e30bc0724555a06a48c9e564614 Author: Reece Williams Date: Wed Apr 5 21:45:22 2023 -0500 mod tidy commit 932919de2d03bd66a9ebf6774ca3c0d9291a83aa Author: Reece Williams Date: Wed Apr 5 21:41:51 2023 -0500 Regen swagger commit 65d1ec8be0382b506aae24abb081dff7d866dfa7 Author: Reece Williams Date: Wed Apr 5 21:41:45 2023 -0500 Migrates to CosmosTokenFactory/token-factory commit 595249dfc459d4e2267e1baa47720acde68479cb Author: Reece Williams Date: Wed Apr 5 21:34:05 2023 -0500 Uses new shared repo for tokenfactory. Adds gas cost commit 2a91d0f9344b02296a5728a67df7da95d3dfe9a5 Author: Reece Williams Date: Wed Apr 5 21:01:27 2023 -0500 lint upgrades.go commit e51ca82c3dcaaa28f4969fa281ee1f4ab90b0c63 Author: Reece Williams Date: Wed Apr 5 21:00:41 2023 -0500 Modify chain test to ensure we 2x blocks per year commit ac3844671f51e0ac5b1c02a88bdf266f4f216bf8 Author: Reece Williams Date: Wed Apr 5 21:00:04 2023 -0500 v15 upgrade handler commit dd43d702836b01e14a6f799fb3a5d2b52f2168c0 Author: Reece Williams Date: Wed Apr 5 20:59:43 2023 -0500 bump vers commit 0b3ad3f15641baf3385786c18a5a8cd40e86ff21 Author: Reece Williams Date: Wed Apr 5 20:34:38 2023 -0500 bump to v15 commit b357073b9a3bc7d8ade67a543a8b10801f969737 Author: Reece Williams Date: Mon Apr 3 12:19:50 2023 -0500 Remove temp upgradeHandler for Uni commit 84a10e345a5a6494f68ccba9693eab7a009ad99e Author: Reece Williams Date: Fri Mar 31 20:46:06 2023 -0500 Move univ14part2 before v14, is it incorrectly applying in ictest? commit f6078afbc89e1fb63cfb28f6f768fe70dc81fdd8 Author: Reece Williams Date: Fri Mar 31 20:30:29 2023 -0500 Adds temp Uni-6 v14 part 2 upgrade handler (for safety) commit b7ac1a887f6092bb4475f252cbdd3b6787843142 Author: Reece Williams Date: Fri Mar 31 20:12:29 2023 -0500 Cancel ictest on new commit push commit 2ab8b830c22d8182fb2072525991b8f51a14ea57 Author: Reece Williams Date: Fri Mar 31 09:29:42 2023 -0500 bump gogoproto commit 86a1a8398591b4ee7a561fa5f6fd1c7baaae2d66 Author: Barry Plunkett Date: Fri Mar 31 10:26:49 2023 -0400 (chore): bump mev-tendermint version (#630) commit 1cf03bc3f7cd8d37663643a7fdcb743994fd1eee Author: Reece Williams Date: Thu Mar 30 16:06:11 2023 -0500 GlobalFee Bypass: MsgTimeout & MsgTimeoutOnClose commit dc98b613e63b0cbd1f1a02297201c6d596119ba9 Author: Reece Williams Date: Wed Mar 29 14:05:47 2023 -0500 Revert "Fix ibchooks to use its correct ModuleName. How did this get past CI until now??" This reverts commit 0820813b8905339cba86050fb05326b47d8b852d. commit 0820813b8905339cba86050fb05326b47d8b852d Author: Reece Williams Date: Wed Mar 29 13:31:44 2023 -0500 Fix ibchooks to use its correct ModuleName. How did this get past CI until now?? commit c2382d97bd1f61e29889a765698418baba5a9f54 Author: Reece Williams Date: Wed Mar 29 13:31:25 2023 -0500 remove old temp things commit 0b6f96c5c97dbd286c3707a1c2d1b7ac8d8898c0 Author: Nikhil Vasan <97126437+nivasan1@users.noreply.github.com> Date: Wed Mar 29 13:59:49 2023 -0400 include mev-cometbft instead of tendermint (#627) commit 618db4a8f6e3c75fe77970967b25ee9b3c083d2c Author: Reece Williams Date: Wed Mar 29 12:55:12 2023 -0500 Fix TestBasicJunoStart commit f403b58bb73e5cd98202a713a36fcadce55f0ca5 Author: Reece Williams Date: Wed Mar 29 12:34:04 2023 -0500 uni do empty upgrades commit 039b17c45df8755ad5ee1dc97092a628aeae990e Author: Reece Williams Date: Wed Mar 29 12:33:00 2023 -0500 lint && gofmt commit 434303e750fd36bb153d3ff4b6ad095613023bcf Author: Reece Williams Date: Wed Mar 29 11:40:10 2023 -0500 Adds a Uni-6 part2 upgrade handler commit 51ec752e594198f4fc1d5f5ef0328ec8cc5a01f2 Author: Reece Williams Date: Wed Mar 29 11:19:45 2023 -0500 Adds cosmwasm_1_2 wasmd feature commit 350a172f49ac9ee1ce0d55960a167f7c6e36a6d7 Merge: 0df4b1d 9f115e0 Author: Jacob Gadikian Date: Fri May 5 23:06:37 2023 +0700 Merge branch 'main' into reece/v15-tokenfactory commit 0df4b1d7754587613ba5d25673ddf01d1a3f90fa Author: Reece Williams Date: Thu May 4 16:09:42 2023 -0500 rename ictest e2e name commit fa06165989a0fe34552c3a9f1bce20fb7f24151f Author: Reece Williams Date: Thu May 4 16:06:29 2023 -0500 mod tidy commit 5835368af572f505ae88bf55a6a9109d9e134748 Author: Reece Williams Date: Thu May 4 16:03:02 2023 -0500 Add Tokenfactory e2e CI commit e711d40e08ebaaf6d34382d80d62309408201342 Author: Reece Williams Date: Thu May 4 11:03:43 2023 -0500 ictest: tokenfactory initial commit 8126994e90f9112dbe0a6400fa8b52f9fffe72f9 Author: Reece Williams Date: Thu May 4 09:50:30 2023 -0500 move CosmosTokenFactory into Juno x/ commit f335494753024035b91343e4358c74e4c1478b27 Author: Reece Williams Date: Thu May 4 09:24:59 2023 -0500 Squash Merged 'reece/v15-initial' branch --- .github/workflows/interchaintest-E2E.yml | 31 ++- Makefile | 12 +- app/params/weights.go | 14 ++ .../chain_start_test.go | 0 .../chain_upgrade_test.go | 0 .../ci_integration.go | 0 interchaintest/contracts/README.md | 5 + .../contracts/tokenfactory_core.wasm | Bin 0 -> 217058 bytes .../interchaintest => interchaintest}/go.mod | 25 ++- .../interchaintest => interchaintest}/go.sum | 40 +++- interchaintest/helpers/cosmwasm.go | 25 +++ interchaintest/helpers/query_helpers.go | 16 ++ interchaintest/helpers/tokenfactory.go | 148 ++++++++++++++ interchaintest/helpers/types.go | 36 ++++ .../ibc_transfer_test.go | 0 interchaintest/setup.go | 187 ++++++++++++++++++ interchaintest/tokenfactory_test.go | 85 ++++++++ .../v1beta1/authorityMetadata.proto | 2 +- .../tokenfactory/v1beta1/genesis.proto | 2 +- .../osmosis/tokenfactory/v1beta1/params.proto | 2 +- .../osmosis/tokenfactory/v1beta1/query.proto | 2 +- proto/osmosis/tokenfactory/v1beta1/tx.proto | 2 +- scripts/protoc_swagger_openapi_gen.sh | 6 +- tests/interchaintest/setup.go | 54 ----- x/feeshare/types/msg_test.go | 2 +- x/tokenfactory/simulation/params.go | 23 +++ 26 files changed, 634 insertions(+), 85 deletions(-) create mode 100644 app/params/weights.go rename {tests/interchaintest => interchaintest}/chain_start_test.go (100%) rename {tests/interchaintest => interchaintest}/chain_upgrade_test.go (100%) rename {tests/interchaintest => interchaintest}/ci_integration.go (100%) create mode 100644 interchaintest/contracts/README.md create mode 100644 interchaintest/contracts/tokenfactory_core.wasm rename {tests/interchaintest => interchaintest}/go.mod (91%) rename {tests/interchaintest => interchaintest}/go.sum (98%) create mode 100644 interchaintest/helpers/cosmwasm.go create mode 100644 interchaintest/helpers/query_helpers.go create mode 100644 interchaintest/helpers/tokenfactory.go create mode 100644 interchaintest/helpers/types.go rename {tests/interchaintest => interchaintest}/ibc_transfer_test.go (100%) create mode 100644 interchaintest/setup.go create mode 100644 interchaintest/tokenfactory_test.go delete mode 100644 tests/interchaintest/setup.go create mode 100644 x/tokenfactory/simulation/params.go diff --git a/.github/workflows/interchaintest-E2E.yml b/.github/workflows/interchaintest-E2E.yml index e1090636a..a3fdece5e 100644 --- a/.github/workflows/interchaintest-E2E.yml +++ b/.github/workflows/interchaintest-E2E.yml @@ -1,4 +1,4 @@ -name: Create Docker Image + E2E Tests +name: ictest E2E on: push: @@ -21,6 +21,7 @@ concurrency: cancel-in-progress: true + jobs: build-and-push-image: runs-on: ubuntu-latest @@ -73,19 +74,22 @@ jobs: cache-from: type=gha cache-to: type=gha,mode=max + # make juno:branchname here for all needs.build-and-push-image.outputs.branchTag + # then upload to github. Then download for each as a cache. This way its only built once + test-juno-basic: runs-on: ubuntu-latest needs: build-and-push-image steps: + - name: checkout chain + uses: actions/checkout@v2 + - name: Setup Golang with cache uses: magnetikonline/action-golang-cache@v4 with: go-version: ${{ env.GO_VERSION }} id: go - - name: checkout chain - uses: actions/checkout@v2 - - run: make ictest-basic env: BRANCH_CI: ${{needs.build-and-push-image.outputs.branchTag}} @@ -111,15 +115,32 @@ jobs: runs-on: ubuntu-latest needs: build-and-push-image steps: + - name: checkout chain + uses: actions/checkout@v2 + - name: Setup Golang with cache uses: magnetikonline/action-golang-cache@v4 with: go-version: ${{ env.GO_VERSION }} id: go + - run: make ictest-upgrade + env: + BRANCH_CI: ${{needs.build-and-push-image.outputs.branchTag}} + + test-juno-tokenfactory: + runs-on: ubuntu-latest + needs: build-and-push-image + steps: - name: checkout chain uses: actions/checkout@v2 - - run: make ictest-upgrade + - name: Setup Golang with cache + uses: magnetikonline/action-golang-cache@v4 + with: + go-version: ${{ env.GO_VERSION }} + id: go + + - run: make ictest-tokenfactory env: BRANCH_CI: ${{needs.build-and-push-image.outputs.branchTag}} diff --git a/Makefile b/Makefile index 05485cd3d..4a5e3f124 100644 --- a/Makefile +++ b/Makefile @@ -103,6 +103,9 @@ install: go.sum build: go build $(BUILD_FLAGS) -o bin/junod ./cmd/junod +test-node: + CHAIN_ID="local-1" HOME_DIR="~/.juno1" TIMEOUT_COMMIT="500ms" CLEAN=true sh scripts/test_node.sh + ############################################################################### ### Testing ### ############################################################################### @@ -120,18 +123,21 @@ benchmark: # Executes basic chain tests via interchaintest ictest-basic: - cd tests/interchaintest && go test -race -v -run TestBasicJunoStart . + cd interchaintest && go test -race -v -run TestBasicJunoStart . + +ictest-tokenfactory: + cd interchaintest && go test -race -v -run TestJunoTokenFactory . # Executes a basic chain upgrade test via interchaintest ictest-upgrade: - cd tests/interchaintest && go test -race -v -run TestBasicJunoUpgrade . + cd interchaintest && go test -race -v -run TestBasicJunoUpgrade . # Executes a basic chain upgrade locally via interchaintest after compiling a local image as juno:local ictest-upgrade-local: local-image ictest-upgrade # Executes IBC tests via interchaintest ictest-ibc: - cd tests/interchaintest && go test -race -v -run TestJunoGaiaIBCTransfer . + cd interchaintest && go test -race -v -run TestJunoGaiaIBCTransfer . # Executes all tests via interchaintest after compling a local image as juno:local ictest-all: local-image ictest-basic ictest-upgrade ictest-ibc diff --git a/app/params/weights.go b/app/params/weights.go new file mode 100644 index 000000000..c8f9337cc --- /dev/null +++ b/app/params/weights.go @@ -0,0 +1,14 @@ +package params + +// Simulation parameter constants +const ( + StakePerAccount = "stake_per_account" + InitiallyBondedValidators = "initially_bonded_validators" + + DefaultWeightMsgCreateDenom int = 100 + DefaultWeightMsgMint int = 100 + DefaultWeightMsgBurn int = 100 + DefaultWeightMsgChangeAdmin int = 100 + DefaultWeightMsgSetDenomMetadata int = 100 + DefaultWeightMsgForceTransfer int = 100 +) diff --git a/tests/interchaintest/chain_start_test.go b/interchaintest/chain_start_test.go similarity index 100% rename from tests/interchaintest/chain_start_test.go rename to interchaintest/chain_start_test.go diff --git a/tests/interchaintest/chain_upgrade_test.go b/interchaintest/chain_upgrade_test.go similarity index 100% rename from tests/interchaintest/chain_upgrade_test.go rename to interchaintest/chain_upgrade_test.go diff --git a/tests/interchaintest/ci_integration.go b/interchaintest/ci_integration.go similarity index 100% rename from tests/interchaintest/ci_integration.go rename to interchaintest/ci_integration.go diff --git a/interchaintest/contracts/README.md b/interchaintest/contracts/README.md new file mode 100644 index 000000000..c0b5ae3d9 --- /dev/null +++ b/interchaintest/contracts/README.md @@ -0,0 +1,5 @@ +# Contracts + +A list of the contracts here which are pre-compiled in other repos. + +> tokenfactory_core.wasm -> (PR 8). diff --git a/interchaintest/contracts/tokenfactory_core.wasm b/interchaintest/contracts/tokenfactory_core.wasm new file mode 100644 index 0000000000000000000000000000000000000000..b6994d28f986494e0ac3f649fd06d6c19807ad3b GIT binary patch literal 217058 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 R_V*}fUdkJvBHD+0ECtdS8tz&!d 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 literal 0 HcmV?d00001 diff --git a/tests/interchaintest/go.mod b/interchaintest/go.mod similarity index 91% rename from tests/interchaintest/go.mod rename to interchaintest/go.mod index 03584a9c0..dba971742 100644 --- a/tests/interchaintest/go.mod +++ b/interchaintest/go.mod @@ -2,6 +2,24 @@ module github.com/CosmosContracts/juno/tests/interchaintest go 1.19 +replace ( + github.com/ChainSafe/go-schnorrkel => github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d + github.com/ChainSafe/go-schnorrkel/1 => github.com/ChainSafe/go-schnorrkel v1.0.0 + + // For this nested module, you always want to replace the parent reference with the current worktree. + github.com/CosmosContracts/juno => ../ + github.com/btcsuite/btcd => github.com/btcsuite/btcd v0.22.2 //indirect + + // interchaintest supports ICS features so we need this for now + github.com/cosmos/cosmos-sdk => github.com/cosmos/cosmos-sdk v0.45.15-ics + github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 + + // github.com/tendermint/tendermint => github.com/informalsystems/tendermint v0.34.17 + github.com/tendermint/tendermint => github.com/skip-mev/mev-cometbft v0.34.27-mev.18 + + github.com/vedhavyas/go-subkey => github.com/strangelove-ventures/go-subkey v1.0.7 +) + require ( cosmossdk.io/simapp v0.0.0-20230224204036-a6adb0821462 github.com/cosmos/ibc-go/v7 v7.0.0 @@ -51,6 +69,7 @@ require ( github.com/cometbft/cometbft-db v0.7.0 // indirect github.com/confio/ics23/go v0.9.0 // indirect github.com/cosmos/btcutil v1.0.5 // indirect + github.com/cosmos/cosmos-db v0.0.0-20221226095112-f3c38ecb5e32 // indirect github.com/cosmos/cosmos-proto v1.0.0-beta.2 // indirect github.com/cosmos/cosmos-sdk v0.47.1 // indirect github.com/cosmos/go-bip39 v1.0.0 // indirect @@ -73,7 +92,6 @@ require ( github.com/dgraph-io/ristretto v0.1.1 // indirect github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect github.com/docker/distribution v2.8.1+incompatible // indirect - github.com/docker/docker v20.10.19+incompatible // indirect github.com/docker/go-connections v0.4.0 // indirect github.com/docker/go-units v0.5.0 // indirect github.com/dustin/go-humanize v1.0.1 // indirect @@ -81,6 +99,7 @@ require ( github.com/ethereum/go-ethereum v1.10.20 // indirect github.com/felixge/httpsnoop v1.0.2 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect + github.com/getsentry/sentry-go v0.17.0 // indirect github.com/go-kit/kit v0.12.0 // indirect github.com/go-kit/log v0.2.1 // indirect github.com/go-logfmt/logfmt v0.6.0 // indirect @@ -161,7 +180,7 @@ require ( github.com/pierrec/xxHash v0.1.5 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/prometheus/client_golang v1.14.0 // indirect + github.com/prometheus/client_golang v1.15.0 // indirect github.com/prometheus/client_model v0.3.0 // indirect github.com/prometheus/common v0.40.0 // indirect github.com/prometheus/procfs v0.9.0 // indirect @@ -232,7 +251,7 @@ require ( replace ( // interchaintest supports ICS features so we need this for now - // github.com/cosmos/cosmos-sdk => github.com/cosmos/cosmos-sdk v0.45.13-ics + github.com/cosmos/cosmos-sdk => github.com/cosmos/cosmos-sdk v0.45.15-ics github.com/ChainSafe/go-schnorrkel => github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d github.com/ChainSafe/go-schnorrkel/1 => github.com/ChainSafe/go-schnorrkel v1.0.0 // For this nested module, you always want to replace the parent reference with the current worktree. diff --git a/tests/interchaintest/go.sum b/interchaintest/go.sum similarity index 98% rename from tests/interchaintest/go.sum rename to interchaintest/go.sum index 6df600f95..64936d661 100644 --- a/tests/interchaintest/go.sum +++ b/interchaintest/go.sum @@ -337,6 +337,8 @@ github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7 github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cosmos/btcutil v1.0.5 h1:t+ZFcX77LpKtDBhjucvnOH8C2l2ioGsBNEQ3jef8xFk= github.com/cosmos/btcutil v1.0.5/go.mod h1:IyB7iuqZMJlthe2tkIFL33xPyzbFYP0XVdS8P5lUPis= +github.com/cosmos/cosmos-db v0.0.0-20221226095112-f3c38ecb5e32 h1:zlCp9n3uwQieELltZWHRmwPmPaZ8+XoL2Sj+A2YJlr8= +github.com/cosmos/cosmos-db v0.0.0-20221226095112-f3c38ecb5e32/go.mod h1:kwMlEC4wWvB48zAShGKVqboJL6w4zCLesaNQ3YLU2BQ= github.com/cosmos/cosmos-proto v1.0.0-beta.2 h1:X3OKvWgK9Gsejo0F1qs5l8Qn6xJV/AzgIWR2wZ8Nua8= github.com/cosmos/cosmos-proto v1.0.0-beta.2/go.mod h1:+XRCLJ14pr5HFEHIUcn51IKXD1Fy3rkEQqt4WqmN4V0= github.com/cosmos/cosmos-sdk v0.47.1 h1:HnaCYtaAMWZp1SdlwwE1mPJ8kFlZ/TuEJ/ciNXH6Uno= @@ -360,7 +362,6 @@ github.com/cosmos/ledger-cosmos-go v0.12.1/go.mod h1:dhO6kj+Y+AHIOgAe4L9HL/6NDdy github.com/cosmos/rosetta-sdk-go v0.10.0 h1:E5RhTruuoA7KTIXUcMicL76cffyeoyvNybzUGSKFTcM= github.com/cosmos/rosetta-sdk-go v0.10.0/go.mod h1:SImAZkb96YbwvoRkzSMQB6noNJXFgWl/ENIznEoYQI4= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= -github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creachadair/taskgroup v0.4.2 h1:jsBLdAJE42asreGss2xZGZ8fJra7WtwnHWeJFxv2Li8= github.com/creachadair/taskgroup v0.4.2/go.mod h1:qiXUOSrbwAY3u0JPGTzObbE3yf9hcXHDKBZ2ZjpCbgM= @@ -429,7 +430,8 @@ github.com/ethereum/go-ethereum v1.10.20/go.mod h1:LWUN82TCHGpxB3En5HVmLLzPD7YSr 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.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= +github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/felixge/httpsnoop v1.0.2 h1:+nS9g82KMXccJ/wp0zyRW9ZBHFETmMGtkk+2CTTrW4o= github.com/felixge/httpsnoop v1.0.2/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= @@ -552,6 +554,7 @@ github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8 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/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= 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.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= @@ -679,6 +682,7 @@ 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/icza/dyno v0.0.0-20220812133438-f0b6f8a18845 h1:H+uM0Bv88eur3ZSsd2NGKg3YIiuXxwxtlN7HjE66UTU= github.com/icza/dyno v0.0.0-20220812133438-f0b6f8a18845/go.mod h1:c1tRKs5Tx7E2+uHGSyyncziFjvGpgv4H2HrqXeUQ/Uk= +github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= 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= @@ -707,6 +711,9 @@ github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHm 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/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/juju/errors v0.0.0-20181118221551-089d3ea4e4d5/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q= +github.com/juju/loggo v0.0.0-20180524022052-584905176618/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U= +github.com/juju/testing v0.0.0-20180920084828-472a3e8b2073/go.mod h1:63prj8cnj0tU0S9OHjGJn+b1h0ZghCndfnbQolrYTwA= 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/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= @@ -724,11 +731,11 @@ github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa02 github.com/klauspost/cpuid/v2 v2.2.3 h1:sxCkb+qR91z4vsqw4vGGZlDgPz3G7gjaLyK3V8y70BU= github.com/klauspost/cpuid/v2 v2.2.3/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= 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.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= 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= @@ -933,12 +940,13 @@ github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qq 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/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/rs/cors v1.8.3 h1:O+qNyWn7Z+F9M0ILBHgMVPuB1xTOucVd5gtaYyXBpRo= github.com/rs/cors v1.8.3/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= -github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= 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= @@ -953,6 +961,8 @@ github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrf github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/skip-mev/mev-cometbft v0.34.27-mev.18 h1:xoZRzzW4u4Rr4jjXUz7y05AoDZu8W5dGvgeg7jxrt0U= +github.com/skip-mev/mev-cometbft v0.34.27-mev.18/go.mod h1:BcCbhKv7ieM0KEddnYXvQZR+pZykTKReJJYf7YC7qhw= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= @@ -968,10 +978,11 @@ github.com/spf13/afero v1.9.3/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcD 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= -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.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= +github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= +github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= 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= @@ -1035,6 +1046,10 @@ github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijb github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= +github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= +github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= +github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc= 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= @@ -1087,10 +1102,12 @@ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 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-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/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.8.0 h1:pd9TJtTueMTVQXzk8E2XESSMQDj/U7OUu0PqJqPXQjQ= golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= @@ -1121,6 +1138,7 @@ golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPI 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/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/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= @@ -1146,6 +1164,7 @@ golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -1183,7 +1202,7 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= 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= @@ -1284,8 +1303,6 @@ golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -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-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1363,11 +1380,13 @@ golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.1.0 h1:xYY+Bajn2a7VBmTM5GikTmnK8ZuX8YgnQCqZpbBNtmA= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/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-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/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= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190327201419-c70d86f8b7cf/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= @@ -1493,6 +1512,7 @@ google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCID 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-20180518175338-11a468237815/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= 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= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= @@ -1669,6 +1689,7 @@ gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLks 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-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 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/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= @@ -1678,6 +1699,7 @@ gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMy gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce h1:+JknDZhAj8YMt7GC73Ei8pv4MzjDUNPHgQWJdtMAaDU= gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= @@ -1690,10 +1712,10 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20191120175047-4206685974f2/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= diff --git a/interchaintest/helpers/cosmwasm.go b/interchaintest/helpers/cosmwasm.go new file mode 100644 index 000000000..2fccee37e --- /dev/null +++ b/interchaintest/helpers/cosmwasm.go @@ -0,0 +1,25 @@ +package helpers + +import ( + "context" + "testing" + + "github.com/strangelove-ventures/interchaintest/v4/chain/cosmos" +) + +func SetupContract(t *testing.T, ctx context.Context, chain *cosmos.CosmosChain, keyname string, fileLoc string, message string) (codeId, contract string) { + codeId, err := chain.StoreContract(ctx, keyname, fileLoc) + if err != nil { + t.Fatal(err) + } + // require.Equal(t, "1", codeId) + + contractAddr, err := chain.InstantiateContract(ctx, keyname, codeId, message, true) + if err != nil { + t.Fatal(err) + } + // t.Log(contractAddr) + + return codeId, contractAddr +} + diff --git a/interchaintest/helpers/query_helpers.go b/interchaintest/helpers/query_helpers.go new file mode 100644 index 000000000..913eda5e7 --- /dev/null +++ b/interchaintest/helpers/query_helpers.go @@ -0,0 +1,16 @@ +package helpers + +import ( + "context" + "testing" + + "github.com/strangelove-ventures/interchaintest/v4/chain/cosmos" + "github.com/stretchr/testify/require" +) + +func GetUserTokenFactoryBalances(t *testing.T, ctx context.Context, chain *cosmos.CosmosChain, contract string, uaddr string) GetAllBalancesResponse { + var res GetAllBalancesResponse + err := chain.QueryContract(ctx, contract, QueryMsg{GetAllBalances: &GetAllBalancesQuery{Address: uaddr}}, &res) + require.NoError(t, err) + return res +} diff --git a/interchaintest/helpers/tokenfactory.go b/interchaintest/helpers/tokenfactory.go new file mode 100644 index 000000000..94d6cc864 --- /dev/null +++ b/interchaintest/helpers/tokenfactory.go @@ -0,0 +1,148 @@ +package helpers + +import ( + "context" + "encoding/json" + "strconv" + "testing" + + tokenfactorytypes "github.com/CosmosContracts/juno/v15/x/tokenfactory/types" + "github.com/cosmos/cosmos-sdk/crypto/keyring" + "github.com/strangelove-ventures/interchaintest/v4/chain/cosmos" + "github.com/strangelove-ventures/interchaintest/v4/ibc" + "github.com/strangelove-ventures/interchaintest/v4/testutil" + "github.com/stretchr/testify/require" +) + +const CHAIN_PREFIX = "juno" + +func debugOutput(t *testing.T, stdout string) { + if true { + t.Log(stdout) + } +} + +func CreateTokenFactoryDenom(t *testing.T, ctx context.Context, chain *cosmos.CosmosChain, user *ibc.Wallet, subDenomName string) (fullDenom string) { + // TF gas to create cost 2mil, so we set to 2.5 to be safe + cmd := []string{"junod", "tx", "tokenfactory", "create-denom", subDenomName, + "--node", chain.GetRPCAddress(), + "--home", chain.HomeDir(), + "--chain-id", chain.Config().ChainID, + "--from", user.KeyName, + "--gas", "2500000", + "--gas-adjustment", "2.0", + "--keyring-dir", chain.HomeDir(), + "--keyring-backend", keyring.BackendTest, + "-y", + } + stdout, _, err := chain.Exec(ctx, cmd, nil) + require.NoError(t, err) + + debugOutput(t, string(stdout)) + + err = testutil.WaitForBlocks(ctx, 2, chain) + require.NoError(t, err) + + return "factory/" + user.Bech32Address(chain.Config().Bech32Prefix) + "/" + subDenomName +} + +func MintTokenFactoryDenom(t *testing.T, ctx context.Context, chain *cosmos.CosmosChain, admin *ibc.Wallet, amount uint64, fullDenom string) { + denom := strconv.FormatUint(amount, 10) + fullDenom + + // mint new tokens to the account + cmd := []string{"junod", "tx", "tokenfactory", "mint", denom, + "--node", chain.GetRPCAddress(), + "--home", chain.HomeDir(), + "--chain-id", chain.Config().ChainID, + "--from", admin.KeyName, + "--keyring-dir", chain.HomeDir(), + "--keyring-backend", keyring.BackendTest, + "-y", + } + stdout, _, err := chain.Exec(ctx, cmd, nil) + require.NoError(t, err) + + debugOutput(t, string(stdout)) + + err = testutil.WaitForBlocks(ctx, 2, chain) + require.NoError(t, err) +} + +func MintToTokenFactoryDenom(t *testing.T, ctx context.Context, chain *cosmos.CosmosChain, admin *ibc.Wallet, toWallet *ibc.Wallet, amount uint64, fullDenom string) { + denom := strconv.FormatUint(amount, 10) + fullDenom + + receiver := toWallet.Bech32Address(chain.Config().Bech32Prefix) + + t.Log("minting", denom, "to", receiver) + + // mint new tokens to the account + cmd := []string{"junod", "tx", "tokenfactory", "mint-to", receiver, denom, + "--node", chain.GetRPCAddress(), + "--home", chain.HomeDir(), + "--chain-id", chain.Config().ChainID, + "--from", admin.KeyName, + "--keyring-dir", chain.HomeDir(), + "--keyring-backend", keyring.BackendTest, + "-y", + } + stdout, _, err := chain.Exec(ctx, cmd, nil) + require.NoError(t, err) + + debugOutput(t, string(stdout)) + + err = testutil.WaitForBlocks(ctx, 2, chain) + require.NoError(t, err) +} + +func TransferTokenFactoryAdmin(t *testing.T, ctx context.Context, chain *cosmos.CosmosChain, currentAdmin *ibc.Wallet, newAdminBech32 string, fullDenom string) { + cmd := []string{"junod", "tx", "tokenfactory", "change-admin", fullDenom, newAdminBech32, + "--node", chain.GetRPCAddress(), + "--home", chain.HomeDir(), + "--chain-id", chain.Config().ChainID, + "--from", currentAdmin.KeyName, + "--keyring-dir", chain.HomeDir(), + "--keyring-backend", keyring.BackendTest, + "-y", + } + stdout, _, err := chain.Exec(ctx, cmd, nil) + require.NoError(t, err) + + debugOutput(t, string(stdout)) + + err = testutil.WaitForBlocks(ctx, 2, chain) + require.NoError(t, err) +} + +// TODO: +// Getters +func GetTokenFactoryAdmin(t *testing.T, ctx context.Context, chain *cosmos.CosmosChain, fullDenom string) string { + // $BINARY q tokenfactory denom-authority-metadata $FULL_DENOM + + // tokenfactorytypes.QueryDenomAuthorityMetadataRequest{ + // Denom: fullDenom, + // } + cmd := []string{"junod", "query", "tokenfactory", "denom-authority-metadata", fullDenom, + "--node", chain.GetRPCAddress(), + "--chain-id", chain.Config().ChainID, + "--output", "json", + } + stdout, _, err := chain.Exec(ctx, cmd, nil) + require.NoError(t, err) + + debugOutput(t, string(stdout)) + + // results := &tokenfactorytypes.DenomAuthorityMetadata{} + results := &tokenfactorytypes.QueryDenomAuthorityMetadataResponse{} + err = json.Unmarshal(stdout, results) + require.NoError(t, err) + + t.Log(results) + + err = testutil.WaitForBlocks(ctx, 2, chain) + require.NoError(t, err) + + // tokenfactorytypes.DenomAuthorityMetadata{ + // Admin: ..., + // } + return results.AuthorityMetadata.Admin +} diff --git a/interchaintest/helpers/types.go b/interchaintest/helpers/types.go new file mode 100644 index 000000000..3a002c4d4 --- /dev/null +++ b/interchaintest/helpers/types.go @@ -0,0 +1,36 @@ +package helpers + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// Go based data types for querying on the contract. + +// TODO: Auto generate in the future from Rust types -> Go types? +// Execute types are not needed here. We just use strings. Could add though in the future and to_string it + +// EntryPoint +type QueryMsg struct { + GetConfig *struct{} `json:"get_config,omitempty"` + + GetBalance *GetBalanceQuery `json:"get_balance,omitempty"` + GetAllBalances *GetAllBalancesQuery `json:"get_all_balances,omitempty"` +} + +type GetAllBalancesQuery struct { + Address string `json:"address"` +} +type GetAllBalancesResponse struct { + // or is it wasm Coin type? + Data []sdk.Coin `json:"data"` +} + +// {"get_balance":{"address":"juno1...","denom":"factory/juno1.../RcqfWz"}} +type GetBalanceQuery struct { + Address string `json:"address"` + Denom string `json:"denom"` +} +type GetBalanceResponse struct { + // or is it wasm Coin type? + Data sdk.Coin `json:"data"` +} diff --git a/tests/interchaintest/ibc_transfer_test.go b/interchaintest/ibc_transfer_test.go similarity index 100% rename from tests/interchaintest/ibc_transfer_test.go rename to interchaintest/ibc_transfer_test.go diff --git a/interchaintest/setup.go b/interchaintest/setup.go new file mode 100644 index 000000000..5947bf5f6 --- /dev/null +++ b/interchaintest/setup.go @@ -0,0 +1,187 @@ +package interchaintest + +import ( + "context" + "encoding/json" + "fmt" + "testing" + + wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" + feesharetypes "github.com/CosmosContracts/juno/v15/x/feeshare/types" + tokenfactorytypes "github.com/CosmosContracts/juno/v15/x/tokenfactory/types" // TODO: fix this so we can store in the DB. + + simappparams "github.com/cosmos/cosmos-sdk/simapp/params" + "github.com/docker/docker/client" + "github.com/icza/dyno" + + interchaintest "github.com/strangelove-ventures/interchaintest/v4" + "github.com/strangelove-ventures/interchaintest/v4/chain/cosmos" + "github.com/strangelove-ventures/interchaintest/v4/ibc" + "github.com/strangelove-ventures/interchaintest/v4/testreporter" + + "github.com/stretchr/testify/require" + "go.uber.org/zap/zaptest" +) + +var ( + JunoE2ERepo = "ghcr.io/cosmoscontracts/juno-e2e" + JunoMainRepo = "ghcr.io/cosmoscontracts/juno" + + junoRepo, junoVersion = GetDockerImageInfo() + + JunoImage = ibc.DockerImage{ + Repository: junoRepo, + Version: junoVersion, + UidGid: "1025:1025", + } + + junoConfig = ibc.ChainConfig{ + Type: "cosmos", + Name: "juno", + ChainID: "juno-2", + Images: []ibc.DockerImage{JunoImage}, + Bin: "junod", + Bech32Prefix: "juno", + Denom: "ujuno", + CoinType: "118", + GasPrices: "0ujuno", + GasAdjustment: 1.8, + TrustingPeriod: "112h", + NoHostMount: false, + SkipGenTx: false, + PreGenesis: nil, + ModifyGenesis: nil, + ConfigFileOverrides: nil, + EncodingConfig: junoEncoding(), + } + + pathJunoGaia = "juno-gaia" + genesisWalletAmount = int64(10_000_000) +) + +// junoEncoding registers the Juno specific module codecs so that the associated types and msgs +// will be supported when writing to the blocksdb sqlite database. +func junoEncoding() *simappparams.EncodingConfig { + cfg := cosmos.DefaultEncoding() + + // register custom types + wasmtypes.RegisterInterfaces(cfg.InterfaceRegistry) + feesharetypes.RegisterInterfaces(cfg.InterfaceRegistry) + tokenfactorytypes.RegisterInterfaces(cfg.InterfaceRegistry) + + return &cfg +} + +// Basic chain setup for a Juno chain. No relaying +func CreateBaseChain(t *testing.T) []ibc.Chain { + // Create chain factory with Juno + numVals := 1 + numFullNodes := 0 + + cf := interchaintest.NewBuiltinChainFactory(zaptest.NewLogger(t), []*interchaintest.ChainSpec{ + { + Name: "juno", + Version: "latest", + ChainName: "juno1", + ChainConfig: ibc.ChainConfig{ + GasPrices: "0ujuno", + GasAdjustment: 2.0, + EncodingConfig: junoEncoding(), + }, + NumValidators: &numVals, + NumFullNodes: &numFullNodes, + }, + }) + + // Get chains from the chain factory + chains, err := cf.Chains(t.Name()) + require.NoError(t, err) + + // juno := chains[0].(*cosmos.CosmosChain) + return chains +} + +func CreateThisBranchChain(t *testing.T) []ibc.Chain { + // Create chain factory with Juno + numVals := 1 + numFullNodes := 0 + + cf := interchaintest.NewBuiltinChainFactory(zaptest.NewLogger(t), []*interchaintest.ChainSpec{ + { + Name: "juno", + ChainName: "juno", + Version: junoVersion, + ChainConfig: ibc.ChainConfig{ + // ModifyGenesis: cosmos.ModifyGenesisProposalTime(votingPeriod, maxDepositPeriod), + Images: []ibc.DockerImage{ + { + Repository: junoRepo, + Version: junoVersion, + UidGid: JunoImage.UidGid, + }, + }, + GasPrices: "0ujuno", + Denom: "ujuno", + }, + NumValidators: &numVals, + NumFullNodes: &numFullNodes, + }, + }) + + // Get chains from the chain factory + chains, err := cf.Chains(t.Name()) + require.NoError(t, err) + + // juno := chains[0].(*cosmos.CosmosChain) + return chains +} + +func BuildInitialChain(t *testing.T, chains []ibc.Chain) (*interchaintest.Interchain, context.Context, *client.Client, string) { + // Create a new Interchain object which describes the chains, relayers, and IBC connections we want to use + ic := interchaintest.NewInterchain() + + for _, chain := range chains { + ic.AddChain(chain) + } + + rep := testreporter.NewNopReporter() + eRep := rep.RelayerExecReporter(t) + + ctx := context.Background() + client, network := interchaintest.DockerSetup(t) + + err := ic.Build(ctx, eRep, interchaintest.InterchainBuildOptions{ + TestName: t.Name(), + Client: client, + NetworkID: network, + SkipPathCreation: true, + // This can be used to write to the block database which will index all block data e.g. txs, msgs, events, etc. + // BlockDatabaseFile: interchaintest.DefaultBlockDatabaseFilepath(), + }) + require.NoError(t, err) + + return ic, ctx, client, network +} + +func ModifyGenesisProposalTime(votingPeriod string, maxDepositPeriod string) func(ibc.ChainConfig, []byte) ([]byte, error) { + return func(chainConfig ibc.ChainConfig, genbz []byte) ([]byte, error) { + g := make(map[string]interface{}) + if err := json.Unmarshal(genbz, &g); err != nil { + return nil, fmt.Errorf("failed to unmarshal genesis file: %w", err) + } + if err := dyno.Set(g, votingPeriod, "app_state", "gov", "voting_params", "voting_period"); err != nil { + return nil, fmt.Errorf("failed to set voting period in genesis json: %w", err) + } + if err := dyno.Set(g, maxDepositPeriod, "app_state", "gov", "deposit_params", "max_deposit_period"); err != nil { + return nil, fmt.Errorf("failed to set voting period in genesis json: %w", err) + } + if err := dyno.Set(g, chainConfig.Denom, "app_state", "gov", "deposit_params", "min_deposit", 0, "denom"); err != nil { + return nil, fmt.Errorf("failed to set voting period in genesis json: %w", err) + } + out, err := json.Marshal(g) + if err != nil { + return nil, fmt.Errorf("failed to marshal genesis bytes to json: %w", err) + } + return out, nil + } +} diff --git a/interchaintest/tokenfactory_test.go b/interchaintest/tokenfactory_test.go new file mode 100644 index 000000000..7b8c5fa3b --- /dev/null +++ b/interchaintest/tokenfactory_test.go @@ -0,0 +1,85 @@ +package interchaintest + +import ( + "fmt" + "testing" + + "github.com/strangelove-ventures/interchaintest/v4" + "github.com/strangelove-ventures/interchaintest/v4/chain/cosmos" + + helpers "github.com/CosmosContracts/juno/tests/interchaintest/helpers" +) + +// TestJunoTokenFactory ensures the tokenfactory module & bindings work properly. +func TestJunoTokenFactory(t *testing.T) { + t.Parallel() + + // Base setup + chains := CreateThisBranchChain(t) + ic, ctx, _, _ := BuildInitialChain(t, chains) + + // get + juno := chains[0].(*cosmos.CosmosChain) + t.Log("juno.GetHostRPCAddress()", juno.GetHostRPCAddress()) + + users := interchaintest.GetAndFundTestUsers(t, ctx, "default", int64(10_000_000), juno, juno) + user := users[0] + uaddr := user.Bech32Address(juno.Config().Bech32Prefix) + + user2 := users[1] + uaddr2 := user2.Bech32Address(juno.Config().Bech32Prefix) + + tfDenom := helpers.CreateTokenFactoryDenom(t, ctx, juno, user, "ictestdenom") + t.Log("tfDenom", tfDenom) + + // mint + helpers.MintTokenFactoryDenom(t, ctx, juno, user, 100, tfDenom) + t.Log("minted tfDenom to user") + if balance, err := juno.GetBalance(ctx, uaddr, tfDenom); err != nil { + t.Fatal(err) + } else if balance != 100 { + t.Fatal("balance not 100") + } + + // mint-to + helpers.MintToTokenFactoryDenom(t, ctx, juno, user, user2, 70, tfDenom) + t.Log("minted tfDenom to user") + if balance, err := juno.GetBalance(ctx, uaddr2, tfDenom); err != nil { + t.Fatal(err) + } else if balance != 70 { + t.Fatal("balance not 70") + } + + // TODO: Use same contract for a feeshare test with changing params + // This allows the uaddr here to mint tokens on behalf of the contract. Typically you only allow a contract here, but this is testing. + coreInitMsg := fmt.Sprintf(`{"allowed_mint_addresses":["%s"],"denoms":["%s"]}`, uaddr, tfDenom) + _, coreTFContract := helpers.SetupContract(t, ctx, juno, user.KeyName, "contracts/tokenfactory_core.wasm", coreInitMsg) + t.Log("coreContract", coreTFContract) + + // change admin to the contract + helpers.TransferTokenFactoryAdmin(t, ctx, juno, user, coreTFContract, tfDenom) + + // ensure the admin is the contract + admin := helpers.GetTokenFactoryAdmin(t, ctx, juno, tfDenom) + t.Log("admin", admin) + if admin != coreTFContract { + t.Fatal("admin not coreTFContract. Did not properly transfer.") + } + + // Mint on the contract for the user to ensure mint bindings work. + mintMsg := fmt.Sprintf(`{"mint":{"address":"%s","denom":[{"denom":"%s","amount":"31"}]}}`, uaddr2, tfDenom) + if _, err := juno.ExecuteContract(ctx, user.KeyName, coreTFContract, mintMsg); err != nil { + t.Fatal(err) + } + + // ensure uaddr2 has 31+70 = 101 + if balance, err := juno.GetBalance(ctx, uaddr2, tfDenom); err != nil { + t.Fatal(err) + } else if balance != 101 { + t.Fatal("balance not 101") + } + + t.Cleanup(func() { + _ = ic.Close() + }) +} diff --git a/proto/osmosis/tokenfactory/v1beta1/authorityMetadata.proto b/proto/osmosis/tokenfactory/v1beta1/authorityMetadata.proto index a9a370253..d1cfb4f44 100755 --- a/proto/osmosis/tokenfactory/v1beta1/authorityMetadata.proto +++ b/proto/osmosis/tokenfactory/v1beta1/authorityMetadata.proto @@ -4,7 +4,7 @@ package osmosis.tokenfactory.v1beta1; import "gogoproto/gogo.proto"; import "cosmos/base/v1beta1/coin.proto"; -option go_package = "github.com/CosmosContracts/juno/v15/x/tokenfactory/types"; +option go_package = "github.com/CosmosContracts/juno/x/tokenfactory/types"; // DenomAuthorityMetadata specifies metadata for addresses that have specific // capabilities over a token factory denom. Right now there is only one Admin diff --git a/proto/osmosis/tokenfactory/v1beta1/genesis.proto b/proto/osmosis/tokenfactory/v1beta1/genesis.proto index c930a8ade..09df7e3f8 100755 --- a/proto/osmosis/tokenfactory/v1beta1/genesis.proto +++ b/proto/osmosis/tokenfactory/v1beta1/genesis.proto @@ -5,7 +5,7 @@ import "gogoproto/gogo.proto"; import "osmosis/tokenfactory/v1beta1/authorityMetadata.proto"; import "osmosis/tokenfactory/v1beta1/params.proto"; -option go_package = "github.com/CosmosContracts/juno/v15/x/tokenfactory/types"; +option go_package = "github.com/CosmosContracts/juno/x/tokenfactory/types"; // GenesisState defines the tokenfactory module's genesis state. message GenesisState { diff --git a/proto/osmosis/tokenfactory/v1beta1/params.proto b/proto/osmosis/tokenfactory/v1beta1/params.proto index 9a6c0982d..a6c8edc2f 100755 --- a/proto/osmosis/tokenfactory/v1beta1/params.proto +++ b/proto/osmosis/tokenfactory/v1beta1/params.proto @@ -6,7 +6,7 @@ import "osmosis/tokenfactory/v1beta1/authorityMetadata.proto"; import "cosmos_proto/cosmos.proto"; import "cosmos/base/v1beta1/coin.proto"; -option go_package = "github.com/CosmosContracts/juno/v15/x/tokenfactory/types"; +option go_package = "github.com/CosmosContracts/juno/x/tokenfactory/types"; // Params defines the parameters for the tokenfactory module. message Params { diff --git a/proto/osmosis/tokenfactory/v1beta1/query.proto b/proto/osmosis/tokenfactory/v1beta1/query.proto index 9ed1f04a9..9491e95c6 100755 --- a/proto/osmosis/tokenfactory/v1beta1/query.proto +++ b/proto/osmosis/tokenfactory/v1beta1/query.proto @@ -7,7 +7,7 @@ import "cosmos/base/query/v1beta1/pagination.proto"; import "osmosis/tokenfactory/v1beta1/authorityMetadata.proto"; import "osmosis/tokenfactory/v1beta1/params.proto"; -option go_package = "github.com/CosmosContracts/juno/v15/x/tokenfactory/types"; +option go_package = "github.com/CosmosContracts/juno/x/tokenfactory/types"; // Query defines the gRPC querier service. service Query { diff --git a/proto/osmosis/tokenfactory/v1beta1/tx.proto b/proto/osmosis/tokenfactory/v1beta1/tx.proto index 22a12a7b6..3aa1a19ae 100755 --- a/proto/osmosis/tokenfactory/v1beta1/tx.proto +++ b/proto/osmosis/tokenfactory/v1beta1/tx.proto @@ -5,7 +5,7 @@ import "gogoproto/gogo.proto"; import "cosmos/base/v1beta1/coin.proto"; import "cosmos/bank/v1beta1/bank.proto"; -option go_package = "github.com/CosmosContracts/juno/v15/x/tokenfactory/types"; +option go_package = "github.com/CosmosContracts/juno/x/tokenfactory/types"; // Msg defines the tokefactory module's gRPC message service. service Msg { diff --git a/scripts/protoc_swagger_openapi_gen.sh b/scripts/protoc_swagger_openapi_gen.sh index 458942a52..c7872f1e2 100644 --- a/scripts/protoc_swagger_openapi_gen.sh +++ b/scripts/protoc_swagger_openapi_gen.sh @@ -17,12 +17,11 @@ mkdir -p ./tmp-swagger-gen # Get the paths used repos from go/pkg/mod cosmos_sdk_dir=$(go list -f '{{ .Dir }}' -m github.com/cosmos/cosmos-sdk) wasmd=$(go list -f '{{ .Dir }}' -m github.com/CosmWasm/wasmd) -token_factory=$(go list -f '{{ .Dir }}' -m github.com/CosmosContracts/juno/v15) gaia=$(go list -f '{{ .Dir }}' -m github.com/cosmos/gaia/v9) ica=$(go list -f '{{ .Dir }}' -m github.com/cosmos/interchain-accounts) pfm=$(go list -f '{{ .Dir }}' -m github.com/strangelove-ventures/packet-forward-middleware/v4) -proto_dirs=$(find ./proto "$cosmos_sdk_dir"/proto "$wasmd"/proto "$token_factory"/proto "$gaia"/proto "$ica"/proto "$pfm"/proto -path -prune -o -name '*.proto' -print0 | xargs -0 -n1 dirname | sort | uniq) +proto_dirs=$(find ./proto "$cosmos_sdk_dir"/proto "$wasmd"/proto "$gaia"/proto "$ica"/proto "$pfm"/proto -path -prune -o -name '*.proto' -print0 | xargs -0 -n1 dirname | sort | uniq) for dir in $proto_dirs; do # generate swagger files (filter query files) @@ -33,7 +32,6 @@ for dir in $proto_dirs; do -I "$cosmos_sdk_dir/third_party/proto" \ -I "$cosmos_sdk_dir/proto" \ -I "$wasmd/proto" \ - -I "$token_factory/proto" \ -I "$gaia/proto" \ -I "$ica/proto" \ -I "$pfm/proto" \ @@ -74,8 +72,6 @@ for f in $files; do cp $f ./tmp-swagger-gen/_all/juno-$counter.json elif [[ "$f" =~ "cosmos" ]]; then cp $f ./tmp-swagger-gen/_all/cosmos-$counter.json - elif [[ "$f" =~ "tokenfactory" ]]; then - cp $f ./tmp-swagger-gen/_all/tokenfactory-$counter.json # elif [[ "$f" =~ "intertx" ]]; then # cp $f ./tmp-swagger-gen/_all/intertx-$counter.json else diff --git a/tests/interchaintest/setup.go b/tests/interchaintest/setup.go deleted file mode 100644 index ec8230d51..000000000 --- a/tests/interchaintest/setup.go +++ /dev/null @@ -1,54 +0,0 @@ -package interchaintest - -import ( - - // feesharetypes "github.com/CosmosContracts/juno/v15/x/feeshare/types" - "github.com/cosmos/cosmos-sdk/types/module/testutil" - "github.com/strangelove-ventures/interchaintest/v7/chain/cosmos" - "github.com/strangelove-ventures/interchaintest/v7/ibc" -) - -var ( - JunoE2ERepo = "ghcr.io/cosmoscontracts/juno-e2e" - JunoMainRepo = "ghcr.io/cosmoscontracts/juno" - - junoRepo, junoVersion = GetDockerImageInfo() - - JunoImage = ibc.DockerImage{ - Repository: junoRepo, - Version: junoVersion, - UidGid: "1025:1025", - } - - junoConfig = ibc.ChainConfig{ - Type: "cosmos", - Name: "juno", - ChainID: "juno-2", - Images: []ibc.DockerImage{JunoImage}, - Bin: "junod", - Bech32Prefix: "juno", - Denom: "ujuno", - CoinType: "118", - GasPrices: "0.0ujuno", - GasAdjustment: 1.1, - TrustingPeriod: "112h", - NoHostMount: false, - ModifyGenesis: nil, - ConfigFileOverrides: nil, - EncodingConfig: junoEncoding(), - } - - pathJunoGaia = "juno-gaia" - genesisWalletAmount = int64(10_000_000) -) - -// junoEncoding registers the Juno specific module codecs so that the associated types and msgs -// will be supported when writing to the blocksdb sqlite database. -func junoEncoding() *testutil.TestEncodingConfig { - cfg := cosmos.DefaultEncoding() - - // register custom types - // feesharetypes.RegisterInterfaces(cfg.InterfaceRegistry) - - return &cfg -} diff --git a/x/feeshare/types/msg_test.go b/x/feeshare/types/msg_test.go index e4cbc9812..d1759b2c9 100644 --- a/x/feeshare/types/msg_test.go +++ b/x/feeshare/types/msg_test.go @@ -23,7 +23,7 @@ func TestMsgsTestSuite(t *testing.T) { func (suite *MsgsTestSuite) SetupTest() { deployer := "cosmos1" withdraw := "cosmos2" - suite.contract = sdk.AccAddress([]byte("cosmos15u3dt79t6sxxa3x3kpkhzsy56edaa5a66wvt3kxmukqjz2sx0hesh45zsv")) + suite.contract = sdk.AccAddress([]byte("juno15u3dt79t6sxxa3x3kpkhzsy56edaa5a66wvt3kxmukqjz2sx0hes5sn38g")) suite.deployer = sdk.AccAddress([]byte(deployer)) suite.deployerStr = suite.deployer.String() suite.withdrawerStr = sdk.AccAddress([]byte(withdraw)).String() diff --git a/x/tokenfactory/simulation/params.go b/x/tokenfactory/simulation/params.go new file mode 100644 index 000000000..f25901d8c --- /dev/null +++ b/x/tokenfactory/simulation/params.go @@ -0,0 +1,23 @@ +package simulation + +import ( + "fmt" + "math/rand" + + "github.com/CosmosContracts/juno/v15/x/tokenfactory/types" + simtypes "github.com/cosmos/cosmos-sdk/types/simulation" + "github.com/cosmos/cosmos-sdk/x/simulation" +) + +func ParamChanges(_ *rand.Rand) []simtypes.ParamChange { + return []simtypes.ParamChange{ + simulation.NewSimParamChange( + types.ModuleName, + string(types.KeyDenomCreationFee), + func(r *rand.Rand) string { + amount := RandDenomCreationFeeParam(r) + return fmt.Sprintf("[{\"denom\":\"%v\",\"amount\":\"%v\"}]", amount[0].Denom, amount[0].Amount) + }, + ), + } +} From eccf42ade60d1e66d1c2199a21254eff7b1f2dd0 Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Wed, 10 May 2023 15:05:44 -0500 Subject: [PATCH 069/131] Fix imported tokenfactory minor touchup --- .gitignore | 2 ++ app/params/params.go | 15 --------------- x/tokenfactory/simulation/params.go | 23 ----------------------- 3 files changed, 2 insertions(+), 38 deletions(-) delete mode 100644 app/params/params.go delete mode 100644 x/tokenfactory/simulation/params.go diff --git a/.gitignore b/.gitignore index fc94a7bab..28dd2df17 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,8 @@ tmp-swagger-gen heighliner* +x/**/data/wasm/* + # emacs editor config \#*\# .\#* diff --git a/app/params/params.go b/app/params/params.go deleted file mode 100644 index eb88c5a26..000000000 --- a/app/params/params.go +++ /dev/null @@ -1,15 +0,0 @@ -package params - -// Simulation parameter constants -const ( - StakePerAccount = "stake_per_account" - InitiallyBondedValidators = "initially_bonded_validators" - - // Token Factory - DefaultWeightMsgCreateDenom int = 100 - DefaultWeightMsgMint int = 100 - DefaultWeightMsgBurn int = 100 - DefaultWeightMsgChangeAdmin int = 100 - DefaultWeightMsgSetDenomMetadata int = 100 - DefaultWeightMsgForceTransfer int = 100 -) diff --git a/x/tokenfactory/simulation/params.go b/x/tokenfactory/simulation/params.go deleted file mode 100644 index f25901d8c..000000000 --- a/x/tokenfactory/simulation/params.go +++ /dev/null @@ -1,23 +0,0 @@ -package simulation - -import ( - "fmt" - "math/rand" - - "github.com/CosmosContracts/juno/v15/x/tokenfactory/types" - simtypes "github.com/cosmos/cosmos-sdk/types/simulation" - "github.com/cosmos/cosmos-sdk/x/simulation" -) - -func ParamChanges(_ *rand.Rand) []simtypes.ParamChange { - return []simtypes.ParamChange{ - simulation.NewSimParamChange( - types.ModuleName, - string(types.KeyDenomCreationFee), - func(r *rand.Rand) string { - amount := RandDenomCreationFeeParam(r) - return fmt.Sprintf("[{\"denom\":\"%v\",\"amount\":\"%v\"}]", amount[0].Denom, amount[0].Amount) - }, - ), - } -} From 060512af55985efe3905d1ba1edda333af3af208 Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Tue, 9 May 2023 16:21:05 -0500 Subject: [PATCH 070/131] Adds FeeShare interchain test --- .github/workflows/interchaintest-E2E.yml | 17 +++++ Makefile | 3 + interchaintest/contracts/README.md | 3 +- interchaintest/contracts/cw_template.wasm | Bin 0 -> 132664 bytes interchaintest/helpers/cosmwasm.go | 60 ++++++++++++++++++ interchaintest/helpers/feeshare.go | 33 ++++++++++ interchaintest/module_feeshare_test.go | 55 ++++++++++++++++ ...ry_test.go => module_tokenfactory_test.go} | 2 +- 8 files changed, 171 insertions(+), 2 deletions(-) create mode 100644 interchaintest/contracts/cw_template.wasm create mode 100644 interchaintest/helpers/feeshare.go create mode 100644 interchaintest/module_feeshare_test.go rename interchaintest/{tokenfactory_test.go => module_tokenfactory_test.go} (99%) diff --git a/.github/workflows/interchaintest-E2E.yml b/.github/workflows/interchaintest-E2E.yml index a3fdece5e..9f0b59916 100644 --- a/.github/workflows/interchaintest-E2E.yml +++ b/.github/workflows/interchaintest-E2E.yml @@ -144,3 +144,20 @@ jobs: - run: make ictest-tokenfactory env: BRANCH_CI: ${{needs.build-and-push-image.outputs.branchTag}} + + test-juno-feeshare: + runs-on: ubuntu-latest + needs: build-and-push-image + steps: + - name: checkout chain + uses: actions/checkout@v2 + + - name: Setup Golang with cache + uses: magnetikonline/action-golang-cache@v4 + with: + go-version: ${{ env.GO_VERSION }} + id: go + + - run: make ictest-feeshare + env: + BRANCH_CI: ${{needs.build-and-push-image.outputs.branchTag}} diff --git a/Makefile b/Makefile index 4a5e3f124..92fc2258c 100644 --- a/Makefile +++ b/Makefile @@ -128,6 +128,9 @@ ictest-basic: ictest-tokenfactory: cd interchaintest && go test -race -v -run TestJunoTokenFactory . +ictest-feeshare: + cd interchaintest && go test -race -v -run TestJunoFeeShare . + # Executes a basic chain upgrade test via interchaintest ictest-upgrade: cd interchaintest && go test -race -v -run TestBasicJunoUpgrade . diff --git a/interchaintest/contracts/README.md b/interchaintest/contracts/README.md index c0b5ae3d9..2851b8e74 100644 --- a/interchaintest/contracts/README.md +++ b/interchaintest/contracts/README.md @@ -2,4 +2,5 @@ A list of the contracts here which are pre-compiled in other repos. -> tokenfactory_core.wasm -> (PR 8). +> tokenfactory_core.wasm -> +> cw_template -> diff --git a/interchaintest/contracts/cw_template.wasm b/interchaintest/contracts/cw_template.wasm new file mode 100644 index 0000000000000000000000000000000000000000..909cbdd198caf9ececdf0c288ceda0b1a4d912f2 GIT binary patch literal 132664 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 M(t{<21#`lG0|9DE)c^nh literal 0 HcmV?d00001 diff --git a/interchaintest/helpers/cosmwasm.go b/interchaintest/helpers/cosmwasm.go index 2fccee37e..5a356533d 100644 --- a/interchaintest/helpers/cosmwasm.go +++ b/interchaintest/helpers/cosmwasm.go @@ -4,7 +4,11 @@ import ( "context" "testing" + "github.com/cosmos/cosmos-sdk/crypto/keyring" "github.com/strangelove-ventures/interchaintest/v4/chain/cosmos" + "github.com/strangelove-ventures/interchaintest/v4/ibc" + "github.com/strangelove-ventures/interchaintest/v4/testutil" + "github.com/stretchr/testify/require" ) func SetupContract(t *testing.T, ctx context.Context, chain *cosmos.CosmosChain, keyname string, fileLoc string, message string) (codeId, contract string) { @@ -23,3 +27,59 @@ func SetupContract(t *testing.T, ctx context.Context, chain *cosmos.CosmosChain, return codeId, contractAddr } +func ExecuteMsgWithAmount(t *testing.T, ctx context.Context, chain *cosmos.CosmosChain, user *ibc.Wallet, contractAddr, amount, message string) { + // amount is #utoken + + // There has to be a way to do this in ictest? + cmd := []string{"junod", "tx", "wasm", "execute", contractAddr, message, + "--node", chain.GetRPCAddress(), + "--home", chain.HomeDir(), + "--chain-id", chain.Config().ChainID, + "--from", user.KeyName, + "--gas", "500000", + "--amount", amount, + "--keyring-dir", chain.HomeDir(), + "--keyring-backend", keyring.BackendTest, + "-y", + } + _, _, err := chain.Exec(ctx, cmd, nil) + require.NoError(t, err) + + // t.Log("msg", cmd) + // t.Log("ExecuteMsgWithAmount", string(stdout)) + + if err := testutil.WaitForBlocks(ctx, 2, chain); err != nil { + t.Fatal(err) + } +} + +func ExecuteMsgWithFee(t *testing.T, ctx context.Context, chain *cosmos.CosmosChain, user *ibc.Wallet, contractAddr, amount, feeCoin, message string) { + // amount is #utoken + + // There has to be a way to do this in ictest? + cmd := []string{"junod", "tx", "wasm", "execute", contractAddr, message, + "--node", chain.GetRPCAddress(), + "--home", chain.HomeDir(), + "--chain-id", chain.Config().ChainID, + "--from", user.KeyName, + "--gas", "500000", + "--fees", feeCoin, + "--keyring-dir", chain.HomeDir(), + "--keyring-backend", keyring.BackendTest, + "-y", + } + + if amount != "" { + cmd = append(cmd, "--amount", amount) + } + + _, _, err := chain.Exec(ctx, cmd, nil) + require.NoError(t, err) + + // t.Log("msg", cmd) + // t.Log("ExecuteMsgWithAmount", string(stdout)) + + if err := testutil.WaitForBlocks(ctx, 2, chain); err != nil { + t.Fatal(err) + } +} diff --git a/interchaintest/helpers/feeshare.go b/interchaintest/helpers/feeshare.go new file mode 100644 index 000000000..0ca21d8be --- /dev/null +++ b/interchaintest/helpers/feeshare.go @@ -0,0 +1,33 @@ +package helpers + +import ( + "context" + "testing" + + "github.com/cosmos/cosmos-sdk/crypto/keyring" + "github.com/strangelove-ventures/interchaintest/v4/chain/cosmos" + "github.com/strangelove-ventures/interchaintest/v4/ibc" + "github.com/strangelove-ventures/interchaintest/v4/testutil" + "github.com/stretchr/testify/require" +) + +func RegisterFeeShare(t *testing.T, ctx context.Context, chain *cosmos.CosmosChain, user *ibc.Wallet, contract, withdrawAddr string) { + // TF gas to create cost 2mil, so we set to 2.5 to be safe + cmd := []string{"junod", "tx", "feeshare", "register", contract, withdrawAddr, + "--node", chain.GetRPCAddress(), + "--home", chain.HomeDir(), + "--chain-id", chain.Config().ChainID, + "--from", user.KeyName, + // "--gas", "500000", + "--keyring-dir", chain.HomeDir(), + "--keyring-backend", keyring.BackendTest, + "-y", + } + stdout, _, err := chain.Exec(ctx, cmd, nil) + require.NoError(t, err) + + debugOutput(t, string(stdout)) + + err = testutil.WaitForBlocks(ctx, 2, chain) + require.NoError(t, err) +} diff --git a/interchaintest/module_feeshare_test.go b/interchaintest/module_feeshare_test.go new file mode 100644 index 000000000..25ec6f4c8 --- /dev/null +++ b/interchaintest/module_feeshare_test.go @@ -0,0 +1,55 @@ +package interchaintest + +import ( + "testing" + + "github.com/strangelove-ventures/interchaintest/v4" + "github.com/strangelove-ventures/interchaintest/v4/chain/cosmos" + + helpers "github.com/CosmosContracts/juno/tests/interchaintest/helpers" +) + +// TestJunoFeeShare ensures the feeshare module register and execute sharing functions work properly on smart contracts. +func TestJunoFeeShare(t *testing.T) { + t.Parallel() + + // Base setup + chains := CreateThisBranchChain(t) + ic, ctx, _, _ := BuildInitialChain(t, chains) + + // Chains + juno := chains[0].(*cosmos.CosmosChain) + t.Log("juno.GetHostRPCAddress()", juno.GetHostRPCAddress()) + + nativeDenom := juno.Config().Denom + + // Users + users := interchaintest.GetAndFundTestUsers(t, ctx, "default", int64(10_000_000), juno, juno) + user := users[0] + feeRcvAddr := "juno1v75wlkccpv7le3560zw32v2zjes5n0e7csr4qh" + + // Upload & init contract payment to another address + _, contractAddr := helpers.SetupContract(t, ctx, juno, user.KeyName, "contracts/cw_template.wasm", `{"count":0}`) + + // register contract to a random address (since we are the creator, though not the admin) + helpers.RegisterFeeShare(t, ctx, juno, user, contractAddr, feeRcvAddr) + if balance, err := juno.GetBalance(ctx, feeRcvAddr, nativeDenom); err != nil { + t.Fatal(err) + } else if balance != 0 { + t.Fatal("balance not 0") + } + + // execute with a 10000 fee (so 5000 denom should be in the contract now with 50% feeshare default) + helpers.ExecuteMsgWithFee(t, ctx, juno, user, contractAddr, "", "10000"+nativeDenom, `{"increment":{}}`) + + // check balance of nativeDenom now + if balance, err := juno.GetBalance(ctx, feeRcvAddr, nativeDenom); err != nil { + t.Fatal(err) + } else if balance != 5000 { + t.Fatal("balance not 5,000. it is ", balance, nativeDenom) + } + + t.Cleanup(func() { + _ = ic.Close() + }) +} diff --git a/interchaintest/tokenfactory_test.go b/interchaintest/module_tokenfactory_test.go similarity index 99% rename from interchaintest/tokenfactory_test.go rename to interchaintest/module_tokenfactory_test.go index 7b8c5fa3b..965ef3dbd 100644 --- a/interchaintest/tokenfactory_test.go +++ b/interchaintest/module_tokenfactory_test.go @@ -18,7 +18,7 @@ func TestJunoTokenFactory(t *testing.T) { chains := CreateThisBranchChain(t) ic, ctx, _, _ := BuildInitialChain(t, chains) - // get + // Chains juno := chains[0].(*cosmos.CosmosChain) t.Log("juno.GetHostRPCAddress()", juno.GetHostRPCAddress()) From d4bf9d6c8b46ab9dd1f903994ac8b4ef4953f215 Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Tue, 9 May 2023 16:39:42 -0500 Subject: [PATCH 071/131] cleanup old comments --- interchaintest/helpers/cosmwasm.go | 12 ++++-------- interchaintest/helpers/tokenfactory.go | 2 -- interchaintest/module_tokenfactory_test.go | 1 - 3 files changed, 4 insertions(+), 11 deletions(-) diff --git a/interchaintest/helpers/cosmwasm.go b/interchaintest/helpers/cosmwasm.go index 5a356533d..388a7e26e 100644 --- a/interchaintest/helpers/cosmwasm.go +++ b/interchaintest/helpers/cosmwasm.go @@ -16,13 +16,11 @@ func SetupContract(t *testing.T, ctx context.Context, chain *cosmos.CosmosChain, if err != nil { t.Fatal(err) } - // require.Equal(t, "1", codeId) contractAddr, err := chain.InstantiateContract(ctx, keyname, codeId, message, true) if err != nil { t.Fatal(err) } - // t.Log(contractAddr) return codeId, contractAddr } @@ -42,11 +40,10 @@ func ExecuteMsgWithAmount(t *testing.T, ctx context.Context, chain *cosmos.Cosmo "--keyring-backend", keyring.BackendTest, "-y", } - _, _, err := chain.Exec(ctx, cmd, nil) + stdout, _, err := chain.Exec(ctx, cmd, nil) require.NoError(t, err) - // t.Log("msg", cmd) - // t.Log("ExecuteMsgWithAmount", string(stdout)) + debugOutput(t, string(stdout)) if err := testutil.WaitForBlocks(ctx, 2, chain); err != nil { t.Fatal(err) @@ -73,11 +70,10 @@ func ExecuteMsgWithFee(t *testing.T, ctx context.Context, chain *cosmos.CosmosCh cmd = append(cmd, "--amount", amount) } - _, _, err := chain.Exec(ctx, cmd, nil) + stdout, _, err := chain.Exec(ctx, cmd, nil) require.NoError(t, err) - // t.Log("msg", cmd) - // t.Log("ExecuteMsgWithAmount", string(stdout)) + debugOutput(t, string(stdout)) if err := testutil.WaitForBlocks(ctx, 2, chain); err != nil { t.Fatal(err) diff --git a/interchaintest/helpers/tokenfactory.go b/interchaintest/helpers/tokenfactory.go index 94d6cc864..06224abc0 100644 --- a/interchaintest/helpers/tokenfactory.go +++ b/interchaintest/helpers/tokenfactory.go @@ -14,8 +14,6 @@ import ( "github.com/stretchr/testify/require" ) -const CHAIN_PREFIX = "juno" - func debugOutput(t *testing.T, stdout string) { if true { t.Log(stdout) diff --git a/interchaintest/module_tokenfactory_test.go b/interchaintest/module_tokenfactory_test.go index 965ef3dbd..f2da9bd10 100644 --- a/interchaintest/module_tokenfactory_test.go +++ b/interchaintest/module_tokenfactory_test.go @@ -50,7 +50,6 @@ func TestJunoTokenFactory(t *testing.T) { t.Fatal("balance not 70") } - // TODO: Use same contract for a feeshare test with changing params // This allows the uaddr here to mint tokens on behalf of the contract. Typically you only allow a contract here, but this is testing. coreInitMsg := fmt.Sprintf(`{"allowed_mint_addresses":["%s"],"denoms":["%s"]}`, uaddr, tfDenom) _, coreTFContract := helpers.SetupContract(t, ctx, juno, user.KeyName, "contracts/tokenfactory_core.wasm", coreInitMsg) From e3e227962cccb8a77c0f849c9eafb9bc313db025 Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Tue, 9 May 2023 16:40:03 -0500 Subject: [PATCH 072/131] only test simulate on merge of PR --- .github/workflows/test-simulation.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test-simulation.yml b/.github/workflows/test-simulation.yml index 8d3b47520..58cd1829b 100644 --- a/.github/workflows/test-simulation.yml +++ b/.github/workflows/test-simulation.yml @@ -1,9 +1,12 @@ --- +name: Test Simulation + on: pull_request: + types: + - closed paths: - '**.go' -name: Test Simulation concurrency: group: ${{ github.workflow }}-${{ github.ref }} @@ -11,6 +14,7 @@ concurrency: jobs: test: + if: github.event.pull_request.merged == true runs-on: ubuntu-latest name: test steps: From d65da17f4e4de63acf935522cc7ad3e8387eb6e6 Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Wed, 10 May 2023 09:39:31 -0500 Subject: [PATCH 073/131] Unity contract CI in house (ictest) --- .github/workflows/gov_deploy.yml | 38 ---------- .github/workflows/gov_submit.yml | 39 ---------- .github/workflows/interchaintest-E2E.yml | 40 +++++++++- Makefile | 7 ++ interchaintest/contract_unity_deploy_test.go | 48 ++++++++++++ interchaintest/contract_unity_submit_test.go | 75 +++++++++++++++++++ interchaintest/contracts/README.md | 1 + interchaintest/contracts/cw_unity_prop.wasm | Bin 0 -> 156998 bytes interchaintest/helpers/cosmwasm.go | 24 ++++++ interchaintest/helpers/query_helpers.go | 8 ++ interchaintest/helpers/types.go | 17 ++++- interchaintest/setup.go | 5 +- 12 files changed, 220 insertions(+), 82 deletions(-) delete mode 100644 .github/workflows/gov_deploy.yml delete mode 100644 .github/workflows/gov_submit.yml create mode 100644 interchaintest/contract_unity_deploy_test.go create mode 100644 interchaintest/contract_unity_submit_test.go create mode 100644 interchaintest/contracts/cw_unity_prop.wasm diff --git a/.github/workflows/gov_deploy.yml b/.github/workflows/gov_deploy.yml deleted file mode 100644 index 7d2e4e7f6..000000000 --- a/.github/workflows/gov_deploy.yml +++ /dev/null @@ -1,38 +0,0 @@ ---- -name: Gov Contract CI - Deploy - -on: - pull_request: - paths: - - '**.go' - push: - paths: - - '**.go' - tags: - branches: - - 'main' - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - docker: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - name: Docker compose - run: STAKE_TOKEN="ujunox" TIMEOUT_COMMIT=500ms docker-compose up -d - - name: Checkout - uses: actions/checkout@v3 - with: - repository: 'CosmosContracts/cw-unity-prop' - ref: 'v0.3.4-alpha' - - name: Test gov deploy - run: | - chmod a+x ./scripts/deploy_ci.sh - ./scripts/deploy_ci.sh juno16g2rahf5846rxzp3fwlswy08fz8ccuwk03k57y - - name: Dump docker logs on failure - if: failure() - uses: jwalton/gh-docker-logs@v2 - diff --git a/.github/workflows/gov_submit.yml b/.github/workflows/gov_submit.yml deleted file mode 100644 index 810ebd9ab..000000000 --- a/.github/workflows/gov_submit.yml +++ /dev/null @@ -1,39 +0,0 @@ ---- -name: Gov Contract CI - Submit Contract Prop - -on: - pull_request: - paths: - - '**.go' - push: - paths: - - '**.go' - tags: - branches: - - 'main' - - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - docker: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - name: Docker compose - run: STAKE_TOKEN="ujunox" TIMEOUT_COMMIT=500ms docker-compose up -d - - name: Checkout - uses: actions/checkout@v3 - with: - repository: 'CosmosContracts/cw-unity-prop' - ref: 'v0.3.4-alpha' - - name: Test smart contract gov prop - run: | - chmod a+x ./scripts/submit_gov_ci.sh - ./scripts/submit_gov_ci.sh juno16g2rahf5846rxzp3fwlswy08fz8ccuwk03k57y - - name: Dump docker logs on failure - if: failure() - uses: jwalton/gh-docker-logs@v2 - diff --git a/.github/workflows/interchaintest-E2E.yml b/.github/workflows/interchaintest-E2E.yml index 9f0b59916..0a5c8e3a0 100644 --- a/.github/workflows/interchaintest-E2E.yml +++ b/.github/workflows/interchaintest-E2E.yml @@ -75,7 +75,9 @@ jobs: cache-to: type=gha,mode=max # make juno:branchname here for all needs.build-and-push-image.outputs.branchTag - # then upload to github. Then download for each as a cache. This way its only built once + # then upload to github. Then download for each as a cache. This way its only built once + + # TODO: Add reusable job template here, just changing the `make` command for each test-juno-basic: runs-on: ubuntu-latest @@ -161,3 +163,39 @@ jobs: - run: make ictest-feeshare env: BRANCH_CI: ${{needs.build-and-push-image.outputs.branchTag}} + + + # === UNITY CONTRACT === + test-juno-unity-deploy: + runs-on: ubuntu-latest + needs: build-and-push-image + steps: + - name: checkout chain + uses: actions/checkout@v2 + + - name: Setup Golang with cache + uses: magnetikonline/action-golang-cache@v4 + with: + go-version: ${{ env.GO_VERSION }} + id: go + + - run: make ictest-unity-deploy + env: + BRANCH_CI: ${{needs.build-and-push-image.outputs.branchTag}} + + test-juno-unity-gov: + runs-on: ubuntu-latest + needs: build-and-push-image + steps: + - name: checkout chain + uses: actions/checkout@v2 + + - name: Setup Golang with cache + uses: magnetikonline/action-golang-cache@v4 + with: + go-version: ${{ env.GO_VERSION }} + id: go + + - run: make ictest-unity-gov + env: + BRANCH_CI: ${{needs.build-and-push-image.outputs.branchTag}} diff --git a/Makefile b/Makefile index 92fc2258c..a44bf5f2d 100644 --- a/Makefile +++ b/Makefile @@ -142,6 +142,13 @@ ictest-upgrade-local: local-image ictest-upgrade ictest-ibc: cd interchaintest && go test -race -v -run TestJunoGaiaIBCTransfer . +# Unity contract CI +ictest-unity-deploy: + cd interchaintest && go test -race -v -run TestJunoUnityContractDeploy . + +ictest-unity-gov: + cd interchaintest && go test -race -v -run TestJunoUnityContractGovSubmit . + # Executes all tests via interchaintest after compling a local image as juno:local ictest-all: local-image ictest-basic ictest-upgrade ictest-ibc diff --git a/interchaintest/contract_unity_deploy_test.go b/interchaintest/contract_unity_deploy_test.go new file mode 100644 index 000000000..a31ca1917 --- /dev/null +++ b/interchaintest/contract_unity_deploy_test.go @@ -0,0 +1,48 @@ +package interchaintest + +import ( + "fmt" + "testing" + + "github.com/strangelove-ventures/interchaintest/v4" + "github.com/strangelove-ventures/interchaintest/v4/chain/cosmos" + + helpers "github.com/CosmosContracts/juno/tests/interchaintest/helpers" +) + +// TestJunoUnityContractDeploy test to ensure the contract withdraw function works as expected on chain. +// - https://github.com/CosmosContracts/cw-unity-prop +func TestJunoUnityContractDeploy(t *testing.T) { + t.Parallel() + + // Base setup + chains := CreateThisBranchChain(t) + ic, ctx, _, _ := BuildInitialChain(t, chains) + + // Chains + juno := chains[0].(*cosmos.CosmosChain) + nativeDenom := juno.Config().Denom + + // Users + users := interchaintest.GetAndFundTestUsers(t, ctx, "default", int64(10_000_000), juno, juno) + user := users[0] + withdrawUser := users[1] + withdrawAddr := withdrawUser.Bech32Address(juno.Config().Bech32Prefix) + + // TEST DEPLOY (./scripts/deploy_ci.sh) + // Upload & init unity contract with no admin in test mode + msg := fmt.Sprintf(`{"native_denom":"%s","withdraw_address":"%s","withdraw_delay_in_days":28}`, nativeDenom, withdrawAddr) + _, contractAddr := helpers.SetupContract(t, ctx, juno, user.KeyName, "contracts/cw_unity_prop.wasm", msg) + t.Log("testing Unity contractAddr", contractAddr) + + // Execute to start the withdrawl countdown + juno.ExecuteContract(ctx, withdrawUser.KeyName, contractAddr, `{"start_withdraw":{}}`) + + // make a query with GetUnityContractWithdrawalReadyTime + res := helpers.GetUnityContractWithdrawalReadyTime(t, ctx, juno, contractAddr) + t.Log("WithdrawalReadyTimestamp", res.Data.WithdrawalReadyTimestamp) + + t.Cleanup(func() { + _ = ic.Close() + }) +} diff --git a/interchaintest/contract_unity_submit_test.go b/interchaintest/contract_unity_submit_test.go new file mode 100644 index 000000000..cd88eece7 --- /dev/null +++ b/interchaintest/contract_unity_submit_test.go @@ -0,0 +1,75 @@ +package interchaintest + +import ( + "fmt" + "testing" + + "github.com/strangelove-ventures/interchaintest/v4" + "github.com/strangelove-ventures/interchaintest/v4/chain/cosmos" + "github.com/strangelove-ventures/interchaintest/v4/ibc" + "github.com/strangelove-ventures/interchaintest/v4/testutil" + "github.com/stretchr/testify/require" + + helpers "github.com/CosmosContracts/juno/tests/interchaintest/helpers" +) + +// TestJunoSubmitUnityContract test to ensure the store code properly works on the contract +// - https://github.com/CosmosContracts/cw-unity-prop +func TestJunoUnityContractGovSubmit(t *testing.T) { + t.Parallel() + + // Base setup + chains := CreateThisBranchChain(t) + ic, ctx, _, _ := BuildInitialChain(t, chains) + + // Chains + juno := chains[0].(*cosmos.CosmosChain) + + nativeDenom := juno.Config().Denom + + // Users + users := interchaintest.GetAndFundTestUsers(t, ctx, "default", int64(10000_000000), juno, juno) + user := users[0] + withdrawUser := users[1] + withdrawAddr := withdrawUser.Bech32Address(juno.Config().Bech32Prefix) + + // Upload & init unity contract with no admin in test mode + msg := fmt.Sprintf(`{"native_denom":"%s","withdraw_address":"%s","withdraw_delay_in_days":28}`, nativeDenom, withdrawAddr) + _, contractAddr := helpers.SetupContract(t, ctx, juno, user.KeyName, "contracts/cw_unity_prop.wasm", msg) + t.Log("testing Unity contractAddr", contractAddr) + + // send 2JUNO funds to the contract from user + juno.SendFunds(ctx, user.KeyName, ibc.WalletAmount{Address: contractAddr, Denom: nativeDenom, Amount: 2000000}) + + height, err := juno.Height(ctx) + require.NoError(t, err, "error fetching height") + + msg = fmt.Sprintf(`{"execute_send":{"amount":"1000000","recipient":"%s"}}`, withdrawAddr) + helpers.StoreContractGovernanceProposal(t, ctx, juno, user, "Prop Title", "description", fmt.Sprintf(`500000000%s`, nativeDenom), contractAddr, "", msg) + proposalID := "1" + + // poll for proposal + err = juno.VoteOnProposalAllValidators(ctx, proposalID, cosmos.ProposalVoteYes) + require.NoError(t, err, "failed to submit votes") + + _, err = cosmos.PollForProposalStatus(ctx, juno, height, height+haltHeightDelta, proposalID, cosmos.ProposalStatusPassed) + require.NoError(t, err, "proposal status did not change to passed in expected number of blocks") + + // TODO start_withdraw on it here to remove the other test + + // Execute to start the withdrawl countdown + // juno.ExecuteContract(ctx, withdrawUser.KeyName, contractAddr, `{"start_withdraw":{}}`) + + fmt.Print("juno RPC: ", juno.GetHostRPCAddress()) + if err := testutil.WaitForBlocks(ctx, 50, juno); err != nil { + t.Fatal(err) + } + + // make a query with GetUnityContractWithdrawalReadyTime + res := helpers.GetUnityContractWithdrawalReadyTime(t, ctx, juno, contractAddr) + t.Log("WithdrawalReadyTimestamp", res.Data.WithdrawalReadyTimestamp) + + t.Cleanup(func() { + _ = ic.Close() + }) +} diff --git a/interchaintest/contracts/README.md b/interchaintest/contracts/README.md index 2851b8e74..d1c7cb6b4 100644 --- a/interchaintest/contracts/README.md +++ b/interchaintest/contracts/README.md @@ -4,3 +4,4 @@ A list of the contracts here which are pre-compiled in other repos. > tokenfactory_core.wasm -> > cw_template -> +> cw_unity_prop -> v0.3.4-alpha \ No newline at end of file diff --git a/interchaintest/contracts/cw_unity_prop.wasm b/interchaintest/contracts/cw_unity_prop.wasm new file mode 100644 index 0000000000000000000000000000000000000000..75080eaa9cbcd39063baff8abc8fcfadb60a7bae GIT binary patch literal 156998 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 literal 0 HcmV?d00001 diff --git a/interchaintest/helpers/cosmwasm.go b/interchaintest/helpers/cosmwasm.go index 388a7e26e..6e4e99bd7 100644 --- a/interchaintest/helpers/cosmwasm.go +++ b/interchaintest/helpers/cosmwasm.go @@ -25,6 +25,30 @@ func SetupContract(t *testing.T, ctx context.Context, chain *cosmos.CosmosChain, return codeId, contractAddr } +func StoreContractGovernanceProposal(t *testing.T, ctx context.Context, chain *cosmos.CosmosChain, user *ibc.Wallet, title, description, depositCoin, contractAddr, amount, message string) { + cmd := []string{"junod", "tx", "gov", "submit-proposal", "sudo-contract", contractAddr, message, + "--title", title, + "--description", description, + "--deposit", depositCoin, + "--node", chain.GetRPCAddress(), + "--home", chain.HomeDir(), + "--chain-id", chain.Config().ChainID, + "--from", user.KeyName, + "--gas", "2000000", + "--keyring-dir", chain.HomeDir(), + "--keyring-backend", keyring.BackendTest, + "-y", + } + + if amount != "" { + cmd = append(cmd, "--amount", amount) + } + + stdout, _, err := chain.Exec(ctx, cmd, nil) + require.NoError(t, err) + debugOutput(t, string(stdout)) +} + func ExecuteMsgWithAmount(t *testing.T, ctx context.Context, chain *cosmos.CosmosChain, user *ibc.Wallet, contractAddr, amount, message string) { // amount is #utoken diff --git a/interchaintest/helpers/query_helpers.go b/interchaintest/helpers/query_helpers.go index 913eda5e7..a21e8f05a 100644 --- a/interchaintest/helpers/query_helpers.go +++ b/interchaintest/helpers/query_helpers.go @@ -14,3 +14,11 @@ func GetUserTokenFactoryBalances(t *testing.T, ctx context.Context, chain *cosmo require.NoError(t, err) return res } + +func GetUnityContractWithdrawalReadyTime(t *testing.T, ctx context.Context, chain *cosmos.CosmosChain, contract string) WithdrawalTimestampResponse { + // junod query wasm contract-state smart '{"get_withdrawal_ready_time":{}}' --output json + var res WithdrawalTimestampResponse + err := chain.QueryContract(ctx, contract, QueryMsg{GetWithdrawalReadyTime: &struct{}{}}, &res) + require.NoError(t, err) + return res +} diff --git a/interchaintest/helpers/types.go b/interchaintest/helpers/types.go index 3a002c4d4..6c3b6f2e6 100644 --- a/interchaintest/helpers/types.go +++ b/interchaintest/helpers/types.go @@ -11,10 +11,13 @@ import ( // EntryPoint type QueryMsg struct { - GetConfig *struct{} `json:"get_config,omitempty"` - + // Tokenfactory Core + GetConfig *struct{} `json:"get_config,omitempty"` GetBalance *GetBalanceQuery `json:"get_balance,omitempty"` GetAllBalances *GetAllBalancesQuery `json:"get_all_balances,omitempty"` + + // Unity Contract + GetWithdrawalReadyTime *struct{} `json:"get_withdrawal_ready_time,omitempty"` } type GetAllBalancesQuery struct { @@ -25,8 +28,8 @@ type GetAllBalancesResponse struct { Data []sdk.Coin `json:"data"` } -// {"get_balance":{"address":"juno1...","denom":"factory/juno1.../RcqfWz"}} type GetBalanceQuery struct { + // {"get_balance":{"address":"juno1...","denom":"factory/juno1.../RcqfWz"}} Address string `json:"address"` Denom string `json:"denom"` } @@ -34,3 +37,11 @@ type GetBalanceResponse struct { // or is it wasm Coin type? Data sdk.Coin `json:"data"` } + +type WithdrawalTimestampResponse struct { + // {"data":{"withdrawal_ready_timestamp":"1686146048614053435"}} + Data *WithdrawalTimestampObj `json:"data"` +} +type WithdrawalTimestampObj struct { + WithdrawalReadyTimestamp string `json:"withdrawal_ready_timestamp"` +} diff --git a/interchaintest/setup.go b/interchaintest/setup.go index 5947bf5f6..4b7c744b1 100644 --- a/interchaintest/setup.go +++ b/interchaintest/setup.go @@ -106,13 +106,16 @@ func CreateThisBranchChain(t *testing.T) []ibc.Chain { numVals := 1 numFullNodes := 0 + votingPeriod := "10s" + maxDepositPeriod := "10s" + cf := interchaintest.NewBuiltinChainFactory(zaptest.NewLogger(t), []*interchaintest.ChainSpec{ { Name: "juno", ChainName: "juno", Version: junoVersion, ChainConfig: ibc.ChainConfig{ - // ModifyGenesis: cosmos.ModifyGenesisProposalTime(votingPeriod, maxDepositPeriod), + ModifyGenesis: cosmos.ModifyGenesisProposalTime(votingPeriod, maxDepositPeriod), Images: []ibc.DockerImage{ { Repository: junoRepo, From e7813b66e3613213f704adcbafff7c3c04c93b0c Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Wed, 10 May 2023 09:50:09 -0500 Subject: [PATCH 074/131] Remove old debug code for gov test --- interchaintest/contract_unity_submit_test.go | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/interchaintest/contract_unity_submit_test.go b/interchaintest/contract_unity_submit_test.go index cd88eece7..d25441c4f 100644 --- a/interchaintest/contract_unity_submit_test.go +++ b/interchaintest/contract_unity_submit_test.go @@ -55,20 +55,6 @@ func TestJunoUnityContractGovSubmit(t *testing.T) { _, err = cosmos.PollForProposalStatus(ctx, juno, height, height+haltHeightDelta, proposalID, cosmos.ProposalStatusPassed) require.NoError(t, err, "proposal status did not change to passed in expected number of blocks") - // TODO start_withdraw on it here to remove the other test - - // Execute to start the withdrawl countdown - // juno.ExecuteContract(ctx, withdrawUser.KeyName, contractAddr, `{"start_withdraw":{}}`) - - fmt.Print("juno RPC: ", juno.GetHostRPCAddress()) - if err := testutil.WaitForBlocks(ctx, 50, juno); err != nil { - t.Fatal(err) - } - - // make a query with GetUnityContractWithdrawalReadyTime - res := helpers.GetUnityContractWithdrawalReadyTime(t, ctx, juno, contractAddr) - t.Log("WithdrawalReadyTimestamp", res.Data.WithdrawalReadyTimestamp) - t.Cleanup(func() { _ = ic.Close() }) From 64b40e97db33634caffe45e8a210ac7bfd9782d6 Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Wed, 10 May 2023 15:18:14 -0500 Subject: [PATCH 075/131] lint --- app/upgrades/v15/upgrades.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/app/upgrades/v15/upgrades.go b/app/upgrades/v15/upgrades.go index ae5c765ff..cd48aa9f5 100644 --- a/app/upgrades/v15/upgrades.go +++ b/app/upgrades/v15/upgrades.go @@ -30,6 +30,9 @@ func CreateV15UpgradeHandler( // Run migrations logger.Info(fmt.Sprintf("pre migrate version map: %v", vm)) versionMap, err := mm.RunMigrations(ctx, cfg, vm) + if err != nil { + return nil, err + } logger.Info(fmt.Sprintf("post migrate version map: %v", versionMap)) // x/Mint @@ -52,7 +55,10 @@ func CreateV15UpgradeHandler( // Double slashing window due to double blocks per year slashingParams := keepers.SlashingKeeper.GetParams(ctx) slashingParams.SignedBlocksWindow *= 2 - keepers.SlashingKeeper.SetParams(ctx, slashingParams) + err = keepers.SlashingKeeper.SetParams(ctx, slashingParams) + if err != nil { + return nil, err + } return versionMap, err } From e1183eb692f6c7bd04e147ced6d1cc7e0887bcdb Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Wed, 10 May 2023 15:26:30 -0500 Subject: [PATCH 076/131] modified v15 upgrade handler (ICQ + consensus modules). Normal block times --- app/upgrades/v15/constants.go | 10 ++++++++- app/upgrades/v15/upgrades.go | 40 ++++++++++++++++++++++------------- cmd/junod/cmd/root.go | 3 +-- 3 files changed, 35 insertions(+), 18 deletions(-) diff --git a/app/upgrades/v15/constants.go b/app/upgrades/v15/constants.go index 97389b4a2..89a6bb20f 100644 --- a/app/upgrades/v15/constants.go +++ b/app/upgrades/v15/constants.go @@ -3,6 +3,9 @@ package v15 import ( "github.com/CosmosContracts/juno/v15/app/upgrades" store "github.com/cosmos/cosmos-sdk/store/types" + + consensustypes "github.com/cosmos/cosmos-sdk/x/consensus/types" + icqtypes "github.com/strangelove-ventures/async-icq/v7/types" ) // UpgradeName defines the on-chain upgrade name for the upgrade. @@ -11,5 +14,10 @@ const UpgradeName = "v15" var Upgrade = upgrades.Upgrade{ UpgradeName: UpgradeName, CreateUpgradeHandler: CreateV15UpgradeHandler, - StoreUpgrades: store.StoreUpgrades{}, + StoreUpgrades: store.StoreUpgrades{ + Added: []string{ + icqtypes.ModuleName, + consensustypes.ModuleName, + }, + }, } diff --git a/app/upgrades/v15/upgrades.go b/app/upgrades/v15/upgrades.go index cd48aa9f5..cc53108b0 100644 --- a/app/upgrades/v15/upgrades.go +++ b/app/upgrades/v15/upgrades.go @@ -11,6 +11,8 @@ import ( tokenfactorytypes "github.com/CosmosContracts/juno/v15/x/tokenfactory/types" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" + + icqtypes "github.com/strangelove-ventures/async-icq/v7/types" ) // We now charge 2 million gas * gas price to create a denom. @@ -35,12 +37,11 @@ func CreateV15UpgradeHandler( } logger.Info(fmt.Sprintf("post migrate version map: %v", versionMap)) - // x/Mint - // Double blocks per year (from 6 seconds to 3 = 2x blocks per year) - mintParams := keepers.MintKeeper.GetParams(ctx) - mintParams.BlocksPerYear *= 2 - keepers.MintKeeper.SetParams(ctx, mintParams) - logger.Info(fmt.Sprintf("updated minted blocks per year logic to %v", mintParams)) + // Anything to do with ConsensusParamsKeeper? + + // Interchain Queries + icqParams := icqtypes.NewParams(true, nil) + keepers.ICQKeeper.SetParams(ctx, icqParams) // x/TokenFactory // Use denom creation gas consumtion instead of fee for contract developers @@ -51,15 +52,24 @@ func CreateV15UpgradeHandler( keepers.TokenFactoryKeeper.SetParams(ctx, updatedTf) logger.Info(fmt.Sprintf("updated tokenfactory params to %v", updatedTf)) - // x/Slashing - // Double slashing window due to double blocks per year - slashingParams := keepers.SlashingKeeper.GetParams(ctx) - slashingParams.SignedBlocksWindow *= 2 - err = keepers.SlashingKeeper.SetParams(ctx, slashingParams) - if err != nil { - return nil, err - } - return versionMap, err } } + +// Previously planned Faster block time upgrade +// +// x/Mint +// Double blocks per year (from 6 seconds to 3 = 2x blocks per year) +// mintParams := keepers.MintKeeper.GetParams(ctx) +// mintParams.BlocksPerYear *= 2 +// keepers.MintKeeper.SetParams(ctx, mintParams) +// logger.Info(fmt.Sprintf("updated minted blocks per year logic to %v", mintParams)) +// +// x/Slashing +// Double slashing window due to double blocks per year +// slashingParams := keepers.SlashingKeeper.GetParams(ctx) +// slashingParams.SignedBlocksWindow *= 2 +// err = keepers.SlashingKeeper.SetParams(ctx, slashingParams) +// if err != nil { +// return nil, err +// } diff --git a/cmd/junod/cmd/root.go b/cmd/junod/cmd/root.go index 8acb171a2..dedd6c4a3 100644 --- a/cmd/junod/cmd/root.go +++ b/cmd/junod/cmd/root.go @@ -5,7 +5,6 @@ import ( "io" "os" "path/filepath" - "time" tmcfg "github.com/cometbft/cometbft/config" "github.com/prometheus/client_golang/prometheus" @@ -110,7 +109,7 @@ func initTendermintConfig() *tmcfg.Config { // cfg.P2P.MaxNumOutboundPeers = 40 // 2 seconds + 1 second tendermint = 3 second blocks (v15 upgrade) - cfg.Consensus.TimeoutCommit = 2 * time.Second + // cfg.Consensus.TimeoutCommit = 2 * time.Second return cfg } From 822f4ff7349155663772542952e9e039ce15516d Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Wed, 10 May 2023 16:16:27 -0500 Subject: [PATCH 077/131] initial ICTest conversion (v7 main) --- docker/setup_junod.sh | 4 +- interchaintest/chain_upgrade_test.go | 54 +++++---- interchaintest/contract_unity_deploy_test.go | 10 +- interchaintest/contract_unity_submit_test.go | 13 +-- interchaintest/go.mod | 66 +++++------ interchaintest/go.sum | 113 +++++++++---------- interchaintest/helpers/cosmwasm.go | 18 +-- interchaintest/helpers/feeshare.go | 10 +- interchaintest/helpers/query_helpers.go | 2 +- interchaintest/helpers/tokenfactory.go | 27 +++-- interchaintest/ibc_transfer_test.go | 8 +- interchaintest/module_feeshare_test.go | 6 +- interchaintest/module_tokenfactory_test.go | 12 +- interchaintest/setup.go | 31 ++--- 14 files changed, 178 insertions(+), 196 deletions(-) diff --git a/docker/setup_junod.sh b/docker/setup_junod.sh index bb313822e..700eb37f3 100755 --- a/docker/setup_junod.sh +++ b/docker/setup_junod.sh @@ -52,12 +52,12 @@ if ! junod keys show validator $KEYRING; then (echo "$PASSWORD"; echo "$PASSWORD") | junod keys add validator $KEYRING # hardcode the validator account for this instance - echo "$PASSWORD" | junod add-genesis-account validator "1000000000$STAKE,1000000000$FEE" $KEYRING + echo "$PASSWORD" | junod genesis add-genesis-account validator "1000000000$STAKE,1000000000$FEE" $KEYRING # (optionally) add a few more genesis accounts for addr in "$@"; do echo $addr - junod add-genesis-account "$addr" "1000000000$STAKE,1000000000$FEE" + junod genesis add-genesis-account "$addr" "1000000000$STAKE,1000000000$FEE" done # submit a genesis validator tx diff --git a/interchaintest/chain_upgrade_test.go b/interchaintest/chain_upgrade_test.go index 334edb1c6..aa6d9f1a7 100644 --- a/interchaintest/chain_upgrade_test.go +++ b/interchaintest/chain_upgrade_test.go @@ -22,8 +22,9 @@ const ( func TestBasicJunoUpgrade(t *testing.T) { repo, version := GetDockerImageInfo() + startVersion := "v14.1.0" upgradeName := "v15" - CosmosChainUpgradeTest(t, "juno", "v14.1.0", version, repo, upgradeName) + CosmosChainUpgradeTest(t, "juno", startVersion, version, repo, upgradeName) } func CosmosChainUpgradeTest(t *testing.T, chainName, initialVersion, upgradeBranchVersion, upgradeRepo, upgradeName string) { @@ -39,7 +40,7 @@ func CosmosChainUpgradeTest(t *testing.T, chainName, initialVersion, upgradeBran ChainName: chainName, Version: initialVersion, ChainConfig: ibc.ChainConfig{ - ModifyGenesis: cosmos.ModifyGenesisProposalTime(votingPeriod, maxDepositPeriod), + ModifyGenesis: modifyGenesisShortProposals(votingPeriod, maxDepositPeriod), Images: []ibc.DockerImage{ { Repository: JunoE2ERepo, @@ -91,20 +92,7 @@ func CosmosChainUpgradeTest(t *testing.T, chainName, initialVersion, upgradeBran Height: haltHeight, } - // TODO: Do a param change proposal to match mainnets '5048093' blocks per year rate? - // or just create a function to modify as a fork of cosmos.ModifyGenesisProposalTime. This should really be a builder yea? - - // !IMPORTANT: V15 - Query the current minting parameters - // param, _ := chain.QueryParam(ctx, "mint", "BlocksPerYear") - param, _ := chain.QueryParam(ctx, "mint", "BlocksPerYear") - require.NoError(t, err, "error querying blocks per year") - require.Equal(t, param.Value, "\"6311520\"") // mainnet it is 5048093, but we are just ensuring the upgrade applies correctly from default. - - param, err = chain.QueryParam(ctx, "slashing", "SignedBlocksWindow") - require.NoError(t, err, "error querying signed blocks window") - require.Equal(t, param.Value, "\"100\"") - - upgradeTx, err := chain.UpgradeProposal(ctx, chainUser.KeyName, proposal) + upgradeTx, err := chain.UpgradeProposal(ctx, chainUser.KeyName(), proposal) require.NoError(t, err, "error submitting software upgrade proposal tx") err = chain.VoteOnProposalAllValidators(ctx, upgradeTx.ProposalID, cosmos.ProposalVoteYes) @@ -132,13 +120,8 @@ func CosmosChainUpgradeTest(t *testing.T, chainName, initialVersion, upgradeBran err = chain.StopAllNodes(ctx) require.NoError(t, err, "error stopping node(s)") - // upgrade version amd repo on all nodes - for _, node := range chain.Nodes() { - node.Image.Repository = upgradeRepo - node.Image.Version = upgradeBranchVersion - } - - chain.UpgradeVersion(ctx, client, upgradeBranchVersion) + // upgrade version on all nodes + chain.UpgradeVersion(ctx, client, upgradeRepo, upgradeBranchVersion) // start all nodes back up. // validators reach consensus on first block after upgrade height @@ -157,6 +140,28 @@ func CosmosChainUpgradeTest(t *testing.T, chainName, initialVersion, upgradeBran require.GreaterOrEqual(t, height, haltHeight+blocksAfterUpgrade, "height did not increment enough after upgrade") + // TODO: ensure tokenfactory denom creation fee is set to 2_000_000 + +} + +// TODO: Future v16+ with faster block times, use these +/* + // TODO: Do a param change proposal to match mainnets '5048093' blocks per year rate? + // or just create a function to modify as a fork of cosmos.ModifyGenesisProposalTime. This should really be a builder yea? + + // !IMPORTANT: V15 Faster block times - Query the current minting parameters + // param, _ := chain.QueryParam(ctx, "mint", "BlocksPerYear") + param, _ := chain.QueryParam(ctx, "mint", "BlocksPerYear") + require.NoError(t, err, "error querying blocks per year") + require.Equal(t, param.Value, "\"6311520\"") // mainnet it is 5048093, but we are just ensuring the upgrade applies correctly from default. + + param, err = chain.QueryParam(ctx, "slashing", "SignedBlocksWindow") + require.NoError(t, err, "error querying signed blocks window") + require.Equal(t, param.Value, "\"100\"") + + + upgrade... + // !IMPORTANT: V15 - Query the current minting parameters param, err = chain.QueryParam(ctx, "mint", "BlocksPerYear") require.NoError(t, err, "error querying blocks per year") @@ -175,4 +180,5 @@ func CosmosChainUpgradeTest(t *testing.T, chainName, initialVersion, upgradeBran param, err = chain.QueryParam(ctx, "tokenfactory", "DenomCreationFee") require.NoError(t, err, "error querying denom creation fee") require.Equal(t, param.Value, "[]") -} + +*/ diff --git a/interchaintest/contract_unity_deploy_test.go b/interchaintest/contract_unity_deploy_test.go index a31ca1917..e2b7a9004 100644 --- a/interchaintest/contract_unity_deploy_test.go +++ b/interchaintest/contract_unity_deploy_test.go @@ -4,8 +4,8 @@ import ( "fmt" "testing" - "github.com/strangelove-ventures/interchaintest/v4" - "github.com/strangelove-ventures/interchaintest/v4/chain/cosmos" + "github.com/strangelove-ventures/interchaintest/v7" + "github.com/strangelove-ventures/interchaintest/v7/chain/cosmos" helpers "github.com/CosmosContracts/juno/tests/interchaintest/helpers" ) @@ -27,16 +27,16 @@ func TestJunoUnityContractDeploy(t *testing.T) { users := interchaintest.GetAndFundTestUsers(t, ctx, "default", int64(10_000_000), juno, juno) user := users[0] withdrawUser := users[1] - withdrawAddr := withdrawUser.Bech32Address(juno.Config().Bech32Prefix) + withdrawAddr := withdrawUser.FormattedAddress() // TEST DEPLOY (./scripts/deploy_ci.sh) // Upload & init unity contract with no admin in test mode msg := fmt.Sprintf(`{"native_denom":"%s","withdraw_address":"%s","withdraw_delay_in_days":28}`, nativeDenom, withdrawAddr) - _, contractAddr := helpers.SetupContract(t, ctx, juno, user.KeyName, "contracts/cw_unity_prop.wasm", msg) + _, contractAddr := helpers.SetupContract(t, ctx, juno, user.KeyName(), "contracts/cw_unity_prop.wasm", msg) t.Log("testing Unity contractAddr", contractAddr) // Execute to start the withdrawl countdown - juno.ExecuteContract(ctx, withdrawUser.KeyName, contractAddr, `{"start_withdraw":{}}`) + juno.ExecuteContract(ctx, withdrawUser.KeyName(), contractAddr, `{"start_withdraw":{}}`) // make a query with GetUnityContractWithdrawalReadyTime res := helpers.GetUnityContractWithdrawalReadyTime(t, ctx, juno, contractAddr) diff --git a/interchaintest/contract_unity_submit_test.go b/interchaintest/contract_unity_submit_test.go index d25441c4f..ecd92c974 100644 --- a/interchaintest/contract_unity_submit_test.go +++ b/interchaintest/contract_unity_submit_test.go @@ -4,10 +4,9 @@ import ( "fmt" "testing" - "github.com/strangelove-ventures/interchaintest/v4" - "github.com/strangelove-ventures/interchaintest/v4/chain/cosmos" - "github.com/strangelove-ventures/interchaintest/v4/ibc" - "github.com/strangelove-ventures/interchaintest/v4/testutil" + "github.com/strangelove-ventures/interchaintest/v7" + "github.com/strangelove-ventures/interchaintest/v7/chain/cosmos" + "github.com/strangelove-ventures/interchaintest/v7/ibc" "github.com/stretchr/testify/require" helpers "github.com/CosmosContracts/juno/tests/interchaintest/helpers" @@ -31,15 +30,15 @@ func TestJunoUnityContractGovSubmit(t *testing.T) { users := interchaintest.GetAndFundTestUsers(t, ctx, "default", int64(10000_000000), juno, juno) user := users[0] withdrawUser := users[1] - withdrawAddr := withdrawUser.Bech32Address(juno.Config().Bech32Prefix) + withdrawAddr := withdrawUser.FormattedAddress() // Upload & init unity contract with no admin in test mode msg := fmt.Sprintf(`{"native_denom":"%s","withdraw_address":"%s","withdraw_delay_in_days":28}`, nativeDenom, withdrawAddr) - _, contractAddr := helpers.SetupContract(t, ctx, juno, user.KeyName, "contracts/cw_unity_prop.wasm", msg) + _, contractAddr := helpers.SetupContract(t, ctx, juno, user.KeyName(), "contracts/cw_unity_prop.wasm", msg) t.Log("testing Unity contractAddr", contractAddr) // send 2JUNO funds to the contract from user - juno.SendFunds(ctx, user.KeyName, ibc.WalletAmount{Address: contractAddr, Denom: nativeDenom, Amount: 2000000}) + juno.SendFunds(ctx, user.KeyName(), ibc.WalletAmount{Address: contractAddr, Denom: nativeDenom, Amount: 2000000}) height, err := juno.Height(ctx) require.NoError(t, err, "error fetching height") diff --git a/interchaintest/go.mod b/interchaintest/go.mod index dba971742..a1b07f2b8 100644 --- a/interchaintest/go.mod +++ b/interchaintest/go.mod @@ -3,27 +3,28 @@ module github.com/CosmosContracts/juno/tests/interchaintest go 1.19 replace ( + // interchaintest supports ICS features so we need this for now + // github.com/cosmos/cosmos-sdk => github.com/cosmos/cosmos-sdk v0.45.13-ics github.com/ChainSafe/go-schnorrkel => github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d github.com/ChainSafe/go-schnorrkel/1 => github.com/ChainSafe/go-schnorrkel v1.0.0 - // For this nested module, you always want to replace the parent reference with the current worktree. - github.com/CosmosContracts/juno => ../ + // For now, we can not do this due to pulling tokenfactory in. + // github.com/CosmosContracts/juno => ../../ + github.com/CosmosContracts/juno/v15 => github.com/CosmosContracts/juno/v15 v15.0.0-20230510202630-e1183eb692f6 github.com/btcsuite/btcd => github.com/btcsuite/btcd v0.22.2 //indirect - - // interchaintest supports ICS features so we need this for now - github.com/cosmos/cosmos-sdk => github.com/cosmos/cosmos-sdk v0.45.15-ics github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 - - // github.com/tendermint/tendermint => github.com/informalsystems/tendermint v0.34.17 - github.com/tendermint/tendermint => github.com/skip-mev/mev-cometbft v0.34.27-mev.18 - github.com/vedhavyas/go-subkey => github.com/strangelove-ventures/go-subkey v1.0.7 ) require ( - cosmossdk.io/simapp v0.0.0-20230224204036-a6adb0821462 + // cosmossdk.io/simapp v0.0.0-20230224204036-a6adb0821462 + github.com/CosmWasm/wasmd v0.40.0-rc.1.0.20230422061626-b85abcf1d7b8 + github.com/CosmosContracts/juno/v15 v15.0.0-00010101000000-000000000000 + github.com/cosmos/cosmos-sdk v0.47.2 github.com/cosmos/ibc-go/v7 v7.0.0 - github.com/strangelove-ventures/interchaintest/v7 v7.0.0-20230428012002-db902d82df33 + github.com/docker/docker v20.10.19+incompatible + github.com/icza/dyno v0.0.0-20220812133438-f0b6f8a18845 + github.com/strangelove-ventures/interchaintest/v7 v7.0.0-20230508154211-ebc1cbd6d88e github.com/stretchr/testify v1.8.2 go.uber.org/zap v1.24.0 @@ -48,6 +49,7 @@ require ( github.com/ChainSafe/go-schnorrkel v1.0.0 // indirect github.com/ChainSafe/go-schnorrkel/1 v0.0.0-00010101000000-000000000000 // indirect github.com/ComposableFi/go-subkey/v2 v2.0.0-tm03420 // indirect + github.com/CosmWasm/wasmvm v1.2.3 // indirect github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e // indirect github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec // indirect github.com/Microsoft/go-winio v0.6.0 // indirect @@ -60,6 +62,7 @@ require ( github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816 // indirect github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect + github.com/bufbuild/protocompile v0.5.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.2.0 // indirect @@ -69,15 +72,13 @@ require ( github.com/cometbft/cometbft-db v0.7.0 // indirect github.com/confio/ics23/go v0.9.0 // indirect github.com/cosmos/btcutil v1.0.5 // indirect - github.com/cosmos/cosmos-db v0.0.0-20221226095112-f3c38ecb5e32 // indirect github.com/cosmos/cosmos-proto v1.0.0-beta.2 // indirect - github.com/cosmos/cosmos-sdk v0.47.1 // indirect github.com/cosmos/go-bip39 v1.0.0 // indirect github.com/cosmos/gogogateway v1.2.0 // indirect github.com/cosmos/gogoproto v1.4.8 // indirect github.com/cosmos/iavl v0.20.0 // indirect - github.com/cosmos/ics23/go v0.9.1-0.20221207100636-b1abd8678aab // indirect - github.com/cosmos/ledger-cosmos-go v0.12.1 // indirect + github.com/cosmos/ics23/go v0.10.0 // indirect + github.com/cosmos/ledger-cosmos-go v0.12.2 // indirect github.com/cosmos/rosetta-sdk-go v0.10.0 // indirect github.com/creachadair/taskgroup v0.4.2 // indirect github.com/danieljoos/wincred v1.1.2 // indirect @@ -99,10 +100,10 @@ require ( github.com/ethereum/go-ethereum v1.10.20 // indirect github.com/felixge/httpsnoop v1.0.2 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect - github.com/getsentry/sentry-go v0.17.0 // indirect github.com/go-kit/kit v0.12.0 // indirect github.com/go-kit/log v0.2.1 // indirect github.com/go-logfmt/logfmt v0.6.0 // indirect + github.com/go-playground/universal-translator v0.18.0 // indirect github.com/go-stack/stack v1.8.1 // indirect github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect github.com/gogo/googleapis v1.4.1 // indirect @@ -127,7 +128,7 @@ require ( 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.7.0 // indirect + github.com/hashicorp/go-getter v1.7.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 @@ -135,23 +136,22 @@ require ( github.com/hashicorp/hcl v1.0.0 // indirect github.com/hdevalence/ed25519consensus v0.1.0 // indirect github.com/huandu/skiplist v1.2.0 // indirect - github.com/icza/dyno v0.0.0-20220812133438-f0b6f8a18845 // indirect github.com/improbable-eng/grpc-web v0.15.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/ipfs/go-cid v0.2.0 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/jmhodges/levigo v1.0.0 // indirect - github.com/json-iterator/go v1.1.12 // indirect github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect github.com/klauspost/compress v1.16.3 // indirect github.com/klauspost/cpuid/v2 v2.2.3 // indirect + github.com/leodido/go-urn v1.2.1 // indirect github.com/lib/pq v1.10.7 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/libp2p/go-libp2p v0.22.0 // indirect github.com/libp2p/go-openssl v0.1.0 // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/manifoldco/promptui v0.9.0 // indirect - github.com/mattn/go-isatty v0.0.17 // indirect + github.com/mattn/go-isatty v0.0.18 // indirect github.com/mattn/go-pointer v0.0.1 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/mimoo/StrobeGo v0.0.0-20220103164710-9a04d6ca976b // indirect @@ -161,8 +161,6 @@ require ( github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/go-testing-interface v1.14.1 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect - github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect - github.com/modern-go/reflect2 v1.0.2 // indirect github.com/mr-tron/base58 v1.2.0 // indirect github.com/mtibben/percent v0.2.1 // indirect github.com/multiformats/go-base32 v0.0.4 // indirect @@ -182,7 +180,7 @@ require ( github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/client_golang v1.15.0 // indirect github.com/prometheus/client_model v0.3.0 // indirect - github.com/prometheus/common v0.40.0 // indirect + github.com/prometheus/common v0.42.0 // indirect github.com/prometheus/procfs v0.9.0 // indirect github.com/rakyll/statik v0.1.7 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect @@ -205,6 +203,7 @@ require ( github.com/tidwall/btree v1.6.0 // indirect github.com/tyler-smith/go-bip32 v1.0.0 // indirect github.com/tyler-smith/go-bip39 v1.1.0 // indirect + github.com/ugorji/go/codec v1.2.7 // indirect github.com/ulikunitz/xz v0.5.11 // indirect github.com/zondax/hid v0.9.1 // indirect github.com/zondax/ledger-go v0.14.1 // indirect @@ -225,7 +224,7 @@ require ( golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect google.golang.org/api v0.110.0 // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto v0.0.0-20230216225411-c8e22ba71e44 // indirect + google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 // indirect google.golang.org/grpc v1.54.0 // indirect google.golang.org/protobuf v1.30.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect @@ -236,27 +235,14 @@ require ( lukechampine.com/uint128 v1.2.0 // indirect modernc.org/cc/v3 v3.40.0 // indirect modernc.org/ccgo/v3 v3.16.13 // indirect - modernc.org/libc v1.22.4 // indirect + modernc.org/libc v1.22.5 // indirect modernc.org/mathutil v1.5.0 // indirect modernc.org/memory v1.5.0 // indirect modernc.org/opt v0.1.3 // indirect - modernc.org/sqlite v1.22.0 // indirect + modernc.org/sqlite v1.22.1 // indirect modernc.org/strutil v1.1.3 // indirect modernc.org/token v1.0.1 // indirect - nhooyr.io/websocket v1.8.6 // indirect + nhooyr.io/websocket v1.8.7 // indirect pgregory.net/rapid v0.5.5 // indirect sigs.k8s.io/yaml v1.3.0 // indirect ) - -replace ( - - // interchaintest supports ICS features so we need this for now - github.com/cosmos/cosmos-sdk => github.com/cosmos/cosmos-sdk v0.45.15-ics - github.com/ChainSafe/go-schnorrkel => github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d - github.com/ChainSafe/go-schnorrkel/1 => github.com/ChainSafe/go-schnorrkel v1.0.0 - // For this nested module, you always want to replace the parent reference with the current worktree. - github.com/CosmosContracts/juno => ../../ - github.com/btcsuite/btcd => github.com/btcsuite/btcd v0.22.2 //indirect - github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 - github.com/vedhavyas/go-subkey => github.com/strangelove-ventures/go-subkey v1.0.7 -) diff --git a/interchaintest/go.sum b/interchaintest/go.sum index 64936d661..e8bf8d654 100644 --- a/interchaintest/go.sum +++ b/interchaintest/go.sum @@ -117,7 +117,7 @@ cloud.google.com/go/language v1.4.0/go.mod h1:F9dRpNFQmJbkaop6g0JhSBXCNlO90e1KWx cloud.google.com/go/language v1.6.0/go.mod h1:6dJ8t3B+lUYfStgls25GusK04NLh3eDLQnWM3mdEbhI= cloud.google.com/go/lifesciences v0.5.0/go.mod h1:3oIKy8ycWGPUyZDR/8RNnTOYevhaMLqh5vLUXs9zvT8= cloud.google.com/go/lifesciences v0.6.0/go.mod h1:ddj6tSX/7BOnhxCSd3ZcETvtNr8NZ6t/iPhY2Tyfu08= -cloud.google.com/go/longrunning v0.3.0 h1:NjljC+FYPV3uh5/OwWT6pVU+doBqMg2x/rZlE+CamDs= +cloud.google.com/go/longrunning v0.4.1 h1:v+yFJOfKC3yZdY6ZUI933pIYdhyhV8S3NpWrXWmg7jM= cloud.google.com/go/mediatranslation v0.5.0/go.mod h1:jGPUhGTybqsPQn91pNXw0xVHfuJ3leR1wj37oU3y1f4= cloud.google.com/go/mediatranslation v0.6.0/go.mod h1:hHdBCTYNigsBxshbznuIMFNe5QXEowAuNmmC7h8pu5w= cloud.google.com/go/memcache v1.4.0/go.mod h1:rTOfiGZtJX1AaFUrOgsMHX5kAzaTQ8azHiuDoTPzNsE= @@ -198,8 +198,6 @@ 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 h1:ro9w7eKx23om2tZz/VM2Pf+z2WAbGX1yDQQOJ6iGeJw= cosmossdk.io/math v1.0.0/go.mod h1:Ygz4wBHrgc7g0N+8+MrnTfS9LLn9aaTGa9hKopuym5k= -cosmossdk.io/simapp v0.0.0-20230224204036-a6adb0821462 h1:g8muUHnXL8vhld2Sjilyhb1UQObc+x9GVuDK43TYZns= -cosmossdk.io/simapp v0.0.0-20230224204036-a6adb0821462/go.mod h1:4Dd3NLoLYoN90kZ0uyHoTHzVVk9+J0v4HhZRBNTAq2c= cosmossdk.io/tools/rosetta v0.2.1 h1:ddOMatOH+pbxWbrGJKRAawdBkPYLfKXutK9IETnjYxw= cosmossdk.io/tools/rosetta v0.2.1/go.mod h1:Pqdc1FdvkNV3LcNIkYWt2RQY6IP1ge6YWZk8MhhO9Hw= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= @@ -220,6 +218,12 @@ github.com/ChainSafe/go-schnorrkel v1.0.0 h1:3aDA67lAykLaG1y3AOjs88dMxC88PgUuHRr github.com/ChainSafe/go-schnorrkel v1.0.0/go.mod h1:dpzHYVxLZcp8pjlV+O+UR8K0Hp/z7vcchBSbMBEhCw4= github.com/ComposableFi/go-subkey/v2 v2.0.0-tm03420 h1:oknQF/iIhf5lVjbwjsVDzDByupRhga8nhA3NAmwyHDA= github.com/ComposableFi/go-subkey/v2 v2.0.0-tm03420/go.mod h1:KYkiMX5AbOlXXYfxkrYPrRPV6EbVUALTQh5ptUOJzu8= +github.com/CosmWasm/wasmd v0.40.0-rc.1.0.20230422061626-b85abcf1d7b8 h1:daJIcrTcYkpDtn1DXqbGhnQkCPSD93El6mXfv15VJRA= +github.com/CosmWasm/wasmd v0.40.0-rc.1.0.20230422061626-b85abcf1d7b8/go.mod h1:uacdue6EGn9JA1TqBNHB3iCe4PCIChuFT23AzIl2VME= +github.com/CosmWasm/wasmvm v1.2.3 h1:OKYlobwmVGbl0eSn0mXoAAjE5hIuXnQCLPjbNd91sVY= +github.com/CosmWasm/wasmvm v1.2.3/go.mod h1:vW/E3h8j9xBQs9bCoijDuawKo9kCtxOaS8N8J7KFtkc= +github.com/CosmosContracts/juno/v15 v15.0.0-20230510202630-e1183eb692f6 h1:7565R2VLJw+Lq5hTu5YKyluu/FD7CGaolXwAQzMQwAo= +github.com/CosmosContracts/juno/v15 v15.0.0-20230510202630-e1183eb692f6/go.mod h1:+Pm43R0RcChyzTn9X0OrkMkifM502S6OQUQl1dzRNlM= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e h1:ahyvB3q25YnZWly5Gq1ekg6jcmWaGj/vG/MhF4aisoc= github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:kGUqhHd//musdITWjFvNTHn90WG9bMLBEPQZ17Cmlpw= @@ -280,6 +284,8 @@ github.com/btcsuite/btcd/btcec/v2 v2.3.2/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY github.com/btcsuite/btcd/btcutil v1.1.2 h1:XLMbX8JQEiwMcYft2EGi8zPUkoa0abKIU6/BJSRsjzQ= github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U= github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce h1:YtWJF7RHm2pYCvA5t0RPmAaLUhREsKuKd+SLhxFbFeQ= +github.com/bufbuild/protocompile v0.5.1 h1:mixz5lJX4Hiz4FpqFREJHIXLfaLBntfaJv1h+/jS+Qg= +github.com/bufbuild/protocompile v0.5.1/go.mod h1:G5iLmavmF4NsYtpZFvE3B/zFch2GIY8+wjsYLR/lc40= 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= @@ -337,12 +343,10 @@ github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7 github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cosmos/btcutil v1.0.5 h1:t+ZFcX77LpKtDBhjucvnOH8C2l2ioGsBNEQ3jef8xFk= github.com/cosmos/btcutil v1.0.5/go.mod h1:IyB7iuqZMJlthe2tkIFL33xPyzbFYP0XVdS8P5lUPis= -github.com/cosmos/cosmos-db v0.0.0-20221226095112-f3c38ecb5e32 h1:zlCp9n3uwQieELltZWHRmwPmPaZ8+XoL2Sj+A2YJlr8= -github.com/cosmos/cosmos-db v0.0.0-20221226095112-f3c38ecb5e32/go.mod h1:kwMlEC4wWvB48zAShGKVqboJL6w4zCLesaNQ3YLU2BQ= github.com/cosmos/cosmos-proto v1.0.0-beta.2 h1:X3OKvWgK9Gsejo0F1qs5l8Qn6xJV/AzgIWR2wZ8Nua8= github.com/cosmos/cosmos-proto v1.0.0-beta.2/go.mod h1:+XRCLJ14pr5HFEHIUcn51IKXD1Fy3rkEQqt4WqmN4V0= -github.com/cosmos/cosmos-sdk v0.47.1 h1:HnaCYtaAMWZp1SdlwwE1mPJ8kFlZ/TuEJ/ciNXH6Uno= -github.com/cosmos/cosmos-sdk v0.47.1/go.mod h1:14tO5KQaTrl2q3OxBnDRfue7TRN9zkXS0cLutrSqkOo= +github.com/cosmos/cosmos-sdk v0.47.2 h1:9rSriCoiJD+4F+tEDobyM8V7HF5BtY5Ef4VYNig96s0= +github.com/cosmos/cosmos-sdk v0.47.2/go.mod h1:zYzgI8w8hhotXTSoGbbSOAKfpJTx4wOy4XgbaKhtRtc= 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= @@ -355,13 +359,14 @@ github.com/cosmos/iavl v0.20.0 h1:fTVznVlepH0KK8NyKq8w+U7c2L6jofa27aFX6YGlm38= github.com/cosmos/iavl v0.20.0/go.mod h1:WO7FyvaZJoH65+HFOsDir7xU9FWk2w9cHXNW1XHcl7A= github.com/cosmos/ibc-go/v7 v7.0.0 h1:j4kyywlG0hhDmT9FmSaR5iCIka7Pz7kJTxGWY1nlV9Q= github.com/cosmos/ibc-go/v7 v7.0.0/go.mod h1:BFh8nKWjr5zeR2OZfhkzdgDzj1+KjRn3aJLpwapStj8= -github.com/cosmos/ics23/go v0.9.1-0.20221207100636-b1abd8678aab h1:I9ialKTQo7248V827Bba4OuKPmk+FPzmTVHsLXaIJWw= -github.com/cosmos/ics23/go v0.9.1-0.20221207100636-b1abd8678aab/go.mod h1:2CwqasX5dSD7Hbp/9b6lhK6BwoBDCBldx7gPKRukR60= -github.com/cosmos/ledger-cosmos-go v0.12.1 h1:sMBxza5p/rNK/06nBSNmsI/WDqI0pVJFVNihy1Y984w= -github.com/cosmos/ledger-cosmos-go v0.12.1/go.mod h1:dhO6kj+Y+AHIOgAe4L9HL/6NDdyyth4q238I9yFpD2g= +github.com/cosmos/ics23/go v0.10.0 h1:iXqLLgp2Lp+EdpIuwXTYIQU+AiHj9mOC2X9ab++bZDM= +github.com/cosmos/ics23/go v0.10.0/go.mod h1:ZfJSmng/TBNTBkFemHHHj5YY7VAU/MBU980F4VU1NG0= +github.com/cosmos/ledger-cosmos-go v0.12.2 h1:/XYaBlE2BJxtvpkHiBm97gFGSGmYGKunKyF3nNqAXZA= +github.com/cosmos/ledger-cosmos-go v0.12.2/go.mod h1:ZcqYgnfNJ6lAXe4HPtWgarNEY+B74i+2/8MhZw4ziiI= github.com/cosmos/rosetta-sdk-go v0.10.0 h1:E5RhTruuoA7KTIXUcMicL76cffyeoyvNybzUGSKFTcM= github.com/cosmos/rosetta-sdk-go v0.10.0/go.mod h1:SImAZkb96YbwvoRkzSMQB6noNJXFgWl/ENIznEoYQI4= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= +github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creachadair/taskgroup v0.4.2 h1:jsBLdAJE42asreGss2xZGZ8fJra7WtwnHWeJFxv2Li8= github.com/creachadair/taskgroup v0.4.2/go.mod h1:qiXUOSrbwAY3u0JPGTzObbE3yf9hcXHDKBZ2ZjpCbgM= @@ -430,8 +435,7 @@ github.com/ethereum/go-ethereum v1.10.20/go.mod h1:LWUN82TCHGpxB3En5HVmLLzPD7YSr 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/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= -github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= +github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/felixge/httpsnoop v1.0.2 h1:+nS9g82KMXccJ/wp0zyRW9ZBHFETmMGtkk+2CTTrW4o= github.com/felixge/httpsnoop v1.0.2/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= @@ -466,10 +470,12 @@ github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= 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= -github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no= +github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU= +github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs= github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= +github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho= +github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA= github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= github.com/go-playground/validator/v10 v10.11.1 h1:prmOlTVv+YjZjmRmNSF3VmspqJIxJWXmqUsHwfTRRkQ= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= @@ -554,7 +560,6 @@ github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8 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/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= 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.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= @@ -640,8 +645,8 @@ github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtng 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.7.0 h1:bzrYP+qu/gMrL1au7/aDvkoOVGUJpeKBgbqRHACAFDY= -github.com/hashicorp/go-getter v1.7.0/go.mod h1:W7TalhMmbPmsSMdNjD0ZskARur/9GJ17cfHTRtXV744= +github.com/hashicorp/go-getter v1.7.1 h1:SWiSWN/42qdpR0MdhaOc/bLR48PLuP1ZQtYLRlM69uY= +github.com/hashicorp/go-getter v1.7.1/go.mod h1:W7TalhMmbPmsSMdNjD0ZskARur/9GJ17cfHTRtXV744= 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= @@ -682,7 +687,6 @@ 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/icza/dyno v0.0.0-20220812133438-f0b6f8a18845 h1:H+uM0Bv88eur3ZSsd2NGKg3YIiuXxwxtlN7HjE66UTU= github.com/icza/dyno v0.0.0-20220812133438-f0b6f8a18845/go.mod h1:c1tRKs5Tx7E2+uHGSyyncziFjvGpgv4H2HrqXeUQ/Uk= -github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= 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= @@ -691,7 +695,7 @@ github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLf github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= github.com/ipfs/go-cid v0.2.0 h1:01JTiihFq9en9Vz0lc0VDWvZe/uBonGpzo4THP0vcQ0= github.com/ipfs/go-cid v0.2.0/go.mod h1:P+HXFDF4CVhaVayiEb4wkAy7zBHxBwsJyt0Y5U6MLro= -github.com/jhump/protoreflect v1.12.1-0.20220721211354-060cc04fc18b h1:izTof8BKh/nE1wrKOrloNA5q4odOarjf+Xpe+4qow98= +github.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c= 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= @@ -707,13 +711,9 @@ github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/u github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= -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/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/juju/errors v0.0.0-20181118221551-089d3ea4e4d5/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q= -github.com/juju/loggo v0.0.0-20180524022052-584905176618/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U= -github.com/juju/testing v0.0.0-20180920084828-472a3e8b2073/go.mod h1:63prj8cnj0tU0S9OHjGJn+b1h0ZghCndfnbQolrYTwA= 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/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= @@ -731,16 +731,17 @@ github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa02 github.com/klauspost/cpuid/v2 v2.2.3 h1:sxCkb+qR91z4vsqw4vGGZlDgPz3G7gjaLyK3V8y70BU= github.com/klauspost/cpuid/v2 v2.2.3/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= 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.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= 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/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/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= +github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw= github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= @@ -761,8 +762,8 @@ github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaO 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.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= -github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.18 h1:DOKFKCQ7FNG2L1rbrmstDN4QVRdS89Nkh85u68Uwp98= +github.com/mattn/go-isatty v0.0.18/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-pointer v0.0.1 h1:n+XhsuGeVO6MEAp7xyEukFINEa+Quek5psIR/ylA6o0= github.com/mattn/go-pointer v0.0.1/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= @@ -801,7 +802,6 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= 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/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= @@ -900,8 +900,8 @@ github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5Fsn github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -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_golang v1.15.0 h1:5fCgGYogn0hFdhyhLbw7hEsWxufKtY9klyvdNfFlFhM= +github.com/prometheus/client_golang v1.15.0/go.mod h1:e9yaBhRPU2pPNsZwE+JdQl0KEt1N9XgF6zxWmaC0xOk= 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= @@ -916,8 +916,8 @@ github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt2 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= github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= -github.com/prometheus/common v0.40.0 h1:Afz7EVRqGg2Mqqf4JuF9vdvp1pi220m55Pi9T2JnO4Q= -github.com/prometheus/common v0.40.0/go.mod h1:L65ZJPSmfn/UBWLQIHV7dBrKFidB/wPlF1y5TlSt9OE= +github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM= +github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= @@ -940,13 +940,12 @@ github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qq 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/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= -github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/rs/cors v1.8.3 h1:O+qNyWn7Z+F9M0ILBHgMVPuB1xTOucVd5gtaYyXBpRo= github.com/rs/cors v1.8.3/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= 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= @@ -961,8 +960,6 @@ github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrf github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/skip-mev/mev-cometbft v0.34.27-mev.18 h1:xoZRzzW4u4Rr4jjXUz7y05AoDZu8W5dGvgeg7jxrt0U= -github.com/skip-mev/mev-cometbft v0.34.27-mev.18/go.mod h1:BcCbhKv7ieM0KEddnYXvQZR+pZykTKReJJYf7YC7qhw= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= @@ -978,11 +975,10 @@ github.com/spf13/afero v1.9.3/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcD 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= +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.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= -github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= -github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= 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= @@ -995,6 +991,8 @@ github.com/spf13/viper v1.15.0 h1:js3yy885G8xwJa6iOISGFwd+qlUo5AvyXb7CiihdtiU= github.com/spf13/viper v1.15.0/go.mod h1:fFcTBJxvhhzSJiZy8n+PeW6t8l+KeT/uTARa0jHOQLA= github.com/strangelove-ventures/interchaintest/v7 v7.0.0-20230428012002-db902d82df33 h1:QG9pAXSiNhCBiYoiImCtMsY0oI3vG7B/vltQJyarfEU= github.com/strangelove-ventures/interchaintest/v7 v7.0.0-20230428012002-db902d82df33/go.mod h1:iX6tg3V6mH64h37ZvLuJa7lp9GbmFixTMlVu6Gilb/Q= +github.com/strangelove-ventures/interchaintest/v7 v7.0.0-20230508154211-ebc1cbd6d88e h1:Hxs0PZQhAtgkyqgl3bTXYkhhYX8OXvHr7z6CjSBclpo= +github.com/strangelove-ventures/interchaintest/v7 v7.0.0-20230508154211-ebc1cbd6d88e/go.mod h1:/FpoaMKTF3OREchZZvg6eGfVYvk7lAwqP9q2TN+lOGs= 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= @@ -1034,11 +1032,12 @@ github.com/tyler-smith/go-bip32 v1.0.0 h1:sDR9juArbUgX+bO/iblgZnMPeWY1KZMUC2AFUJ github.com/tyler-smith/go-bip32 v1.0.0/go.mod h1:onot+eHknzV4BVPwrzqY5OoVpyCvnwD7lMawL5aQupE= github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= -github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= +github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M= 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/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= +github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= github.com/ulikunitz/xz v0.5.10/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/ulikunitz/xz v0.5.11 h1:kpFauv27b6ynzBNT/Xy+1k+fK4WswhN/6PN5WhFAGw8= github.com/ulikunitz/xz v0.5.11/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= @@ -1046,10 +1045,6 @@ github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijb github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= -github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= -github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= -github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= -github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc= 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= @@ -1102,12 +1097,10 @@ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 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-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/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.8.0 h1:pd9TJtTueMTVQXzk8E2XESSMQDj/U7OUu0PqJqPXQjQ= golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= @@ -1138,7 +1131,6 @@ golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPI 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/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/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= @@ -1164,7 +1156,6 @@ golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -1202,7 +1193,7 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211008194852-3b03d305991f/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= @@ -1303,6 +1294,8 @@ golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +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-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1350,10 +1343,10 @@ golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/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/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -1380,13 +1373,11 @@ golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.1.0 h1:xYY+Bajn2a7VBmTM5GikTmnK8ZuX8YgnQCqZpbBNtmA= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/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-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/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= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190327201419-c70d86f8b7cf/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= @@ -1512,7 +1503,6 @@ google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCID 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-20180518175338-11a468237815/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= 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= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= @@ -1622,8 +1612,8 @@ google.golang.org/genproto v0.0.0-20221010155953-15ba04fc1c0e/go.mod h1:3526vdqw google.golang.org/genproto v0.0.0-20221014173430-6e2ab493f96b/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= google.golang.org/genproto v0.0.0-20221014213838-99cd37c6964a/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= google.golang.org/genproto v0.0.0-20221025140454-527a21cfbd71/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= -google.golang.org/genproto v0.0.0-20230216225411-c8e22ba71e44 h1:EfLuoKW5WfkgVdDy7dTK8qSbH37AX5mj/MFh+bGPz14= -google.golang.org/genproto v0.0.0-20230216225411-c8e22ba71e44/go.mod h1:8B0gmkoRebU8ukX6HP+4wrVQUY1+6PkQ44BSyIlflHA= +google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 h1:DdoeryqhaXp1LtT/emMP1BRJPHHKFi5akj/nbx/zNTA= +google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= @@ -1689,7 +1679,6 @@ gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLks 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-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 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/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= @@ -1699,7 +1688,6 @@ gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMy gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce h1:+JknDZhAj8YMt7GC73Ei8pv4MzjDUNPHgQWJdtMAaDU= gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= @@ -1712,10 +1700,10 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20191120175047-4206685974f2/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= @@ -1744,6 +1732,8 @@ modernc.org/ccorpus v1.11.6 h1:J16RXiiqiCgua6+ZvQot4yUuUy8zxgqbqEEUuGPlISk= modernc.org/httpfs v1.0.6 h1:AAgIpFZRXuYnkjftxTAZwMIiwEqAfk8aVB2/oA6nAeM= modernc.org/libc v1.22.4 h1:wymSbZb0AlrjdAVX3cjreCHTPCpPARbQXNz6BHPzdwQ= modernc.org/libc v1.22.4/go.mod h1:jj+Z7dTNX8fBScMVNRAYZ/jF91K8fdT2hYMThc3YjBY= +modernc.org/libc v1.22.5 h1:91BNch/e5B0uPbJFgqbxXuOnxBQjlS//icfQEGmvyjE= +modernc.org/libc v1.22.5/go.mod h1:jj+Z7dTNX8fBScMVNRAYZ/jF91K8fdT2hYMThc3YjBY= modernc.org/mathutil v1.5.0 h1:rV0Ko/6SfM+8G+yKiyI830l3Wuz1zRutdslNoQ0kfiQ= modernc.org/mathutil v1.5.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= modernc.org/memory v1.5.0 h1:N+/8c5rE6EqugZwHii4IFsaJ7MUhoWX07J5tC/iI5Ds= @@ -1752,14 +1742,17 @@ modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4= modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= modernc.org/sqlite v1.22.0 h1:Uo+wEWePCspy4SAu0w2VbzUHEftOs7yoaWX/cYjsq84= modernc.org/sqlite v1.22.0/go.mod h1:cxbLkB5WS32DnQqeH4h4o1B0eMr8W/y8/RGuxQ3JsC0= +modernc.org/sqlite v1.22.1 h1:P2+Dhp5FR1RlVRkQ3dDfCiv3Ok8XPxqpe70IjYVA9oE= +modernc.org/sqlite v1.22.1/go.mod h1:OrDj17Mggn6MhE+iPbBNf7RGKODDE9NFT0f3EwDzJqk= modernc.org/strutil v1.1.3 h1:fNMm+oJklMGYfU9Ylcywl0CO5O6nTfaowNsh2wpPjzY= modernc.org/strutil v1.1.3/go.mod h1:MEHNA7PdEnEwLvspRMtWTNnp2nnyvMfkimT1NKNAGbw= modernc.org/tcl v1.15.1 h1:mOQwiEK4p7HruMZcwKTZPw/aqtGM4aY00uzWhlKKYws= modernc.org/token v1.0.1 h1:A3qvTqOwexpfZZeyI0FeGPDlSWX5pjZu9hF4lU+EKWg= modernc.org/token v1.0.1/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= modernc.org/z v1.7.0 h1:xkDw/KepgEjeizO2sNco+hqYkU12taxQFqPEmgm1GWE= -nhooyr.io/websocket v1.8.6 h1:s+C3xAMLwGmlI31Nyn/eAehUlZPwfYZu2JXM621Q5/k= nhooyr.io/websocket v1.8.6/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= +nhooyr.io/websocket v1.8.7 h1:usjR2uOr/zjjkVMy0lW+PPohFok7PCow5sDjLgX4P4g= +nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= pgregory.net/rapid v0.5.5 h1:jkgx1TjbQPD/feRoK+S/mXw9e1uj6WilpHrXJowi6oA= pgregory.net/rapid v0.5.5/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= diff --git a/interchaintest/helpers/cosmwasm.go b/interchaintest/helpers/cosmwasm.go index 6e4e99bd7..8df844e02 100644 --- a/interchaintest/helpers/cosmwasm.go +++ b/interchaintest/helpers/cosmwasm.go @@ -5,9 +5,9 @@ import ( "testing" "github.com/cosmos/cosmos-sdk/crypto/keyring" - "github.com/strangelove-ventures/interchaintest/v4/chain/cosmos" - "github.com/strangelove-ventures/interchaintest/v4/ibc" - "github.com/strangelove-ventures/interchaintest/v4/testutil" + "github.com/strangelove-ventures/interchaintest/v7/chain/cosmos" + "github.com/strangelove-ventures/interchaintest/v7/ibc" + "github.com/strangelove-ventures/interchaintest/v7/testutil" "github.com/stretchr/testify/require" ) @@ -25,7 +25,7 @@ func SetupContract(t *testing.T, ctx context.Context, chain *cosmos.CosmosChain, return codeId, contractAddr } -func StoreContractGovernanceProposal(t *testing.T, ctx context.Context, chain *cosmos.CosmosChain, user *ibc.Wallet, title, description, depositCoin, contractAddr, amount, message string) { +func StoreContractGovernanceProposal(t *testing.T, ctx context.Context, chain *cosmos.CosmosChain, user ibc.Wallet, title, description, depositCoin, contractAddr, amount, message string) { cmd := []string{"junod", "tx", "gov", "submit-proposal", "sudo-contract", contractAddr, message, "--title", title, "--description", description, @@ -33,7 +33,7 @@ func StoreContractGovernanceProposal(t *testing.T, ctx context.Context, chain *c "--node", chain.GetRPCAddress(), "--home", chain.HomeDir(), "--chain-id", chain.Config().ChainID, - "--from", user.KeyName, + "--from", user.KeyName(), "--gas", "2000000", "--keyring-dir", chain.HomeDir(), "--keyring-backend", keyring.BackendTest, @@ -49,7 +49,7 @@ func StoreContractGovernanceProposal(t *testing.T, ctx context.Context, chain *c debugOutput(t, string(stdout)) } -func ExecuteMsgWithAmount(t *testing.T, ctx context.Context, chain *cosmos.CosmosChain, user *ibc.Wallet, contractAddr, amount, message string) { +func ExecuteMsgWithAmount(t *testing.T, ctx context.Context, chain *cosmos.CosmosChain, user ibc.Wallet, contractAddr, amount, message string) { // amount is #utoken // There has to be a way to do this in ictest? @@ -57,7 +57,7 @@ func ExecuteMsgWithAmount(t *testing.T, ctx context.Context, chain *cosmos.Cosmo "--node", chain.GetRPCAddress(), "--home", chain.HomeDir(), "--chain-id", chain.Config().ChainID, - "--from", user.KeyName, + "--from", user.KeyName(), "--gas", "500000", "--amount", amount, "--keyring-dir", chain.HomeDir(), @@ -74,7 +74,7 @@ func ExecuteMsgWithAmount(t *testing.T, ctx context.Context, chain *cosmos.Cosmo } } -func ExecuteMsgWithFee(t *testing.T, ctx context.Context, chain *cosmos.CosmosChain, user *ibc.Wallet, contractAddr, amount, feeCoin, message string) { +func ExecuteMsgWithFee(t *testing.T, ctx context.Context, chain *cosmos.CosmosChain, user ibc.Wallet, contractAddr, amount, feeCoin, message string) { // amount is #utoken // There has to be a way to do this in ictest? @@ -82,7 +82,7 @@ func ExecuteMsgWithFee(t *testing.T, ctx context.Context, chain *cosmos.CosmosCh "--node", chain.GetRPCAddress(), "--home", chain.HomeDir(), "--chain-id", chain.Config().ChainID, - "--from", user.KeyName, + "--from", user.KeyName(), "--gas", "500000", "--fees", feeCoin, "--keyring-dir", chain.HomeDir(), diff --git a/interchaintest/helpers/feeshare.go b/interchaintest/helpers/feeshare.go index 0ca21d8be..3ee728101 100644 --- a/interchaintest/helpers/feeshare.go +++ b/interchaintest/helpers/feeshare.go @@ -5,19 +5,19 @@ import ( "testing" "github.com/cosmos/cosmos-sdk/crypto/keyring" - "github.com/strangelove-ventures/interchaintest/v4/chain/cosmos" - "github.com/strangelove-ventures/interchaintest/v4/ibc" - "github.com/strangelove-ventures/interchaintest/v4/testutil" + "github.com/strangelove-ventures/interchaintest/v7/chain/cosmos" + "github.com/strangelove-ventures/interchaintest/v7/ibc" + "github.com/strangelove-ventures/interchaintest/v7/testutil" "github.com/stretchr/testify/require" ) -func RegisterFeeShare(t *testing.T, ctx context.Context, chain *cosmos.CosmosChain, user *ibc.Wallet, contract, withdrawAddr string) { +func RegisterFeeShare(t *testing.T, ctx context.Context, chain *cosmos.CosmosChain, user ibc.Wallet, contract, withdrawAddr string) { // TF gas to create cost 2mil, so we set to 2.5 to be safe cmd := []string{"junod", "tx", "feeshare", "register", contract, withdrawAddr, "--node", chain.GetRPCAddress(), "--home", chain.HomeDir(), "--chain-id", chain.Config().ChainID, - "--from", user.KeyName, + "--from", user.KeyName(), // "--gas", "500000", "--keyring-dir", chain.HomeDir(), "--keyring-backend", keyring.BackendTest, diff --git a/interchaintest/helpers/query_helpers.go b/interchaintest/helpers/query_helpers.go index a21e8f05a..92813221b 100644 --- a/interchaintest/helpers/query_helpers.go +++ b/interchaintest/helpers/query_helpers.go @@ -4,7 +4,7 @@ import ( "context" "testing" - "github.com/strangelove-ventures/interchaintest/v4/chain/cosmos" + "github.com/strangelove-ventures/interchaintest/v7/chain/cosmos" "github.com/stretchr/testify/require" ) diff --git a/interchaintest/helpers/tokenfactory.go b/interchaintest/helpers/tokenfactory.go index 06224abc0..f525ef3b9 100644 --- a/interchaintest/helpers/tokenfactory.go +++ b/interchaintest/helpers/tokenfactory.go @@ -8,9 +8,9 @@ import ( tokenfactorytypes "github.com/CosmosContracts/juno/v15/x/tokenfactory/types" "github.com/cosmos/cosmos-sdk/crypto/keyring" - "github.com/strangelove-ventures/interchaintest/v4/chain/cosmos" - "github.com/strangelove-ventures/interchaintest/v4/ibc" - "github.com/strangelove-ventures/interchaintest/v4/testutil" + "github.com/strangelove-ventures/interchaintest/v7/chain/cosmos" + "github.com/strangelove-ventures/interchaintest/v7/ibc" + "github.com/strangelove-ventures/interchaintest/v7/testutil" "github.com/stretchr/testify/require" ) @@ -20,13 +20,13 @@ func debugOutput(t *testing.T, stdout string) { } } -func CreateTokenFactoryDenom(t *testing.T, ctx context.Context, chain *cosmos.CosmosChain, user *ibc.Wallet, subDenomName string) (fullDenom string) { +func CreateTokenFactoryDenom(t *testing.T, ctx context.Context, chain *cosmos.CosmosChain, user ibc.Wallet, subDenomName string) (fullDenom string) { // TF gas to create cost 2mil, so we set to 2.5 to be safe cmd := []string{"junod", "tx", "tokenfactory", "create-denom", subDenomName, "--node", chain.GetRPCAddress(), "--home", chain.HomeDir(), "--chain-id", chain.Config().ChainID, - "--from", user.KeyName, + "--from", user.KeyName(), "--gas", "2500000", "--gas-adjustment", "2.0", "--keyring-dir", chain.HomeDir(), @@ -41,10 +41,10 @@ func CreateTokenFactoryDenom(t *testing.T, ctx context.Context, chain *cosmos.Co err = testutil.WaitForBlocks(ctx, 2, chain) require.NoError(t, err) - return "factory/" + user.Bech32Address(chain.Config().Bech32Prefix) + "/" + subDenomName + return "factory/" + user.FormattedAddress() + "/" + subDenomName } -func MintTokenFactoryDenom(t *testing.T, ctx context.Context, chain *cosmos.CosmosChain, admin *ibc.Wallet, amount uint64, fullDenom string) { +func MintTokenFactoryDenom(t *testing.T, ctx context.Context, chain *cosmos.CosmosChain, admin ibc.Wallet, amount uint64, fullDenom string) { denom := strconv.FormatUint(amount, 10) + fullDenom // mint new tokens to the account @@ -52,7 +52,7 @@ func MintTokenFactoryDenom(t *testing.T, ctx context.Context, chain *cosmos.Cosm "--node", chain.GetRPCAddress(), "--home", chain.HomeDir(), "--chain-id", chain.Config().ChainID, - "--from", admin.KeyName, + "--from", admin.KeyName(), "--keyring-dir", chain.HomeDir(), "--keyring-backend", keyring.BackendTest, "-y", @@ -66,10 +66,10 @@ func MintTokenFactoryDenom(t *testing.T, ctx context.Context, chain *cosmos.Cosm require.NoError(t, err) } -func MintToTokenFactoryDenom(t *testing.T, ctx context.Context, chain *cosmos.CosmosChain, admin *ibc.Wallet, toWallet *ibc.Wallet, amount uint64, fullDenom string) { +func MintToTokenFactoryDenom(t *testing.T, ctx context.Context, chain *cosmos.CosmosChain, admin ibc.Wallet, toWallet ibc.Wallet, amount uint64, fullDenom string) { denom := strconv.FormatUint(amount, 10) + fullDenom - receiver := toWallet.Bech32Address(chain.Config().Bech32Prefix) + receiver := toWallet.FormattedAddress() t.Log("minting", denom, "to", receiver) @@ -78,7 +78,7 @@ func MintToTokenFactoryDenom(t *testing.T, ctx context.Context, chain *cosmos.Co "--node", chain.GetRPCAddress(), "--home", chain.HomeDir(), "--chain-id", chain.Config().ChainID, - "--from", admin.KeyName, + "--from", admin.KeyName(), "--keyring-dir", chain.HomeDir(), "--keyring-backend", keyring.BackendTest, "-y", @@ -92,12 +92,12 @@ func MintToTokenFactoryDenom(t *testing.T, ctx context.Context, chain *cosmos.Co require.NoError(t, err) } -func TransferTokenFactoryAdmin(t *testing.T, ctx context.Context, chain *cosmos.CosmosChain, currentAdmin *ibc.Wallet, newAdminBech32 string, fullDenom string) { +func TransferTokenFactoryAdmin(t *testing.T, ctx context.Context, chain *cosmos.CosmosChain, currentAdmin ibc.Wallet, newAdminBech32 string, fullDenom string) { cmd := []string{"junod", "tx", "tokenfactory", "change-admin", fullDenom, newAdminBech32, "--node", chain.GetRPCAddress(), "--home", chain.HomeDir(), "--chain-id", chain.Config().ChainID, - "--from", currentAdmin.KeyName, + "--from", currentAdmin.KeyName(), "--keyring-dir", chain.HomeDir(), "--keyring-backend", keyring.BackendTest, "-y", @@ -111,7 +111,6 @@ func TransferTokenFactoryAdmin(t *testing.T, ctx context.Context, chain *cosmos. require.NoError(t, err) } -// TODO: // Getters func GetTokenFactoryAdmin(t *testing.T, ctx context.Context, chain *cosmos.CosmosChain, fullDenom string) string { // $BINARY q tokenfactory denom-authority-metadata $FULL_DENOM diff --git a/interchaintest/ibc_transfer_test.go b/interchaintest/ibc_transfer_test.go index ddad77fae..78799ba97 100644 --- a/interchaintest/ibc_transfer_test.go +++ b/interchaintest/ibc_transfer_test.go @@ -107,12 +107,8 @@ func TestJunoGaiaIBCTransfer(t *testing.T) { // Get our Bech32 encoded user addresses junoUser, gaiaUser := users[0], users[1] - - - junoUserAddr := junoUser.Bech32Address(juno.Config().Bech32Prefix) - gaiaUserAddr := gaiaUser.Bech32Address(gaia.Config().Bech32Prefix) - - + junoUserAddr := junoUser.FormattedAddress() + gaiaUserAddr := gaiaUser.FormattedAddress() // Get original account balances junoOrigBal, err := juno.GetBalance(ctx, junoUserAddr, juno.Config().Denom) diff --git a/interchaintest/module_feeshare_test.go b/interchaintest/module_feeshare_test.go index 25ec6f4c8..6180e9bcd 100644 --- a/interchaintest/module_feeshare_test.go +++ b/interchaintest/module_feeshare_test.go @@ -3,8 +3,8 @@ package interchaintest import ( "testing" - "github.com/strangelove-ventures/interchaintest/v4" - "github.com/strangelove-ventures/interchaintest/v4/chain/cosmos" + "github.com/strangelove-ventures/interchaintest/v7" + "github.com/strangelove-ventures/interchaintest/v7/chain/cosmos" helpers "github.com/CosmosContracts/juno/tests/interchaintest/helpers" ) @@ -29,7 +29,7 @@ func TestJunoFeeShare(t *testing.T) { feeRcvAddr := "juno1v75wlkccpv7le3560zw32v2zjes5n0e7csr4qh" // Upload & init contract payment to another address - _, contractAddr := helpers.SetupContract(t, ctx, juno, user.KeyName, "contracts/cw_template.wasm", `{"count":0}`) + _, contractAddr := helpers.SetupContract(t, ctx, juno, user.KeyName(), "contracts/cw_template.wasm", `{"count":0}`) // register contract to a random address (since we are the creator, though not the admin) helpers.RegisterFeeShare(t, ctx, juno, user, contractAddr, feeRcvAddr) diff --git a/interchaintest/module_tokenfactory_test.go b/interchaintest/module_tokenfactory_test.go index f2da9bd10..e6462f976 100644 --- a/interchaintest/module_tokenfactory_test.go +++ b/interchaintest/module_tokenfactory_test.go @@ -4,8 +4,8 @@ import ( "fmt" "testing" - "github.com/strangelove-ventures/interchaintest/v4" - "github.com/strangelove-ventures/interchaintest/v4/chain/cosmos" + "github.com/strangelove-ventures/interchaintest/v7" + "github.com/strangelove-ventures/interchaintest/v7/chain/cosmos" helpers "github.com/CosmosContracts/juno/tests/interchaintest/helpers" ) @@ -24,10 +24,10 @@ func TestJunoTokenFactory(t *testing.T) { users := interchaintest.GetAndFundTestUsers(t, ctx, "default", int64(10_000_000), juno, juno) user := users[0] - uaddr := user.Bech32Address(juno.Config().Bech32Prefix) + uaddr := user.FormattedAddress() user2 := users[1] - uaddr2 := user2.Bech32Address(juno.Config().Bech32Prefix) + uaddr2 := user2.FormattedAddress() tfDenom := helpers.CreateTokenFactoryDenom(t, ctx, juno, user, "ictestdenom") t.Log("tfDenom", tfDenom) @@ -52,7 +52,7 @@ func TestJunoTokenFactory(t *testing.T) { // This allows the uaddr here to mint tokens on behalf of the contract. Typically you only allow a contract here, but this is testing. coreInitMsg := fmt.Sprintf(`{"allowed_mint_addresses":["%s"],"denoms":["%s"]}`, uaddr, tfDenom) - _, coreTFContract := helpers.SetupContract(t, ctx, juno, user.KeyName, "contracts/tokenfactory_core.wasm", coreInitMsg) + _, coreTFContract := helpers.SetupContract(t, ctx, juno, user.KeyName(), "contracts/tokenfactory_core.wasm", coreInitMsg) t.Log("coreContract", coreTFContract) // change admin to the contract @@ -67,7 +67,7 @@ func TestJunoTokenFactory(t *testing.T) { // Mint on the contract for the user to ensure mint bindings work. mintMsg := fmt.Sprintf(`{"mint":{"address":"%s","denom":[{"denom":"%s","amount":"31"}]}}`, uaddr2, tfDenom) - if _, err := juno.ExecuteContract(ctx, user.KeyName, coreTFContract, mintMsg); err != nil { + if err := juno.ExecuteContract(ctx, user.KeyName(), coreTFContract, mintMsg); err != nil { t.Fatal(err) } diff --git a/interchaintest/setup.go b/interchaintest/setup.go index 4b7c744b1..1580f0d7e 100644 --- a/interchaintest/setup.go +++ b/interchaintest/setup.go @@ -10,17 +10,18 @@ import ( feesharetypes "github.com/CosmosContracts/juno/v15/x/feeshare/types" tokenfactorytypes "github.com/CosmosContracts/juno/v15/x/tokenfactory/types" // TODO: fix this so we can store in the DB. - simappparams "github.com/cosmos/cosmos-sdk/simapp/params" "github.com/docker/docker/client" "github.com/icza/dyno" - interchaintest "github.com/strangelove-ventures/interchaintest/v4" - "github.com/strangelove-ventures/interchaintest/v4/chain/cosmos" - "github.com/strangelove-ventures/interchaintest/v4/ibc" - "github.com/strangelove-ventures/interchaintest/v4/testreporter" + interchaintest "github.com/strangelove-ventures/interchaintest/v7" + "github.com/strangelove-ventures/interchaintest/v7/chain/cosmos" + "github.com/strangelove-ventures/interchaintest/v7/ibc" + "github.com/strangelove-ventures/interchaintest/v7/testreporter" "github.com/stretchr/testify/require" "go.uber.org/zap/zaptest" + + testutil "github.com/cosmos/cosmos-sdk/types/module/testutil" ) var ( @@ -48,8 +49,6 @@ var ( GasAdjustment: 1.8, TrustingPeriod: "112h", NoHostMount: false, - SkipGenTx: false, - PreGenesis: nil, ModifyGenesis: nil, ConfigFileOverrides: nil, EncodingConfig: junoEncoding(), @@ -61,7 +60,7 @@ var ( // junoEncoding registers the Juno specific module codecs so that the associated types and msgs // will be supported when writing to the blocksdb sqlite database. -func junoEncoding() *simappparams.EncodingConfig { +func junoEncoding() *testutil.TestEncodingConfig { cfg := cosmos.DefaultEncoding() // register custom types @@ -69,6 +68,8 @@ func junoEncoding() *simappparams.EncodingConfig { feesharetypes.RegisterInterfaces(cfg.InterfaceRegistry) tokenfactorytypes.RegisterInterfaces(cfg.InterfaceRegistry) + //github.com/cosmos/cosmos-sdk/types/module/testutil + return &cfg } @@ -106,8 +107,8 @@ func CreateThisBranchChain(t *testing.T) []ibc.Chain { numVals := 1 numFullNodes := 0 - votingPeriod := "10s" - maxDepositPeriod := "10s" + // votingPeriod := "10s" + // maxDepositPeriod := "10s" cf := interchaintest.NewBuiltinChainFactory(zaptest.NewLogger(t), []*interchaintest.ChainSpec{ { @@ -115,7 +116,7 @@ func CreateThisBranchChain(t *testing.T) []ibc.Chain { ChainName: "juno", Version: junoVersion, ChainConfig: ibc.ChainConfig{ - ModifyGenesis: cosmos.ModifyGenesisProposalTime(votingPeriod, maxDepositPeriod), + // ModifyGenesis: modifyGenesisShortProposals(votingPeriod, maxDepositPeriod), Images: []ibc.DockerImage{ { Repository: junoRepo, @@ -123,8 +124,9 @@ func CreateThisBranchChain(t *testing.T) []ibc.Chain { UidGid: JunoImage.UidGid, }, }, - GasPrices: "0ujuno", - Denom: "ujuno", + GasPrices: "0ujuno", + Denom: "ujuno", + UsingNewGenesisCommand: true, // v47 }, NumValidators: &numVals, NumFullNodes: &numFullNodes, @@ -166,7 +168,8 @@ func BuildInitialChain(t *testing.T, chains []ibc.Chain) (*interchaintest.Interc return ic, ctx, client, network } -func ModifyGenesisProposalTime(votingPeriod string, maxDepositPeriod string) func(ibc.ChainConfig, []byte) ([]byte, error) { +// Setup Helpers +func modifyGenesisShortProposals(votingPeriod string, maxDepositPeriod string) func(ibc.ChainConfig, []byte) ([]byte, error) { return func(chainConfig ibc.ChainConfig, genbz []byte) ([]byte, error) { g := make(map[string]interface{}) if err := json.Unmarshal(genbz, &g); err != nil { From 4ab7b21709e0a5bd043b3d55d86b7d593ab748a9 Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Wed, 10 May 2023 16:22:01 -0500 Subject: [PATCH 078/131] fix version complaints from dep review --- interchaintest/go.mod | 7 ++++--- interchaintest/go.sum | 24 +++++++++++------------- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/interchaintest/go.mod b/interchaintest/go.mod index a1b07f2b8..1d2c78798 100644 --- a/interchaintest/go.mod +++ b/interchaintest/go.mod @@ -22,7 +22,7 @@ require ( github.com/CosmosContracts/juno/v15 v15.0.0-00010101000000-000000000000 github.com/cosmos/cosmos-sdk v0.47.2 github.com/cosmos/ibc-go/v7 v7.0.0 - github.com/docker/docker v20.10.19+incompatible + github.com/docker/docker v20.10.24+incompatible github.com/icza/dyno v0.0.0-20220812133438-f0b6f8a18845 github.com/strangelove-ventures/interchaintest/v7 v7.0.0-20230508154211-ebc1cbd6d88e github.com/stretchr/testify v1.8.2 @@ -97,7 +97,7 @@ require ( github.com/docker/go-units v0.5.0 // indirect github.com/dustin/go-humanize v1.0.1 // indirect github.com/dvsekhvalnov/jose2go v1.5.0 // indirect - github.com/ethereum/go-ethereum v1.10.20 // indirect + github.com/ethereum/go-ethereum v1.11.6 // indirect github.com/felixge/httpsnoop v1.0.2 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/go-kit/kit v0.12.0 // indirect @@ -112,7 +112,7 @@ require ( github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/mock v1.6.0 // indirect github.com/golang/protobuf v1.5.3 // indirect - github.com/golang/snappy v0.0.4 // indirect + github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // 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 @@ -135,6 +135,7 @@ require ( 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.1.0 // indirect + github.com/holiman/uint256 v1.2.2-0.20230321075855-87b91420868c // indirect github.com/huandu/skiplist v1.2.0 // indirect github.com/improbable-eng/grpc-web v0.15.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect diff --git a/interchaintest/go.sum b/interchaintest/go.sum index e8bf8d654..04194670d 100644 --- a/interchaintest/go.sum +++ b/interchaintest/go.sum @@ -380,6 +380,7 @@ 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 h1:sk9/l/KqpunDwP7pSjUg0keiOOLEnOBHzykLrsPppp4= github.com/deckarep/golang-set v1.8.0/go.mod h1:5nI87KwE7wgsBU1F4GKAw2Qod7p5kyS383rP6+o6qqo= +github.com/deckarep/golang-set/v2 v2.1.0 h1:g47V4Or+DUdzbs8FxCCmgb6VYd+ptPAngjM6dtGktsI= github.com/decred/base58 v1.0.4 h1:QJC6B0E0rXOPA8U/kw2rP+qiRJsUaE2Er+pYb3siUeA= github.com/decred/base58 v1.0.4/go.mod h1:jJswKPEdvpFpvf7dsDvFZyLT22xZ9lWqEByX38oGd9E= github.com/decred/dcrd/chaincfg/chainhash v1.0.2 h1:rt5Vlq/jM3ZawwiacWjPa+smINyLRN07EO0cNBV6DGU= @@ -403,8 +404,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/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 v20.10.19+incompatible h1:lzEmjivyNHFHMNAFLXORMBXyGIhw/UP4DvJwvyKYq64= -github.com/docker/docker v20.10.19+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v20.10.24+incompatible h1:Ugvxm7a8+Gz6vqQYQQ2W7GYq5EUPaAiuPgIfVyI3dYE= +github.com/docker/docker v20.10.24+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= @@ -430,8 +431,8 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.m github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/ethereum/go-ethereum v1.10.20 h1:75IW830ClSS40yrQC1ZCMZCt5I+zU16oqId2SiQwdQ4= -github.com/ethereum/go-ethereum v1.10.20/go.mod h1:LWUN82TCHGpxB3En5HVmLLzPD7YSrEUFmFfN1nKkVN0= +github.com/ethereum/go-ethereum v1.11.6 h1:2VF8Mf7XiSUfmoNOy3D+ocfl9Qu8baQBrCNbo2CXQ8E= +github.com/ethereum/go-ethereum v1.11.6/go.mod h1:+a8pUj1tOyJ2RinsNQD4326YS+leSoKGiG/uVVb0x6Y= 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= @@ -538,8 +539,9 @@ github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.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/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk= +github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= 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= @@ -677,6 +679,8 @@ github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2p github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/hdevalence/ed25519consensus v0.1.0 h1:jtBwzzcHuTmFrQN6xQZn6CQEO/V9f7HsjsjeEZ6auqU= github.com/hdevalence/ed25519consensus v0.1.0/go.mod h1:w3BHWjwJbFU29IRHL1Iqkw3sus+7FctEyM4RqDxYNzo= +github.com/holiman/uint256 v1.2.2-0.20230321075855-87b91420868c h1:DZfsyhDK1hnSS5lH8l+JggqzEleHteTYfutAiVlSUM8= +github.com/holiman/uint256 v1.2.2-0.20230321075855-87b91420868c/go.mod h1:SC8Ryt4n+UBbPbIBKaG9zbbDlp4jOru9xFZmPzLUTxw= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huandu/go-assert v1.1.5 h1:fjemmA7sSfYHJD7CUqs9qTwwfdNAx7/j2/ZlHXzNB3c= github.com/huandu/go-assert v1.1.5/go.mod h1:yOLvuqZwmcHIC5rIzrBhT7D3Q9c3GFnd0JrPVhn/06U= @@ -989,8 +993,6 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/spf13/viper v1.15.0 h1:js3yy885G8xwJa6iOISGFwd+qlUo5AvyXb7CiihdtiU= github.com/spf13/viper v1.15.0/go.mod h1:fFcTBJxvhhzSJiZy8n+PeW6t8l+KeT/uTARa0jHOQLA= -github.com/strangelove-ventures/interchaintest/v7 v7.0.0-20230428012002-db902d82df33 h1:QG9pAXSiNhCBiYoiImCtMsY0oI3vG7B/vltQJyarfEU= -github.com/strangelove-ventures/interchaintest/v7 v7.0.0-20230428012002-db902d82df33/go.mod h1:iX6tg3V6mH64h37ZvLuJa7lp9GbmFixTMlVu6Gilb/Q= github.com/strangelove-ventures/interchaintest/v7 v7.0.0-20230508154211-ebc1cbd6d88e h1:Hxs0PZQhAtgkyqgl3bTXYkhhYX8OXvHr7z6CjSBclpo= github.com/strangelove-ventures/interchaintest/v7 v7.0.0-20230508154211-ebc1cbd6d88e/go.mod h1:/FpoaMKTF3OREchZZvg6eGfVYvk7lAwqP9q2TN+lOGs= github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= @@ -1730,8 +1732,6 @@ modernc.org/ccgo/v3 v3.16.13 h1:Mkgdzl46i5F/CNR/Kj80Ri59hC8TKAhZrYSaqvkwzUw= modernc.org/ccgo/v3 v3.16.13/go.mod h1:2Quk+5YgpImhPjv2Qsob1DnZ/4som1lJTodubIcoUkY= modernc.org/ccorpus v1.11.6 h1:J16RXiiqiCgua6+ZvQot4yUuUy8zxgqbqEEUuGPlISk= modernc.org/httpfs v1.0.6 h1:AAgIpFZRXuYnkjftxTAZwMIiwEqAfk8aVB2/oA6nAeM= -modernc.org/libc v1.22.4 h1:wymSbZb0AlrjdAVX3cjreCHTPCpPARbQXNz6BHPzdwQ= -modernc.org/libc v1.22.4/go.mod h1:jj+Z7dTNX8fBScMVNRAYZ/jF91K8fdT2hYMThc3YjBY= modernc.org/libc v1.22.5 h1:91BNch/e5B0uPbJFgqbxXuOnxBQjlS//icfQEGmvyjE= modernc.org/libc v1.22.5/go.mod h1:jj+Z7dTNX8fBScMVNRAYZ/jF91K8fdT2hYMThc3YjBY= modernc.org/mathutil v1.5.0 h1:rV0Ko/6SfM+8G+yKiyI830l3Wuz1zRutdslNoQ0kfiQ= @@ -1740,16 +1740,14 @@ modernc.org/memory v1.5.0 h1:N+/8c5rE6EqugZwHii4IFsaJ7MUhoWX07J5tC/iI5Ds= modernc.org/memory v1.5.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU= modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4= modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= -modernc.org/sqlite v1.22.0 h1:Uo+wEWePCspy4SAu0w2VbzUHEftOs7yoaWX/cYjsq84= -modernc.org/sqlite v1.22.0/go.mod h1:cxbLkB5WS32DnQqeH4h4o1B0eMr8W/y8/RGuxQ3JsC0= modernc.org/sqlite v1.22.1 h1:P2+Dhp5FR1RlVRkQ3dDfCiv3Ok8XPxqpe70IjYVA9oE= modernc.org/sqlite v1.22.1/go.mod h1:OrDj17Mggn6MhE+iPbBNf7RGKODDE9NFT0f3EwDzJqk= modernc.org/strutil v1.1.3 h1:fNMm+oJklMGYfU9Ylcywl0CO5O6nTfaowNsh2wpPjzY= modernc.org/strutil v1.1.3/go.mod h1:MEHNA7PdEnEwLvspRMtWTNnp2nnyvMfkimT1NKNAGbw= -modernc.org/tcl v1.15.1 h1:mOQwiEK4p7HruMZcwKTZPw/aqtGM4aY00uzWhlKKYws= +modernc.org/tcl v1.15.2 h1:C4ybAYCGJw968e+Me18oW55kD/FexcHbqH2xak1ROSY= modernc.org/token v1.0.1 h1:A3qvTqOwexpfZZeyI0FeGPDlSWX5pjZu9hF4lU+EKWg= modernc.org/token v1.0.1/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= -modernc.org/z v1.7.0 h1:xkDw/KepgEjeizO2sNco+hqYkU12taxQFqPEmgm1GWE= +modernc.org/z v1.7.3 h1:zDJf6iHjrnB+WRD88stbXokugjyc0/pB91ri1gO6LZY= nhooyr.io/websocket v1.8.6/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= nhooyr.io/websocket v1.8.7 h1:usjR2uOr/zjjkVMy0lW+PPohFok7PCow5sDjLgX4P4g= nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= From 41bbab542ee06192e296f79df1b228add7b8cf4e Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Wed, 10 May 2023 20:53:13 -0500 Subject: [PATCH 079/131] Fixes a lot of test (Tokenfactory & some mint/feeshare still broken) --- app/apptesting/test_suite.go | 15 +- app/test_helpers.go | 88 ++- x/feeshare/genesis_test.go | 8 +- x/feeshare/integration_test.go | 41 +- x/feeshare/keeper/keeper_test.go | 4 +- x/globalfee/ante/antetest/fee_test.go | 748 -------------------- x/globalfee/ante/antetest/fee_test_setup.go | 5 +- x/globalfee/genesis_test.go | 5 +- x/mint/keeper/grpc_query_test.go | 6 +- x/mint/keeper/integration_test.go | 1 + x/mint/module_test.go | 7 +- x/tokenfactory/bindings/helpers_test.go | 2 +- x/tokenfactory/keeper/keeper_test.go | 2 +- x/tokenfactory/keeper/msg_server_test.go | 2 +- x/tokenfactory/module.go | 2 +- x/tokenfactory/simulation/genesis.go | 3 +- 16 files changed, 114 insertions(+), 825 deletions(-) delete mode 100644 x/globalfee/ante/antetest/fee_test.go diff --git a/app/apptesting/test_suite.go b/app/apptesting/test_suite.go index 5820cb31d..d19d5188b 100644 --- a/app/apptesting/test_suite.go +++ b/app/apptesting/test_suite.go @@ -28,6 +28,7 @@ import ( "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" + appparams "github.com/CosmosContracts/juno/v15/app/params" authzcodec "github.com/CosmosContracts/juno/v15/x/tokenfactory/types/authzcodec" "github.com/CosmosContracts/juno/v15/app" @@ -52,7 +53,7 @@ var ( func (s *KeeperTestHelper) Setup() { var t *testing.T s.App = app.Setup(t) - s.Ctx = s.App.BaseApp.NewContext(false, tmtypes.Header{Height: 1, ChainID: "osmosis-1", Time: time.Now().UTC()}) + s.Ctx = s.App.BaseApp.NewContext(false, tmtypes.Header{Height: 1, ChainID: "testing", Time: time.Now().UTC()}) s.QueryHelper = &baseapp.QueryServiceTestHelper{ GRPCQueryRouter: s.App.GRPCQueryRouter(), Ctx: s.Ctx, @@ -64,7 +65,9 @@ func (s *KeeperTestHelper) SetupTestForInitGenesis() { var t *testing.T // Setting to True, leads to init genesis not running s.App = app.Setup(t) - s.Ctx = s.App.BaseApp.NewContext(true, tmtypes.Header{}) + s.Ctx = s.App.BaseApp.NewContext(true, tmtypes.Header{ + ChainID: "testing", + }) } // CreateTestContext creates a test context. @@ -88,7 +91,7 @@ func (s *KeeperTestHelper) Commit() { oldHeight := s.Ctx.BlockHeight() oldHeader := s.Ctx.BlockHeader() s.App.Commit() - newHeader := tmtypes.Header{Height: oldHeight + 1, ChainID: oldHeader.ChainID, Time: oldHeader.Time.Add(time.Second)} + newHeader := tmtypes.Header{Height: oldHeight + 1, ChainID: "testing", Time: oldHeader.Time.Add(time.Second)} s.App.BeginBlock(abci.RequestBeginBlock{Header: newHeader}) s.Ctx = s.App.NewContext(false, newHeader) } @@ -120,7 +123,7 @@ func (s *KeeperTestHelper) SetupValidator(bondStatus stakingtypes.BondStatus) sd s.FundAcc(sdk.AccAddress(valAddr), selfBond) // stakingHandler := staking.NewHandler(s.App.AppKeepers.StakingKeeper) - stakingCoin := sdk.NewCoin(sdk.DefaultBondDenom, selfBond[0].Amount) + stakingCoin := sdk.NewCoin(appparams.BondDenom, selfBond[0].Amount) ZeroCommission := stakingtypes.NewCommissionRates(sdk.ZeroDec(), sdk.ZeroDec(), sdk.ZeroDec()) _, err := stakingtypes.NewMsgCreateValidator(valAddr, valPub, stakingCoin, stakingtypes.Description{}, ZeroCommission, sdk.OneInt()) s.Require().NoError(err) @@ -209,13 +212,13 @@ func (s *KeeperTestHelper) AllocateRewardsToValidator(valAddr sdk.ValAddress, re s.Require().True(found) // allocate reward tokens to distribution module - coins := sdk.Coins{sdk.NewCoin(sdk.DefaultBondDenom, rewardAmt)} + coins := sdk.Coins{sdk.NewCoin(appparams.BondDenom, rewardAmt)} err := banktestutil.FundModuleAccount(s.App.AppKeepers.BankKeeper, s.Ctx, distrtypes.ModuleName, coins) s.Require().NoError(err) // allocate rewards to validator s.Ctx = s.Ctx.WithBlockHeight(s.Ctx.BlockHeight() + 1) - decTokens := sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: sdk.NewDec(20000)}} + decTokens := sdk.DecCoins{{Denom: appparams.BondDenom, Amount: sdk.NewDec(20000)}} s.App.AppKeepers.DistrKeeper.AllocateTokensToValidator(s.Ctx, validator, decTokens) } diff --git a/app/test_helpers.go b/app/test_helpers.go index 0a4b8eb97..08d811241 100644 --- a/app/test_helpers.go +++ b/app/test_helpers.go @@ -2,9 +2,11 @@ package app import ( "encoding/json" + "path/filepath" "testing" "time" + "cosmossdk.io/math" "github.com/CosmWasm/wasmd/x/wasm" "github.com/CosmWasm/wasmd/x/wasm/keeper" apphelpers "github.com/CosmosContracts/juno/v15/app/helpers" @@ -16,9 +18,14 @@ import ( "github.com/cometbft/cometbft/libs/log" tmproto "github.com/cometbft/cometbft/proto/tendermint/types" tmtypes "github.com/cometbft/cometbft/types" + bam "github.com/cosmos/cosmos-sdk/baseapp" + "github.com/cosmos/cosmos-sdk/client/flags" codectypes "github.com/cosmos/cosmos-sdk/codec/types" cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" + "github.com/cosmos/cosmos-sdk/snapshots" + snapshottypes "github.com/cosmos/cosmos-sdk/snapshots/types" + simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" sdk "github.com/cosmos/cosmos-sdk/types" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" @@ -28,7 +35,7 @@ import ( // SimAppChainID hardcoded chainID for simulation const ( - SimAppChainID = "juno-app" + SimAppChainID = "testing" ) // EmptyBaseAppOptions is a stub implementing AppOptions @@ -68,6 +75,7 @@ func Setup(t *testing.T) *App { privVal := apphelpers.NewPV() pubKey, err := privVal.GetPubKey() require.NoError(t, err) + // create validator set with single validator validator := tmtypes.NewValidator(pubKey, 1) valSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) @@ -80,7 +88,8 @@ func Setup(t *testing.T) *App { Coins: sdk.NewCoins(sdk.NewCoin(appparams.BondDenom, sdk.NewInt(100000000000000))), } - app := SetupWithGenesisValSet(t, valSet, []authtypes.GenesisAccount{acc}, balance) + chainID := "testing" + app := SetupWithGenesisValSet(t, valSet, []authtypes.GenesisAccount{acc}, chainID, balance) return app } @@ -89,10 +98,10 @@ func Setup(t *testing.T) *App { // that also act as delegators. For simplicity, each validator is bonded with a delegation // of one consensus engine unit in the default token of the JunoApp from first genesis // account. A Nop logger is set in JunoApp. -func SetupWithGenesisValSet(t *testing.T, valSet *tmtypes.ValidatorSet, genAccs []authtypes.GenesisAccount, balances ...banktypes.Balance) *App { +func SetupWithGenesisValSet(t *testing.T, valSet *tmtypes.ValidatorSet, genAccs []authtypes.GenesisAccount, chainId string, balances ...banktypes.Balance) *App { t.Helper() - junoApp, genesisState := setup(true) + junoApp, genesisState := setup(t, true) genesisState = genesisStateWithValSet(t, junoApp, genesisState, valSet, genAccs, balances...) stateBytes, err := json.MarshalIndent(genesisState, "", " ") @@ -104,25 +113,38 @@ func SetupWithGenesisValSet(t *testing.T, valSet *tmtypes.ValidatorSet, genAccs Validators: []abci.ValidatorUpdate{}, ConsensusParams: DefaultConsensusParams, AppStateBytes: stateBytes, + ChainId: "testing", }, ) // commit genesis changes junoApp.Commit() junoApp.BeginBlock(abci.RequestBeginBlock{Header: tmproto.Header{ + ChainID: "testing", Height: junoApp.LastBlockHeight() + 1, AppHash: junoApp.LastCommitID().Hash, ValidatorsHash: valSet.Hash(), NextValidatorsHash: valSet.Hash(), + Time: time.Now().UTC(), }}) return junoApp } -func setup(withGenesis bool) (*App, GenesisState) { +func setup(t *testing.T, withGenesis bool, opts ...wasm.Option) (*App, GenesisState) { db := dbm.NewMemDB() - encCdc := MakeEncodingConfig() - var emptyWasmOpts []wasm.Option + nodeHome := t.TempDir() + snapshotDir := filepath.Join(nodeHome, "data", "snapshots") + + snapshotDB, err := dbm.NewDB("metadata", dbm.GoLevelDBBackend, snapshotDir) + require.NoError(t, err) + t.Cleanup(func() { snapshotDB.Close() }) + snapshotStore, err := snapshots.NewStore(snapshotDB, snapshotDir) + require.NoError(t, err) + + // var emptyWasmOpts []wasm.Option + appOptions := make(simtestutil.AppOptionsMap, 0) + appOptions[flags.FlagHome] = nodeHome // ensure unique folder app := New( log.NewNopLogger(), @@ -131,10 +153,12 @@ func setup(withGenesis bool) (*App, GenesisState) { true, wasm.EnableAllProposals, EmptyAppOptions{}, - emptyWasmOpts, + opts, + bam.SetChainID("testing"), + bam.SetSnapshot(snapshotStore, snapshottypes.SnapshotOptions{KeepRecent: 2}), ) if withGenesis { - return app, NewDefaultGenesisState(encCdc.Marshaler) + return app, NewDefaultGenesisState(app.AppCodec()) } return app, GenesisState{} @@ -145,9 +169,12 @@ func genesisStateWithValSet(t *testing.T, valSet *tmtypes.ValidatorSet, genAccs []authtypes.GenesisAccount, balances ...banktypes.Balance, ) GenesisState { + + codec := app.AppCodec() + // set genesis accounts authGenesis := authtypes.NewGenesisState(authtypes.DefaultParams(), genAccs) - genesisState[authtypes.ModuleName] = app.AppCodec().MustMarshalJSON(authGenesis) + genesisState[authtypes.ModuleName] = codec.MustMarshalJSON(authGenesis) validators := make([]stakingtypes.Validator, 0, len(valSet.Validators)) delegations := make([]stakingtypes.Delegation, 0, len(valSet.Validators)) @@ -165,18 +192,18 @@ func genesisStateWithValSet(t *testing.T, Jailed: false, Status: stakingtypes.Bonded, Tokens: bondAmt, - DelegatorShares: sdk.OneDec(), + DelegatorShares: math.LegacyOneDec(), Description: stakingtypes.Description{}, UnbondingHeight: int64(0), UnbondingTime: time.Unix(0, 0).UTC(), - Commission: stakingtypes.NewCommission(sdk.ZeroDec(), sdk.ZeroDec(), sdk.ZeroDec()), - MinSelfDelegation: sdk.ZeroInt(), + Commission: stakingtypes.NewCommission(math.LegacyZeroDec(), math.LegacyZeroDec(), math.LegacyZeroDec()), + MinSelfDelegation: math.ZeroInt(), } validators = append(validators, validator) - delegations = append(delegations, stakingtypes.NewDelegation(genAccs[0].GetAddress(), val.Address.Bytes(), sdk.OneDec())) + delegations = append(delegations, stakingtypes.NewDelegation(genAccs[0].GetAddress(), val.Address.Bytes(), math.LegacyOneDec())) } - // set validators and delegations + defaultStParams := stakingtypes.DefaultParams() stParams := stakingtypes.NewParams( defaultStParams.UnbondingTime, @@ -189,7 +216,13 @@ func genesisStateWithValSet(t *testing.T, // set validators and delegations stakingGenesis := stakingtypes.NewGenesisState(stParams, validators, delegations) - genesisState[stakingtypes.ModuleName] = app.AppCodec().MustMarshalJSON(stakingGenesis) + genesisState[stakingtypes.ModuleName] = codec.MustMarshalJSON(stakingGenesis) + + // add bonded amount to bonded pool module account + balances = append(balances, banktypes.Balance{ + Address: authtypes.NewModuleAddress(stakingtypes.BondedPoolName).String(), + Coins: sdk.Coins{sdk.NewCoin(appparams.BondDenom, bondAmt.MulRaw(int64(len(valSet.Validators))))}, + }) totalSupply := sdk.NewCoins() for _, b := range balances { @@ -197,27 +230,10 @@ func genesisStateWithValSet(t *testing.T, totalSupply = totalSupply.Add(b.Coins...) } - for range delegations { - // add delegated tokens to total supply - totalSupply = totalSupply.Add(sdk.NewCoin(appparams.BondDenom, bondAmt)) - } - - // add bonded amount to bonded pool module account - balances = append(balances, banktypes.Balance{ - Address: authtypes.NewModuleAddress(stakingtypes.BondedPoolName).String(), - Coins: sdk.Coins{sdk.NewCoin(appparams.BondDenom, bondAmt)}, - }) - // update total supply - bankGenesis := banktypes.NewGenesisState( - banktypes.DefaultGenesisState().Params, - balances, - totalSupply, - []banktypes.Metadata{}, - banktypes.DefaultGenesisState().SendEnabled, - ) - - genesisState[banktypes.ModuleName] = app.AppCodec().MustMarshalJSON(bankGenesis) + bankGenesis := banktypes.NewGenesisState(banktypes.DefaultGenesisState().Params, balances, totalSupply, []banktypes.Metadata{}, []banktypes.SendEnabled{}) + genesisState[banktypes.ModuleName] = codec.MustMarshalJSON(bankGenesis) + println(string(genesisState[banktypes.ModuleName])) return genesisState } diff --git a/x/feeshare/genesis_test.go b/x/feeshare/genesis_test.go index 6568eada9..af4b11686 100644 --- a/x/feeshare/genesis_test.go +++ b/x/feeshare/genesis_test.go @@ -4,6 +4,7 @@ import ( "fmt" "testing" + tmproto "github.com/cometbft/cometbft/proto/tendermint/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/suite" @@ -11,7 +12,6 @@ import ( "github.com/CosmosContracts/juno/v15/app" "github.com/CosmosContracts/juno/v15/x/feeshare" "github.com/CosmosContracts/juno/v15/x/feeshare/types" - tmproto "github.com/cometbft/cometbft/proto/tendermint/types" ) type GenesisTestSuite struct { @@ -28,8 +28,10 @@ func TestGenesisTestSuite(t *testing.T) { } func (suite *GenesisTestSuite) SetupTest() { - app := Setup(false) - ctx := app.BaseApp.NewContext(false, tmproto.Header{}) + app := app.Setup(suite.T()) + ctx := app.BaseApp.NewContext(false, tmproto.Header{ + ChainID: "testing", + }) suite.app = app suite.ctx = ctx diff --git a/x/feeshare/integration_test.go b/x/feeshare/integration_test.go index bcf8891d2..9fd0d8463 100644 --- a/x/feeshare/integration_test.go +++ b/x/feeshare/integration_test.go @@ -2,33 +2,41 @@ package feeshare_test import ( "encoding/json" + "path/filepath" + "testing" "github.com/CosmWasm/wasmd/x/wasm" dbm "github.com/cometbft/cometbft-db" abci "github.com/cometbft/cometbft/abci/types" "github.com/cometbft/cometbft/libs/log" tmproto "github.com/cometbft/cometbft/proto/tendermint/types" + bam "github.com/cosmos/cosmos-sdk/baseapp" + "github.com/cosmos/cosmos-sdk/snapshots" + "github.com/stretchr/testify/require" junoapp "github.com/CosmosContracts/juno/v15/app" "github.com/CosmosContracts/juno/v15/x/mint/types" + snapshottypes "github.com/cosmos/cosmos-sdk/snapshots/types" simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" sdk "github.com/cosmos/cosmos-sdk/types" ) // returns context and an app with updated mint keeper -func CreateTestApp(isCheckTx bool) (*junoapp.App, sdk.Context) { - app := Setup(isCheckTx) +func CreateTestApp(t *testing.T, isCheckTx bool) (*junoapp.App, sdk.Context) { + app := Setup(t, isCheckTx) - ctx := app.BaseApp.NewContext(isCheckTx, tmproto.Header{}) + ctx := app.BaseApp.NewContext(isCheckTx, tmproto.Header{ + ChainID: "testing", + }) app.AppKeepers.MintKeeper.SetParams(ctx, types.DefaultParams()) app.AppKeepers.MintKeeper.SetMinter(ctx, types.DefaultInitialMinter()) return app, ctx } -func Setup(isCheckTx bool) *junoapp.App { - app, genesisState := GenApp(!isCheckTx) +func Setup(t *testing.T, isCheckTx bool) *junoapp.App { + app, genesisState := GenApp(t, !isCheckTx) if !isCheckTx { // init chain must be called to stop deliverState from being nil stateBytes, err := json.MarshalIndent(genesisState, "", " ") @@ -39,9 +47,11 @@ func Setup(isCheckTx bool) *junoapp.App { // Initialize the chain app.InitChain( abci.RequestInitChain{ - Validators: []abci.ValidatorUpdate{}, - ConsensusParams: simtestutil.DefaultConsensusParams, + Validators: []abci.ValidatorUpdate{}, + // ConsensusParams: &tmproto.ConsensusParams{}, + ConsensusParams: junoapp.DefaultConsensusParams, AppStateBytes: stateBytes, + ChainId: "testing", }, ) } @@ -49,11 +59,16 @@ func Setup(isCheckTx bool) *junoapp.App { return app } -func GenApp(withGenesis bool) (*junoapp.App, junoapp.GenesisState) { +func GenApp(t *testing.T, withGenesis bool, opts ...wasm.Option) (*junoapp.App, junoapp.GenesisState) { db := dbm.NewMemDB() - encCdc := junoapp.MakeEncodingConfig() + nodeHome := t.TempDir() + snapshotDir := filepath.Join(nodeHome, "data", "snapshots") - var emptyWasmOpts []wasm.Option + snapshotDB, err := dbm.NewDB("metadata", dbm.GoLevelDBBackend, snapshotDir) + require.NoError(t, err) + t.Cleanup(func() { snapshotDB.Close() }) + snapshotStore, err := snapshots.NewStore(snapshotDB, snapshotDir) + require.NoError(t, err) app := junoapp.New( log.NewNopLogger(), @@ -62,11 +77,13 @@ func GenApp(withGenesis bool) (*junoapp.App, junoapp.GenesisState) { true, wasm.EnableAllProposals, simtestutil.EmptyAppOptions{}, - emptyWasmOpts, + opts, + bam.SetChainID("testing"), + bam.SetSnapshot(snapshotStore, snapshottypes.SnapshotOptions{KeepRecent: 2}), ) if withGenesis { - return app, junoapp.NewDefaultGenesisState(encCdc.Marshaler) + return app, junoapp.NewDefaultGenesisState(app.AppCodec()) } return app, junoapp.GenesisState{} diff --git a/x/feeshare/keeper/keeper_test.go b/x/feeshare/keeper/keeper_test.go index 12f84409e..d7810f42f 100644 --- a/x/feeshare/keeper/keeper_test.go +++ b/x/feeshare/keeper/keeper_test.go @@ -1,11 +1,9 @@ package keeper_test import ( - "fmt" "testing" "time" - tmrand "github.com/cometbft/cometbft/libs/rand" tmproto "github.com/cometbft/cometbft/proto/tendermint/types" "github.com/cosmos/cosmos-sdk/baseapp" sdk "github.com/cosmos/cosmos-sdk/types" @@ -45,7 +43,7 @@ func (s *IntegrationTestSuite) SetupTest() { s.app = app.Setup(s.T()) s.ctx = s.app.BaseApp.NewContext(isCheckTx, tmproto.Header{ - ChainID: fmt.Sprintf("test-chain-%s", tmrand.Str(4)), + ChainID: "testing", Height: 9, Time: time.Now().UTC(), }) diff --git a/x/globalfee/ante/antetest/fee_test.go b/x/globalfee/ante/antetest/fee_test.go deleted file mode 100644 index 1c156213e..000000000 --- a/x/globalfee/ante/antetest/fee_test.go +++ /dev/null @@ -1,748 +0,0 @@ -package antetest - -import ( - "testing" - - cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" - "github.com/cosmos/cosmos-sdk/testutil/testdata" - sdk "github.com/cosmos/cosmos-sdk/types" - stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - ibcclienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" - ibcchanneltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" - "github.com/stretchr/testify/suite" - - gaiafeeante "github.com/CosmosContracts/juno/v15/x/globalfee/ante" - globfeetypes "github.com/CosmosContracts/juno/v15/x/globalfee/types" -) - -var testGasLimit uint64 = 200_000 - -func TestIntegrationTestSuite(t *testing.T) { - suite.Run(t, new(IntegrationTestSuite)) -} - -func (s *IntegrationTestSuite) TestGetDefaultGlobalFees() { - // set globalfees and min gas price - feeDecorator, _ := s.SetupTestGlobalFeeStoreAndMinGasPrice([]sdk.DecCoin{}, &globfeetypes.Params{}) - - defaultGlobalFees, err := feeDecorator.DefaultZeroGlobalFee(s.ctx) - s.Require().NoError(err) - s.Require().Greater(len(defaultGlobalFees), 0) - - if defaultGlobalFees[0].Denom != testBondDenom { - s.T().Fatalf("bond denom: %s, default global fee denom: %s", testBondDenom, defaultGlobalFees[0].Denom) - } -} - -// Test global fees and min_gas_price with bypass msg types. -// Please note even globalfee=0, min_gas_price=0, we do not let fee=0random_denom pass. -// Paid fees are already sanitized by removing zero coins(through feeFlag parsing), so use sdk.NewCoins() to create it. -func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { - s.txBuilder = s.clientCtx.TxConfig.NewTxBuilder() - priv1, _, addr1 := testdata.KeyTestPubAddr() - privs, accNums, accSeqs := []cryptotypes.PrivKey{priv1}, []uint64{0}, []uint64{0} - - denominator := int64(100000) - high := sdk.NewDec(400).Quo(sdk.NewDec(denominator)) // 0.004 - med := sdk.NewDec(200).Quo(sdk.NewDec(denominator)) // 0.002 - low := sdk.NewDec(100).Quo(sdk.NewDec(denominator)) // 0.001 - - highFeeAmt := sdk.NewInt(high.MulInt64(int64(2) * denominator).RoundInt64()) - medFeeAmt := sdk.NewInt(med.MulInt64(int64(2) * denominator).RoundInt64()) - lowFeeAmt := sdk.NewInt(low.MulInt64(int64(2) * denominator).RoundInt64()) - - globalfeeParamsEmpty := &globfeetypes.Params{MinimumGasPrices: []sdk.DecCoin{}} - minGasPriceEmpty := []sdk.DecCoin{} - globalfeeParams0 := &globfeetypes.Params{MinimumGasPrices: []sdk.DecCoin{ - sdk.NewDecCoinFromDec("photon", sdk.NewDec(0)), - sdk.NewDecCoinFromDec("uatom", sdk.NewDec(0)), - }} - globalfeeParamsContain0 := &globfeetypes.Params{MinimumGasPrices: []sdk.DecCoin{ - sdk.NewDecCoinFromDec("photon", med), - sdk.NewDecCoinFromDec("uatom", sdk.NewDec(0)), - }} - minGasPrice0 := []sdk.DecCoin{ - sdk.NewDecCoinFromDec("stake", sdk.NewDec(0)), - sdk.NewDecCoinFromDec("uatom", sdk.NewDec(0)), - } - globalfeeParamsHigh := &globfeetypes.Params{ - MinimumGasPrices: []sdk.DecCoin{ - sdk.NewDecCoinFromDec("uatom", high), - }, - } - minGasPrice := []sdk.DecCoin{ - sdk.NewDecCoinFromDec("uatom", med), - sdk.NewDecCoinFromDec("stake", med), - } - globalfeeParamsLow := &globfeetypes.Params{ - MinimumGasPrices: []sdk.DecCoin{ - sdk.NewDecCoinFromDec("uatom", low), - }, - } - // global fee must be sorted in denom - globalfeeParamsNewDenom := &globfeetypes.Params{ - MinimumGasPrices: []sdk.DecCoin{ - sdk.NewDecCoinFromDec("photon", high), - sdk.NewDecCoinFromDec("quark", high), - }, - } - testCases := map[string]struct { - minGasPrice []sdk.DecCoin - globalFeeParams *globfeetypes.Params - gasPrice sdk.Coins - gasLimit sdk.Gas - txMsg sdk.Msg - txCheck bool - expErr bool - }{ - // test fees - // empty min_gas_price or empty global fee - "empty min_gas_price, nonempty global fee, fee higher/equal than global_fee": { - minGasPrice: minGasPriceEmpty, - globalFeeParams: globalfeeParamsHigh, - gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", highFeeAmt)), - gasLimit: testdata.NewTestGasLimit(), - txMsg: testdata.NewTestMsg(addr1), - txCheck: true, - expErr: false, - }, - "empty min_gas_price, nonempty global fee, fee lower than global_fee": { - minGasPrice: minGasPriceEmpty, - globalFeeParams: globalfeeParamsHigh, - gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", lowFeeAmt)), - gasLimit: testdata.NewTestGasLimit(), - txMsg: testdata.NewTestMsg(addr1), - txCheck: true, - expErr: true, - }, - "nonempty min_gas_price with defaultGlobalFee denom, empty global fee, fee higher/equal than min_gas_price": { - minGasPrice: minGasPrice, - globalFeeParams: globalfeeParamsEmpty, // default 0uatom - gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", medFeeAmt)), - gasLimit: testdata.NewTestGasLimit(), - txMsg: testdata.NewTestMsg(addr1), - txCheck: true, - expErr: false, - }, - "nonempty min_gas_price with defaultGlobalFee denom, empty global fee, fee lower than min_gas_price": { - minGasPrice: minGasPrice, - globalFeeParams: globalfeeParamsEmpty, - gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", lowFeeAmt)), - gasLimit: testdata.NewTestGasLimit(), - txMsg: testdata.NewTestMsg(addr1), - txCheck: true, - expErr: true, - }, - "empty min_gas_price, empty global fee, empty fee": { - minGasPrice: minGasPriceEmpty, - globalFeeParams: globalfeeParamsEmpty, - gasPrice: sdk.Coins{}, - gasLimit: testdata.NewTestGasLimit(), - txMsg: testdata.NewTestMsg(addr1), - txCheck: true, - expErr: false, - }, - // zero min_gas_price or zero global fee - "zero min_gas_price, zero global fee, zero fee in global fee denom": { - minGasPrice: minGasPrice0, - globalFeeParams: globalfeeParams0, - gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", sdk.ZeroInt()), sdk.NewCoin("photon", sdk.ZeroInt())), - gasLimit: testdata.NewTestGasLimit(), - txMsg: testdata.NewTestMsg(addr1), - txCheck: true, - expErr: false, - }, - "zero min_gas_price, zero global fee, empty fee": { - minGasPrice: minGasPrice0, - globalFeeParams: globalfeeParams0, - gasPrice: sdk.Coins{}, - gasLimit: testdata.NewTestGasLimit(), - txMsg: testdata.NewTestMsg(addr1), - txCheck: true, - expErr: false, - }, - // zero global fee - "zero min_gas_price, zero global fee, zero fee not in globalfee denom": { - minGasPrice: minGasPrice0, - globalFeeParams: globalfeeParams0, - gasPrice: sdk.NewCoins(sdk.NewCoin("stake", sdk.ZeroInt())), - gasLimit: testdata.NewTestGasLimit(), - txMsg: testdata.NewTestMsg(addr1), - txCheck: true, - expErr: false, - }, - "zero min_gas_price, zero global fee, zero fees one in, one not in globalfee denom": { - minGasPrice: minGasPrice0, - globalFeeParams: globalfeeParams0, - gasPrice: sdk.NewCoins( - sdk.NewCoin("stake", sdk.ZeroInt()), - sdk.NewCoin("uatom", sdk.ZeroInt())), - gasLimit: testdata.NewTestGasLimit(), - txMsg: testdata.NewTestMsg(addr1), - txCheck: true, - expErr: false, - }, - // zero min_gas_price and empty global fee - "zero min_gas_price, empty global fee, zero fee in min_gas_price_denom": { - minGasPrice: minGasPrice0, - globalFeeParams: globalfeeParamsEmpty, - gasPrice: sdk.NewCoins(sdk.NewCoin("stake", sdk.ZeroInt())), - gasLimit: testdata.NewTestGasLimit(), - txMsg: testdata.NewTestMsg(addr1), - txCheck: true, - expErr: false, - }, - "zero min_gas_price, empty global fee, zero fee not in min_gas_price denom, not in defaultZeroGlobalFee denom": { - minGasPrice: minGasPrice0, - globalFeeParams: globalfeeParamsEmpty, - gasPrice: sdk.NewCoins(sdk.NewCoin("quark", sdk.ZeroInt())), - gasLimit: testdata.NewTestGasLimit(), - txMsg: testdata.NewTestMsg(addr1), - txCheck: true, - expErr: false, - }, - "zero min_gas_price, empty global fee, zero fee in defaultZeroGlobalFee denom": { - minGasPrice: minGasPrice0, - globalFeeParams: globalfeeParamsEmpty, - gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", sdk.ZeroInt())), - gasLimit: testGasLimit, - txMsg: testdata.NewTestMsg(addr1), - txCheck: true, - expErr: false, - }, - "zero min_gas_price, empty global fee, nonzero fee in defaultZeroGlobalFee denom": { - minGasPrice: minGasPrice0, - globalFeeParams: globalfeeParamsEmpty, - gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", lowFeeAmt)), - gasLimit: testGasLimit, - txMsg: testdata.NewTestMsg(addr1), - txCheck: true, - expErr: false, - }, - "zero min_gas_price, empty global fee, nonzero fee not in defaultZeroGlobalFee denom": { - minGasPrice: minGasPrice0, - globalFeeParams: globalfeeParamsEmpty, - gasPrice: sdk.NewCoins(sdk.NewCoin("quark", highFeeAmt)), - gasLimit: testGasLimit, - txMsg: testdata.NewTestMsg(addr1), - txCheck: true, - expErr: true, - }, - // empty min_gas_price, zero global fee - "empty min_gas_price, zero global fee, zero fee in global fee denom": { - minGasPrice: minGasPriceEmpty, - globalFeeParams: globalfeeParams0, - gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", sdk.ZeroInt())), - gasLimit: testGasLimit, - txMsg: testdata.NewTestMsg(addr1), - txCheck: true, - expErr: false, - }, - "empty min_gas_price, zero global fee, zero fee not in global fee denom": { - minGasPrice: minGasPriceEmpty, - globalFeeParams: globalfeeParams0, - gasPrice: sdk.NewCoins(sdk.NewCoin("stake", sdk.ZeroInt())), - gasLimit: testGasLimit, - txMsg: testdata.NewTestMsg(addr1), - txCheck: true, - expErr: false, - }, - "empty min_gas_price, zero global fee, nonzero fee in global fee denom": { - minGasPrice: minGasPriceEmpty, - globalFeeParams: globalfeeParams0, - gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", lowFeeAmt)), - gasLimit: testGasLimit, - txMsg: testdata.NewTestMsg(addr1), - txCheck: true, - expErr: false, - }, - "empty min_gas_price, zero global fee, nonzero fee not in global fee denom": { - minGasPrice: minGasPriceEmpty, - globalFeeParams: globalfeeParams0, - gasPrice: sdk.NewCoins(sdk.NewCoin("stake", highFeeAmt)), - gasLimit: testGasLimit, - txMsg: testdata.NewTestMsg(addr1), - txCheck: true, - expErr: true, - }, - // zero min_gas_price, nonzero global fee - "zero min_gas_price, nonzero global fee, fee is higher than global fee": { - minGasPrice: minGasPrice0, - globalFeeParams: globalfeeParamsLow, - gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", lowFeeAmt)), - gasLimit: testGasLimit, - txMsg: testdata.NewTestMsg(addr1), - txCheck: true, - expErr: false, - }, - // nonzero min_gas_price, nonzero global fee - "fee higher/equal than globalfee and min_gas_price": { - minGasPrice: minGasPrice, - globalFeeParams: globalfeeParamsHigh, - gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", highFeeAmt)), - gasLimit: testGasLimit, - txMsg: testdata.NewTestMsg(addr1), - txCheck: true, - expErr: false, - }, - "fee lower than globalfee and min_gas_price": { - minGasPrice: minGasPrice, - globalFeeParams: globalfeeParamsHigh, - gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", lowFeeAmt)), - gasLimit: testGasLimit, - txMsg: testdata.NewTestMsg(addr1), - txCheck: true, - expErr: true, - }, - "fee with one denom higher/equal, one denom lower than globalfee and min_gas_price": { - minGasPrice: minGasPrice, - globalFeeParams: globalfeeParamsNewDenom, - gasPrice: sdk.NewCoins( - sdk.NewCoin("photon", lowFeeAmt), - sdk.NewCoin("quark", highFeeAmt)), - gasLimit: testGasLimit, - txMsg: testdata.NewTestMsg(addr1), - txCheck: true, - expErr: false, - }, - "globalfee > min_gas_price, fee higher/equal than min_gas_price, lower than globalfee": { - minGasPrice: minGasPrice, - globalFeeParams: globalfeeParamsHigh, - gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", medFeeAmt)), - gasLimit: testGasLimit, - txMsg: testdata.NewTestMsg(addr1), - txCheck: true, - expErr: true, - }, - "globalfee < min_gas_price, fee higher/equal than globalfee and lower than min_gas_price": { - minGasPrice: minGasPrice, - globalFeeParams: globalfeeParamsLow, - gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", lowFeeAmt)), - gasLimit: testGasLimit, - txMsg: testdata.NewTestMsg(addr1), - txCheck: true, - expErr: true, - }, - // nonzero min_gas_price, zero global fee - "nonzero min_gas_price, zero global fee, fee is in global fee denom and lower than min_gas_price": { - minGasPrice: minGasPrice, - globalFeeParams: globalfeeParams0, - gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", lowFeeAmt)), - gasLimit: testGasLimit, - txMsg: testdata.NewTestMsg(addr1), - txCheck: true, - expErr: true, - }, - "nonzero min_gas_price, zero global fee, fee is in global fee denom and higher/equal than min_gas_price": { - minGasPrice: minGasPrice, - globalFeeParams: globalfeeParams0, - gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", medFeeAmt)), - gasLimit: testGasLimit, - txMsg: testdata.NewTestMsg(addr1), - txCheck: true, - expErr: false, - }, - "nonzero min_gas_price, zero global fee, fee is in min_gas_price denom which is not in global fee default, but higher/equal than min_gas_price": { - minGasPrice: minGasPrice, - globalFeeParams: globalfeeParams0, - gasPrice: sdk.NewCoins(sdk.NewCoin("stake", highFeeAmt)), - gasLimit: testGasLimit, - txMsg: testdata.NewTestMsg(addr1), - txCheck: true, - expErr: true, - }, - // fee denom tests - "min_gas_price denom is not subset of global fee denom , fee paying in global fee denom": { - minGasPrice: minGasPrice, - globalFeeParams: globalfeeParamsNewDenom, - gasPrice: sdk.NewCoins(sdk.NewCoin("photon", highFeeAmt)), - gasLimit: testGasLimit, - txMsg: testdata.NewTestMsg(addr1), - txCheck: true, - expErr: false, - }, - "min_gas_price denom is not subset of global fee denom, fee paying in min_gas_price denom": { - minGasPrice: minGasPrice, - globalFeeParams: globalfeeParamsNewDenom, - gasPrice: sdk.NewCoins(sdk.NewCoin("stake", highFeeAmt)), - gasLimit: testGasLimit, - txMsg: testdata.NewTestMsg(addr1), - txCheck: true, - expErr: true, - }, - "fees contain denom not in globalfee": { - minGasPrice: minGasPrice, - globalFeeParams: globalfeeParamsLow, - gasPrice: sdk.NewCoins( - sdk.NewCoin("uatom", highFeeAmt), - sdk.NewCoin("quark", highFeeAmt)), - gasLimit: testGasLimit, - txMsg: testdata.NewTestMsg(addr1), - txCheck: true, - expErr: true, - }, - "fees contain denom not in globalfee with zero amount": { - minGasPrice: minGasPrice, - globalFeeParams: globalfeeParamsLow, - gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", highFeeAmt), - sdk.NewCoin("quark", sdk.ZeroInt())), - gasLimit: testGasLimit, - txMsg: testdata.NewTestMsg(addr1), - txCheck: true, - expErr: false, - }, - // cases from https://github.com/cosmos/gaia/pull/1570#issuecomment-1190524402 - // note: this is kind of a silly scenario but technically correct - // if there is a zero coin in the globalfee, the user could pay 0fees - // if the user includes any fee at all in the non-zero denom, it must be higher than that non-zero fee - // unlikely we will ever see zero and non-zero together but technically possible - "globalfee contains zero coin and non-zero coin, fee is lower than the nonzero coin": { - minGasPrice: minGasPrice0, - globalFeeParams: globalfeeParamsContain0, - gasPrice: sdk.NewCoins(sdk.NewCoin("photon", lowFeeAmt)), - gasLimit: testGasLimit, - txMsg: testdata.NewTestMsg(addr1), - txCheck: true, - expErr: true, - }, - "globalfee contains zero coin, fee contains zero coins of the same denom and a lower fee of the other denom in global fee": { - minGasPrice: minGasPrice0, - globalFeeParams: globalfeeParamsContain0, - gasPrice: sdk.NewCoins( - sdk.NewCoin("photon", lowFeeAmt), - sdk.NewCoin("uatom", sdk.ZeroInt())), - gasLimit: testGasLimit, - txMsg: testdata.NewTestMsg(addr1), - txCheck: true, - expErr: true, - }, - "globalfee contains zero coin, fee is empty": { - minGasPrice: minGasPrice0, - globalFeeParams: globalfeeParamsContain0, - gasPrice: sdk.Coins{}, - gasLimit: testGasLimit, - txMsg: testdata.NewTestMsg(addr1), - txCheck: true, - expErr: false, - }, - "globalfee contains zero coin, fee contains lower fee of zero coins's denom, globalfee also contains nonzero coin,fee contains higher fee of nonzero coins's denom, ": { - minGasPrice: minGasPrice0, - globalFeeParams: globalfeeParamsContain0, - gasPrice: sdk.NewCoins( - sdk.NewCoin("photon", lowFeeAmt), - sdk.NewCoin("uatom", highFeeAmt)), - gasLimit: testGasLimit, - txMsg: testdata.NewTestMsg(addr1), - txCheck: true, - expErr: false, - }, - "globalfee contains zero coin, fee is all zero coins but in global fee's denom": { - minGasPrice: minGasPrice0, - globalFeeParams: globalfeeParamsContain0, - gasPrice: sdk.NewCoins( - sdk.NewCoin("photon", sdk.ZeroInt()), - sdk.NewCoin("uatom", sdk.ZeroInt()), - ), - gasLimit: testGasLimit, - txMsg: testdata.NewTestMsg(addr1), - txCheck: true, - expErr: false, - }, - "globalfee contains zero coin, fee is higher than the nonzero coin": { - minGasPrice: minGasPrice0, - globalFeeParams: globalfeeParamsContain0, - gasPrice: sdk.NewCoins(sdk.NewCoin("photon", highFeeAmt)), - gasLimit: testGasLimit, - txMsg: testdata.NewTestMsg(addr1), - txCheck: true, - expErr: false, - }, - "bypass msg type: ibc.core.channel.v1.MsgRecvPacket": { - minGasPrice: minGasPrice, - globalFeeParams: globalfeeParamsLow, - gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", sdk.ZeroInt())), - gasLimit: testGasLimit, - txMsg: ibcchanneltypes.NewMsgRecvPacket( - ibcchanneltypes.Packet{}, nil, ibcclienttypes.Height{}, ""), - txCheck: true, - expErr: false, - }, - "bypass msg type: ibc.core.channel.v1.MsgTimeout": { - minGasPrice: minGasPrice, - globalFeeParams: globalfeeParamsLow, - gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", sdk.ZeroInt())), - gasLimit: testGasLimit, - txMsg: ibcchanneltypes.NewMsgTimeout( - ibcchanneltypes.Packet{}, 1, nil, ibcclienttypes.Height{}, ""), - txCheck: true, - expErr: false, - }, - "bypass msg type: ibc.core.channel.v1.MsgTimeoutOnClose": { - minGasPrice: minGasPrice, - globalFeeParams: globalfeeParamsLow, - gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", sdk.ZeroInt())), - gasLimit: testGasLimit, - txMsg: ibcchanneltypes.NewMsgTimeout( - ibcchanneltypes.Packet{}, 2, nil, ibcclienttypes.Height{}, ""), - txCheck: true, - expErr: false, - }, - "bypass msg gas usage exceeds maxTotalBypassMinFeeMsgGasUsage": { - minGasPrice: minGasPrice, - globalFeeParams: globalfeeParamsLow, - gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", sdk.ZeroInt())), - gasLimit: 2 * testMaxTotalBypassMinFeeMsgGasUsage, - txMsg: ibcchanneltypes.NewMsgTimeout( - ibcchanneltypes.Packet{}, 2, nil, ibcclienttypes.Height{}, ""), - txCheck: true, - expErr: true, - }, - "bypass msg gas usage equals to maxTotalBypassMinFeeMsgGasUsage": { - minGasPrice: minGasPrice, - globalFeeParams: globalfeeParamsLow, - gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", sdk.ZeroInt())), - gasLimit: testGasLimit, - txMsg: ibcchanneltypes.NewMsgTimeout( - ibcchanneltypes.Packet{}, 3, nil, ibcclienttypes.Height{}, ""), - txCheck: true, - expErr: false, - }, - "msg type ibc, zero fee not in globalfee denom": { - minGasPrice: minGasPrice, - globalFeeParams: globalfeeParamsLow, - gasPrice: sdk.NewCoins(sdk.NewCoin("photon", sdk.ZeroInt())), - gasLimit: testGasLimit, - txMsg: ibcchanneltypes.NewMsgRecvPacket( - ibcchanneltypes.Packet{}, nil, ibcclienttypes.Height{}, ""), - txCheck: true, - expErr: false, - }, - "msg type ibc, nonzero fee in globalfee denom": { - minGasPrice: minGasPrice, - globalFeeParams: globalfeeParamsLow, - gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", highFeeAmt)), - gasLimit: testGasLimit, - txMsg: ibcchanneltypes.NewMsgRecvPacket( - ibcchanneltypes.Packet{}, nil, ibcclienttypes.Height{}, ""), - txCheck: true, - expErr: false, - }, - "msg type ibc, nonzero fee not in globalfee denom": { - minGasPrice: minGasPrice, - globalFeeParams: globalfeeParamsLow, - gasPrice: sdk.NewCoins(sdk.NewCoin("photon", highFeeAmt)), - gasLimit: testGasLimit, - txMsg: ibcchanneltypes.NewMsgRecvPacket( - ibcchanneltypes.Packet{}, nil, ibcclienttypes.Height{}, ""), - txCheck: true, - expErr: true, - }, - "msg type ibc, empty fee": { - minGasPrice: minGasPrice, - globalFeeParams: globalfeeParamsLow, - gasPrice: sdk.Coins{}, - gasLimit: testGasLimit, - txMsg: ibcchanneltypes.NewMsgRecvPacket( - ibcchanneltypes.Packet{}, nil, ibcclienttypes.Height{}, ""), - txCheck: true, - expErr: false, - }, - "msg type non-ibc, nonzero fee in globalfee denom": { - minGasPrice: minGasPrice, - globalFeeParams: globalfeeParamsLow, - gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", highFeeAmt)), - gasLimit: testGasLimit, - txMsg: testdata.NewTestMsg(addr1), - txCheck: true, - expErr: false, - }, - "msg type non-ibc, empty fee": { - minGasPrice: minGasPrice, - globalFeeParams: globalfeeParamsLow, - gasPrice: sdk.Coins{}, - gasLimit: testGasLimit, - txMsg: testdata.NewTestMsg(addr1), - txCheck: true, - expErr: true, - }, - "msg type non-ibc, nonzero fee not in globalfee denom": { - minGasPrice: minGasPrice, - globalFeeParams: globalfeeParamsLow, - gasPrice: sdk.NewCoins(sdk.NewCoin("photon", highFeeAmt)), - gasLimit: testGasLimit, - txMsg: testdata.NewTestMsg(addr1), - txCheck: true, - expErr: true, - }, - "disable checkTx: no fee check. min_gas_price is low, global fee is low, tx fee is zero": { - minGasPrice: minGasPrice, - globalFeeParams: globalfeeParamsLow, - gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", sdk.ZeroInt())), - gasLimit: testGasLimit, - txMsg: testdata.NewTestMsg(addr1), - txCheck: false, - expErr: false, - }, - "disable checkTx: no fee check. min_gas_price is low, global fee is low, tx fee's denom is not in global fees denoms set": { - minGasPrice: minGasPrice, - globalFeeParams: globalfeeParamsLow, - gasPrice: sdk.NewCoins(sdk.NewCoin("quark", sdk.ZeroInt())), - gasLimit: testGasLimit, - txMsg: testdata.NewTestMsg(addr1), - txCheck: false, - expErr: false, - }, - } - for name, tc := range testCases { - s.Run(name, func() { - // set globalfees and min gas price - _, antehandler := s.SetupTestGlobalFeeStoreAndMinGasPrice(tc.minGasPrice, tc.globalFeeParams) - - // set fee decorator to ante handler - - s.Require().NoError(s.txBuilder.SetMsgs(tc.txMsg)) - s.txBuilder.SetFeeAmount(tc.gasPrice) - s.txBuilder.SetGasLimit(tc.gasLimit) - tx, err := s.CreateTestTx(privs, accNums, accSeqs, s.ctx.ChainID()) - s.Require().NoError(err) - - s.ctx = s.ctx.WithIsCheckTx(tc.txCheck) - _, err = antehandler(s.ctx, tx, false) - if !tc.expErr { - s.Require().NoError(err) - } else { - s.Require().Error(err) - } - }) - } -} - -// Test how the operator fees are determined using various min gas prices. -// -// Note that in a real Gaia deployment all zero coins can be removed from minGasPrice. -// This sanitizing happens when the minGasPrice is set into the context. -// (see baseapp.SetMinGasPrices in gaia/cmd/root.go line 221) -func (s *IntegrationTestSuite) TestGetMinGasPrice() { - expCoins := sdk.Coins{ - sdk.NewCoin("photon", sdk.NewInt(2000)), - sdk.NewCoin("uatom", sdk.NewInt(3000)), - } - - testCases := []struct { - name string - minGasPrice []sdk.DecCoin - feeTxGasLimit uint64 - expCoins sdk.Coins - }{ - { - "empty min gas price should return empty coins", - []sdk.DecCoin{}, - uint64(1000), - sdk.Coins{}, - }, - { - "zero coins min gas price should return empty coins", - []sdk.DecCoin{ - sdk.NewDecCoinFromDec("stake", sdk.NewDec(0)), - sdk.NewDecCoinFromDec("uatom", sdk.NewDec(0)), - }, - uint64(1000), - sdk.Coins{}, - }, - { - "zero coins, non-zero coins mix should return zero coin and non-zero coins", - []sdk.DecCoin{ - sdk.NewDecCoinFromDec("stake", sdk.NewDec(0)), - sdk.NewDecCoinFromDec("uatom", sdk.NewDec(1)), - }, - uint64(1000), - sdk.Coins{ - sdk.NewCoin("stake", sdk.NewInt(0)), - sdk.NewCoin("uatom", sdk.NewInt(1000)), - }, - }, - - { - "unsorted min gas price should return sorted coins", - []sdk.DecCoin{ - sdk.NewDecCoinFromDec("uatom", sdk.NewDec(3)), - sdk.NewDecCoinFromDec("photon", sdk.NewDec(2)), - }, - uint64(1000), - expCoins, - }, - { - "sorted min gas price should return same conins", - []sdk.DecCoin{ - sdk.NewDecCoinFromDec("photon", sdk.NewDec(2)), - sdk.NewDecCoinFromDec("uatom", sdk.NewDec(3)), - }, - uint64(1000), - expCoins, - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - s.SetupTestGlobalFeeStoreAndMinGasPrice(tc.minGasPrice, &globfeetypes.Params{}) - - fees := gaiafeeante.GetMinGasPrice(s.ctx, int64(tc.feeTxGasLimit)) - s.Require().True(tc.expCoins.Sort().IsEqual(fees)) - }) - } -} - -func (s *IntegrationTestSuite) TestContainsOnlyBypassMinFeeMsgs() { - // set globalfees and min gas price - feeDecorator, _ := s.SetupTestGlobalFeeStoreAndMinGasPrice([]sdk.DecCoin{}, &globfeetypes.Params{}) - - testCases := []struct { - name string - msgs []sdk.Msg - expPass bool - }{ - { - "expect empty msgs to pass", - []sdk.Msg{}, - true, - }, - { - "expect default bypass msg to pass", - []sdk.Msg{ - ibcchanneltypes.NewMsgRecvPacket(ibcchanneltypes.Packet{}, nil, ibcclienttypes.Height{}, ""), - ibcchanneltypes.NewMsgAcknowledgement(ibcchanneltypes.Packet{}, []byte{1}, []byte{1}, ibcclienttypes.Height{}, ""), - }, - true, - }, - { - "expect default bypass msgs to pass", - []sdk.Msg{ - ibcchanneltypes.NewMsgRecvPacket(ibcchanneltypes.Packet{}, nil, ibcclienttypes.Height{}, ""), - ibcchanneltypes.NewMsgAcknowledgement(ibcchanneltypes.Packet{}, []byte{1}, []byte{1}, ibcclienttypes.Height{}, ""), - }, - true, - }, - { - "msgs contain non-bypass msg - should not pass", - []sdk.Msg{ - ibcchanneltypes.NewMsgRecvPacket(ibcchanneltypes.Packet{}, nil, ibcclienttypes.Height{}, ""), - stakingtypes.NewMsgDelegate(sdk.AccAddress{}, sdk.ValAddress{}, sdk.Coin{}), - }, - false, - }, - { - "msgs contain only non-bypass msgs - should not pass", - []sdk.Msg{ - stakingtypes.NewMsgDelegate(sdk.AccAddress{}, sdk.ValAddress{}, sdk.Coin{}), - }, - false, - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - res := feeDecorator.ContainsOnlyBypassMinFeeMsgs(tc.msgs) - s.Require().True(tc.expPass == res) - }) - } -} diff --git a/x/globalfee/ante/antetest/fee_test_setup.go b/x/globalfee/ante/antetest/fee_test_setup.go index b1505d343..3d98ee062 100644 --- a/x/globalfee/ante/antetest/fee_test_setup.go +++ b/x/globalfee/ante/antetest/fee_test_setup.go @@ -1,9 +1,6 @@ package antetest import ( - "fmt" - - tmrand "github.com/cometbft/cometbft/libs/rand" tmproto "github.com/cometbft/cometbft/proto/tendermint/types" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/tx" @@ -42,7 +39,7 @@ var ( func (s *IntegrationTestSuite) SetupTest() { app := app.Setup(s.T()) ctx := app.BaseApp.NewContext(false, tmproto.Header{ - ChainID: fmt.Sprintf("test-chain-%s", tmrand.Str(4)), + ChainID: "testing", Height: 1, }) diff --git a/x/globalfee/genesis_test.go b/x/globalfee/genesis_test.go index c4f23a011..ffafd8523 100644 --- a/x/globalfee/genesis_test.go +++ b/x/globalfee/genesis_test.go @@ -119,8 +119,9 @@ func setupTestStore(t *testing.T) (sdk.Context, appparams.EncodingConfig, params paramsKeeper := paramskeeper.NewKeeper(encCfg.Marshaler, encCfg.Amino, keyParams, tkeyParams) ctx := sdk.NewContext(ms, tmproto.Header{ - Height: 1234567, - Time: time.Date(2020, time.April, 22, 12, 0, 0, 0, time.UTC), + Height: 1234567, + Time: time.Date(2020, time.April, 22, 12, 0, 0, 0, time.UTC), + ChainID: "testing", }, false, log.NewNopLogger()) subspace := paramsKeeper.Subspace(ModuleName).WithKeyTable(types.ParamKeyTable()) diff --git a/x/mint/keeper/grpc_query_test.go b/x/mint/keeper/grpc_query_test.go index cc1765784..28e98007e 100644 --- a/x/mint/keeper/grpc_query_test.go +++ b/x/mint/keeper/grpc_query_test.go @@ -22,8 +22,10 @@ type MintTestSuite struct { } func (suite *MintTestSuite) SetupTest() { - app := setup(false) - ctx := app.BaseApp.NewContext(false, tmproto.Header{}) + app := app.Setup(suite.T()) + ctx := app.BaseApp.NewContext(false, tmproto.Header{ + ChainID: "testing", + }) queryHelper := baseapp.NewQueryServerTestHelper(ctx, app.InterfaceRegistry()) types.RegisterQueryServer(queryHelper, app.AppKeepers.MintKeeper) diff --git a/x/mint/keeper/integration_test.go b/x/mint/keeper/integration_test.go index 4d9fd513a..5b3e5be34 100644 --- a/x/mint/keeper/integration_test.go +++ b/x/mint/keeper/integration_test.go @@ -27,6 +27,7 @@ func setup(isCheckTx bool) *junoapp.App { Validators: []abci.ValidatorUpdate{}, ConsensusParams: simtestutil.DefaultConsensusParams, AppStateBytes: stateBytes, + ChainId: "testing", }, ) } diff --git a/x/mint/module_test.go b/x/mint/module_test.go index bbbd610b6..807a9ca5f 100644 --- a/x/mint/module_test.go +++ b/x/mint/module_test.go @@ -7,22 +7,21 @@ import ( tmproto "github.com/cometbft/cometbft/proto/tendermint/types" "github.com/stretchr/testify/require" - "cosmossdk.io/simapp" + "github.com/CosmosContracts/juno/v15/app" "github.com/CosmosContracts/juno/v15/x/mint/types" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" ) func TestItCreatesModuleAccountOnInitBlock(t *testing.T) { - app := simapp.Setup(t, false) + app := app.Setup(t) ctx := app.BaseApp.NewContext(false, tmproto.Header{}) app.InitChain( abcitypes.RequestInitChain{ AppStateBytes: []byte("{}"), - ChainId: "test-chain-id", }, ) - acc := app.AccountKeeper.GetAccount(ctx, authtypes.NewModuleAddress(types.ModuleName)) + acc := app.AppKeepers.AccountKeeper.GetAccount(ctx, authtypes.NewModuleAddress(types.ModuleName)) require.NotNil(t, acc) } diff --git a/x/tokenfactory/bindings/helpers_test.go b/x/tokenfactory/bindings/helpers_test.go index 415a0c21b..1516125a6 100644 --- a/x/tokenfactory/bindings/helpers_test.go +++ b/x/tokenfactory/bindings/helpers_test.go @@ -20,7 +20,7 @@ import ( func CreateTestInput(t *testing.T) (*app.App, sdk.Context) { osmosis := app.Setup(t) - ctx := osmosis.BaseApp.NewContext(false, tmproto.Header{Height: 1, ChainID: "osmosis-1", Time: time.Now().UTC()}) + ctx := osmosis.BaseApp.NewContext(false, tmproto.Header{Height: 1, ChainID: "testing", Time: time.Now().UTC()}) return osmosis, ctx } diff --git a/x/tokenfactory/keeper/keeper_test.go b/x/tokenfactory/keeper/keeper_test.go index 863989342..421481b20 100644 --- a/x/tokenfactory/keeper/keeper_test.go +++ b/x/tokenfactory/keeper/keeper_test.go @@ -51,7 +51,7 @@ func (suite *KeeperTestSuite) TestCreateModuleAccount() { app.AppKeepers.AccountKeeper.RemoveAccount(suite.Ctx, tokenfactoryModuleAccount) // ensure module account was removed - suite.Ctx = app.BaseApp.NewContext(false, tmproto.Header{}) + suite.Ctx = app.BaseApp.NewContext(false, tmproto.Header{ChainID: "testing"}) tokenfactoryModuleAccount = app.AppKeepers.AccountKeeper.GetAccount(suite.Ctx, app.AppKeepers.AccountKeeper.GetModuleAddress(types.ModuleName)) suite.Require().Nil(tokenfactoryModuleAccount) diff --git a/x/tokenfactory/keeper/msg_server_test.go b/x/tokenfactory/keeper/msg_server_test.go index b3658a5fd..c562fc3e2 100644 --- a/x/tokenfactory/keeper/msg_server_test.go +++ b/x/tokenfactory/keeper/msg_server_test.go @@ -91,7 +91,7 @@ func (suite *KeeperTestSuite) TestBurnDenomMsg() { // TestCreateDenomMsg tests TypeMsgCreateDenom message is emitted on a successful denom creation func (suite *KeeperTestSuite) TestCreateDenomMsg() { - defaultDenomCreationFee := types.Params{DenomCreationFee: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(50000000)))} + defaultDenomCreationFee := types.Params{DenomCreationFee: sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(50000000)))} for _, tc := range []struct { desc string denomCreationFee types.Params diff --git a/x/tokenfactory/module.go b/x/tokenfactory/module.go index f14648494..dde5f86ab 100644 --- a/x/tokenfactory/module.go +++ b/x/tokenfactory/module.go @@ -176,7 +176,7 @@ func (am AppModule) EndBlock(_ sdk.Context, _ abci.RequestEndBlock) []abci.Valid // // GenerateGenesisState creates a randomized GenState of the tokenfactory module. // func (am AppModule) SimulatorGenesisState(simState *module.SimulationState, s *simtypes.SimCtx) { // tfDefaultGen := types.DefaultGenesis() -// tfDefaultGen.Params.DenomCreationFee = sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(10000000))) +// tfDefaultGen.Params.DenomCreationFee = sdk.NewCoins(sdk.NewCoin(appparams.BondDenom, sdk.NewInt(10000000))) // tfDefaultGenJson := simState.Cdc.MustMarshalJSON(tfDefaultGen) // simState.GenState[types.ModuleName] = tfDefaultGenJson // } diff --git a/x/tokenfactory/simulation/genesis.go b/x/tokenfactory/simulation/genesis.go index 03abe07a8..b24c46ab4 100644 --- a/x/tokenfactory/simulation/genesis.go +++ b/x/tokenfactory/simulation/genesis.go @@ -3,6 +3,7 @@ package simulation import ( "math/rand" + appparams "github.com/CosmosContracts/juno/v15/app/params" "github.com/CosmosContracts/juno/v15/x/tokenfactory/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" @@ -10,7 +11,7 @@ import ( func RandDenomCreationFeeParam(r *rand.Rand) sdk.Coins { amount := r.Int63n(10_000_000) - return sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(amount))) + return sdk.NewCoins(sdk.NewCoin(appparams.BondDenom, sdk.NewInt(amount))) } func RandomizedGenState(simstate *module.SimulationState) { From c37f4fbe43348084a8ba76faeb9aca1bd19b5849 Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Wed, 10 May 2023 20:59:04 -0500 Subject: [PATCH 080/131] Fix x/mint MOduleAccount test --- x/mint/module_test.go | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/x/mint/module_test.go b/x/mint/module_test.go index 807a9ca5f..797e3fa59 100644 --- a/x/mint/module_test.go +++ b/x/mint/module_test.go @@ -3,25 +3,23 @@ package mint_test import ( "testing" - abcitypes "github.com/cometbft/cometbft/abci/types" tmproto "github.com/cometbft/cometbft/proto/tendermint/types" + simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" "github.com/stretchr/testify/require" - "github.com/CosmosContracts/juno/v15/app" "github.com/CosmosContracts/juno/v15/x/mint/types" + authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + "github.com/cosmos/cosmos-sdk/x/nft/testutil" ) func TestItCreatesModuleAccountOnInitBlock(t *testing.T) { - app := app.Setup(t) - ctx := app.BaseApp.NewContext(false, tmproto.Header{}) + var accountKeeper authkeeper.AccountKeeper - app.InitChain( - abcitypes.RequestInitChain{ - AppStateBytes: []byte("{}"), - }, - ) + app, err := simtestutil.SetupAtGenesis(testutil.AppConfig, &accountKeeper) + require.NoError(t, err) - acc := app.AppKeepers.AccountKeeper.GetAccount(ctx, authtypes.NewModuleAddress(types.ModuleName)) + ctx := app.BaseApp.NewContext(false, tmproto.Header{}) + acc := accountKeeper.GetAccount(ctx, authtypes.NewModuleAddress(types.ModuleName)) require.NotNil(t, acc) } From ed74b32416c0c43f8777abf6e9637526791a58c9 Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Wed, 10 May 2023 21:37:26 -0500 Subject: [PATCH 081/131] Fix some ictest (new genesis) & crisis upgrade store key --- app/upgrades/v15/constants.go | 2 ++ go.mod | 5 +---- interchaintest/ibc_transfer_test.go | 1 + interchaintest/setup.go | 31 +++++++++++++++-------------- 4 files changed, 20 insertions(+), 19 deletions(-) diff --git a/app/upgrades/v15/constants.go b/app/upgrades/v15/constants.go index 89a6bb20f..0de8612c8 100644 --- a/app/upgrades/v15/constants.go +++ b/app/upgrades/v15/constants.go @@ -5,6 +5,7 @@ import ( store "github.com/cosmos/cosmos-sdk/store/types" consensustypes "github.com/cosmos/cosmos-sdk/x/consensus/types" + crisistypes "github.com/cosmos/cosmos-sdk/x/crisis/types" icqtypes "github.com/strangelove-ventures/async-icq/v7/types" ) @@ -17,6 +18,7 @@ var Upgrade = upgrades.Upgrade{ StoreUpgrades: store.StoreUpgrades{ Added: []string{ icqtypes.ModuleName, + crisistypes.ModuleName, consensustypes.ModuleName, }, }, diff --git a/go.mod b/go.mod index 455d45620..97c7a5e5c 100644 --- a/go.mod +++ b/go.mod @@ -44,7 +44,7 @@ require ( github.com/cosmos/ics23/go v0.10.0 // indirect github.com/cosmos/rosetta-sdk-go v0.10.0 // indirect github.com/gogo/googleapis v1.4.1 // indirect - github.com/gogo/protobuf v1.3.3 // indirect + github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/mock v1.6.0 // indirect github.com/google/uuid v1.3.0 // indirect github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect @@ -193,9 +193,6 @@ replace ( // TODO Remove it: https://github.com/cosmos/cosmos-sdk/issues/10409 github.com/gin-gonic/gin => github.com/gin-gonic/gin v1.8.1 - // temporary, need to fix, issue is at import of: github.com/cosmos/gogogateway - github.com/gogo/protobuf v1.3.3 => github.com/gogo/protobuf v1.3.2 - // pin the version of goleveldb to v1.0.1-0.20210819022825-2ae1ddf74ef7 github.com/syndtr/goleveldb => github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 ) diff --git a/interchaintest/ibc_transfer_test.go b/interchaintest/ibc_transfer_test.go index 78799ba97..f6af4c706 100644 --- a/interchaintest/ibc_transfer_test.go +++ b/interchaintest/ibc_transfer_test.go @@ -34,6 +34,7 @@ func TestJunoGaiaIBCTransfer(t *testing.T) { ChainConfig: junoConfig, NumValidators: &numVals, NumFullNodes: &numFullNodes, + }, { Name: "gaia", diff --git a/interchaintest/setup.go b/interchaintest/setup.go index 1580f0d7e..ca88132ef 100644 --- a/interchaintest/setup.go +++ b/interchaintest/setup.go @@ -37,21 +37,22 @@ var ( } junoConfig = ibc.ChainConfig{ - Type: "cosmos", - Name: "juno", - ChainID: "juno-2", - Images: []ibc.DockerImage{JunoImage}, - Bin: "junod", - Bech32Prefix: "juno", - Denom: "ujuno", - CoinType: "118", - GasPrices: "0ujuno", - GasAdjustment: 1.8, - TrustingPeriod: "112h", - NoHostMount: false, - ModifyGenesis: nil, - ConfigFileOverrides: nil, - EncodingConfig: junoEncoding(), + Type: "cosmos", + Name: "juno", + ChainID: "juno-2", + Images: []ibc.DockerImage{JunoImage}, + Bin: "junod", + Bech32Prefix: "juno", + Denom: "ujuno", + CoinType: "118", + GasPrices: "0ujuno", + GasAdjustment: 1.8, + TrustingPeriod: "112h", + NoHostMount: false, + ModifyGenesis: nil, + ConfigFileOverrides: nil, + EncodingConfig: junoEncoding(), + UsingNewGenesisCommand: true, } pathJunoGaia = "juno-gaia" From 14cf29311d80a3e9ff1049228cb8c1765994fa6a Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Thu, 11 May 2023 12:00:55 -0500 Subject: [PATCH 082/131] FIXES ALL TEST OH MY GOSH FINALLY WOW MUCH FUN --- app/apptesting/events.go | 1 + app/apptesting/test_suite.go | 4 ++-- app/test_helpers.go | 4 +++- x/tokenfactory/bindings/custom_query_test.go | 4 ++-- x/tokenfactory/bindings/message_plugin.go | 2 ++ x/tokenfactory/bindings/validate_msg_test.go | 3 ++- .../bindings/validate_queries_test.go | 8 ++++---- x/tokenfactory/keeper/createdenom.go | 11 +++++----- x/tokenfactory/keeper/createdenom_test.go | 14 ++++++++----- x/tokenfactory/keeper/genesis_test.go | 20 ++++++++----------- x/tokenfactory/keeper/keeper_test.go | 4 ++-- x/tokenfactory/keeper/msg_server.go | 4 ++++ .../testhelpers/{suite.go => authz.go} | 0 x/tokenfactory/testhelpers/consts.go | 8 -------- 14 files changed, 44 insertions(+), 43 deletions(-) rename x/tokenfactory/testhelpers/{suite.go => authz.go} (100%) delete mode 100644 x/tokenfactory/testhelpers/consts.go diff --git a/app/apptesting/events.go b/app/apptesting/events.go index f5a434937..f4e9e4b85 100644 --- a/app/apptesting/events.go +++ b/app/apptesting/events.go @@ -6,6 +6,7 @@ import sdk "github.com/cosmos/cosmos-sdk/types" // of the given type. func (s *KeeperTestHelper) AssertEventEmitted(ctx sdk.Context, eventTypeExpected string, numEventsExpected int) { allEvents := ctx.EventManager().Events() + // filter out other events actualEvents := make([]sdk.Event, 0) for _, event := range allEvents { diff --git a/app/apptesting/test_suite.go b/app/apptesting/test_suite.go index d19d5188b..52a9f8ed2 100644 --- a/app/apptesting/test_suite.go +++ b/app/apptesting/test_suite.go @@ -51,7 +51,7 @@ var ( // Setup sets up basic environment for suite (App, Ctx, and test accounts) func (s *KeeperTestHelper) Setup() { - var t *testing.T + t := s.T() s.App = app.Setup(t) s.Ctx = s.App.BaseApp.NewContext(false, tmtypes.Header{Height: 1, ChainID: "testing", Time: time.Now().UTC()}) s.QueryHelper = &baseapp.QueryServiceTestHelper{ @@ -62,7 +62,7 @@ func (s *KeeperTestHelper) Setup() { } func (s *KeeperTestHelper) SetupTestForInitGenesis() { - var t *testing.T + t := s.T() // Setting to True, leads to init genesis not running s.App = app.Setup(t) s.Ctx = s.App.BaseApp.NewContext(true, tmtypes.Header{ diff --git a/app/test_helpers.go b/app/test_helpers.go index 08d811241..2e2288f0f 100644 --- a/app/test_helpers.go +++ b/app/test_helpers.go @@ -114,6 +114,8 @@ func SetupWithGenesisValSet(t *testing.T, valSet *tmtypes.ValidatorSet, genAccs ConsensusParams: DefaultConsensusParams, AppStateBytes: stateBytes, ChainId: "testing", + Time: time.Now().UTC(), + InitialHeight: 1, }, ) @@ -233,7 +235,7 @@ func genesisStateWithValSet(t *testing.T, // update total supply bankGenesis := banktypes.NewGenesisState(banktypes.DefaultGenesisState().Params, balances, totalSupply, []banktypes.Metadata{}, []banktypes.SendEnabled{}) genesisState[banktypes.ModuleName] = codec.MustMarshalJSON(bankGenesis) - println(string(genesisState[banktypes.ModuleName])) + // println("genesisStateWithValSet bankState:", string(genesisState[banktypes.ModuleName])) return genesisState } diff --git a/x/tokenfactory/bindings/custom_query_test.go b/x/tokenfactory/bindings/custom_query_test.go index 3d60a32df..cf4db0ad7 100644 --- a/x/tokenfactory/bindings/custom_query_test.go +++ b/x/tokenfactory/bindings/custom_query_test.go @@ -53,7 +53,7 @@ func queryCustom(t *testing.T, ctx sdk.Context, junoapp *app.App, contract sdk.A } msgBz, err := json.Marshal(wrapped) require.NoError(t, err) - fmt.Println(string(msgBz)) + fmt.Println("queryCustom1", string(msgBz)) query := ReflectQuery{ Chain: &ChainRequest{ @@ -62,7 +62,7 @@ func queryCustom(t *testing.T, ctx sdk.Context, junoapp *app.App, contract sdk.A } queryBz, err := json.Marshal(query) require.NoError(t, err) - fmt.Println(string(queryBz)) + fmt.Println("queryCustom2", string(queryBz)) resBz, err := junoapp.AppKeepers.WasmKeeper.QuerySmart(ctx, contract, queryBz) require.NoError(t, err) diff --git a/x/tokenfactory/bindings/message_plugin.go b/x/tokenfactory/bindings/message_plugin.go index 835035059..93fa08c95 100644 --- a/x/tokenfactory/bindings/message_plugin.go +++ b/x/tokenfactory/bindings/message_plugin.go @@ -96,10 +96,12 @@ func PerformCreateDenom(f *tokenfactorykeeper.Keeper, b *bankkeeper.BaseKeeper, } // Create denom + // TODO: issue here: nil key on Store resp, err := msgServer.CreateDenom( sdk.WrapSDKContext(ctx), msgCreateDenom, ) + if err != nil { return nil, errorsmod.Wrap(err, "creating denom") } diff --git a/x/tokenfactory/bindings/validate_msg_test.go b/x/tokenfactory/bindings/validate_msg_test.go index 752ce9642..b15c6e09e 100644 --- a/x/tokenfactory/bindings/validate_msg_test.go +++ b/x/tokenfactory/bindings/validate_msg_test.go @@ -40,7 +40,7 @@ func TestCreateDenom(t *testing.T) { createDenom: &bindings.CreateDenom{ Subdenom: "sub-denom_2", }, - expErr: true, + expErr: false, }, "null create denom": { createDenom: nil, @@ -53,6 +53,7 @@ func TestCreateDenom(t *testing.T) { _, gotErr := wasmbinding.PerformCreateDenom(&junoapp.AppKeepers.TokenFactoryKeeper, &junoapp.AppKeepers.BankKeeper, ctx, actor, spec.createDenom) // then if spec.expErr { + t.Logf("validate_msg_test got error: %v", gotErr) require.Error(t, gotErr) return } diff --git a/x/tokenfactory/bindings/validate_queries_test.go b/x/tokenfactory/bindings/validate_queries_test.go index 2302b6d75..561353564 100644 --- a/x/tokenfactory/bindings/validate_queries_test.go +++ b/x/tokenfactory/bindings/validate_queries_test.go @@ -41,10 +41,10 @@ func TestFullDenom(t *testing.T) { subdenom: "", expFullDenom: fmt.Sprintf("factory/%s/", actor.String()), }, - "invalid sub-denom (contains underscore)": { - addr: actor.String(), - subdenom: "sub_denom", - expErr: true, + "valid sub-denom (contains underscore)": { + addr: actor.String(), + subdenom: "sub_denom", + expFullDenom: fmt.Sprintf("factory/%s/sub_denom", actor.String()), }, } for name, spec := range specs { diff --git a/x/tokenfactory/keeper/createdenom.go b/x/tokenfactory/keeper/createdenom.go index 08881e7f1..4dfcb5c08 100644 --- a/x/tokenfactory/keeper/createdenom.go +++ b/x/tokenfactory/keeper/createdenom.go @@ -1,8 +1,6 @@ package keeper import ( - "fmt" - sdk "github.com/cosmos/cosmos-sdk/types" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" @@ -51,11 +49,12 @@ func (k Keeper) createDenomAfterValidation(ctx sdk.Context, creatorAddr string, } func (k Keeper) validateCreateDenom(ctx sdk.Context, creatorAddr string, subdenom string) (newTokenDenom string, err error) { + // TODO: This was a nil key on Store issue. Removed as we are upgrading IBC versions now // Temporary check until IBC bug is sorted out - if k.bankKeeper.HasSupply(ctx, subdenom) { - return "", fmt.Errorf("temporary error until IBC bug is sorted out, " + - "can't create subdenoms that are the same as a native denom") - } + // if k.bankKeeper.HasSupply(ctx, subdenom) { + // return "", fmt.Errorf("temporary error until IBC bug is sorted out, " + + // "can't create subdenoms that are the same as a native denom") + // } denom, err := types.GetTokenDenom(creatorAddr, subdenom) if err != nil { diff --git a/x/tokenfactory/keeper/createdenom_test.go b/x/tokenfactory/keeper/createdenom_test.go index fad6eea93..d45fd315d 100644 --- a/x/tokenfactory/keeper/createdenom_test.go +++ b/x/tokenfactory/keeper/createdenom_test.go @@ -5,7 +5,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/CosmosContracts/juno/v15/x/tokenfactory/testhelpers" + "github.com/CosmosContracts/juno/v15/app/apptesting" "github.com/CosmosContracts/juno/v15/x/tokenfactory/types" ) @@ -64,7 +64,7 @@ func (suite *KeeperTestSuite) TestMsgCreateDenom() { func (suite *KeeperTestSuite) TestCreateDenom() { var ( primaryDenom = types.DefaultParams().DenomCreationFee[0].Denom - secondaryDenom = testhelpers.SecondaryDenom + secondaryDenom = apptesting.SecondaryDenom defaultDenomCreationFee = types.Params{DenomCreationFee: sdk.NewCoins(sdk.NewCoin(primaryDenom, sdk.NewInt(50000000)))} twoDenomCreationFee = types.Params{DenomCreationFee: sdk.NewCoins(sdk.NewCoin(primaryDenom, sdk.NewInt(50000000)), sdk.NewCoin(secondaryDenom, sdk.NewInt(50000000)))} nilCreationFee = types.Params{DenomCreationFee: nil} @@ -138,12 +138,16 @@ func (suite *KeeperTestSuite) TestCreateDenom() { suite.Require().Equal(tc.denomCreationFee.DenomCreationFee, denomCreationFee) // note balance, create a tokenfactory denom, then note balance again - preCreateBalance := bankKeeper.GetAllBalances(suite.Ctx, suite.TestAccs[0]) + // preCreateBalance := bankKeeper.GetAllBalances(suite.Ctx, suite.TestAccs[0]) + preCreateBalance := bankKeeper.GetBalance(suite.Ctx, suite.TestAccs[0], "stake") res, err := suite.msgServer.CreateDenom(sdk.WrapSDKContext(suite.Ctx), types.NewMsgCreateDenom(suite.TestAccs[0].String(), tc.subdenom)) - postCreateBalance := bankKeeper.GetAllBalances(suite.Ctx, suite.TestAccs[0]) + // postCreateBalance := bankKeeper.GetAllBalances(suite.Ctx, suite.TestAccs[0]) + postCreateBalance := bankKeeper.GetBalance(suite.Ctx, suite.TestAccs[0], "stake") if tc.valid { suite.Require().NoError(err) - suite.Require().True(preCreateBalance.Sub(postCreateBalance[0]).IsEqual(denomCreationFee)) + if denomCreationFee != nil { + suite.Require().True(preCreateBalance.Sub(postCreateBalance).IsEqual(denomCreationFee[0])) + } // Make sure that the admin is set correctly queryRes, err := suite.queryClient.DenomAuthorityMetadata(suite.Ctx.Context(), &types.QueryDenomAuthorityMetadataRequest{ diff --git a/x/tokenfactory/keeper/genesis_test.go b/x/tokenfactory/keeper/genesis_test.go index 534990e41..abcf8361d 100644 --- a/x/tokenfactory/keeper/genesis_test.go +++ b/x/tokenfactory/keeper/genesis_test.go @@ -11,21 +11,21 @@ func (suite *KeeperTestSuite) TestGenesis() { genesisState := types.GenesisState{ FactoryDenoms: []types.GenesisDenom{ { - Denom: "factory/cosmos1t7egva48prqmzl59x5ngv4zx0dtrwewcdqdjr8/bitcoin", + Denom: "factory/juno1t7egva48prqmzl59x5ngv4zx0dtrwewcmjwfym/bitcoin", AuthorityMetadata: types.DenomAuthorityMetadata{ - Admin: "cosmos1t7egva48prqmzl59x5ngv4zx0dtrwewcdqdjr8", + Admin: "juno1t7egva48prqmzl59x5ngv4zx0dtrwewcmjwfym", }, }, { - Denom: "factory/cosmos1t7egva48prqmzl59x5ngv4zx0dtrwewcdqdjr8/diff-admin", + Denom: "factory/juno1t7egva48prqmzl59x5ngv4zx0dtrwewcmjwfym/diff-admin", AuthorityMetadata: types.DenomAuthorityMetadata{ - Admin: "cosmos15czt5nhlnvayqq37xun9s9yus0d6y26dx74r5p", + Admin: "juno15czt5nhlnvayqq37xun9s9yus0d6y26dsvkcna", }, }, { - Denom: "factory/cosmos1t7egva48prqmzl59x5ngv4zx0dtrwewcdqdjr8/litecoin", + Denom: "factory/juno1t7egva48prqmzl59x5ngv4zx0dtrwewcmjwfym/litecoin", AuthorityMetadata: types.DenomAuthorityMetadata{ - Admin: "cosmos1t7egva48prqmzl59x5ngv4zx0dtrwewcdqdjr8", + Admin: "juno1t7egva48prqmzl59x5ngv4zx0dtrwewcmjwfym", }, }, }, @@ -42,15 +42,11 @@ func (suite *KeeperTestSuite) TestGenesis() { } } - // check before initGenesis that the module account is nil - tokenfactoryModuleAccount := app.AppKeepers.AccountKeeper.GetAccount(suite.Ctx, app.AppKeepers.AccountKeeper.GetModuleAddress(types.ModuleName)) - suite.Require().Nil(tokenfactoryModuleAccount) - - app.AppKeepers.TokenFactoryKeeper.SetParams(suite.Ctx, types.Params{DenomCreationFee: sdk.Coins{sdk.NewInt64Coin("uosmo", 100)}}) + app.AppKeepers.TokenFactoryKeeper.SetParams(suite.Ctx, types.Params{DenomCreationFee: sdk.Coins{sdk.NewInt64Coin("stake", 100)}}) app.AppKeepers.TokenFactoryKeeper.InitGenesis(suite.Ctx, genesisState) // check that the module account is now initialized - tokenfactoryModuleAccount = app.AppKeepers.AccountKeeper.GetAccount(suite.Ctx, app.AppKeepers.AccountKeeper.GetModuleAddress(types.ModuleName)) + tokenfactoryModuleAccount := app.AppKeepers.AccountKeeper.GetAccount(suite.Ctx, app.AppKeepers.AccountKeeper.GetModuleAddress(types.ModuleName)) suite.Require().NotNil(tokenfactoryModuleAccount) exportedGenesis := app.AppKeepers.TokenFactoryKeeper.ExportGenesis(suite.Ctx) diff --git a/x/tokenfactory/keeper/keeper_test.go b/x/tokenfactory/keeper/keeper_test.go index 421481b20..d33c6d12c 100644 --- a/x/tokenfactory/keeper/keeper_test.go +++ b/x/tokenfactory/keeper/keeper_test.go @@ -9,7 +9,6 @@ import ( "github.com/CosmosContracts/juno/v15/app/apptesting" "github.com/CosmosContracts/juno/v15/x/tokenfactory/keeper" - "github.com/CosmosContracts/juno/v15/x/tokenfactory/testhelpers" "github.com/CosmosContracts/juno/v15/x/tokenfactory/types" ) @@ -28,8 +27,9 @@ func TestKeeperTestSuite(t *testing.T) { func (suite *KeeperTestSuite) SetupTest() { suite.Setup() + // Fund every TestAcc with two denoms, one of which is the denom creation fee - fundAccsAmount := sdk.NewCoins(sdk.NewCoin(types.DefaultParams().DenomCreationFee[0].Denom, types.DefaultParams().DenomCreationFee[0].Amount.MulRaw(100)), sdk.NewCoin(testhelpers.SecondaryDenom, testhelpers.SecondaryAmount)) + fundAccsAmount := sdk.NewCoins(sdk.NewCoin(types.DefaultParams().DenomCreationFee[0].Denom, types.DefaultParams().DenomCreationFee[0].Amount.MulRaw(100)), sdk.NewCoin(apptesting.SecondaryDenom, apptesting.SecondaryAmount)) for _, acc := range suite.TestAccs { suite.FundAcc(acc, fundAccsAmount) } diff --git a/x/tokenfactory/keeper/msg_server.go b/x/tokenfactory/keeper/msg_server.go index fdb84e70f..30f9e438d 100644 --- a/x/tokenfactory/keeper/msg_server.go +++ b/x/tokenfactory/keeper/msg_server.go @@ -21,6 +21,10 @@ func NewMsgServerImpl(keeper Keeper) types.MsgServer { var _ types.MsgServer = msgServer{} func (server msgServer) CreateDenom(goCtx context.Context, msg *types.MsgCreateDenom) (*types.MsgCreateDenomResponse, error) { + if err := msg.ValidateBasic(); err != nil { + return nil, err + } + ctx := sdk.UnwrapSDKContext(goCtx) denom, err := server.Keeper.CreateDenom(ctx, msg.Sender, msg.Subdenom) diff --git a/x/tokenfactory/testhelpers/suite.go b/x/tokenfactory/testhelpers/authz.go similarity index 100% rename from x/tokenfactory/testhelpers/suite.go rename to x/tokenfactory/testhelpers/authz.go diff --git a/x/tokenfactory/testhelpers/consts.go b/x/tokenfactory/testhelpers/consts.go deleted file mode 100644 index d7804a372..000000000 --- a/x/tokenfactory/testhelpers/consts.go +++ /dev/null @@ -1,8 +0,0 @@ -package testhelpers - -import sdk "github.com/cosmos/cosmos-sdk/types" - -var ( - SecondaryDenom = "uion" - SecondaryAmount = sdk.NewInt(100000000) -) From 62c7e74ce23de80fd916443c8f235da7aee5514c Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Thu, 11 May 2023 12:06:55 -0500 Subject: [PATCH 083/131] linter linter linter linter --- app/test_helpers.go | 6 +-- interchaintest/ibc_transfer_test.go | 1 - x/globalfee/ante/antetest/fee_test_setup.go | 8 +-- x/mint/keeper/integration_test.go | 59 --------------------- x/tokenfactory/bindings/message_plugin.go | 2 - 5 files changed, 3 insertions(+), 73 deletions(-) delete mode 100644 x/mint/keeper/integration_test.go diff --git a/app/test_helpers.go b/app/test_helpers.go index 2e2288f0f..a04e6b87e 100644 --- a/app/test_helpers.go +++ b/app/test_helpers.go @@ -88,8 +88,7 @@ func Setup(t *testing.T) *App { Coins: sdk.NewCoins(sdk.NewCoin(appparams.BondDenom, sdk.NewInt(100000000000000))), } - chainID := "testing" - app := SetupWithGenesisValSet(t, valSet, []authtypes.GenesisAccount{acc}, chainID, balance) + app := SetupWithGenesisValSet(t, valSet, []authtypes.GenesisAccount{acc}, balance) return app } @@ -98,7 +97,7 @@ func Setup(t *testing.T) *App { // that also act as delegators. For simplicity, each validator is bonded with a delegation // of one consensus engine unit in the default token of the JunoApp from first genesis // account. A Nop logger is set in JunoApp. -func SetupWithGenesisValSet(t *testing.T, valSet *tmtypes.ValidatorSet, genAccs []authtypes.GenesisAccount, chainId string, balances ...banktypes.Balance) *App { +func SetupWithGenesisValSet(t *testing.T, valSet *tmtypes.ValidatorSet, genAccs []authtypes.GenesisAccount, balances ...banktypes.Balance) *App { t.Helper() junoApp, genesisState := setup(t, true) @@ -171,7 +170,6 @@ func genesisStateWithValSet(t *testing.T, valSet *tmtypes.ValidatorSet, genAccs []authtypes.GenesisAccount, balances ...banktypes.Balance, ) GenesisState { - codec := app.AppCodec() // set genesis accounts diff --git a/interchaintest/ibc_transfer_test.go b/interchaintest/ibc_transfer_test.go index f6af4c706..78799ba97 100644 --- a/interchaintest/ibc_transfer_test.go +++ b/interchaintest/ibc_transfer_test.go @@ -34,7 +34,6 @@ func TestJunoGaiaIBCTransfer(t *testing.T) { ChainConfig: junoConfig, NumValidators: &numVals, NumFullNodes: &numFullNodes, - }, { Name: "gaia", diff --git a/x/globalfee/ante/antetest/fee_test_setup.go b/x/globalfee/ante/antetest/fee_test_setup.go index 3d98ee062..93112a7f2 100644 --- a/x/globalfee/ante/antetest/fee_test_setup.go +++ b/x/globalfee/ante/antetest/fee_test_setup.go @@ -13,7 +13,6 @@ import ( stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/stretchr/testify/suite" - // gaiahelpers "github.com/CosmosContracts/juno/v15/app/helpers" "github.com/CosmosContracts/juno/v15/app" gaiafeeante "github.com/CosmosContracts/juno/v15/x/globalfee/ante" @@ -31,11 +30,6 @@ type IntegrationTestSuite struct { txBuilder client.TxBuilder } -var ( - testBondDenom = "uatom" - testMaxTotalBypassMinFeeMsgGasUsage uint64 = 1_000_000 -) - func (s *IntegrationTestSuite) SetupTest() { app := app.Setup(s.T()) ctx := app.BaseApp.NewContext(false, tmproto.Header{ @@ -59,7 +53,7 @@ func (s *IntegrationTestSuite) SetupTestGlobalFeeStoreAndMinGasPrice(minGasPrice // set staking params stakingParam := stakingtypes.DefaultParams() - stakingParam.BondDenom = testBondDenom + stakingParam.BondDenom = "uatom" stakingSubspace := s.SetupTestStakingSubspace(stakingParam) // build fee decorator diff --git a/x/mint/keeper/integration_test.go b/x/mint/keeper/integration_test.go deleted file mode 100644 index 5b3e5be34..000000000 --- a/x/mint/keeper/integration_test.go +++ /dev/null @@ -1,59 +0,0 @@ -package keeper_test - -import ( - "encoding/json" - - "github.com/CosmWasm/wasmd/x/wasm" - dbm "github.com/cometbft/cometbft-db" - abci "github.com/cometbft/cometbft/abci/types" - "github.com/cometbft/cometbft/libs/log" - simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" - - junoapp "github.com/CosmosContracts/juno/v15/app" -) - -func setup(isCheckTx bool) *junoapp.App { - app, genesisState := genApp(!isCheckTx) - if !isCheckTx { - // init chain must be called to stop deliverState from being nil - stateBytes, err := json.MarshalIndent(genesisState, "", " ") - if err != nil { - panic(err) - } - - // Initialize the chain - app.InitChain( - abci.RequestInitChain{ - Validators: []abci.ValidatorUpdate{}, - ConsensusParams: simtestutil.DefaultConsensusParams, - AppStateBytes: stateBytes, - ChainId: "testing", - }, - ) - } - - return app -} - -func genApp(withGenesis bool) (*junoapp.App, junoapp.GenesisState) { - db := dbm.NewMemDB() - encCdc := junoapp.MakeEncodingConfig() - - var emptyWasmOpts []wasm.Option - - app := junoapp.New( - log.NewNopLogger(), - db, - nil, - true, - wasm.EnableAllProposals, - simtestutil.EmptyAppOptions{}, - emptyWasmOpts, - ) - - if withGenesis { - return app, junoapp.NewDefaultGenesisState(encCdc.Marshaler) - } - - return app, junoapp.GenesisState{} -} diff --git a/x/tokenfactory/bindings/message_plugin.go b/x/tokenfactory/bindings/message_plugin.go index 93fa08c95..835035059 100644 --- a/x/tokenfactory/bindings/message_plugin.go +++ b/x/tokenfactory/bindings/message_plugin.go @@ -96,12 +96,10 @@ func PerformCreateDenom(f *tokenfactorykeeper.Keeper, b *bankkeeper.BaseKeeper, } // Create denom - // TODO: issue here: nil key on Store resp, err := msgServer.CreateDenom( sdk.WrapSDKContext(ctx), msgCreateDenom, ) - if err != nil { return nil, errorsmod.Wrap(err, "creating denom") } From d82d468e4496b2cd126e2dfc94e0943e41975438 Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Thu, 11 May 2023 13:31:36 -0500 Subject: [PATCH 084/131] comments --- .github/workflows/build.yml | 6 ++++-- Makefile | 2 +- go.mod | 8 ++++---- interchaintest/go.mod | 3 +-- scripts/statesync.bash | 1 + 5 files changed, 11 insertions(+), 9 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b4e215670..bf728ce2c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,14 +1,16 @@ --- +name: build + on: push: paths: - '**.go' - 'go.sum' - pull_request: + pull_request: + types: [review_requested, closed, auto_merge_enabled] paths: - '**.go' - 'go.sum' -name: build concurrency: group: ${{ github.workflow }}-${{ github.ref }} diff --git a/Makefile b/Makefile index a44bf5f2d..ca0db3e41 100644 --- a/Makefile +++ b/Makefile @@ -17,7 +17,7 @@ endif PACKAGES_SIMTEST=$(shell go list ./... | grep '/simulation') LEDGER_ENABLED ?= true SDK_PACK := $(shell go list -m github.com/cosmos/cosmos-sdk | sed 's/ /\@/g') -BFT_VERSION := $(shell go list -m github.com/cometbft/cometbft | sed 's:.* ::') # grab everything after the space in "github.com/tendermint/tendermint v0.34.7" +BFT_VERSION := $(shell go list -m github.com/cometbft/cometbft | sed 's:.* ::') # grab everything after the space in "github.com/cometbft/cometbft v0.34.7" DOCKER := $(shell which docker) DOCKER_BUF := $(DOCKER) run --rm -v $(CURDIR):/workspace --workdir /workspace bufbuild/buf:1.0.0-rc8 BUILDDIR ?= $(CURDIR)/build diff --git a/go.mod b/go.mod index 97c7a5e5c..fb5b54040 100644 --- a/go.mod +++ b/go.mod @@ -21,7 +21,6 @@ require ( github.com/strangelove-ventures/async-icq/v7 v7.0.0-20230413165143-a3b65ccdc897 github.com/strangelove-ventures/packet-forward-middleware/v7 v7.0.0-20230412224111-136e94e98861 github.com/stretchr/testify v1.8.2 - // github.com/tendermint/tm-db v0.6.8-0.20220506192307-f628bb5dc95b google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 google.golang.org/grpc v1.54.0 gopkg.in/yaml.v2 v2.4.0 @@ -44,6 +43,7 @@ require ( github.com/cosmos/ics23/go v0.10.0 // indirect github.com/cosmos/rosetta-sdk-go v0.10.0 // indirect github.com/gogo/googleapis v1.4.1 // indirect + // TODO: migrate to cosmos/gogoproto per SDK v47 upgrade guide github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/mock v1.6.0 // indirect github.com/google/uuid v1.3.0 // indirect @@ -70,7 +70,7 @@ require ( ) require ( - cosmossdk.io/api v0.3.1 // indirect + cosmossdk.io/api v0.3.1 cosmossdk.io/core v0.5.1 // indirect cosmossdk.io/depinject v1.0.0-alpha.3 // indirect filippo.io/edwards25519 v1.0.0 // indirect @@ -185,7 +185,6 @@ replace ( // ibc hooks only requires the ibc.go file from osmoutils // github.com/CosmosContracts/juno/v15/osmoutils => ./osmoutils - // github.com/cosmos/cosmos-sdk => github.com/notional-labs/cosmos-sdk v0.47.2-0.20230424060617-ebc292e8de8b // dgrijalva/jwt-go is deprecated and doesn't receive security updates. // TODO: remove it: https://github.com/cosmos/cosmos-sdk/issues/13134 github.com/dgrijalva/jwt-go => github.com/golang-jwt/jwt/v4 v4.4.2 @@ -193,6 +192,7 @@ replace ( // TODO Remove it: https://github.com/cosmos/cosmos-sdk/issues/10409 github.com/gin-gonic/gin => github.com/gin-gonic/gin v1.8.1 - // pin the version of goleveldb to v1.0.1-0.20210819022825-2ae1ddf74ef7 + // https://github.com/cosmos/cosmos-sdk/issues/14949 + // pin the version of goleveldb to v1.0.1-0.20210819022825-2ae1ddf74ef7 required by SDK v47 upgrade guide. github.com/syndtr/goleveldb => github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 ) diff --git a/interchaintest/go.mod b/interchaintest/go.mod index 1d2c78798..4792a6f88 100644 --- a/interchaintest/go.mod +++ b/interchaintest/go.mod @@ -16,8 +16,7 @@ replace ( github.com/vedhavyas/go-subkey => github.com/strangelove-ventures/go-subkey v1.0.7 ) -require ( - // cosmossdk.io/simapp v0.0.0-20230224204036-a6adb0821462 +require ( github.com/CosmWasm/wasmd v0.40.0-rc.1.0.20230422061626-b85abcf1d7b8 github.com/CosmosContracts/juno/v15 v15.0.0-00010101000000-000000000000 github.com/cosmos/cosmos-sdk v0.47.2 diff --git a/scripts/statesync.bash b/scripts/statesync.bash index 09315f7d8..fb3b78c0a 100644 --- a/scripts/statesync.bash +++ b/scripts/statesync.bash @@ -8,6 +8,7 @@ export GOPATH=~/go export PATH=$PATH:~/go/bin # Install Juno with pebbledb +# TODO: use github.com/cometbft/cometbft-db # go mod edit -replace github.com/tendermint/tm-db=github.com/notional-labs/tm-db@136c7b6 go mod tidy go install -ldflags '-w -s -X github.com/cosmos/cosmos-sdk/types.DBBackend=pebbledb' -tags pebbledb ./... From fe1792a95d3d621833c53cc7480af19709c99988 Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Thu, 11 May 2023 13:31:51 -0500 Subject: [PATCH 085/131] remove ante gov filter (v47 does in gov mod) --- app/ante.go | 1 - app/decorators/gov_filter.go | 94 ------------------------------------ 2 files changed, 95 deletions(-) delete mode 100644 app/decorators/gov_filter.go diff --git a/app/ante.go b/app/ante.go index 69da4e06f..8120e3b36 100644 --- a/app/ante.go +++ b/app/ante.go @@ -76,7 +76,6 @@ func NewAnteHandler(options HandlerOptions) (sdk.AnteHandler, error) { wasmkeeper.NewCountTXDecorator(options.TxCounterStoreKey), ante.NewExtensionOptionsDecorator(options.ExtensionOptionChecker), decorators.MsgFilterDecorator{}, - decorators.NewGovPreventSpamDecorator(options.Cdc, options.GovKeeper), ante.NewValidateBasicDecorator(), ante.NewTxTimeoutHeightDecorator(), ante.NewValidateMemoDecorator(options.AccountKeeper), diff --git a/app/decorators/gov_filter.go b/app/decorators/gov_filter.go deleted file mode 100644 index d18ea2cc2..000000000 --- a/app/decorators/gov_filter.go +++ /dev/null @@ -1,94 +0,0 @@ -package decorators - -import ( - errorsmod "cosmossdk.io/errors" - "github.com/cosmos/cosmos-sdk/codec" - sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - "github.com/cosmos/cosmos-sdk/x/authz" - govkeeper "github.com/cosmos/cosmos-sdk/x/gov/keeper" - govv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" -) - -var MiniumInitialDepositRate = sdk.NewDecWithPrec(20, 2) - -type GovPreventSpamDecorator struct { - govKeeper govkeeper.Keeper - cdc codec.BinaryCodec -} - -func NewGovPreventSpamDecorator(cdc codec.BinaryCodec, govKeeper govkeeper.Keeper) GovPreventSpamDecorator { - return GovPreventSpamDecorator{ - govKeeper: govKeeper, - cdc: cdc, - } -} - -func (gpsd GovPreventSpamDecorator) AnteHandle( - ctx sdk.Context, tx sdk.Tx, - simulate bool, next sdk.AnteHandler, -) (newCtx sdk.Context, err error) { - if DefaultIsAppSimulation { - return next(ctx, tx, simulate) - } - msgs := tx.GetMsgs() - - err = gpsd.checkSpamSubmitProposalMsg(ctx, msgs) - - if err != nil { - return ctx, err - } - - return next(ctx, tx, simulate) -} - -func (gpsd GovPreventSpamDecorator) checkSpamSubmitProposalMsg(ctx sdk.Context, msgs []sdk.Msg) error { - validMsg := func(m sdk.Msg) error { - if msg, ok := m.(*govv1.MsgSubmitProposal); ok { - // prevent spam gov msg - depositParams := gpsd.govKeeper.GetParams(ctx) - miniumInitialDeposit := gpsd.calcMiniumInitialDeposit(depositParams.MinDeposit) - for _, coin := range msg.InitialDeposit { - if coin.Amount.LT(miniumInitialDeposit.AmountOf(coin.Denom)) { - return errorsmod.Wrapf(sdkerrors.ErrUnauthorized, "not enough initial deposit. required: %v", miniumInitialDeposit) - } - } - } - return nil - } - - // Check every msg in the tx, if it's a MsgExec, check the inner msgs. - // If it's a MsgSubmitProposal, check the initial deposit is enough. - for _, m := range msgs { - var innerMsg sdk.Msg - if msg, ok := m.(*authz.MsgExec); ok { - for _, v := range msg.Msgs { - err := gpsd.cdc.UnpackAny(v, &innerMsg) - if err != nil { - return errorsmod.Wrapf(sdkerrors.ErrUnauthorized, "cannot unmarshal authz exec msgs") - } - - err = validMsg(innerMsg) - if err != nil { - return err - } - } - } else { - err := validMsg(m) - if err != nil { - return err - } - } - } - - return nil -} - -func (gpsd GovPreventSpamDecorator) calcMiniumInitialDeposit(minDeposit sdk.Coins) (miniumInitialDeposit sdk.Coins) { - for _, coin := range minDeposit { - miniumInitialCoin := MiniumInitialDepositRate.MulInt(coin.Amount).RoundInt() - miniumInitialDeposit = miniumInitialDeposit.Add(sdk.NewCoin(coin.Denom, miniumInitialCoin)) - } - - return -} From d729914814ff3b60e380799b0110b0df9d44a944 Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Thu, 11 May 2023 13:32:18 -0500 Subject: [PATCH 086/131] Add newer gRPC service support --- app/app.go | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/app/app.go b/app/app.go index f51fed62d..56e652a13 100644 --- a/app/app.go +++ b/app/app.go @@ -7,6 +7,8 @@ import ( "strconv" "strings" + autocliv1 "cosmossdk.io/api/cosmos/autocli/v1" + reflectionv1 "cosmossdk.io/api/cosmos/reflection/v1" "github.com/CosmosContracts/juno/v15/app/openapiconsole" "github.com/CosmosContracts/juno/v15/docs" dbm "github.com/cometbft/cometbft-db" @@ -21,6 +23,7 @@ import ( "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/codec/types" "github.com/cosmos/cosmos-sdk/runtime" + runtimeservices "github.com/cosmos/cosmos-sdk/runtime/services" "github.com/cosmos/cosmos-sdk/server/api" "github.com/cosmos/cosmos-sdk/server/config" servertypes "github.com/cosmos/cosmos-sdk/server/types" @@ -304,6 +307,14 @@ func New( // register upgrade app.setupUpgradeHandlers(cfg) + // SDK v47 - since we do not use dep inject, this gives us access to newer gRPC services. + autocliv1.RegisterQueryServer(app.GRPCQueryRouter(), runtimeservices.NewAutoCLIQueryService(app.ModuleManager.Modules)) + reflectionSvc, err := runtimeservices.NewReflectionService() + if err != nil { + panic(err) + } + reflectionv1.RegisterReflectionServiceServer(app.GRPCQueryRouter(), reflectionSvc) + wasmConfig, err := wasm.ReadWasmConfig(appOpts) if err != nil { panic("error while reading wasm config: " + err.Error()) From e6836c9dff7eca5f4e54e722071df97bde17ce06 Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Thu, 11 May 2023 13:32:43 -0500 Subject: [PATCH 087/131] Remove staking subspace, hardcode ujuno for now --- x/globalfee/ante/fee.go | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/x/globalfee/ante/fee.go b/x/globalfee/ante/fee.go index d11e91014..7bb364973 100644 --- a/x/globalfee/ante/fee.go +++ b/x/globalfee/ante/fee.go @@ -8,7 +8,6 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" - stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/CosmosContracts/juno/v15/x/globalfee" "github.com/CosmosContracts/juno/v15/x/globalfee/types" @@ -28,9 +27,10 @@ import ( var _ sdk.AnteDecorator = FeeDecorator{} type FeeDecorator struct { - BypassMinFeeMsgTypes []string - GlobalMinFee globalfee.ParamSource - StakingSubspace paramtypes.Subspace + BypassMinFeeMsgTypes []string + GlobalMinFee globalfee.ParamSource + // TODO: we do not use subspaces anymore. Get it from the module still though + // StakingSubspace paramtypes.Subspace MaxTotalBypassMinFeeMsgGasUsage uint64 } @@ -44,9 +44,9 @@ func NewFeeDecorator(bypassMsgTypes []string, globalfeeSubspace, stakingSubspace } return FeeDecorator{ - BypassMinFeeMsgTypes: bypassMsgTypes, - GlobalMinFee: globalfeeSubspace, - StakingSubspace: stakingSubspace, + BypassMinFeeMsgTypes: bypassMsgTypes, + GlobalMinFee: globalfeeSubspace, + // StakingSubspace: stakingSubspace, MaxTotalBypassMinFeeMsgGasUsage: maxTotalBypassMinFeeMsgGasUsage, } } @@ -182,12 +182,13 @@ func (mfd FeeDecorator) DefaultZeroGlobalFee(ctx sdk.Context) ([]sdk.DecCoin, er } func (mfd FeeDecorator) getBondDenom(ctx sdk.Context) string { - var bondDenom string - if mfd.StakingSubspace.Has(ctx, stakingtypes.KeyBondDenom) { - mfd.StakingSubspace.Get(ctx, stakingtypes.KeyBondDenom, &bondDenom) - } - - return bondDenom + // TODO: + // var bondDenom string + // if mfd.StakingSubspace.Has(ctx, stakingtypes.KeyBondDenom) { + // mfd.StakingSubspace.Get(ctx, stakingtypes.KeyBondDenom, &bondDenom) + // } + // return bondDenom + return "ujuno" } // ContainsOnlyBypassMinFeeMsgs returns true if all the given msgs type are listed From 64f29cd6f70f6754b8729afa66563b5df059716c Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Thu, 11 May 2023 13:33:01 -0500 Subject: [PATCH 088/131] remove broadcastest events which are now in baseapp --- x/feeshare/keeper/msg_server.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/x/feeshare/keeper/msg_server.go b/x/feeshare/keeper/msg_server.go index 2b72f7755..d52b8dcf8 100644 --- a/x/feeshare/keeper/msg_server.go +++ b/x/feeshare/keeper/msg_server.go @@ -153,7 +153,7 @@ func (k Keeper) RegisterFeeShare( sdk.Events{ sdk.NewEvent( types.EventTypeRegisterFeeShare, - sdk.NewAttribute(sdk.AttributeKeySender, msg.DeployerAddress), + // sdk.NewAttribute(sdk.AttributeKeySender, msg.DeployerAddress), // SDK v47 sdk.NewAttribute(types.AttributeKeyContract, msg.ContractAddress), sdk.NewAttribute(types.AttributeKeyWithdrawerAddress, msg.WithdrawerAddress), ), @@ -226,8 +226,8 @@ func (k Keeper) UpdateFeeShare( sdk.Events{ sdk.NewEvent( types.EventTypeUpdateFeeShare, + // sdk.NewAttribute(sdk.AttributeKeySender, msg.DeployerAddress), // SDK v47 sdk.NewAttribute(types.AttributeKeyContract, msg.ContractAddress), - sdk.NewAttribute(sdk.AttributeKeySender, msg.DeployerAddress), sdk.NewAttribute(types.AttributeKeyWithdrawerAddress, msg.WithdrawerAddress), ), }, @@ -284,7 +284,7 @@ func (k Keeper) CancelFeeShare( sdk.Events{ sdk.NewEvent( types.EventTypeCancelFeeShare, - sdk.NewAttribute(sdk.AttributeKeySender, msg.DeployerAddress), + // sdk.NewAttribute(sdk.AttributeKeySender, msg.DeployerAddress), // SDK v47 sdk.NewAttribute(types.AttributeKeyContract, msg.ContractAddress), ), }, From 1c3bac7e77427dd57270ad9107127f151f3131bc Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Thu, 11 May 2023 13:33:26 -0500 Subject: [PATCH 089/131] Add rough outline for v47 upgrade handler + hide paramsKeeper.Subspace --- app/keepers/keepers.go | 37 ++++++++++++---------- app/upgrades/v15/constants.go | 3 ++ app/upgrades/v15/upgrades.go | 59 +++++++++++++++++++++++++++++++++++ 3 files changed, 83 insertions(+), 16 deletions(-) diff --git a/app/keepers/keepers.go b/app/keepers/keepers.go index f563733d2..8578fbe9a 100644 --- a/app/keepers/keepers.go +++ b/app/keepers/keepers.go @@ -191,8 +191,10 @@ func NewAppKeepers( tkeys[paramstypes.TStoreKey], ) + govModAddress := authtypes.NewModuleAddress(govtypes.ModuleName).String() + // set the BaseApp's parameter store - appKeepers.ConsensusParamsKeeper = consensusparamkeeper.NewKeeper(appCodec, keys[consensusparamtypes.StoreKey], authtypes.NewModuleAddress(govtypes.ModuleName).String()) + appKeepers.ConsensusParamsKeeper = consensusparamkeeper.NewKeeper(appCodec, keys[consensusparamtypes.StoreKey], govModAddress) bApp.SetParamStore(&appKeepers.ConsensusParamsKeeper) // add capability keeper and ScopeToModule for ibc module @@ -218,7 +220,7 @@ func NewAppKeepers( authtypes.ProtoBaseAccount, maccPerms, Bech32Prefix, - authtypes.NewModuleAddress(govtypes.ModuleName).String(), + govModAddress, ) appKeepers.BankKeeper = bankkeeper.NewBaseKeeper( @@ -226,7 +228,7 @@ func NewAppKeepers( keys[banktypes.StoreKey], appKeepers.AccountKeeper, BlockedAddresses(), - authtypes.NewModuleAddress(govtypes.ModuleName).String(), + govModAddress, ) stakingKeeper := stakingkeeper.NewKeeper( @@ -234,7 +236,7 @@ func NewAppKeepers( appKeepers.keys[stakingtypes.StoreKey], appKeepers.AccountKeeper, appKeepers.BankKeeper, - authtypes.NewModuleAddress(govtypes.ModuleName).String(), + govModAddress, ) appKeepers.MintKeeper = mintkeeper.NewKeeper( appCodec, @@ -252,14 +254,14 @@ func NewAppKeepers( appKeepers.BankKeeper, stakingKeeper, authtypes.FeeCollectorName, - authtypes.NewModuleAddress(govtypes.ModuleName).String(), + govModAddress, ) appKeepers.SlashingKeeper = slashingkeeper.NewKeeper( appCodec, cdc, appKeepers.keys[slashingtypes.StoreKey], stakingKeeper, - authtypes.NewModuleAddress(govtypes.ModuleName).String(), + govModAddress, ) invCheckPeriod := cast.ToUint(appOpts.Get(server.FlagInvCheckPeriod)) @@ -269,7 +271,7 @@ func NewAppKeepers( invCheckPeriod, appKeepers.BankKeeper, authtypes.FeeCollectorName, - authtypes.NewModuleAddress(govtypes.ModuleName).String(), + govModAddress, ) skipUpgradeHeights := map[int64]bool{} @@ -284,7 +286,7 @@ func NewAppKeepers( appCodec, homePath, bApp, - authtypes.NewModuleAddress(govtypes.ModuleName).String(), + govModAddress, ) // register the staking hooks @@ -335,7 +337,7 @@ func NewAppKeepers( appKeepers.StakingKeeper, bApp.MsgServiceRouter(), govtypes.DefaultConfig(), - authtypes.NewModuleAddress(govtypes.ModuleName).String(), + govModAddress, ) appKeepers.GovKeeper = *govKeeper.SetHooks( govtypes.NewMultiGovHooks( @@ -509,7 +511,7 @@ func NewAppKeepers( wasmDir, wasmConfig, wasmCapabilities, - authtypes.NewModuleAddress(govtypes.ModuleName).String(), + govModAddress, wasmOpts..., ) @@ -584,14 +586,17 @@ func NewAppKeepers( func initParamsKeeper(appCodec codec.BinaryCodec, legacyAmino *codec.LegacyAmino, key, tkey storetypes.StoreKey) paramskeeper.Keeper { paramsKeeper := paramskeeper.NewKeeper(appCodec, legacyAmino, key, tkey) - paramsKeeper.Subspace(authtypes.ModuleName) - paramsKeeper.Subspace(banktypes.ModuleName) + // https://github.com/cosmos/ibc-go/issues/2010 + // can remove all since v47 moves all params to each module + // paramsKeeper.Subspace(authtypes.ModuleName) + // paramsKeeper.Subspace(banktypes.ModuleName) + // paramsKeeper.Subspace(distrtypes.ModuleName) + // paramsKeeper.Subspace(slashingtypes.ModuleName) + // paramsKeeper.Subspace(govtypes.ModuleName) + // paramsKeeper.Subspace(crisistypes.ModuleName) + paramsKeeper.Subspace(stakingtypes.ModuleName).WithKeyTable(stakingtypes.ParamKeyTable()) // Used for GlobalFee paramsKeeper.Subspace(minttypes.ModuleName) - paramsKeeper.Subspace(distrtypes.ModuleName) - paramsKeeper.Subspace(slashingtypes.ModuleName) - paramsKeeper.Subspace(govtypes.ModuleName) - paramsKeeper.Subspace(crisistypes.ModuleName) // custom paramsKeeper.Subspace(ibctransfertypes.ModuleName) diff --git a/app/upgrades/v15/constants.go b/app/upgrades/v15/constants.go index 0de8612c8..9b1c7d401 100644 --- a/app/upgrades/v15/constants.go +++ b/app/upgrades/v15/constants.go @@ -17,7 +17,10 @@ var Upgrade = upgrades.Upgrade{ CreateUpgradeHandler: CreateV15UpgradeHandler, StoreUpgrades: store.StoreUpgrades{ Added: []string{ + // new module icqtypes.ModuleName, + + // v47 module upgrades crisistypes.ModuleName, consensustypes.ModuleName, }, diff --git a/app/upgrades/v15/upgrades.go b/app/upgrades/v15/upgrades.go index cc53108b0..3cc4b8dea 100644 --- a/app/upgrades/v15/upgrades.go +++ b/app/upgrades/v15/upgrades.go @@ -4,6 +4,7 @@ import ( "fmt" "github.com/CosmosContracts/juno/v15/app/keepers" + "github.com/cosmos/cosmos-sdk/baseapp" "github.com/CosmosContracts/juno/v15/app/upgrades" sdk "github.com/cosmos/cosmos-sdk/types" @@ -13,6 +14,18 @@ import ( upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" icqtypes "github.com/strangelove-ventures/async-icq/v7/types" + + // SDK v47 modules + // minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + crisistypes "github.com/cosmos/cosmos-sdk/x/crisis/types" + distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + govv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" + paramstypes "github.com/cosmos/cosmos-sdk/x/params/types" + slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" ) // We now charge 2 million gas * gas price to create a denom. @@ -26,9 +39,49 @@ func CreateV15UpgradeHandler( return func(ctx sdk.Context, _ upgradetypes.Plan, vm module.VersionMap) (module.VersionMap, error) { logger := ctx.Logger().With("upgrade", UpgradeName) + // TODO: Add postHandler (like antehandler but runs after runMsgs) + nativeDenom := upgrades.GetChainsDenomToken(ctx.ChainID()) logger.Info(fmt.Sprintf("With native denom %s", nativeDenom)) + // TODO: Our mint module needs to be migrated to v47 for minttypes.ModuleName + // https://github.com/cosmos/cosmos-sdk/pull/12363/files + // Set param key table for params module migration + for _, subspace := range keepers.ParamsKeeper.GetSubspaces() { + subspace := subspace + + var keyTable paramstypes.KeyTable + switch subspace.Name() { + case authtypes.ModuleName: + keyTable = authtypes.ParamKeyTable() //nolint:staticcheck + case banktypes.ModuleName: + keyTable = banktypes.ParamKeyTable() //nolint:staticcheck + case stakingtypes.ModuleName: + keyTable = stakingtypes.ParamKeyTable() //nolint:staticcheck + // TODO: mint module v47? + // case minttypes.ModuleName: + // keyTable = minttypes.ParamKeyTable() //nolint:staticcheck + case distrtypes.ModuleName: + keyTable = distrtypes.ParamKeyTable() //nolint:staticcheck + case slashingtypes.ModuleName: + keyTable = slashingtypes.ParamKeyTable() //nolint:staticcheck + case govtypes.ModuleName: + keyTable = govv1.ParamKeyTable() //nolint:staticcheck + case crisistypes.ModuleName: + keyTable = crisistypes.ParamKeyTable() //nolint:staticcheck + } + + if !subspace.HasKeyTable() { + subspace.WithKeyTable(keyTable) + } + } + + // Migrate Tendermint consensus parameters from x/params module to a + // x/consensus module. + // The old params module is required to still be imported in your app.go in order to handle this migration. + baseAppLegacySS := keepers.ParamsKeeper.Subspace(baseapp.Paramspace).WithKeyTable(paramstypes.ConsensusParamsKeyTable()) + baseapp.MigrateParams(ctx, baseAppLegacySS, &keepers.ConsensusParamsKeeper) + // Run migrations logger.Info(fmt.Sprintf("pre migrate version map: %v", vm)) versionMap, err := mm.RunMigrations(ctx, cfg, vm) @@ -43,6 +96,12 @@ func CreateV15UpgradeHandler( icqParams := icqtypes.NewParams(true, nil) keepers.ICQKeeper.SetParams(ctx, icqParams) + // update gov params to use a 20% initial deposit ratio, allowing us to remote the ante handler + // TODO: Add test for this + govParams := keepers.GovKeeper.GetParams(ctx) + govParams.MinInitialDepositRatio = sdk.NewDec(20).Quo(sdk.NewDec(100)).String() + keepers.GovKeeper.SetParams(ctx, govParams) + // x/TokenFactory // Use denom creation gas consumtion instead of fee for contract developers updatedTf := tokenfactorytypes.Params{ From c5c5faf9fb9e426b7841883d50ca6cca244782f1 Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Thu, 11 May 2023 13:34:20 -0500 Subject: [PATCH 090/131] lint --- app/upgrades/v15/upgrades.go | 4 +++- x/globalfee/ante/fee.go | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/app/upgrades/v15/upgrades.go b/app/upgrades/v15/upgrades.go index 3cc4b8dea..3d02dc70e 100644 --- a/app/upgrades/v15/upgrades.go +++ b/app/upgrades/v15/upgrades.go @@ -100,7 +100,9 @@ func CreateV15UpgradeHandler( // TODO: Add test for this govParams := keepers.GovKeeper.GetParams(ctx) govParams.MinInitialDepositRatio = sdk.NewDec(20).Quo(sdk.NewDec(100)).String() - keepers.GovKeeper.SetParams(ctx, govParams) + if err := keepers.GovKeeper.SetParams(ctx, govParams); err != nil { + return nil, err + } // x/TokenFactory // Use denom creation gas consumtion instead of fee for contract developers diff --git a/x/globalfee/ante/fee.go b/x/globalfee/ante/fee.go index 7bb364973..7449609c9 100644 --- a/x/globalfee/ante/fee.go +++ b/x/globalfee/ante/fee.go @@ -181,7 +181,7 @@ func (mfd FeeDecorator) DefaultZeroGlobalFee(ctx sdk.Context) ([]sdk.DecCoin, er return []sdk.DecCoin{sdk.NewDecCoinFromDec(bondDenom, sdk.NewDec(0))}, nil } -func (mfd FeeDecorator) getBondDenom(ctx sdk.Context) string { +func (mfd FeeDecorator) getBondDenom(_ sdk.Context) string { // TODO: // var bondDenom string // if mfd.StakingSubspace.Has(ctx, stakingtypes.KeyBondDenom) { From 7e54dbb867973a8849ad475965e3712e2151ef67 Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Thu, 11 May 2023 14:51:27 -0500 Subject: [PATCH 091/131] fix ictest gas issues (my fork) --- interchaintest/go.mod | 7 ++++++- interchaintest/go.sum | 4 ++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/interchaintest/go.mod b/interchaintest/go.mod index 4792a6f88..010c32436 100644 --- a/interchaintest/go.mod +++ b/interchaintest/go.mod @@ -13,10 +13,15 @@ replace ( github.com/CosmosContracts/juno/v15 => github.com/CosmosContracts/juno/v15 v15.0.0-20230510202630-e1183eb692f6 github.com/btcsuite/btcd => github.com/btcsuite/btcd v0.22.2 //indirect github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 + + // Fixes gas issues in ictest + // go get github.com/Reecepbcups/interchaintest@83b50de71a69f3c463a7d809b8f1c02762fb4114 + github.com/strangelove-ventures/interchaintest/v7 => github.com/Reecepbcups/interchaintest/v7 v7.0.0-20230511194528-83b50de71a69 github.com/vedhavyas/go-subkey => github.com/strangelove-ventures/go-subkey v1.0.7 + ) -require ( +require ( github.com/CosmWasm/wasmd v0.40.0-rc.1.0.20230422061626-b85abcf1d7b8 github.com/CosmosContracts/juno/v15 v15.0.0-00010101000000-000000000000 github.com/cosmos/cosmos-sdk v0.47.2 diff --git a/interchaintest/go.sum b/interchaintest/go.sum index 04194670d..6191f8757 100644 --- a/interchaintest/go.sum +++ b/interchaintest/go.sum @@ -235,6 +235,8 @@ github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2B 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= +github.com/Reecepbcups/interchaintest/v7 v7.0.0-20230511194528-83b50de71a69 h1:y48srfoyjfPg6KCHFpBOOo/AhFnsM8Att7y+KnZ6Y0M= +github.com/Reecepbcups/interchaintest/v7 v7.0.0-20230511194528-83b50de71a69/go.mod h1:/FpoaMKTF3OREchZZvg6eGfVYvk7lAwqP9q2TN+lOGs= 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 h1:fLjPD/aNc3UIOA6tDi6QXUemppXK3P9BI7mr2hd6gx8= @@ -993,8 +995,6 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/spf13/viper v1.15.0 h1:js3yy885G8xwJa6iOISGFwd+qlUo5AvyXb7CiihdtiU= github.com/spf13/viper v1.15.0/go.mod h1:fFcTBJxvhhzSJiZy8n+PeW6t8l+KeT/uTARa0jHOQLA= -github.com/strangelove-ventures/interchaintest/v7 v7.0.0-20230508154211-ebc1cbd6d88e h1:Hxs0PZQhAtgkyqgl3bTXYkhhYX8OXvHr7z6CjSBclpo= -github.com/strangelove-ventures/interchaintest/v7 v7.0.0-20230508154211-ebc1cbd6d88e/go.mod h1:/FpoaMKTF3OREchZZvg6eGfVYvk7lAwqP9q2TN+lOGs= 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= From 48a209f993d276eb294a3b834ccd3645e32e943b Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Thu, 11 May 2023 14:52:15 -0500 Subject: [PATCH 092/131] Use CreateThisBranchChain for all test (excl IBC) --- interchaintest/chain_start_test.go | 47 +++----------------- interchaintest/contract_unity_deploy_test.go | 2 +- interchaintest/contract_unity_submit_test.go | 2 +- interchaintest/module_feeshare_test.go | 2 +- interchaintest/module_tokenfactory_test.go | 2 +- interchaintest/setup.go | 11 +++-- 6 files changed, 14 insertions(+), 52 deletions(-) diff --git a/interchaintest/chain_start_test.go b/interchaintest/chain_start_test.go index cda463dd4..395fd426d 100644 --- a/interchaintest/chain_start_test.go +++ b/interchaintest/chain_start_test.go @@ -1,14 +1,9 @@ package interchaintest import ( - "context" "testing" - "github.com/strangelove-ventures/interchaintest/v7" - "github.com/strangelove-ventures/interchaintest/v7/chain/cosmos" - "github.com/strangelove-ventures/interchaintest/v7/testreporter" "github.com/stretchr/testify/require" - "go.uber.org/zap/zaptest" ) // TestBasicJunoStart is a basic test to assert that spinning up a Juno network with one validator works properly. @@ -19,44 +14,12 @@ func TestBasicJunoStart(t *testing.T) { t.Parallel() - // Create chain factory with Juno - numVals := 1 - numFullNodes := 1 + // Base setup + chains := CreateThisBranchChain(t, 1, 0) + ic, ctx, _, _ := BuildInitialChain(t, chains) - cf := interchaintest.NewBuiltinChainFactory(zaptest.NewLogger(t), []*interchaintest.ChainSpec{ - { - Name: "juno", - ChainConfig: junoConfig, - NumValidators: &numVals, - NumFullNodes: &numFullNodes, - }, - }) - - // Get chains from the chain factory - chains, err := cf.Chains(t.Name()) - require.NoError(t, err) - - juno := chains[0].(*cosmos.CosmosChain) - - // Create a new Interchain object which describes the chains, relayers, and IBC connections we want to use - ic := interchaintest.NewInterchain().AddChain(juno) - - rep := testreporter.NewNopReporter() - eRep := rep.RelayerExecReporter(t) - - ctx := context.Background() - client, network := interchaintest.DockerSetup(t) - - err = ic.Build(ctx, eRep, interchaintest.InterchainBuildOptions{ - TestName: t.Name(), - Client: client, - NetworkID: network, - SkipPathCreation: true, - - // This can be used to write to the block database which will index all block data e.g. txs, msgs, events, etc. - // BlockDatabaseFile: interchaintest.DefaultBlockDatabaseFilepath(), - }) - require.NoError(t, err) + require.NotNil(t, ic) + require.NotNil(t, ctx) t.Cleanup(func() { _ = ic.Close() diff --git a/interchaintest/contract_unity_deploy_test.go b/interchaintest/contract_unity_deploy_test.go index e2b7a9004..118170a3d 100644 --- a/interchaintest/contract_unity_deploy_test.go +++ b/interchaintest/contract_unity_deploy_test.go @@ -16,7 +16,7 @@ func TestJunoUnityContractDeploy(t *testing.T) { t.Parallel() // Base setup - chains := CreateThisBranchChain(t) + chains := CreateThisBranchChain(t, 1, 0) ic, ctx, _, _ := BuildInitialChain(t, chains) // Chains diff --git a/interchaintest/contract_unity_submit_test.go b/interchaintest/contract_unity_submit_test.go index ecd92c974..e5aed41bd 100644 --- a/interchaintest/contract_unity_submit_test.go +++ b/interchaintest/contract_unity_submit_test.go @@ -18,7 +18,7 @@ func TestJunoUnityContractGovSubmit(t *testing.T) { t.Parallel() // Base setup - chains := CreateThisBranchChain(t) + chains := CreateThisBranchChain(t, 1, 0) ic, ctx, _, _ := BuildInitialChain(t, chains) // Chains diff --git a/interchaintest/module_feeshare_test.go b/interchaintest/module_feeshare_test.go index 6180e9bcd..098346a28 100644 --- a/interchaintest/module_feeshare_test.go +++ b/interchaintest/module_feeshare_test.go @@ -14,7 +14,7 @@ func TestJunoFeeShare(t *testing.T) { t.Parallel() // Base setup - chains := CreateThisBranchChain(t) + chains := CreateThisBranchChain(t, 1, 0) ic, ctx, _, _ := BuildInitialChain(t, chains) // Chains diff --git a/interchaintest/module_tokenfactory_test.go b/interchaintest/module_tokenfactory_test.go index e6462f976..bbfcb9828 100644 --- a/interchaintest/module_tokenfactory_test.go +++ b/interchaintest/module_tokenfactory_test.go @@ -15,7 +15,7 @@ func TestJunoTokenFactory(t *testing.T) { t.Parallel() // Base setup - chains := CreateThisBranchChain(t) + chains := CreateThisBranchChain(t, 1, 0) ic, ctx, _, _ := BuildInitialChain(t, chains) // Chains diff --git a/interchaintest/setup.go b/interchaintest/setup.go index ca88132ef..cac22d9c6 100644 --- a/interchaintest/setup.go +++ b/interchaintest/setup.go @@ -46,7 +46,7 @@ var ( Denom: "ujuno", CoinType: "118", GasPrices: "0ujuno", - GasAdjustment: 1.8, + GasAdjustment: 2.0, TrustingPeriod: "112h", NoHostMount: false, ModifyGenesis: nil, @@ -103,10 +103,8 @@ func CreateBaseChain(t *testing.T) []ibc.Chain { return chains } -func CreateThisBranchChain(t *testing.T) []ibc.Chain { - // Create chain factory with Juno - numVals := 1 - numFullNodes := 0 +func CreateThisBranchChain(t *testing.T, numVals, numFull int) []ibc.Chain { + // Create chain factory with Juno on this current branch // votingPeriod := "10s" // maxDepositPeriod := "10s" @@ -126,11 +124,12 @@ func CreateThisBranchChain(t *testing.T) []ibc.Chain { }, }, GasPrices: "0ujuno", + GasAdjustment: 2.0, Denom: "ujuno", UsingNewGenesisCommand: true, // v47 }, NumValidators: &numVals, - NumFullNodes: &numFullNodes, + NumFullNodes: &numFull, }, }) From a15730c4fd393dcb142fc7d8f346c34e06453886 Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Thu, 11 May 2023 21:49:26 -0500 Subject: [PATCH 093/131] We do wasm integration CI elsewhere now --- .github/workflows/integration.yml | 38 ------------------------------- 1 file changed, 38 deletions(-) delete mode 100644 .github/workflows/integration.yml diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml deleted file mode 100644 index 24c8a7750..000000000 --- a/.github/workflows/integration.yml +++ /dev/null @@ -1,38 +0,0 @@ ---- -name: Contract CI - -on: - pull_request: - paths: - - '**.go' - push: - paths: - - '**.go' - tags: - branches: - - 'main' - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - docker: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - name: Docker compose - run: STAKE_TOKEN="ujunox" TIMEOUT_COMMIT=500ms docker-compose up -d - - name: Checkout - uses: actions/checkout@v3 - with: - repository: 'envoylabs/whoami' - ref: 'v0.7.1-alpha' - - name: Run deploy script - run: | - chmod a+x ./scripts/deploy_ci.sh - ./scripts/deploy_ci.sh - - name: Dump docker logs on failure - if: failure() - uses: jwalton/gh-docker-logs@v2 - From e0ee77a0af84e3994808f97727c07452ab6b038a Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Thu, 11 May 2023 23:31:10 -0500 Subject: [PATCH 094/131] Cleanup node, dep bump, reuse initParamsKeeper --- app/keepers/keepers.go | 24 +++++----- go.mod | 2 +- go.sum | 4 +- interchaintest/chain_upgrade_test.go | 5 +-- interchaintest/go.mod | 2 +- interchaintest/setup.go | 67 +++++++--------------------- scripts/test_node.sh | 4 +- 7 files changed, 37 insertions(+), 71 deletions(-) diff --git a/app/keepers/keepers.go b/app/keepers/keepers.go index 8578fbe9a..afc9f8e21 100644 --- a/app/keepers/keepers.go +++ b/app/keepers/keepers.go @@ -38,7 +38,8 @@ import ( feegrantkeeper "github.com/cosmos/cosmos-sdk/x/feegrant/keeper" govkeeper "github.com/cosmos/cosmos-sdk/x/gov/keeper" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" - govv1beta1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" + govv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" + govv1beta "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" "github.com/cosmos/cosmos-sdk/x/params" paramskeeper "github.com/cosmos/cosmos-sdk/x/params/keeper" paramstypes "github.com/cosmos/cosmos-sdk/x/params/types" @@ -322,8 +323,8 @@ func NewAppKeepers( ) // register the proposal types - govRouter := govv1beta1.NewRouter() - govRouter.AddRoute(govtypes.RouterKey, govv1beta1.ProposalHandler). + govRouter := govv1beta.NewRouter() + govRouter.AddRoute(govtypes.RouterKey, govv1beta.ProposalHandler). AddRoute(paramproposal.RouterKey, params.NewParamChangeProposalHandler(appKeepers.ParamsKeeper)). // This should be removed. It is still in place to avoid failures of modules that have not yet been upgraded AddRoute(upgradetypes.RouterKey, upgrade.NewSoftwareUpgradeProposalHandler(appKeepers.UpgradeKeeper)). AddRoute(ibcclienttypes.RouterKey, ibcclient.NewClientProposalHandler(appKeepers.IBCKeeper.ClientKeeper)) @@ -472,7 +473,7 @@ func NewAppKeepers( "/ibc.core.connection.v1.Query/Connection": &ibcconnectiontypes.QueryConnectionResponse{}, // governance - "/cosmos.gov.v1beta1.Query/Vote": &govv1beta1.QueryVoteResponse{}, + "/cosmos.gov.v1beta1.Query/Vote": &govv1.QueryVoteResponse{}, // distribution "/cosmos.distribution.v1beta1.Query/DelegationRewards": &distrtypes.QueryDelegationRewardsResponse{}, @@ -502,6 +503,7 @@ func NewAppKeepers( appKeepers.BankKeeper, appKeepers.StakingKeeper, distrkeeper.NewQuerier(appKeepers.DistrKeeper), + appKeepers.IBCFeeKeeper, appKeepers.IBCKeeper.ChannelKeeper, &appKeepers.IBCKeeper.PortKeeper, scopedWasmKeeper, @@ -587,13 +589,13 @@ func initParamsKeeper(appCodec codec.BinaryCodec, legacyAmino *codec.LegacyAmino paramsKeeper := paramskeeper.NewKeeper(appCodec, legacyAmino, key, tkey) // https://github.com/cosmos/ibc-go/issues/2010 - // can remove all since v47 moves all params to each module - // paramsKeeper.Subspace(authtypes.ModuleName) - // paramsKeeper.Subspace(banktypes.ModuleName) - // paramsKeeper.Subspace(distrtypes.ModuleName) - // paramsKeeper.Subspace(slashingtypes.ModuleName) - // paramsKeeper.Subspace(govtypes.ModuleName) - // paramsKeeper.Subspace(crisistypes.ModuleName) + // Will remove all of these in the future. For now we keep for legacy proposals to work properly. + paramsKeeper.Subspace(authtypes.ModuleName) + paramsKeeper.Subspace(banktypes.ModuleName) + paramsKeeper.Subspace(distrtypes.ModuleName) + paramsKeeper.Subspace(slashingtypes.ModuleName) + paramsKeeper.Subspace(govtypes.ModuleName) + paramsKeeper.Subspace(crisistypes.ModuleName) paramsKeeper.Subspace(stakingtypes.ModuleName).WithKeyTable(stakingtypes.ParamKeyTable()) // Used for GlobalFee paramsKeeper.Subspace(minttypes.ModuleName) diff --git a/go.mod b/go.mod index fb5b54040..165447dfa 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( cosmossdk.io/errors v1.0.0-beta.7 cosmossdk.io/math v1.0.0 cosmossdk.io/simapp v0.0.0-20230224204036-a6adb0821462 - github.com/CosmWasm/wasmd v0.40.0-rc.1.0.20230422061626-b85abcf1d7b8 + github.com/CosmWasm/wasmd v0.40.0-rc.2 github.com/cometbft/cometbft v0.37.1 github.com/cometbft/cometbft-db v0.7.0 github.com/cosmos/cosmos-sdk v0.47.2 diff --git a/go.sum b/go.sum index 8640a669b..4e0601ae8 100644 --- a/go.sum +++ b/go.sum @@ -224,8 +224,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/wasmd v0.40.0-rc.1.0.20230422061626-b85abcf1d7b8 h1:daJIcrTcYkpDtn1DXqbGhnQkCPSD93El6mXfv15VJRA= -github.com/CosmWasm/wasmd v0.40.0-rc.1.0.20230422061626-b85abcf1d7b8/go.mod h1:uacdue6EGn9JA1TqBNHB3iCe4PCIChuFT23AzIl2VME= +github.com/CosmWasm/wasmd v0.40.0-rc.2 h1:UgOr8CaitJ8C8Y80viKLT6mL2Xh4yg2X4szCdTVr6xg= +github.com/CosmWasm/wasmd v0.40.0-rc.2/go.mod h1:l2s42GHKp1CHcR0N6J8P6p02b5RMWFCpcmRjyKMtqqg= github.com/CosmWasm/wasmvm v1.2.3 h1:OKYlobwmVGbl0eSn0mXoAAjE5hIuXnQCLPjbNd91sVY= github.com/CosmWasm/wasmvm v1.2.3/go.mod h1:vW/E3h8j9xBQs9bCoijDuawKo9kCtxOaS8N8J7KFtkc= github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= diff --git a/interchaintest/chain_upgrade_test.go b/interchaintest/chain_upgrade_test.go index aa6d9f1a7..fd4dacb9c 100644 --- a/interchaintest/chain_upgrade_test.go +++ b/interchaintest/chain_upgrade_test.go @@ -16,8 +16,7 @@ import ( const ( haltHeightDelta = uint64(7) // will propose upgrade this many blocks in the future blocksAfterUpgrade = uint64(10) - votingPeriod = "10s" - maxDepositPeriod = "10s" + ) func TestBasicJunoUpgrade(t *testing.T) { @@ -40,7 +39,7 @@ func CosmosChainUpgradeTest(t *testing.T, chainName, initialVersion, upgradeBran ChainName: chainName, Version: initialVersion, ChainConfig: ibc.ChainConfig{ - ModifyGenesis: modifyGenesisShortProposals(votingPeriod, maxDepositPeriod), + ModifyGenesis: modifyGenesisShortProposals(VotingPeriod, MaxDepositPeriod), Images: []ibc.DockerImage{ { Repository: JunoE2ERepo, diff --git a/interchaintest/go.mod b/interchaintest/go.mod index 010c32436..f37fecfab 100644 --- a/interchaintest/go.mod +++ b/interchaintest/go.mod @@ -96,7 +96,7 @@ require ( github.com/dgraph-io/badger/v2 v2.2007.4 // indirect github.com/dgraph-io/ristretto v0.1.1 // indirect github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect - github.com/docker/distribution v2.8.1+incompatible // indirect + github.com/docker/distribution v2.8.2+incompatible // indirect github.com/docker/go-connections v0.4.0 // indirect github.com/docker/go-units v0.5.0 // indirect github.com/dustin/go-humanize v1.0.1 // indirect diff --git a/interchaintest/setup.go b/interchaintest/setup.go index cac22d9c6..3a7bf4031 100644 --- a/interchaintest/setup.go +++ b/interchaintest/setup.go @@ -25,6 +25,9 @@ import ( ) var ( + VotingPeriod = "25s" + MaxDepositPeriod = "10s" + JunoE2ERepo = "ghcr.io/cosmoscontracts/juno-e2e" JunoMainRepo = "ghcr.io/cosmoscontracts/juno" @@ -49,10 +52,10 @@ var ( GasAdjustment: 2.0, TrustingPeriod: "112h", NoHostMount: false, - ModifyGenesis: nil, ConfigFileOverrides: nil, EncodingConfig: junoEncoding(), UsingNewGenesisCommand: true, + ModifyGenesis: modifyGenesisShortProposals(VotingPeriod, MaxDepositPeriod), } pathJunoGaia = "juno-gaia" @@ -74,60 +77,21 @@ func junoEncoding() *testutil.TestEncodingConfig { return &cfg } -// Basic chain setup for a Juno chain. No relaying -func CreateBaseChain(t *testing.T) []ibc.Chain { - // Create chain factory with Juno - numVals := 1 - numFullNodes := 0 - - cf := interchaintest.NewBuiltinChainFactory(zaptest.NewLogger(t), []*interchaintest.ChainSpec{ - { - Name: "juno", - Version: "latest", - ChainName: "juno1", - ChainConfig: ibc.ChainConfig{ - GasPrices: "0ujuno", - GasAdjustment: 2.0, - EncodingConfig: junoEncoding(), - }, - NumValidators: &numVals, - NumFullNodes: &numFullNodes, - }, - }) +// This allows for us to test +func FundSpecificUsers() { - // Get chains from the chain factory - chains, err := cf.Chains(t.Name()) - require.NoError(t, err) - - // juno := chains[0].(*cosmos.CosmosChain) - return chains } +// Base chain, no relaying off this branch (or juno:local if no branch is provided.) func CreateThisBranchChain(t *testing.T, numVals, numFull int) []ibc.Chain { // Create chain factory with Juno on this current branch - // votingPeriod := "10s" - // maxDepositPeriod := "10s" - cf := interchaintest.NewBuiltinChainFactory(zaptest.NewLogger(t), []*interchaintest.ChainSpec{ { - Name: "juno", - ChainName: "juno", - Version: junoVersion, - ChainConfig: ibc.ChainConfig{ - // ModifyGenesis: modifyGenesisShortProposals(votingPeriod, maxDepositPeriod), - Images: []ibc.DockerImage{ - { - Repository: junoRepo, - Version: junoVersion, - UidGid: JunoImage.UidGid, - }, - }, - GasPrices: "0ujuno", - GasAdjustment: 2.0, - Denom: "ujuno", - UsingNewGenesisCommand: true, // v47 - }, + Name: "juno", + ChainName: "juno", + Version: junoVersion, + ChainConfig: junoConfig, NumValidators: &numVals, NumFullNodes: &numFull, }, @@ -137,7 +101,7 @@ func CreateThisBranchChain(t *testing.T, numVals, numFull int) []ibc.Chain { chains, err := cf.Chains(t.Name()) require.NoError(t, err) - // juno := chains[0].(*cosmos.CosmosChain) + // chain := chains[0].(*cosmos.CosmosChain) return chains } @@ -175,13 +139,14 @@ func modifyGenesisShortProposals(votingPeriod string, maxDepositPeriod string) f if err := json.Unmarshal(genbz, &g); err != nil { return nil, fmt.Errorf("failed to unmarshal genesis file: %w", err) } - if err := dyno.Set(g, votingPeriod, "app_state", "gov", "voting_params", "voting_period"); err != nil { + // v47 puts params in a params field now. + if err := dyno.Set(g, votingPeriod, "app_state", "gov", "params", "voting_period"); err != nil { return nil, fmt.Errorf("failed to set voting period in genesis json: %w", err) } - if err := dyno.Set(g, maxDepositPeriod, "app_state", "gov", "deposit_params", "max_deposit_period"); err != nil { + if err := dyno.Set(g, maxDepositPeriod, "app_state", "gov", "params", "max_deposit_period"); err != nil { return nil, fmt.Errorf("failed to set voting period in genesis json: %w", err) } - if err := dyno.Set(g, chainConfig.Denom, "app_state", "gov", "deposit_params", "min_deposit", 0, "denom"); err != nil { + if err := dyno.Set(g, chainConfig.Denom, "app_state", "gov", "params", "min_deposit", 0, "denom"); err != nil { return nil, fmt.Errorf("failed to set voting period in genesis json: %w", err) } out, err := json.Marshal(g) diff --git a/scripts/test_node.sh b/scripts/test_node.sh index 711df88bf..17aab3cc9 100755 --- a/scripts/test_node.sh +++ b/scripts/test_node.sh @@ -60,7 +60,7 @@ from_scratch () { # Set gas limit in genesis update_test_genesis '.consensus_params["block"]["max_gas"]="100000000"' - update_test_genesis '.app_state["gov"]["voting_params"]["voting_period"]="15s"' + update_test_genesis '.app_state["gov"]["voting_params"]["voting_period"]="150s"' # GlobalFee update_test_genesis '.app_state["globalfee"]["params"]["minimum_gas_prices"]=[{"amount":"0.002500000000000000","denom":"ujuno"}]' @@ -70,7 +70,7 @@ from_scratch () { # update_test_genesis '.app_state["staking"]["params"]["min_commission_rate"]="0.100000000000000000"' # sdk 46 only update_test_genesis '.app_state["mint"]["params"]["mint_denom"]="ujuno"' - update_test_genesis '.app_state["gov"]["deposit_params"]["min_deposit"]=[{"denom": "ujuno","amount": "1000000"}]' + update_test_genesis '.app_state["gov"]["params"]["min_deposit"]=[{"denom": "ujuno","amount": "1000000"}]' update_test_genesis '.app_state["crisis"]["constant_fee"]={"denom": "ujuno","amount": "1000"}' # update_test_genesis '.app_state["tokenfactory"]["params"]["denom_creation_fee"]=[{"denom":"ujuno","amount":"100"}]' From cdfaf6fe259dc8854347531242b35f9939010799 Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Thu, 11 May 2023 23:46:49 -0500 Subject: [PATCH 095/131] gomod tidy ictest --- .github/workflows/interchaintest-E2E.yml | 2 +- interchaintest/go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/interchaintest-E2E.yml b/.github/workflows/interchaintest-E2E.yml index 0a5c8e3a0..0777d9a6f 100644 --- a/.github/workflows/interchaintest-E2E.yml +++ b/.github/workflows/interchaintest-E2E.yml @@ -9,7 +9,7 @@ on: paths: - '**.yml' - '**.go' - - 'go.sum' + - '**.sum' env: REGISTRY: ghcr.io diff --git a/interchaintest/go.sum b/interchaintest/go.sum index 6191f8757..048a31070 100644 --- a/interchaintest/go.sum +++ b/interchaintest/go.sum @@ -404,8 +404,8 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZm 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/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/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= +github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/docker v20.10.24+incompatible h1:Ugvxm7a8+Gz6vqQYQQ2W7GYq5EUPaAiuPgIfVyI3dYE= github.com/docker/docker v20.10.24+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= From 10f1282c01beb696fc502fb22d64ace96a6955c8 Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Fri, 12 May 2023 09:25:12 -0500 Subject: [PATCH 096/131] add IBC + wasm upgrade handler param keys --- app/upgrades/v15/upgrades.go | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/app/upgrades/v15/upgrades.go b/app/upgrades/v15/upgrades.go index 3d02dc70e..34b36713b 100644 --- a/app/upgrades/v15/upgrades.go +++ b/app/upgrades/v15/upgrades.go @@ -26,6 +26,12 @@ import ( paramstypes "github.com/cosmos/cosmos-sdk/x/params/types" slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + + // External modules + wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" + icacontrollertypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/types" + icahosttypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/host/types" + ibctransfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" ) // We now charge 2 million gas * gas price to create a denom. @@ -69,6 +75,17 @@ func CreateV15UpgradeHandler( keyTable = govv1.ParamKeyTable() //nolint:staticcheck case crisistypes.ModuleName: keyTable = crisistypes.ParamKeyTable() //nolint:staticcheck + + // ibc types + case ibctransfertypes.ModuleName: + keyTable = ibctransfertypes.ParamKeyTable() + case icahosttypes.SubModuleName: + keyTable = icahosttypes.ParamKeyTable() + case icacontrollertypes.SubModuleName: + keyTable = icacontrollertypes.ParamKeyTable() + // wasm + case wasmtypes.ModuleName: + keyTable = wasmtypes.ParamKeyTable() //nolint:staticcheck } if !subspace.HasKeyTable() { @@ -76,8 +93,7 @@ func CreateV15UpgradeHandler( } } - // Migrate Tendermint consensus parameters from x/params module to a - // x/consensus module. + // Migrate Tendermint consensus parameters from x/params module to a deprecated x/consensus module. // The old params module is required to still be imported in your app.go in order to handle this migration. baseAppLegacySS := keepers.ParamsKeeper.Subspace(baseapp.Paramspace).WithKeyTable(paramstypes.ConsensusParamsKeyTable()) baseapp.MigrateParams(ctx, baseAppLegacySS, &keepers.ConsensusParamsKeeper) From aa085d6946c83842ccb1f5d2ec3cd1ac5875214d Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Fri, 12 May 2023 09:53:20 -0500 Subject: [PATCH 097/131] Use ictest IBC conformance for v47 --- interchaintest/ibc_transfer_test.go | 163 +++++++++------------------- 1 file changed, 49 insertions(+), 114 deletions(-) diff --git a/interchaintest/ibc_transfer_test.go b/interchaintest/ibc_transfer_test.go index 78799ba97..10799fddb 100644 --- a/interchaintest/ibc_transfer_test.go +++ b/interchaintest/ibc_transfer_test.go @@ -2,15 +2,13 @@ package interchaintest import ( "context" - "fmt" "testing" - transfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" "github.com/strangelove-ventures/interchaintest/v7" "github.com/strangelove-ventures/interchaintest/v7/chain/cosmos" + "github.com/strangelove-ventures/interchaintest/v7/conformance" "github.com/strangelove-ventures/interchaintest/v7/ibc" "github.com/strangelove-ventures/interchaintest/v7/testreporter" - "github.com/strangelove-ventures/interchaintest/v7/testutil" "github.com/stretchr/testify/require" "go.uber.org/zap/zaptest" ) @@ -35,6 +33,29 @@ func TestJunoGaiaIBCTransfer(t *testing.T) { NumValidators: &numVals, NumFullNodes: &numFullNodes, }, + // { + // Name: "juno", + // ChainConfig: ibc.ChainConfig{ + // Type: "cosmos", + // Name: "juno", + // ChainID: "juno-3", + // Images: []ibc.DockerImage{JunoImage}, + // Bin: "junod", + // Bech32Prefix: "juno", + // Denom: "ujuno", + // CoinType: "118", + // GasPrices: "0ujuno", + // GasAdjustment: 2.0, + // TrustingPeriod: "112h", + // NoHostMount: false, + // ConfigFileOverrides: nil, + // EncodingConfig: junoEncoding(), + // UsingNewGenesisCommand: true, + // ModifyGenesis: modifyGenesisShortProposals(VotingPeriod, MaxDepositPeriod), + // }, + // NumValidators: &numVals, + // NumFullNodes: &numFullNodes, + // }, { Name: "gaia", Version: "v9.0.0", @@ -43,139 +64,53 @@ func TestJunoGaiaIBCTransfer(t *testing.T) { }, }) + const ( + path = "ibc-path" + relayerName = "relayer" + ) + // Get chains from the chain factory chains, err := cf.Chains(t.Name()) require.NoError(t, err) + client, network := interchaintest.DockerSetup(t) + juno, gaia := chains[0].(*cosmos.CosmosChain), chains[1].(*cosmos.CosmosChain) - // Create relayer factory to utilize the go-relayer - client, network := interchaintest.DockerSetup(t) + // Get a relayer instance + rf := interchaintest.NewBuiltinRelayerFactory( + ibc.CosmosRly, + zaptest.NewLogger(t), + ) - r := interchaintest.NewBuiltinRelayerFactory(ibc.CosmosRly, zaptest.NewLogger(t)).Build(t, client, network) + r := rf.Build(t, client, network) - // Create a new Interchain object which describes the chains, relayers, and IBC connections we want to use ic := interchaintest.NewInterchain(). AddChain(juno). AddChain(gaia). - AddRelayer(r, "rly"). + AddRelayer(r, relayerName). AddLink(interchaintest.InterchainLink{ Chain1: juno, Chain2: gaia, Relayer: r, - Path: pathJunoGaia, + Path: path, }) - rep := testreporter.NewNopReporter() - eRep := rep.RelayerExecReporter(t) - ctx := context.Background() - err = ic.Build(ctx, eRep, interchaintest.InterchainBuildOptions{ - TestName: t.Name(), - Client: client, - NetworkID: network, - SkipPathCreation: false, - - // This can be used to write to the block database which will index all block data e.g. txs, msgs, events, etc. - // BlockDatabaseFile: interchaintest.DefaultBlockDatabaseFilepath(), - }) - require.NoError(t, err) + rep := testreporter.NewNopReporter() + require.NoError(t, ic.Build(ctx, rep.RelayerExecReporter(t), interchaintest.InterchainBuildOptions{ + TestName: t.Name(), + Client: client, + NetworkID: network, + BlockDatabaseFile: interchaintest.DefaultBlockDatabaseFilepath(), + SkipPathCreation: false, + })) t.Cleanup(func() { _ = ic.Close() }) - // Start the relayer - require.NoError(t, r.StartRelayer(ctx, eRep, pathJunoGaia)) - t.Cleanup( - func() { - err := r.StopRelayer(ctx, eRep) - if err != nil { - panic(fmt.Errorf("an error occurred while stopping the relayer: %s", err)) - } - }, - ) - - // Create some user accounts on both chains - users := interchaintest.GetAndFundTestUsers(t, ctx, t.Name(), genesisWalletAmount, juno, gaia) - - // Wait a few blocks for relayer to start and for user accounts to be created - err = testutil.WaitForBlocks(ctx, 5, juno, gaia) - require.NoError(t, err) - - // Get our Bech32 encoded user addresses - junoUser, gaiaUser := users[0], users[1] - - junoUserAddr := junoUser.FormattedAddress() - gaiaUserAddr := gaiaUser.FormattedAddress() - - // Get original account balances - junoOrigBal, err := juno.GetBalance(ctx, junoUserAddr, juno.Config().Denom) - require.NoError(t, err) - require.Equal(t, genesisWalletAmount, junoOrigBal) - - gaiaOrigBal, err := gaia.GetBalance(ctx, gaiaUserAddr, gaia.Config().Denom) - require.NoError(t, err) - require.Equal(t, genesisWalletAmount, gaiaOrigBal) - - // Compose an IBC transfer and send from Juno -> Gaia - const transferAmount = int64(1_000) - transfer := ibc.WalletAmount{ - Address: gaiaUserAddr, - Denom: juno.Config().Denom, - Amount: transferAmount, - } - - channel, err := ibc.GetTransferChannel(ctx, r, eRep, juno.Config().ChainID, gaia.Config().ChainID) - require.NoError(t, err) - - transferTx, err := juno.SendIBCTransfer(ctx, channel.ChannelID, junoUserAddr, transfer, ibc.TransferOptions{}) - require.NoError(t, err) - - junoHeight, err := juno.Height(ctx) - require.NoError(t, err) - - // Poll for the ack to know the transfer was successful - _, err = testutil.PollForAck(ctx, juno, junoHeight, junoHeight+10, transferTx.Packet) - require.NoError(t, err) - - // Get the IBC denom for ujuno on Gaia - junoTokenDenom := transfertypes.GetPrefixedDenom(channel.Counterparty.PortID, channel.Counterparty.ChannelID, juno.Config().Denom) - junoIBCDenom := transfertypes.ParseDenomTrace(junoTokenDenom).IBCDenom() - - // Assert that the funds are no longer present in user acc on Juno and are in the user acc on Gaia - junoUpdateBal, err := juno.GetBalance(ctx, junoUserAddr, juno.Config().Denom) - require.NoError(t, err) - require.Equal(t, junoOrigBal-transferAmount, junoUpdateBal) - - gaiaUpdateBal, err := gaia.GetBalance(ctx, gaiaUserAddr, junoIBCDenom) - require.NoError(t, err) - require.Equal(t, transferAmount, gaiaUpdateBal) - - // Compose an IBC transfer and send from Gaia -> Juno - transfer = ibc.WalletAmount{ - Address: junoUserAddr, - Denom: junoIBCDenom, - Amount: transferAmount, - } - - transferTx, err = gaia.SendIBCTransfer(ctx, channel.Counterparty.ChannelID, gaiaUserAddr, transfer, ibc.TransferOptions{}) - require.NoError(t, err) - - gaiaHeight, err := gaia.Height(ctx) - require.NoError(t, err) - - // Poll for the ack to know the transfer was successful - _, err = testutil.PollForAck(ctx, gaia, gaiaHeight, gaiaHeight+10, transferTx.Packet) - require.NoError(t, err) - - // Assert that the funds are now back on Juno and not on Gaia - junoUpdateBal, err = juno.GetBalance(ctx, junoUserAddr, juno.Config().Denom) - require.NoError(t, err) - require.Equal(t, junoOrigBal, junoUpdateBal) - - gaiaUpdateBal, err = gaia.GetBalance(ctx, gaiaUserAddr, junoIBCDenom) - require.NoError(t, err) - require.Equal(t, int64(0), gaiaUpdateBal) + // test IBC conformance + conformance.TestChainPair(t, ctx, client, network, juno, gaia, rf, rep, r, path) } From 99cc71a0632c27036ddb713d8b8aebe167887a9b Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Fri, 12 May 2023 11:10:43 -0500 Subject: [PATCH 098/131] MsgSudoContract govv1 proposal ictest --- interchaintest/contract_unity_submit_test.go | 24 ++++++++++++++++---- interchaintest/go.mod | 10 ++++---- interchaintest/go.sum | 4 ++-- interchaintest/helpers/cosmwasm.go | 24 -------------------- 4 files changed, 27 insertions(+), 35 deletions(-) diff --git a/interchaintest/contract_unity_submit_test.go b/interchaintest/contract_unity_submit_test.go index e5aed41bd..da05cb208 100644 --- a/interchaintest/contract_unity_submit_test.go +++ b/interchaintest/contract_unity_submit_test.go @@ -4,11 +4,13 @@ import ( "fmt" "testing" + cosmosproto "github.com/cosmos/gogoproto/proto" "github.com/strangelove-ventures/interchaintest/v7" "github.com/strangelove-ventures/interchaintest/v7/chain/cosmos" "github.com/strangelove-ventures/interchaintest/v7/ibc" "github.com/stretchr/testify/require" + wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" helpers "github.com/CosmosContracts/juno/tests/interchaintest/helpers" ) @@ -43,15 +45,29 @@ func TestJunoUnityContractGovSubmit(t *testing.T) { height, err := juno.Height(ctx) require.NoError(t, err, "error fetching height") - msg = fmt.Sprintf(`{"execute_send":{"amount":"1000000","recipient":"%s"}}`, withdrawAddr) - helpers.StoreContractGovernanceProposal(t, ctx, juno, user, "Prop Title", "description", fmt.Sprintf(`500000000%s`, nativeDenom), contractAddr, "", msg) + // Use cosmos messages, then build the proposal, and submit it. + proposalMsgs := []cosmosproto.Message{ + &wasmtypes.MsgSudoContract{ + Authority: "juno10d07y265gmmuvt4z0w9aw880jnsr700jvss730", + Contract: contractAddr, + Msg: []byte(fmt.Sprintf(`{"execute_send":{"amount":"1000000","recipient":"%s"}}`, withdrawAddr)), + }, + } + + proposal, err := juno.BuildProposal(juno, proposalMsgs, "Prop Title", "description", "ipfs://CID", fmt.Sprintf(`1000000000%s`, nativeDenom)) + require.NoError(t, err, "error making proposal") + + txProp, err := juno.SubmitProposal(ctx, user.KeyName(), proposal) + t.Log("txProp", txProp) + t.Log("err", err) + proposalID := "1" - // poll for proposal err = juno.VoteOnProposalAllValidators(ctx, proposalID, cosmos.ProposalVoteYes) require.NoError(t, err, "failed to submit votes") - _, err = cosmos.PollForProposalStatus(ctx, juno, height, height+haltHeightDelta, proposalID, cosmos.ProposalStatusPassed) + // poll for proposal + _, err = cosmos.PollForProposalStatus(ctx, juno, height, height+50, proposalID, cosmos.ProposalStatusPassed) require.NoError(t, err, "proposal status did not change to passed in expected number of blocks") t.Cleanup(func() { diff --git a/interchaintest/go.mod b/interchaintest/go.mod index f37fecfab..4a9437481 100644 --- a/interchaintest/go.mod +++ b/interchaintest/go.mod @@ -14,9 +14,9 @@ replace ( github.com/btcsuite/btcd => github.com/btcsuite/btcd v0.22.2 //indirect github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 - // Fixes gas issues in ictest - // go get github.com/Reecepbcups/interchaintest@83b50de71a69f3c463a7d809b8f1c02762fb4114 - github.com/strangelove-ventures/interchaintest/v7 => github.com/Reecepbcups/interchaintest/v7 v7.0.0-20230511194528-83b50de71a69 + // Fixes gas issue, public SubmitProposal + // go get github.com/Reecepbcups/interchaintest/v7@62fd485e383a7bd88d5065e0dca022351fad427b + github.com/strangelove-ventures/interchaintest/v7 => github.com/Reecepbcups/interchaintest/v7 v7.0.0-20230512160712-62fd485e383a github.com/vedhavyas/go-subkey => github.com/strangelove-ventures/go-subkey v1.0.7 ) @@ -25,7 +25,7 @@ require ( github.com/CosmWasm/wasmd v0.40.0-rc.1.0.20230422061626-b85abcf1d7b8 github.com/CosmosContracts/juno/v15 v15.0.0-00010101000000-000000000000 github.com/cosmos/cosmos-sdk v0.47.2 - github.com/cosmos/ibc-go/v7 v7.0.0 + github.com/cosmos/gogoproto v1.4.8 github.com/docker/docker v20.10.24+incompatible github.com/icza/dyno v0.0.0-20220812133438-f0b6f8a18845 github.com/strangelove-ventures/interchaintest/v7 v7.0.0-20230508154211-ebc1cbd6d88e @@ -79,8 +79,8 @@ require ( github.com/cosmos/cosmos-proto v1.0.0-beta.2 // indirect github.com/cosmos/go-bip39 v1.0.0 // indirect github.com/cosmos/gogogateway v1.2.0 // indirect - github.com/cosmos/gogoproto v1.4.8 // indirect github.com/cosmos/iavl v0.20.0 // indirect + github.com/cosmos/ibc-go/v7 v7.0.0 // indirect github.com/cosmos/ics23/go v0.10.0 // indirect github.com/cosmos/ledger-cosmos-go v0.12.2 // indirect github.com/cosmos/rosetta-sdk-go v0.10.0 // indirect diff --git a/interchaintest/go.sum b/interchaintest/go.sum index 048a31070..17e2ad19d 100644 --- a/interchaintest/go.sum +++ b/interchaintest/go.sum @@ -235,8 +235,8 @@ github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2B 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= -github.com/Reecepbcups/interchaintest/v7 v7.0.0-20230511194528-83b50de71a69 h1:y48srfoyjfPg6KCHFpBOOo/AhFnsM8Att7y+KnZ6Y0M= -github.com/Reecepbcups/interchaintest/v7 v7.0.0-20230511194528-83b50de71a69/go.mod h1:/FpoaMKTF3OREchZZvg6eGfVYvk7lAwqP9q2TN+lOGs= +github.com/Reecepbcups/interchaintest/v7 v7.0.0-20230512160712-62fd485e383a h1:ogtersqsfWEuVDbyhnFfBPmQbUCDEpAXA8TUtPpNdEQ= +github.com/Reecepbcups/interchaintest/v7 v7.0.0-20230512160712-62fd485e383a/go.mod h1:/FpoaMKTF3OREchZZvg6eGfVYvk7lAwqP9q2TN+lOGs= 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 h1:fLjPD/aNc3UIOA6tDi6QXUemppXK3P9BI7mr2hd6gx8= diff --git a/interchaintest/helpers/cosmwasm.go b/interchaintest/helpers/cosmwasm.go index 8df844e02..416053d9d 100644 --- a/interchaintest/helpers/cosmwasm.go +++ b/interchaintest/helpers/cosmwasm.go @@ -25,30 +25,6 @@ func SetupContract(t *testing.T, ctx context.Context, chain *cosmos.CosmosChain, return codeId, contractAddr } -func StoreContractGovernanceProposal(t *testing.T, ctx context.Context, chain *cosmos.CosmosChain, user ibc.Wallet, title, description, depositCoin, contractAddr, amount, message string) { - cmd := []string{"junod", "tx", "gov", "submit-proposal", "sudo-contract", contractAddr, message, - "--title", title, - "--description", description, - "--deposit", depositCoin, - "--node", chain.GetRPCAddress(), - "--home", chain.HomeDir(), - "--chain-id", chain.Config().ChainID, - "--from", user.KeyName(), - "--gas", "2000000", - "--keyring-dir", chain.HomeDir(), - "--keyring-backend", keyring.BackendTest, - "-y", - } - - if amount != "" { - cmd = append(cmd, "--amount", amount) - } - - stdout, _, err := chain.Exec(ctx, cmd, nil) - require.NoError(t, err) - debugOutput(t, string(stdout)) -} - func ExecuteMsgWithAmount(t *testing.T, ctx context.Context, chain *cosmos.CosmosChain, user ibc.Wallet, contractAddr, amount, message string) { // amount is #utoken From bdb8ca2bc9e27d92e9afb258768adee1d836465a Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Fri, 12 May 2023 11:15:03 -0500 Subject: [PATCH 099/131] Remove duplicate arg --- interchaintest/contract_unity_submit_test.go | 2 +- interchaintest/go.mod | 4 ++-- interchaintest/go.sum | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/interchaintest/contract_unity_submit_test.go b/interchaintest/contract_unity_submit_test.go index da05cb208..a0e10f15e 100644 --- a/interchaintest/contract_unity_submit_test.go +++ b/interchaintest/contract_unity_submit_test.go @@ -54,7 +54,7 @@ func TestJunoUnityContractGovSubmit(t *testing.T) { }, } - proposal, err := juno.BuildProposal(juno, proposalMsgs, "Prop Title", "description", "ipfs://CID", fmt.Sprintf(`1000000000%s`, nativeDenom)) + proposal, err := juno.BuildProposal(proposalMsgs, "Prop Title", "description", "ipfs://CID", fmt.Sprintf(`1000000000%s`, nativeDenom)) require.NoError(t, err, "error making proposal") txProp, err := juno.SubmitProposal(ctx, user.KeyName(), proposal) diff --git a/interchaintest/go.mod b/interchaintest/go.mod index 4a9437481..227743301 100644 --- a/interchaintest/go.mod +++ b/interchaintest/go.mod @@ -15,8 +15,8 @@ replace ( github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 // Fixes gas issue, public SubmitProposal - // go get github.com/Reecepbcups/interchaintest/v7@62fd485e383a7bd88d5065e0dca022351fad427b - github.com/strangelove-ventures/interchaintest/v7 => github.com/Reecepbcups/interchaintest/v7 v7.0.0-20230512160712-62fd485e383a + // go get github.com/Reecepbcups/interchaintest/v7@33d7fafb6f8b0207be920659b37dd5ae9c85c0ff + github.com/strangelove-ventures/interchaintest/v7 => github.com/Reecepbcups/interchaintest/v7 v7.0.0-20230512161406-33d7fafb6f8b github.com/vedhavyas/go-subkey => github.com/strangelove-ventures/go-subkey v1.0.7 ) diff --git a/interchaintest/go.sum b/interchaintest/go.sum index 17e2ad19d..a616ae880 100644 --- a/interchaintest/go.sum +++ b/interchaintest/go.sum @@ -235,8 +235,8 @@ github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2B 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= -github.com/Reecepbcups/interchaintest/v7 v7.0.0-20230512160712-62fd485e383a h1:ogtersqsfWEuVDbyhnFfBPmQbUCDEpAXA8TUtPpNdEQ= -github.com/Reecepbcups/interchaintest/v7 v7.0.0-20230512160712-62fd485e383a/go.mod h1:/FpoaMKTF3OREchZZvg6eGfVYvk7lAwqP9q2TN+lOGs= +github.com/Reecepbcups/interchaintest/v7 v7.0.0-20230512161406-33d7fafb6f8b h1:mTHn72tz8bNXcmf/RClTzhIFuyPbDxdVSXpCeCmCy2Y= +github.com/Reecepbcups/interchaintest/v7 v7.0.0-20230512161406-33d7fafb6f8b/go.mod h1:/FpoaMKTF3OREchZZvg6eGfVYvk7lAwqP9q2TN+lOGs= 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 h1:fLjPD/aNc3UIOA6tDi6QXUemppXK3P9BI7mr2hd6gx8= From 64383e6f4bafbc895fd7ded40cd9585ffbaf1085 Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Fri, 12 May 2023 15:55:49 -0500 Subject: [PATCH 100/131] setPostHandler & configurator --- app/app.go | 47 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 43 insertions(+), 4 deletions(-) diff --git a/app/app.go b/app/app.go index 56e652a13..0219fa642 100644 --- a/app/app.go +++ b/app/app.go @@ -1,6 +1,7 @@ package app import ( + "fmt" "io" "net/http" "os" @@ -16,6 +17,7 @@ import ( tmjson "github.com/cometbft/cometbft/libs/json" "github.com/cometbft/cometbft/libs/log" tmos "github.com/cometbft/cometbft/libs/os" + tmproto "github.com/cometbft/cometbft/proto/tendermint/types" "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/client" nodeservice "github.com/cosmos/cosmos-sdk/client/grpc/node" @@ -35,6 +37,7 @@ import ( "github.com/cosmos/cosmos-sdk/types/module" "github.com/cosmos/cosmos-sdk/version" "github.com/cosmos/cosmos-sdk/x/auth/ante" + "github.com/cosmos/cosmos-sdk/x/auth/posthandler" authtx "github.com/cosmos/cosmos-sdk/x/auth/tx" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" @@ -209,7 +212,7 @@ type App struct { sm *module.SimulationManager // module configurator - // configurator module.Configurator // TODO: I think we need to do something with this... + configurator module.Configurator } // New returns a reference to an initialized Juno. @@ -270,7 +273,7 @@ func New( } // upgrade handlers - cfg := module.NewConfigurator(appCodec, app.MsgServiceRouter(), app.GRPCQueryRouter()) + app.configurator = module.NewConfigurator(appCodec, app.MsgServiceRouter(), app.GRPCQueryRouter()) /**** Module Options ****/ @@ -281,6 +284,7 @@ func New( // NOTE: Any module instantiated in the module manager that is later modified // must be passed by reference here. app.ModuleManager = module.NewManager(appModules(app, encodingConfig, skipGenesisInvariants)...) + app.ModuleManager.RegisterServices(app.configurator) // During begin block slashing happens after distr.BeginBlocker so that // there is nothing left over in the validator fee pool, so as to keep the @@ -298,14 +302,13 @@ func New( app.ModuleManager.SetOrderInitGenesis(orderInitBlockers()...) app.ModuleManager.RegisterInvariants(app.AppKeepers.CrisisKeeper) - app.ModuleManager.RegisterServices(cfg) // initialize stores app.MountKVStores(app.keys) app.MountTransientStores(app.AppKeepers.GetTransientStoreKey()) app.MountMemoryStores(app.AppKeepers.GetMemoryStoreKey()) // register upgrade - app.setupUpgradeHandlers(cfg) + app.setupUpgradeHandlers(app.configurator) // SDK v47 - since we do not use dep inject, this gives us access to newer gRPC services. autocliv1.RegisterQueryServer(app.GRPCQueryRouter(), runtimeservices.NewAutoCLIQueryService(app.ModuleManager.Modules)) @@ -364,10 +367,35 @@ func New( app.setupUpgradeStoreLoaders() + // In v0.46, the SDK introduces _postHandlers_. PostHandlers are like + // antehandlers, but are run _after_ the `runMsgs` execution. They are also + // defined as a chain, and have the same signature as antehandlers. + // + // In baseapp, postHandlers are run in the same store branch as `runMsgs`, + // meaning that both `runMsgs` and `postHandler` state will be committed if + // both are successful, and both will be reverted if any of the two fails. + // + // The SDK exposes a default postHandlers chain, which comprises of only + // one decorator: the Transaction Tips decorator. However, some chains do + // not need it by default, so feel free to comment the next line if you do + // not need tips. + // To read more about tips: + // https://docs.cosmos.network/main/core/tips.html + // + // Please note that changing any of the anteHandler or postHandler chain is + // likely to be a state-machine breaking change, which needs a coordinated + // upgrade. + app.setPostHandler() + if loadLatest { if err := app.LoadLatestVersion(); err != nil { tmos.Exit(err.Error()) } + ctx := app.BaseApp.NewUncachedContext(true, tmproto.Header{}) + // Initialize pinned codes in wasmvm as they are not persisted there + if err := app.AppKeepers.WasmKeeper.InitializePinnedCodes(ctx); err != nil { + tmos.Exit(fmt.Sprintf("failed initialize pinned codes %s", err)) + } // Initialize and seal the capability keeper so all persistent capabilities // are loaded in-memory and prevent any further modules from creating scoped @@ -402,6 +430,17 @@ func GetDefaultBypassFeeMessages() []string { } } +func (app *App) setPostHandler() { + postHandler, err := posthandler.NewPostHandler( + posthandler.HandlerOptions{}, + ) + if err != nil { + panic(err) + } + + app.SetPostHandler(postHandler) +} + // Name returns the name of the App func (app *App) Name() string { return app.BaseApp.Name() From d7570f32df141835eca53caea7b6bf28fbcf2b31 Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Fri, 12 May 2023 15:56:05 -0500 Subject: [PATCH 101/131] new Cmds: rosetta & AuxToFee --- cmd/junod/cmd/root.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/cmd/junod/cmd/root.go b/cmd/junod/cmd/root.go index dedd6c4a3..d8cf59685 100644 --- a/cmd/junod/cmd/root.go +++ b/cmd/junod/cmd/root.go @@ -31,6 +31,8 @@ import ( "github.com/spf13/cast" "github.com/spf13/cobra" + rosettaCmd "cosmossdk.io/tools/rosetta/cmd" + "github.com/CosmWasm/wasmd/x/wasm" wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" @@ -204,6 +206,8 @@ func initRootCmd(rootCmd *cobra.Command, encodingConfig params.EncodingConfig) { keys.Commands(app.DefaultNodeHome), ResetCmd(), ) + // add rosetta + rootCmd.AddCommand(rosettaCmd.RosettaCommand(encodingConfig.InterfaceRegistry, encodingConfig.Marshaler)) } func addModuleInitFlags(startCmd *cobra.Command) { @@ -264,6 +268,7 @@ func txCommand() *cobra.Command { authcmd.GetBroadcastCommand(), authcmd.GetEncodeCommand(), authcmd.GetDecodeCommand(), + authcmd.GetAuxToFeeCommand(), ) app.ModuleBasics.AddTxCommands(cmd) From ea26513bc062fba2d3e5a5ef66af463f69b3dfc0 Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Fri, 12 May 2023 16:05:44 -0500 Subject: [PATCH 102/131] mod tidy --- go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 165447dfa..b66485372 100644 --- a/go.mod +++ b/go.mod @@ -34,7 +34,7 @@ require ( cloud.google.com/go/compute/metadata v0.2.3 // indirect cloud.google.com/go/iam v0.12.0 // indirect cloud.google.com/go/storage v1.29.0 // indirect - cosmossdk.io/tools/rosetta v0.2.1 // indirect + cosmossdk.io/tools/rosetta v0.2.1 github.com/aws/aws-sdk-go v1.44.203 // indirect github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect github.com/chzyer/readline v1.5.1 // indirect From fc3b870e181004fb30d34073c11dcbb5bf7125ee Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Fri, 12 May 2023 16:09:12 -0500 Subject: [PATCH 103/131] If mod files are edited, ICtest --- .github/workflows/interchaintest-E2E.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/interchaintest-E2E.yml b/.github/workflows/interchaintest-E2E.yml index 0777d9a6f..22d1ca085 100644 --- a/.github/workflows/interchaintest-E2E.yml +++ b/.github/workflows/interchaintest-E2E.yml @@ -9,6 +9,7 @@ on: paths: - '**.yml' - '**.go' + - '**.mod' - '**.sum' env: From c2465cc233fa40a7a8c71e5296d791e6e3ba9ca8 Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Fri, 12 May 2023 21:42:38 -0500 Subject: [PATCH 104/131] Fix upgrade test (SDK 45 genesis + longer height delta) --- interchaintest/chain_upgrade_test.go | 33 +++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/interchaintest/chain_upgrade_test.go b/interchaintest/chain_upgrade_test.go index fd4dacb9c..79401e2c1 100644 --- a/interchaintest/chain_upgrade_test.go +++ b/interchaintest/chain_upgrade_test.go @@ -2,9 +2,12 @@ package interchaintest import ( "context" + "encoding/json" + "fmt" "testing" "time" + "github.com/icza/dyno" "github.com/strangelove-ventures/interchaintest/v7" "github.com/strangelove-ventures/interchaintest/v7/chain/cosmos" "github.com/strangelove-ventures/interchaintest/v7/ibc" @@ -14,9 +17,8 @@ import ( ) const ( - haltHeightDelta = uint64(7) // will propose upgrade this many blocks in the future + haltHeightDelta = uint64(15) // will propose upgrade this many blocks in the future blocksAfterUpgrade = uint64(10) - ) func TestBasicJunoUpgrade(t *testing.T) { @@ -26,6 +28,31 @@ func TestBasicJunoUpgrade(t *testing.T) { CosmosChainUpgradeTest(t, "juno", startVersion, version, repo, upgradeName) } +// With us upgrading from v45 to v47, we need to modify the params in the v45 style here & only here. +// In the future this will be removed to use just `modifyGenesisShortProposals` +func modifySDKv45GenesisShortProposals(votingPeriod string, maxDepositPeriod string) func(ibc.ChainConfig, []byte) ([]byte, error) { + return func(chainConfig ibc.ChainConfig, genbz []byte) ([]byte, error) { + g := make(map[string]interface{}) + if err := json.Unmarshal(genbz, &g); err != nil { + return nil, fmt.Errorf("failed to unmarshal genesis file: %w", err) + } + if err := dyno.Set(g, votingPeriod, "app_state", "gov", "voting_params", "voting_period"); err != nil { + return nil, fmt.Errorf("failed to set voting period in genesis json: %w", err) + } + if err := dyno.Set(g, maxDepositPeriod, "app_state", "gov", "deposit_params", "max_deposit_period"); err != nil { + return nil, fmt.Errorf("failed to set voting period in genesis json: %w", err) + } + if err := dyno.Set(g, chainConfig.Denom, "app_state", "gov", "deposit_params", "min_deposit", 0, "denom"); err != nil { + return nil, fmt.Errorf("failed to set voting period in genesis json: %w", err) + } + out, err := json.Marshal(g) + if err != nil { + return nil, fmt.Errorf("failed to marshal genesis bytes to json: %w", err) + } + return out, nil + } +} + func CosmosChainUpgradeTest(t *testing.T, chainName, initialVersion, upgradeBranchVersion, upgradeRepo, upgradeName string) { if testing.Short() { t.Skip("skipping in short mode") @@ -39,7 +66,7 @@ func CosmosChainUpgradeTest(t *testing.T, chainName, initialVersion, upgradeBran ChainName: chainName, Version: initialVersion, ChainConfig: ibc.ChainConfig{ - ModifyGenesis: modifyGenesisShortProposals(VotingPeriod, MaxDepositPeriod), + ModifyGenesis: modifySDKv45GenesisShortProposals(VotingPeriod, MaxDepositPeriod), Images: []ibc.DockerImage{ { Repository: JunoE2ERepo, From cdaf3ff7a077d26b3a17b604e087ed504b9a18e7 Mon Sep 17 00:00:00 2001 From: Reece Williams <31943163+Reecepbcups@users.noreply.github.com> Date: Fri, 12 May 2023 22:08:20 -0500 Subject: [PATCH 105/131] Download dependencies (#673) --- .github/workflows/interchaintest-E2E.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/interchaintest-E2E.yml b/.github/workflows/interchaintest-E2E.yml index 22d1ca085..e4d178ad9 100644 --- a/.github/workflows/interchaintest-E2E.yml +++ b/.github/workflows/interchaintest-E2E.yml @@ -43,6 +43,11 @@ jobs: with: go-version: ${{ env.GO_VERSION }} id: go + + - name: Download dependencies + run: | + go mod download + cd interchaintest && go mod download - name: Set up QEMU uses: docker/setup-qemu-action@v2 From e0f054873937f56cb7e139321ec3200211f51d3d Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Sun, 14 May 2023 11:57:59 -0500 Subject: [PATCH 106/131] Empty-Commit From f1ead4324fbb2bf90feb387069964a7705982d92 Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Sun, 14 May 2023 12:01:04 -0500 Subject: [PATCH 107/131] workflow tweaks --- .github/workflows/golangci-lint.yml | 2 -- .github/workflows/interchaintest-E2E.yml | 3 +-- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml index 2704cab58..d0ece38f9 100644 --- a/.github/workflows/golangci-lint.yml +++ b/.github/workflows/golangci-lint.yml @@ -13,8 +13,6 @@ on: permissions: contents: read - # Optional: allow read access to pull request. Use with `only-new-issues` option. - # pull-requests: read concurrency: group: ${{ github.workflow }}-${{ github.ref }} diff --git a/.github/workflows/interchaintest-E2E.yml b/.github/workflows/interchaintest-E2E.yml index e4d178ad9..45f08332a 100644 --- a/.github/workflows/interchaintest-E2E.yml +++ b/.github/workflows/interchaintest-E2E.yml @@ -20,8 +20,6 @@ env: concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true - - jobs: build-and-push-image: @@ -38,6 +36,7 @@ jobs: # We setup go & cache dependencies here. This way each child job # does not have to reinstall all dependencies individually. + # Should ID be unique to this job only? - name: Setup Golang with cache uses: magnetikonline/action-golang-cache@v4 with: From 9bea7be4caa8a1572d443811eb86262dfba2ca1e Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Mon, 15 May 2023 12:53:58 -0500 Subject: [PATCH 108/131] See if this fixes v47 test --- app/app.go | 20 ++-- app/keepers/keepers.go | 21 +++-- app/modules.go | 6 +- go.mod | 2 +- interchaintest/ibc_transfer_test.go | 141 +++++++++++++++++++++------- scripts/hermes/transfer.sh | 3 + scripts/test_node.sh | 6 +- 7 files changed, 140 insertions(+), 59 deletions(-) diff --git a/app/app.go b/app/app.go index 0219fa642..74ab94cb1 100644 --- a/app/app.go +++ b/app/app.go @@ -8,8 +8,6 @@ import ( "strconv" "strings" - autocliv1 "cosmossdk.io/api/cosmos/autocli/v1" - reflectionv1 "cosmossdk.io/api/cosmos/reflection/v1" "github.com/CosmosContracts/juno/v15/app/openapiconsole" "github.com/CosmosContracts/juno/v15/docs" dbm "github.com/cometbft/cometbft-db" @@ -25,7 +23,6 @@ import ( "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/codec/types" "github.com/cosmos/cosmos-sdk/runtime" - runtimeservices "github.com/cosmos/cosmos-sdk/runtime/services" "github.com/cosmos/cosmos-sdk/server/api" "github.com/cosmos/cosmos-sdk/server/config" servertypes "github.com/cosmos/cosmos-sdk/server/types" @@ -310,13 +307,18 @@ func New( // register upgrade app.setupUpgradeHandlers(app.configurator) + // TODO: + // autocliv1 "cosmossdk.io/api/cosmos/autocli/v1" + // reflectionv1 "cosmossdk.io/api/cosmos/reflection/v1" + // runtimeservices "github.com/cosmos/cosmos-sdk/runtime/services" + // // SDK v47 - since we do not use dep inject, this gives us access to newer gRPC services. - autocliv1.RegisterQueryServer(app.GRPCQueryRouter(), runtimeservices.NewAutoCLIQueryService(app.ModuleManager.Modules)) - reflectionSvc, err := runtimeservices.NewReflectionService() - if err != nil { - panic(err) - } - reflectionv1.RegisterReflectionServiceServer(app.GRPCQueryRouter(), reflectionSvc) + // autocliv1.RegisterQueryServer(app.GRPCQueryRouter(), runtimeservices.NewAutoCLIQueryService(app.ModuleManager.Modules)) + // reflectionSvc, err := runtimeservices.NewReflectionService() + // if err != nil { + // panic(err) + // } + // reflectionv1.RegisterReflectionServiceServer(app.GRPCQueryRouter(), reflectionSvc) wasmConfig, err := wasm.ReadWasmConfig(appOpts) if err != nil { diff --git a/app/keepers/keepers.go b/app/keepers/keepers.go index afc9f8e21..daabfa2e5 100644 --- a/app/keepers/keepers.go +++ b/app/keepers/keepers.go @@ -165,8 +165,8 @@ type AppKeepers struct { TokenFactoryKeeper tokenfactorykeeper.Keeper // Middleware wrapper - Ics20WasmHooks *ibchooks.WasmHooks - HooksICS4Wrapper ibchooks.ICS4Middleware + Ics20WasmHooks *ibchooks.WasmHooks + // HooksICS4Wrapper ibchooks.ICS4Middleware } func NewAppKeepers( @@ -328,7 +328,6 @@ func NewAppKeepers( AddRoute(paramproposal.RouterKey, params.NewParamChangeProposalHandler(appKeepers.ParamsKeeper)). // This should be removed. It is still in place to avoid failures of modules that have not yet been upgraded AddRoute(upgradetypes.RouterKey, upgrade.NewSoftwareUpgradeProposalHandler(appKeepers.UpgradeKeeper)). AddRoute(ibcclienttypes.RouterKey, ibcclient.NewClientProposalHandler(appKeepers.IBCKeeper.ClientKeeper)) - // AddRoute(distrtypes.RouterKey, distr.NewCommunityPoolSpendProposalHandler(appKeepers.DistrKeeper)). govKeeper := govkeeper.NewKeeper( appCodec, @@ -355,10 +354,10 @@ func NewAppKeepers( junoPrefix := sdk.GetConfig().GetBech32AccountAddrPrefix() wasmHooks := ibchooks.NewWasmHooks(appKeepers.IBCHooksKeeper, nil, junoPrefix) // The contract keeper needs to be set later appKeepers.Ics20WasmHooks = &wasmHooks - appKeepers.HooksICS4Wrapper = ibchooks.NewICS4Middleware( - appKeepers.IBCKeeper.ChannelKeeper, - appKeepers.Ics20WasmHooks, - ) + // appKeepers.HooksICS4Wrapper = ibchooks.NewICS4Middleware( + // appKeepers.IBCKeeper.ChannelKeeper, + // appKeepers.Ics20WasmHooks, + // ) // Initialize packet forward middleware router appKeepers.PacketForwardKeeper = packetforwardkeeper.NewKeeper( @@ -375,7 +374,8 @@ func NewAppKeepers( appKeepers.IBCFeeKeeper = ibcfeekeeper.NewKeeper( appCodec, appKeepers.keys[ibcfeetypes.StoreKey], - appKeepers.HooksICS4Wrapper, // replaced with IBC middleware + // appKeepers.HooksICS4Wrapper, // replaced with IBC middleware // TODO: + appKeepers.IBCKeeper.ChannelKeeper, // replaced with IBC middleware appKeepers.IBCKeeper.ChannelKeeper, &appKeepers.IBCKeeper.PortKeeper, appKeepers.AccountKeeper, @@ -414,7 +414,8 @@ func NewAppKeepers( appCodec, appKeepers.keys[icahosttypes.StoreKey], appKeepers.GetSubspace(icahosttypes.SubModuleName), - appKeepers.HooksICS4Wrapper, + // appKeepers.HooksICS4Wrapper, // TODO: + appKeepers.IBCKeeper.ChannelKeeper, appKeepers.IBCKeeper.ChannelKeeper, &appKeepers.IBCKeeper.PortKeeper, appKeepers.AccountKeeper, @@ -546,7 +547,7 @@ func NewAppKeepers( packetforwardkeeper.DefaultRefundTransferPacketTimeoutTimestamp, ) transferStack = ibcfee.NewIBCMiddleware(transferStack, appKeepers.IBCFeeKeeper) - transferStack = ibchooks.NewIBCMiddleware(transferStack, &appKeepers.HooksICS4Wrapper) + // transferStack = ibchooks.NewIBCMiddleware(transferStack, &appKeepers.HooksICS4Wrapper) // RecvPacket, message that originates from core IBC and goes down to app, the flow is: // channel.RecvPacket -> fee.OnRecvPacket -> icaHost.OnRecvPacket diff --git a/app/modules.go b/app/modules.go index f464167fe..7a772578c 100644 --- a/app/modules.go +++ b/app/modules.go @@ -195,8 +195,8 @@ func orderBeginBlockers() []string { vestingtypes.ModuleName, consensusparamtypes.ModuleName, // additional modules - ibcexported.ModuleName, ibctransfertypes.ModuleName, + ibcexported.ModuleName, icatypes.ModuleName, packetforwardtypes.ModuleName, ibcfeetypes.ModuleName, @@ -229,8 +229,8 @@ func orderEndBlockers() []string { vestingtypes.ModuleName, consensusparamtypes.ModuleName, // additional non simd modules - ibcexported.ModuleName, ibctransfertypes.ModuleName, + ibcexported.ModuleName, icatypes.ModuleName, packetforwardtypes.ModuleName, ibcfeetypes.ModuleName, @@ -263,8 +263,8 @@ func orderInitBlockers() []string { feegrant.ModuleName, consensusparamtypes.ModuleName, // additional non simd modules - ibcexported.ModuleName, ibctransfertypes.ModuleName, + ibcexported.ModuleName, icatypes.ModuleName, packetforwardtypes.ModuleName, ibcfeetypes.ModuleName, diff --git a/go.mod b/go.mod index b66485372..d1807b74d 100644 --- a/go.mod +++ b/go.mod @@ -70,7 +70,7 @@ require ( ) require ( - cosmossdk.io/api v0.3.1 + cosmossdk.io/api v0.3.1 // indirect cosmossdk.io/core v0.5.1 // indirect cosmossdk.io/depinject v1.0.0-alpha.3 // indirect filippo.io/edwards25519 v1.0.0 // indirect diff --git a/interchaintest/ibc_transfer_test.go b/interchaintest/ibc_transfer_test.go index 10799fddb..380f66b13 100644 --- a/interchaintest/ibc_transfer_test.go +++ b/interchaintest/ibc_transfer_test.go @@ -4,11 +4,13 @@ import ( "context" "testing" + transfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" "github.com/strangelove-ventures/interchaintest/v7" "github.com/strangelove-ventures/interchaintest/v7/chain/cosmos" - "github.com/strangelove-ventures/interchaintest/v7/conformance" "github.com/strangelove-ventures/interchaintest/v7/ibc" + "github.com/strangelove-ventures/interchaintest/v7/relayer" "github.com/strangelove-ventures/interchaintest/v7/testreporter" + "github.com/strangelove-ventures/interchaintest/v7/testutil" "github.com/stretchr/testify/require" "go.uber.org/zap/zaptest" ) @@ -27,32 +29,9 @@ func TestJunoGaiaIBCTransfer(t *testing.T) { numFullNodes := 1 cf := interchaintest.NewBuiltinChainFactory(zaptest.NewLogger(t), []*interchaintest.ChainSpec{ - { - Name: "juno", - ChainConfig: junoConfig, - NumValidators: &numVals, - NumFullNodes: &numFullNodes, - }, // { - // Name: "juno", - // ChainConfig: ibc.ChainConfig{ - // Type: "cosmos", - // Name: "juno", - // ChainID: "juno-3", - // Images: []ibc.DockerImage{JunoImage}, - // Bin: "junod", - // Bech32Prefix: "juno", - // Denom: "ujuno", - // CoinType: "118", - // GasPrices: "0ujuno", - // GasAdjustment: 2.0, - // TrustingPeriod: "112h", - // NoHostMount: false, - // ConfigFileOverrides: nil, - // EncodingConfig: junoEncoding(), - // UsingNewGenesisCommand: true, - // ModifyGenesis: modifyGenesisShortProposals(VotingPeriod, MaxDepositPeriod), - // }, + // Name: "juno", + // ChainConfig: junoConfig, // NumValidators: &numVals, // NumFullNodes: &numFullNodes, // }, @@ -62,11 +41,16 @@ func TestJunoGaiaIBCTransfer(t *testing.T) { NumValidators: &numVals, NumFullNodes: &numFullNodes, }, + { + Name: "juno", + Version: "v14.1.0", + NumValidators: &numVals, + NumFullNodes: &numFullNodes, + }, }) const ( - path = "ibc-path" - relayerName = "relayer" + path = "ibc-path" ) // Get chains from the chain factory @@ -77,10 +61,21 @@ func TestJunoGaiaIBCTransfer(t *testing.T) { juno, gaia := chains[0].(*cosmos.CosmosChain), chains[1].(*cosmos.CosmosChain) + // relayerType, relayerName := ibc.CosmosRly, "rly" + relayerType, relayerName := ibc.Hermes, "hermes" + // Get a relayer instance rf := interchaintest.NewBuiltinRelayerFactory( - ibc.CosmosRly, + relayerType, zaptest.NewLogger(t), + // custom docker iamge for the relayer + relayer.RelayerOptionDockerImage{ + DockerImage: ibc.DockerImage{ + Repository: "ghcr.io/informalsystems/hermes", + Version: "1.4.1", + UidGid: JunoImage.UidGid, + }, + }, ) r := rf.Build(t, client, network) @@ -99,18 +94,98 @@ func TestJunoGaiaIBCTransfer(t *testing.T) { ctx := context.Background() rep := testreporter.NewNopReporter() + eRep := rep.RelayerExecReporter(t) - require.NoError(t, ic.Build(ctx, rep.RelayerExecReporter(t), interchaintest.InterchainBuildOptions{ + require.NoError(t, ic.Build(ctx, eRep, interchaintest.InterchainBuildOptions{ TestName: t.Name(), Client: client, NetworkID: network, BlockDatabaseFile: interchaintest.DefaultBlockDatabaseFilepath(), - SkipPathCreation: false, + SkipPathCreation: false, })) t.Cleanup(func() { _ = ic.Close() }) - // test IBC conformance - conformance.TestChainPair(t, ctx, client, network, juno, gaia, rf, rep, r, path) + // Create some user accounts on both chains + users := interchaintest.GetAndFundTestUsers(t, ctx, t.Name(), genesisWalletAmount, juno, gaia) + + // Wait a few blocks for relayer to start and for user accounts to be created + err = testutil.WaitForBlocks(ctx, 5, juno, gaia) + require.NoError(t, err) + + // Get our Bech32 encoded user addresses + junoUser, gaiaUser := users[0], users[1] + + junoUserAddr := junoUser.FormattedAddress() + gaiaUserAddr := gaiaUser.FormattedAddress() + + // Get original account balances + junoOrigBal, err := juno.GetBalance(ctx, junoUserAddr, juno.Config().Denom) + require.NoError(t, err) + require.Equal(t, genesisWalletAmount, junoOrigBal) + + gaiaOrigBal, err := gaia.GetBalance(ctx, gaiaUserAddr, gaia.Config().Denom) + require.NoError(t, err) + require.Equal(t, genesisWalletAmount, gaiaOrigBal) + + // Compose an IBC transfer and send from Juno -> Gaia + const transferAmount = int64(1_000) + transfer := ibc.WalletAmount{ + Address: gaiaUserAddr, + Denom: juno.Config().Denom, + Amount: transferAmount, + } + + channel, err := ibc.GetTransferChannel(ctx, r, eRep, juno.Config().ChainID, gaia.Config().ChainID) + require.NoError(t, err) + + transferTx, err := juno.SendIBCTransfer(ctx, channel.ChannelID, junoUserAddr, transfer, ibc.TransferOptions{}) + require.NoError(t, err) + + junoHeight, err := juno.Height(ctx) + require.NoError(t, err) + + // Poll for the ack to know the transfer was successful + _, err = testutil.PollForAck(ctx, juno, junoHeight, junoHeight+10, transferTx.Packet) + require.NoError(t, err) + + // Get the IBC denom for ujuno on Gaia + junoTokenDenom := transfertypes.GetPrefixedDenom(channel.Counterparty.PortID, channel.Counterparty.ChannelID, juno.Config().Denom) + junoIBCDenom := transfertypes.ParseDenomTrace(junoTokenDenom).IBCDenom() + + // Assert that the funds are no longer present in user acc on Juno and are in the user acc on Gaia + junoUpdateBal, err := juno.GetBalance(ctx, junoUserAddr, juno.Config().Denom) + require.NoError(t, err) + require.Equal(t, junoOrigBal-transferAmount, junoUpdateBal) + + gaiaUpdateBal, err := gaia.GetBalance(ctx, gaiaUserAddr, junoIBCDenom) + require.NoError(t, err) + require.Equal(t, transferAmount, gaiaUpdateBal) + + // Compose an IBC transfer and send from Gaia -> Juno + transfer = ibc.WalletAmount{ + Address: junoUserAddr, + Denom: junoIBCDenom, + Amount: transferAmount, + } + + transferTx, err = gaia.SendIBCTransfer(ctx, channel.Counterparty.ChannelID, gaiaUserAddr, transfer, ibc.TransferOptions{}) + require.NoError(t, err) + + gaiaHeight, err := gaia.Height(ctx) + require.NoError(t, err) + + // Poll for the ack to know the transfer was successful + _, err = testutil.PollForAck(ctx, gaia, gaiaHeight, gaiaHeight+10, transferTx.Packet) + require.NoError(t, err) + + // Assert that the funds are now back on Juno and not on Gaia + junoUpdateBal, err = juno.GetBalance(ctx, junoUserAddr, juno.Config().Denom) + require.NoError(t, err) + require.Equal(t, junoOrigBal, junoUpdateBal) + + gaiaUpdateBal, err = gaia.GetBalance(ctx, gaiaUserAddr, junoIBCDenom) + require.NoError(t, err) + require.Equal(t, int64(0), gaiaUpdateBal) } diff --git a/scripts/hermes/transfer.sh b/scripts/hermes/transfer.sh index 8632c3ec4..e7165e7f6 100644 --- a/scripts/hermes/transfer.sh +++ b/scripts/hermes/transfer.sh @@ -1,7 +1,10 @@ #!/bin/sh +export JUNOD_NODE="http://localhost:26657" CHAIN_A_ARGS="--from juno1 --keyring-backend test --chain-id local-1 --home $HOME/.juno1/ --node http://localhost:26657 --yes" +# junod q ibc channel channels + # Send from local-1 to local-2 via the relayer junod tx ibc-transfer transfer transfer channel-0 juno1hj5fveer5cjtn4wd6wstzugjfdxzl0xps73ftl 9ujuno $CHAIN_A_ARGS --packet-timeout-height 0-0 diff --git a/scripts/test_node.sh b/scripts/test_node.sh index 17aab3cc9..4ef546f82 100755 --- a/scripts/test_node.sh +++ b/scripts/test_node.sh @@ -105,7 +105,7 @@ sed -i 's/laddr = "tcp:\/\/127.0.0.1:26657"/c\laddr = "tcp:\/\/0.0.0.0:'$RPC'"/g sed -i 's/cors_allowed_origins = \[\]/cors_allowed_origins = \["\*"\]/g' $HOME_DIR/config/config.toml # REST endpoint -sed -i 's/address = "tcp:\/\/0.0.0.0:1317"/address = "tcp:\/\/0.0.0.0:'$REST'"/g' $HOME_DIR/config/app.toml +sed -i 's/address = "tcp:\/\/localhost:1317"/address = "tcp:\/\/0.0.0.0:'$REST'"/g' $HOME_DIR/config/app.toml sed -i 's/enable = false/enable = true/g' $HOME_DIR/config/app.toml # replace pprof_laddr = "localhost:6060" binding @@ -115,8 +115,8 @@ sed -i 's/pprof_laddr = "localhost:6060"/pprof_laddr = "localhost:'$PROFF_LADDER sed -i 's/laddr = "tcp:\/\/0.0.0.0:26656"/laddr = "tcp:\/\/0.0.0.0:'$P2P'"/g' $HOME_DIR/config/config.toml # GRPC -sed -i 's/address = "0.0.0.0:9090"/address = "0.0.0.0:'$GRPC'"/g' $HOME_DIR/config/app.toml -sed -i 's/address = "0.0.0.0:9091"/address = "0.0.0.0:'$GRPC_WEB'"/g' $HOME_DIR/config/app.toml +sed -i 's/address = "localhost:9090"/address = "0.0.0.0:'$GRPC'"/g' $HOME_DIR/config/app.toml +sed -i 's/address = "localhost:9091"/address = "0.0.0.0:'$GRPC_WEB'"/g' $HOME_DIR/config/app.toml # Rosetta Api sed -i 's/address = ":8080"/address = "0.0.0.0:'$ROSETTA'"/g' $HOME_DIR/config/app.toml From 9870e28318b5c554eed7dcec6773b2d07413398f Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Mon, 15 May 2023 12:58:40 -0500 Subject: [PATCH 109/131] Only build docker on merge to main branch --- .github/workflows/build_docker.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build_docker.yml b/.github/workflows/build_docker.yml index d236a10ac..066af9387 100644 --- a/.github/workflows/build_docker.yml +++ b/.github/workflows/build_docker.yml @@ -3,10 +3,9 @@ name: Build Docker Image on PR on: push: - paths: - - "**docker**" - - "**.sh" - - "**.bash" + branches: + - master + - main env: REGISTRY: ghcr.io From 026f50b953c528ce58e4c31e3303596d0907f47a Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Mon, 15 May 2023 13:01:30 -0500 Subject: [PATCH 110/131] Fix ictest to use local image --- interchaintest/ibc_transfer_test.go | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/interchaintest/ibc_transfer_test.go b/interchaintest/ibc_transfer_test.go index 380f66b13..fec3904b6 100644 --- a/interchaintest/ibc_transfer_test.go +++ b/interchaintest/ibc_transfer_test.go @@ -29,21 +29,15 @@ func TestJunoGaiaIBCTransfer(t *testing.T) { numFullNodes := 1 cf := interchaintest.NewBuiltinChainFactory(zaptest.NewLogger(t), []*interchaintest.ChainSpec{ - // { - // Name: "juno", - // ChainConfig: junoConfig, - // NumValidators: &numVals, - // NumFullNodes: &numFullNodes, - // }, { - Name: "gaia", - Version: "v9.0.0", + Name: "juno", + ChainConfig: junoConfig, NumValidators: &numVals, NumFullNodes: &numFullNodes, }, { - Name: "juno", - Version: "v14.1.0", + Name: "gaia", + Version: "v9.0.0", NumValidators: &numVals, NumFullNodes: &numFullNodes, }, @@ -101,7 +95,7 @@ func TestJunoGaiaIBCTransfer(t *testing.T) { Client: client, NetworkID: network, BlockDatabaseFile: interchaintest.DefaultBlockDatabaseFilepath(), - SkipPathCreation: false, + SkipPathCreation: false, })) t.Cleanup(func() { _ = ic.Close() From 5fc2290aa5face123b6a93cbc51ce627a9ae27f4 Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Mon, 15 May 2023 13:13:36 -0500 Subject: [PATCH 111/131] Use rly instead of hermes --- go.mod | 6 +++--- go.sum | 8 ++++---- interchaintest/ibc_transfer_test.go | 3 +-- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index d1807b74d..a31f4a73f 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( cosmossdk.io/errors v1.0.0-beta.7 cosmossdk.io/math v1.0.0 cosmossdk.io/simapp v0.0.0-20230224204036-a6adb0821462 - github.com/CosmWasm/wasmd v0.40.0-rc.2 + github.com/CosmWasm/wasmd v0.40.0-rc.2.0.20230515091654-e36611aa22b6 github.com/cometbft/cometbft v0.37.1 github.com/cometbft/cometbft-db v0.7.0 github.com/cosmos/cosmos-sdk v0.47.2 @@ -70,7 +70,7 @@ require ( ) require ( - cosmossdk.io/api v0.3.1 // indirect + cosmossdk.io/api v0.3.1 cosmossdk.io/core v0.5.1 // indirect cosmossdk.io/depinject v1.0.0-alpha.3 // indirect filippo.io/edwards25519 v1.0.0 // indirect @@ -100,7 +100,7 @@ require ( github.com/dgraph-io/badger/v2 v2.2007.4 // indirect github.com/dgraph-io/ristretto v0.1.1 // indirect github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect - github.com/docker/distribution v2.8.1+incompatible // indirect + github.com/docker/distribution v2.8.2+incompatible // indirect github.com/dustin/go-humanize v1.0.1 // indirect github.com/dvsekhvalnov/jose2go v1.5.0 // indirect github.com/felixge/httpsnoop v1.0.2 // indirect diff --git a/go.sum b/go.sum index 4e0601ae8..33c1c8825 100644 --- a/go.sum +++ b/go.sum @@ -224,8 +224,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/wasmd v0.40.0-rc.2 h1:UgOr8CaitJ8C8Y80viKLT6mL2Xh4yg2X4szCdTVr6xg= -github.com/CosmWasm/wasmd v0.40.0-rc.2/go.mod h1:l2s42GHKp1CHcR0N6J8P6p02b5RMWFCpcmRjyKMtqqg= +github.com/CosmWasm/wasmd v0.40.0-rc.2.0.20230515091654-e36611aa22b6 h1:rnnnJQ14eZrfCCf4rauWasHQulv3dtGkynIisz9HDB8= +github.com/CosmWasm/wasmd v0.40.0-rc.2.0.20230515091654-e36611aa22b6/go.mod h1:frHH5xVukE5xRaJcUNjE+TVPzbuHeV7sPnElR5gcA1w= github.com/CosmWasm/wasmvm v1.2.3 h1:OKYlobwmVGbl0eSn0mXoAAjE5hIuXnQCLPjbNd91sVY= github.com/CosmWasm/wasmvm v1.2.3/go.mod h1:vW/E3h8j9xBQs9bCoijDuawKo9kCtxOaS8N8J7KFtkc= github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= @@ -449,8 +449,8 @@ github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8 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/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/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= +github.com/docker/distribution v2.8.2+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= diff --git a/interchaintest/ibc_transfer_test.go b/interchaintest/ibc_transfer_test.go index fec3904b6..3ecae4662 100644 --- a/interchaintest/ibc_transfer_test.go +++ b/interchaintest/ibc_transfer_test.go @@ -55,8 +55,7 @@ func TestJunoGaiaIBCTransfer(t *testing.T) { juno, gaia := chains[0].(*cosmos.CosmosChain), chains[1].(*cosmos.CosmosChain) - // relayerType, relayerName := ibc.CosmosRly, "rly" - relayerType, relayerName := ibc.Hermes, "hermes" + relayerType, relayerName := ibc.CosmosRly, "rly" // Get a relayer instance rf := interchaintest.NewBuiltinRelayerFactory( From 0af3267f4450f1d062b033dd530792dea15cf8a6 Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Mon, 15 May 2023 13:16:26 -0500 Subject: [PATCH 112/131] go mod tidy --- interchaintest/go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interchaintest/go.mod b/interchaintest/go.mod index 227743301..61441aaca 100644 --- a/interchaintest/go.mod +++ b/interchaintest/go.mod @@ -26,6 +26,7 @@ require ( github.com/CosmosContracts/juno/v15 v15.0.0-00010101000000-000000000000 github.com/cosmos/cosmos-sdk v0.47.2 github.com/cosmos/gogoproto v1.4.8 + github.com/cosmos/ibc-go/v7 v7.0.0 github.com/docker/docker v20.10.24+incompatible github.com/icza/dyno v0.0.0-20220812133438-f0b6f8a18845 github.com/strangelove-ventures/interchaintest/v7 v7.0.0-20230508154211-ebc1cbd6d88e @@ -80,7 +81,6 @@ require ( github.com/cosmos/go-bip39 v1.0.0 // indirect github.com/cosmos/gogogateway v1.2.0 // indirect github.com/cosmos/iavl v0.20.0 // indirect - github.com/cosmos/ibc-go/v7 v7.0.0 // indirect github.com/cosmos/ics23/go v0.10.0 // indirect github.com/cosmos/ledger-cosmos-go v0.12.2 // indirect github.com/cosmos/rosetta-sdk-go v0.10.0 // indirect From 4a9cfb9f9461c5d4c7baf86d46aab9223deeeae4 Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Mon, 15 May 2023 13:49:56 -0500 Subject: [PATCH 113/131] Use rly --- interchaintest/ibc_transfer_test.go | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/interchaintest/ibc_transfer_test.go b/interchaintest/ibc_transfer_test.go index 3ecae4662..c59b8623f 100644 --- a/interchaintest/ibc_transfer_test.go +++ b/interchaintest/ibc_transfer_test.go @@ -8,7 +8,6 @@ import ( "github.com/strangelove-ventures/interchaintest/v7" "github.com/strangelove-ventures/interchaintest/v7/chain/cosmos" "github.com/strangelove-ventures/interchaintest/v7/ibc" - "github.com/strangelove-ventures/interchaintest/v7/relayer" "github.com/strangelove-ventures/interchaintest/v7/testreporter" "github.com/strangelove-ventures/interchaintest/v7/testutil" "github.com/stretchr/testify/require" @@ -55,20 +54,12 @@ func TestJunoGaiaIBCTransfer(t *testing.T) { juno, gaia := chains[0].(*cosmos.CosmosChain), chains[1].(*cosmos.CosmosChain) - relayerType, relayerName := ibc.CosmosRly, "rly" + relayerType, relayerName := ibc.CosmosRly, "relay" // Get a relayer instance rf := interchaintest.NewBuiltinRelayerFactory( relayerType, zaptest.NewLogger(t), - // custom docker iamge for the relayer - relayer.RelayerOptionDockerImage{ - DockerImage: ibc.DockerImage{ - Repository: "ghcr.io/informalsystems/hermes", - Version: "1.4.1", - UidGid: JunoImage.UidGid, - }, - }, ) r := rf.Build(t, client, network) From e05632f65c03a98759959b4310a08e6d800cb844 Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Mon, 15 May 2023 13:58:20 -0500 Subject: [PATCH 114/131] Re-enable v47 GRPC --- app/app.go | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/app/app.go b/app/app.go index 74ab94cb1..a2b476efb 100644 --- a/app/app.go +++ b/app/app.go @@ -8,6 +8,10 @@ import ( "strconv" "strings" + autocliv1 "cosmossdk.io/api/cosmos/autocli/v1" + reflectionv1 "cosmossdk.io/api/cosmos/reflection/v1" + runtimeservices "github.com/cosmos/cosmos-sdk/runtime/services" + "github.com/CosmosContracts/juno/v15/app/openapiconsole" "github.com/CosmosContracts/juno/v15/docs" dbm "github.com/cometbft/cometbft-db" @@ -307,18 +311,13 @@ func New( // register upgrade app.setupUpgradeHandlers(app.configurator) - // TODO: - // autocliv1 "cosmossdk.io/api/cosmos/autocli/v1" - // reflectionv1 "cosmossdk.io/api/cosmos/reflection/v1" - // runtimeservices "github.com/cosmos/cosmos-sdk/runtime/services" - // // SDK v47 - since we do not use dep inject, this gives us access to newer gRPC services. - // autocliv1.RegisterQueryServer(app.GRPCQueryRouter(), runtimeservices.NewAutoCLIQueryService(app.ModuleManager.Modules)) - // reflectionSvc, err := runtimeservices.NewReflectionService() - // if err != nil { - // panic(err) - // } - // reflectionv1.RegisterReflectionServiceServer(app.GRPCQueryRouter(), reflectionSvc) + autocliv1.RegisterQueryServer(app.GRPCQueryRouter(), runtimeservices.NewAutoCLIQueryService(app.ModuleManager.Modules)) + reflectionSvc, err := runtimeservices.NewReflectionService() + if err != nil { + panic(err) + } + reflectionv1.RegisterReflectionServiceServer(app.GRPCQueryRouter(), reflectionSvc) wasmConfig, err := wasm.ReadWasmConfig(appOpts) if err != nil { From 1fbc827ce07565e148e7ecee2960c14beeb9d531 Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Mon, 15 May 2023 13:59:01 -0500 Subject: [PATCH 115/131] Remove PFM for debugging --- app/keepers/keepers.go | 98 ++++++++++++++++++------------------ app/modules.go | 2 +- app/upgrades/v13/upgrades.go | 4 +- 3 files changed, 50 insertions(+), 54 deletions(-) diff --git a/app/keepers/keepers.go b/app/keepers/keepers.go index daabfa2e5..0a2989f03 100644 --- a/app/keepers/keepers.go +++ b/app/keepers/keepers.go @@ -64,9 +64,9 @@ import ( ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" ibckeeper "github.com/cosmos/ibc-go/v7/modules/core/keeper" - packetforward "github.com/strangelove-ventures/packet-forward-middleware/v7/router" - packetforwardkeeper "github.com/strangelove-ventures/packet-forward-middleware/v7/router/keeper" - packetforwardtypes "github.com/strangelove-ventures/packet-forward-middleware/v7/router/types" + // packetforward "github.com/strangelove-ventures/packet-forward-middleware/v7/router" + // packetforwardkeeper "github.com/strangelove-ventures/packet-forward-middleware/v7/router/keeper" + // packetforwardtypes "github.com/strangelove-ventures/packet-forward-middleware/v7/router/types" "github.com/CosmosContracts/juno/v15/x/tokenfactory/bindings" tokenfactorykeeper "github.com/CosmosContracts/juno/v15/x/tokenfactory/keeper" @@ -125,22 +125,22 @@ type AppKeepers struct { memKeys map[string]*storetypes.MemoryStoreKey // keepers - AccountKeeper authkeeper.AccountKeeper - BankKeeper bankkeeper.BaseKeeper - CapabilityKeeper *capabilitykeeper.Keeper - StakingKeeper *stakingkeeper.Keeper - SlashingKeeper slashingkeeper.Keeper - MintKeeper mintkeeper.Keeper - DistrKeeper distrkeeper.Keeper - GovKeeper govkeeper.Keeper - CrisisKeeper *crisiskeeper.Keeper - UpgradeKeeper *upgradekeeper.Keeper - ParamsKeeper paramskeeper.Keeper - IBCKeeper *ibckeeper.Keeper // IBC Keeper must be a pointer in the app, so we can SetRouter on it correctly - ICQKeeper icqkeeper.Keeper - IBCFeeKeeper ibcfeekeeper.Keeper - IBCHooksKeeper *ibchookskeeper.Keeper - PacketForwardKeeper *packetforwardkeeper.Keeper + AccountKeeper authkeeper.AccountKeeper + BankKeeper bankkeeper.BaseKeeper + CapabilityKeeper *capabilitykeeper.Keeper + StakingKeeper *stakingkeeper.Keeper + SlashingKeeper slashingkeeper.Keeper + MintKeeper mintkeeper.Keeper + DistrKeeper distrkeeper.Keeper + GovKeeper govkeeper.Keeper + CrisisKeeper *crisiskeeper.Keeper + UpgradeKeeper *upgradekeeper.Keeper + ParamsKeeper paramskeeper.Keeper + IBCKeeper *ibckeeper.Keeper // IBC Keeper must be a pointer in the app, so we can SetRouter on it correctly + ICQKeeper icqkeeper.Keeper + IBCFeeKeeper ibcfeekeeper.Keeper + IBCHooksKeeper *ibchookskeeper.Keeper + // PacketForwardKeeper *packetforwardkeeper.Keeper EvidenceKeeper evidencekeeper.Keeper TransferKeeper ibctransferkeeper.Keeper AuthzKeeper authzkeeper.Keeper @@ -165,8 +165,8 @@ type AppKeepers struct { TokenFactoryKeeper tokenfactorykeeper.Keeper // Middleware wrapper - Ics20WasmHooks *ibchooks.WasmHooks - // HooksICS4Wrapper ibchooks.ICS4Middleware + Ics20WasmHooks *ibchooks.WasmHooks + HooksICS4Wrapper ibchooks.ICS4Middleware } func NewAppKeepers( @@ -354,28 +354,27 @@ func NewAppKeepers( junoPrefix := sdk.GetConfig().GetBech32AccountAddrPrefix() wasmHooks := ibchooks.NewWasmHooks(appKeepers.IBCHooksKeeper, nil, junoPrefix) // The contract keeper needs to be set later appKeepers.Ics20WasmHooks = &wasmHooks - // appKeepers.HooksICS4Wrapper = ibchooks.NewICS4Middleware( - // appKeepers.IBCKeeper.ChannelKeeper, - // appKeepers.Ics20WasmHooks, - // ) - - // Initialize packet forward middleware router - appKeepers.PacketForwardKeeper = packetforwardkeeper.NewKeeper( - appCodec, appKeepers.keys[packetforwardtypes.StoreKey], - appKeepers.GetSubspace(packetforwardtypes.ModuleName), - appKeepers.TransferKeeper, // Will be zero-value here. Reference is set later on with SetTransferKeeper. + appKeepers.HooksICS4Wrapper = ibchooks.NewICS4Middleware( appKeepers.IBCKeeper.ChannelKeeper, - appKeepers.DistrKeeper, - appKeepers.BankKeeper, - // The ICS4Wrapper is replaced by the IBCFeeKeeper instead of the channel so that sending can be overridden by the middleware - &appKeepers.IBCFeeKeeper, + appKeepers.Ics20WasmHooks, ) + // Initialize packet forward middleware router + // appKeepers.PacketForwardKeeper = packetforwardkeeper.NewKeeper( + // appCodec, appKeepers.keys[packetforwardtypes.StoreKey], + // appKeepers.GetSubspace(packetforwardtypes.ModuleName), + // appKeepers.TransferKeeper, // Will be zero-value here. Reference is set later on with SetTransferKeeper. + // appKeepers.IBCKeeper.ChannelKeeper, + // appKeepers.DistrKeeper, + // appKeepers.BankKeeper, + // // The ICS4Wrapper is replaced by the IBCFeeKeeper instead of the channel so that sending can be overridden by the middleware + // &appKeepers.IBCFeeKeeper, + // ) + appKeepers.IBCFeeKeeper = ibcfeekeeper.NewKeeper( appCodec, appKeepers.keys[ibcfeetypes.StoreKey], - // appKeepers.HooksICS4Wrapper, // replaced with IBC middleware // TODO: - appKeepers.IBCKeeper.ChannelKeeper, // replaced with IBC middleware + appKeepers.HooksICS4Wrapper, // replaced with IBC middleware appKeepers.IBCKeeper.ChannelKeeper, &appKeepers.IBCKeeper.PortKeeper, appKeepers.AccountKeeper, @@ -388,7 +387,7 @@ func NewAppKeepers( appKeepers.keys[ibctransfertypes.StoreKey], appKeepers.GetSubspace(ibctransfertypes.ModuleName), // The ICS4Wrapper is replaced by the PacketForwardKeeper instead of the channel so that sending can be overridden by the middleware - appKeepers.PacketForwardKeeper, + appKeepers.IBCKeeper.ChannelKeeper, appKeepers.IBCKeeper.ChannelKeeper, &appKeepers.IBCKeeper.PortKeeper, appKeepers.AccountKeeper, @@ -408,14 +407,13 @@ func NewAppKeepers( NewQuerierWrapper(bApp), ) - appKeepers.PacketForwardKeeper.SetTransferKeeper(appKeepers.TransferKeeper) + // appKeepers.PacketForwardKeeper.SetTransferKeeper(appKeepers.TransferKeeper) appKeepers.ICAHostKeeper = icahostkeeper.NewKeeper( appCodec, appKeepers.keys[icahosttypes.StoreKey], appKeepers.GetSubspace(icahosttypes.SubModuleName), - // appKeepers.HooksICS4Wrapper, // TODO: - appKeepers.IBCKeeper.ChannelKeeper, + appKeepers.HooksICS4Wrapper, appKeepers.IBCKeeper.ChannelKeeper, &appKeepers.IBCKeeper.PortKeeper, appKeepers.AccountKeeper, @@ -539,15 +537,15 @@ func NewAppKeepers( // Create Transfer Stack var transferStack porttypes.IBCModule transferStack = transfer.NewIBCModule(appKeepers.TransferKeeper) - transferStack = packetforward.NewIBCMiddleware( - transferStack, - appKeepers.PacketForwardKeeper, - 0, - packetforwardkeeper.DefaultForwardTransferPacketTimeoutTimestamp, - packetforwardkeeper.DefaultRefundTransferPacketTimeoutTimestamp, - ) + // transferStack = packetforward.NewIBCMiddleware( + // transferStack, + // appKeepers.PacketForwardKeeper, + // 0, + // packetforwardkeeper.DefaultForwardTransferPacketTimeoutTimestamp, + // packetforwardkeeper.DefaultRefundTransferPacketTimeoutTimestamp, + // ) transferStack = ibcfee.NewIBCMiddleware(transferStack, appKeepers.IBCFeeKeeper) - // transferStack = ibchooks.NewIBCMiddleware(transferStack, &appKeepers.HooksICS4Wrapper) + transferStack = ibchooks.NewIBCMiddleware(transferStack, &appKeepers.HooksICS4Wrapper) // RecvPacket, message that originates from core IBC and goes down to app, the flow is: // channel.RecvPacket -> fee.OnRecvPacket -> icaHost.OnRecvPacket @@ -607,7 +605,7 @@ func initParamsKeeper(appCodec codec.BinaryCodec, legacyAmino *codec.LegacyAmino paramsKeeper.Subspace(icahosttypes.SubModuleName) paramsKeeper.Subspace(icacontrollertypes.SubModuleName) paramsKeeper.Subspace(icqtypes.ModuleName) - paramsKeeper.Subspace(packetforwardtypes.ModuleName) + // paramsKeeper.Subspace(packetforwardtypes.ModuleName) paramsKeeper.Subspace(globalfee.ModuleName) paramsKeeper.Subspace(tokenfactorytypes.ModuleName) paramsKeeper.Subspace(feesharetypes.ModuleName) diff --git a/app/modules.go b/app/modules.go index 7a772578c..5e3a42c3b 100644 --- a/app/modules.go +++ b/app/modules.go @@ -139,7 +139,7 @@ func appModules( crisis.NewAppModule(app.AppKeepers.CrisisKeeper, skipGenesisInvariants, app.GetSubspace(crisistypes.ModuleName)), // IBC modules icq.NewAppModule(app.AppKeepers.ICQKeeper), - packetforward.NewAppModule(app.AppKeepers.PacketForwardKeeper), + // packetforward.NewAppModule(app.AppKeepers.PacketForwardKeeper), } } diff --git a/app/upgrades/v13/upgrades.go b/app/upgrades/v13/upgrades.go index 36eddaf44..abb900b5e 100644 --- a/app/upgrades/v13/upgrades.go +++ b/app/upgrades/v13/upgrades.go @@ -18,8 +18,6 @@ import ( tokenfactorytypes "github.com/CosmosContracts/juno/v15/x/tokenfactory/types" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" ibcfeetypes "github.com/cosmos/ibc-go/v7/modules/apps/29-fee/types" - - packetforwardtypes "github.com/strangelove-ventures/packet-forward-middleware/v7/router/types" ) func CreateV13UpgradeHandler( @@ -77,7 +75,7 @@ func CreateV13UpgradeHandler( logger.Info("set feeshare params") // Packet Forward middleware initial params - keepers.PacketForwardKeeper.SetParams(ctx, packetforwardtypes.DefaultParams()) + // keepers.PacketForwardKeeper.SetParams(ctx, packetforwardtypes.DefaultParams()) return versionMap, err } From c58c1c5fca63040cf78e8e6fe8a3bcf52fcd1c99 Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Mon, 15 May 2023 15:03:13 -0500 Subject: [PATCH 116/131] Remove ibchooks & PFM fully --- app/keepers/keepers.go | 42 ++++++++++++++--------------- app/keepers/keys.go | 7 ++--- app/modules.go | 22 +++++++-------- interchaintest/ibc_transfer_test.go | 28 ++++++++++++++++--- 4 files changed, 58 insertions(+), 41 deletions(-) diff --git a/app/keepers/keepers.go b/app/keepers/keepers.go index 0a2989f03..24f2b944e 100644 --- a/app/keepers/keepers.go +++ b/app/keepers/keepers.go @@ -3,13 +3,12 @@ package keepers import ( "path/filepath" - ibchookstypes "github.com/CosmosContracts/juno/v15/x/ibchooks/types" "github.com/spf13/cast" "github.com/CosmWasm/wasmd/x/wasm" wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" - ibchooks "github.com/CosmosContracts/juno/v15/x/ibchooks" - ibchookskeeper "github.com/CosmosContracts/juno/v15/x/ibchooks/keeper" + + // ibchooks "github.com/CosmosContracts/juno/v15/x/ibchooks" mintkeeper "github.com/CosmosContracts/juno/v15/x/mint/keeper" minttypes "github.com/CosmosContracts/juno/v15/x/mint/types" "github.com/cosmos/cosmos-sdk/baseapp" @@ -18,7 +17,6 @@ import ( "github.com/cosmos/cosmos-sdk/server" servertypes "github.com/cosmos/cosmos-sdk/server/types" storetypes "github.com/cosmos/cosmos-sdk/store/types" - sdk "github.com/cosmos/cosmos-sdk/types" authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" authzkeeper "github.com/cosmos/cosmos-sdk/x/authz/keeper" @@ -139,7 +137,7 @@ type AppKeepers struct { IBCKeeper *ibckeeper.Keeper // IBC Keeper must be a pointer in the app, so we can SetRouter on it correctly ICQKeeper icqkeeper.Keeper IBCFeeKeeper ibcfeekeeper.Keeper - IBCHooksKeeper *ibchookskeeper.Keeper + // IBCHooksKeeper *ibchookskeeper.Keeper // PacketForwardKeeper *packetforwardkeeper.Keeper EvidenceKeeper evidencekeeper.Keeper TransferKeeper ibctransferkeeper.Keeper @@ -165,8 +163,8 @@ type AppKeepers struct { TokenFactoryKeeper tokenfactorykeeper.Keeper // Middleware wrapper - Ics20WasmHooks *ibchooks.WasmHooks - HooksICS4Wrapper ibchooks.ICS4Middleware + // Ics20WasmHooks *ibchooks.WasmHooks + // HooksICS4Wrapper ibchooks.ICS4Middleware } func NewAppKeepers( @@ -346,18 +344,18 @@ func NewAppKeepers( ) // Configure the hooks keeper - hooksKeeper := ibchookskeeper.NewKeeper( - appKeepers.keys[ibchookstypes.StoreKey], - ) - appKeepers.IBCHooksKeeper = &hooksKeeper + // hooksKeeper := ibchookskeeper.NewKeeper( + // appKeepers.keys[ibchookstypes.StoreKey], + // ) + // appKeepers.IBCHooksKeeper = &hooksKeeper - junoPrefix := sdk.GetConfig().GetBech32AccountAddrPrefix() - wasmHooks := ibchooks.NewWasmHooks(appKeepers.IBCHooksKeeper, nil, junoPrefix) // The contract keeper needs to be set later - appKeepers.Ics20WasmHooks = &wasmHooks - appKeepers.HooksICS4Wrapper = ibchooks.NewICS4Middleware( - appKeepers.IBCKeeper.ChannelKeeper, - appKeepers.Ics20WasmHooks, - ) + // junoPrefix := sdk.GetConfig().GetBech32AccountAddrPrefix() + // wasmHooks := ibchooks.NewWasmHooks(appKeepers.IBCHooksKeeper, nil, junoPrefix) // The contract keeper needs to be set later + // appKeepers.Ics20WasmHooks = &wasmHooks + // appKeepers.HooksICS4Wrapper = ibchooks.NewICS4Middleware( + // appKeepers.IBCKeeper.ChannelKeeper, + // appKeepers.Ics20WasmHooks, + // ) // Initialize packet forward middleware router // appKeepers.PacketForwardKeeper = packetforwardkeeper.NewKeeper( @@ -374,7 +372,7 @@ func NewAppKeepers( appKeepers.IBCFeeKeeper = ibcfeekeeper.NewKeeper( appCodec, appKeepers.keys[ibcfeetypes.StoreKey], - appKeepers.HooksICS4Wrapper, // replaced with IBC middleware + appKeepers.IBCKeeper.ChannelKeeper, // replaced with IBC middleware appKeepers.IBCKeeper.ChannelKeeper, &appKeepers.IBCKeeper.PortKeeper, appKeepers.AccountKeeper, @@ -413,7 +411,7 @@ func NewAppKeepers( appCodec, appKeepers.keys[icahosttypes.StoreKey], appKeepers.GetSubspace(icahosttypes.SubModuleName), - appKeepers.HooksICS4Wrapper, + appKeepers.IBCKeeper.ChannelKeeper, appKeepers.IBCKeeper.ChannelKeeper, &appKeepers.IBCKeeper.PortKeeper, appKeepers.AccountKeeper, @@ -545,7 +543,7 @@ func NewAppKeepers( // packetforwardkeeper.DefaultRefundTransferPacketTimeoutTimestamp, // ) transferStack = ibcfee.NewIBCMiddleware(transferStack, appKeepers.IBCFeeKeeper) - transferStack = ibchooks.NewIBCMiddleware(transferStack, &appKeepers.HooksICS4Wrapper) + // transferStack = ibchooks.NewIBCMiddleware(transferStack, &appKeepers.HooksICS4Wrapper) // RecvPacket, message that originates from core IBC and goes down to app, the flow is: // channel.RecvPacket -> fee.OnRecvPacket -> icaHost.OnRecvPacket @@ -578,7 +576,7 @@ func NewAppKeepers( // set the contract keeper for the Ics20WasmHooks appKeepers.ContractKeeper = &appKeepers.WasmKeeper - appKeepers.Ics20WasmHooks.ContractKeeper = appKeepers.ContractKeeper + // appKeepers.Ics20WasmHooks.ContractKeeper = appKeepers.ContractKeeper return appKeepers } diff --git a/app/keepers/keys.go b/app/keepers/keys.go index 2a47e7008..37d47dec3 100644 --- a/app/keepers/keys.go +++ b/app/keepers/keys.go @@ -3,7 +3,6 @@ package keepers import ( "github.com/CosmWasm/wasmd/x/wasm" feesharetypes "github.com/CosmosContracts/juno/v15/x/feeshare/types" - ibchookstypes "github.com/CosmosContracts/juno/v15/x/ibchooks/types" minttypes "github.com/CosmosContracts/juno/v15/x/mint/types" tokenfactorytypes "github.com/CosmosContracts/juno/v15/x/tokenfactory/types" storetypes "github.com/cosmos/cosmos-sdk/store/types" @@ -28,7 +27,7 @@ import ( ibctransfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" icqtypes "github.com/strangelove-ventures/async-icq/v7/types" - packetforwardtypes "github.com/strangelove-ventures/packet-forward-middleware/v7/router/types" + // packetforwardtypes "github.com/strangelove-ventures/packet-forward-middleware/v7/router/types" ) func (appKeepers *AppKeepers) GenerateKeys() { @@ -42,7 +41,9 @@ func (appKeepers *AppKeepers) GenerateKeys() { // non sdk store keys ibcexported.StoreKey, ibctransfertypes.StoreKey, ibcfeetypes.StoreKey, wasm.StoreKey, icahosttypes.StoreKey, - icacontrollertypes.StoreKey, icqtypes.StoreKey, packetforwardtypes.StoreKey, ibchookstypes.StoreKey, tokenfactorytypes.StoreKey, feesharetypes.StoreKey, + icacontrollertypes.StoreKey, icqtypes.StoreKey, + // packetforwardtypes.StoreKey, ibchookstypes.StoreKey, + tokenfactorytypes.StoreKey, feesharetypes.StoreKey, ) appKeepers.tkeys = sdk.NewTransientStoreKeys(paramstypes.TStoreKey) diff --git a/app/modules.go b/app/modules.go index 5e3a42c3b..32188eaaa 100644 --- a/app/modules.go +++ b/app/modules.go @@ -7,8 +7,6 @@ import ( feeshare "github.com/CosmosContracts/juno/v15/x/feeshare" feesharetypes "github.com/CosmosContracts/juno/v15/x/feeshare/types" "github.com/CosmosContracts/juno/v15/x/globalfee" - ibchooks "github.com/CosmosContracts/juno/v15/x/ibchooks" - ibchookstypes "github.com/CosmosContracts/juno/v15/x/ibchooks/types" "github.com/CosmosContracts/juno/v15/x/mint" minttypes "github.com/CosmosContracts/juno/v15/x/mint/types" "github.com/CosmosContracts/juno/v15/x/tokenfactory" @@ -58,8 +56,6 @@ import ( ibctm "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" icq "github.com/strangelove-ventures/async-icq/v7" icqtypes "github.com/strangelove-ventures/async-icq/v7/types" - packetforward "github.com/strangelove-ventures/packet-forward-middleware/v7/router" - packetforwardtypes "github.com/strangelove-ventures/packet-forward-middleware/v7/router/types" ) // ModuleBasics defines the module BasicManager is in charge of setting up basic, @@ -94,8 +90,8 @@ var ModuleBasics = module.NewBasicManager( tokenfactory.AppModuleBasic{}, feeshare.AppModuleBasic{}, globalfee.AppModuleBasic{}, - ibchooks.AppModuleBasic{}, - packetforward.AppModuleBasic{}, + // ibchooks.AppModuleBasic{}, + // packetforward.AppModuleBasic{}, ) func appModules( @@ -135,7 +131,7 @@ func appModules( feeshare.NewAppModule(app.AppKeepers.FeeShareKeeper, app.AppKeepers.AccountKeeper), wasm.NewAppModule(appCodec, &app.AppKeepers.WasmKeeper, app.AppKeepers.StakingKeeper, app.AppKeepers.AccountKeeper, app.AppKeepers.BankKeeper, app.MsgServiceRouter(), app.GetSubspace(wasmtypes.ModuleName)), ica.NewAppModule(&app.AppKeepers.ICAControllerKeeper, &app.AppKeepers.ICAHostKeeper), - ibchooks.NewAppModule(app.AppKeepers.AccountKeeper), + // ibchooks.NewAppModule(app.AppKeepers.AccountKeeper), crisis.NewAppModule(app.AppKeepers.CrisisKeeper, skipGenesisInvariants, app.GetSubspace(crisistypes.ModuleName)), // IBC modules icq.NewAppModule(app.AppKeepers.ICQKeeper), @@ -198,14 +194,14 @@ func orderBeginBlockers() []string { ibctransfertypes.ModuleName, ibcexported.ModuleName, icatypes.ModuleName, - packetforwardtypes.ModuleName, + // packetforwardtypes.ModuleName, ibcfeetypes.ModuleName, icqtypes.ModuleName, tokenfactorytypes.ModuleName, feesharetypes.ModuleName, globalfee.ModuleName, wasm.ModuleName, - ibchookstypes.ModuleName, + // ibchookstypes.ModuleName, } } @@ -232,14 +228,14 @@ func orderEndBlockers() []string { ibctransfertypes.ModuleName, ibcexported.ModuleName, icatypes.ModuleName, - packetforwardtypes.ModuleName, + // packetforwardtypes.ModuleName, ibcfeetypes.ModuleName, icqtypes.ModuleName, tokenfactorytypes.ModuleName, feesharetypes.ModuleName, globalfee.ModuleName, wasm.ModuleName, - ibchookstypes.ModuleName, + // ibchookstypes.ModuleName, } } @@ -266,13 +262,13 @@ func orderInitBlockers() []string { ibctransfertypes.ModuleName, ibcexported.ModuleName, icatypes.ModuleName, - packetforwardtypes.ModuleName, + // packetforwardtypes.ModuleName, ibcfeetypes.ModuleName, icqtypes.ModuleName, tokenfactorytypes.ModuleName, feesharetypes.ModuleName, globalfee.ModuleName, wasm.ModuleName, - ibchookstypes.ModuleName, + // ibchookstypes.ModuleName, } } diff --git a/interchaintest/ibc_transfer_test.go b/interchaintest/ibc_transfer_test.go index c59b8623f..6edc549c3 100644 --- a/interchaintest/ibc_transfer_test.go +++ b/interchaintest/ibc_transfer_test.go @@ -2,12 +2,14 @@ package interchaintest import ( "context" + "fmt" "testing" transfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" "github.com/strangelove-ventures/interchaintest/v7" "github.com/strangelove-ventures/interchaintest/v7/chain/cosmos" "github.com/strangelove-ventures/interchaintest/v7/ibc" + interchaintestrelayer "github.com/strangelove-ventures/interchaintest/v7/relayer" "github.com/strangelove-ventures/interchaintest/v7/testreporter" "github.com/strangelove-ventures/interchaintest/v7/testutil" "github.com/stretchr/testify/require" @@ -36,7 +38,7 @@ func TestJunoGaiaIBCTransfer(t *testing.T) { }, { Name: "gaia", - Version: "v9.0.0", + Version: "v9.1.0", NumValidators: &numVals, NumFullNodes: &numFullNodes, }, @@ -60,6 +62,15 @@ func TestJunoGaiaIBCTransfer(t *testing.T) { rf := interchaintest.NewBuiltinRelayerFactory( relayerType, zaptest.NewLogger(t), + // relayer.RelayerOptionDockerImage{ + // DockerImage: ibc.DockerImage{ + // Repository: , + // Version: "main", + // UidGid: JunoImage.UidGid, + // }, + // }, + interchaintestrelayer.CustomDockerImage("ghcr.io/cosmos/relayer", "latest", "100:1000"), + interchaintestrelayer.StartupFlags("--processor", "events", "--block-history", "100"), ) r := rf.Build(t, client, network) @@ -127,11 +138,22 @@ func TestJunoGaiaIBCTransfer(t *testing.T) { transferTx, err := juno.SendIBCTransfer(ctx, channel.ChannelID, junoUserAddr, transfer, ibc.TransferOptions{}) require.NoError(t, err) + // TODO The packet exits the users account with the 1_000 in funds, but never is ack'ed. + + // print transferTx + junoHeight, err := juno.Height(ctx) require.NoError(t, err) + t.Log("JUNO RPC", fmt.Sprintf("export JUNOD_NODE=%s", juno.GetHostRPCAddress())) + t.Log("GAIA RPC", fmt.Sprintf("export GAIAD_NODE=%s", gaia.GetHostRPCAddress())) + t.Log(transferTx.TxHash) + // Poll for the ack to know the transfer was successful - _, err = testutil.PollForAck(ctx, juno, junoHeight, junoHeight+10, transferTx.Packet) + _, err = testutil.PollForAck(ctx, juno, junoHeight-5, junoHeight+50, transferTx.Packet) + require.NoError(t, err) + + err = testutil.WaitForBlocks(ctx, 10, juno) require.NoError(t, err) // Get the IBC denom for ujuno on Gaia @@ -161,7 +183,7 @@ func TestJunoGaiaIBCTransfer(t *testing.T) { require.NoError(t, err) // Poll for the ack to know the transfer was successful - _, err = testutil.PollForAck(ctx, gaia, gaiaHeight, gaiaHeight+10, transferTx.Packet) + _, err = testutil.PollForAck(ctx, gaia, gaiaHeight, gaiaHeight+25, transferTx.Packet) require.NoError(t, err) // Assert that the funds are now back on Juno and not on Gaia From 9eea99c146f11e28c0922d44e05b4ccd9d4d6cac Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Tue, 16 May 2023 16:36:28 -0500 Subject: [PATCH 117/131] Force Flush IBC Packets to Ack --- interchaintest/ibc_transfer_test.go | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/interchaintest/ibc_transfer_test.go b/interchaintest/ibc_transfer_test.go index 6edc549c3..f26e89065 100644 --- a/interchaintest/ibc_transfer_test.go +++ b/interchaintest/ibc_transfer_test.go @@ -2,7 +2,6 @@ package interchaintest import ( "context" - "fmt" "testing" transfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" @@ -62,13 +61,6 @@ func TestJunoGaiaIBCTransfer(t *testing.T) { rf := interchaintest.NewBuiltinRelayerFactory( relayerType, zaptest.NewLogger(t), - // relayer.RelayerOptionDockerImage{ - // DockerImage: ibc.DockerImage{ - // Repository: , - // Version: "main", - // UidGid: JunoImage.UidGid, - // }, - // }, interchaintestrelayer.CustomDockerImage("ghcr.io/cosmos/relayer", "latest", "100:1000"), interchaintestrelayer.StartupFlags("--processor", "events", "--block-history", "100"), ) @@ -145,11 +137,8 @@ func TestJunoGaiaIBCTransfer(t *testing.T) { junoHeight, err := juno.Height(ctx) require.NoError(t, err) - t.Log("JUNO RPC", fmt.Sprintf("export JUNOD_NODE=%s", juno.GetHostRPCAddress())) - t.Log("GAIA RPC", fmt.Sprintf("export GAIAD_NODE=%s", gaia.GetHostRPCAddress())) - t.Log(transferTx.TxHash) - // Poll for the ack to know the transfer was successful + r.Flush(ctx, eRep, path, channel.ChannelID) _, err = testutil.PollForAck(ctx, juno, junoHeight-5, junoHeight+50, transferTx.Packet) require.NoError(t, err) @@ -183,6 +172,7 @@ func TestJunoGaiaIBCTransfer(t *testing.T) { require.NoError(t, err) // Poll for the ack to know the transfer was successful + r.Flush(ctx, eRep, path, channel.Counterparty.ChannelID) _, err = testutil.PollForAck(ctx, gaia, gaiaHeight, gaiaHeight+25, transferTx.Packet) require.NoError(t, err) From 6c710f4b1de58739b278ed4a8c035f317c75a2ec Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Tue, 16 May 2023 16:49:33 -0500 Subject: [PATCH 118/131] Docker with cache --- .github/workflows/build_docker.yml | 4 +++- .github/workflows/interchaintest-E2E.yml | 7 +++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build_docker.yml b/.github/workflows/build_docker.yml index 066af9387..febe31be9 100644 --- a/.github/workflows/build_docker.yml +++ b/.github/workflows/build_docker.yml @@ -27,4 +27,6 @@ jobs: context: . platforms: linux/amd64 push: false - build-args: arch=x86_64 \ No newline at end of file + build-args: arch=x86_64 + cache-from: type=gha + cache-to: type=gha,mode=max \ No newline at end of file diff --git a/.github/workflows/interchaintest-E2E.yml b/.github/workflows/interchaintest-E2E.yml index 45f08332a..5a95d80b6 100644 --- a/.github/workflows/interchaintest-E2E.yml +++ b/.github/workflows/interchaintest-E2E.yml @@ -53,6 +53,13 @@ jobs: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v2 + with: + context: . + platforms: linux/amd64 + push: false + build-args: arch=x86_64 + cache-from: type=gha + cache-to: type=gha,mode=max - name: Log in to the Container registry uses: docker/login-action@v2 From 05ac7190cec806378a70ae785042849a0cd6de17 Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Tue, 16 May 2023 17:10:02 -0500 Subject: [PATCH 119/131] Add back IBCHooks --- app/keepers/keepers.go | 40 ++++++++++++++++++++++------------------ app/keepers/keys.go | 4 +++- app/modules.go | 12 +++++++----- 3 files changed, 32 insertions(+), 24 deletions(-) diff --git a/app/keepers/keepers.go b/app/keepers/keepers.go index 24f2b944e..9ae72ca1c 100644 --- a/app/keepers/keepers.go +++ b/app/keepers/keepers.go @@ -5,10 +5,14 @@ import ( "github.com/spf13/cast" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/CosmWasm/wasmd/x/wasm" wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" - // ibchooks "github.com/CosmosContracts/juno/v15/x/ibchooks" + "github.com/CosmosContracts/juno/v15/x/ibchooks" + ibchookskeeper "github.com/CosmosContracts/juno/v15/x/ibchooks/keeper" + ibchookstypes "github.com/CosmosContracts/juno/v15/x/ibchooks/types" mintkeeper "github.com/CosmosContracts/juno/v15/x/mint/keeper" minttypes "github.com/CosmosContracts/juno/v15/x/mint/types" "github.com/cosmos/cosmos-sdk/baseapp" @@ -137,7 +141,7 @@ type AppKeepers struct { IBCKeeper *ibckeeper.Keeper // IBC Keeper must be a pointer in the app, so we can SetRouter on it correctly ICQKeeper icqkeeper.Keeper IBCFeeKeeper ibcfeekeeper.Keeper - // IBCHooksKeeper *ibchookskeeper.Keeper + IBCHooksKeeper *ibchookskeeper.Keeper // PacketForwardKeeper *packetforwardkeeper.Keeper EvidenceKeeper evidencekeeper.Keeper TransferKeeper ibctransferkeeper.Keeper @@ -163,8 +167,8 @@ type AppKeepers struct { TokenFactoryKeeper tokenfactorykeeper.Keeper // Middleware wrapper - // Ics20WasmHooks *ibchooks.WasmHooks - // HooksICS4Wrapper ibchooks.ICS4Middleware + Ics20WasmHooks *ibchooks.WasmHooks + HooksICS4Wrapper ibchooks.ICS4Middleware } func NewAppKeepers( @@ -344,18 +348,18 @@ func NewAppKeepers( ) // Configure the hooks keeper - // hooksKeeper := ibchookskeeper.NewKeeper( - // appKeepers.keys[ibchookstypes.StoreKey], - // ) - // appKeepers.IBCHooksKeeper = &hooksKeeper + hooksKeeper := ibchookskeeper.NewKeeper( + appKeepers.keys[ibchookstypes.StoreKey], + ) + appKeepers.IBCHooksKeeper = &hooksKeeper - // junoPrefix := sdk.GetConfig().GetBech32AccountAddrPrefix() - // wasmHooks := ibchooks.NewWasmHooks(appKeepers.IBCHooksKeeper, nil, junoPrefix) // The contract keeper needs to be set later - // appKeepers.Ics20WasmHooks = &wasmHooks - // appKeepers.HooksICS4Wrapper = ibchooks.NewICS4Middleware( - // appKeepers.IBCKeeper.ChannelKeeper, - // appKeepers.Ics20WasmHooks, - // ) + junoPrefix := sdk.GetConfig().GetBech32AccountAddrPrefix() + wasmHooks := ibchooks.NewWasmHooks(appKeepers.IBCHooksKeeper, nil, junoPrefix) // The contract keeper needs to be set later + appKeepers.Ics20WasmHooks = &wasmHooks + appKeepers.HooksICS4Wrapper = ibchooks.NewICS4Middleware( + appKeepers.IBCKeeper.ChannelKeeper, + appKeepers.Ics20WasmHooks, + ) // Initialize packet forward middleware router // appKeepers.PacketForwardKeeper = packetforwardkeeper.NewKeeper( @@ -372,7 +376,7 @@ func NewAppKeepers( appKeepers.IBCFeeKeeper = ibcfeekeeper.NewKeeper( appCodec, appKeepers.keys[ibcfeetypes.StoreKey], - appKeepers.IBCKeeper.ChannelKeeper, // replaced with IBC middleware + appKeepers.HooksICS4Wrapper, // replaced with IBC middleware appKeepers.IBCKeeper.ChannelKeeper, &appKeepers.IBCKeeper.PortKeeper, appKeepers.AccountKeeper, @@ -411,7 +415,7 @@ func NewAppKeepers( appCodec, appKeepers.keys[icahosttypes.StoreKey], appKeepers.GetSubspace(icahosttypes.SubModuleName), - appKeepers.IBCKeeper.ChannelKeeper, + appKeepers.HooksICS4Wrapper, appKeepers.IBCKeeper.ChannelKeeper, &appKeepers.IBCKeeper.PortKeeper, appKeepers.AccountKeeper, @@ -576,7 +580,7 @@ func NewAppKeepers( // set the contract keeper for the Ics20WasmHooks appKeepers.ContractKeeper = &appKeepers.WasmKeeper - // appKeepers.Ics20WasmHooks.ContractKeeper = appKeepers.ContractKeeper + appKeepers.Ics20WasmHooks.ContractKeeper = appKeepers.ContractKeeper return appKeepers } diff --git a/app/keepers/keys.go b/app/keepers/keys.go index 37d47dec3..30ad2f585 100644 --- a/app/keepers/keys.go +++ b/app/keepers/keys.go @@ -3,6 +3,7 @@ package keepers import ( "github.com/CosmWasm/wasmd/x/wasm" feesharetypes "github.com/CosmosContracts/juno/v15/x/feeshare/types" + ibchookstypes "github.com/CosmosContracts/juno/v15/x/ibchooks/types" minttypes "github.com/CosmosContracts/juno/v15/x/mint/types" tokenfactorytypes "github.com/CosmosContracts/juno/v15/x/tokenfactory/types" storetypes "github.com/cosmos/cosmos-sdk/store/types" @@ -42,7 +43,8 @@ func (appKeepers *AppKeepers) GenerateKeys() { ibcexported.StoreKey, ibctransfertypes.StoreKey, ibcfeetypes.StoreKey, wasm.StoreKey, icahosttypes.StoreKey, icacontrollertypes.StoreKey, icqtypes.StoreKey, - // packetforwardtypes.StoreKey, ibchookstypes.StoreKey, + // packetforwardtypes.StoreKey, + ibchookstypes.StoreKey, tokenfactorytypes.StoreKey, feesharetypes.StoreKey, ) diff --git a/app/modules.go b/app/modules.go index 32188eaaa..bfdca58db 100644 --- a/app/modules.go +++ b/app/modules.go @@ -7,6 +7,8 @@ import ( feeshare "github.com/CosmosContracts/juno/v15/x/feeshare" feesharetypes "github.com/CosmosContracts/juno/v15/x/feeshare/types" "github.com/CosmosContracts/juno/v15/x/globalfee" + "github.com/CosmosContracts/juno/v15/x/ibchooks" + ibchookstypes "github.com/CosmosContracts/juno/v15/x/ibchooks/types" "github.com/CosmosContracts/juno/v15/x/mint" minttypes "github.com/CosmosContracts/juno/v15/x/mint/types" "github.com/CosmosContracts/juno/v15/x/tokenfactory" @@ -90,7 +92,7 @@ var ModuleBasics = module.NewBasicManager( tokenfactory.AppModuleBasic{}, feeshare.AppModuleBasic{}, globalfee.AppModuleBasic{}, - // ibchooks.AppModuleBasic{}, + ibchooks.AppModuleBasic{}, // packetforward.AppModuleBasic{}, ) @@ -131,9 +133,9 @@ func appModules( feeshare.NewAppModule(app.AppKeepers.FeeShareKeeper, app.AppKeepers.AccountKeeper), wasm.NewAppModule(appCodec, &app.AppKeepers.WasmKeeper, app.AppKeepers.StakingKeeper, app.AppKeepers.AccountKeeper, app.AppKeepers.BankKeeper, app.MsgServiceRouter(), app.GetSubspace(wasmtypes.ModuleName)), ica.NewAppModule(&app.AppKeepers.ICAControllerKeeper, &app.AppKeepers.ICAHostKeeper), - // ibchooks.NewAppModule(app.AppKeepers.AccountKeeper), crisis.NewAppModule(app.AppKeepers.CrisisKeeper, skipGenesisInvariants, app.GetSubspace(crisistypes.ModuleName)), // IBC modules + ibchooks.NewAppModule(app.AppKeepers.AccountKeeper), icq.NewAppModule(app.AppKeepers.ICQKeeper), // packetforward.NewAppModule(app.AppKeepers.PacketForwardKeeper), } @@ -201,7 +203,7 @@ func orderBeginBlockers() []string { feesharetypes.ModuleName, globalfee.ModuleName, wasm.ModuleName, - // ibchookstypes.ModuleName, + ibchookstypes.ModuleName, } } @@ -235,7 +237,7 @@ func orderEndBlockers() []string { feesharetypes.ModuleName, globalfee.ModuleName, wasm.ModuleName, - // ibchookstypes.ModuleName, + ibchookstypes.ModuleName, } } @@ -269,6 +271,6 @@ func orderInitBlockers() []string { feesharetypes.ModuleName, globalfee.ModuleName, wasm.ModuleName, - // ibchookstypes.ModuleName, + ibchookstypes.ModuleName, } } From 2491a44f8e76163cfbf0f651ba26c15067018f54 Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Tue, 16 May 2023 17:19:04 -0500 Subject: [PATCH 120/131] Remove buildx cache --- .github/workflows/build_docker.yml | 4 +--- .github/workflows/interchaintest-E2E.yml | 2 -- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/.github/workflows/build_docker.yml b/.github/workflows/build_docker.yml index febe31be9..066af9387 100644 --- a/.github/workflows/build_docker.yml +++ b/.github/workflows/build_docker.yml @@ -27,6 +27,4 @@ jobs: context: . platforms: linux/amd64 push: false - build-args: arch=x86_64 - cache-from: type=gha - cache-to: type=gha,mode=max \ No newline at end of file + build-args: arch=x86_64 \ No newline at end of file diff --git a/.github/workflows/interchaintest-E2E.yml b/.github/workflows/interchaintest-E2E.yml index 5a95d80b6..903d4ea0d 100644 --- a/.github/workflows/interchaintest-E2E.yml +++ b/.github/workflows/interchaintest-E2E.yml @@ -58,8 +58,6 @@ jobs: platforms: linux/amd64 push: false build-args: arch=x86_64 - cache-from: type=gha - cache-to: type=gha,mode=max - name: Log in to the Container registry uses: docker/login-action@v2 From 250b715317ff31b947eba041b30ce070ad97a793 Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Tue, 16 May 2023 17:32:45 -0500 Subject: [PATCH 121/131] remove buildx context --- .github/workflows/interchaintest-E2E.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.github/workflows/interchaintest-E2E.yml b/.github/workflows/interchaintest-E2E.yml index 903d4ea0d..45f08332a 100644 --- a/.github/workflows/interchaintest-E2E.yml +++ b/.github/workflows/interchaintest-E2E.yml @@ -53,11 +53,6 @@ jobs: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v2 - with: - context: . - platforms: linux/amd64 - push: false - build-args: arch=x86_64 - name: Log in to the Container registry uses: docker/login-action@v2 From 236ef8c7a18f000555525de752b2e2d93ee39233 Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Tue, 16 May 2023 18:19:18 -0500 Subject: [PATCH 122/131] Add back PFM but use ChannelKeeper instead of IBCFeeKeeper --- Makefile | 20 +++---- app/keepers/keepers.go | 104 +++++++++++++++++------------------ app/keepers/keys.go | 4 +- app/modules.go | 13 +++-- app/upgrades/v13/upgrades.go | 3 +- 5 files changed, 74 insertions(+), 70 deletions(-) diff --git a/Makefile b/Makefile index ca0db3e41..593372978 100644 --- a/Makefile +++ b/Makefile @@ -122,37 +122,37 @@ benchmark: ############################################################################### # Executes basic chain tests via interchaintest -ictest-basic: +ictest-basic: rm-testcache cd interchaintest && go test -race -v -run TestBasicJunoStart . -ictest-tokenfactory: +ictest-tokenfactory: rm-testcache cd interchaintest && go test -race -v -run TestJunoTokenFactory . -ictest-feeshare: +ictest-feeshare: rm-testcache cd interchaintest && go test -race -v -run TestJunoFeeShare . # Executes a basic chain upgrade test via interchaintest -ictest-upgrade: +ictest-upgrade: rm-testcache cd interchaintest && go test -race -v -run TestBasicJunoUpgrade . # Executes a basic chain upgrade locally via interchaintest after compiling a local image as juno:local ictest-upgrade-local: local-image ictest-upgrade # Executes IBC tests via interchaintest -ictest-ibc: +ictest-ibc: rm-testcache cd interchaintest && go test -race -v -run TestJunoGaiaIBCTransfer . # Unity contract CI -ictest-unity-deploy: +ictest-unity-deploy: rm-testcache cd interchaintest && go test -race -v -run TestJunoUnityContractDeploy . -ictest-unity-gov: +ictest-unity-gov: rm-testcache cd interchaintest && go test -race -v -run TestJunoUnityContractGovSubmit . -# Executes all tests via interchaintest after compling a local image as juno:local -ictest-all: local-image ictest-basic ictest-upgrade ictest-ibc +rm-testcache: + go clean -testcache -.PHONY: test-mutation ictest-basic ictest-upgrade ictest-ibc ictest-all +.PHONY: test-mutation ictest-basic ictest-upgrade ictest-ibc ictest-unity-deploy ictest-unity-gov ############################################################################### ### heighliner ### diff --git a/app/keepers/keepers.go b/app/keepers/keepers.go index 9ae72ca1c..8be1dc248 100644 --- a/app/keepers/keepers.go +++ b/app/keepers/keepers.go @@ -66,9 +66,9 @@ import ( ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" ibckeeper "github.com/cosmos/ibc-go/v7/modules/core/keeper" - // packetforward "github.com/strangelove-ventures/packet-forward-middleware/v7/router" - // packetforwardkeeper "github.com/strangelove-ventures/packet-forward-middleware/v7/router/keeper" - // packetforwardtypes "github.com/strangelove-ventures/packet-forward-middleware/v7/router/types" + packetforward "github.com/strangelove-ventures/packet-forward-middleware/v7/router" + packetforwardkeeper "github.com/strangelove-ventures/packet-forward-middleware/v7/router/keeper" + packetforwardtypes "github.com/strangelove-ventures/packet-forward-middleware/v7/router/types" "github.com/CosmosContracts/juno/v15/x/tokenfactory/bindings" tokenfactorykeeper "github.com/CosmosContracts/juno/v15/x/tokenfactory/keeper" @@ -127,22 +127,22 @@ type AppKeepers struct { memKeys map[string]*storetypes.MemoryStoreKey // keepers - AccountKeeper authkeeper.AccountKeeper - BankKeeper bankkeeper.BaseKeeper - CapabilityKeeper *capabilitykeeper.Keeper - StakingKeeper *stakingkeeper.Keeper - SlashingKeeper slashingkeeper.Keeper - MintKeeper mintkeeper.Keeper - DistrKeeper distrkeeper.Keeper - GovKeeper govkeeper.Keeper - CrisisKeeper *crisiskeeper.Keeper - UpgradeKeeper *upgradekeeper.Keeper - ParamsKeeper paramskeeper.Keeper - IBCKeeper *ibckeeper.Keeper // IBC Keeper must be a pointer in the app, so we can SetRouter on it correctly - ICQKeeper icqkeeper.Keeper - IBCFeeKeeper ibcfeekeeper.Keeper - IBCHooksKeeper *ibchookskeeper.Keeper - // PacketForwardKeeper *packetforwardkeeper.Keeper + AccountKeeper authkeeper.AccountKeeper + BankKeeper bankkeeper.BaseKeeper + CapabilityKeeper *capabilitykeeper.Keeper + StakingKeeper *stakingkeeper.Keeper + SlashingKeeper slashingkeeper.Keeper + MintKeeper mintkeeper.Keeper + DistrKeeper distrkeeper.Keeper + GovKeeper govkeeper.Keeper + CrisisKeeper *crisiskeeper.Keeper + UpgradeKeeper *upgradekeeper.Keeper + ParamsKeeper paramskeeper.Keeper + IBCKeeper *ibckeeper.Keeper // IBC Keeper must be a pointer in the app, so we can SetRouter on it correctly + ICQKeeper icqkeeper.Keeper + IBCFeeKeeper ibcfeekeeper.Keeper + IBCHooksKeeper *ibchookskeeper.Keeper + PacketForwardKeeper *packetforwardkeeper.Keeper EvidenceKeeper evidencekeeper.Keeper TransferKeeper ibctransferkeeper.Keeper AuthzKeeper authzkeeper.Keeper @@ -361,18 +361,6 @@ func NewAppKeepers( appKeepers.Ics20WasmHooks, ) - // Initialize packet forward middleware router - // appKeepers.PacketForwardKeeper = packetforwardkeeper.NewKeeper( - // appCodec, appKeepers.keys[packetforwardtypes.StoreKey], - // appKeepers.GetSubspace(packetforwardtypes.ModuleName), - // appKeepers.TransferKeeper, // Will be zero-value here. Reference is set later on with SetTransferKeeper. - // appKeepers.IBCKeeper.ChannelKeeper, - // appKeepers.DistrKeeper, - // appKeepers.BankKeeper, - // // The ICS4Wrapper is replaced by the IBCFeeKeeper instead of the channel so that sending can be overridden by the middleware - // &appKeepers.IBCFeeKeeper, - // ) - appKeepers.IBCFeeKeeper = ibcfeekeeper.NewKeeper( appCodec, appKeepers.keys[ibcfeetypes.StoreKey], @@ -383,13 +371,26 @@ func NewAppKeepers( appKeepers.BankKeeper, ) + // Initialize packet forward middleware router + appKeepers.PacketForwardKeeper = packetforwardkeeper.NewKeeper( + appCodec, appKeepers.keys[packetforwardtypes.StoreKey], + appKeepers.GetSubspace(packetforwardtypes.ModuleName), + appKeepers.TransferKeeper, // Will be zero-value here. Reference is set later on with SetTransferKeeper. + appKeepers.IBCKeeper.ChannelKeeper, + appKeepers.DistrKeeper, + appKeepers.BankKeeper, + // The ICS4Wrapper is replaced by the IBCFeeKeeper instead of the channel so that sending can be overridden by the middleware + // &appKeepers.IBCFeeKeeper, + appKeepers.IBCKeeper.ChannelKeeper, + ) + // Create Transfer Keepers appKeepers.TransferKeeper = ibctransferkeeper.NewKeeper( appCodec, appKeepers.keys[ibctransfertypes.StoreKey], appKeepers.GetSubspace(ibctransfertypes.ModuleName), // The ICS4Wrapper is replaced by the PacketForwardKeeper instead of the channel so that sending can be overridden by the middleware - appKeepers.IBCKeeper.ChannelKeeper, + appKeepers.PacketForwardKeeper, appKeepers.IBCKeeper.ChannelKeeper, &appKeepers.IBCKeeper.PortKeeper, appKeepers.AccountKeeper, @@ -397,6 +398,8 @@ func NewAppKeepers( scopedTransferKeeper, ) + appKeepers.PacketForwardKeeper.SetTransferKeeper(appKeepers.TransferKeeper) + // ICQ Keeper appKeepers.ICQKeeper = icqkeeper.NewKeeper( appCodec, @@ -409,8 +412,6 @@ func NewAppKeepers( NewQuerierWrapper(bApp), ) - // appKeepers.PacketForwardKeeper.SetTransferKeeper(appKeepers.TransferKeeper) - appKeepers.ICAHostKeeper = icahostkeeper.NewKeeper( appCodec, appKeepers.keys[icahosttypes.StoreKey], @@ -431,13 +432,6 @@ func NewAppKeepers( scopedICAControllerKeeper, bApp.MsgServiceRouter(), ) - icaHostIBCModule := icahost.NewIBCModule(appKeepers.ICAHostKeeper) - - // initialize ICA module with mock module as the authentication module on the controller side - var icaControllerStack porttypes.IBCModule - icaControllerStack = icacontroller.NewIBCMiddleware(icaControllerStack, appKeepers.ICAControllerKeeper) - icaControllerStack = ibcfee.NewIBCMiddleware(icaControllerStack, appKeepers.IBCFeeKeeper) - // Create evidence Keeper for to register the IBC light client misbehaviour evidence route evidenceKeeper := evidencekeeper.NewKeeper( appCodec, appKeepers.keys[evidencetypes.StoreKey], appKeepers.StakingKeeper, appKeepers.SlashingKeeper, @@ -539,19 +533,26 @@ func NewAppKeepers( // Create Transfer Stack var transferStack porttypes.IBCModule transferStack = transfer.NewIBCModule(appKeepers.TransferKeeper) - // transferStack = packetforward.NewIBCMiddleware( - // transferStack, - // appKeepers.PacketForwardKeeper, - // 0, - // packetforwardkeeper.DefaultForwardTransferPacketTimeoutTimestamp, - // packetforwardkeeper.DefaultRefundTransferPacketTimeoutTimestamp, - // ) transferStack = ibcfee.NewIBCMiddleware(transferStack, appKeepers.IBCFeeKeeper) - // transferStack = ibchooks.NewIBCMiddleware(transferStack, &appKeepers.HooksICS4Wrapper) + transferStack = ibchooks.NewIBCMiddleware(transferStack, &appKeepers.HooksICS4Wrapper) + transferStack = packetforward.NewIBCMiddleware( + transferStack, + appKeepers.PacketForwardKeeper, + 0, + packetforwardkeeper.DefaultForwardTransferPacketTimeoutTimestamp, + packetforwardkeeper.DefaultRefundTransferPacketTimeoutTimestamp, + ) + + // initialize ICA module with mock module as the authentication module on the controller side + var icaControllerStack porttypes.IBCModule + icaControllerStack = icacontroller.NewIBCMiddleware(icaControllerStack, appKeepers.ICAControllerKeeper) + icaControllerStack = ibcfee.NewIBCMiddleware(icaControllerStack, appKeepers.IBCFeeKeeper) // RecvPacket, message that originates from core IBC and goes down to app, the flow is: // channel.RecvPacket -> fee.OnRecvPacket -> icaHost.OnRecvPacket - icaHostStack := ibcfee.NewIBCMiddleware(icaHostIBCModule, appKeepers.IBCFeeKeeper) + var icaHostStack porttypes.IBCModule + icaHostStack = icahost.NewIBCModule(appKeepers.ICAHostKeeper) + icaHostStack = ibcfee.NewIBCMiddleware(icaHostStack, appKeepers.IBCFeeKeeper) // Create fee enabled wasm ibc Stack var wasmStack porttypes.IBCModule @@ -568,7 +569,6 @@ func NewAppKeepers( AddRoute(icacontrollertypes.SubModuleName, icaControllerStack). AddRoute(icahosttypes.SubModuleName, icaHostStack). AddRoute(icqtypes.ModuleName, icqModule) - appKeepers.IBCKeeper.SetRouter(ibcRouter) appKeepers.ScopedIBCKeeper = scopedIBCKeeper @@ -607,7 +607,7 @@ func initParamsKeeper(appCodec codec.BinaryCodec, legacyAmino *codec.LegacyAmino paramsKeeper.Subspace(icahosttypes.SubModuleName) paramsKeeper.Subspace(icacontrollertypes.SubModuleName) paramsKeeper.Subspace(icqtypes.ModuleName) - // paramsKeeper.Subspace(packetforwardtypes.ModuleName) + paramsKeeper.Subspace(packetforwardtypes.ModuleName) paramsKeeper.Subspace(globalfee.ModuleName) paramsKeeper.Subspace(tokenfactorytypes.ModuleName) paramsKeeper.Subspace(feesharetypes.ModuleName) diff --git a/app/keepers/keys.go b/app/keepers/keys.go index 30ad2f585..0933a9500 100644 --- a/app/keepers/keys.go +++ b/app/keepers/keys.go @@ -28,7 +28,7 @@ import ( ibctransfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" icqtypes "github.com/strangelove-ventures/async-icq/v7/types" - // packetforwardtypes "github.com/strangelove-ventures/packet-forward-middleware/v7/router/types" + packetforwardtypes "github.com/strangelove-ventures/packet-forward-middleware/v7/router/types" ) func (appKeepers *AppKeepers) GenerateKeys() { @@ -43,7 +43,7 @@ func (appKeepers *AppKeepers) GenerateKeys() { ibcexported.StoreKey, ibctransfertypes.StoreKey, ibcfeetypes.StoreKey, wasm.StoreKey, icahosttypes.StoreKey, icacontrollertypes.StoreKey, icqtypes.StoreKey, - // packetforwardtypes.StoreKey, + packetforwardtypes.StoreKey, ibchookstypes.StoreKey, tokenfactorytypes.StoreKey, feesharetypes.StoreKey, ) diff --git a/app/modules.go b/app/modules.go index bfdca58db..6cae325fa 100644 --- a/app/modules.go +++ b/app/modules.go @@ -58,6 +58,9 @@ import ( ibctm "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" icq "github.com/strangelove-ventures/async-icq/v7" icqtypes "github.com/strangelove-ventures/async-icq/v7/types" + + packetforward "github.com/strangelove-ventures/packet-forward-middleware/v7/router" + packetforwardtypes "github.com/strangelove-ventures/packet-forward-middleware/v7/router/types" ) // ModuleBasics defines the module BasicManager is in charge of setting up basic, @@ -93,7 +96,7 @@ var ModuleBasics = module.NewBasicManager( feeshare.AppModuleBasic{}, globalfee.AppModuleBasic{}, ibchooks.AppModuleBasic{}, - // packetforward.AppModuleBasic{}, + packetforward.AppModuleBasic{}, ) func appModules( @@ -137,7 +140,7 @@ func appModules( // IBC modules ibchooks.NewAppModule(app.AppKeepers.AccountKeeper), icq.NewAppModule(app.AppKeepers.ICQKeeper), - // packetforward.NewAppModule(app.AppKeepers.PacketForwardKeeper), + packetforward.NewAppModule(app.AppKeepers.PacketForwardKeeper), } } @@ -196,7 +199,7 @@ func orderBeginBlockers() []string { ibctransfertypes.ModuleName, ibcexported.ModuleName, icatypes.ModuleName, - // packetforwardtypes.ModuleName, + packetforwardtypes.ModuleName, ibcfeetypes.ModuleName, icqtypes.ModuleName, tokenfactorytypes.ModuleName, @@ -230,7 +233,7 @@ func orderEndBlockers() []string { ibctransfertypes.ModuleName, ibcexported.ModuleName, icatypes.ModuleName, - // packetforwardtypes.ModuleName, + packetforwardtypes.ModuleName, ibcfeetypes.ModuleName, icqtypes.ModuleName, tokenfactorytypes.ModuleName, @@ -264,7 +267,7 @@ func orderInitBlockers() []string { ibctransfertypes.ModuleName, ibcexported.ModuleName, icatypes.ModuleName, - // packetforwardtypes.ModuleName, + packetforwardtypes.ModuleName, ibcfeetypes.ModuleName, icqtypes.ModuleName, tokenfactorytypes.ModuleName, diff --git a/app/upgrades/v13/upgrades.go b/app/upgrades/v13/upgrades.go index abb900b5e..0e099e756 100644 --- a/app/upgrades/v13/upgrades.go +++ b/app/upgrades/v13/upgrades.go @@ -18,6 +18,7 @@ import ( tokenfactorytypes "github.com/CosmosContracts/juno/v15/x/tokenfactory/types" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" ibcfeetypes "github.com/cosmos/ibc-go/v7/modules/apps/29-fee/types" + packetforwardtypes "github.com/strangelove-ventures/packet-forward-middleware/v7/router/types" ) func CreateV13UpgradeHandler( @@ -75,7 +76,7 @@ func CreateV13UpgradeHandler( logger.Info("set feeshare params") // Packet Forward middleware initial params - // keepers.PacketForwardKeeper.SetParams(ctx, packetforwardtypes.DefaultParams()) + keepers.PacketForwardKeeper.SetParams(ctx, packetforwardtypes.DefaultParams()) return versionMap, err } From f5e035ed228c786091554132775e60bbbd1e9f75 Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Wed, 17 May 2023 09:05:28 -0500 Subject: [PATCH 123/131] Remove DSStore --- osmoutils/.DS_Store | Bin 6148 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 osmoutils/.DS_Store diff --git a/osmoutils/.DS_Store b/osmoutils/.DS_Store deleted file mode 100644 index f9b392d6f5ef6c6e70d98b5504d75bd7a6cd9f4e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHLyH3L}6upL)K3F<3W@2C~Ul6LYu%SxKl(vFO390&EL|IuX{-F~C8|)0Mu=NM% zH?VWAZCX1Ix>bPe$Ue@^v3+vf*hz^>~^= z>#a@{4pLkfa1J;JexC#U>=vm_9UK#~pI1)}BIqA;B=UXPND?i$A6 z%2*-P3R0nKilAYDV@y37(b!%`Dt8zqgJtSDY&{*Eyh}Zq%$2U6nU+5CFfdi2ZbYHf zI6|#Q!=%EUc^=QyI6GTv%F}FQi z;d7K`nA+Yxmf8~in5yzwmLBY)8%%n%^6m!5bVE4@oCANu0bUT)jvdK>`y8e@fsAPLnJsG17>i6K;T#68XPHO2~6a}w&+frK7e=r0r@M@Rpj zq?7O!y3#q|9IzeOR;M-I|Bv&(|LsQZ%sJp3_*V{yLbKIu;Fk2>nz}jOYdz$1WKPVB o70M Date: Thu, 18 May 2023 21:36:14 -0500 Subject: [PATCH 124/131] Move MinCommission ante -> x/staking params --- app/ante.go | 5 -- app/decorators/min_commission.go | 88 -------------------------------- app/sim_test.go | 2 - app/upgrades/v15/upgrades.go | 5 ++ scripts/test_node.sh | 5 +- 5 files changed, 8 insertions(+), 97 deletions(-) delete mode 100644 app/decorators/min_commission.go diff --git a/app/ante.go b/app/ante.go index 8120e3b36..92120089f 100644 --- a/app/ante.go +++ b/app/ante.go @@ -26,10 +26,6 @@ import ( const maxBypassMinFeeMsgGasUsage = 1_000_000 -func updateAppSimulationFlag(flag bool) { - decorators.DefaultIsAppSimulation = flag -} - // HandlerOptions extends the SDK's AnteHandler options by requiring the IBC // channel keeper and a BankKeeper with an added method for fee sharing. type HandlerOptions struct { @@ -71,7 +67,6 @@ func NewAnteHandler(options HandlerOptions) (sdk.AnteHandler, error) { anteDecorators := []sdk.AnteDecorator{ ante.NewSetUpContextDecorator(), // outermost AnteDecorator. SetUpContext must be called first - decorators.NewMinCommissionDecorator(options.Cdc), wasmkeeper.NewLimitSimulationGasDecorator(options.WasmConfig.SimulationGasLimit), wasmkeeper.NewCountTXDecorator(options.TxCounterStoreKey), ante.NewExtensionOptionsDecorator(options.ExtensionOptionChecker), diff --git a/app/decorators/min_commission.go b/app/decorators/min_commission.go deleted file mode 100644 index fd8833b28..000000000 --- a/app/decorators/min_commission.go +++ /dev/null @@ -1,88 +0,0 @@ -package decorators - -import ( - errorsmod "cosmossdk.io/errors" - "github.com/cosmos/cosmos-sdk/codec" - sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - "github.com/cosmos/cosmos-sdk/x/authz" - stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" -) - -var DefaultIsAppSimulation = false - -type MinCommissionDecorator struct { - cdc codec.BinaryCodec -} - -func NewMinCommissionDecorator(cdc codec.BinaryCodec) MinCommissionDecorator { - return MinCommissionDecorator{cdc} -} - -func (min MinCommissionDecorator) AnteHandle( - ctx sdk.Context, tx sdk.Tx, - simulate bool, next sdk.AnteHandler, -) (newCtx sdk.Context, err error) { - if DefaultIsAppSimulation { - return next(ctx, tx, simulate) - } - msgs := tx.GetMsgs() - minCommissionRate := sdk.NewDecWithPrec(5, 2) - - validMsg := func(m sdk.Msg) error { - switch msg := m.(type) { - case *stakingtypes.MsgCreateValidator: - // prevent new validators joining the set with - // commission set below 5% - c := msg.Commission - if c.Rate.LT(minCommissionRate) { - return errorsmod.Wrap(sdkerrors.ErrUnauthorized, "commission can't be lower than 5%") - } - case *stakingtypes.MsgEditValidator: - // if commission rate is nil, it means only - // other fields are affected - skip - if msg.CommissionRate == nil { - break - } - if msg.CommissionRate.LT(minCommissionRate) { - return errorsmod.Wrap(sdkerrors.ErrUnauthorized, "commission can't be lower than 5%") - } - } - - return nil - } - - validAuthz := func(execMsg *authz.MsgExec) error { - for _, v := range execMsg.Msgs { - var innerMsg sdk.Msg - err := min.cdc.UnpackAny(v, &innerMsg) - if err != nil { - return errorsmod.Wrapf(sdkerrors.ErrUnauthorized, "cannot unmarshal authz exec msgs") - } - - err = validMsg(innerMsg) - if err != nil { - return err - } - } - - return nil - } - - for _, m := range msgs { - if msg, ok := m.(*authz.MsgExec); ok { - if err := validAuthz(msg); err != nil { - return ctx, err - } - continue - } - - // validate normal msgs - err = validMsg(m) - if err != nil { - return ctx, err - } - } - - return next(ctx, tx, simulate) -} diff --git a/app/sim_test.go b/app/sim_test.go index afe21ef5c..98a26415a 100644 --- a/app/sim_test.go +++ b/app/sim_test.go @@ -100,8 +100,6 @@ func TestFullAppSimulation(t *testing.T) { db.Close() require.NoError(t, os.RemoveAll(dir)) }() - // encConf := MakeEncodingConfig() - updateAppSimulationFlag(true) var emptyWasmOption []wasm.Option app := New( diff --git a/app/upgrades/v15/upgrades.go b/app/upgrades/v15/upgrades.go index 34b36713b..a659298ae 100644 --- a/app/upgrades/v15/upgrades.go +++ b/app/upgrades/v15/upgrades.go @@ -129,6 +129,11 @@ func CreateV15UpgradeHandler( keepers.TokenFactoryKeeper.SetParams(ctx, updatedTf) logger.Info(fmt.Sprintf("updated tokenfactory params to %v", updatedTf)) + // x/Staking - set minimum commission to 0.050000000000000000 + stakingParams := keepers.StakingKeeper.GetParams(ctx) + stakingParams.MinCommissionRate = sdk.NewDecWithPrec(5, 2) + keepers.StakingKeeper.SetParams(ctx, stakingParams) + return versionMap, err } } diff --git a/scripts/test_node.sh b/scripts/test_node.sh index 4ef546f82..a45081b74 100755 --- a/scripts/test_node.sh +++ b/scripts/test_node.sh @@ -50,7 +50,7 @@ from_scratch () { # juno1hj5fveer5cjtn4wd6wstzugjfdxzl0xps73ftl echo "wealth flavor believe regret funny network recall kiss grape useless pepper cram hint member few certain unveil rather brick bargain curious require crowd raise" | BINARY keys add feeacc --keyring-backend $KEYRING --algo $KEYALGO --recover - BINARY init $MONIKER --chain-id $CHAIN_ID + BINARY init $MONIKER --chain-id $CHAIN_ID --default-denom ujuno # Function updates the config based on a jq argument as a string update_test_genesis () { @@ -64,8 +64,9 @@ from_scratch () { # GlobalFee update_test_genesis '.app_state["globalfee"]["params"]["minimum_gas_prices"]=[{"amount":"0.002500000000000000","denom":"ujuno"}]' - + update_test_genesis '.app_state["staking"]["params"]["bond_denom"]="ujuno"' + update_test_genesis '.app_state["staking"]["params"]["min_commission_rate"]="0.050000000000000000"' # update_test_genesis '.app_state["bank"]["params"]["send_enabled"]=[{"denom": "ujuno","enabled": true}]' # update_test_genesis '.app_state["staking"]["params"]["min_commission_rate"]="0.100000000000000000"' # sdk 46 only From 279a6a4ff63c4e8f9b0ab63de8c7ff51349d243b Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Thu, 18 May 2023 22:19:42 -0500 Subject: [PATCH 125/131] lint --- app/upgrades/v15/upgrades.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/upgrades/v15/upgrades.go b/app/upgrades/v15/upgrades.go index a659298ae..eb37da521 100644 --- a/app/upgrades/v15/upgrades.go +++ b/app/upgrades/v15/upgrades.go @@ -132,7 +132,10 @@ func CreateV15UpgradeHandler( // x/Staking - set minimum commission to 0.050000000000000000 stakingParams := keepers.StakingKeeper.GetParams(ctx) stakingParams.MinCommissionRate = sdk.NewDecWithPrec(5, 2) - keepers.StakingKeeper.SetParams(ctx, stakingParams) + err = keepers.StakingKeeper.SetParams(ctx, stakingParams) + if err != nil { + return nil, err + } return versionMap, err } From 9f5de1b7ab96507e92a597ba62f3d978e73f2312 Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Fri, 19 May 2023 12:15:25 -0500 Subject: [PATCH 126/131] Removes old TODO comments which were completed --- app/upgrades/v15/upgrades.go | 24 ++--------------- interchaintest/chain_upgrade_test.go | 39 ---------------------------- interchaintest/helpers/types.go | 2 -- interchaintest/setup.go | 2 +- x/ibchooks/client/cli/query.go | 1 - 5 files changed, 3 insertions(+), 65 deletions(-) diff --git a/app/upgrades/v15/upgrades.go b/app/upgrades/v15/upgrades.go index eb37da521..93289c089 100644 --- a/app/upgrades/v15/upgrades.go +++ b/app/upgrades/v15/upgrades.go @@ -45,12 +45,10 @@ func CreateV15UpgradeHandler( return func(ctx sdk.Context, _ upgradetypes.Plan, vm module.VersionMap) (module.VersionMap, error) { logger := ctx.Logger().With("upgrade", UpgradeName) - // TODO: Add postHandler (like antehandler but runs after runMsgs) - nativeDenom := upgrades.GetChainsDenomToken(ctx.ChainID()) logger.Info(fmt.Sprintf("With native denom %s", nativeDenom)) - // TODO: Our mint module needs to be migrated to v47 for minttypes.ModuleName + // TODO: Our mint, feeshare, globalfee, and tokenfactory module needs to be migrated to v47 for minttypes.ModuleName // https://github.com/cosmos/cosmos-sdk/pull/12363/files // Set param key table for params module migration for _, subspace := range keepers.ParamsKeeper.GetSubspaces() { @@ -64,7 +62,7 @@ func CreateV15UpgradeHandler( keyTable = banktypes.ParamKeyTable() //nolint:staticcheck case stakingtypes.ModuleName: keyTable = stakingtypes.ParamKeyTable() //nolint:staticcheck - // TODO: mint module v47? + // case minttypes.ModuleName: // keyTable = minttypes.ParamKeyTable() //nolint:staticcheck case distrtypes.ModuleName: @@ -140,21 +138,3 @@ func CreateV15UpgradeHandler( return versionMap, err } } - -// Previously planned Faster block time upgrade -// -// x/Mint -// Double blocks per year (from 6 seconds to 3 = 2x blocks per year) -// mintParams := keepers.MintKeeper.GetParams(ctx) -// mintParams.BlocksPerYear *= 2 -// keepers.MintKeeper.SetParams(ctx, mintParams) -// logger.Info(fmt.Sprintf("updated minted blocks per year logic to %v", mintParams)) -// -// x/Slashing -// Double slashing window due to double blocks per year -// slashingParams := keepers.SlashingKeeper.GetParams(ctx) -// slashingParams.SignedBlocksWindow *= 2 -// err = keepers.SlashingKeeper.SetParams(ctx, slashingParams) -// if err != nil { -// return nil, err -// } diff --git a/interchaintest/chain_upgrade_test.go b/interchaintest/chain_upgrade_test.go index 79401e2c1..38fe6447c 100644 --- a/interchaintest/chain_upgrade_test.go +++ b/interchaintest/chain_upgrade_test.go @@ -169,42 +169,3 @@ func CosmosChainUpgradeTest(t *testing.T, chainName, initialVersion, upgradeBran // TODO: ensure tokenfactory denom creation fee is set to 2_000_000 } - -// TODO: Future v16+ with faster block times, use these -/* - // TODO: Do a param change proposal to match mainnets '5048093' blocks per year rate? - // or just create a function to modify as a fork of cosmos.ModifyGenesisProposalTime. This should really be a builder yea? - - // !IMPORTANT: V15 Faster block times - Query the current minting parameters - // param, _ := chain.QueryParam(ctx, "mint", "BlocksPerYear") - param, _ := chain.QueryParam(ctx, "mint", "BlocksPerYear") - require.NoError(t, err, "error querying blocks per year") - require.Equal(t, param.Value, "\"6311520\"") // mainnet it is 5048093, but we are just ensuring the upgrade applies correctly from default. - - param, err = chain.QueryParam(ctx, "slashing", "SignedBlocksWindow") - require.NoError(t, err, "error querying signed blocks window") - require.Equal(t, param.Value, "\"100\"") - - - upgrade... - - // !IMPORTANT: V15 - Query the current minting parameters - param, err = chain.QueryParam(ctx, "mint", "BlocksPerYear") - require.NoError(t, err, "error querying blocks per year") - require.Equal(t, param.Value, "\"12623040\"") // double the blocks per year from default - - // ensure the new SignedBlocksWindow is double (efault 100) - param, err = chain.QueryParam(ctx, "slashing", "SignedBlocksWindow") - require.NoError(t, err, "error querying signed blocks window") - require.Equal(t, param.Value, "\"200\"") - - // ensure DenomCreationGasConsume for tokenfactory is set to 2000000 with the standard fee being set to empty - param, err = chain.QueryParam(ctx, "tokenfactory", "DenomCreationGasConsume") - require.NoError(t, err, "error querying denom creation gas consume") - require.Equal(t, param.Value, "\"2000000\"") - - param, err = chain.QueryParam(ctx, "tokenfactory", "DenomCreationFee") - require.NoError(t, err, "error querying denom creation fee") - require.Equal(t, param.Value, "[]") - -*/ diff --git a/interchaintest/helpers/types.go b/interchaintest/helpers/types.go index 6c3b6f2e6..5df113c8a 100644 --- a/interchaintest/helpers/types.go +++ b/interchaintest/helpers/types.go @@ -5,8 +5,6 @@ import ( ) // Go based data types for querying on the contract. - -// TODO: Auto generate in the future from Rust types -> Go types? // Execute types are not needed here. We just use strings. Could add though in the future and to_string it // EntryPoint diff --git a/interchaintest/setup.go b/interchaintest/setup.go index 3a7bf4031..573b7dc2b 100644 --- a/interchaintest/setup.go +++ b/interchaintest/setup.go @@ -8,7 +8,7 @@ import ( wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" feesharetypes "github.com/CosmosContracts/juno/v15/x/feeshare/types" - tokenfactorytypes "github.com/CosmosContracts/juno/v15/x/tokenfactory/types" // TODO: fix this so we can store in the DB. + tokenfactorytypes "github.com/CosmosContracts/juno/v15/x/tokenfactory/types" "github.com/docker/docker/client" "github.com/icza/dyno" diff --git a/x/ibchooks/client/cli/query.go b/x/ibchooks/client/cli/query.go index 9bbe53f30..ab6ec960b 100644 --- a/x/ibchooks/client/cli/query.go +++ b/x/ibchooks/client/cli/query.go @@ -59,7 +59,6 @@ $ %s query ibc-hooks wasm-hooks-sender channel-42 juno12smx2wdlyttvyzvzg54y2vnqw RunE: func(cmd *cobra.Command, args []string) error { channelID := args[0] originalSender := args[1] - // ToDo: Make this flexible as an arg prefix := sdk.GetConfig().GetBech32AccountAddrPrefix() senderBech32, err := keeper.DeriveIntermediateSender(channelID, originalSender, prefix) if err != nil { From ae76d8f192e06f9746d1328d14a75a2e05b6e08a Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Fri, 19 May 2023 12:34:00 -0500 Subject: [PATCH 127/131] go.mod version bumps, remove simapp usage --- app/sim_test.go | 3 +-- go.mod | 10 ++++------ go.sum | 16 +++++++--------- 3 files changed, 12 insertions(+), 17 deletions(-) diff --git a/app/sim_test.go b/app/sim_test.go index 98a26415a..2a15648cc 100644 --- a/app/sim_test.go +++ b/app/sim_test.go @@ -12,7 +12,6 @@ import ( "github.com/cometbft/cometbft/libs/log" "github.com/stretchr/testify/require" - "cosmossdk.io/simapp" dbm "github.com/cometbft/cometbft-db" "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/codec" @@ -142,7 +141,7 @@ func TestFullAppSimulation(t *testing.T) { // If a file is not given for the genesis or the sim params, it creates a randomized one. func AppStateFn(codec codec.Codec, manager *module.SimulationManager, genesisState map[string]json.RawMessage) simtypes.AppStateFn { // quick hack to setup app state genesis with our app modules - simapp.ModuleBasics = ModuleBasics + // simapp.ModuleBasics = ModuleBasics if simcli.FlagGenesisTimeValue == 0 { // always set to have a block time simcli.FlagGenesisTimeValue = time.Now().Unix() } diff --git a/go.mod b/go.mod index a31f4a73f..1da754299 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,6 @@ go 1.19 require ( cosmossdk.io/errors v1.0.0-beta.7 cosmossdk.io/math v1.0.0 - cosmossdk.io/simapp v0.0.0-20230224204036-a6adb0821462 github.com/CosmWasm/wasmd v0.40.0-rc.2.0.20230515091654-e36611aa22b6 github.com/cometbft/cometbft v0.37.1 github.com/cometbft/cometbft-db v0.7.0 @@ -15,20 +14,19 @@ require ( github.com/golang/protobuf v1.5.3 github.com/gorilla/mux v1.8.0 github.com/grpc-ecosystem/grpc-gateway v1.16.0 - github.com/prometheus/client_golang v1.15.0 - github.com/spf13/cast v1.5.0 + github.com/prometheus/client_golang v1.15.1 + github.com/spf13/cast v1.5.1 github.com/spf13/cobra v1.7.0 github.com/strangelove-ventures/async-icq/v7 v7.0.0-20230413165143-a3b65ccdc897 github.com/strangelove-ventures/packet-forward-middleware/v7 v7.0.0-20230412224111-136e94e98861 - github.com/stretchr/testify v1.8.2 + github.com/stretchr/testify v1.8.3 google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 google.golang.org/grpc v1.54.0 gopkg.in/yaml.v2 v2.4.0 ) -require cosmossdk.io/log v1.1.0 - require ( + cosmossdk.io/log v1.1.0 cloud.google.com/go v0.110.0 // indirect cloud.google.com/go/compute v1.18.0 // indirect cloud.google.com/go/compute/metadata v0.2.3 // indirect diff --git a/go.sum b/go.sum index 33c1c8825..c0eea4850 100644 --- a/go.sum +++ b/go.sum @@ -204,8 +204,6 @@ cosmossdk.io/log v1.1.0 h1:v0ogPHYeTzPcBTcPR1A3j1hkei4pZama8kz8LKlCMv0= cosmossdk.io/log v1.1.0/go.mod h1:6zjroETlcDs+mm62gd8Ig7mZ+N+fVOZS91V17H+M4N4= cosmossdk.io/math v1.0.0 h1:ro9w7eKx23om2tZz/VM2Pf+z2WAbGX1yDQQOJ6iGeJw= cosmossdk.io/math v1.0.0/go.mod h1:Ygz4wBHrgc7g0N+8+MrnTfS9LLn9aaTGa9hKopuym5k= -cosmossdk.io/simapp v0.0.0-20230224204036-a6adb0821462 h1:g8muUHnXL8vhld2Sjilyhb1UQObc+x9GVuDK43TYZns= -cosmossdk.io/simapp v0.0.0-20230224204036-a6adb0821462/go.mod h1:4Dd3NLoLYoN90kZ0uyHoTHzVVk9+J0v4HhZRBNTAq2c= cosmossdk.io/tools/rosetta v0.2.1 h1:ddOMatOH+pbxWbrGJKRAawdBkPYLfKXutK9IETnjYxw= cosmossdk.io/tools/rosetta v0.2.1/go.mod h1:Pqdc1FdvkNV3LcNIkYWt2RQY6IP1ge6YWZk8MhhO9Hw= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= @@ -492,7 +490,7 @@ github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/ 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/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= 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= @@ -1006,8 +1004,8 @@ github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5Fsn github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.15.0 h1:5fCgGYogn0hFdhyhLbw7hEsWxufKtY9klyvdNfFlFhM= -github.com/prometheus/client_golang v1.15.0/go.mod h1:e9yaBhRPU2pPNsZwE+JdQl0KEt1N9XgF6zxWmaC0xOk= +github.com/prometheus/client_golang v1.15.1 h1:8tXpTmJbyH5lydzFPoxSIJ0J46jdh3tylbvM1xCv0LI= +github.com/prometheus/client_golang v1.15.1/go.mod h1:e9yaBhRPU2pPNsZwE+JdQl0KEt1N9XgF6zxWmaC0xOk= 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= @@ -1085,8 +1083,8 @@ github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B github.com/spf13/afero v1.9.3 h1:41FoI0fD7OR7mGcKE/aOiLkGreyf8ifIOQmJANWogMk= github.com/spf13/afero v1.9.3/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= +github.com/spf13/cast v1.5.1 h1:R+kOtfhWQE6TVQzY+4D7wJLBgkdVasCEFxSUBYBYIlA= +github.com/spf13/cast v1.5.1/go.mod h1:b9PdjNptOpzXr7Rq1q9gJML/2cdGQAo69NKzQ10KN48= 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.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= @@ -1124,8 +1122,8 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= -github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY= +github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= From 7b3f076739e4ee429803d27c046fe3d1ccc83a7c Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Fri, 19 May 2023 12:35:03 -0500 Subject: [PATCH 128/131] Remove legacy forcePrune cmd --- cmd/junod/cmd/debug.go | 1 - cmd/junod/cmd/forceprune.go | 209 ------------------------------------ go.mod | 4 +- 3 files changed, 2 insertions(+), 212 deletions(-) delete mode 100644 cmd/junod/cmd/forceprune.go diff --git a/cmd/junod/cmd/debug.go b/cmd/junod/cmd/debug.go index 92cca531c..a5415f1af 100644 --- a/cmd/junod/cmd/debug.go +++ b/cmd/junod/cmd/debug.go @@ -31,7 +31,6 @@ func DebugCmd() *cobra.Command { ConvertBech32Cmd(), ExportDeriveBalancesCmd(), StakedToCSVCmd(), - forceprune(), ) return cmd diff --git a/cmd/junod/cmd/forceprune.go b/cmd/junod/cmd/forceprune.go deleted file mode 100644 index f80c3f178..000000000 --- a/cmd/junod/cmd/forceprune.go +++ /dev/null @@ -1,209 +0,0 @@ -package cmd - -// DONTCOVER - -// from osmosis -// https://github.com/CosmosContracts/juno/v15/blob/main/cmd/junod/cmd/forceprune.go - -import ( - "fmt" - "os/exec" - "strconv" - - "github.com/spf13/cobra" - - tmdb "github.com/cometbft/cometbft-db" - tmstore "github.com/cometbft/cometbft/store" - "github.com/syndtr/goleveldb/leveldb" - "github.com/syndtr/goleveldb/leveldb/opt" - "github.com/syndtr/goleveldb/leveldb/util" - - "github.com/cometbft/cometbft/config" - "github.com/cosmos/cosmos-sdk/client" -) - -const ( - batchMaxSize = 1000 - validators = "validatorsKey:" - consensusParams = "consensusParamsKey:" - ABCIResponses = "abciResponsesKey:" - fullHeight = "full_height" - minHeight = "min_height" - defaultFullHeight = "188000" - defaultMinHeight = "1000" -) - -func forceprune() *cobra.Command { - cmd := &cobra.Command{ - Use: "forceprune", - Short: "Example junod debug forceprune -f 188000 -m 1000, which would keep blockchain and state data of last 188000 blocks (approximately 2 weeks) and ABCI responses of last 1000 blocks.", - Long: "Forceprune options prunes and compacts blockstore.db and state.db. One needs to shut down chain before running forceprune. By default it keeps last 188000 blocks (approximately 2 weeks of data) blockstore and state db (validator and consensus information) and 1000 blocks of abci responses from state.db. Everything beyond these heights in blockstore and state.db is pruned. ABCI Responses are stored in index db and so redundant especially if one is running pruned nodes. As a result we are removing ABCI data from state.db aggressively by default. One can override height for blockstore.db and state.db by using -f option and for abci response by using -m option. Example junod forceprune -f 188000 -m 1000.", - RunE: func(cmd *cobra.Command, args []string) error { - fullHeightFlag, err := cmd.Flags().GetString(fullHeight) - if err != nil { - return err - } - - minHeightFlag, err := cmd.Flags().GetString(minHeight) - if err != nil { - return err - } - - clientCtx := client.GetClientContextFromCmd(cmd) - conf := config.DefaultConfig() - dbPath := clientCtx.HomeDir + "/" + conf.DBPath - - cmdr := exec.Command("junod", "status") - err = cmdr.Run() - - if err == nil { - // continue only if throws error - return nil - } - - fullHeight, err := strconv.ParseInt(fullHeightFlag, 10, 64) - if err != nil { - return err - } - - minHeight, err := strconv.ParseInt(minHeightFlag, 10, 64) - if err != nil { - return err - } - - startHeight, currentHeight, err := pruneBlockStoreAndGetHeights(dbPath, fullHeight) - if err != nil { - return err - } - - err = compactBlockStore(dbPath) - if err != nil { - return err - } - - err = forcepruneStateStore(dbPath, startHeight, currentHeight, minHeight, fullHeight) - if err != nil { - return err - } - fmt.Println("Done ...") - - return nil - }, - } - - cmd.Flags().StringP(fullHeight, "f", defaultFullHeight, "Full height to chop to") - cmd.Flags().StringP(minHeight, "m", defaultMinHeight, "Min height for ABCI to chop to") - return cmd -} - -// pruneBlockStoreAndGetHeights prunes blockstore and returns the startHeight and currentHeight. -func pruneBlockStoreAndGetHeights(dbPath string, fullHeight int64) ( - startHeight int64, currentHeight int64, err error, -) { - opts := opt.Options{ - DisableSeeksCompaction: true, - } - - dbBs, err := tmdb.NewGoLevelDBWithOpts("blockstore", dbPath, &opts) - if err != nil { - return 0, 0, err - } - - defer dbBs.Close() - - bs := tmstore.NewBlockStore(dbBs) - startHeight = bs.Base() - currentHeight = bs.Height() - - fmt.Println("Pruning Block Store ...") - prunedBlocks, err := bs.PruneBlocks(currentHeight - fullHeight) - if err != nil { - return 0, 0, err - } - fmt.Println("Pruned Block Store ...", prunedBlocks) - - // N.B: We duplicate the call to dbBs.Close() on top of - // the call in defer statement above to make sure that the resources - // are properly released and any potential error from Close() - // is handled. Close() should be idempotent so this is acceptable. - if err := dbBs.Close(); err != nil { - return 0, 0, err - } - - return startHeight, currentHeight, nil -} - -// compactBlockStore compacts block storage. -func compactBlockStore(dbPath string) (err error) { - compactOpts := opt.Options{ - DisableSeeksCompaction: true, - } - - fmt.Println("Compacting Block Store ...") - - db, err := leveldb.OpenFile(dbPath+"/blockstore.db", &compactOpts) - defer func() { - err = db.Close() - }() - if err != nil { - return err - } - err = db.CompactRange(*util.BytesPrefix([]byte{})) - return err -} - -// forcepruneStateStore prunes and compacts state storage. -func forcepruneStateStore(dbPath string, startHeight, currentHeight, minHeight, fullHeight int64) error { - opts := opt.Options{ - DisableSeeksCompaction: true, - } - - db, err := leveldb.OpenFile(dbPath+"/state.db", &opts) - if err != nil { - return err - } - defer db.Close() - - stateDBKeys := []string{validators, consensusParams, ABCIResponses} - fmt.Println("Pruning State Store ...") - for i, s := range stateDBKeys { - fmt.Println(i, s) - - retainHeight := int64(0) - if s == ABCIResponses { - retainHeight = currentHeight - minHeight - } else { - retainHeight = currentHeight - fullHeight - } - - batch := new(leveldb.Batch) - curBatchSize := uint64(0) - - fmt.Println(startHeight, currentHeight, retainHeight) - - for c := startHeight; c < retainHeight; c++ { - batch.Delete([]byte(s + strconv.FormatInt(c, 10))) - curBatchSize++ - - if curBatchSize%batchMaxSize == 0 && curBatchSize > 0 { - err := db.Write(batch, nil) - if err != nil { - return err - } - batch.Reset() - batch = new(leveldb.Batch) - } - } - - err := db.Write(batch, nil) - if err != nil { - return err - } - batch.Reset() - } - - fmt.Println("Compacting State Store ...") - err = db.CompactRange(*util.BytesPrefix([]byte{})) - - return err -} diff --git a/go.mod b/go.mod index 1da754299..c2d4c7e05 100644 --- a/go.mod +++ b/go.mod @@ -26,12 +26,12 @@ require ( ) require ( - cosmossdk.io/log v1.1.0 cloud.google.com/go v0.110.0 // indirect cloud.google.com/go/compute v1.18.0 // indirect cloud.google.com/go/compute/metadata v0.2.3 // indirect cloud.google.com/go/iam v0.12.0 // indirect cloud.google.com/go/storage v1.29.0 // indirect + cosmossdk.io/log v1.1.0 cosmossdk.io/tools/rosetta v0.2.1 github.com/aws/aws-sdk-go v1.44.203 // indirect github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect @@ -157,7 +157,7 @@ require ( github.com/spf13/pflag v1.0.5 // indirect github.com/spf13/viper v1.15.0 github.com/subosito/gotenv v1.4.2 // indirect - github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d + github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect github.com/tendermint/go-amino v0.16.0 // indirect github.com/tidwall/btree v1.6.0 // indirect github.com/zondax/hid v0.9.1 // indirect From 9cea11c42c85bec15a76a4ff25bed2eeed88e8da Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Fri, 19 May 2023 13:08:48 -0500 Subject: [PATCH 129/131] ictest: ModifyGenesis for Upgrade --- interchaintest/chain_upgrade_test.go | 53 +++++++++++---------------- interchaintest/helpers/genesis.go | 50 +++++++++++++++++++++++++ interchaintest/setup.go | 55 ++++++++++++---------------- 3 files changed, 95 insertions(+), 63 deletions(-) create mode 100644 interchaintest/helpers/genesis.go diff --git a/interchaintest/chain_upgrade_test.go b/interchaintest/chain_upgrade_test.go index 38fe6447c..a34ae9a53 100644 --- a/interchaintest/chain_upgrade_test.go +++ b/interchaintest/chain_upgrade_test.go @@ -2,12 +2,10 @@ package interchaintest import ( "context" - "encoding/json" - "fmt" "testing" "time" - "github.com/icza/dyno" + "github.com/CosmosContracts/juno/tests/interchaintest/helpers" "github.com/strangelove-ventures/interchaintest/v7" "github.com/strangelove-ventures/interchaintest/v7/chain/cosmos" "github.com/strangelove-ventures/interchaintest/v7/ibc" @@ -17,7 +15,7 @@ import ( ) const ( - haltHeightDelta = uint64(15) // will propose upgrade this many blocks in the future + haltHeightDelta = uint64(10) // will propose upgrade this many blocks in the future blocksAfterUpgrade = uint64(10) ) @@ -28,31 +26,6 @@ func TestBasicJunoUpgrade(t *testing.T) { CosmosChainUpgradeTest(t, "juno", startVersion, version, repo, upgradeName) } -// With us upgrading from v45 to v47, we need to modify the params in the v45 style here & only here. -// In the future this will be removed to use just `modifyGenesisShortProposals` -func modifySDKv45GenesisShortProposals(votingPeriod string, maxDepositPeriod string) func(ibc.ChainConfig, []byte) ([]byte, error) { - return func(chainConfig ibc.ChainConfig, genbz []byte) ([]byte, error) { - g := make(map[string]interface{}) - if err := json.Unmarshal(genbz, &g); err != nil { - return nil, fmt.Errorf("failed to unmarshal genesis file: %w", err) - } - if err := dyno.Set(g, votingPeriod, "app_state", "gov", "voting_params", "voting_period"); err != nil { - return nil, fmt.Errorf("failed to set voting period in genesis json: %w", err) - } - if err := dyno.Set(g, maxDepositPeriod, "app_state", "gov", "deposit_params", "max_deposit_period"); err != nil { - return nil, fmt.Errorf("failed to set voting period in genesis json: %w", err) - } - if err := dyno.Set(g, chainConfig.Denom, "app_state", "gov", "deposit_params", "min_deposit", 0, "denom"); err != nil { - return nil, fmt.Errorf("failed to set voting period in genesis json: %w", err) - } - out, err := json.Marshal(g) - if err != nil { - return nil, fmt.Errorf("failed to marshal genesis bytes to json: %w", err) - } - return out, nil - } -} - func CosmosChainUpgradeTest(t *testing.T, chainName, initialVersion, upgradeBranchVersion, upgradeRepo, upgradeName string) { if testing.Short() { t.Skip("skipping in short mode") @@ -60,13 +33,31 @@ func CosmosChainUpgradeTest(t *testing.T, chainName, initialVersion, upgradeBran t.Parallel() + t.Log(chainName, initialVersion, upgradeBranchVersion, upgradeRepo, upgradeName) + + // v45 genesis params + genesisKVs := []helpers.GenesisKV{ + { + Key: "app_state.gov.voting_params.voting_period", + Value: VotingPeriod, + }, + { + Key: "app_state.gov.deposit_params.max_deposit_period", + Value: MaxDepositPeriod, + }, + { + Key: "app_state.gov.deposit_params.min_deposit.0.denom", + Value: junoConfig.Denom, + }, + } + cf := interchaintest.NewBuiltinChainFactory(zaptest.NewLogger(t), []*interchaintest.ChainSpec{ { Name: chainName, ChainName: chainName, Version: initialVersion, ChainConfig: ibc.ChainConfig{ - ModifyGenesis: modifySDKv45GenesisShortProposals(VotingPeriod, MaxDepositPeriod), + ModifyGenesis: helpers.ModifyGenesis(genesisKVs), Images: []ibc.DockerImage{ { Repository: JunoE2ERepo, @@ -124,7 +115,7 @@ func CosmosChainUpgradeTest(t *testing.T, chainName, initialVersion, upgradeBran err = chain.VoteOnProposalAllValidators(ctx, upgradeTx.ProposalID, cosmos.ProposalVoteYes) require.NoError(t, err, "failed to submit votes") - _, err = cosmos.PollForProposalStatus(ctx, chain, height, height+haltHeightDelta, upgradeTx.ProposalID, cosmos.ProposalStatusPassed) + _, err = cosmos.PollForProposalStatus(ctx, chain, height, height+(haltHeightDelta*2), upgradeTx.ProposalID, cosmos.ProposalStatusPassed) require.NoError(t, err, "proposal status did not change to passed in expected number of blocks") timeoutCtx, timeoutCtxCancel := context.WithTimeout(ctx, time.Second*45) diff --git a/interchaintest/helpers/genesis.go b/interchaintest/helpers/genesis.go new file mode 100644 index 000000000..f0d381997 --- /dev/null +++ b/interchaintest/helpers/genesis.go @@ -0,0 +1,50 @@ +package helpers + +import ( + "encoding/json" + "fmt" + "strconv" + "strings" + + "github.com/icza/dyno" + "github.com/strangelove-ventures/interchaintest/v7/ibc" +) + +// Move this into ictest under 'cosmos' package. + +type GenesisKV struct { + Key string `json:"key"` + Value interface{} `json:"val"` +} + +func ModifyGenesis(genesisKV []GenesisKV) func(ibc.ChainConfig, []byte) ([]byte, error) { + return func(chainConfig ibc.ChainConfig, genbz []byte) ([]byte, error) { + g := make(map[string]interface{}) + if err := json.Unmarshal(genbz, &g); err != nil { + return nil, fmt.Errorf("failed to unmarshal genesis file: %w", err) + } + + for idx, values := range genesisKV { + path := strings.Split(values.Key, ".") + + result := make([]interface{}, len(path)) + for i, component := range path { + if v, err := strconv.Atoi(component); err == nil { + result[i] = v + } else { + result[i] = component + } + } + + if err := dyno.Set(g, values.Value, result...); err != nil { + return nil, fmt.Errorf("failed to set value (index:%d) in genesis json: %w", idx, err) + } + } + + out, err := json.Marshal(g) + if err != nil { + return nil, fmt.Errorf("failed to marshal genesis bytes to json: %w", err) + } + return out, nil + } +} diff --git a/interchaintest/setup.go b/interchaintest/setup.go index 573b7dc2b..7c22d6b83 100644 --- a/interchaintest/setup.go +++ b/interchaintest/setup.go @@ -2,7 +2,6 @@ package interchaintest import ( "context" - "encoding/json" "fmt" "testing" @@ -11,13 +10,14 @@ import ( tokenfactorytypes "github.com/CosmosContracts/juno/v15/x/tokenfactory/types" "github.com/docker/docker/client" - "github.com/icza/dyno" interchaintest "github.com/strangelove-ventures/interchaintest/v7" "github.com/strangelove-ventures/interchaintest/v7/chain/cosmos" "github.com/strangelove-ventures/interchaintest/v7/ibc" "github.com/strangelove-ventures/interchaintest/v7/testreporter" + "github.com/CosmosContracts/juno/tests/interchaintest/helpers" + "github.com/stretchr/testify/require" "go.uber.org/zap/zaptest" @@ -25,8 +25,9 @@ import ( ) var ( - VotingPeriod = "25s" + VotingPeriod = "15s" MaxDepositPeriod = "10s" + Denom = "ujuno" JunoE2ERepo = "ghcr.io/cosmoscontracts/juno-e2e" JunoMainRepo = "ghcr.io/cosmoscontracts/juno" @@ -39,6 +40,22 @@ var ( UidGid: "1025:1025", } + // SDK v47 Genesis + defaultGenesisKV = []helpers.GenesisKV{ + { + Key: "app_state.gov.params.voting_period", + Value: VotingPeriod, + }, + { + Key: "app_state.gov.params.max_deposit_period", + Value: MaxDepositPeriod, + }, + { + Key: "app_state.gov.params.min_deposit.0.denom", + Value: Denom, + }, + } + junoConfig = ibc.ChainConfig{ Type: "cosmos", Name: "juno", @@ -46,19 +63,18 @@ var ( Images: []ibc.DockerImage{JunoImage}, Bin: "junod", Bech32Prefix: "juno", - Denom: "ujuno", + Denom: Denom, CoinType: "118", - GasPrices: "0ujuno", + GasPrices: fmt.Sprintf("0%s", Denom), GasAdjustment: 2.0, TrustingPeriod: "112h", NoHostMount: false, ConfigFileOverrides: nil, EncodingConfig: junoEncoding(), UsingNewGenesisCommand: true, - ModifyGenesis: modifyGenesisShortProposals(VotingPeriod, MaxDepositPeriod), + ModifyGenesis: helpers.ModifyGenesis(defaultGenesisKV), } - pathJunoGaia = "juno-gaia" genesisWalletAmount = int64(10_000_000) ) @@ -131,28 +147,3 @@ func BuildInitialChain(t *testing.T, chains []ibc.Chain) (*interchaintest.Interc return ic, ctx, client, network } - -// Setup Helpers -func modifyGenesisShortProposals(votingPeriod string, maxDepositPeriod string) func(ibc.ChainConfig, []byte) ([]byte, error) { - return func(chainConfig ibc.ChainConfig, genbz []byte) ([]byte, error) { - g := make(map[string]interface{}) - if err := json.Unmarshal(genbz, &g); err != nil { - return nil, fmt.Errorf("failed to unmarshal genesis file: %w", err) - } - // v47 puts params in a params field now. - if err := dyno.Set(g, votingPeriod, "app_state", "gov", "params", "voting_period"); err != nil { - return nil, fmt.Errorf("failed to set voting period in genesis json: %w", err) - } - if err := dyno.Set(g, maxDepositPeriod, "app_state", "gov", "params", "max_deposit_period"); err != nil { - return nil, fmt.Errorf("failed to set voting period in genesis json: %w", err) - } - if err := dyno.Set(g, chainConfig.Denom, "app_state", "gov", "params", "min_deposit", 0, "denom"); err != nil { - return nil, fmt.Errorf("failed to set voting period in genesis json: %w", err) - } - out, err := json.Marshal(g) - if err != nil { - return nil, fmt.Errorf("failed to marshal genesis bytes to json: %w", err) - } - return out, nil - } -} From 7a1ae6f68eb19e9412c46293f7473a844f4c78cd Mon Sep 17 00:00:00 2001 From: Jacob Gadikian Date: Sat, 20 May 2023 02:13:51 +0700 Subject: [PATCH 130/131] pin protos, correct buf.yaml and remove superfluous dockerfile --- go.mod | 4 ++-- go.sum | 8 ++++---- proto/Dockerfile | 39 --------------------------------------- proto/buf.lock | 13 +++++++++---- proto/buf.yaml | 9 +++++---- 5 files changed, 20 insertions(+), 53 deletions(-) delete mode 100644 proto/Dockerfile diff --git a/go.mod b/go.mod index c2d4c7e05..d3cf6b575 100644 --- a/go.mod +++ b/go.mod @@ -4,8 +4,8 @@ go 1.19 require ( cosmossdk.io/errors v1.0.0-beta.7 - cosmossdk.io/math v1.0.0 - github.com/CosmWasm/wasmd v0.40.0-rc.2.0.20230515091654-e36611aa22b6 + cosmossdk.io/math v1.0.1 + github.com/CosmWasm/wasmd v0.40.0-rc.2.0.20230519100721-8e5b1572ac46 github.com/cometbft/cometbft v0.37.1 github.com/cometbft/cometbft-db v0.7.0 github.com/cosmos/cosmos-sdk v0.47.2 diff --git a/go.sum b/go.sum index c0eea4850..627f2694e 100644 --- a/go.sum +++ b/go.sum @@ -202,8 +202,8 @@ 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/log v1.1.0 h1:v0ogPHYeTzPcBTcPR1A3j1hkei4pZama8kz8LKlCMv0= cosmossdk.io/log v1.1.0/go.mod h1:6zjroETlcDs+mm62gd8Ig7mZ+N+fVOZS91V17H+M4N4= -cosmossdk.io/math v1.0.0 h1:ro9w7eKx23om2tZz/VM2Pf+z2WAbGX1yDQQOJ6iGeJw= -cosmossdk.io/math v1.0.0/go.mod h1:Ygz4wBHrgc7g0N+8+MrnTfS9LLn9aaTGa9hKopuym5k= +cosmossdk.io/math v1.0.1 h1:Qx3ifyOPaMLNH/89WeZFH268yCvU4xEcnPLu3sJqPPg= +cosmossdk.io/math v1.0.1/go.mod h1:Ygz4wBHrgc7g0N+8+MrnTfS9LLn9aaTGa9hKopuym5k= cosmossdk.io/tools/rosetta v0.2.1 h1:ddOMatOH+pbxWbrGJKRAawdBkPYLfKXutK9IETnjYxw= cosmossdk.io/tools/rosetta v0.2.1/go.mod h1:Pqdc1FdvkNV3LcNIkYWt2RQY6IP1ge6YWZk8MhhO9Hw= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= @@ -222,8 +222,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/wasmd v0.40.0-rc.2.0.20230515091654-e36611aa22b6 h1:rnnnJQ14eZrfCCf4rauWasHQulv3dtGkynIisz9HDB8= -github.com/CosmWasm/wasmd v0.40.0-rc.2.0.20230515091654-e36611aa22b6/go.mod h1:frHH5xVukE5xRaJcUNjE+TVPzbuHeV7sPnElR5gcA1w= +github.com/CosmWasm/wasmd v0.40.0-rc.2.0.20230519100721-8e5b1572ac46 h1:2hfUHq11YUv+ep3/YJxEFJMLiABWsEGyg4EnYmlnd1E= +github.com/CosmWasm/wasmd v0.40.0-rc.2.0.20230519100721-8e5b1572ac46/go.mod h1:kGCnjs881+dNjzlw2hn6sLvbi+xFn5pH9FBTRLtfUbg= github.com/CosmWasm/wasmvm v1.2.3 h1:OKYlobwmVGbl0eSn0mXoAAjE5hIuXnQCLPjbNd91sVY= github.com/CosmWasm/wasmvm v1.2.3/go.mod h1:vW/E3h8j9xBQs9bCoijDuawKo9kCtxOaS8N8J7KFtkc= github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= diff --git a/proto/Dockerfile b/proto/Dockerfile deleted file mode 100644 index f5e6f162c..000000000 --- a/proto/Dockerfile +++ /dev/null @@ -1,39 +0,0 @@ -# This Dockerfile is used for proto generation -# To build, run `make proto-image-build` - -FROM bufbuild/buf:1.7.0 as BUILDER - -FROM golang:1.19-alpine - - -RUN apk add --no-cache \ - nodejs \ - npm \ - git \ - make - -ENV GOLANG_PROTOBUF_VERSION=1.28.0 \ - GOGO_PROTOBUF_VERSION=1.3.2 \ - GRPC_GATEWAY_VERSION=1.16.0 - - -RUN go install github.com/cosmos/cosmos-proto/cmd/protoc-gen-go-pulsar@latest -RUN go install google.golang.org/protobuf/cmd/protoc-gen-go@v${GOLANG_PROTOBUF_VERSION} -RUN go install github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway@v${GRPC_GATEWAY_VERSION} \ - github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger@v${GRPC_GATEWAY_VERSION} - -# install all gogo protobuf binaries -RUN git clone https://github.com/regen-network/protobuf.git; \ - cd protobuf; \ - go mod download; \ - make install - -# we need to use git clone because we use 'replace' directive in go.mod -# protoc-gen-gocosmos was moved to to in cosmos/gogoproto but pending a migration there. -RUN git clone https://github.com/regen-network/cosmos-proto.git; \ - cd cosmos-proto/protoc-gen-gocosmos; \ - go install . - -RUN npm install -g swagger-combine - -COPY --from=BUILDER /usr/local/bin /usr/local/bin diff --git a/proto/buf.lock b/proto/buf.lock index 6bfb203f7..7906031c4 100644 --- a/proto/buf.lock +++ b/proto/buf.lock @@ -9,15 +9,20 @@ deps: - remote: buf.build owner: cosmos repository: cosmos-sdk - commit: 51aaa75f36aa4190b2965726557f499e - digest: shake256:fab0021db39a20737093bda0096c3f6b01f1a87f93675532488fce92768992ea39023d57fa6a4b68d25a93b63f48af6404f0de54b35e22ae2b4ea8a9d10b723f + commit: 954f7b05f38440fc8250134b15adec47 + digest: shake256:2ab4404fd04a7d1d52df0e2d0f2d477a3d83ffd88d876957bf3fedfd702c8e52833d65b3ce1d89a3c5adf2aab512616b0e4f51d8463f07eda9a8a3317ee3ac54 - remote: buf.build owner: cosmos repository: gogo-proto commit: 34d970b699f84aa382f3c29773a60836 digest: shake256:3d3bee5229ba579e7d19ffe6e140986a228b48a8c7fe74348f308537ab95e9135210e81812489d42cd8941d33ff71f11583174ccc5972e86e6112924b6ce9f04 + - remote: buf.build + owner: cosmos + repository: ics23 + commit: 55085f7c710a45f58fa09947208eb70b + digest: shake256:9bf0bc495b5a11c88d163d39ef521bc4b00bc1374a05758c91d82821bdc61f09e8c2c51dda8452529bf80137f34d852561eacbe9550a59015d51cecb0dacb628 - remote: buf.build owner: googleapis repository: googleapis - commit: 5ae7f88519b04fe1965da0f8a375a088 - digest: shake256:27d9fcdc0e3eb957449dc3d17e2d24c7ce59c3c483ecf128818183c336dfd28595ecd13771fb3172247775caf7707c4076dd8e70c5ac2cbcac170df35e4d0028 + commit: 8d7204855ec14631a499bd7393ce1970 + digest: shake256:40bf4112960cad01281930beed85829910768e32e80e986791596853eccd42c0cbd9d96690b918f658020d2d427e16f8b6514e2ac7f4a10306fd32e77be44329 diff --git a/proto/buf.yaml b/proto/buf.yaml index 80dd620c1..4a9402a9a 100644 --- a/proto/buf.yaml +++ b/proto/buf.yaml @@ -1,10 +1,11 @@ version: v1 -name: buf.build/osmosis-labs/osmosis +name: buf.build/juno-network/juno deps: - buf.build/cosmos/cosmos-sdk:v0.47.0 - - buf.build/cosmos/cosmos-proto - - buf.build/cosmos/gogo-proto - - buf.build/googleapis/googleapis + - buf.build/cosmos/cosmos-proto:1935555c206d4afb9e94615dfd0fad31 + - buf.build/cosmos/gogo-proto:a14993478f40695898ed8a86931094b6656e8a5d + - buf.build/googleapis/googleapis:8d7204855ec14631a499bd7393ce1970 + - buf.build/cosmos/ics23:b1abd8678aab07165efd453c96796a179eb3131f breaking: use: - FILE From 3f69251c51665c71cd205b3a65f676fd98c2d4e0 Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Fri, 19 May 2023 20:59:54 -0500 Subject: [PATCH 131/131] Use upstream test features --- app/upgrades/v15/upgrades.go | 6 ++++ interchaintest/chain_upgrade_test.go | 12 ++++--- interchaintest/go.mod | 6 ++-- interchaintest/go.sum | 4 +-- interchaintest/helpers/genesis.go | 50 ---------------------------- interchaintest/setup.go | 6 ++-- 6 files changed, 20 insertions(+), 64 deletions(-) delete mode 100644 interchaintest/helpers/genesis.go diff --git a/app/upgrades/v15/upgrades.go b/app/upgrades/v15/upgrades.go index 93289c089..aebbcfa44 100644 --- a/app/upgrades/v15/upgrades.go +++ b/app/upgrades/v15/upgrades.go @@ -135,6 +135,12 @@ func CreateV15UpgradeHandler( return nil, err } + for _, channel := range keepers.IBCKeeper.ChannelKeeper.GetAllChannels(ctx) { + if channel.PortId == "transfer" { + keepers.IBCFeeKeeper.SetFeeEnabled(ctx, channel.PortId, channel.ChannelId) + } + } + return versionMap, err } } diff --git a/interchaintest/chain_upgrade_test.go b/interchaintest/chain_upgrade_test.go index a34ae9a53..1aac54d6f 100644 --- a/interchaintest/chain_upgrade_test.go +++ b/interchaintest/chain_upgrade_test.go @@ -5,7 +5,6 @@ import ( "testing" "time" - "github.com/CosmosContracts/juno/tests/interchaintest/helpers" "github.com/strangelove-ventures/interchaintest/v7" "github.com/strangelove-ventures/interchaintest/v7/chain/cosmos" "github.com/strangelove-ventures/interchaintest/v7/ibc" @@ -36,7 +35,7 @@ func CosmosChainUpgradeTest(t *testing.T, chainName, initialVersion, upgradeBran t.Log(chainName, initialVersion, upgradeBranchVersion, upgradeRepo, upgradeName) // v45 genesis params - genesisKVs := []helpers.GenesisKV{ + genesisKVs := []cosmos.GenesisKV{ { Key: "app_state.gov.voting_params.voting_period", Value: VotingPeriod, @@ -47,7 +46,7 @@ func CosmosChainUpgradeTest(t *testing.T, chainName, initialVersion, upgradeBran }, { Key: "app_state.gov.deposit_params.min_deposit.0.denom", - Value: junoConfig.Denom, + Value: Denom, }, } @@ -57,7 +56,7 @@ func CosmosChainUpgradeTest(t *testing.T, chainName, initialVersion, upgradeBran ChainName: chainName, Version: initialVersion, ChainConfig: ibc.ChainConfig{ - ModifyGenesis: helpers.ModifyGenesis(genesisKVs), + ModifyGenesis: cosmos.ModifyGenesis(genesisKVs), Images: []ibc.DockerImage{ { Repository: JunoE2ERepo, @@ -115,7 +114,7 @@ func CosmosChainUpgradeTest(t *testing.T, chainName, initialVersion, upgradeBran err = chain.VoteOnProposalAllValidators(ctx, upgradeTx.ProposalID, cosmos.ProposalVoteYes) require.NoError(t, err, "failed to submit votes") - _, err = cosmos.PollForProposalStatus(ctx, chain, height, height+(haltHeightDelta*2), upgradeTx.ProposalID, cosmos.ProposalStatusPassed) + _, err = cosmos.PollForProposalStatus(ctx, chain, height, height+haltHeightDelta, upgradeTx.ProposalID, cosmos.ProposalStatusPassed) require.NoError(t, err, "proposal status did not change to passed in expected number of blocks") timeoutCtx, timeoutCtxCancel := context.WithTimeout(ctx, time.Second*45) @@ -134,15 +133,18 @@ func CosmosChainUpgradeTest(t *testing.T, chainName, initialVersion, upgradeBran require.Equal(t, haltHeight, height, "height is not equal to halt height") // bring down nodes to prepare for upgrade + t.Log("stopping node(s)") err = chain.StopAllNodes(ctx) require.NoError(t, err, "error stopping node(s)") // upgrade version on all nodes + t.Log("upgrading node(s)") chain.UpgradeVersion(ctx, client, upgradeRepo, upgradeBranchVersion) // start all nodes back up. // validators reach consensus on first block after upgrade height // and chain block production resumes. + t.Log("starting node(s)") err = chain.StartAllNodes(ctx) require.NoError(t, err, "error starting upgraded node(s)") diff --git a/interchaintest/go.mod b/interchaintest/go.mod index 61441aaca..484312092 100644 --- a/interchaintest/go.mod +++ b/interchaintest/go.mod @@ -14,9 +14,9 @@ replace ( github.com/btcsuite/btcd => github.com/btcsuite/btcd v0.22.2 //indirect github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 - // Fixes gas issue, public SubmitProposal - // go get github.com/Reecepbcups/interchaintest/v7@33d7fafb6f8b0207be920659b37dd5ae9c85c0ff - github.com/strangelove-ventures/interchaintest/v7 => github.com/Reecepbcups/interchaintest/v7 v7.0.0-20230512161406-33d7fafb6f8b + // Fixes gas issue, public SubmitProposal, & modify genesis + // go get github.com/Reecepbcups/interchaintest/v7@a01b723ae4e1cd77a8fe114bbc1d6b2cf0136018 + github.com/strangelove-ventures/interchaintest/v7 => github.com/Reecepbcups/interchaintest/v7 v7.0.0-20230519210824-a01b723ae4e1 github.com/vedhavyas/go-subkey => github.com/strangelove-ventures/go-subkey v1.0.7 ) diff --git a/interchaintest/go.sum b/interchaintest/go.sum index a616ae880..3eaf23b78 100644 --- a/interchaintest/go.sum +++ b/interchaintest/go.sum @@ -235,8 +235,8 @@ github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2B 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= -github.com/Reecepbcups/interchaintest/v7 v7.0.0-20230512161406-33d7fafb6f8b h1:mTHn72tz8bNXcmf/RClTzhIFuyPbDxdVSXpCeCmCy2Y= -github.com/Reecepbcups/interchaintest/v7 v7.0.0-20230512161406-33d7fafb6f8b/go.mod h1:/FpoaMKTF3OREchZZvg6eGfVYvk7lAwqP9q2TN+lOGs= +github.com/Reecepbcups/interchaintest/v7 v7.0.0-20230519210824-a01b723ae4e1 h1:T2sJ2qnsiCNl3B+tgLSVt3ktieDgAWjsbiMTPC+7ZC0= +github.com/Reecepbcups/interchaintest/v7 v7.0.0-20230519210824-a01b723ae4e1/go.mod h1:/FpoaMKTF3OREchZZvg6eGfVYvk7lAwqP9q2TN+lOGs= 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 h1:fLjPD/aNc3UIOA6tDi6QXUemppXK3P9BI7mr2hd6gx8= diff --git a/interchaintest/helpers/genesis.go b/interchaintest/helpers/genesis.go deleted file mode 100644 index f0d381997..000000000 --- a/interchaintest/helpers/genesis.go +++ /dev/null @@ -1,50 +0,0 @@ -package helpers - -import ( - "encoding/json" - "fmt" - "strconv" - "strings" - - "github.com/icza/dyno" - "github.com/strangelove-ventures/interchaintest/v7/ibc" -) - -// Move this into ictest under 'cosmos' package. - -type GenesisKV struct { - Key string `json:"key"` - Value interface{} `json:"val"` -} - -func ModifyGenesis(genesisKV []GenesisKV) func(ibc.ChainConfig, []byte) ([]byte, error) { - return func(chainConfig ibc.ChainConfig, genbz []byte) ([]byte, error) { - g := make(map[string]interface{}) - if err := json.Unmarshal(genbz, &g); err != nil { - return nil, fmt.Errorf("failed to unmarshal genesis file: %w", err) - } - - for idx, values := range genesisKV { - path := strings.Split(values.Key, ".") - - result := make([]interface{}, len(path)) - for i, component := range path { - if v, err := strconv.Atoi(component); err == nil { - result[i] = v - } else { - result[i] = component - } - } - - if err := dyno.Set(g, values.Value, result...); err != nil { - return nil, fmt.Errorf("failed to set value (index:%d) in genesis json: %w", idx, err) - } - } - - out, err := json.Marshal(g) - if err != nil { - return nil, fmt.Errorf("failed to marshal genesis bytes to json: %w", err) - } - return out, nil - } -} diff --git a/interchaintest/setup.go b/interchaintest/setup.go index 7c22d6b83..773a81e44 100644 --- a/interchaintest/setup.go +++ b/interchaintest/setup.go @@ -16,8 +16,6 @@ import ( "github.com/strangelove-ventures/interchaintest/v7/ibc" "github.com/strangelove-ventures/interchaintest/v7/testreporter" - "github.com/CosmosContracts/juno/tests/interchaintest/helpers" - "github.com/stretchr/testify/require" "go.uber.org/zap/zaptest" @@ -41,7 +39,7 @@ var ( } // SDK v47 Genesis - defaultGenesisKV = []helpers.GenesisKV{ + defaultGenesisKV = []cosmos.GenesisKV{ { Key: "app_state.gov.params.voting_period", Value: VotingPeriod, @@ -72,7 +70,7 @@ var ( ConfigFileOverrides: nil, EncodingConfig: junoEncoding(), UsingNewGenesisCommand: true, - ModifyGenesis: helpers.ModifyGenesis(defaultGenesisKV), + ModifyGenesis: cosmos.ModifyGenesis(defaultGenesisKV), } genesisWalletAmount = int64(10_000_000)