From 676b6e7ccc097d0505fd110cee66ca4c7d85ba5d Mon Sep 17 00:00:00 2001 From: Marc Puig Date: Thu, 6 Jul 2023 15:24:50 +0200 Subject: [PATCH 001/100] audit rev1 (#556) --- x/liquidstakeibc/keeper/msg_server.go | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/x/liquidstakeibc/keeper/msg_server.go b/x/liquidstakeibc/keeper/msg_server.go index 2b6aab7b7..920812a14 100644 --- a/x/liquidstakeibc/keeper/msg_server.go +++ b/x/liquidstakeibc/keeper/msg_server.go @@ -475,8 +475,7 @@ func (k msgServer) LiquidUnstake( // calculate the host chain token unbond amount from the stk amount decTokenAmount := sdktypes.NewDecCoinFromCoin(unstakeAmount).Amount.Mul(sdktypes.OneDec().Quo(hc.CValue)) - tokenAmount, _ := sdktypes.NewDecCoinFromDec(hc.HostDenom, decTokenAmount).TruncateDecimal() - unbondAmount := sdktypes.NewCoin(hc.HostDenom, tokenAmount.Amount) + unbondAmount, _ := sdktypes.NewDecCoinFromDec(hc.HostDenom, decTokenAmount).TruncateDecimal() // calculate the current unbonding epoch epoch := k.epochsKeeper.GetEpochInfo(ctx, types.UndelegationEpoch) @@ -487,14 +486,14 @@ func (k msgServer) LiquidUnstake( k.IncreaseUndelegatingAmountForEpoch(ctx, hc.ChainId, unbondingEpoch, unstakeAmount, unbondAmount) // check if the total unbonding amount for the next unbonding epoch is less than what is currently staked - totalUnbondings, _ := k.GetUnbonding(ctx, hc.ChainId, unbondingEpoch) + totalUnbondingsForEpoch, _ := k.GetUnbonding(ctx, hc.ChainId, unbondingEpoch) totalDelegations := hc.GetHostChainTotalDelegations() - if totalDelegations.LT(unbondAmount.Amount) { + if totalDelegations.LTE(totalUnbondingsForEpoch.UnbondAmount.Amount) { return nil, errorsmod.Wrapf( types.ErrNotEnoughDelegations, "delegated amount %s is less than the total undelegation %s for epoch %d", totalDelegations, - totalUnbondings, + totalUnbondingsForEpoch, unbondingEpoch, ) } @@ -605,7 +604,7 @@ func (k msgServer) Redeem( // amount of tokens to be redeemed stkAmount := msg.Amount.Sub(fee) - redeemAmount := sdktypes.NewDecCoinFromCoin(stkAmount).Amount.Mul(hc.CValue) + redeemAmount := sdktypes.NewDecCoinFromCoin(stkAmount).Amount.Quo(hc.CValue) redeemToken, _ := sdktypes.NewDecCoinFromDec(hc.IBCDenom(), redeemAmount).TruncateDecimal() // check if there is enough deposits to fulfill the instant redemption request From 7813331f51013edc96a2d12fa594d203e0b245f1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 7 Jul 2023 11:08:08 +0530 Subject: [PATCH 002/100] Bump google.golang.org/protobuf from 1.30.0 to 1.31.0 (#544) Bumps google.golang.org/protobuf from 1.30.0 to 1.31.0. --- updated-dependencies: - dependency-name: google.golang.org/protobuf dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index c2acf8b08..2926cb15a 100644 --- a/go.mod +++ b/go.mod @@ -28,7 +28,7 @@ require ( github.com/stretchr/testify v1.8.4 google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 google.golang.org/grpc v1.56.1 - google.golang.org/protobuf v1.30.0 + google.golang.org/protobuf v1.31.0 gopkg.in/yaml.v2 v2.4.0 sigs.k8s.io/yaml v1.3.0 ) diff --git a/go.sum b/go.sum index 5fe9693e3..ad995a067 100644 --- a/go.sum +++ b/go.sum @@ -2215,8 +2215,8 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ 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= +google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.31.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= From 55277d83d07368340e300f66cc0885a2ffbfb238 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 7 Jul 2023 11:19:27 +0530 Subject: [PATCH 003/100] Bump bufbuild/buf-setup-action from 1.21.0 to 1.23.1 (#553) Bumps [bufbuild/buf-setup-action](https://github.com/bufbuild/buf-setup-action) from 1.21.0 to 1.23.1. - [Release notes](https://github.com/bufbuild/buf-setup-action/releases) - [Commits](https://github.com/bufbuild/buf-setup-action/compare/v1.21.0...v1.23.1) --- updated-dependencies: - dependency-name: bufbuild/buf-setup-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/proto-registry.yml | 2 +- .github/workflows/proto.yml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/proto-registry.yml b/.github/workflows/proto-registry.yml index 42dd9c506..0eab714b4 100644 --- a/.github/workflows/proto-registry.yml +++ b/.github/workflows/proto-registry.yml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - uses: bufbuild/buf-setup-action@v1.21.0 + - uses: bufbuild/buf-setup-action@v1.23.1 - uses: bufbuild/buf-push-action@v1 with: input: "proto" diff --git a/.github/workflows/proto.yml b/.github/workflows/proto.yml index fcba5e467..08cbc66cf 100644 --- a/.github/workflows/proto.yml +++ b/.github/workflows/proto.yml @@ -15,7 +15,7 @@ jobs: timeout-minutes: 5 steps: - uses: actions/checkout@v3 - - uses: bufbuild/buf-setup-action@v1.21.0 + - uses: bufbuild/buf-setup-action@v1.23.1 - uses: bufbuild/buf-lint-action@v1 with: input: "proto" @@ -24,7 +24,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - uses: bufbuild/buf-setup-action@v1.21.0 + - uses: bufbuild/buf-setup-action@v1.23.1 - uses: bufbuild/buf-breaking-action@v1 with: input: "proto" From 29ef8d2f1f813acb9dc384fb4317dfbde9c042fa Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 7 Jul 2023 11:29:46 +0530 Subject: [PATCH 004/100] Bump google.golang.org/grpc from 1.56.1 to 1.56.2 (#557) Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.56.1 to 1.56.2. - [Release notes](https://github.com/grpc/grpc-go/releases) - [Commits](https://github.com/grpc/grpc-go/compare/v1.56.1...v1.56.2) --- updated-dependencies: - dependency-name: google.golang.org/grpc dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 2926cb15a..e3dd108e8 100644 --- a/go.mod +++ b/go.mod @@ -27,7 +27,7 @@ require ( github.com/spf13/viper v1.16.0 github.com/stretchr/testify v1.8.4 google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 - google.golang.org/grpc v1.56.1 + google.golang.org/grpc v1.56.2 google.golang.org/protobuf v1.31.0 gopkg.in/yaml.v2 v2.4.0 sigs.k8s.io/yaml v1.3.0 diff --git a/go.sum b/go.sum index ad995a067..0f5a12313 100644 --- a/go.sum +++ b/go.sum @@ -2197,8 +2197,8 @@ google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACu 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.56.1 h1:z0dNfjIl0VpaZ9iSVjA6daGatAYwPGstTjt5vkRMFkQ= -google.golang.org/grpc v1.56.1/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s= +google.golang.org/grpc v1.56.2 h1:fVRFRnXvU+x6C4IlHZewvJOVHoOv1TUuQyoRsYnB4bI= +google.golang.org/grpc v1.56.2/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s= 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= From d2a6cc5e6307753a7bbb0be73ec0e0b12a339df9 Mon Sep 17 00:00:00 2001 From: Puneet <59960662+puneet2019@users.noreply.github.com> Date: Mon, 10 Jul 2023 13:33:02 +0530 Subject: [PATCH 005/100] allow localhost client type. (#560) * allow localhost client type. * remove unused function. --- x/liquidstakeibc/keeper/keeper.go | 40 +++++++++------------------- x/lscosmos/types/expected_keepers.go | 2 -- 2 files changed, 12 insertions(+), 30 deletions(-) diff --git a/x/liquidstakeibc/keeper/keeper.go b/x/liquidstakeibc/keeper/keeper.go index 736a6ef68..e4d28e646 100644 --- a/x/liquidstakeibc/keeper/keeper.go +++ b/x/liquidstakeibc/keeper/keeper.go @@ -15,8 +15,10 @@ import ( icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" ibctransfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + "github.com/cosmos/ibc-go/v7/modules/core/exported" ibckeeper "github.com/cosmos/ibc-go/v7/modules/core/keeper" ibctmtypes "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" + ibclocalhosttypes "github.com/cosmos/ibc-go/v7/modules/light-clients/09-localhost" "github.com/persistenceOne/pstake-native/v2/x/liquidstakeibc/types" ) @@ -119,7 +121,7 @@ func (k *Keeper) SendProtocolFee(ctx sdk.Context, protocolFee sdk.Coins, moduleA } // GetClientState retrieves the client state given a connection id -func (k *Keeper) GetClientState(ctx sdk.Context, connectionID string) (*ibctmtypes.ClientState, error) { +func (k *Keeper) GetClientState(ctx sdk.Context, connectionID string) (exported.ClientState, error) { conn, found := k.ibcKeeper.ConnectionKeeper.GetConnection(ctx, connectionID) if !found { return nil, fmt.Errorf("invalid connection id, \"%s\" not found", connectionID) @@ -130,32 +132,7 @@ func (k *Keeper) GetClientState(ctx sdk.Context, connectionID string) (*ibctmtyp return nil, fmt.Errorf("client id \"%s\" not found for connection \"%s\"", conn.ClientId, connectionID) } - client, ok := clientState.(*ibctmtypes.ClientState) - if !ok { - return nil, fmt.Errorf("invalid client state for connection \"%s\"", connectionID) - } - - return client, nil -} - -// GetLatestConsensusState retrieves the last tendermint consensus state -func (k *Keeper) GetLatestConsensusState(ctx sdk.Context, connectionID string) (*ibctmtypes.ConsensusState, error) { - conn, found := k.ibcKeeper.ConnectionKeeper.GetConnection(ctx, connectionID) - if !found { - return nil, fmt.Errorf("invalid connection id, \"%s\" not found", connectionID) - } - - consensusState, found := k.ibcKeeper.ClientKeeper.GetLatestClientConsensusState(ctx, conn.ClientId) - if !found { - return nil, fmt.Errorf("client id \"%s\" not found for connection \"%s\"", conn.ClientId, connectionID) - } - - state, ok := consensusState.(*ibctmtypes.ConsensusState) - if !ok { - return nil, fmt.Errorf("invalid consensus state for connection \"%s\"", connectionID) - } - - return state, nil + return clientState, nil } // GetChainID gets the id of the host chain given a connection id @@ -165,7 +142,14 @@ func (k *Keeper) GetChainID(ctx sdk.Context, connectionID string) (string, error return "", fmt.Errorf("client state not found for connection \"%s\": \"%s\"", connectionID, err.Error()) } - return clientState.ChainId, nil + switch clientType := clientState.(type) { + case *ibctmtypes.ClientState: + return clientType.ChainId, nil + case *ibclocalhosttypes.ClientState: + return ctx.ChainID(), nil + default: + return "", fmt.Errorf("unexpected type of client, cannot determine chain-id: clientType: %s, connectionid: %s", clientState.ClientType(), connectionID) + } } // GetPortID constructs a port id given the port owner diff --git a/x/lscosmos/types/expected_keepers.go b/x/lscosmos/types/expected_keepers.go index d8b1b113a..173b32f40 100644 --- a/x/lscosmos/types/expected_keepers.go +++ b/x/lscosmos/types/expected_keepers.go @@ -8,7 +8,6 @@ import ( "github.com/cosmos/gogoproto/proto" channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" "github.com/cosmos/ibc-go/v7/modules/core/exported" - ibctmtypes "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" epochstypes "github.com/persistenceOne/persistence-sdk/v2/x/epochs/types" liquidstakeibctypes "github.com/persistenceOne/pstake-native/v2/x/liquidstakeibc/types" @@ -104,7 +103,6 @@ type LiquidStakeIBCKeeper interface { SetValidatorUnbonding(ctx sdk.Context, vu *liquidstakeibctypes.ValidatorUnbonding) SetUserUnbonding(ctx sdk.Context, ub *liquidstakeibctypes.UserUnbonding) SetDeposit(ctx sdk.Context, deposit *liquidstakeibctypes.Deposit) - GetLatestConsensusState(ctx sdk.Context, connectionID string) (*ibctmtypes.ConsensusState, error) GetHostChain(ctx sdk.Context, chainID string) (*liquidstakeibctypes.HostChain, bool) GenerateAndExecuteICATx(ctx sdk.Context, connectionID string, ownerID string, messages []proto.Message) (string, error) SetParams(ctx sdk.Context, params liquidstakeibctypes.Params) From 8124cff9fd8e9af54eea3e9fd79a8b00349f4c0a Mon Sep 17 00:00:00 2001 From: Puneet <59960662+puneet2019@users.noreply.github.com> Date: Mon, 10 Jul 2023 13:41:20 +0530 Subject: [PATCH 006/100] change epoch used as sdk.Int to int64 in deposits. (#559) * change epoch used as sdk.Int to int64 in deposits. * phix tests. * change and move key funciton to keys.go --- .../v1beta1/liquidstakeibc.proto | 6 +- x/liquidstakeibc/keeper/deposit.go | 12 +- x/liquidstakeibc/keeper/deposit_test.go | 122 +++++----- x/liquidstakeibc/keeper/grpc_querier_test.go | 3 +- x/liquidstakeibc/keeper/hooks.go | 2 +- x/liquidstakeibc/types/keys.go | 4 + x/liquidstakeibc/types/liquidstakeibc.pb.go | 224 +++++++++--------- x/lscosmos/keeper/migrate_module.go | 2 +- 8 files changed, 181 insertions(+), 194 deletions(-) diff --git a/proto/pstake/liquidstakeibc/v1beta1/liquidstakeibc.proto b/proto/pstake/liquidstakeibc/v1beta1/liquidstakeibc.proto index 982367bda..8a4ad6843 100644 --- a/proto/pstake/liquidstakeibc/v1beta1/liquidstakeibc.proto +++ b/proto/pstake/liquidstakeibc/v1beta1/liquidstakeibc.proto @@ -147,11 +147,7 @@ message Deposit { (gogoproto.nullable) = false ]; // epoch number of the deposit - string epoch = 3 [ - (cosmos_proto.scalar) = "cosmos.Int", - (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", - (gogoproto.nullable) = false - ]; + int64 epoch = 3; // state DepositState state = 4; // sequence id of the ibc transaction diff --git a/x/liquidstakeibc/keeper/deposit.go b/x/liquidstakeibc/keeper/deposit.go index 7d579ddb4..50d2d8ace 100644 --- a/x/liquidstakeibc/keeper/deposit.go +++ b/x/liquidstakeibc/keeper/deposit.go @@ -12,12 +12,12 @@ import ( func (k *Keeper) SetDeposit(ctx sdk.Context, deposit *liquidstakeibctypes.Deposit) { store := prefix.NewStore(ctx.KVStore(k.storeKey), liquidstakeibctypes.DepositKey) bytes := k.cdc.MustMarshal(deposit) - store.Set([]byte(deposit.ChainId+deposit.Epoch.String()), bytes) + store.Set(liquidstakeibctypes.GetDepositStoreKey(deposit.ChainId, deposit.Epoch), bytes) } func (k *Keeper) DeleteDeposit(ctx sdk.Context, deposit *liquidstakeibctypes.Deposit) { store := prefix.NewStore(ctx.KVStore(k.storeKey), liquidstakeibctypes.DepositKey) - store.Delete([]byte(deposit.ChainId + deposit.Epoch.String())) + store.Delete(liquidstakeibctypes.GetDepositStoreKey(deposit.ChainId, deposit.Epoch)) } func (k *Keeper) CreateDeposits(ctx sdk.Context, epoch int64) { @@ -28,12 +28,12 @@ func (k *Keeper) CreateDeposits(ctx sdk.Context, epoch int64) { deposit := &liquidstakeibctypes.Deposit{ ChainId: hc.ChainId, Amount: sdk.NewCoin(hc.IBCDenom(), sdk.NewInt(0)), - Epoch: sdk.NewInt(epoch), + Epoch: epoch, State: liquidstakeibctypes.Deposit_DEPOSIT_PENDING, IbcSequenceId: "", } bytes := k.cdc.MustMarshal(deposit) - store.Set([]byte(deposit.ChainId+deposit.Epoch.String()), bytes) + store.Set(liquidstakeibctypes.GetDepositStoreKey(deposit.ChainId, deposit.Epoch), bytes) } } @@ -108,7 +108,7 @@ func (k *Keeper) GetDepositForChainAndEpoch( deposit := &liquidstakeibctypes.Deposit{} k.cdc.MustUnmarshal(iterator.Value(), deposit) - if deposit.Epoch.Int64() == epoch && + if deposit.Epoch == epoch && deposit.ChainId == chainID { return deposit, true } @@ -163,7 +163,7 @@ func (k *Keeper) GetPendingDepositsBeforeEpoch(ctx sdk.Context, epoch int64) []* deposit := &liquidstakeibctypes.Deposit{} k.cdc.MustUnmarshal(iterator.Value(), deposit) - if deposit.Epoch.Int64() <= epoch && + if deposit.Epoch <= epoch && deposit.State == liquidstakeibctypes.Deposit_DEPOSIT_PENDING { deposits = append(deposits, deposit) } diff --git a/x/liquidstakeibc/keeper/deposit_test.go b/x/liquidstakeibc/keeper/deposit_test.go index 26129d04d..2e7b33270 100644 --- a/x/liquidstakeibc/keeper/deposit_test.go +++ b/x/liquidstakeibc/keeper/deposit_test.go @@ -32,7 +32,7 @@ func (suite *IntegrationTestSuite) TestCreateDeposits() { deposits := suite.app.LiquidStakeIBCKeeper.GetAllDeposits(suite.ctx) suite.Require().Equal(1, len(deposits)) - suite.Require().Equal(epoch, deposits[0].Epoch.Int64()) + suite.Require().Equal(epoch, deposits[0].Epoch) } func (suite *IntegrationTestSuite) TestRevertDepositState() { @@ -93,7 +93,7 @@ func (suite *IntegrationTestSuite) TestAdjustDepositsForRedemption() { deposits: []*types.Deposit{ { ChainId: suite.path.EndpointB.Chain.ChainID, - Epoch: sdk.NewInt(epoch), + Epoch: epoch, Amount: sdk.Coin{Denom: HostDenom, Amount: sdk.NewInt(10000)}, State: types.Deposit_DEPOSIT_PENDING, }, @@ -108,7 +108,7 @@ func (suite *IntegrationTestSuite) TestAdjustDepositsForRedemption() { deposits: []*types.Deposit{ { ChainId: suite.path.EndpointB.Chain.ChainID, - Epoch: sdk.NewInt(epoch), + Epoch: epoch, Amount: sdk.Coin{Denom: HostDenom, Amount: sdk.NewInt(3500)}, State: types.Deposit_DEPOSIT_PENDING, }, @@ -123,7 +123,7 @@ func (suite *IntegrationTestSuite) TestAdjustDepositsForRedemption() { deposits: []*types.Deposit{ { ChainId: suite.path.EndpointB.Chain.ChainID, - Epoch: sdk.NewInt(epoch), + Epoch: epoch, Amount: sdk.Coin{Denom: HostDenom, Amount: sdk.NewInt(5000)}, State: types.Deposit_DEPOSIT_PENDING, }, @@ -136,13 +136,13 @@ func (suite *IntegrationTestSuite) TestAdjustDepositsForRedemption() { deposits: []*types.Deposit{ { ChainId: suite.path.EndpointB.Chain.ChainID, - Epoch: sdk.NewInt(epoch), + Epoch: epoch, Amount: sdk.Coin{Denom: HostDenom, Amount: sdk.NewInt(10000)}, State: types.Deposit_DEPOSIT_PENDING, }, { ChainId: suite.path.EndpointB.Chain.ChainID, - Epoch: sdk.NewInt(epoch + 1), + Epoch: epoch + 1, Amount: sdk.Coin{Denom: HostDenom, Amount: sdk.NewInt(5000)}, State: types.Deposit_DEPOSIT_PENDING, }, @@ -158,13 +158,13 @@ func (suite *IntegrationTestSuite) TestAdjustDepositsForRedemption() { deposits: []*types.Deposit{ { ChainId: suite.path.EndpointB.Chain.ChainID, - Epoch: sdk.NewInt(epoch), + Epoch: epoch, Amount: sdk.Coin{Denom: HostDenom, Amount: sdk.NewInt(5000)}, State: types.Deposit_DEPOSIT_PENDING, }, { ChainId: suite.path.EndpointB.Chain.ChainID, - Epoch: sdk.NewInt(epoch + 1), + Epoch: epoch + 1, Amount: sdk.Coin{Denom: HostDenom, Amount: sdk.NewInt(10000)}, State: types.Deposit_DEPOSIT_PENDING, }, @@ -179,13 +179,13 @@ func (suite *IntegrationTestSuite) TestAdjustDepositsForRedemption() { deposits: []*types.Deposit{ { ChainId: suite.path.EndpointB.Chain.ChainID, - Epoch: sdk.NewInt(epoch), + Epoch: epoch, Amount: sdk.Coin{Denom: HostDenom, Amount: sdk.NewInt(10000)}, State: types.Deposit_DEPOSIT_PENDING, }, { ChainId: suite.path.EndpointB.Chain.ChainID, - Epoch: sdk.NewInt(epoch + 1), + Epoch: epoch + 1, Amount: sdk.Coin{Denom: HostDenom, Amount: sdk.NewInt(5000)}, State: types.Deposit_DEPOSIT_PENDING, }, @@ -212,7 +212,7 @@ func (suite *IntegrationTestSuite) TestAdjustDepositsForRedemption() { deposits := suite.app.LiquidStakeIBCKeeper.GetAllDeposits(suite.ctx) for _, deposit := range deposits { - suite.Require().Equal(t.expected[deposit.Epoch.Int64()], deposit.Amount) + suite.Require().Equal(t.expected[deposit.Epoch], deposit.Amount) } suite.Require().Equal(len(t.expected), len(deposits)) @@ -234,23 +234,23 @@ func (suite *IntegrationTestSuite) TestGetDepositForChainAndEpoch() { { name: "Success", deposits: []types.Deposit{ - {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: sdk.NewInt(epoch)}, - {ChainId: suite.path.EndpointA.Chain.ChainID, Epoch: sdk.NewInt(epoch + 1)}, - {ChainId: suite.path.EndpointA.Chain.ChainID, Epoch: sdk.NewInt(epoch)}, - {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: sdk.NewInt(epoch + 1)}, + {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: epoch}, + {ChainId: suite.path.EndpointA.Chain.ChainID, Epoch: epoch + 1}, + {ChainId: suite.path.EndpointA.Chain.ChainID, Epoch: epoch}, + {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: epoch + 1}, }, chainID: suite.path.EndpointB.Chain.ChainID, epoch: epoch, - expected: types.Deposit{ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: sdk.NewInt(epoch)}, + expected: types.Deposit{ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: epoch}, found: true, }, { name: "unsuccessful test", deposits: []types.Deposit{ - {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: sdk.NewInt(epoch)}, - {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: sdk.NewInt(epoch + 1)}, - {ChainId: suite.path.EndpointA.Chain.ChainID, Epoch: sdk.NewInt(epoch)}, - {ChainId: suite.path.EndpointA.Chain.ChainID, Epoch: sdk.NewInt(epoch + 1)}, + {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: epoch}, + {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: epoch + 1}, + {ChainId: suite.path.EndpointA.Chain.ChainID, Epoch: epoch}, + {ChainId: suite.path.EndpointA.Chain.ChainID, Epoch: epoch + 1}, }, chainID: suite.path.EndpointA.Chain.ChainID, epoch: epoch + 2, @@ -269,7 +269,7 @@ func (suite *IntegrationTestSuite) TestGetDepositForChainAndEpoch() { if found { suite.Require().Equal(t.chainID, hc.ChainId) - suite.Require().Equal(sdk.NewInt(t.epoch), hc.Epoch) + suite.Require().Equal(t.epoch, hc.Epoch) } suite.Require().Equal(t.found, found) @@ -289,16 +289,16 @@ func (suite *IntegrationTestSuite) TestGetDepositsWithSequenceID() { { name: "Success", deposits: []types.Deposit{ - {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: sdk.NewInt(epoch), IbcSequenceId: "seq-1"}, - {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: sdk.NewInt(epoch + 1), IbcSequenceId: "seq-2"}, - {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: sdk.NewInt(epoch + 2), IbcSequenceId: "seq-3"}, - {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: sdk.NewInt(epoch + 3), IbcSequenceId: "seq-4"}, + {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: epoch, IbcSequenceId: "seq-1"}, + {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: epoch + 1, IbcSequenceId: "seq-2"}, + {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: epoch + 2, IbcSequenceId: "seq-3"}, + {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: epoch + 3, IbcSequenceId: "seq-4"}, }, sequenceID: "seq-1", expected: []types.Deposit{ { ChainId: suite.path.EndpointB.Chain.ChainID, - Epoch: sdk.NewInt(1), + Epoch: 1, IbcSequenceId: "seq-1", }, }, @@ -306,10 +306,10 @@ func (suite *IntegrationTestSuite) TestGetDepositsWithSequenceID() { { name: "NotFound", deposits: []types.Deposit{ - {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: sdk.NewInt(epoch), IbcSequenceId: "seq-1"}, - {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: sdk.NewInt(epoch + 1), IbcSequenceId: "seq-2"}, - {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: sdk.NewInt(epoch + 2), IbcSequenceId: "seq-3"}, - {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: sdk.NewInt(epoch + 3), IbcSequenceId: "seq-4"}, + {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: epoch, IbcSequenceId: "seq-1"}, + {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: epoch + 1, IbcSequenceId: "seq-2"}, + {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: epoch + 2, IbcSequenceId: "seq-3"}, + {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: epoch + 3, IbcSequenceId: "seq-4"}, }, sequenceID: "seq-8", expected: []types.Deposit{}, @@ -344,24 +344,24 @@ func (suite *IntegrationTestSuite) TestGetPendingDepositsBeforeEpoch() { { name: "Success", deposits: []types.Deposit{ - {Epoch: sdk.NewInt(epoch), State: types.Deposit_DEPOSIT_PENDING}, - {Epoch: sdk.NewInt(epoch + 1), State: types.Deposit_DEPOSIT_PENDING}, - {Epoch: sdk.NewInt(epoch + 2), State: types.Deposit_DEPOSIT_RECEIVED}, - {Epoch: sdk.NewInt(epoch + 3), State: types.Deposit_DEPOSIT_DELEGATING}, + {Epoch: epoch, State: types.Deposit_DEPOSIT_PENDING}, + {Epoch: epoch + 1, State: types.Deposit_DEPOSIT_PENDING}, + {Epoch: epoch + 2, State: types.Deposit_DEPOSIT_RECEIVED}, + {Epoch: epoch + 3, State: types.Deposit_DEPOSIT_DELEGATING}, }, epoch: epoch + 1, expected: []types.Deposit{ - {Epoch: sdk.NewInt(epoch), State: types.Deposit_DEPOSIT_PENDING}, - {Epoch: sdk.NewInt(epoch + 1), State: types.Deposit_DEPOSIT_PENDING}, + {Epoch: epoch, State: types.Deposit_DEPOSIT_PENDING}, + {Epoch: epoch + 1, State: types.Deposit_DEPOSIT_PENDING}, }, }, { name: "NotFound", deposits: []types.Deposit{ - {Epoch: sdk.NewInt(epoch), State: types.Deposit_DEPOSIT_RECEIVED}, - {Epoch: sdk.NewInt(epoch + 1), State: types.Deposit_DEPOSIT_DELEGATING}, - {Epoch: sdk.NewInt(epoch + 2), State: types.Deposit_DEPOSIT_PENDING}, - {Epoch: sdk.NewInt(epoch + 3), State: types.Deposit_DEPOSIT_PENDING}, + {Epoch: epoch, State: types.Deposit_DEPOSIT_RECEIVED}, + {Epoch: epoch + 1, State: types.Deposit_DEPOSIT_DELEGATING}, + {Epoch: epoch + 2, State: types.Deposit_DEPOSIT_PENDING}, + {Epoch: epoch + 3, State: types.Deposit_DEPOSIT_PENDING}, }, epoch: epoch + 1, expected: []types.Deposit{}, @@ -378,7 +378,7 @@ func (suite *IntegrationTestSuite) TestGetPendingDepositsBeforeEpoch() { suite.Require().Equal(len(t.expected), len(hcs)) for _, hc := range hcs { - suite.Require().LessOrEqual(hc.Epoch.Int64(), t.epoch) + suite.Require().LessOrEqual(hc.Epoch, t.epoch) suite.Require().Equal(types.Deposit_DEPOSIT_PENDING, hc.State) } }) @@ -397,24 +397,24 @@ func (suite *IntegrationTestSuite) TestGetDelegableDepositsForChain() { { name: "Success", deposits: []types.Deposit{ - {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: sdk.NewInt(epoch), State: types.Deposit_DEPOSIT_RECEIVED}, - {ChainId: suite.path.EndpointA.Chain.ChainID, Epoch: sdk.NewInt(epoch + 1), State: types.Deposit_DEPOSIT_RECEIVED}, - {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: sdk.NewInt(epoch + 2), State: types.Deposit_DEPOSIT_RECEIVED}, - {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: sdk.NewInt(epoch + 3), State: types.Deposit_DEPOSIT_PENDING}, + {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: epoch, State: types.Deposit_DEPOSIT_RECEIVED}, + {ChainId: suite.path.EndpointA.Chain.ChainID, Epoch: epoch + 1, State: types.Deposit_DEPOSIT_RECEIVED}, + {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: epoch + 2, State: types.Deposit_DEPOSIT_RECEIVED}, + {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: epoch + 3, State: types.Deposit_DEPOSIT_PENDING}, }, chainID: suite.path.EndpointB.Chain.ChainID, expected: []types.Deposit{ - {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: sdk.NewInt(epoch), State: types.Deposit_DEPOSIT_RECEIVED}, - {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: sdk.NewInt(epoch + 2), State: types.Deposit_DEPOSIT_RECEIVED}, + {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: epoch, State: types.Deposit_DEPOSIT_RECEIVED}, + {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: epoch + 2, State: types.Deposit_DEPOSIT_RECEIVED}, }, }, { name: "NotFound", deposits: []types.Deposit{ - {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: sdk.NewInt(epoch), State: types.Deposit_DEPOSIT_RECEIVED}, - {ChainId: suite.path.EndpointA.Chain.ChainID, Epoch: sdk.NewInt(epoch + 1), State: types.Deposit_DEPOSIT_RECEIVED}, - {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: sdk.NewInt(epoch + 2), State: types.Deposit_DEPOSIT_RECEIVED}, - {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: sdk.NewInt(epoch + 3), State: types.Deposit_DEPOSIT_PENDING}, + {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: epoch, State: types.Deposit_DEPOSIT_RECEIVED}, + {ChainId: suite.path.EndpointA.Chain.ChainID, Epoch: epoch + 1, State: types.Deposit_DEPOSIT_RECEIVED}, + {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: epoch + 2, State: types.Deposit_DEPOSIT_RECEIVED}, + {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: epoch + 3, State: types.Deposit_DEPOSIT_PENDING}, }, chainID: "test-chain-id", expected: []types.Deposit{}, @@ -450,24 +450,24 @@ func (suite *IntegrationTestSuite) TestGetDelegatingDepositsForChain() { { name: "found test", deposits: []types.Deposit{ - {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: sdk.NewInt(epoch), State: types.Deposit_DEPOSIT_DELEGATING}, - {ChainId: suite.path.EndpointA.Chain.ChainID, Epoch: sdk.NewInt(epoch + 1), State: types.Deposit_DEPOSIT_DELEGATING}, - {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: sdk.NewInt(epoch + 2), State: types.Deposit_DEPOSIT_DELEGATING}, - {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: sdk.NewInt(epoch + 3), State: types.Deposit_DEPOSIT_PENDING}, + {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: epoch, State: types.Deposit_DEPOSIT_DELEGATING}, + {ChainId: suite.path.EndpointA.Chain.ChainID, Epoch: epoch + 1, State: types.Deposit_DEPOSIT_DELEGATING}, + {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: epoch + 2, State: types.Deposit_DEPOSIT_DELEGATING}, + {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: epoch + 3, State: types.Deposit_DEPOSIT_PENDING}, }, chainID: suite.path.EndpointB.Chain.ChainID, expected: []types.Deposit{ - {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: sdk.NewInt(epoch), State: types.Deposit_DEPOSIT_DELEGATING}, - {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: sdk.NewInt(epoch + 2), State: types.Deposit_DEPOSIT_DELEGATING}, + {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: epoch, State: types.Deposit_DEPOSIT_DELEGATING}, + {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: epoch + 2, State: types.Deposit_DEPOSIT_DELEGATING}, }, }, { name: "not found test", deposits: []types.Deposit{ - {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: sdk.NewInt(epoch), State: types.Deposit_DEPOSIT_DELEGATING}, - {ChainId: suite.path.EndpointA.Chain.ChainID, Epoch: sdk.NewInt(epoch + 1), State: types.Deposit_DEPOSIT_DELEGATING}, - {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: sdk.NewInt(epoch + 2), State: types.Deposit_DEPOSIT_DELEGATING}, - {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: sdk.NewInt(epoch + 3), State: types.Deposit_DEPOSIT_PENDING}, + {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: epoch, State: types.Deposit_DEPOSIT_DELEGATING}, + {ChainId: suite.path.EndpointA.Chain.ChainID, Epoch: epoch + 1, State: types.Deposit_DEPOSIT_DELEGATING}, + {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: epoch + 2, State: types.Deposit_DEPOSIT_DELEGATING}, + {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: epoch + 3, State: types.Deposit_DEPOSIT_PENDING}, }, chainID: "test-host-chain", expected: []types.Deposit{}, diff --git a/x/liquidstakeibc/keeper/grpc_querier_test.go b/x/liquidstakeibc/keeper/grpc_querier_test.go index 784d1cc24..9cbc31509 100644 --- a/x/liquidstakeibc/keeper/grpc_querier_test.go +++ b/x/liquidstakeibc/keeper/grpc_querier_test.go @@ -1,7 +1,6 @@ package keeper_test import ( - sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" @@ -127,7 +126,7 @@ func (suite *IntegrationTestSuite) TestQueryDeposits() { for i := 0; i < MultipleTestSize; i += 1 { deposit := &types.Deposit{ ChainId: suite.path.EndpointB.Chain.ChainID, - Epoch: sdk.NewInt(int64(i)), + Epoch: int64(i), } suite.app.LiquidStakeIBCKeeper.SetDeposit(suite.ctx, deposit) deposits = append(deposits, deposit) diff --git a/x/liquidstakeibc/keeper/hooks.go b/x/liquidstakeibc/keeper/hooks.go index a33b2cd5b..65c603e88 100644 --- a/x/liquidstakeibc/keeper/hooks.go +++ b/x/liquidstakeibc/keeper/hooks.go @@ -421,7 +421,7 @@ func (k *Keeper) DepositWorkflow(ctx sdk.Context, epoch int64) { // check if the deposit amount is larger than 0 if deposit.Amount.Amount.LTE(sdk.NewInt(0)) { // delete empty deposits to save on storage - if deposit.Epoch.Int64() < epoch { + if deposit.Epoch < epoch { k.DeleteDeposit(ctx, deposit) } diff --git a/x/liquidstakeibc/types/keys.go b/x/liquidstakeibc/types/keys.go index cb9a7f69c..2180a146b 100644 --- a/x/liquidstakeibc/types/keys.go +++ b/x/liquidstakeibc/types/keys.go @@ -63,3 +63,7 @@ func GetUserUnbondingStoreKey(chainID, delegatorAddress string, epochNumber int6 func GetValidatorUnbondingStoreKey(chainID, validatorAddress string, epochNumber int64) []byte { return append([]byte(chainID), append([]byte(validatorAddress), []byte(strconv.FormatInt(epochNumber, 10))...)...) } + +func GetDepositStoreKey(chainID string, epochNumber int64) []byte { + return append([]byte(chainID), []byte(strconv.FormatInt(epochNumber, 10))...) +} diff --git a/x/liquidstakeibc/types/liquidstakeibc.pb.go b/x/liquidstakeibc/types/liquidstakeibc.pb.go index 3d0abb60c..08fa34446 100644 --- a/x/liquidstakeibc/types/liquidstakeibc.pb.go +++ b/x/liquidstakeibc/types/liquidstakeibc.pb.go @@ -164,7 +164,7 @@ type HostChain struct { UnbondingFactor int64 `protobuf:"varint,13,opt,name=unbonding_factor,json=unbondingFactor,proto3" json:"unbonding_factor,omitempty"` // whether the chain is ready to accept delegations or not Active bool `protobuf:"varint,14,opt,name=active,proto3" json:"active,omitempty"` - // factor limit for auto-compounding + // factor limit for auto-compounding, daily periodic rate (APY / 365s) AutoCompoundFactor github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,15,opt,name=auto_compound_factor,json=autoCompoundFactor,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"auto_compound_factor"` } @@ -463,7 +463,7 @@ type Deposit struct { ChainId string `protobuf:"bytes,1,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` Amount types.Coin `protobuf:"bytes,2,opt,name=amount,proto3" json:"amount"` // epoch number of the deposit - Epoch github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,3,opt,name=epoch,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"epoch"` + Epoch int64 `protobuf:"varint,3,opt,name=epoch,proto3" json:"epoch,omitempty"` // state State Deposit_DepositState `protobuf:"varint,4,opt,name=state,proto3,enum=pstake.liquidstakeibc.v1beta1.Deposit_DepositState" json:"state,omitempty"` // sequence id of the ibc transaction @@ -517,6 +517,13 @@ func (m *Deposit) GetAmount() types.Coin { return types.Coin{} } +func (m *Deposit) GetEpoch() int64 { + if m != nil { + return m.Epoch + } + return 0 +} + func (m *Deposit) GetState() Deposit_DepositState { if m != nil { return m.State @@ -873,93 +880,93 @@ func init() { } var fileDescriptor_71a9a61e676043b6 = []byte{ - // 1363 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x57, 0xcb, 0x6f, 0x13, 0x47, - 0x18, 0x8f, 0xb3, 0x7e, 0xc4, 0x9f, 0xed, 0x78, 0x33, 0xa4, 0x60, 0x90, 0x70, 0x52, 0x57, 0x82, - 0x70, 0x88, 0x5d, 0x8c, 0x54, 0xa4, 0xaa, 0xaa, 0xea, 0xd8, 0x1b, 0xb2, 0x6a, 0x30, 0x68, 0xe3, - 0x44, 0x55, 0x51, 0xbb, 0x1a, 0xef, 0x0e, 0xce, 0x2a, 0xde, 0x1d, 0xb3, 0x3b, 0x1b, 0xe0, 0x2f, - 0xa8, 0x7a, 0xe3, 0x52, 0xa9, 0xa7, 0xaa, 0xe7, 0x9e, 0x2a, 0x95, 0x5b, 0x4f, 0xbd, 0x71, 0x44, - 0x9c, 0xaa, 0xaa, 0x82, 0x0a, 0xfe, 0x91, 0x6a, 0x1e, 0x6b, 0x9b, 0x87, 0x88, 0xa3, 0xfa, 0xd0, - 0x93, 0x67, 0xbe, 0x6f, 0x7f, 0xbf, 0x99, 0xf9, 0xde, 0x86, 0xe6, 0x28, 0x62, 0xf8, 0x88, 0x34, - 0x86, 0xde, 0xbd, 0xd8, 0x73, 0xc5, 0xda, 0xeb, 0x3b, 0x8d, 0xe3, 0xab, 0x7d, 0xc2, 0xf0, 0xd5, - 0x37, 0xc4, 0xf5, 0x51, 0x48, 0x19, 0x45, 0x17, 0x25, 0xa6, 0xfe, 0x86, 0x52, 0x61, 0x2e, 0xac, - 0x0e, 0xe8, 0x80, 0x8a, 0x2f, 0x1b, 0x7c, 0x25, 0x41, 0x17, 0xce, 0x3b, 0x34, 0xf2, 0x69, 0x64, - 0x4b, 0x85, 0xdc, 0x28, 0x55, 0x55, 0xee, 0x1a, 0x7d, 0x1c, 0x91, 0xf1, 0xc9, 0x0e, 0xf5, 0x02, - 0xa5, 0x5f, 0x1b, 0x50, 0x3a, 0x18, 0x92, 0x86, 0xd8, 0xf5, 0xe3, 0xbb, 0x0d, 0xe6, 0xf9, 0x24, - 0x62, 0xd8, 0x1f, 0xc9, 0x0f, 0x6a, 0xbf, 0xe7, 0x20, 0xbf, 0x43, 0x23, 0xd6, 0x3e, 0xc4, 0x5e, - 0x80, 0xce, 0xc3, 0x92, 0xc3, 0x17, 0xb6, 0xe7, 0x56, 0x52, 0xeb, 0xa9, 0x8d, 0xbc, 0x95, 0x13, - 0x7b, 0xd3, 0x45, 0x1f, 0x41, 0xc9, 0xa1, 0x41, 0x40, 0x1c, 0xe6, 0x51, 0xa1, 0x5f, 0x14, 0xfa, - 0xe2, 0x44, 0x68, 0xba, 0x68, 0x07, 0xb2, 0x23, 0x1c, 0x62, 0x3f, 0xaa, 0x68, 0xeb, 0xa9, 0x8d, - 0x42, 0xf3, 0xe3, 0xfa, 0x7b, 0xdf, 0x5b, 0x1f, 0x9f, 0xbc, 0xbb, 0x77, 0x5b, 0xe0, 0x2c, 0x85, - 0x47, 0x17, 0x01, 0x0e, 0x69, 0xc4, 0x6c, 0x97, 0x04, 0xd4, 0xaf, 0xa4, 0xc5, 0x59, 0x79, 0x2e, - 0xe9, 0x70, 0x01, 0x57, 0x3b, 0x87, 0x38, 0x08, 0xc8, 0x90, 0x5f, 0x25, 0x23, 0xd5, 0x4a, 0x62, - 0xba, 0xe8, 0x1c, 0xe4, 0x46, 0x34, 0x64, 0x5c, 0x97, 0x15, 0xba, 0x2c, 0xdf, 0x9a, 0x2e, 0xfa, - 0x0a, 0x90, 0x4b, 0x86, 0x64, 0x80, 0xc5, 0x2b, 0xb0, 0xe3, 0xd0, 0x38, 0x60, 0x95, 0x9c, 0xb8, - 0xec, 0x95, 0x13, 0x2e, 0x6b, 0xb6, 0x5b, 0x2d, 0x09, 0xb0, 0x56, 0x26, 0x24, 0x4a, 0x84, 0x2c, - 0x28, 0x87, 0xe4, 0x3e, 0x0e, 0xdd, 0x68, 0x4c, 0xbb, 0x74, 0x5a, 0xda, 0x65, 0xc5, 0x90, 0x70, - 0xee, 0x00, 0x1c, 0xe3, 0xa1, 0xe7, 0x62, 0x46, 0xc3, 0xa8, 0x92, 0x5f, 0xd7, 0x36, 0x0a, 0xcd, - 0x8d, 0x13, 0xe8, 0x0e, 0x12, 0x80, 0x35, 0x85, 0x45, 0x04, 0xca, 0xbe, 0x17, 0x78, 0x7e, 0xec, - 0xdb, 0x2e, 0x19, 0xd1, 0xc8, 0x63, 0x15, 0xe0, 0x86, 0xd9, 0xfa, 0xec, 0xc9, 0xf3, 0xb5, 0x85, - 0xbf, 0x9e, 0xaf, 0x5d, 0x1a, 0x78, 0xec, 0x30, 0xee, 0xd7, 0x1d, 0xea, 0xab, 0x08, 0x53, 0x3f, - 0x9b, 0x91, 0x7b, 0xd4, 0x60, 0x0f, 0x47, 0x24, 0xaa, 0x9b, 0x01, 0x7b, 0xf6, 0x78, 0x13, 0x54, - 0x00, 0x9a, 0xfc, 0xc2, 0x8a, 0xb4, 0x23, 0x39, 0xd1, 0x3e, 0xe4, 0x1c, 0xfb, 0x18, 0x0f, 0x63, - 0x52, 0x29, 0x9c, 0x9a, 0xbe, 0x43, 0x9c, 0x29, 0xfa, 0x0e, 0x71, 0xac, 0xac, 0x73, 0xc0, 0xb9, - 0xd0, 0xb7, 0x50, 0x1c, 0xe2, 0x88, 0xd9, 0x09, 0x77, 0x71, 0x0e, 0xdc, 0xc0, 0x19, 0xdb, 0x92, - 0xff, 0x0a, 0xe8, 0x71, 0xd0, 0xa7, 0x81, 0xeb, 0x05, 0x03, 0xfb, 0x2e, 0x76, 0x18, 0x0d, 0x2b, - 0xa5, 0xf5, 0xd4, 0x86, 0x66, 0x95, 0xc7, 0xf2, 0x6d, 0x21, 0x46, 0x67, 0x21, 0x8b, 0x1d, 0xe6, - 0x1d, 0x93, 0xca, 0xf2, 0x7a, 0x6a, 0x63, 0xc9, 0x52, 0x3b, 0x14, 0xc0, 0x2a, 0x8e, 0x19, 0xb5, - 0x1d, 0xea, 0x8f, 0x68, 0x1c, 0xb8, 0x09, 0x4d, 0x79, 0x0e, 0x57, 0x45, 0x9c, 0xb9, 0xad, 0x88, - 0xe5, 0x3d, 0x3e, 0x4d, 0xff, 0xf8, 0xf3, 0x5a, 0xaa, 0xf6, 0x83, 0x06, 0x2b, 0x6f, 0xe5, 0x10, - 0xfa, 0x06, 0x0a, 0xca, 0xc9, 0xf6, 0x5d, 0x42, 0x64, 0x22, 0xff, 0x57, 0x6b, 0x29, 0xc2, 0x6d, - 0x42, 0x38, 0x7d, 0x48, 0x44, 0xdc, 0x09, 0xfa, 0xc5, 0x79, 0xd0, 0x2b, 0x42, 0x45, 0x1f, 0x07, - 0x13, 0x7a, 0x6d, 0x1e, 0xf4, 0x8a, 0x90, 0xd3, 0x3b, 0xb0, 0x1c, 0x12, 0x97, 0xf8, 0x23, 0x51, - 0x01, 0xf8, 0x09, 0xe9, 0x39, 0x9c, 0x50, 0x9a, 0x70, 0x6e, 0x13, 0x52, 0xfb, 0x7b, 0x11, 0x60, - 0x92, 0xd7, 0xa8, 0x09, 0x39, 0xec, 0xba, 0x21, 0x89, 0x22, 0xe5, 0x8c, 0xca, 0xb3, 0xc7, 0x9b, - 0xab, 0x0a, 0xde, 0x92, 0x9a, 0x3d, 0x16, 0x7a, 0xc1, 0xc0, 0x4a, 0x3e, 0x44, 0x2e, 0xe4, 0xfa, - 0x78, 0x88, 0x03, 0x47, 0x5a, 0xb8, 0xd0, 0x3c, 0x5f, 0x57, 0x00, 0x5e, 0xeb, 0xc7, 0xe9, 0xde, - 0xa6, 0x5e, 0xb0, 0xd5, 0xe0, 0x77, 0xff, 0xe5, 0xc5, 0xda, 0xe5, 0x19, 0xee, 0xce, 0x01, 0x56, - 0x42, 0x8d, 0x56, 0x21, 0x43, 0xef, 0x07, 0x24, 0x94, 0x66, 0xb6, 0xe4, 0x06, 0xdd, 0x81, 0x52, - 0x52, 0x5d, 0x23, 0x86, 0x99, 0x34, 0xd1, 0x72, 0xf3, 0x93, 0x99, 0x2b, 0x59, 0xbd, 0x2d, 0xe1, - 0x7b, 0x1c, 0x6d, 0x15, 0x9d, 0xa9, 0x5d, 0xad, 0x05, 0xc5, 0x69, 0x2d, 0xaa, 0xc0, 0xaa, 0xd9, - 0x6e, 0xd9, 0xed, 0x9d, 0x56, 0xb7, 0x6b, 0xec, 0xda, 0x6d, 0xcb, 0x68, 0xf5, 0xcc, 0xee, 0x0d, - 0x7d, 0x01, 0x9d, 0x83, 0x33, 0x6f, 0x69, 0x8c, 0x8e, 0x9e, 0xaa, 0xfd, 0xa6, 0x41, 0x7e, 0x5c, - 0xe7, 0x50, 0x1b, 0x74, 0x3a, 0x22, 0x21, 0x5f, 0xdb, 0xb3, 0x9a, 0xb9, 0x9c, 0x20, 0x94, 0x98, - 0xe7, 0x35, 0x7f, 0x6a, 0x1c, 0xa9, 0xbe, 0xa6, 0x76, 0xa8, 0x07, 0xd9, 0xfb, 0xc4, 0x1b, 0x1c, - 0xb2, 0xb9, 0x04, 0xa2, 0xe2, 0x42, 0x03, 0xd0, 0x55, 0x07, 0x21, 0xae, 0x8d, 0x7d, 0xd1, 0x2d, - 0xd2, 0x73, 0xa8, 0xc7, 0xe5, 0x31, 0x6b, 0x4b, 0x90, 0x22, 0x0c, 0x25, 0xf2, 0x80, 0x9b, 0x7f, - 0x40, 0xec, 0x90, 0x7b, 0x32, 0x33, 0x87, 0x57, 0x14, 0x13, 0x4a, 0x8b, 0xfb, 0xef, 0x32, 0x4c, - 0x8a, 0xa4, 0x4d, 0x46, 0xd4, 0x39, 0x14, 0x3d, 0x57, 0xb3, 0x96, 0xc7, 0x62, 0x83, 0x4b, 0x6b, - 0xdf, 0x6b, 0x90, 0x4b, 0x1a, 0xc5, 0x7b, 0x06, 0x8d, 0xeb, 0x90, 0x55, 0x16, 0x39, 0x31, 0xee, - 0xd3, 0xfc, 0x19, 0x96, 0xfa, 0x1c, 0x59, 0x90, 0x91, 0xc7, 0x6b, 0x73, 0xb0, 0xa4, 0xa4, 0x42, - 0x26, 0x64, 0xa6, 0x33, 0xe0, 0xda, 0x09, 0x19, 0xa0, 0x9e, 0x97, 0xfc, 0xca, 0xf0, 0x97, 0x0c, - 0xe8, 0x12, 0x94, 0xbd, 0xbe, 0x63, 0x47, 0xe4, 0x5e, 0x4c, 0x02, 0x87, 0x4c, 0xe6, 0x96, 0x92, - 0xd7, 0x77, 0xf6, 0x94, 0xd4, 0x74, 0x6b, 0x0e, 0x14, 0xa7, 0xe1, 0xe8, 0x0c, 0x94, 0x3b, 0xc6, - 0xed, 0x5b, 0x7b, 0x66, 0xcf, 0xbe, 0x6d, 0x74, 0x3b, 0x32, 0x35, 0x74, 0x28, 0x26, 0xc2, 0x3d, - 0xa3, 0xdb, 0xd3, 0x53, 0x68, 0x15, 0xf4, 0x44, 0x62, 0x19, 0x6d, 0xc3, 0x3c, 0x30, 0x3a, 0xfa, - 0x22, 0x3a, 0x0b, 0x28, 0x91, 0x76, 0x8c, 0x5d, 0xe3, 0x86, 0x4c, 0x2d, 0xad, 0xf6, 0x6b, 0x1a, - 0xf2, 0xfb, 0x89, 0x7b, 0xde, 0xe7, 0x8d, 0x0f, 0xa1, 0x28, 0x2c, 0x61, 0x07, 0xb1, 0xdf, 0x27, - 0xa1, 0xf0, 0x89, 0x66, 0x15, 0x84, 0xac, 0x2b, 0x44, 0xc8, 0x80, 0x82, 0x8f, 0x59, 0x1c, 0x12, - 0x9b, 0x0f, 0x97, 0x6a, 0xf2, 0xbb, 0x50, 0x97, 0x93, 0x67, 0x3d, 0x99, 0x3c, 0xeb, 0xbd, 0x64, - 0xf2, 0xdc, 0x5a, 0xe2, 0x9e, 0x79, 0xf4, 0x62, 0x2d, 0x65, 0x81, 0x04, 0x72, 0x15, 0xfa, 0x02, - 0x0a, 0xfd, 0x38, 0x0c, 0xa6, 0xd3, 0x61, 0x06, 0xe7, 0x03, 0xc7, 0xa8, 0x60, 0xef, 0x40, 0x49, - 0x86, 0x5c, 0xc2, 0x91, 0x99, 0x8d, 0xa3, 0x28, 0x51, 0x8a, 0xe5, 0x1d, 0x7e, 0xca, 0xbe, 0xc3, - 0x4f, 0xe8, 0x66, 0x12, 0x1a, 0x39, 0x11, 0x1a, 0xd7, 0x4f, 0x08, 0x8d, 0xb1, 0xb5, 0x27, 0xab, - 0xe9, 0xf0, 0xa8, 0xfd, 0x94, 0x82, 0xe5, 0xd7, 0x35, 0xe8, 0x03, 0x58, 0xd9, 0xef, 0x6e, 0xdd, - 0x12, 0x3e, 0x9f, 0xf2, 0xfd, 0x39, 0x38, 0x33, 0x11, 0x9b, 0x5d, 0xb3, 0x67, 0xca, 0xb2, 0xc8, - 0x9d, 0x3d, 0x51, 0xdc, 0x6c, 0xf5, 0xf6, 0x2d, 0x0e, 0x58, 0x7c, 0x9d, 0x47, 0xc8, 0x8d, 0x8e, - 0xae, 0xbd, 0xce, 0xd3, 0xde, 0x6d, 0x99, 0x37, 0x5b, 0x5b, 0xbb, 0x86, 0x9e, 0xe6, 0xa1, 0x34, - 0x51, 0x6c, 0xb7, 0xcc, 0x5d, 0xa3, 0xa3, 0x67, 0x6a, 0xdf, 0x2d, 0x42, 0x69, 0x3f, 0x22, 0xe1, - 0xbc, 0xc2, 0x66, 0xaa, 0x29, 0x6a, 0xb3, 0x36, 0xc5, 0xcf, 0x01, 0x22, 0x76, 0x74, 0xca, 0x10, - 0xc9, 0x47, 0xec, 0x68, 0x9e, 0x11, 0x52, 0xfb, 0x63, 0x11, 0xd0, 0xb8, 0xfd, 0xfc, 0xcf, 0xb2, - 0xc8, 0x80, 0x95, 0xf1, 0xd8, 0x3f, 0xee, 0x86, 0xe9, 0x13, 0xec, 0xab, 0x8f, 0x21, 0x49, 0x3b, - 0x9c, 0x14, 0xe1, 0xcc, 0xe9, 0x8a, 0xf0, 0x8c, 0xd9, 0x53, 0x6b, 0xc2, 0xd2, 0x97, 0x07, 0xfb, - 0x23, 0x97, 0xc7, 0xb9, 0x0e, 0xda, 0x11, 0x79, 0xa8, 0x6c, 0xc6, 0x97, 0x7c, 0x2c, 0x91, 0x93, - 0xbe, 0x6c, 0xc6, 0x72, 0xb3, 0x75, 0xe7, 0xc9, 0xcb, 0x6a, 0xea, 0xe9, 0xcb, 0x6a, 0xea, 0x9f, - 0x97, 0xd5, 0xd4, 0xa3, 0x57, 0xd5, 0x85, 0xa7, 0xaf, 0xaa, 0x0b, 0x7f, 0xbe, 0xaa, 0x2e, 0x7c, - 0xdd, 0x9a, 0xaa, 0xf1, 0x23, 0x12, 0x46, 0x5e, 0xc4, 0xf8, 0x39, 0xb7, 0x02, 0xd2, 0x90, 0x59, - 0xb9, 0x19, 0x60, 0x3e, 0xa6, 0x37, 0x8e, 0x9b, 0x8d, 0x07, 0x6f, 0xfe, 0x61, 0x17, 0x2d, 0xa0, - 0x9f, 0x15, 0x26, 0xbe, 0xf6, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x19, 0x66, 0x96, 0xc2, 0xd6, - 0x0f, 0x00, 0x00, + // 1364 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x57, 0xcd, 0x6f, 0x13, 0x47, + 0x14, 0x8f, 0x3f, 0x62, 0xc7, 0xcf, 0x76, 0xbc, 0x19, 0x52, 0x30, 0x48, 0x38, 0xa9, 0x2b, 0x41, + 0x38, 0xc4, 0x2e, 0x46, 0x2a, 0x52, 0x55, 0x55, 0x75, 0xec, 0x0d, 0x59, 0x35, 0x18, 0xb4, 0x71, + 0xa2, 0xaa, 0xa8, 0x5d, 0x8d, 0x77, 0x07, 0x67, 0x15, 0xef, 0x8e, 0xd9, 0x9d, 0x0d, 0xf0, 0x17, + 0xf4, 0xca, 0xa5, 0x52, 0x4f, 0x55, 0xcf, 0x3d, 0x55, 0x2a, 0xb7, 0x9e, 0x7a, 0x43, 0xea, 0x05, + 0x71, 0xaa, 0xaa, 0x0a, 0x2a, 0xf8, 0x47, 0xaa, 0xf9, 0xd8, 0xb5, 0xf9, 0x10, 0x71, 0x54, 0x1f, + 0x7a, 0xf2, 0xbc, 0xf7, 0xf6, 0xf7, 0x9b, 0x99, 0x37, 0xbf, 0x79, 0x6f, 0x0c, 0xad, 0x71, 0xc8, + 0xf0, 0x11, 0x69, 0x8e, 0xdc, 0x7b, 0x91, 0xeb, 0x88, 0xb1, 0x3b, 0xb0, 0x9b, 0xc7, 0x57, 0x07, + 0x84, 0xe1, 0xab, 0x6f, 0xb8, 0x1b, 0xe3, 0x80, 0x32, 0x8a, 0x2e, 0x4a, 0x4c, 0xe3, 0x8d, 0xa0, + 0xc2, 0x5c, 0x58, 0x1d, 0xd2, 0x21, 0x15, 0x5f, 0x36, 0xf9, 0x48, 0x82, 0x2e, 0x9c, 0xb7, 0x69, + 0xe8, 0xd1, 0xd0, 0x92, 0x01, 0x69, 0xa8, 0x50, 0x4d, 0x5a, 0xcd, 0x01, 0x0e, 0x49, 0x32, 0xb3, + 0x4d, 0x5d, 0x5f, 0xc5, 0xd7, 0x86, 0x94, 0x0e, 0x47, 0xa4, 0x29, 0xac, 0x41, 0x74, 0xb7, 0xc9, + 0x5c, 0x8f, 0x84, 0x0c, 0x7b, 0x63, 0xf9, 0x41, 0xfd, 0xb7, 0x3c, 0x14, 0x76, 0x68, 0xc8, 0x3a, + 0x87, 0xd8, 0xf5, 0xd1, 0x79, 0x58, 0xb2, 0xf9, 0xc0, 0x72, 0x9d, 0x6a, 0x6a, 0x3d, 0xb5, 0x51, + 0x30, 0xf3, 0xc2, 0x36, 0x1c, 0xf4, 0x11, 0x94, 0x6d, 0xea, 0xfb, 0xc4, 0x66, 0x2e, 0x15, 0xf1, + 0xb4, 0x88, 0x97, 0x26, 0x4e, 0xc3, 0x41, 0x3b, 0x90, 0x1b, 0xe3, 0x00, 0x7b, 0x61, 0x35, 0xb3, + 0x9e, 0xda, 0x28, 0xb6, 0x3e, 0x6e, 0xbc, 0x77, 0xbf, 0x8d, 0x64, 0xe6, 0xdd, 0xbd, 0xdb, 0x02, + 0x67, 0x2a, 0x3c, 0xba, 0x08, 0x70, 0x48, 0x43, 0x66, 0x39, 0xc4, 0xa7, 0x5e, 0x35, 0x2b, 0xe6, + 0x2a, 0x70, 0x4f, 0x97, 0x3b, 0x78, 0xd8, 0x3e, 0xc4, 0xbe, 0x4f, 0x46, 0x7c, 0x29, 0x8b, 0x32, + 0xac, 0x3c, 0x86, 0x83, 0xce, 0x41, 0x7e, 0x4c, 0x03, 0xc6, 0x63, 0x39, 0x11, 0xcb, 0x71, 0xd3, + 0x70, 0xd0, 0x57, 0x80, 0x1c, 0x32, 0x22, 0x43, 0x2c, 0x76, 0x81, 0x6d, 0x9b, 0x46, 0x3e, 0xab, + 0xe6, 0xc5, 0x62, 0xaf, 0x9c, 0xb0, 0x58, 0xa3, 0xd3, 0x6e, 0x4b, 0x80, 0xb9, 0x32, 0x21, 0x51, + 0x2e, 0x64, 0x42, 0x25, 0x20, 0xf7, 0x71, 0xe0, 0x84, 0x09, 0xed, 0xd2, 0x69, 0x69, 0x97, 0x15, + 0x43, 0xcc, 0xb9, 0x03, 0x70, 0x8c, 0x47, 0xae, 0x83, 0x19, 0x0d, 0xc2, 0x6a, 0x61, 0x3d, 0xb3, + 0x51, 0x6c, 0x6d, 0x9c, 0x40, 0x77, 0x10, 0x03, 0xcc, 0x29, 0x2c, 0x22, 0x50, 0xf1, 0x5c, 0xdf, + 0xf5, 0x22, 0xcf, 0x72, 0xc8, 0x98, 0x86, 0x2e, 0xab, 0x02, 0x4f, 0xcc, 0xd6, 0x67, 0x4f, 0x9e, + 0xaf, 0x2d, 0xfc, 0xf5, 0x7c, 0xed, 0xd2, 0xd0, 0x65, 0x87, 0xd1, 0xa0, 0x61, 0x53, 0x4f, 0x29, + 0x4c, 0xfd, 0x6c, 0x86, 0xce, 0x51, 0x93, 0x3d, 0x1c, 0x93, 0xb0, 0x61, 0xf8, 0xec, 0xd9, 0xe3, + 0x4d, 0x50, 0x02, 0x34, 0xf8, 0x82, 0x15, 0x69, 0x57, 0x72, 0xa2, 0x7d, 0xc8, 0xdb, 0xd6, 0x31, + 0x1e, 0x45, 0xa4, 0x5a, 0x3c, 0x35, 0x7d, 0x97, 0xd8, 0x53, 0xf4, 0x5d, 0x62, 0x9b, 0x39, 0xfb, + 0x80, 0x73, 0xa1, 0x6f, 0xa1, 0x34, 0xc2, 0x21, 0xb3, 0x62, 0xee, 0xd2, 0x1c, 0xb8, 0x81, 0x33, + 0x76, 0x24, 0xff, 0x15, 0xd0, 0x22, 0x7f, 0x40, 0x7d, 0xc7, 0xf5, 0x87, 0xd6, 0x5d, 0x6c, 0x33, + 0x1a, 0x54, 0xcb, 0xeb, 0xa9, 0x8d, 0x8c, 0x59, 0x49, 0xfc, 0xdb, 0xc2, 0x8d, 0xce, 0x42, 0x0e, + 0xdb, 0xcc, 0x3d, 0x26, 0xd5, 0xe5, 0xf5, 0xd4, 0xc6, 0x92, 0xa9, 0x2c, 0xe4, 0xc3, 0x2a, 0x8e, + 0x18, 0xb5, 0x6c, 0xea, 0x8d, 0x69, 0xe4, 0x3b, 0x31, 0x4d, 0x65, 0x0e, 0x4b, 0x45, 0x9c, 0xb9, + 0xa3, 0x88, 0xe5, 0x3a, 0x3e, 0xcd, 0xfe, 0xf0, 0xd3, 0x5a, 0xaa, 0xfe, 0x7d, 0x06, 0x56, 0xde, + 0xba, 0x43, 0xe8, 0x1b, 0x28, 0xaa, 0x43, 0xb6, 0xee, 0x12, 0x22, 0x2f, 0xf2, 0x7f, 0xcd, 0x96, + 0x22, 0xdc, 0x26, 0x84, 0xd3, 0x07, 0x44, 0xe8, 0x4e, 0xd0, 0xa7, 0xe7, 0x41, 0xaf, 0x08, 0x15, + 0x7d, 0xe4, 0x4f, 0xe8, 0x33, 0xf3, 0xa0, 0x57, 0x84, 0x9c, 0xde, 0x86, 0xe5, 0x80, 0x38, 0xc4, + 0x1b, 0x8b, 0x0a, 0xc0, 0x67, 0xc8, 0xce, 0x61, 0x86, 0xf2, 0x84, 0x73, 0x9b, 0x90, 0xfa, 0xdf, + 0x69, 0x80, 0xc9, 0xbd, 0x46, 0x2d, 0xc8, 0x63, 0xc7, 0x09, 0x48, 0x18, 0xaa, 0xc3, 0xa8, 0x3e, + 0x7b, 0xbc, 0xb9, 0xaa, 0xe0, 0x6d, 0x19, 0xd9, 0x63, 0x81, 0xeb, 0x0f, 0xcd, 0xf8, 0x43, 0xe4, + 0x40, 0x7e, 0x80, 0x47, 0xd8, 0xb7, 0x65, 0x86, 0x8b, 0xad, 0xf3, 0x0d, 0x05, 0xe0, 0xb5, 0x3e, + 0xb9, 0xee, 0x1d, 0xea, 0xfa, 0x5b, 0x4d, 0xbe, 0xf6, 0x9f, 0x5f, 0xac, 0x5d, 0x9e, 0x61, 0xed, + 0x1c, 0x60, 0xc6, 0xd4, 0x68, 0x15, 0x16, 0xe9, 0x7d, 0x9f, 0x04, 0x32, 0xcd, 0xa6, 0x34, 0xd0, + 0x1d, 0x28, 0xc7, 0xd5, 0x35, 0x64, 0x98, 0xc9, 0x14, 0x2d, 0xb7, 0x3e, 0x99, 0xb9, 0x92, 0x35, + 0x3a, 0x12, 0xbe, 0xc7, 0xd1, 0x66, 0xc9, 0x9e, 0xb2, 0xea, 0x6d, 0x28, 0x4d, 0x47, 0x51, 0x15, + 0x56, 0x8d, 0x4e, 0xdb, 0xea, 0xec, 0xb4, 0x7b, 0x3d, 0x7d, 0xd7, 0xea, 0x98, 0x7a, 0xbb, 0x6f, + 0xf4, 0x6e, 0x68, 0x0b, 0xe8, 0x1c, 0x9c, 0x79, 0x2b, 0xa2, 0x77, 0xb5, 0x54, 0xfd, 0xd7, 0x0c, + 0x14, 0x92, 0x3a, 0x87, 0x3a, 0xa0, 0xd1, 0x31, 0x09, 0xf8, 0xd8, 0x9a, 0x35, 0xcd, 0x95, 0x18, + 0xa1, 0xdc, 0xfc, 0x5e, 0xf3, 0xad, 0x46, 0xa1, 0xea, 0x6b, 0xca, 0x42, 0x7d, 0xc8, 0xdd, 0x27, + 0xee, 0xf0, 0x90, 0xcd, 0x45, 0x88, 0x8a, 0x0b, 0x0d, 0x41, 0x53, 0x1d, 0x84, 0x38, 0x16, 0xf6, + 0x44, 0xb7, 0xc8, 0xce, 0xa1, 0x1e, 0x57, 0x12, 0xd6, 0xb6, 0x20, 0x45, 0x18, 0xca, 0xe4, 0x01, + 0x4f, 0xff, 0x90, 0x58, 0x01, 0x3f, 0xc9, 0xc5, 0x39, 0xec, 0xa2, 0x14, 0x53, 0x9a, 0xfc, 0xfc, + 0x2e, 0xc3, 0xa4, 0x48, 0x5a, 0x64, 0x4c, 0xed, 0x43, 0xd1, 0x73, 0x33, 0xe6, 0x72, 0xe2, 0xd6, + 0xb9, 0xb7, 0xfe, 0x47, 0x1a, 0xf2, 0x71, 0xa3, 0x78, 0xcf, 0x43, 0xe3, 0x3a, 0xe4, 0x54, 0x46, + 0x4e, 0xd4, 0x7d, 0x96, 0x6f, 0xc3, 0x54, 0x9f, 0x73, 0x2d, 0xcb, 0xe9, 0x33, 0x62, 0x7a, 0x69, + 0x20, 0x03, 0x16, 0xa7, 0x35, 0x7c, 0xed, 0x04, 0x0d, 0xab, 0x05, 0xc6, 0xbf, 0x52, 0xc0, 0x92, + 0x01, 0x5d, 0x82, 0x8a, 0x3b, 0xb0, 0xad, 0x90, 0xdc, 0x8b, 0x88, 0x6f, 0x93, 0xc9, 0xcb, 0xa3, + 0xec, 0x0e, 0xec, 0x3d, 0xe5, 0x35, 0x9c, 0xba, 0x0d, 0xa5, 0x69, 0x38, 0x3a, 0x03, 0x95, 0xae, + 0x7e, 0xfb, 0xd6, 0x9e, 0xd1, 0xb7, 0x6e, 0xeb, 0xbd, 0xae, 0x14, 0xb7, 0x06, 0xa5, 0xd8, 0xb9, + 0xa7, 0xf7, 0xfa, 0x5a, 0x0a, 0xad, 0x82, 0x16, 0x7b, 0x4c, 0xbd, 0xa3, 0x1b, 0x07, 0x7a, 0x57, + 0x4b, 0xa3, 0xb3, 0x80, 0x62, 0x6f, 0x57, 0xdf, 0xd5, 0x6f, 0xc8, 0xcb, 0x91, 0xa9, 0xff, 0x92, + 0x85, 0xc2, 0x7e, 0x9c, 0xe0, 0xf7, 0xe5, 0xf3, 0x43, 0x28, 0x89, 0x4c, 0x58, 0x7e, 0xe4, 0x0d, + 0x48, 0x20, 0xb2, 0x9a, 0x31, 0x8b, 0xc2, 0xd7, 0x13, 0x2e, 0xa4, 0x43, 0xd1, 0xc3, 0x2c, 0x0a, + 0x88, 0xc5, 0x9f, 0x87, 0xea, 0xed, 0x76, 0xa1, 0x21, 0xdf, 0x8e, 0x8d, 0xf8, 0xed, 0xd8, 0xe8, + 0xc7, 0x6f, 0xc7, 0xad, 0x25, 0x9e, 0xf8, 0x47, 0x2f, 0xd6, 0x52, 0x26, 0x48, 0x20, 0x0f, 0xa1, + 0x2f, 0xa0, 0x38, 0x88, 0x02, 0x7f, 0x5a, 0xd0, 0x33, 0x1c, 0x1f, 0x70, 0x8c, 0x92, 0x6b, 0x17, + 0xca, 0x52, 0x34, 0x31, 0xc7, 0xe2, 0x6c, 0x1c, 0x25, 0x89, 0x52, 0x2c, 0xef, 0x38, 0xa7, 0xdc, + 0x3b, 0xce, 0x09, 0xdd, 0x8c, 0xa5, 0x91, 0x17, 0xd2, 0xb8, 0x7e, 0x82, 0x34, 0x92, 0x6c, 0x4f, + 0x46, 0xd3, 0xf2, 0xa8, 0xff, 0x98, 0x82, 0xe5, 0xd7, 0x23, 0xe8, 0x03, 0x58, 0xd9, 0xef, 0x6d, + 0xdd, 0x12, 0x67, 0x3e, 0x75, 0xf6, 0xe7, 0xe0, 0xcc, 0xc4, 0x6d, 0xf4, 0x8c, 0xbe, 0x21, 0x0b, + 0x1b, 0x3f, 0xec, 0x49, 0xe0, 0x66, 0xbb, 0xbf, 0x6f, 0x72, 0x40, 0xfa, 0x75, 0x1e, 0xe1, 0xd7, + 0xbb, 0x5a, 0xe6, 0x75, 0x9e, 0xce, 0x6e, 0xdb, 0xb8, 0xd9, 0xde, 0xda, 0xd5, 0xb5, 0x2c, 0x97, + 0xd2, 0x24, 0xb0, 0xdd, 0x36, 0x76, 0xf5, 0xae, 0xb6, 0x58, 0xff, 0x2e, 0x0d, 0xe5, 0xfd, 0x90, + 0x04, 0xf3, 0x92, 0xcd, 0x54, 0x5b, 0xcb, 0xcc, 0xda, 0xd6, 0x3e, 0x07, 0x08, 0xd9, 0xd1, 0x29, + 0x25, 0x52, 0x08, 0xd9, 0xd1, 0x3c, 0x15, 0x52, 0xff, 0x3d, 0x0d, 0x28, 0x69, 0x20, 0xff, 0xb3, + 0x5b, 0xa4, 0xc3, 0x4a, 0xf2, 0x70, 0x4f, 0xfa, 0x59, 0xf6, 0x84, 0xfc, 0x6a, 0x09, 0x24, 0x6e, + 0x68, 0x93, 0x32, 0xba, 0x78, 0xba, 0x32, 0x3a, 0xe3, 0xed, 0xa9, 0xb7, 0x60, 0xe9, 0xcb, 0x83, + 0xfd, 0xb1, 0xc3, 0x75, 0xae, 0x41, 0xe6, 0x88, 0x3c, 0x54, 0x39, 0xe3, 0x43, 0x5e, 0x8c, 0xe5, + 0x5b, 0x5d, 0xb6, 0x53, 0x69, 0x6c, 0xdd, 0x79, 0xf2, 0xb2, 0x96, 0x7a, 0xfa, 0xb2, 0x96, 0xfa, + 0xe7, 0x65, 0x2d, 0xf5, 0xe8, 0x55, 0x6d, 0xe1, 0xe9, 0xab, 0xda, 0xc2, 0x9f, 0xaf, 0x6a, 0x0b, + 0x5f, 0xb7, 0xa7, 0x3a, 0xd1, 0x98, 0x04, 0xa1, 0x1b, 0x32, 0x3e, 0xcf, 0x2d, 0x9f, 0x34, 0xe5, + 0xad, 0xdc, 0xf4, 0x31, 0x7f, 0x68, 0x37, 0x8f, 0x5b, 0xcd, 0x07, 0x6f, 0xfe, 0xe5, 0x16, 0x8d, + 0x6a, 0x90, 0x13, 0x29, 0xbe, 0xf6, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x6d, 0x74, 0x98, 0xcc, + 0x98, 0x0f, 0x00, 0x00, } func (m *HostChain) Marshal() (dAtA []byte, err error) { @@ -1344,16 +1351,11 @@ func (m *Deposit) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x20 } - { - size := m.Epoch.Size() - i -= size - if _, err := m.Epoch.MarshalTo(dAtA[i:]); err != nil { - return 0, err - } - i = encodeVarintLiquidstakeibc(dAtA, i, uint64(size)) + if m.Epoch != 0 { + i = encodeVarintLiquidstakeibc(dAtA, i, uint64(m.Epoch)) + i-- + dAtA[i] = 0x18 } - i-- - dAtA[i] = 0x1a { size, err := m.Amount.MarshalToSizedBuffer(dAtA[:i]) if err != nil { @@ -1764,8 +1766,9 @@ func (m *Deposit) Size() (n int) { } l = m.Amount.Size() n += 1 + l + sovLiquidstakeibc(uint64(l)) - l = m.Epoch.Size() - n += 1 + l + sovLiquidstakeibc(uint64(l)) + if m.Epoch != 0 { + n += 1 + sovLiquidstakeibc(uint64(m.Epoch)) + } if m.State != 0 { n += 1 + sovLiquidstakeibc(uint64(m.State)) } @@ -3089,10 +3092,10 @@ func (m *Deposit) Unmarshal(dAtA []byte) error { } iNdEx = postIndex case 3: - if wireType != 2 { + if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field Epoch", wireType) } - var stringLen uint64 + m.Epoch = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowLiquidstakeibc @@ -3102,26 +3105,11 @@ func (m *Deposit) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + m.Epoch |= int64(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthLiquidstakeibc - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthLiquidstakeibc - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.Epoch.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex case 4: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field State", wireType) diff --git a/x/lscosmos/keeper/migrate_module.go b/x/lscosmos/keeper/migrate_module.go index 5dea36981..1d0297726 100644 --- a/x/lscosmos/keeper/migrate_module.go +++ b/x/lscosmos/keeper/migrate_module.go @@ -190,7 +190,7 @@ func (k Keeper) Migrate(ctx sdk.Context) error { k.liquidStakeIBCKeeper.SetDeposit(ctx, &liquidstakeibctypes.Deposit{ ChainId: newhc.ChainId, Amount: sdk.NewCoin(newhc.IBCDenom(), depositAccBalance.AmountOf(newhc.IBCDenom())), - Epoch: sdk.NewInt(currEpoch.CurrentEpoch), + Epoch: currEpoch.CurrentEpoch, State: liquidstakeibctypes.Deposit_DEPOSIT_PENDING, IbcSequenceId: "", }) From b70f9f8b24536eb120089638601fb09de8cc3cac Mon Sep 17 00:00:00 2001 From: Puneet <59960662+puneet2019@users.noreply.github.com> Date: Mon, 10 Jul 2023 13:50:09 +0530 Subject: [PATCH 007/100] test types/ genesis.go (#558) * test types/ genesis.go * fix test with latest int64 epoch * fix imports --- x/liquidstakeibc/types/genesis.go | 14 ++--- x/liquidstakeibc/types/genesis_test.go | 80 ++++++++++++++++++++++++++ 2 files changed, 87 insertions(+), 7 deletions(-) diff --git a/x/liquidstakeibc/types/genesis.go b/x/liquidstakeibc/types/genesis.go index 527a423c2..f991aa06f 100644 --- a/x/liquidstakeibc/types/genesis.go +++ b/x/liquidstakeibc/types/genesis.go @@ -31,12 +31,12 @@ func (gs *GenesisState) Validate() error { if !ok { return fmt.Errorf("deposit for chain %s doesnt have a valid chain id", deposit.ChainId) } - if hc.HostDenom != deposit.Amount.Denom { + if hc.IBCDenom() != deposit.Amount.Denom { return fmt.Errorf( "deposit for chain %s doesnt have the correct host chain denom: %s, should be %s", deposit.ChainId, deposit.Amount.Denom, - hc.HostDenom, + hc.IBCDenom(), ) } } @@ -45,7 +45,7 @@ func (gs *GenesisState) Validate() error { if !ok { return fmt.Errorf("unbonding for chain %s doesnt have a valid chain id", unbonding.ChainId) } - if hc.MintDenom() == unbonding.BurnAmount.Denom { + if hc.MintDenom() != unbonding.BurnAmount.Denom { return fmt.Errorf( "unbonding for chain %s doesnt have the correct burn amount denom: %s, should be %s", hc.ChainId, @@ -53,7 +53,7 @@ func (gs *GenesisState) Validate() error { hc.MintDenom(), ) } - if hc.HostDenom == unbonding.UnbondAmount.Denom { + if hc.HostDenom != unbonding.UnbondAmount.Denom { return fmt.Errorf( "unbonding for chain %s doesnt have the correct host chain denom: %s, should be %s", hc.ChainId, @@ -70,7 +70,7 @@ func (gs *GenesisState) Validate() error { if !ok { return fmt.Errorf("user unbonding for chain %s doesnt have a valid chain id", userUnbonding.ChainId) } - if hc.MintDenom() == userUnbonding.StkAmount.Denom { + if hc.MintDenom() != userUnbonding.StkAmount.Denom { return fmt.Errorf( "user unbonding for chain %s doesnt have the correct mint amount denom: %s, should be %s", hc.ChainId, @@ -78,7 +78,7 @@ func (gs *GenesisState) Validate() error { hc.MintDenom(), ) } - if hc.HostDenom == userUnbonding.UnbondAmount.Denom { + if hc.HostDenom != userUnbonding.UnbondAmount.Denom { return fmt.Errorf( "user unbonding for chain %s doesnt have the correct host chain denom: %s, should be %s", hc.ChainId, @@ -95,7 +95,7 @@ func (gs *GenesisState) Validate() error { if !ok { return fmt.Errorf("validator unbonding for chain %s doesnt have a valid chain id", valUnbonding.ChainId) } - if hc.HostDenom == valUnbonding.Amount.Denom { + if hc.HostDenom != valUnbonding.Amount.Denom { return fmt.Errorf( "validator unbonding for chain %s doesnt have the correct host chain denom: %s, should be %s", hc.ChainId, diff --git a/x/liquidstakeibc/types/genesis_test.go b/x/liquidstakeibc/types/genesis_test.go index 286483f05..f0fee22b2 100644 --- a/x/liquidstakeibc/types/genesis_test.go +++ b/x/liquidstakeibc/types/genesis_test.go @@ -2,7 +2,11 @@ package types_test import ( "testing" + "time" + sdk "github.com/cosmos/cosmos-sdk/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/stretchr/testify/require" "github.com/persistenceOne/pstake-native/v2/x/liquidstakeibc/types" @@ -23,6 +27,82 @@ func TestGenesisState_Validate(t *testing.T) { desc: "invalid genesis state, params not set", genState: &types.GenesisState{}, valid: false, + }, { + desc: "Valid State with all fields present", + genState: &types.GenesisState{ + Params: types.DefaultParams(), + HostChains: []*types.HostChain{{ + ChainId: "chainA-1", + ConnectionId: "connection-1", + Params: &types.HostChainLSParams{ + DepositFee: sdk.ZeroDec(), + RestakeFee: sdk.ZeroDec(), + UnstakeFee: sdk.ZeroDec(), + RedemptionFee: sdk.ZeroDec(), + }, + HostDenom: "uatom", + ChannelId: "channel-1", + PortId: "transfer", + DelegationAccount: &types.ICAAccount{ + Address: "", + Balance: sdk.Coin{}, + Owner: "", + ChannelState: 0, + }, + RewardsAccount: &types.ICAAccount{ + Address: "", + Balance: sdk.Coin{}, + Owner: "", + ChannelState: 0, + }, + Validators: []*types.Validator{{ + OperatorAddress: "", + Status: stakingtypes.BondStatusBonded, + Weight: sdk.OneDec(), + DelegatedAmount: sdk.NewInt(1221), + ExchangeRate: sdk.Dec{}, + UnbondingEpoch: 0, + }}, + MinimumDeposit: sdk.OneInt(), + CValue: sdk.OneDec(), + LastCValue: sdk.Dec{}, + UnbondingFactor: 0, + Active: false, + AutoCompoundFactor: sdk.Dec{}, + }}, + Deposits: []*types.Deposit{{ + ChainId: "chainA-1", + Amount: sdk.NewInt64Coin("ibc/C4CFF46FD6DE35CA4CF4CE031E643C8FDC9BA4B99AE598E9B0ED98FE3A2319F9", 100), + Epoch: 0, + State: 0, + IbcSequenceId: "", + }}, + Unbondings: []*types.Unbonding{{ + ChainId: "chainA-1", + EpochNumber: 0, + MatureTime: time.Time{}, + BurnAmount: sdk.NewInt64Coin("stk/uatom", 10), + UnbondAmount: sdk.NewInt64Coin("uatom", 10), + IbcSequenceId: "", + State: 0, + }}, + UserUnbondings: []*types.UserUnbonding{{ + ChainId: "chainA-1", + EpochNumber: 0, + Address: authtypes.NewModuleAddressOrBech32Address("test").String(), + StkAmount: sdk.NewInt64Coin("stk/uatom", 10), + UnbondAmount: sdk.NewInt64Coin("uatom", 10), + }}, + ValidatorUnbondings: []*types.ValidatorUnbonding{{ + ChainId: "chainA-1", + EpochNumber: 0, + MatureTime: time.Time{}, + ValidatorAddress: authtypes.NewModuleAddressOrBech32Address("testval").String(), + Amount: sdk.NewInt64Coin("uatom", 1000), + IbcSequenceId: "", + }}, + }, + valid: true, }, } { t.Run(tc.desc, func(t *testing.T) { From 067ac6c80acf79ab9485558c6eb0a68870168c28 Mon Sep 17 00:00:00 2001 From: Puneet <59960662+puneet2019@users.noreply.github.com> Date: Mon, 10 Jul 2023 15:39:15 +0530 Subject: [PATCH 008/100] add genesis tests (#561) --- x/liquidstakeibc/genesis_test.go | 78 ++++- x/liquidstakeibc/types/genesis_test.go | 358 ++++++++++++++++++----- x/liquidstakeibc/types/liquidstakeibc.go | 12 + 3 files changed, 376 insertions(+), 72 deletions(-) diff --git a/x/liquidstakeibc/genesis_test.go b/x/liquidstakeibc/genesis_test.go index 969376171..8f3e35f05 100644 --- a/x/liquidstakeibc/genesis_test.go +++ b/x/liquidstakeibc/genesis_test.go @@ -2,7 +2,11 @@ package liquidstakeibc_test import ( "testing" + "time" + sdk "github.com/cosmos/cosmos-sdk/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/stretchr/testify/require" "github.com/persistenceOne/pstake-native/v2/app/helpers" @@ -12,9 +16,77 @@ import ( func TestGenesis(t *testing.T) { genesisState := &types.GenesisState{ - Params: types.DefaultParams(), - HostChains: make([]*types.HostChain, 0), - Deposits: make([]*types.Deposit, 0), + Params: types.DefaultParams(), + HostChains: []*types.HostChain{{ + ChainId: "chainA-1", + ConnectionId: "connection-1", + Params: &types.HostChainLSParams{ + DepositFee: sdk.ZeroDec(), + RestakeFee: sdk.ZeroDec(), + UnstakeFee: sdk.ZeroDec(), + RedemptionFee: sdk.ZeroDec(), + }, + HostDenom: "uatom", + ChannelId: "channel-1", + PortId: "transfer", + DelegationAccount: &types.ICAAccount{ + Address: "", + Balance: sdk.Coin{}, + Owner: "", + ChannelState: 0, + }, + RewardsAccount: &types.ICAAccount{ + Address: "", + Balance: sdk.Coin{}, + Owner: "", + ChannelState: 0, + }, + Validators: []*types.Validator{{ + OperatorAddress: "", + Status: stakingtypes.BondStatusBonded, + Weight: sdk.OneDec(), + DelegatedAmount: sdk.NewInt(1221), + ExchangeRate: sdk.OneDec(), + UnbondingEpoch: 0, + }}, + MinimumDeposit: sdk.OneInt(), + CValue: sdk.OneDec(), + LastCValue: sdk.OneDec(), + UnbondingFactor: 0, + Active: false, + AutoCompoundFactor: sdk.MustNewDecFromStr("2"), + }}, + Deposits: []*types.Deposit{{ + ChainId: "chainA-1", + Amount: sdk.NewInt64Coin("ibc/C4CFF46FD6DE35CA4CF4CE031E643C8FDC9BA4B99AE598E9B0ED98FE3A2319F9", 100), + Epoch: 0, + State: 0, + IbcSequenceId: "", + }}, + Unbondings: []*types.Unbonding{{ + ChainId: "chainA-1", + EpochNumber: 0, + MatureTime: time.Time{}, + BurnAmount: sdk.NewInt64Coin("stk/uatom", 10), + UnbondAmount: sdk.NewInt64Coin("uatom", 10), + IbcSequenceId: "", + State: 0, + }}, + UserUnbondings: []*types.UserUnbonding{{ + ChainId: "chainA-1", + EpochNumber: 0, + Address: authtypes.NewModuleAddressOrBech32Address("test").String(), + StkAmount: sdk.NewInt64Coin("stk/uatom", 10), + UnbondAmount: sdk.NewInt64Coin("uatom", 10), + }}, + ValidatorUnbondings: []*types.ValidatorUnbonding{{ + ChainId: "chainA-1", + EpochNumber: 0, + MatureTime: time.Time{}, + ValidatorAddress: authtypes.NewModuleAddressOrBech32Address("testval").String(), + Amount: sdk.NewInt64Coin("uatom", 1000), + IbcSequenceId: "", + }}, } _, pStakeApp, ctx := helpers.CreateTestApp(t) diff --git a/x/liquidstakeibc/types/genesis_test.go b/x/liquidstakeibc/types/genesis_test.go index f0fee22b2..52f87e61c 100644 --- a/x/liquidstakeibc/types/genesis_test.go +++ b/x/liquidstakeibc/types/genesis_test.go @@ -15,98 +15,242 @@ import ( func TestGenesisState_Validate(t *testing.T) { for _, tc := range []struct { desc string - genState *types.GenesisState + genState func() *types.GenesisState valid bool }{ { desc: "default is valid", - genState: types.DefaultGenesisState(), + genState: func() *types.GenesisState { return types.DefaultGenesisState() }, valid: true, }, { desc: "invalid genesis state, params not set", - genState: &types.GenesisState{}, + genState: func() *types.GenesisState { return &types.GenesisState{} }, valid: false, - }, { - desc: "Valid State with all fields present", - genState: &types.GenesisState{ - Params: types.DefaultParams(), - HostChains: []*types.HostChain{{ - ChainId: "chainA-1", - ConnectionId: "connection-1", - Params: &types.HostChainLSParams{ - DepositFee: sdk.ZeroDec(), - RestakeFee: sdk.ZeroDec(), - UnstakeFee: sdk.ZeroDec(), - RedemptionFee: sdk.ZeroDec(), - }, - HostDenom: "uatom", - ChannelId: "channel-1", - PortId: "transfer", - DelegationAccount: &types.ICAAccount{ - Address: "", - Balance: sdk.Coin{}, - Owner: "", - ChannelState: 0, - }, - RewardsAccount: &types.ICAAccount{ - Address: "", - Balance: sdk.Coin{}, - Owner: "", - ChannelState: 0, - }, - Validators: []*types.Validator{{ - OperatorAddress: "", - Status: stakingtypes.BondStatusBonded, - Weight: sdk.OneDec(), - DelegatedAmount: sdk.NewInt(1221), - ExchangeRate: sdk.Dec{}, - UnbondingEpoch: 0, - }}, - MinimumDeposit: sdk.OneInt(), - CValue: sdk.OneDec(), - LastCValue: sdk.Dec{}, - UnbondingFactor: 0, - Active: false, - AutoCompoundFactor: sdk.Dec{}, - }}, - Deposits: []*types.Deposit{{ + }, + { + desc: "Valid State with all fields present", + genState: func() *types.GenesisState { return ValidGenesis() }, + valid: true, + }, + { + desc: "Multiple host chains with same chain-id", + genState: func() *types.GenesisState { + genesis := ValidGenesis() + genesis.HostChains = append(genesis.HostChains, &types.HostChain{ChainId: "chainA-1"}) + return genesis + }, + valid: false, + }, + { + desc: "host chains invalid", + genState: func() *types.GenesisState { + genesis := ValidGenesis() + genesis.HostChains[0].CValue = sdk.MustNewDecFromStr("1.1") + return genesis + }, + valid: false, + }, + { + desc: "deposits of non existant chain-id", + genState: func() *types.GenesisState { + genesis := ValidGenesis() + genesis.Deposits = append(genesis.Deposits, &types.Deposit{ + ChainId: "nonExistent-1", + Amount: sdk.NewInt64Coin("ibc/C4CFF46FD6DE35CA4CF4CE031E643C8FDC9BA4B99AE598E9B0ED98FE3A2319F9", 100), + Epoch: 0, + State: 0, + IbcSequenceId: ""}) + return genesis + }, + valid: false, + }, + { + desc: "invalid deposit", + genState: func() *types.GenesisState { + genesis := ValidGenesis() + genesis.Deposits = append(genesis.Deposits, &types.Deposit{ ChainId: "chainA-1", Amount: sdk.NewInt64Coin("ibc/C4CFF46FD6DE35CA4CF4CE031E643C8FDC9BA4B99AE598E9B0ED98FE3A2319F9", 100), Epoch: 0, + State: 4, + IbcSequenceId: ""}) + return genesis + }, + valid: false, + }, { + desc: "invalid amount denom", + genState: func() *types.GenesisState { + genesis := ValidGenesis() + genesis.Deposits = append(genesis.Deposits, &types.Deposit{ + ChainId: "chainA-1", + Amount: sdk.NewInt64Coin("uatom", 100), + Epoch: 0, State: 0, + IbcSequenceId: ""}) + return genesis + }, + valid: false, + }, + { + desc: "unbondings of non existant chain-id", + genState: func() *types.GenesisState { + genesis := ValidGenesis() + genesis.Unbondings = append(genesis.Unbondings, &types.Unbonding{ChainId: "nonExistent-1"}) + return genesis + }, + valid: false, + }, + { + desc: "invalid BurnAmount", + genState: func() *types.GenesisState { + genesis := ValidGenesis() + genesis.Unbondings = append(genesis.Unbondings, &types.Unbonding{ + ChainId: "chainA-1", + EpochNumber: 0, + MatureTime: time.Time{}, + BurnAmount: sdk.NewInt64Coin("ibc/uatom", 10), + UnbondAmount: sdk.NewInt64Coin("uatom", 10), IbcSequenceId: "", - }}, - Unbondings: []*types.Unbonding{{ + State: 0, + }) + return genesis + }, + valid: false, + }, { + desc: "invalid unbound amount", + genState: func() *types.GenesisState { + genesis := ValidGenesis() + genesis.Unbondings = append(genesis.Unbondings, &types.Unbonding{ ChainId: "chainA-1", EpochNumber: 0, MatureTime: time.Time{}, BurnAmount: sdk.NewInt64Coin("stk/uatom", 10), - UnbondAmount: sdk.NewInt64Coin("uatom", 10), + UnbondAmount: sdk.NewInt64Coin("ibc/C4CFF46FD6DE35CA4CF4CE031E643C8FDC9BA4B99AE598E9B0ED98FE3A2319F9", 10), IbcSequenceId: "", State: 0, - }}, - UserUnbondings: []*types.UserUnbonding{{ - ChainId: "chainA-1", - EpochNumber: 0, - Address: authtypes.NewModuleAddressOrBech32Address("test").String(), - StkAmount: sdk.NewInt64Coin("stk/uatom", 10), - UnbondAmount: sdk.NewInt64Coin("uatom", 10), - }}, - ValidatorUnbondings: []*types.ValidatorUnbonding{{ - ChainId: "chainA-1", - EpochNumber: 0, - MatureTime: time.Time{}, - ValidatorAddress: authtypes.NewModuleAddressOrBech32Address("testval").String(), - Amount: sdk.NewInt64Coin("uatom", 1000), - IbcSequenceId: "", - }}, - }, - valid: true, + }) + return genesis + }, + valid: false, + }, { + desc: "invalid unbonding state", + genState: func() *types.GenesisState { + genesis := ValidGenesis() + genesis.Unbondings = append(genesis.Unbondings, &types.Unbonding{ + ChainId: "chainA-1", + EpochNumber: 0, + MatureTime: time.Time{}, + BurnAmount: sdk.NewInt64Coin("stk/uatom", 0), + UnbondAmount: sdk.NewInt64Coin("uatom", 0), + IbcSequenceId: "", + State: 6, + }) + return genesis + }, + valid: false, + }, + { + desc: "user unbondings of non existent chain-id", + genState: func() *types.GenesisState { + genesis := ValidGenesis() + genesis.UserUnbondings = append(genesis.UserUnbondings, &types.UserUnbonding{ChainId: "nonExistent-1"}) + return genesis + }, + valid: false, + }, + { + desc: "user unbondings incorrect stkamount denom", + genState: func() *types.GenesisState { + genesis := ValidGenesis() + genesis.UserUnbondings = append(genesis.UserUnbondings, + &types.UserUnbonding{ + ChainId: "chainA-1", + EpochNumber: 0, + Address: authtypes.NewModuleAddressOrBech32Address("test2").String(), + StkAmount: sdk.NewInt64Coin("uatom", 10), + UnbondAmount: sdk.NewInt64Coin("uatom", 10), + }) + return genesis + }, + valid: false, + }, { + desc: "user unbondings incorrect unboundAmount denom", + genState: func() *types.GenesisState { + genesis := ValidGenesis() + genesis.UserUnbondings = append(genesis.UserUnbondings, + &types.UserUnbonding{ + ChainId: "chainA-1", + EpochNumber: 0, + Address: authtypes.NewModuleAddressOrBech32Address("test2").String(), + StkAmount: sdk.NewInt64Coin("stk/uatom", 10), + UnbondAmount: sdk.NewInt64Coin("ibc/C4CFF46FD6DE35CA4CF4CE031E643C8FDC9BA4B99AE598E9B0ED98FE3A2319F9", 10), + }) + return genesis + }, + valid: false, + }, { + desc: "user unbondings invalid", + genState: func() *types.GenesisState { + genesis := ValidGenesis() + genesis.UserUnbondings = append(genesis.UserUnbondings, + &types.UserUnbonding{ + ChainId: "chainA-1", + EpochNumber: 0, + Address: "", + StkAmount: sdk.NewInt64Coin("stk/uatom", 10), + UnbondAmount: sdk.NewInt64Coin("uatom", 10), + }) + return genesis + }, + valid: false, + }, + { + desc: "validator unbonding of non existent chain-id", + genState: func() *types.GenesisState { + genesis := ValidGenesis() + genesis.ValidatorUnbondings = append(genesis.ValidatorUnbondings, &types.ValidatorUnbonding{ChainId: "nonExistent-1"}) + return genesis + }, + valid: false, + }, + { + desc: "validator unbonding incorrect amount denom", + genState: func() *types.GenesisState { + genesis := ValidGenesis() + genesis.ValidatorUnbondings = append(genesis.ValidatorUnbondings, + &types.ValidatorUnbonding{ + ChainId: "chainA-1", + EpochNumber: 0, + MatureTime: time.Time{}, + ValidatorAddress: authtypes.NewModuleAddressOrBech32Address("testval2").String(), + Amount: sdk.NewInt64Coin("ibc/C4CFF46FD6DE35CA4CF4CE031E643C8FDC9BA4B99AE598E9B0ED98FE3A2319F9", 1000), + IbcSequenceId: "", + }) + return genesis + }, + valid: false, + }, + { + desc: "validator unbonding invalid", + genState: func() *types.GenesisState { + genesis := ValidGenesis() + genesis.ValidatorUnbondings = append(genesis.ValidatorUnbondings, + &types.ValidatorUnbonding{ + ChainId: "chainA-1", + EpochNumber: 0, + MatureTime: time.Time{}, + ValidatorAddress: "", + Amount: sdk.NewInt64Coin("uatom", 1000), + IbcSequenceId: "", + }) + return genesis + }, + valid: false, }, } { t.Run(tc.desc, func(t *testing.T) { - err := tc.genState.Validate() + err := tc.genState().Validate() if tc.valid { require.NoError(t, err) } else { @@ -115,3 +259,79 @@ func TestGenesisState_Validate(t *testing.T) { }) } } + +func ValidGenesis() *types.GenesisState { + return &types.GenesisState{ + Params: types.DefaultParams(), + HostChains: []*types.HostChain{{ + ChainId: "chainA-1", + ConnectionId: "connection-1", + Params: &types.HostChainLSParams{ + DepositFee: sdk.ZeroDec(), + RestakeFee: sdk.ZeroDec(), + UnstakeFee: sdk.ZeroDec(), + RedemptionFee: sdk.ZeroDec(), + }, + HostDenom: "uatom", + ChannelId: "channel-1", + PortId: "transfer", + DelegationAccount: &types.ICAAccount{ + Address: "", + Balance: sdk.Coin{}, + Owner: "", + ChannelState: 0, + }, + RewardsAccount: &types.ICAAccount{ + Address: "", + Balance: sdk.Coin{}, + Owner: "", + ChannelState: 0, + }, + Validators: []*types.Validator{{ + OperatorAddress: "", + Status: stakingtypes.BondStatusBonded, + Weight: sdk.OneDec(), + DelegatedAmount: sdk.NewInt(1221), + ExchangeRate: sdk.Dec{}, + UnbondingEpoch: 0, + }}, + MinimumDeposit: sdk.OneInt(), + CValue: sdk.OneDec(), + LastCValue: sdk.Dec{}, + UnbondingFactor: 0, + Active: false, + AutoCompoundFactor: sdk.Dec{}, + }}, + Deposits: []*types.Deposit{{ + ChainId: "chainA-1", + Amount: sdk.NewInt64Coin("ibc/C4CFF46FD6DE35CA4CF4CE031E643C8FDC9BA4B99AE598E9B0ED98FE3A2319F9", 100), + Epoch: 0, + State: 0, + IbcSequenceId: "", + }}, + Unbondings: []*types.Unbonding{{ + ChainId: "chainA-1", + EpochNumber: 0, + MatureTime: time.Time{}, + BurnAmount: sdk.NewInt64Coin("stk/uatom", 10), + UnbondAmount: sdk.NewInt64Coin("uatom", 10), + IbcSequenceId: "", + State: 0, + }}, + UserUnbondings: []*types.UserUnbonding{{ + ChainId: "chainA-1", + EpochNumber: 0, + Address: authtypes.NewModuleAddressOrBech32Address("test").String(), + StkAmount: sdk.NewInt64Coin("stk/uatom", 10), + UnbondAmount: sdk.NewInt64Coin("uatom", 10), + }}, + ValidatorUnbondings: []*types.ValidatorUnbonding{{ + ChainId: "chainA-1", + EpochNumber: 0, + MatureTime: time.Time{}, + ValidatorAddress: authtypes.NewModuleAddressOrBech32Address("testval").String(), + Amount: sdk.NewInt64Coin("uatom", 1000), + IbcSequenceId: "", + }}, + } +} diff --git a/x/liquidstakeibc/types/liquidstakeibc.go b/x/liquidstakeibc/types/liquidstakeibc.go index 09b2194d1..6081a4555 100644 --- a/x/liquidstakeibc/types/liquidstakeibc.go +++ b/x/liquidstakeibc/types/liquidstakeibc.go @@ -111,6 +111,18 @@ func (u *Unbonding) Validate() error { if u.UnbondAmount.IsNegative() { return fmt.Errorf("unbonding entry %s has negative unbond amount: %s", u.String(), u.UnbondAmount) } + if u.State != Unbonding_UNBONDING_PENDING && + u.State != Unbonding_UNBONDING_INITIATED && + u.State != Unbonding_UNBONDING_MATURING && + u.State != Unbonding_UNBONDING_MATURED && + u.State != Unbonding_UNBONDING_CLAIMABLE && + u.State != Unbonding_UNBONDING_FAILED { + return fmt.Errorf( + "host chain %s unbonding has an invalid state: %s", + u.ChainId, + u.State, + ) + } return nil } From d7ee4406d90628baa0776e3a44942352738391e2 Mon Sep 17 00:00:00 2001 From: Marc Puig Date: Mon, 10 Jul 2023 14:55:34 +0200 Subject: [PATCH 009/100] [Liquidstakeibc] Telemetry (#562) * telemetry * remove amount metrics --- x/liquidstakeibc/keeper/hooks.go | 3 +++ x/liquidstakeibc/keeper/keeper.go | 10 ++++++++++ x/liquidstakeibc/keeper/msg_server.go | 16 ++++++++++++++++ x/liquidstakeibc/keeper/unbonding.go | 3 +++ x/liquidstakeibc/keeper/validator_unbonding.go | 3 +++ 5 files changed, 35 insertions(+) diff --git a/x/liquidstakeibc/keeper/hooks.go b/x/liquidstakeibc/keeper/hooks.go index 65c603e88..e87b334c2 100644 --- a/x/liquidstakeibc/keeper/hooks.go +++ b/x/liquidstakeibc/keeper/hooks.go @@ -5,6 +5,7 @@ import ( "time" errorsmod "cosmossdk.io/errors" + "github.com/cosmos/cosmos-sdk/telemetry" sdk "github.com/cosmos/cosmos-sdk/types" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" distributiontypes "github.com/cosmos/cosmos-sdk/x/distribution/types" @@ -605,6 +606,8 @@ func (k *Keeper) ValidatorUndelegationWorkflow(ctx sdk.Context, epoch int64) { // redistribute the unbonding validator weight among all the other validators with weight k.RedistributeValidatorWeight(ctx, hc, validator) + telemetry.IncrCounter(float32(1), hc.ChainId, "validator_unbondings") + k.Logger(ctx).Info( "Started total validator unbonding.", "host_chain", diff --git a/x/liquidstakeibc/keeper/keeper.go b/x/liquidstakeibc/keeper/keeper.go index e4d28e646..5e4741ec1 100644 --- a/x/liquidstakeibc/keeper/keeper.go +++ b/x/liquidstakeibc/keeper/keeper.go @@ -7,6 +7,7 @@ import ( "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/codec" storetypes "github.com/cosmos/cosmos-sdk/store/types" + "github.com/cosmos/cosmos-sdk/telemetry" sdk "github.com/cosmos/cosmos-sdk/types" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" distributiontypes "github.com/cosmos/cosmos-sdk/x/distribution/types" @@ -296,11 +297,20 @@ func (k *Keeper) UpdateCValues(ctx sdk.Context) { hc.CValue = cValue k.SetHostChain(ctx, hc) + defer func() { + cValueFloat, _ := hc.CValue.Float64() + telemetry.ModuleSetGauge(types.ModuleName, float32(cValueFloat), hc.ChainId, "c_value") + }() + // if the c value is out of bounds, disable the chain if !k.CValueWithinLimits(ctx, hc) { hc.Active = false k.SetHostChain(ctx, hc) + defer func() { + telemetry.ModuleSetGauge(types.ModuleName, float32(0), hc.ChainId, "active") + }() + k.Logger(ctx).Error(fmt.Sprintf("C value out of limits !!! Disabling chain %s with c value %v.", hc.ChainId, hc.CValue)) ctx.EventManager().EmitEvent( sdk.NewEvent( diff --git a/x/liquidstakeibc/keeper/msg_server.go b/x/liquidstakeibc/keeper/msg_server.go index 920812a14..6ab0256b6 100644 --- a/x/liquidstakeibc/keeper/msg_server.go +++ b/x/liquidstakeibc/keeper/msg_server.go @@ -8,6 +8,7 @@ import ( "strings" errorsmod "cosmossdk.io/errors" + "github.com/cosmos/cosmos-sdk/telemetry" sdktypes "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" @@ -266,6 +267,14 @@ func (k msgServer) UpdateHostChain( k.SetHostChain(ctx, hc) + defer func() { + if hc.Active { + telemetry.ModuleSetGauge(types.ModuleName, float32(1), hc.ChainId, "active") + } else { + telemetry.ModuleSetGauge(types.ModuleName, float32(0), hc.ChainId, "active") + } + }() + return &types.MsgUpdateHostChainResponse{}, nil } @@ -397,6 +406,9 @@ func (k msgServer) LiquidStake( sdktypes.NewAttribute(sdktypes.AttributeKeySender, msg.DelegatorAddress), )}, ) + + telemetry.IncrCounter(float32(1), hostChain.ChainId, "liquid_stake") + return &types.MsgLiquidStakeResponse{}, nil } @@ -514,6 +526,8 @@ func (k msgServer) LiquidUnstake( )}, ) + telemetry.IncrCounter(float32(1), hc.ChainId, "liquid_unstake") + return &types.MsgLiquidUnstakeResponse{}, nil } @@ -673,6 +687,8 @@ func (k msgServer) Redeem( )}, ) + telemetry.IncrCounter(float32(1), hc.ChainId, "redeem") + return &types.MsgRedeemResponse{}, nil } diff --git a/x/liquidstakeibc/keeper/unbonding.go b/x/liquidstakeibc/keeper/unbonding.go index 587ac8a0d..00ca2b0ad 100644 --- a/x/liquidstakeibc/keeper/unbonding.go +++ b/x/liquidstakeibc/keeper/unbonding.go @@ -4,6 +4,7 @@ import ( "time" "github.com/cosmos/cosmos-sdk/store/prefix" + "github.com/cosmos/cosmos-sdk/telemetry" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/persistenceOne/pstake-native/v2/x/liquidstakeibc/types" @@ -67,6 +68,8 @@ func (k *Keeper) IncreaseUndelegatingAmountForEpoch( IbcSequenceId: "", State: types.Unbonding_UNBONDING_PENDING, } + + telemetry.ModuleSetGauge(types.ModuleName, float32(epochNumber), chainID, "unbonding_epoch") } else { unbonding.UnbondAmount = unbonding.UnbondAmount.Add(unbondAmount) unbonding.BurnAmount = unbonding.BurnAmount.Add(burnAmount) diff --git a/x/liquidstakeibc/keeper/validator_unbonding.go b/x/liquidstakeibc/keeper/validator_unbonding.go index c610a1790..2f5845f0b 100644 --- a/x/liquidstakeibc/keeper/validator_unbonding.go +++ b/x/liquidstakeibc/keeper/validator_unbonding.go @@ -4,6 +4,7 @@ import ( "time" "github.com/cosmos/cosmos-sdk/store/prefix" + "github.com/cosmos/cosmos-sdk/telemetry" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/persistenceOne/pstake-native/v2/x/liquidstakeibc/types" @@ -51,6 +52,8 @@ func (k *Keeper) GetAllValidatorUnbondedAmount(ctx sdk.Context, hc *types.HostCh func (k *Keeper) DeleteValidatorUnbonding(ctx sdk.Context, ub *types.ValidatorUnbonding) { store := prefix.NewStore(ctx.KVStore(k.storeKey), types.ValidatorUnbondingKey) store.Delete(types.GetValidatorUnbondingStoreKey(ub.ChainId, ub.ValidatorAddress, ub.EpochNumber)) + + telemetry.IncrCounter(float32(-1), ub.ChainId, "validator_unbondings") } func (k *Keeper) DeleteValidatorUnbondingsForSequenceID(ctx sdk.Context, sequenceID string) { From 396fdb961e7aebac334143cbddf7ffb176c7cbfc Mon Sep 17 00:00:00 2001 From: Puneet <59960662+puneet2019@users.noreply.github.com> Date: Mon, 10 Jul 2023 18:56:41 +0530 Subject: [PATCH 010/100] add liquidstakeibc_test.go (#563) --- x/liquidstakeibc/genesis_test.go | 2 +- x/liquidstakeibc/types/genesis_test.go | 2 +- x/liquidstakeibc/types/liquidstakeibc.go | 100 ++- x/liquidstakeibc/types/liquidstakeibc_test.go | 713 ++++++++++++++++++ 4 files changed, 776 insertions(+), 41 deletions(-) create mode 100644 x/liquidstakeibc/types/liquidstakeibc_test.go diff --git a/x/liquidstakeibc/genesis_test.go b/x/liquidstakeibc/genesis_test.go index 8f3e35f05..f8131e537 100644 --- a/x/liquidstakeibc/genesis_test.go +++ b/x/liquidstakeibc/genesis_test.go @@ -42,7 +42,7 @@ func TestGenesis(t *testing.T) { ChannelState: 0, }, Validators: []*types.Validator{{ - OperatorAddress: "", + OperatorAddress: authtypes.NewModuleAddressOrBech32Address("testval").String(), Status: stakingtypes.BondStatusBonded, Weight: sdk.OneDec(), DelegatedAmount: sdk.NewInt(1221), diff --git a/x/liquidstakeibc/types/genesis_test.go b/x/liquidstakeibc/types/genesis_test.go index 52f87e61c..31063f3c9 100644 --- a/x/liquidstakeibc/types/genesis_test.go +++ b/x/liquidstakeibc/types/genesis_test.go @@ -288,7 +288,7 @@ func ValidGenesis() *types.GenesisState { ChannelState: 0, }, Validators: []*types.Validator{{ - OperatorAddress: "", + OperatorAddress: authtypes.NewModuleAddressOrBech32Address("testval").String(), Status: stakingtypes.BondStatusBonded, Weight: sdk.OneDec(), DelegatedAmount: sdk.NewInt(1221), diff --git a/x/liquidstakeibc/types/liquidstakeibc.go b/x/liquidstakeibc/types/liquidstakeibc.go index 6081a4555..a3cdceb6c 100644 --- a/x/liquidstakeibc/types/liquidstakeibc.go +++ b/x/liquidstakeibc/types/liquidstakeibc.go @@ -25,13 +25,13 @@ func CurrentUnbondingEpoch(factor, epochNumber int64) int64 { // DefaultDelegateAccountPortOwner generates a delegate ICA port owner given the chain id // Only Use this function while registering a new chain func DefaultDelegateAccountPortOwner(chainID string) string { - return chainID + "." + DelegateICAType + return fmt.Sprintf("%s.%s", chainID, DelegateICAType) } // DefaultRewardsAccountPortOwner generates a rewards ICA port owner given the chain id // Only Use this function while registering a new chain func DefaultRewardsAccountPortOwner(chainID string) string { - return chainID + "." + RewardsICAType + return fmt.Sprintf("%s.%s", chainID, RewardsICAType) } func (deposit *Deposit) Validate() error { @@ -51,19 +51,10 @@ func (deposit *Deposit) Validate() error { } func (hc *HostChain) Validate() error { - if hc.Params.DepositFee.LT(sdk.ZeroDec()) { - return fmt.Errorf("host chain %s has negative deposit fee", hc.ChainId) + err := hc.Params.Validate() + if err != nil { + return fmt.Errorf("host chain %s validation failed with err, err: %s", hc.ChainId, err) } - if hc.Params.RestakeFee.LT(sdk.ZeroDec()) { - return fmt.Errorf("host chain %s has negative restake fee", hc.ChainId) - } - if hc.Params.RedemptionFee.LT(sdk.ZeroDec()) { - return fmt.Errorf("host chain %s has negative redemption fee", hc.ChainId) - } - if hc.Params.UnstakeFee.LT(sdk.ZeroDec()) { - return fmt.Errorf("host chain %s has negative unstake fee", hc.ChainId) - } - if hc.MinimumDeposit.LT(sdk.ZeroInt()) { return fmt.Errorf("host chain %s has negative minimum deposit", hc.ChainId) } @@ -72,35 +63,66 @@ func (hc *HostChain) Validate() error { } for _, validator := range hc.Validators { - if validator.Status != stakingtypes.Unspecified.String() && - validator.Status != stakingtypes.Unbonded.String() && - validator.Status != stakingtypes.Unbonding.String() && - validator.Status != stakingtypes.Bonded.String() { - return fmt.Errorf( - "host chain %s validator %s has an invalid status: %s", - hc.ChainId, - validator.OperatorAddress, - validator.Status, - ) + err := validator.Validate() + if err != nil { + return fmt.Errorf("host chain %s validator is invalid, err: %s", hc.ChainId, err) } + } + return nil +} - if validator.Weight.LT(sdk.ZeroDec()) || validator.Weight.GT(sdk.OneDec()) { - return fmt.Errorf( - "host chain %s validator %s has weight out of bounds: %d", - hc.ChainId, - validator.OperatorAddress, - validator.Weight) - } +func (params *HostChainLSParams) Validate() error { + if params.DepositFee.LT(sdk.ZeroDec()) || params.DepositFee.GT(sdk.OneDec()) { + return fmt.Errorf("host chain lsparams has invalid deposit fee, should be 0<=fee<=1") + } + if params.RestakeFee.LT(sdk.ZeroDec()) || params.RestakeFee.GT(sdk.OneDec()) { + return fmt.Errorf("host chain lsparams has invalid restake fee, should be 0<=fee<=1\"") + } + if params.RedemptionFee.LT(sdk.ZeroDec()) || params.RedemptionFee.GT(sdk.OneDec()) { + return fmt.Errorf("host chain lsparams has invalid redemption fee, should be 0<=fee<=1\"") + } + if params.UnstakeFee.LT(sdk.ZeroDec()) || params.UnstakeFee.GT(sdk.OneDec()) { + return fmt.Errorf("host chain lsparams has invalid unstake fee, should be 0<=fee<=1\"") + } + return nil +} - if validator.DelegatedAmount.LT(sdk.ZeroInt()) { - return fmt.Errorf( - "host chain %s validator %s has negative delegated amount: %s", - hc.ChainId, - validator.OperatorAddress, - validator.DelegatedAmount.String(), - ) - } +func (validator *Validator) Validate() error { + if validator.Status != stakingtypes.Unspecified.String() && + validator.Status != stakingtypes.Unbonded.String() && + validator.Status != stakingtypes.Unbonding.String() && + validator.Status != stakingtypes.Bonded.String() { + return fmt.Errorf( + "host chain validator %s has an invalid status: %s", + validator.OperatorAddress, + validator.Status, + ) + } + + if validator.Weight.LT(sdk.ZeroDec()) || validator.Weight.GT(sdk.OneDec()) { + return fmt.Errorf( + "host chain validator %s has weight out of bounds: %d", + validator.OperatorAddress, + validator.Weight) + } + + if validator.DelegatedAmount.LT(sdk.ZeroInt()) { + return fmt.Errorf( + "host chain validator %s has negative delegated amount: %s", + validator.OperatorAddress, + validator.DelegatedAmount.String(), + ) } + + _, _, err := bech32.DecodeAndConvert(validator.OperatorAddress) + if err != nil { + return fmt.Errorf( + "host chain validator %s is invalid bech32 addr, err: %s", + validator.OperatorAddress, + err, + ) + } + return nil } diff --git a/x/liquidstakeibc/types/liquidstakeibc_test.go b/x/liquidstakeibc/types/liquidstakeibc_test.go new file mode 100644 index 000000000..816ae9453 --- /dev/null +++ b/x/liquidstakeibc/types/liquidstakeibc_test.go @@ -0,0 +1,713 @@ +package types_test + +import ( + "testing" + "time" + + "cosmossdk.io/math" + sdk "github.com/cosmos/cosmos-sdk/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + + "github.com/persistenceOne/pstake-native/v2/app" + "github.com/persistenceOne/pstake-native/v2/x/liquidstakeibc/types" +) + +func init() { + app.SetAddressPrefixes() +} + +func TestCurrentUnbondingEpoch(t *testing.T) { + type args struct { + factor int64 + epochNumber int64 + } + tests := []struct { + name string + args args + want int64 + }{ + { + name: "1 gets 4", + args: args{ + factor: 4, + epochNumber: 1, + }, + want: 4, + }, { + name: "4 gets 4", + args: args{ + factor: 4, + epochNumber: 4, + }, + want: 4, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := types.CurrentUnbondingEpoch(tt.args.factor, tt.args.epochNumber); got != tt.want { + t.Errorf("CurrentUnbondingEpoch() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestIsUnbondingEpoch(t *testing.T) { + type args struct { + factor int64 + epochNumber int64 + } + tests := []struct { + name string + args args + want bool + }{ + { + name: "valid", + args: args{ + factor: 4, + epochNumber: 4, + }, + want: true, + }, { + name: "valid", + args: args{ + factor: 4, + epochNumber: 3, + }, + want: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := types.IsUnbondingEpoch(tt.args.factor, tt.args.epochNumber); got != tt.want { + t.Errorf("IsUnbondingEpoch() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestDefaultDelegateAccountPortOwner(t *testing.T) { + type args struct { + chainID string + } + tests := []struct { + name string + args args + want string + }{ + { + name: "valid", + args: args{chainID: "chain-1"}, + want: "chain-1.delegate", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := types.DefaultDelegateAccountPortOwner(tt.args.chainID); got != tt.want { + t.Errorf("DefaultDelegateAccountPortOwner() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestDefaultRewardsAccountPortOwner(t *testing.T) { + type args struct { + chainID string + } + tests := []struct { + name string + args args + want string + }{ + { + name: "valid", + args: args{chainID: "chain-1"}, + want: "chain-1.rewards", + }} + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := types.DefaultRewardsAccountPortOwner(tt.args.chainID); got != tt.want { + t.Errorf("DefaultRewardsAccountPortOwner() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestDeposit_Validate(t *testing.T) { + type fields struct { + ChainId string + Amount sdk.Coin + Epoch int64 + State types.Deposit_DepositState + IbcSequenceId string + } + validCoin := sdk.NewInt64Coin("ibc/uatom", 1000) + invalidCoin := validCoin + invalidCoin.Amount = sdk.NewInt(-1) + tests := []struct { + name string + fields fields + wantErr bool + }{ + { + name: "valid", + fields: fields{ + ChainId: "chain-1", + Amount: validCoin, + Epoch: 0, + State: 0, + IbcSequenceId: "", + }, + wantErr: false, + }, + { + name: "invalid amount", + fields: fields{ + ChainId: "chain-1", + Amount: invalidCoin, + Epoch: 0, + State: 0, + IbcSequenceId: "", + }, + wantErr: true, + }, { + name: "invalid state", + fields: fields{ + ChainId: "chain-1", + Amount: validCoin, + Epoch: 0, + State: 5, + IbcSequenceId: "", + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + deposit := &types.Deposit{ + ChainId: tt.fields.ChainId, + Amount: tt.fields.Amount, + Epoch: tt.fields.Epoch, + State: tt.fields.State, + IbcSequenceId: tt.fields.IbcSequenceId, + } + if err := deposit.Validate(); (err != nil) != tt.wantErr { + t.Errorf("Validate() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func TestHostChain_Validate(t *testing.T) { + type fields struct { + ChainId string + ConnectionId string + Params *types.HostChainLSParams + HostDenom string + ChannelId string + PortId string + DelegationAccount *types.ICAAccount + RewardsAccount *types.ICAAccount + Validators []*types.Validator + MinimumDeposit math.Int + CValue sdk.Dec + LastCValue sdk.Dec + UnbondingFactor int64 + Active bool + AutoCompoundFactor sdk.Dec + } + validFields := func() fields { + return fields{ + ChainId: "chain-1", + ConnectionId: "connection-1", + Params: &types.HostChainLSParams{ + DepositFee: sdk.ZeroDec(), + RestakeFee: sdk.ZeroDec(), + UnstakeFee: sdk.ZeroDec(), + RedemptionFee: sdk.ZeroDec(), + }, + HostDenom: "uatom", + ChannelId: "channel-1", + PortId: "transfer", + DelegationAccount: &types.ICAAccount{ + Address: "", + Balance: sdk.Coin{}, + Owner: "", + ChannelState: 0, + }, + RewardsAccount: &types.ICAAccount{ + Address: "", + Balance: sdk.Coin{}, + Owner: "", + ChannelState: 0, + }, + Validators: []*types.Validator{{ + OperatorAddress: authtypes.NewModuleAddressOrBech32Address("testval").String(), + Status: stakingtypes.BondStatusBonded, + Weight: sdk.OneDec(), + DelegatedAmount: sdk.OneInt(), + ExchangeRate: sdk.OneDec(), + UnbondingEpoch: 0, + }}, + MinimumDeposit: sdk.OneInt(), + CValue: sdk.OneDec(), + LastCValue: sdk.OneDec(), + UnbondingFactor: 4, + Active: false, + AutoCompoundFactor: sdk.MustNewDecFromStr("2"), + } + } + + tests := []struct { + name string + fields func() fields + wantErr bool + }{ + { + name: "correct", + fields: func() fields { return validFields() }, + wantErr: false, + }, + { + name: "invalid params", + fields: func() fields { + newfields := validFields() + newfields.Params.DepositFee = sdk.MustNewDecFromStr("2") + return newfields + }, + wantErr: true, + }, + { + name: "invalid validator", + fields: func() fields { + newfields := validFields() + newfields.Validators[0].Weight = sdk.MustNewDecFromStr("2") + return newfields + }, + wantErr: true, + }, + { + name: "invalid cvalue", + fields: func() fields { + newfields := validFields() + newfields.CValue = sdk.MustNewDecFromStr("2") + return newfields + }, + wantErr: true, + }, + { + name: "invalid mindeposit", + fields: func() fields { + newfields := validFields() + newfields.MinimumDeposit = sdk.NewInt(-2) + return newfields + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ttfields := tt.fields() + hc := &types.HostChain{ + ChainId: ttfields.ChainId, + ConnectionId: ttfields.ConnectionId, + Params: ttfields.Params, + HostDenom: ttfields.HostDenom, + ChannelId: ttfields.ChannelId, + PortId: ttfields.PortId, + DelegationAccount: ttfields.DelegationAccount, + RewardsAccount: ttfields.RewardsAccount, + Validators: ttfields.Validators, + MinimumDeposit: ttfields.MinimumDeposit, + CValue: ttfields.CValue, + LastCValue: ttfields.LastCValue, + UnbondingFactor: ttfields.UnbondingFactor, + Active: ttfields.Active, + AutoCompoundFactor: ttfields.AutoCompoundFactor, + } + if err := hc.Validate(); (err != nil) != tt.wantErr { + t.Errorf("Validate() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func TestUnbonding_Validate(t *testing.T) { + type fields struct { + ChainId string + EpochNumber int64 + MatureTime time.Time + BurnAmount sdk.Coin + UnbondAmount sdk.Coin + IbcSequenceId string + State types.Unbonding_UnbondingState + } + validCoin := sdk.NewInt64Coin("ibc/uatom", 1000) + invalidCoin := validCoin + invalidCoin.Amount = sdk.NewInt(-1000) + validFields := func() fields { + return fields{ + ChainId: "chain-1", + EpochNumber: 0, + MatureTime: time.Time{}, + BurnAmount: validCoin, + UnbondAmount: validCoin, + IbcSequenceId: "", + State: 0, + } + } + tests := []struct { + name string + fields func() fields + wantErr bool + }{ + { + name: "valid", + fields: func() fields { return validFields() }, + wantErr: false, + }, { + name: "invalid burnamount", + fields: func() fields { + field := validFields() + field.BurnAmount = invalidCoin + return field + }, + wantErr: true, + }, { + name: "invalid unbound amount", + fields: func() fields { + field := validFields() + field.UnbondAmount = invalidCoin + return field + }, + wantErr: true, + }, { + name: "invalid unbonding state", + fields: func() fields { + field := validFields() + field.State = 9 + return field + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + fields := tt.fields() + u := &types.Unbonding{ + ChainId: fields.ChainId, + EpochNumber: fields.EpochNumber, + MatureTime: fields.MatureTime, + BurnAmount: fields.BurnAmount, + UnbondAmount: fields.UnbondAmount, + IbcSequenceId: fields.IbcSequenceId, + State: fields.State, + } + if err := u.Validate(); (err != nil) != tt.wantErr { + t.Errorf("Validate() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func TestUserUnbonding_Validate(t *testing.T) { + type fields struct { + ChainId string + EpochNumber int64 + Address string + StkAmount sdk.Coin + UnbondAmount sdk.Coin + } + validCoin := sdk.NewInt64Coin("stk/uatom", 1000) + invalidCoin := validCoin + invalidCoin.Amount = sdk.NewInt(-1000) + tests := []struct { + name string + fields fields + wantErr bool + }{ + { + name: "valid", + fields: fields{ + ChainId: "chain-1", + EpochNumber: 0, + Address: authtypes.NewModuleAddressOrBech32Address("test").String(), + StkAmount: validCoin, + UnbondAmount: validCoin, + }, + wantErr: false, + }, + { + name: "invalid coin", + fields: fields{ + ChainId: "chain-1", + EpochNumber: 0, + Address: authtypes.NewModuleAddressOrBech32Address("test").String(), + StkAmount: validCoin, + UnbondAmount: invalidCoin, + }, + wantErr: true, + }, { + name: "invalid addr", + fields: fields{ + ChainId: "chain-1", + EpochNumber: 0, + Address: "test", + StkAmount: validCoin, + UnbondAmount: validCoin, + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ub := &types.UserUnbonding{ + ChainId: tt.fields.ChainId, + EpochNumber: tt.fields.EpochNumber, + Address: tt.fields.Address, + StkAmount: tt.fields.StkAmount, + UnbondAmount: tt.fields.UnbondAmount, + } + if err := ub.Validate(); (err != nil) != tt.wantErr { + t.Errorf("Validate() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func TestValidatorUnbonding_Validate(t *testing.T) { + type fields struct { + ChainId string + EpochNumber int64 + MatureTime time.Time + ValidatorAddress string + Amount sdk.Coin + IbcSequenceId string + } + validCoin := sdk.NewInt64Coin("uatom", 1000) + invalidCoin := validCoin + invalidCoin.Amount = sdk.NewInt(-1000) + tests := []struct { + name string + fields fields + wantErr bool + }{ + { + name: "valid", + fields: fields{ + ChainId: "chain-1", + EpochNumber: 0, + MatureTime: time.Time{}, + ValidatorAddress: authtypes.NewModuleAddressOrBech32Address("testval").String(), + Amount: validCoin, + IbcSequenceId: "", + }, + wantErr: false, + }, + { + name: "invalid amount", + fields: fields{ + ChainId: "chain-1", + EpochNumber: 0, + MatureTime: time.Time{}, + ValidatorAddress: authtypes.NewModuleAddressOrBech32Address("testval").String(), + Amount: invalidCoin, + IbcSequenceId: "", + }, + wantErr: true, + }, + { + name: "invalid addr", + fields: fields{ + ChainId: "chain-1", + EpochNumber: 0, + MatureTime: time.Time{}, + ValidatorAddress: "testval", + Amount: validCoin, + IbcSequenceId: "", + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + vb := &types.ValidatorUnbonding{ + ChainId: tt.fields.ChainId, + EpochNumber: tt.fields.EpochNumber, + MatureTime: tt.fields.MatureTime, + ValidatorAddress: tt.fields.ValidatorAddress, + Amount: tt.fields.Amount, + IbcSequenceId: tt.fields.IbcSequenceId, + } + if err := vb.Validate(); (err != nil) != tt.wantErr { + t.Errorf("Validate() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func TestHostChainLSParams_Validate(t *testing.T) { + type fields struct { + DepositFee sdk.Dec + RestakeFee sdk.Dec + UnstakeFee sdk.Dec + RedemptionFee sdk.Dec + } + tests := []struct { + name string + fields fields + wantErr bool + }{ + { + name: "valid", + fields: fields{ + DepositFee: sdk.ZeroDec(), + RestakeFee: sdk.ZeroDec(), + UnstakeFee: sdk.ZeroDec(), + RedemptionFee: sdk.ZeroDec(), + }, + wantErr: false, + }, + { + name: "invalid deposit fee", + fields: fields{ + DepositFee: sdk.MustNewDecFromStr("-1"), + RestakeFee: sdk.ZeroDec(), + UnstakeFee: sdk.ZeroDec(), + RedemptionFee: sdk.ZeroDec(), + }, + wantErr: true, + }, + { + name: "invalid restake fee", + fields: fields{ + DepositFee: sdk.ZeroDec(), + RestakeFee: sdk.MustNewDecFromStr("1.1"), + UnstakeFee: sdk.ZeroDec(), + RedemptionFee: sdk.ZeroDec(), + }, + wantErr: true, + }, { + name: "invalid unstake fee", + fields: fields{ + DepositFee: sdk.ZeroDec(), + RestakeFee: sdk.ZeroDec(), + UnstakeFee: sdk.MustNewDecFromStr("-1"), + RedemptionFee: sdk.ZeroDec(), + }, + wantErr: true, + }, { + name: "invalid redemption fee", + fields: fields{ + DepositFee: sdk.ZeroDec(), + RestakeFee: sdk.ZeroDec(), + UnstakeFee: sdk.ZeroDec(), + RedemptionFee: sdk.MustNewDecFromStr("1.2"), + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + params := &types.HostChainLSParams{ + DepositFee: tt.fields.DepositFee, + RestakeFee: tt.fields.RestakeFee, + UnstakeFee: tt.fields.UnstakeFee, + RedemptionFee: tt.fields.RedemptionFee, + } + if err := params.Validate(); (err != nil) != tt.wantErr { + t.Errorf("Validate() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func TestValidator_Validate(t *testing.T) { + type fields struct { + OperatorAddress string + Status string + Weight sdk.Dec + DelegatedAmount math.Int + ExchangeRate sdk.Dec + UnbondingEpoch int64 + } + tests := []struct { + name string + fields fields + wantErr bool + }{ + { + name: "valid", + fields: fields{ + OperatorAddress: authtypes.NewModuleAddressOrBech32Address("testval").String(), + Status: stakingtypes.BondStatusBonded, + Weight: sdk.OneDec(), + DelegatedAmount: sdk.OneInt(), + ExchangeRate: sdk.OneDec(), + UnbondingEpoch: 0, + }, + wantErr: false, + }, { + name: "invalid operatorAddr", + fields: fields{ + OperatorAddress: "testval", + Status: stakingtypes.BondStatusBonded, + Weight: sdk.OneDec(), + DelegatedAmount: sdk.OneInt(), + ExchangeRate: sdk.OneDec(), + UnbondingEpoch: 0, + }, + wantErr: true, + }, { + name: "invalid status", + fields: fields{ + OperatorAddress: authtypes.NewModuleAddressOrBech32Address("testval").String(), + Status: "Status random", + Weight: sdk.OneDec(), + DelegatedAmount: sdk.OneInt(), + ExchangeRate: sdk.OneDec(), + UnbondingEpoch: 0, + }, + wantErr: true, + }, { + name: "invalid weight", + fields: fields{ + OperatorAddress: authtypes.NewModuleAddressOrBech32Address("testval").String(), + Status: stakingtypes.BondStatusBonded, + Weight: sdk.MustNewDecFromStr("3"), + DelegatedAmount: sdk.OneInt(), + ExchangeRate: sdk.OneDec(), + UnbondingEpoch: 0, + }, + wantErr: true, + }, + { + name: "invalid delegated amount", + fields: fields{ + OperatorAddress: authtypes.NewModuleAddressOrBech32Address("testval").String(), + Status: stakingtypes.BondStatusBonded, + Weight: sdk.OneDec(), + DelegatedAmount: sdk.NewInt(-1), + ExchangeRate: sdk.OneDec(), + UnbondingEpoch: 0, + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + validator := &types.Validator{ + OperatorAddress: tt.fields.OperatorAddress, + Status: tt.fields.Status, + Weight: tt.fields.Weight, + DelegatedAmount: tt.fields.DelegatedAmount, + ExchangeRate: tt.fields.ExchangeRate, + UnbondingEpoch: tt.fields.UnbondingEpoch, + } + if err := validator.Validate(); (err != nil) != tt.wantErr { + t.Errorf("Validate() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} From 9016f012842bc32e715ade2d769318ac594fb160 Mon Sep 17 00:00:00 2001 From: Puneet <59960662+puneet2019@users.noreply.github.com> Date: Mon, 10 Jul 2023 18:59:15 +0530 Subject: [PATCH 011/100] Puneet/paramstest (#564) * update params proto to include stringer. * add params test --- go.mod | 2 +- .../liquidstakeibc/v1beta1/params.proto | 2 - x/liquidstakeibc/types/errors.go | 1 + x/liquidstakeibc/types/params.go | 89 ++++--------------- x/liquidstakeibc/types/params.pb.go | 21 ++--- x/liquidstakeibc/types/params_test.go | 77 ++++++++++++++++ x/lscosmos/keeper/migrate_module.go | 4 +- 7 files changed, 107 insertions(+), 89 deletions(-) create mode 100644 x/liquidstakeibc/types/params_test.go diff --git a/go.mod b/go.mod index e3dd108e8..8b0bd6864 100644 --- a/go.mod +++ b/go.mod @@ -30,7 +30,6 @@ require ( google.golang.org/grpc v1.56.2 google.golang.org/protobuf v1.31.0 gopkg.in/yaml.v2 v2.4.0 - sigs.k8s.io/yaml v1.3.0 ) require ( @@ -322,6 +321,7 @@ require ( mvdan.cc/unparam v0.0.0-20221223090309-7455f1af531d // indirect nhooyr.io/websocket v1.8.6 // indirect pgregory.net/rapid v0.5.5 // indirect + sigs.k8s.io/yaml v1.3.0 // indirect ) replace ( diff --git a/proto/pstake/liquidstakeibc/v1beta1/params.proto b/proto/pstake/liquidstakeibc/v1beta1/params.proto index c70cd2600..b942527be 100644 --- a/proto/pstake/liquidstakeibc/v1beta1/params.proto +++ b/proto/pstake/liquidstakeibc/v1beta1/params.proto @@ -8,8 +8,6 @@ option go_package = "github.com/persistenceOne/pstake-native/v2/x/liquidstakeibc // Params defines the parameters for the module. message Params { - option (gogoproto.goproto_stringer) = false; - string admin_address = 1 [ (cosmos_proto.scalar) = "cosmos.AddressString" ]; // protocol admin address diff --git a/x/liquidstakeibc/types/errors.go b/x/liquidstakeibc/types/errors.go index db07453b4..2d0eb2e33 100644 --- a/x/liquidstakeibc/types/errors.go +++ b/x/liquidstakeibc/types/errors.go @@ -22,4 +22,5 @@ var ( ErrBurnFailed = errorsmod.Register(ModuleName, 2014, "burn failed") ErrParsingAmount = errorsmod.Register(ModuleName, 2015, "could not parse message amount") ErrHostChainInactive = errorsmod.Register(ModuleName, 2016, "host chain is not active") + ErrInvalidParams = errorsmod.Register(ModuleName, 2017, "invalid params") ) diff --git a/x/liquidstakeibc/types/params.go b/x/liquidstakeibc/types/params.go index 15e20dda4..7b24f4412 100644 --- a/x/liquidstakeibc/types/params.go +++ b/x/liquidstakeibc/types/params.go @@ -1,36 +1,32 @@ package types import ( - "fmt" - "strings" - sdktypes "github.com/cosmos/cosmos-sdk/types" - "sigs.k8s.io/yaml" ) const ( - DefaultAdminAddress string = "persistence10khgeppewe4rgfrcy809r9h00aquwxxxrk6glr" // TODO: Use correct address on launch - DefaultFeeAddress string = "persistence1xruvjju28j0a5ud5325rfdak8f5a04h0s30mld" // TODO: Use correct address on launch - DefaultUpperCValueLimit string = "1.1" - DefaultLowerCValueLimit string = "0.85" + DefaultAdminAddress string = "persistence10khgeppewe4rgfrcy809r9h00aquwxxxrk6glr" // TODO: Use correct address on launch + DefaultFeeAddress string = "persistence1xruvjju28j0a5ud5325rfdak8f5a04h0s30mld" // TODO: Use correct address on launch +) + +var ( + DefaultUpperCValueLimit = sdktypes.MustNewDecFromStr("1.1") + DefaultLowerCValueLimit = sdktypes.MustNewDecFromStr("0.85") ) // NewParams creates a new Params object func NewParams( adminAddress string, feeAddress string, - upperCValueLimit string, - lowerCValueLimit string, + upperCValueLimit sdktypes.Dec, + lowerCValueLimit sdktypes.Dec, ) Params { - upperLimit, _ := sdktypes.NewDecFromStr(upperCValueLimit) - lowerLimit, _ := sdktypes.NewDecFromStr(lowerCValueLimit) - return Params{ AdminAddress: adminAddress, FeeAddress: feeAddress, - UpperCValueLimit: upperLimit, - LowerCValueLimit: lowerLimit, + UpperCValueLimit: upperCValueLimit, + LowerCValueLimit: lowerCValueLimit, } } @@ -46,69 +42,14 @@ func DefaultParams() Params { // Validate all liquidstakeibc module parameters func (p *Params) Validate() error { - if err := isAddress(p.AdminAddress); err != nil { + if _, err := sdktypes.AccAddressFromBech32(p.AdminAddress); err != nil { return err } - if err := isAddress(p.FeeAddress); err != nil { - return err - } - if err := isGTOne(p.UpperCValueLimit); err != nil { - return err - } - if err := isLTOne(p.LowerCValueLimit); err != nil { - return err - } - - return nil -} - -// String implements the Stringer interface. -func (p *Params) String() string { - out, _ := yaml.Marshal(p) - return string(out) -} - -// checks - -func isAddress(i interface{}) error { - val, ok := i.(string) - if !ok { - return fmt.Errorf("parameter is not valid: %T", i) - } - - if len(strings.TrimSpace(val)) == 0 { - return fmt.Errorf("empty address string is not allowed") - } - - _, err := sdktypes.GetFromBech32(val, "persistence") - if err != nil { + if _, err := sdktypes.AccAddressFromBech32(p.FeeAddress); err != nil { return err } - - return nil -} - -func isGTOne(i interface{}) error { - val, ok := i.(sdktypes.Dec) - if !ok { - return fmt.Errorf("parameter is not valid: %T", i) - } - - if !val.GT(sdktypes.OneDec()) { - return fmt.Errorf("upper limit must be higher than 1") - } - - return nil -} - -func isLTOne(i interface{}) error { - val, ok := i.(sdktypes.Dec) - if !ok { - return fmt.Errorf("parameter is not valid: %T", i) - } - - if !val.LT(sdktypes.OneDec()) { - return fmt.Errorf("lower limit must be lower than 1") + if p.LowerCValueLimit.GT(sdktypes.OneDec()) || p.LowerCValueLimit.GTE(p.UpperCValueLimit) { + return ErrInvalidParams.Wrapf("LowerCValue limit should be less than both 1 and UpperCValue limit, lowerCValue: %s, UpperCValue: %s", p.LowerCValueLimit, p.UpperCValueLimit) } return nil diff --git a/x/liquidstakeibc/types/params.pb.go b/x/liquidstakeibc/types/params.pb.go index 932eda737..a3d7c5d1e 100644 --- a/x/liquidstakeibc/types/params.pb.go +++ b/x/liquidstakeibc/types/params.pb.go @@ -33,8 +33,9 @@ type Params struct { LowerCValueLimit github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,4,opt,name=lower_c_value_limit,json=lowerCValueLimit,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"lower_c_value_limit"` } -func (m *Params) Reset() { *m = Params{} } -func (*Params) ProtoMessage() {} +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_ed8bf02c8aabc0b0, []int{0} } @@ -88,13 +89,13 @@ func init() { } var fileDescriptor_ed8bf02c8aabc0b0 = []byte{ - // 352 bytes of a gzipped FileDescriptorProto + // 346 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xd2, 0x2a, 0x28, 0x2e, 0x49, 0xcc, 0x4e, 0xd5, 0xcf, 0xc9, 0x2c, 0x2c, 0xcd, 0x4c, 0x01, 0xb3, 0x33, 0x93, 0x92, 0xf5, 0xcb, 0x0c, 0x93, 0x52, 0x4b, 0x12, 0x0d, 0xf5, 0x0b, 0x12, 0x8b, 0x12, 0x73, 0x8b, 0xf5, 0x0a, 0x8a, 0xf2, 0x4b, 0xf2, 0x85, 0x64, 0x21, 0x6a, 0xf5, 0x50, 0xd5, 0xea, 0x41, 0xd5, 0x4a, 0x89, 0xa4, 0xe7, 0xa7, 0xe7, 0x83, 0x55, 0xea, 0x83, 0x58, 0x10, 0x4d, 0x52, 0x92, 0xc9, 0xf9, 0xc5, 0xb9, - 0xf9, 0xc5, 0xf1, 0x10, 0x09, 0x08, 0x07, 0x22, 0xa5, 0xf4, 0x88, 0x89, 0x8b, 0x2d, 0x00, 0x6c, + 0xf9, 0xc5, 0xf1, 0x10, 0x09, 0x08, 0x07, 0x22, 0xa5, 0x74, 0x87, 0x89, 0x8b, 0x2d, 0x00, 0x6c, 0x81, 0x90, 0x2d, 0x17, 0x6f, 0x62, 0x4a, 0x6e, 0x66, 0x5e, 0x7c, 0x62, 0x4a, 0x4a, 0x51, 0x6a, 0x71, 0xb1, 0x04, 0xa3, 0x02, 0xa3, 0x06, 0xa7, 0x93, 0xc4, 0xa5, 0x2d, 0xba, 0x22, 0x50, 0x3d, 0x8e, 0x10, 0x99, 0xe0, 0x92, 0xa2, 0xcc, 0xbc, 0xf4, 0x20, 0x1e, 0xb0, 0x72, 0xa8, 0x98, 0x90, @@ -105,12 +106,12 @@ var fileDescriptor_ed8bf02c8aabc0b0 = []byte{ 0x05, 0x28, 0xa5, 0x5b, 0x9c, 0x92, 0xad, 0x5f, 0x52, 0x59, 0x90, 0x5a, 0xac, 0xe7, 0x92, 0x9a, 0x7c, 0x69, 0x8b, 0x2e, 0x17, 0xd4, 0x42, 0x97, 0xd4, 0xe4, 0x20, 0x01, 0xb0, 0xc1, 0xce, 0x61, 0x20, 0x63, 0x7d, 0x40, 0xa6, 0x82, 0x2c, 0xcb, 0xc9, 0x2f, 0xc7, 0xb0, 0x8c, 0x85, 0x1a, 0x96, - 0x81, 0x0d, 0x46, 0xb2, 0xcc, 0x8a, 0x65, 0xc6, 0x02, 0x79, 0x06, 0xa7, 0xe8, 0x13, 0x8f, 0xe4, - 0x18, 0x2f, 0x3c, 0x92, 0x63, 0x7c, 0xf0, 0x48, 0x8e, 0x71, 0xc2, 0x63, 0x39, 0x86, 0x0b, 0x8f, - 0xe5, 0x18, 0x6e, 0x3c, 0x96, 0x63, 0x88, 0x72, 0x44, 0xb2, 0xa7, 0x20, 0xb5, 0xa8, 0x38, 0xb3, - 0xb8, 0x24, 0x35, 0x2f, 0x39, 0xd5, 0x3f, 0x2f, 0x55, 0x1f, 0x12, 0xd1, 0xba, 0x79, 0x89, 0x25, - 0x99, 0x65, 0xa9, 0xfa, 0x65, 0x46, 0xfa, 0x15, 0xe8, 0x09, 0x04, 0xec, 0x8c, 0x24, 0x36, 0x70, - 0x44, 0x1a, 0x03, 0x02, 0x00, 0x00, 0xff, 0xff, 0x9a, 0x9f, 0x8e, 0x0f, 0x46, 0x02, 0x00, 0x00, + 0x81, 0x0d, 0x46, 0xb2, 0xcc, 0x29, 0xfa, 0xc4, 0x23, 0x39, 0xc6, 0x0b, 0x8f, 0xe4, 0x18, 0x1f, + 0x3c, 0x92, 0x63, 0x9c, 0xf0, 0x58, 0x8e, 0xe1, 0xc2, 0x63, 0x39, 0x86, 0x1b, 0x8f, 0xe5, 0x18, + 0xa2, 0x1c, 0x91, 0x6c, 0x28, 0x48, 0x2d, 0x2a, 0xce, 0x2c, 0x2e, 0x49, 0xcd, 0x4b, 0x4e, 0xf5, + 0xcf, 0x4b, 0xd5, 0x87, 0x44, 0xb1, 0x6e, 0x5e, 0x62, 0x49, 0x66, 0x59, 0xaa, 0x7e, 0x99, 0x91, + 0x7e, 0x05, 0x7a, 0xd2, 0x00, 0x3b, 0x20, 0x89, 0x0d, 0x1c, 0x85, 0xc6, 0x80, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xe2, 0x09, 0x61, 0x5f, 0x40, 0x02, 0x00, 0x00, } func (m *Params) Marshal() (dAtA []byte, err error) { diff --git a/x/liquidstakeibc/types/params_test.go b/x/liquidstakeibc/types/params_test.go new file mode 100644 index 000000000..259a00258 --- /dev/null +++ b/x/liquidstakeibc/types/params_test.go @@ -0,0 +1,77 @@ +package types_test + +import ( + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/persistenceOne/pstake-native/v2/x/liquidstakeibc/types" +) + +func TestParams_Validate(t *testing.T) { + type fields struct { + AdminAddress string + FeeAddress string + UpperCValueLimit sdk.Dec + LowerCValueLimit sdk.Dec + } + tests := []struct { + name string + fields fields + wantErr bool + }{ + { + name: "Valid Params", + fields: fields{ + AdminAddress: types.DefaultAdminAddress, + FeeAddress: types.DefaultFeeAddress, + UpperCValueLimit: sdk.OneDec(), + LowerCValueLimit: sdk.ZeroDec(), + }, + wantErr: false, + }, + { + name: "Invalid admin address", + fields: fields{ + AdminAddress: "", + FeeAddress: types.DefaultFeeAddress, + UpperCValueLimit: sdk.OneDec(), + LowerCValueLimit: sdk.ZeroDec(), + }, + wantErr: true, + }, + { + name: "invalid fee address", + fields: fields{ + AdminAddress: types.DefaultAdminAddress, + FeeAddress: "", + UpperCValueLimit: sdk.OneDec(), + LowerCValueLimit: sdk.ZeroDec(), + }, + wantErr: true, + }, + { + name: "Invalid Lower Limit", + fields: fields{ + AdminAddress: types.DefaultAdminAddress, + FeeAddress: types.DefaultFeeAddress, + UpperCValueLimit: sdk.OneDec(), + LowerCValueLimit: sdk.OneDec(), + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &types.Params{ + AdminAddress: tt.fields.AdminAddress, + FeeAddress: tt.fields.FeeAddress, + UpperCValueLimit: tt.fields.UpperCValueLimit, + LowerCValueLimit: tt.fields.LowerCValueLimit, + } + if err := p.Validate(); (err != nil) != tt.wantErr { + t.Errorf("Validate() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} diff --git a/x/lscosmos/keeper/migrate_module.go b/x/lscosmos/keeper/migrate_module.go index 1d0297726..2545a6037 100644 --- a/x/lscosmos/keeper/migrate_module.go +++ b/x/lscosmos/keeper/migrate_module.go @@ -199,8 +199,8 @@ func (k Keeper) Migrate(ctx sdk.Context) error { k.liquidStakeIBCKeeper.SetParams(ctx, liquidstakeibctypes.Params{ AdminAddress: hcparams.PstakeParams.PstakeFeeAddress, FeeAddress: hcparams.PstakeParams.PstakeFeeAddress, - UpperCValueLimit: sdk.MustNewDecFromStr(liquidstakeibctypes.DefaultUpperCValueLimit), - LowerCValueLimit: sdk.MustNewDecFromStr(liquidstakeibctypes.DefaultLowerCValueLimit), + UpperCValueLimit: liquidstakeibctypes.DefaultUpperCValueLimit, + LowerCValueLimit: liquidstakeibctypes.DefaultLowerCValueLimit, }) err = k.bankKeeper.SendCoinsFromModuleToModule(ctx, types.DepositModuleAccount, liquidstakeibctypes.DepositModuleAccount, depositAccBalance) From 22a6d113f549dc471b8c09ab100cc17257c8275b Mon Sep 17 00:00:00 2001 From: Puneet <59960662+puneet2019@users.noreply.github.com> Date: Mon, 10 Jul 2023 20:02:10 +0530 Subject: [PATCH 012/100] Puneet/removecvalue GT(1)check from hostchain validation (#565) * remove cvalue gt 1 check. * add invariants to check c value greater than limits. * use keepr function to check cvalue limits. * lint --- x/liquidstakeibc/keeper/invariants.go | 34 +++++++++++++++++++ x/liquidstakeibc/module.go | 4 ++- x/liquidstakeibc/types/genesis_test.go | 2 +- x/liquidstakeibc/types/liquidstakeibc.go | 2 +- x/liquidstakeibc/types/liquidstakeibc_test.go | 2 +- 5 files changed, 40 insertions(+), 4 deletions(-) create mode 100644 x/liquidstakeibc/keeper/invariants.go diff --git a/x/liquidstakeibc/keeper/invariants.go b/x/liquidstakeibc/keeper/invariants.go new file mode 100644 index 000000000..854486db6 --- /dev/null +++ b/x/liquidstakeibc/keeper/invariants.go @@ -0,0 +1,34 @@ +package keeper + +import ( + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/persistenceOne/pstake-native/v2/x/liquidstakeibc/types" +) + +// RegisterInvariants registers the bank module invariants +func RegisterInvariants(ir sdk.InvariantRegistry, k Keeper) { + ir.RegisterRoute(types.ModuleName, "cvalue-limits", CValueLimits(k)) +} + +func CValueLimits(k Keeper) sdk.Invariant { + return func(ctx sdk.Context) (string, bool) { + hostChains := k.GetAllHostChains(ctx) + str := "" + broken := false + for _, hc := range hostChains { + if !k.CValueWithinLimits(ctx, hc) { + str = fmt.Sprintf("chainID: %s, cValue: %s \n", hc.ChainId, hc.CValue) + } + } + if str != "" { + broken = true + } + return sdk.FormatInvariant( + types.ModuleName, "cvalue-limits", + fmt.Sprintf("cvalue out of bounds as follows \n%s ", str), + ), broken + } +} diff --git a/x/liquidstakeibc/module.go b/x/liquidstakeibc/module.go index 43e1b7bd5..7423ad0e6 100644 --- a/x/liquidstakeibc/module.go +++ b/x/liquidstakeibc/module.go @@ -109,7 +109,9 @@ func (a AppModule) EndBlock(_ sdk.Context, _ abci.RequestEndBlock) []abci.Valida return []abci.ValidatorUpdate{} } -func (a AppModule) RegisterInvariants(registry sdk.InvariantRegistry) {} +func (a AppModule) RegisterInvariants(registry sdk.InvariantRegistry) { + keeper.RegisterInvariants(registry, a.keeper) +} // Deprecated: QuerierRoute func (a AppModule) QuerierRoute() string { diff --git a/x/liquidstakeibc/types/genesis_test.go b/x/liquidstakeibc/types/genesis_test.go index 31063f3c9..c1127f566 100644 --- a/x/liquidstakeibc/types/genesis_test.go +++ b/x/liquidstakeibc/types/genesis_test.go @@ -46,7 +46,7 @@ func TestGenesisState_Validate(t *testing.T) { desc: "host chains invalid", genState: func() *types.GenesisState { genesis := ValidGenesis() - genesis.HostChains[0].CValue = sdk.MustNewDecFromStr("1.1") + genesis.HostChains[0].CValue = sdk.MustNewDecFromStr("-1") return genesis }, valid: false, diff --git a/x/liquidstakeibc/types/liquidstakeibc.go b/x/liquidstakeibc/types/liquidstakeibc.go index a3cdceb6c..277c3244b 100644 --- a/x/liquidstakeibc/types/liquidstakeibc.go +++ b/x/liquidstakeibc/types/liquidstakeibc.go @@ -58,7 +58,7 @@ func (hc *HostChain) Validate() error { if hc.MinimumDeposit.LT(sdk.ZeroInt()) { return fmt.Errorf("host chain %s has negative minimum deposit", hc.ChainId) } - if hc.CValue.LT(sdk.ZeroDec()) || hc.CValue.GT(sdk.OneDec()) { + if hc.CValue.LT(sdk.ZeroDec()) { //GT limits should be checked by module level params, invariants. return fmt.Errorf("host chain %s has c value out of bounds: %d", hc.ChainId, hc.CValue) } diff --git a/x/liquidstakeibc/types/liquidstakeibc_test.go b/x/liquidstakeibc/types/liquidstakeibc_test.go index 816ae9453..108ae6ce5 100644 --- a/x/liquidstakeibc/types/liquidstakeibc_test.go +++ b/x/liquidstakeibc/types/liquidstakeibc_test.go @@ -291,7 +291,7 @@ func TestHostChain_Validate(t *testing.T) { name: "invalid cvalue", fields: func() fields { newfields := validFields() - newfields.CValue = sdk.MustNewDecFromStr("2") + newfields.CValue = sdk.MustNewDecFromStr("-2") return newfields }, wantErr: true, From 409787d341c50e1d70001d4770aa5e18c4cd745f Mon Sep 17 00:00:00 2001 From: Puneet <59960662+puneet2019@users.noreply.github.com> Date: Tue, 11 Jul 2023 12:17:07 +0530 Subject: [PATCH 013/100] add msgs test, hostchain tests (#566) --- x/liquidstakeibc/types/host_chain.go | 7 +- x/liquidstakeibc/types/host_chain_test.go | 135 +++++++++++ x/liquidstakeibc/types/keys.go | 2 + x/liquidstakeibc/types/liquidstakeibc.go | 5 + x/liquidstakeibc/types/liquidstakeibc_test.go | 2 + x/liquidstakeibc/types/msgs.go | 14 ++ x/liquidstakeibc/types/msgs_test.go | 226 ++++++++++++++++++ 7 files changed, 389 insertions(+), 2 deletions(-) create mode 100644 x/liquidstakeibc/types/host_chain_test.go create mode 100644 x/liquidstakeibc/types/msgs_test.go diff --git a/x/liquidstakeibc/types/host_chain.go b/x/liquidstakeibc/types/host_chain.go index 478c00b2c..c3e828a23 100644 --- a/x/liquidstakeibc/types/host_chain.go +++ b/x/liquidstakeibc/types/host_chain.go @@ -1,6 +1,9 @@ package types import ( + "fmt" + + "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" ibctfrtypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" ) @@ -10,7 +13,7 @@ func (hc *HostChain) IBCDenom() string { } func (hc *HostChain) MintDenom() string { - return "stk" + "/" + hc.HostDenom + return fmt.Sprintf("%s/%s", LiquidStakeDenomPrefix, hc.HostDenom) } func (hc *HostChain) GetValidator(operatorAddress string) (*Validator, bool) { @@ -23,7 +26,7 @@ func (hc *HostChain) GetValidator(operatorAddress string) (*Validator, bool) { return nil, false } -func (hc *HostChain) GetHostChainTotalDelegations() sdk.Int { //nolint:staticcheck +func (hc *HostChain) GetHostChainTotalDelegations() math.Int { totalDelegations := sdk.ZeroInt() for _, validator := range hc.Validators { totalDelegations = totalDelegations.Add(validator.DelegatedAmount) diff --git a/x/liquidstakeibc/types/host_chain_test.go b/x/liquidstakeibc/types/host_chain_test.go new file mode 100644 index 000000000..c6ea21154 --- /dev/null +++ b/x/liquidstakeibc/types/host_chain_test.go @@ -0,0 +1,135 @@ +package types_test + +import ( + "reflect" + "testing" + + "cosmossdk.io/math" + sdk "github.com/cosmos/cosmos-sdk/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + + "github.com/persistenceOne/pstake-native/v2/x/liquidstakeibc/types" +) + +func TestHostChain_GetHostChainTotalDelegations(t *testing.T) { + + tests := []struct { + name string + hostChain func() types.HostChain + want math.Int + }{ + { + name: "count", + hostChain: func() types.HostChain { + hc := validHostChain() + hc.Validators = append(hc.Validators, makeVal("one")) + return *hc + }, + want: sdk.NewInt(3), + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + hc := tt.hostChain() + if got := hc.GetHostChainTotalDelegations(); !reflect.DeepEqual(got, tt.want) { + t.Errorf("GetHostChainTotalDelegations() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestHostChain_GetValidator(t *testing.T) { + foundvaloper := authtypes.NewModuleAddressOrBech32Address("testval1").String() + + type args struct { + operatorAddress string + } + tests := []struct { + name string + hostChain func() types.HostChain + args args + want *types.Validator + want1 bool + }{ + { + name: "findone", + hostChain: func() types.HostChain { + hc := validHostChain() + hc.Validators = append(hc.Validators, makeVal(foundvaloper)) + return *hc + }, + args: args{operatorAddress: foundvaloper}, + want: makeVal(foundvaloper), + want1: true, + }, + { + name: "not found", + hostChain: func() types.HostChain { + hc := validHostChain() + hc.Validators = append(hc.Validators, makeVal(authtypes.NewModuleAddressOrBech32Address("testval4").String())) + return *hc + }, + args: args{operatorAddress: foundvaloper}, + want: nil, + want1: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + hc := tt.hostChain() + got, got1 := hc.GetValidator(tt.args.operatorAddress) + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("GetValidator() got = %v, want %v", got, tt.want) + } + if got1 != tt.want1 { + t.Errorf("GetValidator() got1 = %v, want %v", got1, tt.want1) + } + }) + } +} + +func validHostChain() *types.HostChain { + return &types.HostChain{ + ChainId: "chain-1", + ConnectionId: "connection-1", + Params: nil, + HostDenom: "uatom", + ChannelId: "channel-1", + PortId: "transfer", + DelegationAccount: nil, + RewardsAccount: nil, + Validators: []*types.Validator{{ + OperatorAddress: authtypes.NewModuleAddressOrBech32Address("testval2").String(), + Status: stakingtypes.BondStatusBonded, + Weight: sdk.MustNewDecFromStr("0.5"), + DelegatedAmount: sdk.OneInt(), + ExchangeRate: sdk.OneDec(), + UnbondingEpoch: 0, + }, { + OperatorAddress: authtypes.NewModuleAddressOrBech32Address("testval3").String(), + Status: stakingtypes.BondStatusBonded, + Weight: sdk.MustNewDecFromStr("0.3"), + DelegatedAmount: sdk.OneInt(), + ExchangeRate: sdk.OneDec(), + UnbondingEpoch: 0, + }}, + MinimumDeposit: sdk.OneInt(), + CValue: sdk.OneDec(), + LastCValue: sdk.OneDec(), + UnbondingFactor: 0, + Active: false, + AutoCompoundFactor: sdk.Dec{}, + } + +} +func makeVal(valoperAddr string) *types.Validator { + return &types.Validator{ + OperatorAddress: valoperAddr, + Status: stakingtypes.BondStatusBonded, + Weight: sdk.MustNewDecFromStr("0.2"), + DelegatedAmount: sdk.OneInt(), + ExchangeRate: sdk.OneDec(), + UnbondingEpoch: 0, + } +} diff --git a/x/liquidstakeibc/types/keys.go b/x/liquidstakeibc/types/keys.go index 2180a146b..827229634 100644 --- a/x/liquidstakeibc/types/keys.go +++ b/x/liquidstakeibc/types/keys.go @@ -36,6 +36,8 @@ const ( StakingStoreQuery = "store/staking/key" BankStoreQuery = "store/bank/key" + LiquidStakeDenomPrefix = "stk" + IBCTimeoutHeightIncrement uint64 = 1000 ICATimeoutTimestamp = 15 * time.Minute diff --git a/x/liquidstakeibc/types/liquidstakeibc.go b/x/liquidstakeibc/types/liquidstakeibc.go index 277c3244b..587a9f69c 100644 --- a/x/liquidstakeibc/types/liquidstakeibc.go +++ b/x/liquidstakeibc/types/liquidstakeibc.go @@ -2,6 +2,7 @@ package types import ( "fmt" + "strings" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/bech32" @@ -9,6 +10,10 @@ import ( stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" ) +func IsLiquidStakingDenom(denom string) bool { + return strings.HasPrefix(denom, fmt.Sprintf("%s/", LiquidStakeDenomPrefix)) +} + func IsUnbondingEpoch(factor, epochNumber int64) bool { return epochNumber%factor == 0 } diff --git a/x/liquidstakeibc/types/liquidstakeibc_test.go b/x/liquidstakeibc/types/liquidstakeibc_test.go index 108ae6ce5..657f1b2c8 100644 --- a/x/liquidstakeibc/types/liquidstakeibc_test.go +++ b/x/liquidstakeibc/types/liquidstakeibc_test.go @@ -5,6 +5,7 @@ import ( "time" "cosmossdk.io/math" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" sdk "github.com/cosmos/cosmos-sdk/types" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" @@ -15,6 +16,7 @@ import ( func init() { app.SetAddressPrefixes() + types.RegisterInterfaces(codectypes.NewInterfaceRegistry()) } func TestCurrentUnbondingEpoch(t *testing.T) { diff --git a/x/liquidstakeibc/types/msgs.go b/x/liquidstakeibc/types/msgs.go index 72562fa91..b400f197d 100644 --- a/x/liquidstakeibc/types/msgs.go +++ b/x/liquidstakeibc/types/msgs.go @@ -86,6 +86,10 @@ func (m *MsgRegisterHostChain) GetSigners() []sdk.AccAddress { } func (m *MsgRegisterHostChain) ValidateBasic() error { + if _, err := sdk.AccAddressFromBech32(m.Authority); err != nil { + return errorsmod.Wrapf(sdkerrors.ErrInvalidAddress, "invalid authority address %q: %v", m.Authority, err) + } + // connection id cannot be empty and must begin with "connection" if m.ConnectionId == "" { return errorsmod.Wrapf(sdkerrors.ErrInvalidRequest, "connection id cannot be empty") @@ -174,6 +178,9 @@ func (m *MsgUpdateHostChain) GetSigners() []sdk.AccAddress { } func (m *MsgUpdateHostChain) ValidateBasic() error { + if _, err := sdk.AccAddressFromBech32(m.Authority); err != nil { + return errorsmod.Wrapf(sdkerrors.ErrInvalidAddress, "invalid authority address %q: %v", m.Authority, err) + } return nil } @@ -270,6 +277,10 @@ func (m *MsgLiquidUnstake) ValidateBasic() error { return errorsmod.Wrap(sdkerrors.ErrInvalidCoins, m.Amount.String()) } + if !IsLiquidStakingDenom(m.Amount.Denom) { + return sdkerrors.ErrInvalidCoins.Wrapf("invalid denom, required stk/{host-denom} got %s", m.Amount.Denom) + } + return nil } @@ -318,6 +329,9 @@ func (m *MsgRedeem) ValidateBasic() error { return errorsmod.Wrap(sdkerrors.ErrInvalidCoins, m.Amount.String()) } + if !IsLiquidStakingDenom(m.Amount.Denom) { + return sdkerrors.ErrInvalidCoins.Wrapf("invalid denom, required stk/{host-denom} got %s", m.Amount.Denom) + } return nil } diff --git a/x/liquidstakeibc/types/msgs_test.go b/x/liquidstakeibc/types/msgs_test.go new file mode 100644 index 000000000..d6f47f1dd --- /dev/null +++ b/x/liquidstakeibc/types/msgs_test.go @@ -0,0 +1,226 @@ +package types_test + +import ( + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + "github.com/stretchr/testify/require" + + "github.com/persistenceOne/pstake-native/v2/x/liquidstakeibc/types" +) + +var ( + addr1 = authtypes.NewModuleAddressOrBech32Address("test1") + ibcDenom = "ibc/C4CFF46FD6DE35CA4CF4CE031E643C8FDC9BA4B99AE598E9B0ED98FE3A2319F9" + amount1 = sdk.NewInt64Coin(ibcDenom, 10000) + liquidstakedDenom = "stk/uatom" + stkAmount1 = sdk.NewInt64Coin(liquidstakedDenom, 10000) +) + +func TestMsgLiquidStake(t *testing.T) { + msgLiquidStake := &types.MsgLiquidStake{ + DelegatorAddress: addr1.String(), + Amount: amount1, + } + newMsgLiquidStake := types.NewMsgLiquidStake(amount1, addr1) + require.Equal(t, msgLiquidStake, newMsgLiquidStake) + require.Equal(t, types.ModuleName, msgLiquidStake.Route()) + require.Equal(t, types.MsgTypeLiquidStake, msgLiquidStake.Type()) + require.Equal(t, addr1, msgLiquidStake.GetSigners()[0]) + require.NotPanics(t, func() { msgLiquidStake.GetSignBytes() }) + + require.Equal(t, nil, msgLiquidStake.ValidateBasic()) + + invalidCoin := amount1 + invalidCoin.Amount = sdk.NewInt(-1) + invalidCoinMsg := types.NewMsgLiquidStake(invalidCoin, addr1) + require.Error(t, invalidCoinMsg.ValidateBasic()) + + zeroCoinMsg := types.NewMsgLiquidStake(sdk.NewCoin(ibcDenom, sdk.ZeroInt()), addr1) + require.Error(t, zeroCoinMsg.ValidateBasic()) + + invalidAddrMsg := types.NewMsgLiquidStake(amount1, sdk.AccAddress("test")) + require.Error(t, invalidAddrMsg.ValidateBasic()) + require.Panics(t, func() { invalidAddrMsg.GetSigners() }) +} +func TestMsgLiquidUnstake(t *testing.T) { + msgLiquidUnstake := &types.MsgLiquidUnstake{ + DelegatorAddress: addr1.String(), + Amount: stkAmount1, + } + newMsgLiquidUnstake := types.NewMsgLiquidUnstake(stkAmount1, addr1) + require.Equal(t, msgLiquidUnstake, newMsgLiquidUnstake) + require.Equal(t, types.ModuleName, msgLiquidUnstake.Route()) + require.Equal(t, types.MsgTypeLiquidUnstake, msgLiquidUnstake.Type()) + require.Equal(t, addr1, msgLiquidUnstake.GetSigners()[0]) + require.NotPanics(t, func() { msgLiquidUnstake.GetSignBytes() }) + + require.Equal(t, nil, msgLiquidUnstake.ValidateBasic()) + + invalidCoin := stkAmount1 + invalidCoin.Amount = sdk.NewInt(-10) + invalidCoinMsg := types.NewMsgLiquidUnstake(invalidCoin, addr1) + require.Error(t, invalidCoinMsg.ValidateBasic()) + + zeroCoinMsg := types.NewMsgLiquidUnstake(sdk.NewCoin(liquidstakedDenom, sdk.ZeroInt()), addr1) + require.Error(t, zeroCoinMsg.ValidateBasic()) + + invalidDenomMsg := types.NewMsgLiquidUnstake(amount1, addr1) + require.Error(t, invalidDenomMsg.ValidateBasic()) + + invalidAddrMsg := types.NewMsgLiquidUnstake(stkAmount1, sdk.AccAddress("test")) + require.Error(t, invalidAddrMsg.ValidateBasic()) + require.Panics(t, func() { invalidAddrMsg.GetSigners() }) +} +func TestMsgRedeem(t *testing.T) { + msgRedeem := &types.MsgRedeem{ + DelegatorAddress: addr1.String(), + Amount: stkAmount1, + } + newMsgRedeem := types.NewMsgRedeem(stkAmount1, addr1) + require.Equal(t, msgRedeem, newMsgRedeem) + require.Equal(t, types.ModuleName, msgRedeem.Route()) + require.Equal(t, types.MsgTypeRedeem, msgRedeem.Type()) + require.Equal(t, addr1, msgRedeem.GetSigners()[0]) + require.NotPanics(t, func() { msgRedeem.GetSignBytes() }) + + require.Equal(t, nil, msgRedeem.ValidateBasic()) + + invalidCoin := stkAmount1 + invalidCoin.Amount = sdk.NewInt(-10) + invalidCoinMsg := types.NewMsgRedeem(invalidCoin, addr1) + require.Error(t, invalidCoinMsg.ValidateBasic()) + + zeroCoinMsg := types.NewMsgRedeem(sdk.NewCoin(liquidstakedDenom, sdk.ZeroInt()), addr1) + require.Error(t, zeroCoinMsg.ValidateBasic()) + + invalidDenomMsg := types.NewMsgRedeem(amount1, addr1) + require.Error(t, invalidDenomMsg.ValidateBasic()) + + invalidAddrMsg := types.NewMsgRedeem(stkAmount1, sdk.AccAddress("test")) + require.Error(t, invalidAddrMsg.ValidateBasic()) + require.Panics(t, func() { invalidAddrMsg.GetSigners() }) +} + +func TestMsgRegisterHostChain(t *testing.T) { + msgRegisterHostChain := &types.MsgRegisterHostChain{ + Authority: addr1.String(), + ConnectionId: "connection-localhost", + DepositFee: sdk.ZeroDec(), + RestakeFee: sdk.ZeroDec(), + UnstakeFee: sdk.ZeroDec(), + RedemptionFee: sdk.ZeroDec(), + ChannelId: "channel-1", + PortId: "transfer", + HostDenom: "uatom", + MinimumDeposit: sdk.OneInt(), + UnbondingFactor: 4, + AutoCompoundFactor: 2, + } + newMsgRegisterHostChain := types.NewMsgRegisterHostChain("connection-localhost", "channel-1", "transfer", + "0", "0", "0", "0", "uatom", sdk.OneInt(), 4, + addr1.String(), 2) + require.Equal(t, msgRegisterHostChain, newMsgRegisterHostChain) + require.Equal(t, types.ModuleName, msgRegisterHostChain.Route()) + require.Equal(t, types.MsgTypeRegisterHostChain, msgRegisterHostChain.Type()) + require.Equal(t, addr1, msgRegisterHostChain.GetSigners()[0]) + require.NotPanics(t, func() { msgRegisterHostChain.GetSignBytes() }) + + require.Equal(t, nil, msgRegisterHostChain.ValidateBasic()) + + invalidAddrMsg := *msgRegisterHostChain + invalidAddrMsg.Authority = "test" + require.Error(t, invalidAddrMsg.ValidateBasic()) + require.Panics(t, func() { invalidAddrMsg.GetSigners() }) + + invalidMsg := *msgRegisterHostChain + invalidMsg.ConnectionId = "" + require.Error(t, invalidMsg.ValidateBasic()) + + invalidMsg = *msgRegisterHostChain + invalidMsg.ConnectionId = "notconnection-0" + require.Error(t, invalidMsg.ValidateBasic()) + + invalidMsg = *msgRegisterHostChain + invalidMsg.HostDenom = "s" // small denom invalid + require.Error(t, invalidMsg.ValidateBasic()) + + invalidMsg = *msgRegisterHostChain + invalidMsg.ChannelId = "notchannel-0" + require.Error(t, invalidMsg.ValidateBasic()) + + invalidMsg = *msgRegisterHostChain + invalidMsg.RestakeFee = sdk.MustNewDecFromStr("-1") + require.Error(t, invalidMsg.ValidateBasic()) + + invalidMsg = *msgRegisterHostChain + invalidMsg.DepositFee = sdk.MustNewDecFromStr("-1") + require.Error(t, invalidMsg.ValidateBasic()) + + invalidMsg = *msgRegisterHostChain + invalidMsg.UnstakeFee = sdk.MustNewDecFromStr("-1") + require.Error(t, invalidMsg.ValidateBasic()) + + invalidMsg = *msgRegisterHostChain + invalidMsg.RedemptionFee = sdk.MustNewDecFromStr("-1") + require.Error(t, invalidMsg.ValidateBasic()) +} + +func TestMsgUpdateHostChain(t *testing.T) { + msgUpdateHostChain := &types.MsgUpdateHostChain{ + Authority: addr1.String(), + ChainId: "chain-1", + Updates: []*types.KVUpdate{ + { + Key: "add_val", + Value: "cosmos1someval", + }, + }, + } + newMsgUpdateHostChain := types.NewMsgUpdateHostChain("chain-1", addr1.String(), []*types.KVUpdate{{ + Key: "add_val", + Value: "cosmos1someval", + }}) + require.Equal(t, msgUpdateHostChain, newMsgUpdateHostChain) + require.Equal(t, types.ModuleName, msgUpdateHostChain.Route()) + require.Equal(t, types.MsgTypeUpdateHostChain, msgUpdateHostChain.Type()) + require.Equal(t, addr1, msgUpdateHostChain.GetSigners()[0]) + require.NotPanics(t, func() { msgUpdateHostChain.GetSignBytes() }) + + require.Equal(t, nil, msgUpdateHostChain.ValidateBasic()) + + invalidAddrMsg := *msgUpdateHostChain + invalidAddrMsg.Authority = "test" + require.Error(t, invalidAddrMsg.ValidateBasic()) + require.Panics(t, func() { invalidAddrMsg.GetSigners() }) +} + +func TestMsgUpdateParams(t *testing.T) { + msgUpdateParams := &types.MsgUpdateParams{ + Authority: addr1.String(), + Params: types.DefaultParams(), + } + newMsgUpdateParams := types.NewMsgUpdateParams(addr1, types.DefaultParams()) + require.Equal(t, msgUpdateParams, newMsgUpdateParams) + require.Equal(t, types.ModuleName, msgUpdateParams.Route()) + require.Equal(t, types.MsgTypeUpdateParams, msgUpdateParams.Type()) + require.Equal(t, addr1, msgUpdateParams.GetSigners()[0]) + require.NotPanics(t, func() { msgUpdateParams.GetSignBytes() }) + + require.Equal(t, nil, msgUpdateParams.ValidateBasic()) + + invalidAddrMsg := types.NewMsgUpdateParams(sdk.AccAddress("test"), types.Params{ + AdminAddress: addr1.String(), + FeeAddress: addr1.String(), + UpperCValueLimit: sdk.OneDec(), + LowerCValueLimit: sdk.ZeroDec(), + }) + require.Error(t, invalidAddrMsg.ValidateBasic()) + require.Panics(t, func() { invalidAddrMsg.GetSigners() }) + + invalidParamsMsg := *msgUpdateParams + invalidParamsMsg.Params.AdminAddress = "test" + require.Error(t, invalidParamsMsg.ValidateBasic()) + +} From 5e6f4ffbaa5ff2305714c9d373293f92893bbb3e Mon Sep 17 00:00:00 2001 From: Puneet <59960662+puneet2019@users.noreply.github.com> Date: Tue, 11 Jul 2023 20:09:45 +0530 Subject: [PATCH 014/100] add more test cases (#567) * add more test cases * msgupdate hostchain refactor * lint --- x/liquidstakeibc/keeper/msg_server.go | 71 ++++---------- x/liquidstakeibc/types/keys.go | 16 ++++ x/liquidstakeibc/types/msgs.go | 133 ++++++++++++++++++++++++-- x/liquidstakeibc/types/msgs_test.go | 132 +++++++++++++++++++++++-- 4 files changed, 283 insertions(+), 69 deletions(-) diff --git a/x/liquidstakeibc/keeper/msg_server.go b/x/liquidstakeibc/keeper/msg_server.go index 6ab0256b6..16c374da3 100644 --- a/x/liquidstakeibc/keeper/msg_server.go +++ b/x/liquidstakeibc/keeper/msg_server.go @@ -17,21 +17,6 @@ import ( "github.com/persistenceOne/pstake-native/v2/x/liquidstakeibc/types" ) -const ( - KeyAddValidator string = "add_validator" - KeyRemoveValidator string = "remove_validator" - KeyValidatorSlashing string = "validator_slashing" - KeyValidatorWeight string = "validator_weight" - KeyDepositFee string = "deposit_fee" - KeyRestakeFee string = "restake_fee" - KeyUnstakeFee string = "unstake_fee" - KeyRedemptionFee string = "redemption_fee" - KeyMinimumDeposit string = "min_deposit" - KeyActive string = "active" - KeySetWithdrawAddress string = "set_withdraw_address" - KeyAutocompoundFactor string = "autocompound_factor" -) - type msgServer struct { Keeper } @@ -138,7 +123,7 @@ func (k msgServer) UpdateHostChain( for _, update := range msg.Updates { updateCase: switch update.Key { - case KeyAddValidator: + case types.KeyAddValidator: var validator types.Validator err := json.Unmarshal([]byte(update.Value), &validator) if err != nil { @@ -152,7 +137,7 @@ func (k msgServer) UpdateHostChain( hc.Validators = append(hc.Validators, &validator) k.SetHostChain(ctx, hc) - case KeyRemoveValidator: + case types.KeyRemoveValidator: for i, validator := range hc.Validators { if validator.OperatorAddress == update.Value { // remove just when there are no delegated tokens and weight is 0 @@ -169,7 +154,7 @@ func (k msgServer) UpdateHostChain( } return nil, types.ErrValidatorNotFound - case KeyValidatorSlashing: + case types.KeyValidatorSlashing: _, found = hc.GetValidator(update.Value) if !found { return nil, types.ErrValidatorNotFound @@ -178,7 +163,7 @@ func (k msgServer) UpdateHostChain( if err := k.QueryHostChainValidator(ctx, hc, update.Value); err != nil { return nil, fmt.Errorf("unable to send ICQ query for validator") } - case KeyValidatorWeight: + case types.KeyValidatorWeight: validator, weight, valid := strings.Cut(update.Value, ",") if !valid { return nil, fmt.Errorf("unable to parse validator update string") @@ -187,78 +172,62 @@ func (k msgServer) UpdateHostChain( if err := k.UpdateHostChainValidatorWeight(ctx, hc, validator, weight); err != nil { return nil, fmt.Errorf("invalid validator weight update values: %v", err) } - case KeyDepositFee: + case types.KeyDepositFee: fee, err := sdktypes.NewDecFromStr(update.Value) if err != nil { return nil, fmt.Errorf("unable to parse string to sdk.Dec: %w", err) } - + //fee limits validated in msg.ValidateBasic() hc.Params.DepositFee = fee - if fee.LT(sdktypes.NewDec(0)) { - return nil, fmt.Errorf("invalid deposit fee value, less than zero") - } - case KeyRestakeFee: + + case types.KeyRestakeFee: fee, err := sdktypes.NewDecFromStr(update.Value) if err != nil { return nil, fmt.Errorf("unable to parse string to sdk.Dec: %w", err) } - + //fee limits validated in msg.ValidateBasic() hc.Params.RestakeFee = fee - if fee.LT(sdktypes.NewDec(0)) { - return nil, fmt.Errorf("invalid deposit fee value, less than zero") - } - case KeyRedemptionFee: + + case types.KeyRedemptionFee: fee, err := sdktypes.NewDecFromStr(update.Value) if err != nil { return nil, fmt.Errorf("unable to parse string to sdk.Dec: %w", err) } - + //fee limits validated in msg.ValidateBasic() hc.Params.RedemptionFee = fee - if fee.LT(sdktypes.NewDec(0)) { - return nil, fmt.Errorf("invalid deposit fee value, less than zero") - } - case KeyUnstakeFee: + case types.KeyUnstakeFee: fee, err := sdktypes.NewDecFromStr(update.Value) if err != nil { return nil, fmt.Errorf("unable to parse string to sdk.Dec: %w", err) } - + //fee limits validated in msg.ValidateBasic() hc.Params.UnstakeFee = fee - if fee.LT(sdktypes.NewDec(0)) { - return nil, fmt.Errorf("invalid deposit fee value, less than zero") - } - case KeyMinimumDeposit: + case types.KeyMinimumDeposit: minimumDeposit, ok := sdktypes.NewIntFromString(update.Value) if !ok { return nil, fmt.Errorf("unable to parse string to sdk.Int") } - + //min deposit limits validated in msg.ValidateBasic() hc.MinimumDeposit = minimumDeposit - if minimumDeposit.LT(sdktypes.NewInt(0)) { - return nil, fmt.Errorf("invalid minimum deposit value less than zero") - } - case KeyActive: + case types.KeyActive: active, err := strconv.ParseBool(update.Value) if err != nil { return nil, fmt.Errorf("unable to parse string to bool") } hc.Active = active - case KeySetWithdrawAddress: + case types.KeySetWithdrawAddress: err := k.SetWithdrawAddress(ctx, hc) if err != nil { k.Logger(ctx).Error("Could not set withdraw address.", "chain_id", hc.ChainId) return nil, fmt.Errorf("could not set withdraw address for host chain %s", hc.ChainId) } - case KeyAutocompoundFactor: + case types.KeyAutocompoundFactor: autocompoundFactor, err := sdktypes.NewDecFromStr(update.Value) if err != nil { return nil, fmt.Errorf("unable to parse string to sdk.Dec") } - - if autocompoundFactor.LTE(sdktypes.NewDec(0)) { - return nil, fmt.Errorf("invalid autocompound factor value less or equal than zero") - } + //autoCompoundFactor limits validated in msg.ValidateBasic() hc.AutoCompoundFactor = k.CalculateAutocompoundLimit(autocompoundFactor) default: return nil, fmt.Errorf("invalid or unexpected update key: %s", update.Key) diff --git a/x/liquidstakeibc/types/keys.go b/x/liquidstakeibc/types/keys.go index 827229634..ac59f3324 100644 --- a/x/liquidstakeibc/types/keys.go +++ b/x/liquidstakeibc/types/keys.go @@ -45,6 +45,22 @@ const ( UnbondingStateEpochLimit = 4 ) +// Consts for KV updates, update host chain +const ( + KeyAddValidator string = "add_validator" + KeyRemoveValidator string = "remove_validator" + KeyValidatorSlashing string = "validator_slashing" + KeyValidatorWeight string = "validator_weight" + KeyDepositFee string = "deposit_fee" + KeyRestakeFee string = "restake_fee" + KeyUnstakeFee string = "unstake_fee" + KeyRedemptionFee string = "redemption_fee" + KeyMinimumDeposit string = "min_deposit" + KeyActive string = "active" + KeySetWithdrawAddress string = "set_withdraw_address" + KeyAutocompoundFactor string = "autocompound_factor" +) + var ( HostChainKey = []byte{0x01} DepositKey = []byte{0x02} diff --git a/x/liquidstakeibc/types/msgs.go b/x/liquidstakeibc/types/msgs.go index b400f197d..426b4d825 100644 --- a/x/liquidstakeibc/types/msgs.go +++ b/x/liquidstakeibc/types/msgs.go @@ -1,12 +1,15 @@ package types import ( + "encoding/json" "fmt" + "strconv" "strings" errorsmod "cosmossdk.io/errors" "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/bech32" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ibctransfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" connectiontypes "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" @@ -115,34 +118,40 @@ func (m *MsgRegisterHostChain) ValidateBasic() error { } // deposit fee must be positive or zero - if m.DepositFee.LT(sdk.NewDec(0)) { + if m.DepositFee.LT(sdk.ZeroDec()) || m.DepositFee.GT(sdk.OneDec()) { return errorsmod.Wrapf( sdkerrors.ErrInvalidRequest, - "deposit fee quantity must be greater or equal than zero", + "deposit fee quantity must be greater or equal than zero and less than equal one", ) } // restake fee must be positive or zero - if m.RestakeFee.LT(sdk.NewDec(0)) { + if m.RestakeFee.LT(sdk.ZeroDec()) || m.RestakeFee.GT(sdk.OneDec()) { return errorsmod.Wrapf( sdkerrors.ErrInvalidRequest, - "restake fee quantity must be greater or equal than zero", + "restake fee quantity must be greater or equal than zero and less than equal one", ) } // unstake fee must be positive or zero - if m.UnstakeFee.LT(sdk.NewDec(0)) { + if m.UnstakeFee.LT(sdk.ZeroDec()) || m.UnstakeFee.GT(sdk.OneDec()) { return errorsmod.Wrapf( sdkerrors.ErrInvalidRequest, - "unstake fee quantity must be greater or equal than zero", + "unstake fee quantity must be greater or equal than zero and less than equal one", ) } // redemption deposit must be positive or zero - if m.RedemptionFee.LT(sdk.NewDec(0)) { + if m.RedemptionFee.LT(sdk.ZeroDec()) || m.RedemptionFee.GT(sdk.OneDec()) { return errorsmod.Wrapf( sdkerrors.ErrInvalidRequest, - "redemption fee quantity must be greater or equal than zero", + "redemption fee quantity must be greater or equal than zero and less than equal one", + ) + } + + if m.MinimumDeposit.LTE(sdk.ZeroInt()) { + return sdkerrors.ErrInvalidRequest.Wrapf( + "minimum deposit should be greater than zero", ) } @@ -181,6 +190,114 @@ func (m *MsgUpdateHostChain) ValidateBasic() error { if _, err := sdk.AccAddressFromBech32(m.Authority); err != nil { return errorsmod.Wrapf(sdkerrors.ErrInvalidAddress, "invalid authority address %q: %v", m.Authority, err) } + for _, update := range m.Updates { + switch update.Key { + case KeyAddValidator: + var validator Validator + err := json.Unmarshal([]byte(update.Value), &validator) + if err != nil { + return fmt.Errorf("unable to unmarshal validator update string") + } + err = validator.Validate() + if err != nil { + return err + } + + case KeyRemoveValidator: + _, _, err := bech32.DecodeAndConvert(update.Value) + if err != nil { + return err + } + case KeyValidatorSlashing: + _, _, err := bech32.DecodeAndConvert(update.Value) + if err != nil { + return err + } + case KeyValidatorWeight: + validator, weight, valid := strings.Cut(update.Value, ",") + if !valid { + return fmt.Errorf("unable to parse validator update string") + } + _, _, err := bech32.DecodeAndConvert(validator) + if err != nil { + return err + } + decWt, err := sdk.NewDecFromStr(weight) + if err != nil { + return err + } + if decWt.GT(sdk.OneDec()) || decWt.LT(sdk.ZeroDec()) { + return fmt.Errorf("weight should be, 0 <= weight <= 1") + } + + case KeyDepositFee: + fee, err := sdk.NewDecFromStr(update.Value) + if err != nil { + return fmt.Errorf("unable to parse string to sdk.Dec: %w", err) + } + + if fee.LT(sdk.ZeroDec()) || fee.GT(sdk.OneDec()) { + return sdkerrors.ErrInvalidRequest.Wrapf("invalid deposit fee value should be 0 <= fee <= 1") + } + case KeyRestakeFee: + fee, err := sdk.NewDecFromStr(update.Value) + if err != nil { + return fmt.Errorf("unable to parse string to sdk.Dec: %w", err) + } + + if fee.LT(sdk.ZeroDec()) || fee.GT(sdk.OneDec()) { + return sdkerrors.ErrInvalidRequest.Wrapf("invalid restake fee value should be 0 <= fee <= 1") + } + case KeyRedemptionFee: + fee, err := sdk.NewDecFromStr(update.Value) + if err != nil { + return fmt.Errorf("unable to parse string to sdk.Dec: %w", err) + } + + if fee.LT(sdk.ZeroDec()) || fee.GT(sdk.OneDec()) { + return sdkerrors.ErrInvalidRequest.Wrapf("invalid redemption fee value should be 0 <= fee <= 1") + } + case KeyUnstakeFee: + fee, err := sdk.NewDecFromStr(update.Value) + if err != nil { + return fmt.Errorf("unable to parse string to sdk.Dec: %w", err) + } + + if fee.LT(sdk.ZeroDec()) || fee.GT(sdk.OneDec()) { + return sdkerrors.ErrInvalidRequest.Wrapf("invalid unstake fee value should be 0 <= fee <= 1") + } + case KeyMinimumDeposit: + minimumDeposit, ok := sdk.NewIntFromString(update.Value) + if !ok { + return sdkerrors.ErrInvalidRequest.Wrapf("") + } + + if minimumDeposit.LTE(sdk.ZeroInt()) { + return fmt.Errorf("invalid minimum deposit value less or equal than zero") + } + case KeyActive: + _, err := strconv.ParseBool(update.Value) + if err != nil { + return fmt.Errorf("unable to parse string to bool") + } + case KeySetWithdrawAddress: + if update.Value != "" { + return fmt.Errorf("expected value for key:SetWithdrawAddress is empty") + } + case KeyAutocompoundFactor: + autocompoundFactor, err := sdk.NewDecFromStr(update.Value) + if err != nil { + return fmt.Errorf("unable to parse string to sdk.Dec") + } + + if autocompoundFactor.LTE(sdk.ZeroDec()) { + return fmt.Errorf("invalid autocompound factor value less or equal than zero") + } + default: + return fmt.Errorf("invalid or unexpected update key: %s", update.Key) + } + } + return nil } diff --git a/x/liquidstakeibc/types/msgs_test.go b/x/liquidstakeibc/types/msgs_test.go index d6f47f1dd..764c9f220 100644 --- a/x/liquidstakeibc/types/msgs_test.go +++ b/x/liquidstakeibc/types/msgs_test.go @@ -165,23 +165,58 @@ func TestMsgRegisterHostChain(t *testing.T) { invalidMsg = *msgRegisterHostChain invalidMsg.RedemptionFee = sdk.MustNewDecFromStr("-1") require.Error(t, invalidMsg.ValidateBasic()) + + invalidMsg = *msgRegisterHostChain + invalidMsg.MinimumDeposit = sdk.ZeroInt() + require.Error(t, invalidMsg.ValidateBasic()) } func TestMsgUpdateHostChain(t *testing.T) { + validKVUpdates := []*types.KVUpdate{ + { + Key: types.KeySetWithdrawAddress, + Value: "", + }, { + Key: types.KeyAddValidator, + Value: "{\"operator_address\":\"cosmosvaloper1hcqg5wj9t42zawqkqucs7la85ffyv08le09ljt\",\"status\":\"BOND_STATUS_UNSPECIFIED\",\"weight\":\"0\",\"delegated_amount\":\"0\",\"exchange_rate\":\"1\"}", + }, { + Key: types.KeyRemoveValidator, + Value: "cosmosvaloper1hcqg5wj9t42zawqkqucs7la85ffyv08le09ljt", + }, { + Key: types.KeyValidatorSlashing, + Value: "cosmosvaloper1hcqg5wj9t42zawqkqucs7la85ffyv08le09ljt", + }, { + Key: types.KeyValidatorWeight, + Value: "cosmosvaloper1hcqg5wj9t42zawqkqucs7la85ffyv08le09ljt,1", + }, { + Key: types.KeyRedemptionFee, + Value: "0", + }, { + Key: types.KeyDepositFee, + Value: "0", + }, { + Key: types.KeyRestakeFee, + Value: "0", + }, { + Key: types.KeyUnstakeFee, + Value: "0", + }, { + Key: types.KeyMinimumDeposit, + Value: "1", + }, { + Key: types.KeyActive, + Value: "true", + }, { + Key: types.KeyAutocompoundFactor, + Value: "2", + }, + } msgUpdateHostChain := &types.MsgUpdateHostChain{ Authority: addr1.String(), ChainId: "chain-1", - Updates: []*types.KVUpdate{ - { - Key: "add_val", - Value: "cosmos1someval", - }, - }, + Updates: validKVUpdates, } - newMsgUpdateHostChain := types.NewMsgUpdateHostChain("chain-1", addr1.String(), []*types.KVUpdate{{ - Key: "add_val", - Value: "cosmos1someval", - }}) + newMsgUpdateHostChain := types.NewMsgUpdateHostChain("chain-1", addr1.String(), validKVUpdates) require.Equal(t, msgUpdateHostChain, newMsgUpdateHostChain) require.Equal(t, types.ModuleName, msgUpdateHostChain.Route()) require.Equal(t, types.MsgTypeUpdateHostChain, msgUpdateHostChain.Type()) @@ -194,6 +229,83 @@ func TestMsgUpdateHostChain(t *testing.T) { invalidAddrMsg.Authority = "test" require.Error(t, invalidAddrMsg.ValidateBasic()) require.Panics(t, func() { invalidAddrMsg.GetSigners() }) + + invalidKVUpdates := []*types.KVUpdate{ + { + Key: types.KeyAddValidator, + Value: "InvalidJson", + }, { + Key: types.KeyAddValidator, + Value: "{\"operator_address\":\"cosmosvaloper1hcqg5wj9t42zawqkqucs7la85ffyv08le09ljt\"}", + }, { + Key: types.KeyRemoveValidator, + Value: "testval", + }, { + Key: types.KeyValidatorSlashing, + Value: "testval", + }, { + Key: types.KeyValidatorWeight, + Value: "testval", + }, { + Key: types.KeyValidatorWeight, + Value: "testval,1", + }, { + Key: types.KeyValidatorWeight, + Value: "cosmosvaloper1hcqg5wj9t42zawqkqucs7la85ffyv08le09ljt,2", + }, { + Key: types.KeyValidatorWeight, + Value: "cosmosvaloper1hcqg5wj9t42zawqkqucs7la85ffyv08le09ljt,invalidDec", + }, { + Key: types.KeyDepositFee, + Value: "2", + }, { + Key: types.KeyDepositFee, + Value: "InvalidDec", + }, { + Key: types.KeyRestakeFee, + Value: "2", + }, { + Key: types.KeyRestakeFee, + Value: "InvalidDec", + }, { + Key: types.KeyUnstakeFee, + Value: "2", + }, { + Key: types.KeyUnstakeFee, + Value: "invalidDec", + }, { + Key: types.KeyRedemptionFee, + Value: "2", + }, { + Key: types.KeyRedemptionFee, + Value: "invalidDec", + }, { + Key: types.KeyMinimumDeposit, + Value: "0", + }, { + Key: types.KeyMinimumDeposit, + Value: "InvalidInt", + }, { + Key: types.KeyActive, + Value: "not bool", + }, { + Key: types.KeySetWithdrawAddress, + Value: "SomeStrHere", + }, { + Key: types.KeyAutocompoundFactor, + Value: "0", + }, { + Key: types.KeyAutocompoundFactor, + Value: "InvalidDec", + }, { + Key: "InvalidKey", + Value: "InvalidKey", + }, + } + for _, update := range invalidKVUpdates { + invalidMsg := types.NewMsgUpdateHostChain("chain-1", addr1.String(), []*types.KVUpdate{update}) + require.Error(t, invalidMsg.ValidateBasic()) + } } func TestMsgUpdateParams(t *testing.T) { From f302721d93092dd4dbffd6df7afae235d2d8f474 Mon Sep 17 00:00:00 2001 From: Puneet <59960662+puneet2019@users.noreply.github.com> Date: Tue, 11 Jul 2023 20:16:12 +0530 Subject: [PATCH 015/100] edit keeper test setup. (#568) --- x/liquidstakeibc/keeper/deposit_test.go | 10 +++++----- x/liquidstakeibc/keeper/keeper_test.go | 25 +++++++++---------------- 2 files changed, 14 insertions(+), 21 deletions(-) diff --git a/x/liquidstakeibc/keeper/deposit_test.go b/x/liquidstakeibc/keeper/deposit_test.go index 2e7b33270..5f9e738f6 100644 --- a/x/liquidstakeibc/keeper/deposit_test.go +++ b/x/liquidstakeibc/keeper/deposit_test.go @@ -99,7 +99,7 @@ func (suite *IntegrationTestSuite) TestAdjustDepositsForRedemption() { }, }, expected: map[int64]sdk.Coin{ - 1: {Denom: HostDenom, Amount: sdk.NewInt(5000)}, + epoch: {Denom: HostDenom, Amount: sdk.NewInt(5000)}, }, redemptionAmount: sdk.Coin{Denom: HostDenom, Amount: sdk.NewInt(5000)}, }, @@ -114,7 +114,7 @@ func (suite *IntegrationTestSuite) TestAdjustDepositsForRedemption() { }, }, expected: map[int64]sdk.Coin{ - 1: {Denom: HostDenom, Amount: sdk.NewInt(3500)}, + epoch: {Denom: HostDenom, Amount: sdk.NewInt(3500)}, }, redemptionAmount: sdk.Coin{Denom: HostDenom, Amount: sdk.NewInt(5000)}, }, @@ -148,8 +148,8 @@ func (suite *IntegrationTestSuite) TestAdjustDepositsForRedemption() { }, }, expected: map[int64]sdk.Coin{ - 1: {Denom: HostDenom, Amount: sdk.NewInt(5000)}, - 2: {Denom: HostDenom, Amount: sdk.NewInt(5000)}, + epoch: {Denom: HostDenom, Amount: sdk.NewInt(5000)}, + epoch + 1: {Denom: HostDenom, Amount: sdk.NewInt(5000)}, }, redemptionAmount: sdk.Coin{Denom: HostDenom, Amount: sdk.NewInt(5000)}, }, @@ -170,7 +170,7 @@ func (suite *IntegrationTestSuite) TestAdjustDepositsForRedemption() { }, }, expected: map[int64]sdk.Coin{ - 2: {Denom: HostDenom, Amount: sdk.NewInt(5000)}, + epoch + 1: {Denom: HostDenom, Amount: sdk.NewInt(5000)}, }, redemptionAmount: sdk.Coin{Denom: HostDenom, Amount: sdk.NewInt(10000)}, }, diff --git a/x/liquidstakeibc/keeper/keeper_test.go b/x/liquidstakeibc/keeper/keeper_test.go index 061c45671..0955ac780 100644 --- a/x/liquidstakeibc/keeper/keeper_test.go +++ b/x/liquidstakeibc/keeper/keeper_test.go @@ -2,15 +2,11 @@ package keeper_test import ( "testing" - "time" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/bank/testutil" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" - connectiontypes "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" - ibctmtypes "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" ibctesting "github.com/cosmos/ibc-go/v7/testing" "github.com/stretchr/testify/suite" @@ -52,15 +48,7 @@ func TestKeeperTestSuite(t *testing.T) { } func (suite *IntegrationTestSuite) SetupTest() { - _, pstakeApp, ctx := helpers.CreateTestApp(suite.T()) - - keeper := pstakeApp.LiquidStakeIBCKeeper - - params := types.DefaultParams() - keeper.SetParams(ctx, params) - - suite.app = &pstakeApp - suite.ctx = ctx + //_, pstakeApp, ctx := helpers.CreateTestApp(suite.T()) suite.coordinator = ibctesting.NewCoordinator(suite.T(), 2) suite.chainA = suite.coordinator.GetChain(ibctesting.GetChainID(1)) @@ -71,6 +59,14 @@ func (suite *IntegrationTestSuite) SetupTest() { suite.path.EndpointB.ChannelConfig.PortID = ibctesting.TransferPort suite.coordinator.SetupConnections(suite.path) + suite.app = suite.chainA.App.(*app.PstakeApp) + suite.ctx = suite.chainA.GetContext() + + keeper := suite.app.LiquidStakeIBCKeeper + + params := types.DefaultParams() + keeper.SetParams(suite.ctx, params) + // set host chain params depositFee, err := sdk.NewDecFromStr("0.01") suite.NoError(err) @@ -128,9 +124,6 @@ func (suite *IntegrationTestSuite) SetupTest() { suite.app.LiquidStakeIBCKeeper.SetHostChain(suite.ctx, hc) - pstakeApp.IBCKeeper.ClientKeeper.SetClientState(ctx, "07-tendermint-0", &ibctmtypes.ClientState{ChainId: suite.chainB.ChainID, TrustingPeriod: time.Hour, LatestHeight: clienttypes.Height{RevisionNumber: 1, RevisionHeight: 100}}) - pstakeApp.IBCKeeper.ClientKeeper.SetClientConsensusState(ctx, "07-tendermint-0", clienttypes.Height{RevisionNumber: 1, RevisionHeight: 100}, &ibctmtypes.ConsensusState{Timestamp: ctx.BlockTime()}) - pstakeApp.IBCKeeper.ConnectionKeeper.SetConnection(ctx, suite.path.EndpointA.ConnectionID, connectiontypes.ConnectionEnd{ClientId: "07-tendermint-0"}) } func (suite *IntegrationTestSuite) TestGetSetParams() { From f93955cab47a9f0d2ecc36752fea0a8e5e418ecb Mon Sep 17 00:00:00 2001 From: Puneet <59960662+puneet2019@users.noreply.github.com> Date: Tue, 11 Jul 2023 23:03:16 +0530 Subject: [PATCH 016/100] tests for deposit.go (#570) --- x/liquidstakeibc/keeper/deposit.go | 7 +-- x/liquidstakeibc/keeper/deposit_test.go | 65 +++++++++++++++++++++++++ 2 files changed, 69 insertions(+), 3 deletions(-) diff --git a/x/liquidstakeibc/keeper/deposit.go b/x/liquidstakeibc/keeper/deposit.go index 50d2d8ace..aafce4b9d 100644 --- a/x/liquidstakeibc/keeper/deposit.go +++ b/x/liquidstakeibc/keeper/deposit.go @@ -3,6 +3,7 @@ package keeper import ( "strconv" + "cosmossdk.io/math" "github.com/cosmos/cosmos-sdk/store/prefix" sdk "github.com/cosmos/cosmos-sdk/types" @@ -175,7 +176,7 @@ func (k *Keeper) GetPendingDepositsBeforeEpoch(ctx sdk.Context, epoch int64) []* func (k *Keeper) GetRedeemableDepositsForHostChain( ctx sdk.Context, hc *liquidstakeibctypes.HostChain, -) ([]*liquidstakeibctypes.Deposit, sdk.Int) { //nolint:staticcheck +) ([]*liquidstakeibctypes.Deposit, math.Int) { store := prefix.NewStore(ctx.KVStore(k.storeKey), liquidstakeibctypes.DepositKey) iterator := sdk.KVStorePrefixIterator(store, nil) defer iterator.Close() @@ -235,7 +236,7 @@ func (k *Keeper) GetDelegatingDepositsForChain(ctx sdk.Context, chainID string) return deposits } -func (k *Keeper) GetDepositAmountOnPersistence(ctx sdk.Context, chainID string) sdk.Int { //nolint:staticcheck +func (k *Keeper) GetDepositAmountOnPersistence(ctx sdk.Context, chainID string) math.Int { store := prefix.NewStore(ctx.KVStore(k.storeKey), liquidstakeibctypes.DepositKey) iterator := sdk.KVStorePrefixIterator(store, nil) defer iterator.Close() @@ -255,7 +256,7 @@ func (k *Keeper) GetDepositAmountOnPersistence(ctx sdk.Context, chainID string) return amount } -func (k *Keeper) GetDepositAmountOnHostChain(ctx sdk.Context, chainID string) sdk.Int { //nolint:staticcheck +func (k *Keeper) GetDepositAmountOnHostChain(ctx sdk.Context, chainID string) math.Int { store := prefix.NewStore(ctx.KVStore(k.storeKey), liquidstakeibctypes.DepositKey) iterator := sdk.KVStorePrefixIterator(store, nil) defer iterator.Close() diff --git a/x/liquidstakeibc/keeper/deposit_test.go b/x/liquidstakeibc/keeper/deposit_test.go index 5f9e738f6..88a5b0935 100644 --- a/x/liquidstakeibc/keeper/deposit_test.go +++ b/x/liquidstakeibc/keeper/deposit_test.go @@ -1,6 +1,7 @@ package keeper_test import ( + "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/persistenceOne/pstake-native/v2/x/liquidstakeibc/types" @@ -490,3 +491,67 @@ func (suite *IntegrationTestSuite) TestGetDelegatingDepositsForChain() { }) } } + +func (suite *IntegrationTestSuite) TestGetDepositAmountOnPersistence() { + + tc := []struct { + name string + deposits []types.Deposit + chainID string + expected math.Int + }{ + { + name: "found test", + deposits: []types.Deposit{ + {Amount: sdk.NewInt64Coin("ibc/uatom", 1), ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: 1, State: types.Deposit_DEPOSIT_PENDING}, + {Amount: sdk.NewInt64Coin("ibc/uatom", 2), ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: 2, State: types.Deposit_DEPOSIT_SENT}, + {Amount: sdk.NewInt64Coin("ibc/uatom", 3), ChainId: suite.path.EndpointA.Chain.ChainID, Epoch: 2, State: types.Deposit_DEPOSIT_SENT}, + {Amount: sdk.NewInt64Coin("ibc/uatom", 4), ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: 3, State: types.Deposit_DEPOSIT_DELEGATING}, + {Amount: sdk.NewInt64Coin("ibc/uatom", 5), ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: 4, State: types.Deposit_DEPOSIT_RECEIVED}, + }, + chainID: suite.path.EndpointB.Chain.ChainID, + expected: sdk.NewInt(3), + }} + for _, t := range tc { + suite.Run(t.name, func() { + for _, deposit := range t.deposits { + suite.app.LiquidStakeIBCKeeper.SetDeposit(suite.ctx, &deposit) + } + + amt := suite.app.LiquidStakeIBCKeeper.GetDepositAmountOnPersistence(suite.ctx, t.chainID) + suite.Require().Equal(t.expected, amt) + + }) + } +} +func (suite *IntegrationTestSuite) TestGetDepositAmountOnHostChain() { + tc := []struct { + name string + deposits []types.Deposit + chainID string + expected math.Int + }{ + { + name: "found test", + deposits: []types.Deposit{ + {Amount: sdk.NewInt64Coin("ibc/uatom", 1), ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: 1, State: types.Deposit_DEPOSIT_PENDING}, + {Amount: sdk.NewInt64Coin("ibc/uatom", 2), ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: 2, State: types.Deposit_DEPOSIT_SENT}, + {Amount: sdk.NewInt64Coin("ibc/uatom", 3), ChainId: suite.path.EndpointA.Chain.ChainID, Epoch: 2, State: types.Deposit_DEPOSIT_SENT}, + {Amount: sdk.NewInt64Coin("ibc/uatom", 4), ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: 3, State: types.Deposit_DEPOSIT_DELEGATING}, + {Amount: sdk.NewInt64Coin("ibc/uatom", 5), ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: 4, State: types.Deposit_DEPOSIT_RECEIVED}, + }, + chainID: suite.path.EndpointB.Chain.ChainID, + expected: sdk.NewInt(9), + }} + for _, t := range tc { + suite.Run(t.name, func() { + for _, deposit := range t.deposits { + suite.app.LiquidStakeIBCKeeper.SetDeposit(suite.ctx, &deposit) + } + + amt := suite.app.LiquidStakeIBCKeeper.GetDepositAmountOnHostChain(suite.ctx, t.chainID) + suite.Require().Equal(t.expected, amt) + + }) + } +} From 070bdbf2eede625501962efd122035948521a2a6 Mon Sep 17 00:00:00 2001 From: Puneet <59960662+puneet2019@users.noreply.github.com> Date: Tue, 11 Jul 2023 23:03:41 +0530 Subject: [PATCH 017/100] remove unused file (#569) --- x/liquidstakeibc/types/delegation_strategy.go | 10 ---------- 1 file changed, 10 deletions(-) delete mode 100644 x/liquidstakeibc/types/delegation_strategy.go diff --git a/x/liquidstakeibc/types/delegation_strategy.go b/x/liquidstakeibc/types/delegation_strategy.go deleted file mode 100644 index 801e11a13..000000000 --- a/x/liquidstakeibc/types/delegation_strategy.go +++ /dev/null @@ -1,10 +0,0 @@ -package types - -import ( - sdk "github.com/cosmos/cosmos-sdk/types" -) - -type ValidatorDelegation struct { - ValidatorAddress string - DelegationAmount sdk.Coin -} From d6aa55d9d091a760c5f8488c1adf6ef891c0196f Mon Sep 17 00:00:00 2001 From: Puneet <59960662+puneet2019@users.noreply.github.com> Date: Wed, 12 Jul 2023 13:11:32 +0530 Subject: [PATCH 018/100] delegation_strategy_test.go 100% (#571) --- x/liquidstakeibc/keeper/delegation_strategy.go | 9 +++++---- x/liquidstakeibc/keeper/delegation_strategy_test.go | 10 +++++----- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/x/liquidstakeibc/keeper/delegation_strategy.go b/x/liquidstakeibc/keeper/delegation_strategy.go index 538ebd8e9..541a13959 100644 --- a/x/liquidstakeibc/keeper/delegation_strategy.go +++ b/x/liquidstakeibc/keeper/delegation_strategy.go @@ -2,6 +2,7 @@ package keeper import ( errorsmod "cosmossdk.io/errors" + "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/cosmos/gogoproto/proto" @@ -15,17 +16,17 @@ type DelegateAmount struct { Amount sdk.Dec } -func (k *Keeper) GenerateDelegateMessages(hc *types.HostChain, depositAmount sdk.Int) ([]proto.Message, error) { //nolint:staticcheck +func (k *Keeper) GenerateDelegateMessages(hc *types.HostChain, depositAmount math.Int) ([]proto.Message, error) { return k.generateMessages(hc, depositAmount, false) } -func (k *Keeper) GenerateUndelegateMessages(hc *types.HostChain, unbondAmount sdk.Int) ([]proto.Message, error) { //nolint:staticcheck +func (k *Keeper) GenerateUndelegateMessages(hc *types.HostChain, unbondAmount math.Int) ([]proto.Message, error) { return k.generateMessages(hc, unbondAmount, true) } func (k *Keeper) generateMessages( hc *types.HostChain, - actionableAmount sdk.Int, //nolint:staticcheck + actionableAmount math.Int, undelegating bool, ) ([]proto.Message, error) { delegateAmounts := make([]DelegateAmount, 0) @@ -86,7 +87,7 @@ func (k *Keeper) generateMessages( } messages = append(messages, message) - return messages, nil + break } // add the amount to the message and append it diff --git a/x/liquidstakeibc/keeper/delegation_strategy_test.go b/x/liquidstakeibc/keeper/delegation_strategy_test.go index 50f5931e1..459fbd25d 100644 --- a/x/liquidstakeibc/keeper/delegation_strategy_test.go +++ b/x/liquidstakeibc/keeper/delegation_strategy_test.go @@ -141,31 +141,31 @@ func (suite *IntegrationTestSuite) TestGenerateDelegateMessages() { validators: []*types.Validator{ { OperatorAddress: hc.Validators[0].OperatorAddress, - Weight: decFromStr("0"), + Weight: decFromStr("0.2"), DelegatedAmount: sdk.NewInt(0), Status: stakingtypes.BondStatusBonded, }, { OperatorAddress: hc.Validators[1].OperatorAddress, - Weight: decFromStr("0"), + Weight: decFromStr("0.2"), DelegatedAmount: sdk.NewInt(0), Status: stakingtypes.BondStatusBonded, }, { OperatorAddress: hc.Validators[2].OperatorAddress, - Weight: decFromStr("0"), + Weight: decFromStr("0.33"), DelegatedAmount: sdk.NewInt(0), Status: stakingtypes.BondStatusBonded, }, { OperatorAddress: hc.Validators[3].OperatorAddress, - Weight: decFromStr("0"), + Weight: decFromStr("0.27"), DelegatedAmount: sdk.NewInt(0), Status: stakingtypes.BondStatusBonded, }, }, expected: map[string]int64{}, - totalDelegationAmount: int64(100), + totalDelegationAmount: int64(0), err: errorsmod.Wrap(types.ErrInvalidMessages, "no messages to delegate"), }, } From dfac4081759306e22fd2d0ce177b2869c90e47d0 Mon Sep 17 00:00:00 2001 From: Puneet <59960662+puneet2019@users.noreply.github.com> Date: Wed, 12 Jul 2023 15:19:05 +0530 Subject: [PATCH 019/100] chainID usage, grpc querier test. (#573) --- .../keeper/delegation_strategy_test.go | 4 +- x/liquidstakeibc/keeper/deposit_test.go | 100 +++++++------- x/liquidstakeibc/keeper/grpc_querier_test.go | 127 +++++++++++++++++- x/liquidstakeibc/keeper/host_chain_test.go | 14 +- x/liquidstakeibc/keeper/keeper_test.go | 8 +- x/liquidstakeibc/keeper/unbonding_test.go | 38 +++--- .../keeper/user_unbonding_test.go | 16 +-- .../keeper/validator_unbonding_test.go | 26 ++-- 8 files changed, 223 insertions(+), 110 deletions(-) diff --git a/x/liquidstakeibc/keeper/delegation_strategy_test.go b/x/liquidstakeibc/keeper/delegation_strategy_test.go index 459fbd25d..2857adde2 100644 --- a/x/liquidstakeibc/keeper/delegation_strategy_test.go +++ b/x/liquidstakeibc/keeper/delegation_strategy_test.go @@ -15,7 +15,7 @@ func decFromStr(str string) sdk.Dec { } func (suite *IntegrationTestSuite) TestGenerateDelegateMessages() { - hc, found := suite.app.LiquidStakeIBCKeeper.GetHostChain(suite.ctx, suite.path.EndpointB.Chain.ChainID) + hc, found := suite.app.LiquidStakeIBCKeeper.GetHostChain(suite.ctx, suite.chainB.ChainID) suite.Require().Equal(found, true) tc := []struct { @@ -198,7 +198,7 @@ func (suite *IntegrationTestSuite) TestGenerateDelegateMessages() { } func (suite *IntegrationTestSuite) TestGenerateUndelegateMessages() { - hc, found := suite.app.LiquidStakeIBCKeeper.GetHostChain(suite.ctx, suite.path.EndpointB.Chain.ChainID) + hc, found := suite.app.LiquidStakeIBCKeeper.GetHostChain(suite.ctx, suite.chainB.ChainID) suite.Require().Equal(found, true) tc := []struct { diff --git a/x/liquidstakeibc/keeper/deposit_test.go b/x/liquidstakeibc/keeper/deposit_test.go index 88a5b0935..b1f7111d5 100644 --- a/x/liquidstakeibc/keeper/deposit_test.go +++ b/x/liquidstakeibc/keeper/deposit_test.go @@ -8,15 +8,15 @@ import ( ) func (suite *IntegrationTestSuite) TestGetSetDeposit() { - suite.app.LiquidStakeIBCKeeper.SetDeposit(suite.ctx, &types.Deposit{ChainId: suite.path.EndpointB.Chain.ChainID}) + suite.app.LiquidStakeIBCKeeper.SetDeposit(suite.ctx, &types.Deposit{ChainId: suite.chainB.ChainID}) deposits := suite.app.LiquidStakeIBCKeeper.GetAllDeposits(suite.ctx) suite.Require().Equal(1, len(deposits)) - suite.Require().Equal(suite.path.EndpointB.Chain.ChainID, deposits[0].ChainId) + suite.Require().Equal(suite.chainB.ChainID, deposits[0].ChainId) } func (suite *IntegrationTestSuite) TestDeleteDeposit() { - deposit := &types.Deposit{ChainId: suite.path.EndpointB.Chain.ChainID} + deposit := &types.Deposit{ChainId: suite.chainB.ChainID} suite.app.LiquidStakeIBCKeeper.SetDeposit(suite.ctx, deposit) suite.app.LiquidStakeIBCKeeper.DeleteDeposit(suite.ctx, deposit) @@ -93,7 +93,7 @@ func (suite *IntegrationTestSuite) TestAdjustDepositsForRedemption() { name: "Case 1", deposits: []*types.Deposit{ { - ChainId: suite.path.EndpointB.Chain.ChainID, + ChainId: suite.chainB.ChainID, Epoch: epoch, Amount: sdk.Coin{Denom: HostDenom, Amount: sdk.NewInt(10000)}, State: types.Deposit_DEPOSIT_PENDING, @@ -108,7 +108,7 @@ func (suite *IntegrationTestSuite) TestAdjustDepositsForRedemption() { name: "Case 2", deposits: []*types.Deposit{ { - ChainId: suite.path.EndpointB.Chain.ChainID, + ChainId: suite.chainB.ChainID, Epoch: epoch, Amount: sdk.Coin{Denom: HostDenom, Amount: sdk.NewInt(3500)}, State: types.Deposit_DEPOSIT_PENDING, @@ -123,7 +123,7 @@ func (suite *IntegrationTestSuite) TestAdjustDepositsForRedemption() { name: "Case 3", deposits: []*types.Deposit{ { - ChainId: suite.path.EndpointB.Chain.ChainID, + ChainId: suite.chainB.ChainID, Epoch: epoch, Amount: sdk.Coin{Denom: HostDenom, Amount: sdk.NewInt(5000)}, State: types.Deposit_DEPOSIT_PENDING, @@ -136,13 +136,13 @@ func (suite *IntegrationTestSuite) TestAdjustDepositsForRedemption() { name: "Case 4", deposits: []*types.Deposit{ { - ChainId: suite.path.EndpointB.Chain.ChainID, + ChainId: suite.chainB.ChainID, Epoch: epoch, Amount: sdk.Coin{Denom: HostDenom, Amount: sdk.NewInt(10000)}, State: types.Deposit_DEPOSIT_PENDING, }, { - ChainId: suite.path.EndpointB.Chain.ChainID, + ChainId: suite.chainB.ChainID, Epoch: epoch + 1, Amount: sdk.Coin{Denom: HostDenom, Amount: sdk.NewInt(5000)}, State: types.Deposit_DEPOSIT_PENDING, @@ -158,13 +158,13 @@ func (suite *IntegrationTestSuite) TestAdjustDepositsForRedemption() { name: "Case 5", deposits: []*types.Deposit{ { - ChainId: suite.path.EndpointB.Chain.ChainID, + ChainId: suite.chainB.ChainID, Epoch: epoch, Amount: sdk.Coin{Denom: HostDenom, Amount: sdk.NewInt(5000)}, State: types.Deposit_DEPOSIT_PENDING, }, { - ChainId: suite.path.EndpointB.Chain.ChainID, + ChainId: suite.chainB.ChainID, Epoch: epoch + 1, Amount: sdk.Coin{Denom: HostDenom, Amount: sdk.NewInt(10000)}, State: types.Deposit_DEPOSIT_PENDING, @@ -179,13 +179,13 @@ func (suite *IntegrationTestSuite) TestAdjustDepositsForRedemption() { name: "Case 6", deposits: []*types.Deposit{ { - ChainId: suite.path.EndpointB.Chain.ChainID, + ChainId: suite.chainB.ChainID, Epoch: epoch, Amount: sdk.Coin{Denom: HostDenom, Amount: sdk.NewInt(10000)}, State: types.Deposit_DEPOSIT_PENDING, }, { - ChainId: suite.path.EndpointB.Chain.ChainID, + ChainId: suite.chainB.ChainID, Epoch: epoch + 1, Amount: sdk.Coin{Denom: HostDenom, Amount: sdk.NewInt(5000)}, State: types.Deposit_DEPOSIT_PENDING, @@ -205,7 +205,7 @@ func (suite *IntegrationTestSuite) TestAdjustDepositsForRedemption() { err := suite.app.LiquidStakeIBCKeeper.AdjustDepositsForRedemption( suite.ctx, - &types.HostChain{ChainId: suite.path.EndpointB.Chain.ChainID}, + &types.HostChain{ChainId: suite.chainB.ChainID}, t.redemptionAmount, ) @@ -235,25 +235,25 @@ func (suite *IntegrationTestSuite) TestGetDepositForChainAndEpoch() { { name: "Success", deposits: []types.Deposit{ - {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: epoch}, - {ChainId: suite.path.EndpointA.Chain.ChainID, Epoch: epoch + 1}, - {ChainId: suite.path.EndpointA.Chain.ChainID, Epoch: epoch}, - {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: epoch + 1}, + {ChainId: suite.chainB.ChainID, Epoch: epoch}, + {ChainId: suite.chainA.ChainID, Epoch: epoch + 1}, + {ChainId: suite.chainA.ChainID, Epoch: epoch}, + {ChainId: suite.chainB.ChainID, Epoch: epoch + 1}, }, - chainID: suite.path.EndpointB.Chain.ChainID, + chainID: suite.chainB.ChainID, epoch: epoch, - expected: types.Deposit{ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: epoch}, + expected: types.Deposit{ChainId: suite.chainB.ChainID, Epoch: epoch}, found: true, }, { name: "unsuccessful test", deposits: []types.Deposit{ - {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: epoch}, - {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: epoch + 1}, - {ChainId: suite.path.EndpointA.Chain.ChainID, Epoch: epoch}, - {ChainId: suite.path.EndpointA.Chain.ChainID, Epoch: epoch + 1}, + {ChainId: suite.chainB.ChainID, Epoch: epoch}, + {ChainId: suite.chainB.ChainID, Epoch: epoch + 1}, + {ChainId: suite.chainA.ChainID, Epoch: epoch}, + {ChainId: suite.chainA.ChainID, Epoch: epoch + 1}, }, - chainID: suite.path.EndpointA.Chain.ChainID, + chainID: suite.chainA.ChainID, epoch: epoch + 2, expected: types.Deposit{}, found: false, @@ -290,15 +290,15 @@ func (suite *IntegrationTestSuite) TestGetDepositsWithSequenceID() { { name: "Success", deposits: []types.Deposit{ - {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: epoch, IbcSequenceId: "seq-1"}, - {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: epoch + 1, IbcSequenceId: "seq-2"}, - {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: epoch + 2, IbcSequenceId: "seq-3"}, - {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: epoch + 3, IbcSequenceId: "seq-4"}, + {ChainId: suite.chainB.ChainID, Epoch: epoch, IbcSequenceId: "seq-1"}, + {ChainId: suite.chainB.ChainID, Epoch: epoch + 1, IbcSequenceId: "seq-2"}, + {ChainId: suite.chainB.ChainID, Epoch: epoch + 2, IbcSequenceId: "seq-3"}, + {ChainId: suite.chainB.ChainID, Epoch: epoch + 3, IbcSequenceId: "seq-4"}, }, sequenceID: "seq-1", expected: []types.Deposit{ { - ChainId: suite.path.EndpointB.Chain.ChainID, + ChainId: suite.chainB.ChainID, Epoch: 1, IbcSequenceId: "seq-1", }, @@ -307,10 +307,10 @@ func (suite *IntegrationTestSuite) TestGetDepositsWithSequenceID() { { name: "NotFound", deposits: []types.Deposit{ - {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: epoch, IbcSequenceId: "seq-1"}, - {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: epoch + 1, IbcSequenceId: "seq-2"}, - {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: epoch + 2, IbcSequenceId: "seq-3"}, - {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: epoch + 3, IbcSequenceId: "seq-4"}, + {ChainId: suite.chainB.ChainID, Epoch: epoch, IbcSequenceId: "seq-1"}, + {ChainId: suite.chainB.ChainID, Epoch: epoch + 1, IbcSequenceId: "seq-2"}, + {ChainId: suite.chainB.ChainID, Epoch: epoch + 2, IbcSequenceId: "seq-3"}, + {ChainId: suite.chainB.ChainID, Epoch: epoch + 3, IbcSequenceId: "seq-4"}, }, sequenceID: "seq-8", expected: []types.Deposit{}, @@ -398,24 +398,24 @@ func (suite *IntegrationTestSuite) TestGetDelegableDepositsForChain() { { name: "Success", deposits: []types.Deposit{ - {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: epoch, State: types.Deposit_DEPOSIT_RECEIVED}, - {ChainId: suite.path.EndpointA.Chain.ChainID, Epoch: epoch + 1, State: types.Deposit_DEPOSIT_RECEIVED}, - {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: epoch + 2, State: types.Deposit_DEPOSIT_RECEIVED}, - {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: epoch + 3, State: types.Deposit_DEPOSIT_PENDING}, + {ChainId: suite.chainB.ChainID, Epoch: epoch, State: types.Deposit_DEPOSIT_RECEIVED}, + {ChainId: suite.chainA.ChainID, Epoch: epoch + 1, State: types.Deposit_DEPOSIT_RECEIVED}, + {ChainId: suite.chainB.ChainID, Epoch: epoch + 2, State: types.Deposit_DEPOSIT_RECEIVED}, + {ChainId: suite.chainB.ChainID, Epoch: epoch + 3, State: types.Deposit_DEPOSIT_PENDING}, }, - chainID: suite.path.EndpointB.Chain.ChainID, + chainID: suite.chainB.ChainID, expected: []types.Deposit{ - {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: epoch, State: types.Deposit_DEPOSIT_RECEIVED}, - {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: epoch + 2, State: types.Deposit_DEPOSIT_RECEIVED}, + {ChainId: suite.chainB.ChainID, Epoch: epoch, State: types.Deposit_DEPOSIT_RECEIVED}, + {ChainId: suite.chainB.ChainID, Epoch: epoch + 2, State: types.Deposit_DEPOSIT_RECEIVED}, }, }, { name: "NotFound", deposits: []types.Deposit{ - {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: epoch, State: types.Deposit_DEPOSIT_RECEIVED}, - {ChainId: suite.path.EndpointA.Chain.ChainID, Epoch: epoch + 1, State: types.Deposit_DEPOSIT_RECEIVED}, - {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: epoch + 2, State: types.Deposit_DEPOSIT_RECEIVED}, - {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: epoch + 3, State: types.Deposit_DEPOSIT_PENDING}, + {ChainId: suite.chainB.ChainID, Epoch: epoch, State: types.Deposit_DEPOSIT_RECEIVED}, + {ChainId: suite.chainA.ChainID, Epoch: epoch + 1, State: types.Deposit_DEPOSIT_RECEIVED}, + {ChainId: suite.chainB.ChainID, Epoch: epoch + 2, State: types.Deposit_DEPOSIT_RECEIVED}, + {ChainId: suite.chainB.ChainID, Epoch: epoch + 3, State: types.Deposit_DEPOSIT_PENDING}, }, chainID: "test-chain-id", expected: []types.Deposit{}, @@ -451,9 +451,9 @@ func (suite *IntegrationTestSuite) TestGetDelegatingDepositsForChain() { { name: "found test", deposits: []types.Deposit{ - {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: epoch, State: types.Deposit_DEPOSIT_DELEGATING}, - {ChainId: suite.path.EndpointA.Chain.ChainID, Epoch: epoch + 1, State: types.Deposit_DEPOSIT_DELEGATING}, - {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: epoch + 2, State: types.Deposit_DEPOSIT_DELEGATING}, + {ChainId: suite.chainB.ChainID, Epoch: epoch, State: types.Deposit_DEPOSIT_DELEGATING}, + {ChainId: suite.chainA.ChainID, Epoch: epoch + 1, State: types.Deposit_DEPOSIT_DELEGATING}, + {ChainId: suite.chainB.ChainID, Epoch: epoch + 2, State: types.Deposit_DEPOSIT_DELEGATING}, {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: epoch + 3, State: types.Deposit_DEPOSIT_PENDING}, }, chainID: suite.path.EndpointB.Chain.ChainID, @@ -466,7 +466,7 @@ func (suite *IntegrationTestSuite) TestGetDelegatingDepositsForChain() { name: "not found test", deposits: []types.Deposit{ {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: epoch, State: types.Deposit_DEPOSIT_DELEGATING}, - {ChainId: suite.path.EndpointA.Chain.ChainID, Epoch: epoch + 1, State: types.Deposit_DEPOSIT_DELEGATING}, + {ChainId: suite.chainA.ChainID, Epoch: epoch + 1, State: types.Deposit_DEPOSIT_DELEGATING}, {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: epoch + 2, State: types.Deposit_DEPOSIT_DELEGATING}, {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: epoch + 3, State: types.Deposit_DEPOSIT_PENDING}, }, @@ -505,7 +505,7 @@ func (suite *IntegrationTestSuite) TestGetDepositAmountOnPersistence() { deposits: []types.Deposit{ {Amount: sdk.NewInt64Coin("ibc/uatom", 1), ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: 1, State: types.Deposit_DEPOSIT_PENDING}, {Amount: sdk.NewInt64Coin("ibc/uatom", 2), ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: 2, State: types.Deposit_DEPOSIT_SENT}, - {Amount: sdk.NewInt64Coin("ibc/uatom", 3), ChainId: suite.path.EndpointA.Chain.ChainID, Epoch: 2, State: types.Deposit_DEPOSIT_SENT}, + {Amount: sdk.NewInt64Coin("ibc/uatom", 3), ChainId: suite.chainA.ChainID, Epoch: 2, State: types.Deposit_DEPOSIT_SENT}, {Amount: sdk.NewInt64Coin("ibc/uatom", 4), ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: 3, State: types.Deposit_DEPOSIT_DELEGATING}, {Amount: sdk.NewInt64Coin("ibc/uatom", 5), ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: 4, State: types.Deposit_DEPOSIT_RECEIVED}, }, @@ -536,7 +536,7 @@ func (suite *IntegrationTestSuite) TestGetDepositAmountOnHostChain() { deposits: []types.Deposit{ {Amount: sdk.NewInt64Coin("ibc/uatom", 1), ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: 1, State: types.Deposit_DEPOSIT_PENDING}, {Amount: sdk.NewInt64Coin("ibc/uatom", 2), ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: 2, State: types.Deposit_DEPOSIT_SENT}, - {Amount: sdk.NewInt64Coin("ibc/uatom", 3), ChainId: suite.path.EndpointA.Chain.ChainID, Epoch: 2, State: types.Deposit_DEPOSIT_SENT}, + {Amount: sdk.NewInt64Coin("ibc/uatom", 3), ChainId: suite.chainA.ChainID, Epoch: 2, State: types.Deposit_DEPOSIT_SENT}, {Amount: sdk.NewInt64Coin("ibc/uatom", 4), ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: 3, State: types.Deposit_DEPOSIT_DELEGATING}, {Amount: sdk.NewInt64Coin("ibc/uatom", 5), ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: 4, State: types.Deposit_DEPOSIT_RECEIVED}, }, diff --git a/x/liquidstakeibc/keeper/grpc_querier_test.go b/x/liquidstakeibc/keeper/grpc_querier_test.go index 9cbc31509..4f9b87524 100644 --- a/x/liquidstakeibc/keeper/grpc_querier_test.go +++ b/x/liquidstakeibc/keeper/grpc_querier_test.go @@ -1,7 +1,10 @@ package keeper_test import ( + sdktypes "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + "github.com/cosmos/cosmos-sdk/x/bank/testutil" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" @@ -125,7 +128,7 @@ func (suite *IntegrationTestSuite) TestQueryDeposits() { deposits := make([]*types.Deposit, 0) for i := 0; i < MultipleTestSize; i += 1 { deposit := &types.Deposit{ - ChainId: suite.path.EndpointB.Chain.ChainID, + ChainId: suite.chainB.ChainID, Epoch: int64(i), } suite.app.LiquidStakeIBCKeeper.SetDeposit(suite.ctx, deposit) @@ -140,7 +143,7 @@ func (suite *IntegrationTestSuite) TestQueryDeposits() { }{ { name: "Success", - req: &types.QueryDepositsRequest{ChainId: suite.path.EndpointB.Chain.ChainID}, + req: &types.QueryDepositsRequest{ChainId: suite.chainB.ChainID}, resp: &types.QueryDepositsResponse{Deposits: deposits}, }, { @@ -168,7 +171,7 @@ func (suite *IntegrationTestSuite) TestQueryDeposits() { func (suite *IntegrationTestSuite) TestQueryUnbondings() { unbondings := make([]*types.Unbonding, 0) for i := 0; i < MultipleTestSize; i += 1 { - unbonding := &types.Unbonding{ChainId: suite.path.EndpointB.Chain.ChainID, EpochNumber: int64(i)} + unbonding := &types.Unbonding{ChainId: suite.chainB.ChainID, EpochNumber: int64(i)} suite.app.LiquidStakeIBCKeeper.SetUnbonding(suite.ctx, unbonding) unbondings = append(unbondings, unbonding) } @@ -181,7 +184,7 @@ func (suite *IntegrationTestSuite) TestQueryUnbondings() { }{ { name: "Success", - req: &types.QueryUnbondingsRequest{ChainId: suite.path.EndpointB.Chain.ChainID}, + req: &types.QueryUnbondingsRequest{ChainId: suite.chainB.ChainID}, resp: &types.QueryUnbondingsResponse{Unbondings: unbondings}, }, { @@ -215,7 +218,7 @@ func (suite *IntegrationTestSuite) TestQueryUserUnbondings() { userUnbondings := make([]*types.UserUnbonding, 0) for i := 0; i < MultipleTestSize; i += 1 { userUnbonding := &types.UserUnbonding{ - ChainId: suite.path.EndpointB.Chain.ChainID, + ChainId: suite.chainB.ChainID, Address: TestAddress, EpochNumber: int64(i), } @@ -265,7 +268,7 @@ func (suite *IntegrationTestSuite) TestQueryValidatorUnbondings() { validatorUnbondings := make([]*types.ValidatorUnbonding, 0) for i := 0; i < MultipleTestSize; i += 1 { validatorUnbonding := &types.ValidatorUnbonding{ - ChainId: suite.path.EndpointB.Chain.ChainID, + ChainId: suite.chainB.ChainID, ValidatorAddress: TestAddress, EpochNumber: int64(i), } @@ -281,7 +284,7 @@ func (suite *IntegrationTestSuite) TestQueryValidatorUnbondings() { }{ { name: "Success", - req: &types.QueryValidatorUnbondingRequest{ChainId: suite.path.EndpointB.Chain.ChainID}, + req: &types.QueryValidatorUnbondingRequest{ChainId: suite.chainB.ChainID}, resp: &types.QueryValidatorUnbondingResponse{ValidatorUnbondings: validatorUnbondings}, }, { @@ -310,3 +313,113 @@ func (suite *IntegrationTestSuite) TestQueryValidatorUnbondings() { }) } } + +func (suite *IntegrationTestSuite) TestQueryUnbonding() { + unbonding := &types.Unbonding{ChainId: suite.chainB.ChainID, EpochNumber: int64(1)} + suite.app.LiquidStakeIBCKeeper.SetUnbonding(suite.ctx, unbonding) + + tc := []struct { + name string + req *types.QueryUnbondingRequest + resp *types.QueryUnbondingResponse + err error + }{{ + name: "Valid", + req: &types.QueryUnbondingRequest{ + ChainId: suite.chainB.ChainID, + Epoch: 1, + }, + resp: &types.QueryUnbondingResponse{Unbonding: unbonding}, + err: nil, + }, { + name: "NotFound", + req: &types.QueryUnbondingRequest{ChainId: "chain-1"}, + resp: nil, + err: sdkerrors.ErrKeyNotFound, + }, { + name: "InvalidRequest", + req: &types.QueryUnbondingRequest{ChainId: ""}, + err: status.Error(codes.InvalidArgument, "chain_id cannot be empty"), + }, { + name: "InvalidRequest", + err: status.Error(codes.InvalidArgument, "empty request"), + }, + } + for _, t := range tc { + suite.Run(t.name, func() { + + resp, err := suite.app.LiquidStakeIBCKeeper.Unbonding(suite.ctx, t.req) + + suite.Require().Equal(t.err, err) + suite.Require().Equal(t.resp, resp) + }) + } +} + +func (suite *IntegrationTestSuite) TestQueryDepositAccountBalance() { + + err := testutil.FundAccount(suite.app.BankKeeper, suite.ctx, + authtypes.NewModuleAddress(types.DepositModuleAccount), + sdktypes.NewCoins(sdktypes.NewInt64Coin("ibc/27394FB092D2ECCD56123C74F36E4C1F926001CEADA9CA97EA622B25F41E5EB2", 1000))) + suite.Require().NoError(err) + + tc := []struct { + name string + req *types.QueryDepositAccountBalanceRequest + resp *types.QueryDepositAccountBalanceResponse + err error + }{{ + name: "Valid", + req: &types.QueryDepositAccountBalanceRequest{ChainId: suite.chainB.ChainID}, + resp: &types.QueryDepositAccountBalanceResponse{Balance: sdktypes.NewInt64Coin("ibc/27394FB092D2ECCD56123C74F36E4C1F926001CEADA9CA97EA622B25F41E5EB2", 1000)}, + err: nil, + }, { + name: "NotFound", + req: &types.QueryDepositAccountBalanceRequest{ChainId: "chain-1"}, + err: sdkerrors.ErrKeyNotFound, + }, { + name: "InvalidRequest", + err: status.Error(codes.InvalidArgument, "empty request"), + }} + + for _, t := range tc { + suite.Run(t.name, func() { + + resp, err := suite.app.LiquidStakeIBCKeeper.DepositAccountBalance(suite.ctx, t.req) + + suite.Require().Equal(err, t.err) + suite.Require().Equal(resp, t.resp) + }) + } +} +func (suite *IntegrationTestSuite) TestQueryExchangeRate() { + + tc := []struct { + name string + req *types.QueryExchangeRateRequest + resp *types.QueryExchangeRateResponse + err error + }{{ + name: "Valid", + req: &types.QueryExchangeRateRequest{ChainId: suite.chainB.ChainID}, + resp: &types.QueryExchangeRateResponse{Rate: sdktypes.OneDec()}, + err: nil, + }, { + name: "NotFound", + req: &types.QueryExchangeRateRequest{ChainId: "chain-1"}, + err: sdkerrors.ErrKeyNotFound, + }, { + name: "InvalidRequest", + err: status.Error(codes.InvalidArgument, "empty request"), + }} + + for _, t := range tc { + suite.Run(t.name, func() { + + resp, err := suite.app.LiquidStakeIBCKeeper.ExchangeRate(suite.ctx, t.req) + + suite.Require().Equal(err, t.err) + suite.Require().Equal(resp, t.resp) + }) + } +} diff --git a/x/liquidstakeibc/keeper/host_chain_test.go b/x/liquidstakeibc/keeper/host_chain_test.go index cb6ba3da1..d51c50197 100644 --- a/x/liquidstakeibc/keeper/host_chain_test.go +++ b/x/liquidstakeibc/keeper/host_chain_test.go @@ -17,13 +17,13 @@ func (suite *IntegrationTestSuite) TestGetSetHostChain() { }{ { name: "Success", - input: types.HostChain{ChainId: suite.path.EndpointB.Chain.ChainID}, - expected: types.HostChain{ChainId: suite.path.EndpointB.Chain.ChainID}, + input: types.HostChain{ChainId: suite.chainB.ChainID}, + expected: types.HostChain{ChainId: suite.chainB.ChainID}, found: true, }, { name: "NotFound", - input: types.HostChain{ChainId: suite.path.EndpointB.Chain.ChainID}, + input: types.HostChain{ChainId: suite.chainB.ChainID}, expected: types.HostChain{ChainId: ""}, found: false, }, @@ -322,7 +322,7 @@ func (suite *IntegrationTestSuite) TestGetHostChainFromDelegatorAddress() { } func (suite *IntegrationTestSuite) TestGetHostChainCValue() { - hc, found := suite.app.LiquidStakeIBCKeeper.GetHostChain(suite.ctx, suite.path.EndpointB.Chain.ChainID) + hc, found := suite.app.LiquidStakeIBCKeeper.GetHostChain(suite.ctx, suite.chainB.ChainID) suite.Require().Equal(true, found) suite.Require().Equal(sdk.OneDec(), hc.CValue) @@ -346,7 +346,7 @@ func (suite *IntegrationTestSuite) TestUpdateHostChainValidatorWeight() { { name: "Case 1", hc: types.HostChain{ - ChainId: suite.path.EndpointB.Chain.ChainID, + ChainId: suite.chainB.ChainID, Validators: []*types.Validator{ { OperatorAddress: "valoper1", @@ -363,7 +363,7 @@ func (suite *IntegrationTestSuite) TestUpdateHostChainValidatorWeight() { { name: "NotFound", hc: types.HostChain{ - ChainId: suite.path.EndpointB.Chain.ChainID, + ChainId: suite.chainB.ChainID, Validators: []*types.Validator{ { OperatorAddress: "valoper1", @@ -380,7 +380,7 @@ func (suite *IntegrationTestSuite) TestUpdateHostChainValidatorWeight() { { name: "InvalidRequest", hc: types.HostChain{ - ChainId: suite.path.EndpointB.Chain.ChainID, + ChainId: suite.chainB.ChainID, Validators: []*types.Validator{ { OperatorAddress: "valoper1", diff --git a/x/liquidstakeibc/keeper/keeper_test.go b/x/liquidstakeibc/keeper/keeper_test.go index 0955ac780..5042fc678 100644 --- a/x/liquidstakeibc/keeper/keeper_test.go +++ b/x/liquidstakeibc/keeper/keeper_test.go @@ -98,7 +98,7 @@ func (suite *IntegrationTestSuite) SetupTest() { } hc := &types.HostChain{ - ChainId: suite.path.EndpointB.Chain.ChainID, + ChainId: suite.chainB.ChainID, ConnectionId: suite.path.EndpointA.ConnectionID, Params: hostChainLSParams, HostDenom: HostDenom, @@ -192,7 +192,7 @@ func (suite *IntegrationTestSuite) TestSendProtocolFee() { } pstakeApp, ctx := suite.app, suite.ctx - hc, found := pstakeApp.LiquidStakeIBCKeeper.GetHostChain(ctx, suite.path.EndpointB.Chain.ChainID) + hc, found := pstakeApp.LiquidStakeIBCKeeper.GetHostChain(ctx, suite.chainB.ChainID) suite.Require().Equal(found, true) baseFee := sdk.NewInt64Coin(hc.MintDenom(), 100) @@ -229,7 +229,7 @@ func (suite *IntegrationTestSuite) TestSendProtocolFee() { func (suite *IntegrationTestSuite) TestDelegateAccountPortOwner() { pstakeApp, ctx := suite.app, suite.ctx - hc, found := pstakeApp.LiquidStakeIBCKeeper.GetHostChain(ctx, suite.path.EndpointB.Chain.ChainID) + hc, found := pstakeApp.LiquidStakeIBCKeeper.GetHostChain(ctx, suite.chainB.ChainID) suite.Require().Equal(found, true) suite.Require().Equal( @@ -240,7 +240,7 @@ func (suite *IntegrationTestSuite) TestDelegateAccountPortOwner() { func (suite *IntegrationTestSuite) TestRewardsAccountPortOwner() { pstakeApp, ctx := suite.app, suite.ctx - hc, found := pstakeApp.LiquidStakeIBCKeeper.GetHostChain(ctx, suite.path.EndpointB.Chain.ChainID) + hc, found := pstakeApp.LiquidStakeIBCKeeper.GetHostChain(ctx, suite.chainB.ChainID) suite.Require().Equal(found, true) suite.Require().Equal( diff --git a/x/liquidstakeibc/keeper/unbonding_test.go b/x/liquidstakeibc/keeper/unbonding_test.go index 5ad4e12cd..de58d01ae 100644 --- a/x/liquidstakeibc/keeper/unbonding_test.go +++ b/x/liquidstakeibc/keeper/unbonding_test.go @@ -12,26 +12,26 @@ func (suite *IntegrationTestSuite) TestGetSetUnbonding() { suite.app.LiquidStakeIBCKeeper.SetUnbonding( suite.ctx, &types.Unbonding{ - ChainId: suite.path.EndpointB.Chain.ChainID, + ChainId: suite.chainB.ChainID, EpochNumber: epoch, }, ) unbonding, found := suite.app.LiquidStakeIBCKeeper.GetUnbonding( suite.ctx, - suite.path.EndpointB.Chain.ChainID, + suite.chainB.ChainID, epoch, ) suite.Require().Equal(true, found) - suite.Require().Equal(suite.path.EndpointB.Chain.ChainID, unbonding.ChainId) + suite.Require().Equal(suite.chainB.ChainID, unbonding.ChainId) } func (suite *IntegrationTestSuite) TestDeleteUnbonding() { epoch := suite.app.EpochsKeeper.GetEpochInfo(suite.ctx, types.DelegationEpoch).CurrentEpoch unbonding := &types.Unbonding{ - ChainId: suite.path.EndpointB.Chain.ChainID, + ChainId: suite.chainB.ChainID, EpochNumber: epoch, } @@ -40,7 +40,7 @@ func (suite *IntegrationTestSuite) TestDeleteUnbonding() { unbonding, found := suite.app.LiquidStakeIBCKeeper.GetUnbonding( suite.ctx, - suite.path.EndpointB.Chain.ChainID, + suite.chainB.ChainID, epoch, ) @@ -51,7 +51,7 @@ func (suite *IntegrationTestSuite) TestFilterUnbondings() { epoch := suite.app.EpochsKeeper.GetEpochInfo(suite.ctx, types.DelegationEpoch).CurrentEpoch unbonding := &types.Unbonding{ - ChainId: suite.path.EndpointB.Chain.ChainID, + ChainId: suite.chainB.ChainID, EpochNumber: epoch, } @@ -60,13 +60,13 @@ func (suite *IntegrationTestSuite) TestFilterUnbondings() { unbondings := suite.app.LiquidStakeIBCKeeper.FilterUnbondings( suite.ctx, func(u types.Unbonding) bool { - return u.ChainId == suite.path.EndpointB.Chain.ChainID && + return u.ChainId == suite.chainB.ChainID && u.EpochNumber == epoch }, ) suite.Require().Equal(1, len(unbondings)) - suite.Require().Equal(suite.path.EndpointB.Chain.ChainID, unbondings[0].ChainId) + suite.Require().Equal(suite.chainB.ChainID, unbondings[0].ChainId) suite.Require().Equal(epoch, unbondings[0].EpochNumber) } @@ -84,7 +84,7 @@ func (suite *IntegrationTestSuite) TestIncreaseUndelegatingAmountForEpoch() { burn: sdk.NewCoin(HostDenom, sdk.NewInt(1000)), unbond: sdk.NewCoin(HostDenom, sdk.NewInt(1000)), unbonding: &types.Unbonding{ - ChainId: suite.path.EndpointB.Chain.ChainID, + ChainId: suite.chainB.ChainID, EpochNumber: epoch, BurnAmount: sdk.NewCoin(HostDenom, sdk.NewInt(1000)), UnbondAmount: sdk.NewCoin(HostDenom, sdk.NewInt(1000)), @@ -95,7 +95,7 @@ func (suite *IntegrationTestSuite) TestIncreaseUndelegatingAmountForEpoch() { burn: sdk.NewCoin(HostDenom, sdk.NewInt(1000)), unbond: sdk.NewCoin(HostDenom, sdk.NewInt(1000)), unbonding: &types.Unbonding{ - ChainId: suite.path.EndpointB.Chain.ChainID, + ChainId: suite.chainB.ChainID, EpochNumber: epoch + 1, BurnAmount: sdk.NewCoin(HostDenom, sdk.NewInt(0)), UnbondAmount: sdk.NewCoin(HostDenom, sdk.NewInt(0)), @@ -132,19 +132,19 @@ func (suite *IntegrationTestSuite) TestFailAllUnbondingsForSequenceID() { unbondings := []*types.Unbonding{ { - ChainId: suite.path.EndpointB.Chain.ChainID, + ChainId: suite.chainB.ChainID, EpochNumber: epoch, IbcSequenceId: "sequence-1", State: types.Unbonding_UNBONDING_PENDING, }, { - ChainId: suite.path.EndpointB.Chain.ChainID, + ChainId: suite.chainB.ChainID, EpochNumber: epoch + 1, IbcSequenceId: "sequence-1", State: types.Unbonding_UNBONDING_MATURING, }, { - ChainId: suite.path.EndpointB.Chain.ChainID, + ChainId: suite.chainB.ChainID, EpochNumber: epoch + 2, IbcSequenceId: "sequence-2", State: types.Unbonding_UNBONDING_MATURED, @@ -176,32 +176,32 @@ func (suite *IntegrationTestSuite) TestRevertUnbondingsState() { unbondings := []*types.Unbonding{ { - ChainId: suite.path.EndpointB.Chain.ChainID, + ChainId: suite.chainB.ChainID, EpochNumber: epoch, State: types.Unbonding_UNBONDING_PENDING, }, { - ChainId: suite.path.EndpointB.Chain.ChainID, + ChainId: suite.chainB.ChainID, EpochNumber: epoch + 1, State: types.Unbonding_UNBONDING_INITIATED, }, { - ChainId: suite.path.EndpointB.Chain.ChainID, + ChainId: suite.chainB.ChainID, EpochNumber: epoch + 2, State: types.Unbonding_UNBONDING_MATURING, }, { - ChainId: suite.path.EndpointB.Chain.ChainID, + ChainId: suite.chainB.ChainID, EpochNumber: epoch + 3, State: types.Unbonding_UNBONDING_MATURED, }, { - ChainId: suite.path.EndpointB.Chain.ChainID, + ChainId: suite.chainB.ChainID, EpochNumber: epoch + 4, State: types.Unbonding_UNBONDING_CLAIMABLE, }, { - ChainId: suite.path.EndpointB.Chain.ChainID, + ChainId: suite.chainB.ChainID, EpochNumber: epoch + 5, State: types.Unbonding_UNBONDING_FAILED, }, diff --git a/x/liquidstakeibc/keeper/user_unbonding_test.go b/x/liquidstakeibc/keeper/user_unbonding_test.go index 45bd7105b..278da405e 100644 --- a/x/liquidstakeibc/keeper/user_unbonding_test.go +++ b/x/liquidstakeibc/keeper/user_unbonding_test.go @@ -12,7 +12,7 @@ func (suite *IntegrationTestSuite) TestGetSetUserUnbonding() { suite.app.LiquidStakeIBCKeeper.SetUserUnbonding( suite.ctx, &types.UserUnbonding{ - ChainId: suite.path.EndpointB.Chain.ChainID, + ChainId: suite.chainB.ChainID, Address: TestAddress, EpochNumber: epoch, }, @@ -20,7 +20,7 @@ func (suite *IntegrationTestSuite) TestGetSetUserUnbonding() { unbonding, found := suite.app.LiquidStakeIBCKeeper.GetUserUnbonding( suite.ctx, - suite.path.EndpointB.Chain.ChainID, + suite.chainB.ChainID, TestAddress, epoch, ) @@ -33,7 +33,7 @@ func (suite *IntegrationTestSuite) TestDeleteUserUnbonding() { epoch := suite.app.EpochsKeeper.GetEpochInfo(suite.ctx, types.DelegationEpoch).CurrentEpoch unbonding := &types.UserUnbonding{ - ChainId: suite.path.EndpointB.Chain.ChainID, + ChainId: suite.chainB.ChainID, Address: TestAddress, EpochNumber: epoch, } @@ -44,7 +44,7 @@ func (suite *IntegrationTestSuite) TestDeleteUserUnbonding() { unbonding, found := suite.app.LiquidStakeIBCKeeper.GetUserUnbonding( suite.ctx, TestAddress, - suite.path.EndpointB.Chain.ChainID, + suite.chainB.ChainID, epoch, ) @@ -55,7 +55,7 @@ func (suite *IntegrationTestSuite) TestFilterUserUnbondings() { epoch := suite.app.EpochsKeeper.GetEpochInfo(suite.ctx, types.DelegationEpoch).CurrentEpoch unbonding := &types.UserUnbonding{ - ChainId: suite.path.EndpointB.Chain.ChainID, + ChainId: suite.chainB.ChainID, Address: TestAddress, EpochNumber: epoch, } @@ -65,7 +65,7 @@ func (suite *IntegrationTestSuite) TestFilterUserUnbondings() { unbondings := suite.app.LiquidStakeIBCKeeper.FilterUserUnbondings( suite.ctx, func(u types.UserUnbonding) bool { - return u.ChainId == suite.path.EndpointB.Chain.ChainID && + return u.ChainId == suite.chainB.ChainID && u.Address == TestAddress && u.EpochNumber == epoch }, @@ -89,7 +89,7 @@ func (suite *IntegrationTestSuite) TestIncreaseUserUnbondingAmountForEpoch() { burn: sdk.NewCoin(HostDenom, sdk.NewInt(1000)), unbond: sdk.NewCoin(HostDenom, sdk.NewInt(1000)), unbonding: &types.UserUnbonding{ - ChainId: suite.path.EndpointB.Chain.ChainID, + ChainId: suite.chainB.ChainID, Address: TestAddress, EpochNumber: epoch, StkAmount: sdk.NewCoin(HostDenom, sdk.NewInt(1000)), @@ -101,7 +101,7 @@ func (suite *IntegrationTestSuite) TestIncreaseUserUnbondingAmountForEpoch() { burn: sdk.NewCoin(HostDenom, sdk.NewInt(1000)), unbond: sdk.NewCoin(HostDenom, sdk.NewInt(1000)), unbonding: &types.UserUnbonding{ - ChainId: suite.path.EndpointB.Chain.ChainID, + ChainId: suite.chainB.ChainID, Address: TestAddress, EpochNumber: epoch + 1, StkAmount: sdk.NewCoin(HostDenom, sdk.NewInt(0)), diff --git a/x/liquidstakeibc/keeper/validator_unbonding_test.go b/x/liquidstakeibc/keeper/validator_unbonding_test.go index e6e3b9ff9..81e7c19d4 100644 --- a/x/liquidstakeibc/keeper/validator_unbonding_test.go +++ b/x/liquidstakeibc/keeper/validator_unbonding_test.go @@ -14,7 +14,7 @@ func (suite *IntegrationTestSuite) TestGetSetValidatorUnbonding() { suite.app.LiquidStakeIBCKeeper.SetValidatorUnbonding( suite.ctx, &types.ValidatorUnbonding{ - ChainId: suite.path.EndpointB.Chain.ChainID, + ChainId: suite.chainB.ChainID, ValidatorAddress: TestAddress, EpochNumber: epoch, }, @@ -22,7 +22,7 @@ func (suite *IntegrationTestSuite) TestGetSetValidatorUnbonding() { unbonding, found := suite.app.LiquidStakeIBCKeeper.GetValidatorUnbonding( suite.ctx, - suite.path.EndpointB.Chain.ChainID, + suite.chainB.ChainID, TestAddress, epoch, ) @@ -35,7 +35,7 @@ func (suite *IntegrationTestSuite) TestDeleteValidatorUnbonding() { epoch := suite.app.EpochsKeeper.GetEpochInfo(suite.ctx, types.DelegationEpoch).CurrentEpoch unbonding := &types.ValidatorUnbonding{ - ChainId: suite.path.EndpointB.Chain.ChainID, + ChainId: suite.chainB.ChainID, ValidatorAddress: TestAddress, EpochNumber: epoch, } @@ -46,7 +46,7 @@ func (suite *IntegrationTestSuite) TestDeleteValidatorUnbonding() { unbonding, found := suite.app.LiquidStakeIBCKeeper.GetValidatorUnbonding( suite.ctx, TestAddress, - suite.path.EndpointB.Chain.ChainID, + suite.chainB.ChainID, epoch, ) @@ -58,19 +58,19 @@ func (suite *IntegrationTestSuite) TestDeleteValidatorUnbondingsForSequenceID() unbondings := []*types.ValidatorUnbonding{ { - ChainId: suite.path.EndpointB.Chain.ChainID, + ChainId: suite.chainB.ChainID, ValidatorAddress: TestAddress, EpochNumber: epoch, IbcSequenceId: "sequence-1", }, { - ChainId: suite.path.EndpointB.Chain.ChainID, + ChainId: suite.chainB.ChainID, ValidatorAddress: TestAddress, EpochNumber: epoch + 1, IbcSequenceId: "sequence-1", }, { - ChainId: suite.path.EndpointB.Chain.ChainID, + ChainId: suite.chainB.ChainID, ValidatorAddress: TestAddress, EpochNumber: epoch + 2, IbcSequenceId: "sequence-2", @@ -97,21 +97,21 @@ func (suite *IntegrationTestSuite) TestGetAllValidatorUnbondedAmount() { unbondings := []*types.ValidatorUnbonding{ { - ChainId: suite.path.EndpointB.Chain.ChainID, + ChainId: suite.chainB.ChainID, ValidatorAddress: TestAddress, EpochNumber: epoch, MatureTime: time.Now(), Amount: sdk.NewCoin(HostDenom, sdk.NewInt(100)), }, { - ChainId: suite.path.EndpointB.Chain.ChainID, + ChainId: suite.chainB.ChainID, ValidatorAddress: TestAddress, EpochNumber: epoch + 1, MatureTime: time.Now(), Amount: sdk.NewCoin(HostDenom, sdk.NewInt(100)), }, { - ChainId: suite.path.EndpointB.Chain.ChainID, + ChainId: suite.chainB.ChainID, ValidatorAddress: TestAddress, EpochNumber: epoch + 2, MatureTime: time.Time{}, @@ -123,7 +123,7 @@ func (suite *IntegrationTestSuite) TestGetAllValidatorUnbondedAmount() { suite.app.LiquidStakeIBCKeeper.SetValidatorUnbonding(suite.ctx, unbonding) } - hc, _ := suite.app.LiquidStakeIBCKeeper.GetHostChain(suite.ctx, suite.path.EndpointB.Chain.ChainID) + hc, _ := suite.app.LiquidStakeIBCKeeper.GetHostChain(suite.ctx, suite.chainB.ChainID) amount := suite.app.LiquidStakeIBCKeeper.GetAllValidatorUnbondedAmount(suite.ctx, hc) suite.Require().Equal(int64(200), amount.Int64()) @@ -133,7 +133,7 @@ func (suite *IntegrationTestSuite) TestFilterValidatorUnbondings() { epoch := suite.app.EpochsKeeper.GetEpochInfo(suite.ctx, types.DelegationEpoch).CurrentEpoch unbonding := &types.ValidatorUnbonding{ - ChainId: suite.path.EndpointB.Chain.ChainID, + ChainId: suite.chainB.ChainID, ValidatorAddress: TestAddress, EpochNumber: epoch, } @@ -143,7 +143,7 @@ func (suite *IntegrationTestSuite) TestFilterValidatorUnbondings() { unbondings := suite.app.LiquidStakeIBCKeeper.FilterValidatorUnbondings( suite.ctx, func(u types.ValidatorUnbonding) bool { - return u.ChainId == suite.path.EndpointB.Chain.ChainID && + return u.ChainId == suite.chainB.ChainID && u.ValidatorAddress == TestAddress && u.EpochNumber == epoch }, From 8ea66c3abf7fd0596058395343be72831ecdb889 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 12 Jul 2023 15:38:59 +0530 Subject: [PATCH 020/100] Bump cosmossdk.io/errors from 1.0.0-beta.7 to 1.0.0 (#572) Bumps [cosmossdk.io/errors](https://github.com/cosmos/cosmos-sdk) from 1.0.0-beta.7 to 1.0.0. - [Release notes](https://github.com/cosmos/cosmos-sdk/releases) - [Changelog](https://github.com/cosmos/cosmos-sdk/blob/main/CHANGELOG.md) - [Commits](https://github.com/cosmos/cosmos-sdk/compare/errors/v1.0.0-beta.7...log/v1.0.0) --- updated-dependencies: - dependency-name: cosmossdk.io/errors dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 12 ++++++------ go.sum | 24 ++++++++++++------------ 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/go.mod b/go.mod index 8b0bd6864..f1edbd750 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.19 require ( cosmossdk.io/api v0.3.1 - cosmossdk.io/errors v1.0.0-beta.7 + cosmossdk.io/errors v1.0.0 cosmossdk.io/math v1.0.1 github.com/cometbft/cometbft v0.37.2 github.com/cometbft/cometbft-db v0.8.0 @@ -298,16 +298,16 @@ require ( go.uber.org/atomic v1.10.0 // indirect go.uber.org/multierr v1.8.0 // indirect go.uber.org/zap v1.24.0 // indirect - golang.org/x/crypto v0.9.0 // indirect + golang.org/x/crypto v0.11.0 // indirect golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc // indirect golang.org/x/exp/typeparams v0.0.0-20230224173230-c95f2b4c22f2 // indirect golang.org/x/mod v0.10.0 // indirect - golang.org/x/net v0.10.0 // indirect + golang.org/x/net v0.12.0 // indirect golang.org/x/oauth2 v0.7.0 // indirect golang.org/x/sync v0.2.0 // indirect - golang.org/x/sys v0.8.0 // indirect - golang.org/x/term v0.8.0 // indirect - golang.org/x/text v0.9.0 // indirect + golang.org/x/sys v0.10.0 // indirect + golang.org/x/term v0.10.0 // indirect + golang.org/x/text v0.11.0 // indirect golang.org/x/tools v0.9.3 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect google.golang.org/api v0.122.0 // indirect diff --git a/go.sum b/go.sum index 0f5a12313..37d6267e6 100644 --- a/go.sum +++ b/go.sum @@ -202,8 +202,8 @@ 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/errors v1.0.0 h1:nxF07lmlBbB8NKQhtJ+sJm6ef5uV1XkvPXG2bUntb04= +cosmossdk.io/errors v1.0.0/go.mod h1:+hJZLuhdDE0pYN8HkOrVNwrIOYvUGnn6+4fjnJs/oV0= 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.1 h1:Qx3ifyOPaMLNH/89WeZFH268yCvU4xEcnPLu3sJqPPg= @@ -1558,8 +1558,8 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= -golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g= -golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= +golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA= +golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= 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= @@ -1684,8 +1684,8 @@ golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= -golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50= +golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= 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= @@ -1851,8 +1851,8 @@ golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= -golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= +golang.org/x/sys v0.10.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= @@ -1860,8 +1860,8 @@ golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols= -golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.10.0 h1:3R7pNqamzBraeqj/Tj8qt1aQ2HpmlC+Cx/qL/7hn4/c= +golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= 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= @@ -1875,8 +1875,8 @@ golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.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/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4= +golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= 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= From db76917fdf463b62e5ffa78229bf5ea157218553 Mon Sep 17 00:00:00 2001 From: Puneet <59960662+puneet2019@users.noreply.github.com> Date: Wed, 12 Jul 2023 16:19:10 +0530 Subject: [PATCH 021/100] test unbondings, userunbondings. (#575) --- x/liquidstakeibc/keeper/unbonding_test.go | 21 ++++++++-------- .../keeper/user_unbonding_test.go | 24 +++++++++---------- 2 files changed, 23 insertions(+), 22 deletions(-) diff --git a/x/liquidstakeibc/keeper/unbonding_test.go b/x/liquidstakeibc/keeper/unbonding_test.go index de58d01ae..6a860aee3 100644 --- a/x/liquidstakeibc/keeper/unbonding_test.go +++ b/x/liquidstakeibc/keeper/unbonding_test.go @@ -72,6 +72,13 @@ func (suite *IntegrationTestSuite) TestFilterUnbondings() { func (suite *IntegrationTestSuite) TestIncreaseUndelegatingAmountForEpoch() { epoch := suite.app.EpochsKeeper.GetEpochInfo(suite.ctx, types.DelegationEpoch).CurrentEpoch + ubd1 := &types.Unbonding{ + ChainId: suite.chainB.ChainID, + EpochNumber: epoch, + BurnAmount: sdk.NewCoin(HostDenom, sdk.NewInt(1000)), + UnbondAmount: sdk.NewCoin(HostDenom, sdk.NewInt(1000)), + } + suite.app.LiquidStakeIBCKeeper.SetUnbonding(suite.ctx, ubd1) tc := []struct { name string @@ -80,15 +87,10 @@ func (suite *IntegrationTestSuite) TestIncreaseUndelegatingAmountForEpoch() { unbonding *types.Unbonding }{ { - name: "Success", - burn: sdk.NewCoin(HostDenom, sdk.NewInt(1000)), - unbond: sdk.NewCoin(HostDenom, sdk.NewInt(1000)), - unbonding: &types.Unbonding{ - ChainId: suite.chainB.ChainID, - EpochNumber: epoch, - BurnAmount: sdk.NewCoin(HostDenom, sdk.NewInt(1000)), - UnbondAmount: sdk.NewCoin(HostDenom, sdk.NewInt(1000)), - }, + name: "Success", + burn: sdk.NewCoin(HostDenom, sdk.NewInt(1000)), + unbond: sdk.NewCoin(HostDenom, sdk.NewInt(1000)), + unbonding: ubd1, }, { name: "NotFound", @@ -105,7 +107,6 @@ func (suite *IntegrationTestSuite) TestIncreaseUndelegatingAmountForEpoch() { for _, t := range tc { suite.Run(t.name, func() { - suite.app.LiquidStakeIBCKeeper.SetUnbonding(suite.ctx, t.unbonding) suite.app.LiquidStakeIBCKeeper.IncreaseUndelegatingAmountForEpoch( suite.ctx, diff --git a/x/liquidstakeibc/keeper/user_unbonding_test.go b/x/liquidstakeibc/keeper/user_unbonding_test.go index 278da405e..17482af49 100644 --- a/x/liquidstakeibc/keeper/user_unbonding_test.go +++ b/x/liquidstakeibc/keeper/user_unbonding_test.go @@ -77,7 +77,14 @@ func (suite *IntegrationTestSuite) TestFilterUserUnbondings() { func (suite *IntegrationTestSuite) TestIncreaseUserUnbondingAmountForEpoch() { epoch := suite.app.EpochsKeeper.GetEpochInfo(suite.ctx, types.DelegationEpoch).CurrentEpoch - + ubd1 := &types.UserUnbonding{ + ChainId: suite.chainB.ChainID, + Address: TestAddress, + EpochNumber: epoch, + StkAmount: sdk.NewCoin(HostDenom, sdk.NewInt(1000)), + UnbondAmount: sdk.NewCoin(HostDenom, sdk.NewInt(1000)), + } + suite.app.LiquidStakeIBCKeeper.SetUserUnbonding(suite.ctx, ubd1) tc := []struct { name string burn sdk.Coin @@ -85,16 +92,10 @@ func (suite *IntegrationTestSuite) TestIncreaseUserUnbondingAmountForEpoch() { unbonding *types.UserUnbonding }{ { - name: "Success", - burn: sdk.NewCoin(HostDenom, sdk.NewInt(1000)), - unbond: sdk.NewCoin(HostDenom, sdk.NewInt(1000)), - unbonding: &types.UserUnbonding{ - ChainId: suite.chainB.ChainID, - Address: TestAddress, - EpochNumber: epoch, - StkAmount: sdk.NewCoin(HostDenom, sdk.NewInt(1000)), - UnbondAmount: sdk.NewCoin(HostDenom, sdk.NewInt(1000)), - }, + name: "Success", + burn: sdk.NewCoin(HostDenom, sdk.NewInt(1000)), + unbond: sdk.NewCoin(HostDenom, sdk.NewInt(1000)), + unbonding: ubd1, }, { name: "NotFound", @@ -112,7 +113,6 @@ func (suite *IntegrationTestSuite) TestIncreaseUserUnbondingAmountForEpoch() { for _, t := range tc { suite.Run(t.name, func() { - suite.app.LiquidStakeIBCKeeper.SetUserUnbonding(suite.ctx, t.unbonding) suite.app.LiquidStakeIBCKeeper.IncreaseUserUnbondingAmountForEpoch( suite.ctx, From 7136f6e70b5dec65953cec7bd3da4ab47195ba13 Mon Sep 17 00:00:00 2001 From: Puneet <59960662+puneet2019@users.noreply.github.com> Date: Wed, 12 Jul 2023 16:19:25 +0530 Subject: [PATCH 022/100] test host_chain.go (#574) --- x/liquidstakeibc/keeper/host_chain_test.go | 123 +++++++++++++++++---- 1 file changed, 103 insertions(+), 20 deletions(-) diff --git a/x/liquidstakeibc/keeper/host_chain_test.go b/x/liquidstakeibc/keeper/host_chain_test.go index d51c50197..be3ac23b8 100644 --- a/x/liquidstakeibc/keeper/host_chain_test.go +++ b/x/liquidstakeibc/keeper/host_chain_test.go @@ -1,6 +1,7 @@ package keeper_test import ( + "fmt" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/bank/testutil" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" @@ -82,6 +83,7 @@ func (suite *IntegrationTestSuite) TestProcessHostChainValidatorUpdates() { hcValidators []*types.Validator validators []stakingtypes.Validator expected []*types.Validator + err error }{ { name: "UpdateState", @@ -114,6 +116,32 @@ func (suite *IntegrationTestSuite) TestProcessHostChainValidatorUpdates() { DelegatorShares: sdk.NewDec(100), }, }, + }, { + name: "Validator not found.", + hc: *hcs[0], + hcValidators: []*types.Validator{ + { + OperatorAddress: "valoper1", + Status: stakingtypes.BondStatusBonded, + UnbondingEpoch: 0, + ExchangeRate: sdk.NewDec(1), + }, + { + OperatorAddress: "valoper2", + Status: stakingtypes.BondStatusUnbonding, + UnbondingEpoch: types.CurrentUnbondingEpoch(hcs[0].UnbondingFactor, epoch), + ExchangeRate: sdk.NewDec(1), + }, + }, + validators: []stakingtypes.Validator{ + { + OperatorAddress: "valoper3", + Status: stakingtypes.Unbonding, + Tokens: sdk.NewInt(100), + DelegatorShares: sdk.NewDec(100), + }, + }, + err: fmt.Errorf("validator with address %s not registered", "valoper3"), }, { name: "UpdateExchangeRate", @@ -154,6 +182,27 @@ func (suite *IntegrationTestSuite) TestProcessHostChainValidatorUpdates() { DelegatorShares: sdk.NewDec(0), }, }, + }, { + name: "UpdateState", + hc: *hcs[0], + hcValidators: []*types.Validator{ + { + OperatorAddress: "valoper2", + Status: stakingtypes.BondStatusUnbonding, + UnbondingEpoch: types.CurrentUnbondingEpoch(hcs[0].UnbondingFactor, epoch), + ExchangeRate: sdk.NewDec(1), + DelegatedAmount: sdk.NewInt(100), + }, + }, + validators: []stakingtypes.Validator{ + { + OperatorAddress: "valoper2", + Status: stakingtypes.Bonded, + Tokens: sdk.NewInt(100), + DelegatorShares: sdk.NewDec(101), + }, + }, + err: fmt.Errorf("error while querying validator valoper2 delegation: decoding bech32 failed: invalid separator index -1"), }, } @@ -163,27 +212,28 @@ func (suite *IntegrationTestSuite) TestProcessHostChainValidatorUpdates() { for _, validator := range t.validators { err := suite.app.LiquidStakeIBCKeeper.ProcessHostChainValidatorUpdates(suite.ctx, &t.hc, validator) - suite.Require().Equal(nil, err) + suite.Require().Equal(t.err, err) } - - suite.Require().Equal(len(t.validators), len(t.hc.Validators)) - - for i, validator := range t.hc.Validators { - suite.Require().Equal(t.validators[i].OperatorAddress, validator.OperatorAddress) - suite.Require().Equal(t.validators[i].Status.String(), validator.Status) - - var exchangeRate sdk.Dec - if t.validators[i].DelegatorShares.IsZero() { - exchangeRate = sdk.OneDec() - } else { - exchangeRate = sdk.NewDecFromInt(t.validators[i].Tokens).Quo(t.validators[i].DelegatorShares) - } - suite.Require().Equal(exchangeRate, validator.ExchangeRate) - - if validator.Status == stakingtypes.BondStatusUnbonding { - suite.Require().Equal(types.CurrentUnbondingEpoch(hcs[0].UnbondingFactor, epoch), validator.UnbondingEpoch) - } else if validator.Status == stakingtypes.BondStatusBonded { - suite.Require().Equal(int64(0), validator.UnbondingEpoch) + if t.err == nil { + suite.Require().Equal(len(t.validators), len(t.hc.Validators)) + + for i, validator := range t.hc.Validators { + suite.Require().Equal(t.validators[i].OperatorAddress, validator.OperatorAddress) + suite.Require().Equal(t.validators[i].Status.String(), validator.Status) + + var exchangeRate sdk.Dec + if t.validators[i].DelegatorShares.IsZero() { + exchangeRate = sdk.OneDec() + } else { + exchangeRate = sdk.NewDecFromInt(t.validators[i].Tokens).Quo(t.validators[i].DelegatorShares) + } + suite.Require().Equal(exchangeRate, validator.ExchangeRate) + + if validator.Status == stakingtypes.BondStatusUnbonding { + suite.Require().Equal(types.CurrentUnbondingEpoch(hcs[0].UnbondingFactor, epoch), validator.UnbondingEpoch) + } else if validator.Status == stakingtypes.BondStatusBonded { + suite.Require().Equal(int64(0), validator.UnbondingEpoch) + } } } }) @@ -416,3 +466,36 @@ func (suite *IntegrationTestSuite) TestUpdateHostChainValidatorWeight() { }) } } + +func (suite *IntegrationTestSuite) TestGetHostChainFromHostDenom() { + tc := []struct { + name string + hostdenom string + found bool + }{ + { + name: "Success", + hostdenom: "uatom", + found: true, + }, + { + name: "NotFound", + hostdenom: "notuatom", + found: false, + }, + } + + for _, t := range tc { + suite.Run(t.name, func() { + hc, found := suite.app.LiquidStakeIBCKeeper.GetHostChainFromHostDenom(suite.ctx, t.hostdenom) + + suite.Require().Equal(t.found, found) + + if t.found { + suite.Require().Equal(suite.chainB.ChainID, hc.ChainId) + } else { + suite.Require().Equal("", hc.ChainId) + } + }) + } +} From a7064ac3a9e3db0e6be46658103247e02e173cbc Mon Sep 17 00:00:00 2001 From: puneetmahajan Date: Wed, 12 Jul 2023 18:49:16 +0530 Subject: [PATCH 023/100] keeper tests, not complete. --- x/liquidstakeibc/keeper/keeper.go | 2 +- x/liquidstakeibc/keeper/keeper_test.go | 185 +++++++++++++++++++++++-- 2 files changed, 176 insertions(+), 11 deletions(-) diff --git a/x/liquidstakeibc/keeper/keeper.go b/x/liquidstakeibc/keeper/keeper.go index 5e4741ec1..e964283d2 100644 --- a/x/liquidstakeibc/keeper/keeper.go +++ b/x/liquidstakeibc/keeper/keeper.go @@ -155,7 +155,7 @@ func (k *Keeper) GetChainID(ctx sdk.Context, connectionID string) (string, error // GetPortID constructs a port id given the port owner func (k *Keeper) GetPortID(owner string) string { - return icatypes.ControllerPortPrefix + owner + return fmt.Sprintf("%s%s", icatypes.ControllerPortPrefix, owner) } // RegisterICAAccount registers an ICA diff --git a/x/liquidstakeibc/keeper/keeper_test.go b/x/liquidstakeibc/keeper/keeper_test.go index 5042fc678..a16545dce 100644 --- a/x/liquidstakeibc/keeper/keeper_test.go +++ b/x/liquidstakeibc/keeper/keeper_test.go @@ -1,12 +1,20 @@ package keeper_test import ( + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" + ibctransfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" + connectiontypes "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" + channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" + commitmenttypes "github.com/cosmos/ibc-go/v7/modules/core/23-commitment/types" + ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" + solomachine "github.com/cosmos/ibc-go/v7/modules/light-clients/06-solomachine" + "github.com/stretchr/testify/require" "testing" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/bank/testutil" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" - stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" ibctesting "github.com/cosmos/ibc-go/v7/testing" "github.com/stretchr/testify/suite" @@ -16,14 +24,22 @@ import ( ) var ( - ChainID = "cosmoshub-4" - ConnectionID = "connection-0" - TransferChannel = "channel-0" - TransferPort = "transfer" + //ChainID = "cosmoshub-4" + //ConnectionID = "connection-0" + //TransferChannel = "channel-0" + //TransferPort = "transfer" HostDenom = "uatom" MintDenom = "stk/uatom" MinDeposit = sdk.NewInt(5) PstakeFeeAddress = "persistence1xruvjju28j0a5ud5325rfdak8f5a04h0s30mld" + // TestVersion defines a reusable interchainaccounts version string for testing purposes + TestVersion = string(icatypes.ModuleCdc.MustMarshalJSON(&icatypes.Metadata{ + Version: icatypes.Version, + ControllerConnectionId: ibctesting.FirstConnectionID, + HostConnectionId: ibctesting.FirstConnectionID, + Encoding: icatypes.EncodingProtobuf, + TxType: icatypes.TxTypeSDKMultiMsg, + })) ) func init() { @@ -48,16 +64,13 @@ func TestKeeperTestSuite(t *testing.T) { } func (suite *IntegrationTestSuite) SetupTest() { - //_, pstakeApp, ctx := helpers.CreateTestApp(suite.T()) suite.coordinator = ibctesting.NewCoordinator(suite.T(), 2) suite.chainA = suite.coordinator.GetChain(ibctesting.GetChainID(1)) suite.chainB = suite.coordinator.GetChain(ibctesting.GetChainID(2)) - suite.path = ibctesting.NewPath(suite.chainA, suite.chainB) - suite.path.EndpointA.ChannelConfig.PortID = ibctesting.TransferPort - suite.path.EndpointB.ChannelConfig.PortID = ibctesting.TransferPort - suite.coordinator.SetupConnections(suite.path) + suite.path = NewTransferPath(suite.chainA, suite.chainB) + suite.coordinator.Setup(suite.path) suite.app = suite.chainA.App.(*app.PstakeApp) suite.ctx = suite.chainA.GetContext() @@ -67,6 +80,10 @@ func (suite *IntegrationTestSuite) SetupTest() { params := types.DefaultParams() keeper.SetParams(suite.ctx, params) + suite.SetupHostChain() + +} +func (suite *IntegrationTestSuite) SetupHostChain() { // set host chain params depositFee, err := sdk.NewDecFromStr("0.01") suite.NoError(err) @@ -123,9 +140,88 @@ func (suite *IntegrationTestSuite) SetupTest() { } suite.app.LiquidStakeIBCKeeper.SetHostChain(suite.ctx, hc) +} + +func NewTransferPath(chainA, chainB *ibctesting.TestChain) *ibctesting.Path { + path := ibctesting.NewPath(chainA, chainB) + path.EndpointA.ChannelConfig.PortID = ibctesting.TransferPort + path.EndpointB.ChannelConfig.PortID = ibctesting.TransferPort + path.EndpointA.ChannelConfig.Version = ibctransfertypes.Version + path.EndpointB.ChannelConfig.Version = ibctransfertypes.Version + + return path +} +func (suite *IntegrationTestSuite) SetupICAChannels() *ibctesting.Path { + icapath := NewICAPath(suite.chainA, suite.chainB) + icapath.EndpointA.ClientID = suite.path.EndpointA.ClientID + icapath.EndpointB.ClientID = suite.path.EndpointB.ClientID + icapath.EndpointA.ConnectionID = suite.path.EndpointA.ConnectionID + icapath.EndpointB.ConnectionID = suite.path.EndpointB.ConnectionID + icapath.EndpointA.ClientConfig = suite.path.EndpointA.ClientConfig + icapath.EndpointB.ClientConfig = suite.path.EndpointB.ClientConfig + icapath.EndpointA.ConnectionConfig = suite.path.EndpointA.ConnectionConfig + icapath.EndpointB.ConnectionConfig = suite.path.EndpointB.ConnectionConfig + + err := suite.SetupICAPath(icapath, types.DefaultDelegateAccountPortOwner(suite.chainB.ChainID)) + suite.Require().NoError(err) + + return icapath +} +func NewICAPath(chainA, chainB *ibctesting.TestChain) *ibctesting.Path { + path := ibctesting.NewPath(chainA, chainB) + path.EndpointA.ChannelConfig.PortID = icatypes.HostPortID + path.EndpointB.ChannelConfig.PortID = icatypes.HostPortID + path.EndpointA.ChannelConfig.Order = channeltypes.ORDERED + path.EndpointB.ChannelConfig.Order = channeltypes.ORDERED + path.EndpointA.ChannelConfig.Version = TestVersion + path.EndpointB.ChannelConfig.Version = TestVersion + + return path +} + +func (suite *IntegrationTestSuite) RegisterInterchainAccount(endpoint *ibctesting.Endpoint, owner string) error { + portID, err := icatypes.NewControllerPortID(owner) + if err != nil { + return err + } + + channelSequence := suite.app.GetIBCKeeper().ChannelKeeper.GetNextChannelSequence(endpoint.Chain.GetContext()) + if err := suite.app.ICAControllerKeeper.RegisterInterchainAccount(endpoint.Chain.GetContext(), endpoint.ConnectionID, owner, TestVersion); err != nil { + return err + } + + // commit state changes for proof verification + endpoint.Chain.NextBlock() + + // update port/channel ids + endpoint.ChannelID = channeltypes.FormatChannelIdentifier(channelSequence) + endpoint.ChannelConfig.PortID = portID + endpoint.ChannelConfig.Version = TestVersion + + return nil } +// SetupICAPath invokes the InterchainAccounts entrypoint and subsequent channel handshake handlers +func (suite *IntegrationTestSuite) SetupICAPath(path *ibctesting.Path, owner string) error { + if err := suite.RegisterInterchainAccount(path.EndpointA, owner); err != nil { + return err + } + + if err := path.EndpointB.ChanOpenTry(); err != nil { + return err + } + + if err := path.EndpointA.ChanOpenAck(); err != nil { + return err + } + + if err := path.EndpointB.ChanOpenConfirm(); err != nil { + return err + } + + return nil +} func (suite *IntegrationTestSuite) TestGetSetParams() { tc := []struct { name string @@ -257,3 +353,72 @@ func (suite *IntegrationTestSuite) TestGetEpochNumber() { pstakeApp.EpochsKeeper.GetEpochInfo(ctx, types.DelegationEpoch).CurrentEpoch, ) } + +func (suite *IntegrationTestSuite) TestGetClientState() { + pstakeApp, ctx := suite.app, suite.ctx + + // check client state + state, err := pstakeApp.LiquidStakeIBCKeeper.GetClientState(ctx, suite.path.EndpointA.ConnectionID) + require.NoError(suite.T(), err) + require.Equal(suite.T(), ibcexported.Tendermint, state.ClientType()) + + // check localhost client exists + state, err = pstakeApp.LiquidStakeIBCKeeper.GetClientState(ctx, ibcexported.LocalhostConnectionID) + require.NoError(suite.T(), err) + require.Equal(suite.T(), ibcexported.Localhost, state.ClientType()) + + //no connection found + _, err = pstakeApp.LiquidStakeIBCKeeper.GetClientState(ctx, "connection-1") + require.Error(suite.T(), err) + + // set connection without an active client-id + pstakeApp.IBCKeeper.ConnectionKeeper.SetConnection(ctx, "connection-1", connectiontypes.ConnectionEnd{ClientId: "client-1"}) + _, err = pstakeApp.LiquidStakeIBCKeeper.GetClientState(ctx, "connection-1") + require.Error(suite.T(), err) +} + +func (suite *IntegrationTestSuite) TestGetChainID() { + pstakeApp, ctx := suite.app, suite.ctx + + chainID, err := pstakeApp.LiquidStakeIBCKeeper.GetChainID(ctx, suite.path.EndpointA.ConnectionID) + suite.Require().NoError(err) + suite.Require().Equal(suite.chainB.ChainID, chainID) + + chainID, err = pstakeApp.LiquidStakeIBCKeeper.GetChainID(ctx, ibcexported.LocalhostConnectionID) + suite.Require().NoError(err) + suite.Require().Equal(suite.chainA.ChainID, chainID) + + // random type of client not supported + solomachine.RegisterInterfaces(pstakeApp.InterfaceRegistry()) + pstakeApp.IBCKeeper.ClientKeeper.SetClientState(ctx, "client-1", &solomachine.ClientState{ConsensusState: &solomachine.ConsensusState{}}) + pstakeApp.IBCKeeper.ConnectionKeeper.SetConnection(ctx, "connection-1", connectiontypes.NewConnectionEnd(connectiontypes.OPEN, "client-1", connectiontypes.NewCounterparty("--", "--", commitmenttypes.NewMerklePrefix([]byte("New"))), nil, 1)) + _, err = pstakeApp.LiquidStakeIBCKeeper.GetChainID(ctx, "connection-1") + suite.Require().Error(err) + + //connection not found + _, err = pstakeApp.LiquidStakeIBCKeeper.GetChainID(ctx, "connection-2") + suite.Require().Error(err) + +} + +func (suite *IntegrationTestSuite) TestGetPortID() { + portID := suite.app.LiquidStakeIBCKeeper.GetPortID("owner") + suite.Require().Equal(icatypes.ControllerPortPrefix+"owner", portID) +} + +func (suite *IntegrationTestSuite) TestRegisterICAAccount() { + pstakeApp, ctx := suite.app, suite.ctx + err := pstakeApp.LiquidStakeIBCKeeper.RegisterICAAccount(ctx, suite.path.EndpointA.ConnectionID, types.DefaultDelegateAccountPortOwner(suite.chainB.ChainID)) + suite.Require().NoError(err) +} + +func (suite *IntegrationTestSuite) TestSetWithdrawAddress() { + pstakeApp, ctx := suite.app, suite.ctx + hc, found := pstakeApp.LiquidStakeIBCKeeper.GetHostChain(ctx, suite.chainB.ChainID) + require.Equal(suite.T(), true, found) + require.NotNil(suite.T(), hc) + + _ = suite.SetupICAChannels() + err := pstakeApp.LiquidStakeIBCKeeper.SetWithdrawAddress(ctx, hc) + require.NoError(suite.T(), err) +} From 031baa20fee58dab80e03368521536efb2801ce6 Mon Sep 17 00:00:00 2001 From: Puneet <59960662+puneet2019@users.noreply.github.com> Date: Wed, 12 Jul 2023 19:05:53 +0530 Subject: [PATCH 024/100] keeper tests, not complete. (#576) From 5ba1592212cf2a1530eb971d031381165c92de09 Mon Sep 17 00:00:00 2001 From: Puneet <59960662+puneet2019@users.noreply.github.com> Date: Thu, 13 Jul 2023 12:51:34 +0530 Subject: [PATCH 025/100] refactor keeper tests (#577) * refactor keeper tests * refactor keeper tests * refactor keeper tests (#579) --- app/app.go | 18 +- x/liquidstakeibc/keeper/deposit_test.go | 34 ++-- x/liquidstakeibc/keeper/host_chain_test.go | 4 +- x/liquidstakeibc/keeper/keeper.go | 4 +- x/liquidstakeibc/keeper/keeper_test.go | 157 +++++++++++------- .../keeper/validator_unbonding.go | 3 +- x/lspersistence/client/testutil/suite.go | 11 +- 7 files changed, 137 insertions(+), 94 deletions(-) diff --git a/app/app.go b/app/app.go index f7d2ad341..bbe68b8a4 100644 --- a/app/app.go +++ b/app/app.go @@ -987,17 +987,19 @@ func RegisterSwaggerAPI(_ client.Context, rtr *mux.Router) { } // initParamsKeeper init params keeper and its subspaces +// +//nolint:staticcheck func initParamsKeeper(appCodec codec.BinaryCodec, legacyAmino *codec.LegacyAmino, key, tkey store.StoreKey) paramskeeper.Keeper { paramsKeeper := paramskeeper.NewKeeper(appCodec, legacyAmino, key, tkey) - paramsKeeper.Subspace(authtypes.ModuleName).WithKeyTable(authtypes.ParamKeyTable()) //nolint:staticcheck - paramsKeeper.Subspace(banktypes.ModuleName).WithKeyTable(banktypes.ParamKeyTable()) //nolint:staticcheck - paramsKeeper.Subspace(stakingtypes.ModuleName).WithKeyTable(stakingtypes.ParamKeyTable()) //nolint:staticcheck,nolintlint - paramsKeeper.Subspace(minttypes.ModuleName).WithKeyTable(minttypes.ParamKeyTable()) //nolint:staticcheck - paramsKeeper.Subspace(distrtypes.ModuleName).WithKeyTable(distrtypes.ParamKeyTable()) //nolint:staticcheck - paramsKeeper.Subspace(slashingtypes.ModuleName).WithKeyTable(slashingtypes.ParamKeyTable()) //nolint:staticcheck - paramsKeeper.Subspace(govtypes.ModuleName).WithKeyTable(govv1types.ParamKeyTable()) //nolint:staticcheck - paramsKeeper.Subspace(crisistypes.ModuleName).WithKeyTable(crisistypes.ParamKeyTable()) //nolint:staticcheck + paramsKeeper.Subspace(authtypes.ModuleName).WithKeyTable(authtypes.ParamKeyTable()) + paramsKeeper.Subspace(banktypes.ModuleName).WithKeyTable(banktypes.ParamKeyTable()) + paramsKeeper.Subspace(stakingtypes.ModuleName).WithKeyTable(stakingtypes.ParamKeyTable()) + paramsKeeper.Subspace(minttypes.ModuleName).WithKeyTable(minttypes.ParamKeyTable()) + paramsKeeper.Subspace(distrtypes.ModuleName).WithKeyTable(distrtypes.ParamKeyTable()) + paramsKeeper.Subspace(slashingtypes.ModuleName).WithKeyTable(slashingtypes.ParamKeyTable()) + paramsKeeper.Subspace(govtypes.ModuleName).WithKeyTable(govv1types.ParamKeyTable()) + paramsKeeper.Subspace(crisistypes.ModuleName).WithKeyTable(crisistypes.ParamKeyTable()) paramsKeeper.Subspace(ibctransfertypes.ModuleName) paramsKeeper.Subspace(ibcexported.ModuleName) paramsKeeper.Subspace(icacontrollertypes.SubModuleName) diff --git a/x/liquidstakeibc/keeper/deposit_test.go b/x/liquidstakeibc/keeper/deposit_test.go index b1f7111d5..beacf12da 100644 --- a/x/liquidstakeibc/keeper/deposit_test.go +++ b/x/liquidstakeibc/keeper/deposit_test.go @@ -454,21 +454,21 @@ func (suite *IntegrationTestSuite) TestGetDelegatingDepositsForChain() { {ChainId: suite.chainB.ChainID, Epoch: epoch, State: types.Deposit_DEPOSIT_DELEGATING}, {ChainId: suite.chainA.ChainID, Epoch: epoch + 1, State: types.Deposit_DEPOSIT_DELEGATING}, {ChainId: suite.chainB.ChainID, Epoch: epoch + 2, State: types.Deposit_DEPOSIT_DELEGATING}, - {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: epoch + 3, State: types.Deposit_DEPOSIT_PENDING}, + {ChainId: suite.chainB.ChainID, Epoch: epoch + 3, State: types.Deposit_DEPOSIT_PENDING}, }, - chainID: suite.path.EndpointB.Chain.ChainID, + chainID: suite.chainB.ChainID, expected: []types.Deposit{ - {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: epoch, State: types.Deposit_DEPOSIT_DELEGATING}, - {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: epoch + 2, State: types.Deposit_DEPOSIT_DELEGATING}, + {ChainId: suite.chainB.ChainID, Epoch: epoch, State: types.Deposit_DEPOSIT_DELEGATING}, + {ChainId: suite.chainB.ChainID, Epoch: epoch + 2, State: types.Deposit_DEPOSIT_DELEGATING}, }, }, { name: "not found test", deposits: []types.Deposit{ - {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: epoch, State: types.Deposit_DEPOSIT_DELEGATING}, + {ChainId: suite.chainB.ChainID, Epoch: epoch, State: types.Deposit_DEPOSIT_DELEGATING}, {ChainId: suite.chainA.ChainID, Epoch: epoch + 1, State: types.Deposit_DEPOSIT_DELEGATING}, - {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: epoch + 2, State: types.Deposit_DEPOSIT_DELEGATING}, - {ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: epoch + 3, State: types.Deposit_DEPOSIT_PENDING}, + {ChainId: suite.chainB.ChainID, Epoch: epoch + 2, State: types.Deposit_DEPOSIT_DELEGATING}, + {ChainId: suite.chainB.ChainID, Epoch: epoch + 3, State: types.Deposit_DEPOSIT_PENDING}, }, chainID: "test-host-chain", expected: []types.Deposit{}, @@ -503,13 +503,13 @@ func (suite *IntegrationTestSuite) TestGetDepositAmountOnPersistence() { { name: "found test", deposits: []types.Deposit{ - {Amount: sdk.NewInt64Coin("ibc/uatom", 1), ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: 1, State: types.Deposit_DEPOSIT_PENDING}, - {Amount: sdk.NewInt64Coin("ibc/uatom", 2), ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: 2, State: types.Deposit_DEPOSIT_SENT}, + {Amount: sdk.NewInt64Coin("ibc/uatom", 1), ChainId: suite.chainB.ChainID, Epoch: 1, State: types.Deposit_DEPOSIT_PENDING}, + {Amount: sdk.NewInt64Coin("ibc/uatom", 2), ChainId: suite.chainB.ChainID, Epoch: 2, State: types.Deposit_DEPOSIT_SENT}, {Amount: sdk.NewInt64Coin("ibc/uatom", 3), ChainId: suite.chainA.ChainID, Epoch: 2, State: types.Deposit_DEPOSIT_SENT}, - {Amount: sdk.NewInt64Coin("ibc/uatom", 4), ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: 3, State: types.Deposit_DEPOSIT_DELEGATING}, - {Amount: sdk.NewInt64Coin("ibc/uatom", 5), ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: 4, State: types.Deposit_DEPOSIT_RECEIVED}, + {Amount: sdk.NewInt64Coin("ibc/uatom", 4), ChainId: suite.chainB.ChainID, Epoch: 3, State: types.Deposit_DEPOSIT_DELEGATING}, + {Amount: sdk.NewInt64Coin("ibc/uatom", 5), ChainId: suite.chainB.ChainID, Epoch: 4, State: types.Deposit_DEPOSIT_RECEIVED}, }, - chainID: suite.path.EndpointB.Chain.ChainID, + chainID: suite.chainB.ChainID, expected: sdk.NewInt(3), }} for _, t := range tc { @@ -534,13 +534,13 @@ func (suite *IntegrationTestSuite) TestGetDepositAmountOnHostChain() { { name: "found test", deposits: []types.Deposit{ - {Amount: sdk.NewInt64Coin("ibc/uatom", 1), ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: 1, State: types.Deposit_DEPOSIT_PENDING}, - {Amount: sdk.NewInt64Coin("ibc/uatom", 2), ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: 2, State: types.Deposit_DEPOSIT_SENT}, + {Amount: sdk.NewInt64Coin("ibc/uatom", 1), ChainId: suite.chainB.ChainID, Epoch: 1, State: types.Deposit_DEPOSIT_PENDING}, + {Amount: sdk.NewInt64Coin("ibc/uatom", 2), ChainId: suite.chainB.ChainID, Epoch: 2, State: types.Deposit_DEPOSIT_SENT}, {Amount: sdk.NewInt64Coin("ibc/uatom", 3), ChainId: suite.chainA.ChainID, Epoch: 2, State: types.Deposit_DEPOSIT_SENT}, - {Amount: sdk.NewInt64Coin("ibc/uatom", 4), ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: 3, State: types.Deposit_DEPOSIT_DELEGATING}, - {Amount: sdk.NewInt64Coin("ibc/uatom", 5), ChainId: suite.path.EndpointB.Chain.ChainID, Epoch: 4, State: types.Deposit_DEPOSIT_RECEIVED}, + {Amount: sdk.NewInt64Coin("ibc/uatom", 4), ChainId: suite.chainB.ChainID, Epoch: 3, State: types.Deposit_DEPOSIT_DELEGATING}, + {Amount: sdk.NewInt64Coin("ibc/uatom", 5), ChainId: suite.chainB.ChainID, Epoch: 4, State: types.Deposit_DEPOSIT_RECEIVED}, }, - chainID: suite.path.EndpointB.Chain.ChainID, + chainID: suite.chainB.ChainID, expected: sdk.NewInt(9), }} for _, t := range tc { diff --git a/x/liquidstakeibc/keeper/host_chain_test.go b/x/liquidstakeibc/keeper/host_chain_test.go index be3ac23b8..82300202e 100644 --- a/x/liquidstakeibc/keeper/host_chain_test.go +++ b/x/liquidstakeibc/keeper/host_chain_test.go @@ -339,6 +339,8 @@ func (suite *IntegrationTestSuite) TestGetHostChainFromIBCDenom() { } func (suite *IntegrationTestSuite) TestGetHostChainFromDelegatorAddress() { + hcFromChainID, found := suite.app.LiquidStakeIBCKeeper.GetHostChain(suite.ctx, suite.chainB.ChainID) + suite.Require().True(found) tc := []struct { name string delegatorAddress string @@ -346,7 +348,7 @@ func (suite *IntegrationTestSuite) TestGetHostChainFromDelegatorAddress() { }{ { name: "Success", - delegatorAddress: "cosmos1mykw6u6dq4z7qhw9aztpk5yp8j8y5n0c6usg9faqepw83y2u4nzq2qxaxc", + delegatorAddress: hcFromChainID.DelegationAccount.Address, found: true, }, { diff --git a/x/liquidstakeibc/keeper/keeper.go b/x/liquidstakeibc/keeper/keeper.go index e964283d2..c74462761 100644 --- a/x/liquidstakeibc/keeper/keeper.go +++ b/x/liquidstakeibc/keeper/keeper.go @@ -189,8 +189,8 @@ func (k *Keeper) SetWithdrawAddress(ctx sdk.Context, hc *types.HostChain) error } // IsICAChannelActive checks if an ICA channel is active -func (k *Keeper) IsICAChannelActive(ctx sdk.Context, hc *types.HostChain, owner string) bool { - _, isActive := k.icaControllerKeeper.GetOpenActiveChannel(ctx, hc.ConnectionId, owner) +func (k *Keeper) IsICAChannelActive(ctx sdk.Context, hc *types.HostChain, portID string) bool { + _, isActive := k.icaControllerKeeper.GetOpenActiveChannel(ctx, hc.ConnectionId, portID) return isActive } diff --git a/x/liquidstakeibc/keeper/keeper_test.go b/x/liquidstakeibc/keeper/keeper_test.go index a16545dce..336e22a39 100644 --- a/x/liquidstakeibc/keeper/keeper_test.go +++ b/x/liquidstakeibc/keeper/keeper_test.go @@ -1,6 +1,11 @@ package keeper_test import ( + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/bank/testutil" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" ibctransfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" @@ -9,12 +14,6 @@ import ( commitmenttypes "github.com/cosmos/ibc-go/v7/modules/core/23-commitment/types" ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" solomachine "github.com/cosmos/ibc-go/v7/modules/light-clients/06-solomachine" - "github.com/stretchr/testify/require" - "testing" - - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/bank/testutil" - govtypes "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" ibctesting "github.com/cosmos/ibc-go/v7/testing" "github.com/stretchr/testify/suite" @@ -24,10 +23,6 @@ import ( ) var ( - //ChainID = "cosmoshub-4" - //ConnectionID = "connection-0" - //TransferChannel = "channel-0" - //TransferPort = "transfer" HostDenom = "uatom" MintDenom = "stk/uatom" MinDeposit = sdk.NewInt(5) @@ -54,9 +49,12 @@ type IntegrationTestSuite struct { govHandler govtypes.Handler coordinator *ibctesting.Coordinator - chainA *ibctesting.TestChain - chainB *ibctesting.TestChain - path *ibctesting.Path + chainA *ibctesting.TestChain //pstake chain + chainB *ibctesting.TestChain //host chain, run tests of active chains + chainC *ibctesting.TestChain //host chain 2, run tests of to activate chains + + transferPathAB *ibctesting.Path // chainA - chainB transfer path + transferPathAC *ibctesting.Path // chainA - chainC transfer path } func TestKeeperTestSuite(t *testing.T) { @@ -65,25 +63,45 @@ func TestKeeperTestSuite(t *testing.T) { func (suite *IntegrationTestSuite) SetupTest() { - suite.coordinator = ibctesting.NewCoordinator(suite.T(), 2) - suite.chainA = suite.coordinator.GetChain(ibctesting.GetChainID(1)) - suite.chainB = suite.coordinator.GetChain(ibctesting.GetChainID(2)) + suite.coordinator = ibctesting.NewCoordinator(suite.T(), 0) + + ibctesting.DefaultTestingAppInit = helpers.SetupTestingApp + suite.chainA = ibctesting.NewTestChain(suite.T(), suite.coordinator, ibctesting.GetChainID(1)) + + ibctesting.DefaultTestingAppInit = ibctesting.SetupTestingApp + suite.chainB = ibctesting.NewTestChain(suite.T(), suite.coordinator, ibctesting.GetChainID(2)) + suite.chainC = ibctesting.NewTestChain(suite.T(), suite.coordinator, ibctesting.GetChainID(3)) + + suite.coordinator.Chains = map[string]*ibctesting.TestChain{ + ibctesting.GetChainID(1): suite.chainA, + ibctesting.GetChainID(2): suite.chainB, + ibctesting.GetChainID(3): suite.chainC, + } + + suite.transferPathAB = NewTransferPath(suite.chainA, suite.chainB) + suite.coordinator.Setup(suite.transferPathAB) - suite.path = NewTransferPath(suite.chainA, suite.chainB) - suite.coordinator.Setup(suite.path) + suite.transferPathAC = NewTransferPath(suite.chainA, suite.chainC) + suite.coordinator.Setup(suite.transferPathAC) suite.app = suite.chainA.App.(*app.PstakeApp) suite.ctx = suite.chainA.GetContext() - keeper := suite.app.LiquidStakeIBCKeeper + suite.SetupHostChainAB() + suite.SetupICAChannelsAB() - params := types.DefaultParams() - keeper.SetParams(suite.ctx, params) - - suite.SetupHostChain() + suite.CleanupSetup() +} +func (suite *IntegrationTestSuite) CleanupSetup() { + pstakeApp, ctx := suite.app, suite.ctx + deposits := pstakeApp.LiquidStakeIBCKeeper.GetAllDeposits(ctx) + for _, deposit := range deposits { + pstakeApp.LiquidStakeIBCKeeper.DeleteDeposit(ctx, deposit) + } } -func (suite *IntegrationTestSuite) SetupHostChain() { + +func (suite *IntegrationTestSuite) SetupHostChainAB() { // set host chain params depositFee, err := sdk.NewDecFromStr("0.01") suite.NoError(err) @@ -116,21 +134,21 @@ func (suite *IntegrationTestSuite) SetupHostChain() { hc := &types.HostChain{ ChainId: suite.chainB.ChainID, - ConnectionId: suite.path.EndpointA.ConnectionID, + ConnectionId: suite.transferPathAB.EndpointA.ConnectionID, Params: hostChainLSParams, HostDenom: HostDenom, - ChannelId: "channel-0", //suite.path.EndpointA.ChannelID, - PortId: suite.path.EndpointA.ChannelConfig.PortID, + ChannelId: "channel-0", //suite.transferPathAB.EndpointA.ChannelID, + PortId: suite.transferPathAB.EndpointA.ChannelConfig.PortID, DelegationAccount: &types.ICAAccount{ - Address: "cosmos1mykw6u6dq4z7qhw9aztpk5yp8j8y5n0c6usg9faqepw83y2u4nzq2qxaxc", + Address: "cosmos1mykw6u6dq4z7qhw9aztpk5yp8j8y5n0c6usg9faqepw83y2u4nzq2qxaxc", //gets replaced Balance: sdk.Coin{Denom: HostDenom, Amount: sdk.ZeroInt()}, - Owner: suite.chainB.ChainID + "." + types.DelegateICAType, + Owner: types.DefaultDelegateAccountPortOwner(suite.chainB.ChainID), ChannelState: types.ICAAccount_ICA_CHANNEL_CREATED, }, RewardsAccount: &types.ICAAccount{ - Address: "cosmos19dade3sxq2wqvy6fenytxmn0y3njw8r2p88cn27pj4naxcyzzs8qgxrun3", + Address: "cosmos19dade3sxq2wqvy6fenytxmn0y3njw8r2p88cn27pj4naxcyzzs8qgxrun3", //gets replaced Balance: sdk.Coin{Denom: HostDenom, Amount: sdk.ZeroInt()}, - Owner: suite.chainB.ChainID + "." + types.RewardsICAType, + Owner: types.DefaultRewardsAccountPortOwner(suite.chainB.ChainID), ChannelState: types.ICAAccount_ICA_CHANNEL_CREATED, }, Validators: validators, @@ -151,21 +169,32 @@ func NewTransferPath(chainA, chainB *ibctesting.TestChain) *ibctesting.Path { return path } -func (suite *IntegrationTestSuite) SetupICAChannels() *ibctesting.Path { +func (suite *IntegrationTestSuite) SetupICAChannelsAB() { icapath := NewICAPath(suite.chainA, suite.chainB) - icapath.EndpointA.ClientID = suite.path.EndpointA.ClientID - icapath.EndpointB.ClientID = suite.path.EndpointB.ClientID - icapath.EndpointA.ConnectionID = suite.path.EndpointA.ConnectionID - icapath.EndpointB.ConnectionID = suite.path.EndpointB.ConnectionID - icapath.EndpointA.ClientConfig = suite.path.EndpointA.ClientConfig - icapath.EndpointB.ClientConfig = suite.path.EndpointB.ClientConfig - icapath.EndpointA.ConnectionConfig = suite.path.EndpointA.ConnectionConfig - icapath.EndpointB.ConnectionConfig = suite.path.EndpointB.ConnectionConfig + icapath.EndpointA.ClientID = suite.transferPathAB.EndpointA.ClientID + icapath.EndpointB.ClientID = suite.transferPathAB.EndpointB.ClientID + icapath.EndpointA.ConnectionID = suite.transferPathAB.EndpointA.ConnectionID + icapath.EndpointB.ConnectionID = suite.transferPathAB.EndpointB.ConnectionID + icapath.EndpointA.ClientConfig = suite.transferPathAB.EndpointA.ClientConfig + icapath.EndpointB.ClientConfig = suite.transferPathAB.EndpointB.ClientConfig + icapath.EndpointA.ConnectionConfig = suite.transferPathAB.EndpointA.ConnectionConfig + icapath.EndpointB.ConnectionConfig = suite.transferPathAB.EndpointB.ConnectionConfig + + icapath2 := NewICAPath(suite.chainA, suite.chainB) + icapath2.EndpointA.ClientID = suite.transferPathAB.EndpointA.ClientID + icapath2.EndpointB.ClientID = suite.transferPathAB.EndpointB.ClientID + icapath2.EndpointA.ConnectionID = suite.transferPathAB.EndpointA.ConnectionID + icapath2.EndpointB.ConnectionID = suite.transferPathAB.EndpointB.ConnectionID + icapath2.EndpointA.ClientConfig = suite.transferPathAB.EndpointA.ClientConfig + icapath2.EndpointB.ClientConfig = suite.transferPathAB.EndpointB.ClientConfig + icapath2.EndpointA.ConnectionConfig = suite.transferPathAB.EndpointA.ConnectionConfig + icapath2.EndpointB.ConnectionConfig = suite.transferPathAB.EndpointB.ConnectionConfig err := suite.SetupICAPath(icapath, types.DefaultDelegateAccountPortOwner(suite.chainB.ChainID)) suite.Require().NoError(err) - return icapath + err = suite.SetupICAPath(icapath2, types.DefaultRewardsAccountPortOwner(suite.chainB.ChainID)) + suite.Require().NoError(err) } func NewICAPath(chainA, chainB *ibctesting.TestChain) *ibctesting.Path { path := ibctesting.NewPath(chainA, chainB) @@ -358,29 +387,29 @@ func (suite *IntegrationTestSuite) TestGetClientState() { pstakeApp, ctx := suite.app, suite.ctx // check client state - state, err := pstakeApp.LiquidStakeIBCKeeper.GetClientState(ctx, suite.path.EndpointA.ConnectionID) - require.NoError(suite.T(), err) - require.Equal(suite.T(), ibcexported.Tendermint, state.ClientType()) + state, err := pstakeApp.LiquidStakeIBCKeeper.GetClientState(ctx, suite.transferPathAB.EndpointA.ConnectionID) + suite.Require().NoError(err) + suite.Require().Equal(ibcexported.Tendermint, state.ClientType()) // check localhost client exists state, err = pstakeApp.LiquidStakeIBCKeeper.GetClientState(ctx, ibcexported.LocalhostConnectionID) - require.NoError(suite.T(), err) - require.Equal(suite.T(), ibcexported.Localhost, state.ClientType()) + suite.Require().NoError(err) + suite.Require().Equal(ibcexported.Localhost, state.ClientType()) //no connection found - _, err = pstakeApp.LiquidStakeIBCKeeper.GetClientState(ctx, "connection-1") - require.Error(suite.T(), err) + _, err = pstakeApp.LiquidStakeIBCKeeper.GetClientState(ctx, "connection-2") + suite.Require().Error(err) // set connection without an active client-id - pstakeApp.IBCKeeper.ConnectionKeeper.SetConnection(ctx, "connection-1", connectiontypes.ConnectionEnd{ClientId: "client-1"}) - _, err = pstakeApp.LiquidStakeIBCKeeper.GetClientState(ctx, "connection-1") - require.Error(suite.T(), err) + pstakeApp.IBCKeeper.ConnectionKeeper.SetConnection(ctx, "connection-2", connectiontypes.ConnectionEnd{ClientId: "client-1"}) + _, err = pstakeApp.LiquidStakeIBCKeeper.GetClientState(ctx, "connection-2") + suite.Require().Error(err) } func (suite *IntegrationTestSuite) TestGetChainID() { pstakeApp, ctx := suite.app, suite.ctx - chainID, err := pstakeApp.LiquidStakeIBCKeeper.GetChainID(ctx, suite.path.EndpointA.ConnectionID) + chainID, err := pstakeApp.LiquidStakeIBCKeeper.GetChainID(ctx, suite.transferPathAB.EndpointA.ConnectionID) suite.Require().NoError(err) suite.Require().Equal(suite.chainB.ChainID, chainID) @@ -391,12 +420,12 @@ func (suite *IntegrationTestSuite) TestGetChainID() { // random type of client not supported solomachine.RegisterInterfaces(pstakeApp.InterfaceRegistry()) pstakeApp.IBCKeeper.ClientKeeper.SetClientState(ctx, "client-1", &solomachine.ClientState{ConsensusState: &solomachine.ConsensusState{}}) - pstakeApp.IBCKeeper.ConnectionKeeper.SetConnection(ctx, "connection-1", connectiontypes.NewConnectionEnd(connectiontypes.OPEN, "client-1", connectiontypes.NewCounterparty("--", "--", commitmenttypes.NewMerklePrefix([]byte("New"))), nil, 1)) - _, err = pstakeApp.LiquidStakeIBCKeeper.GetChainID(ctx, "connection-1") + pstakeApp.IBCKeeper.ConnectionKeeper.SetConnection(ctx, "connection-2", connectiontypes.NewConnectionEnd(connectiontypes.OPEN, "client-1", connectiontypes.NewCounterparty("--", "--", commitmenttypes.NewMerklePrefix([]byte("New"))), nil, 1)) + _, err = pstakeApp.LiquidStakeIBCKeeper.GetChainID(ctx, "connection-2") suite.Require().Error(err) //connection not found - _, err = pstakeApp.LiquidStakeIBCKeeper.GetChainID(ctx, "connection-2") + _, err = pstakeApp.LiquidStakeIBCKeeper.GetChainID(ctx, "connection-3") suite.Require().Error(err) } @@ -408,17 +437,25 @@ func (suite *IntegrationTestSuite) TestGetPortID() { func (suite *IntegrationTestSuite) TestRegisterICAAccount() { pstakeApp, ctx := suite.app, suite.ctx - err := pstakeApp.LiquidStakeIBCKeeper.RegisterICAAccount(ctx, suite.path.EndpointA.ConnectionID, types.DefaultDelegateAccountPortOwner(suite.chainB.ChainID)) + err := pstakeApp.LiquidStakeIBCKeeper.RegisterICAAccount(ctx, suite.transferPathAC.EndpointA.ConnectionID, types.DefaultDelegateAccountPortOwner(suite.chainB.ChainID)) suite.Require().NoError(err) } func (suite *IntegrationTestSuite) TestSetWithdrawAddress() { pstakeApp, ctx := suite.app, suite.ctx hc, found := pstakeApp.LiquidStakeIBCKeeper.GetHostChain(ctx, suite.chainB.ChainID) - require.Equal(suite.T(), true, found) - require.NotNil(suite.T(), hc) + suite.Require().Equal(true, found) + suite.Require().NotNil(hc) - _ = suite.SetupICAChannels() err := pstakeApp.LiquidStakeIBCKeeper.SetWithdrawAddress(ctx, hc) - require.NoError(suite.T(), err) + suite.Require().NoError(err) +} +func (suite *IntegrationTestSuite) TestIsICAChannelActive() { + pstakeApp, ctx := suite.app, suite.ctx + hc, found := pstakeApp.LiquidStakeIBCKeeper.GetHostChain(ctx, suite.chainB.ChainID) + suite.Require().Equal(true, found) + suite.Require().NotNil(hc) + + active := pstakeApp.LiquidStakeIBCKeeper.IsICAChannelActive(ctx, hc, pstakeApp.LiquidStakeIBCKeeper.GetPortID(hc.DelegationAccount.Owner)) + suite.Require().Equal(true, active) } diff --git a/x/liquidstakeibc/keeper/validator_unbonding.go b/x/liquidstakeibc/keeper/validator_unbonding.go index 2f5845f0b..44a75b3e0 100644 --- a/x/liquidstakeibc/keeper/validator_unbonding.go +++ b/x/liquidstakeibc/keeper/validator_unbonding.go @@ -3,6 +3,7 @@ package keeper import ( "time" + "cosmossdk.io/math" "github.com/cosmos/cosmos-sdk/store/prefix" "github.com/cosmos/cosmos-sdk/telemetry" sdk "github.com/cosmos/cosmos-sdk/types" @@ -33,7 +34,7 @@ func (k *Keeper) GetValidatorUnbonding( return &validatorUnbonding, true } -func (k *Keeper) GetAllValidatorUnbondedAmount(ctx sdk.Context, hc *types.HostChain) sdk.Int { //nolint:staticcheck +func (k *Keeper) GetAllValidatorUnbondedAmount(ctx sdk.Context, hc *types.HostChain) math.Int { validatorUnbondings := k.FilterValidatorUnbondings( ctx, func(u types.ValidatorUnbonding) bool { diff --git a/x/lspersistence/client/testutil/suite.go b/x/lspersistence/client/testutil/suite.go index 0df7f9683..db166bd45 100644 --- a/x/lspersistence/client/testutil/suite.go +++ b/x/lspersistence/client/testutil/suite.go @@ -45,6 +45,7 @@ func NewAppConstructor(encodingCfg params.EncodingConfig) network.AppConstructor } } +//nolint:staticcheck func (s *IntegrationTestSuite) SetupSuite() { s.T().Log("setting up integration test suite") db := tmdb.NewMemDB() @@ -59,13 +60,13 @@ func (s *IntegrationTestSuite) SetupSuite() { d := time.Duration(15) * time.Second genesisStateGov := govtypes.DefaultGenesisState() - dp := govtypes.NewDepositParams(sdk.NewCoins(sdk.NewCoin(cfg.BondDenom, govtypes.DefaultMinDepositTokens)), &d) //nolint:staticcheck - genesisStateGov.DepositParams = &dp //nolint:staticcheck + dp := govtypes.NewDepositParams(sdk.NewCoins(sdk.NewCoin(cfg.BondDenom, govtypes.DefaultMinDepositTokens)), &d) + genesisStateGov.DepositParams = &dp d = time.Duration(3) * time.Second - vp := govtypes.NewVotingParams(&d) //nolint:staticcheck - genesisStateGov.VotingParams = &vp //nolint:staticcheck - genesisStateGov.TallyParams.Quorum = sdk.MustNewDecFromStr("0.01").String() //nolint:staticcheck + vp := govtypes.NewVotingParams(&d) + genesisStateGov.VotingParams = &vp + genesisStateGov.TallyParams.Quorum = sdk.MustNewDecFromStr("0.01").String() bz, err := cfg.Codec.MarshalJSON(genesisStateGov) s.Require().NoError(err) cfg.GenesisState["gov"] = bz From 980d784de5f07394b7f36737c0c69520f503aa39 Mon Sep 17 00:00:00 2001 From: Puneet <59960662+puneet2019@users.noreply.github.com> Date: Thu, 13 Jul 2023 16:00:03 +0530 Subject: [PATCH 026/100] refactor keeper tests (#580) --- x/liquidstakeibc/keeper/deposit_test.go | 15 +++++----- x/liquidstakeibc/keeper/grpc_querier_test.go | 7 +++-- x/liquidstakeibc/keeper/keeper_test.go | 30 +++++++++++++++++--- 3 files changed, 39 insertions(+), 13 deletions(-) diff --git a/x/liquidstakeibc/keeper/deposit_test.go b/x/liquidstakeibc/keeper/deposit_test.go index beacf12da..4288026ae 100644 --- a/x/liquidstakeibc/keeper/deposit_test.go +++ b/x/liquidstakeibc/keeper/deposit_test.go @@ -11,7 +11,7 @@ func (suite *IntegrationTestSuite) TestGetSetDeposit() { suite.app.LiquidStakeIBCKeeper.SetDeposit(suite.ctx, &types.Deposit{ChainId: suite.chainB.ChainID}) deposits := suite.app.LiquidStakeIBCKeeper.GetAllDeposits(suite.ctx) - suite.Require().Equal(1, len(deposits)) + suite.Require().Equal(2, len(deposits)) suite.Require().Equal(suite.chainB.ChainID, deposits[0].ChainId) } @@ -22,7 +22,8 @@ func (suite *IntegrationTestSuite) TestDeleteDeposit() { suite.app.LiquidStakeIBCKeeper.DeleteDeposit(suite.ctx, deposit) deposits := suite.app.LiquidStakeIBCKeeper.GetAllDeposits(suite.ctx) - suite.Require().Equal(0, len(deposits)) + // preexisting deposit + suite.Require().Equal(1, len(deposits)) } func (suite *IntegrationTestSuite) TestCreateDeposits() { @@ -211,12 +212,12 @@ func (suite *IntegrationTestSuite) TestAdjustDepositsForRedemption() { suite.Require().Equal(t.err, err) - deposits := suite.app.LiquidStakeIBCKeeper.GetAllDeposits(suite.ctx) - for _, deposit := range deposits { - suite.Require().Equal(t.expected[deposit.Epoch], deposit.Amount) + for epoch, deposit := range t.expected { + depositState, ok := suite.app.LiquidStakeIBCKeeper.GetDepositForChainAndEpoch(suite.ctx, suite.chainB.ChainID, epoch) + suite.True(ok) + suite.Require().Equal(depositState.Amount, deposit) } - suite.Require().Equal(len(t.expected), len(deposits)) }) } } @@ -376,7 +377,7 @@ func (suite *IntegrationTestSuite) TestGetPendingDepositsBeforeEpoch() { } hcs := suite.app.LiquidStakeIBCKeeper.GetPendingDepositsBeforeEpoch(suite.ctx, t.epoch) - suite.Require().Equal(len(t.expected), len(hcs)) + suite.Require().Equal(len(t.expected)+1, len(hcs)) for _, hc := range hcs { suite.Require().LessOrEqual(hc.Epoch, t.epoch) diff --git a/x/liquidstakeibc/keeper/grpc_querier_test.go b/x/liquidstakeibc/keeper/grpc_querier_test.go index 4f9b87524..8d79983b8 100644 --- a/x/liquidstakeibc/keeper/grpc_querier_test.go +++ b/x/liquidstakeibc/keeper/grpc_querier_test.go @@ -124,8 +124,11 @@ func (suite *IntegrationTestSuite) TestQueryHostChains() { } func (suite *IntegrationTestSuite) TestQueryDeposits() { - - deposits := make([]*types.Deposit, 0) + deposits := suite.app.LiquidStakeIBCKeeper.GetAllDeposits(suite.ctx) + for _, deposit := range deposits { + suite.app.LiquidStakeIBCKeeper.DeleteDeposit(suite.ctx, deposit) + } + deposits = make([]*types.Deposit, 0) for i := 0; i < MultipleTestSize; i += 1 { deposit := &types.Deposit{ ChainId: suite.chainB.ChainID, diff --git a/x/liquidstakeibc/keeper/keeper_test.go b/x/liquidstakeibc/keeper/keeper_test.go index 336e22a39..783f7b839 100644 --- a/x/liquidstakeibc/keeper/keeper_test.go +++ b/x/liquidstakeibc/keeper/keeper_test.go @@ -66,10 +66,13 @@ func (suite *IntegrationTestSuite) SetupTest() { suite.coordinator = ibctesting.NewCoordinator(suite.T(), 0) ibctesting.DefaultTestingAppInit = helpers.SetupTestingApp + sdk.DefaultBondDenom = "uxprt" suite.chainA = ibctesting.NewTestChain(suite.T(), suite.coordinator, ibctesting.GetChainID(1)) ibctesting.DefaultTestingAppInit = ibctesting.SetupTestingApp + sdk.DefaultBondDenom = HostDenom suite.chainB = ibctesting.NewTestChain(suite.T(), suite.coordinator, ibctesting.GetChainID(2)) + sdk.DefaultBondDenom = "uosmo" suite.chainC = ibctesting.NewTestChain(suite.T(), suite.coordinator, ibctesting.GetChainID(3)) suite.coordinator.Chains = map[string]*ibctesting.TestChain{ @@ -90,15 +93,16 @@ func (suite *IntegrationTestSuite) SetupTest() { suite.SetupHostChainAB() suite.SetupICAChannelsAB() + suite.Transfer(suite.transferPathAB, "uatom") + suite.Transfer(suite.transferPathAC, "uosmo") + suite.CleanupSetup() } func (suite *IntegrationTestSuite) CleanupSetup() { pstakeApp, ctx := suite.app, suite.ctx - deposits := pstakeApp.LiquidStakeIBCKeeper.GetAllDeposits(ctx) - for _, deposit := range deposits { - pstakeApp.LiquidStakeIBCKeeper.DeleteDeposit(ctx, deposit) - } + epoch := suite.app.EpochsKeeper.GetEpochInfo(ctx, types.DelegationEpoch).CurrentEpoch + pstakeApp.LiquidStakeIBCKeeper.DepositWorkflow(ctx, epoch) } func (suite *IntegrationTestSuite) SetupHostChainAB() { @@ -155,6 +159,7 @@ func (suite *IntegrationTestSuite) SetupHostChainAB() { MinimumDeposit: MinDeposit, CValue: sdk.OneDec(), UnbondingFactor: 4, + Active: true, } suite.app.LiquidStakeIBCKeeper.SetHostChain(suite.ctx, hc) @@ -169,6 +174,22 @@ func NewTransferPath(chainA, chainB *ibctesting.TestChain) *ibctesting.Path { return path } +func (suite *IntegrationTestSuite) Transfer(path *ibctesting.Path, denom string) { + coin := sdk.NewCoin(denom, sdk.NewInt(1000000000000)) + + transferMsg := ibctransfertypes.NewMsgTransfer(path.EndpointB.ChannelConfig.PortID, + path.EndpointB.ChannelID, coin, path.EndpointB.Chain.SenderAccount.GetAddress().String(), + path.EndpointA.Chain.SenderAccount.GetAddress().String(), path.EndpointA.Chain.GetTimeoutHeight(), + 0, "") + result, err := path.EndpointB.Chain.SendMsgs(transferMsg) + suite.Require().NoError(err) // message committed + + packet, err := ibctesting.ParsePacketFromEvents(result.GetEvents()) + suite.Require().NoError(err) + + err = path.RelayPacket(packet) + suite.Require().NoError(err) +} func (suite *IntegrationTestSuite) SetupICAChannelsAB() { icapath := NewICAPath(suite.chainA, suite.chainB) icapath.EndpointA.ClientID = suite.transferPathAB.EndpointA.ClientID @@ -251,6 +272,7 @@ func (suite *IntegrationTestSuite) SetupICAPath(path *ibctesting.Path, owner str return nil } + func (suite *IntegrationTestSuite) TestGetSetParams() { tc := []struct { name string From 5b04a3e4828bbefcab6163087567fb6ab65911a7 Mon Sep 17 00:00:00 2001 From: Puneet <59960662+puneet2019@users.noreply.github.com> Date: Thu, 13 Jul 2023 16:55:03 +0530 Subject: [PATCH 027/100] add msg server tests skeleton (#581) --- x/liquidstakeibc/keeper/keeper_test.go | 4 + x/liquidstakeibc/keeper/msg_server_test.go | 282 +++++++++++++++++++++ 2 files changed, 286 insertions(+) create mode 100644 x/liquidstakeibc/keeper/msg_server_test.go diff --git a/x/liquidstakeibc/keeper/keeper_test.go b/x/liquidstakeibc/keeper/keeper_test.go index 783f7b839..d3a1bafd2 100644 --- a/x/liquidstakeibc/keeper/keeper_test.go +++ b/x/liquidstakeibc/keeper/keeper_test.go @@ -101,6 +101,10 @@ func (suite *IntegrationTestSuite) SetupTest() { func (suite *IntegrationTestSuite) CleanupSetup() { pstakeApp, ctx := suite.app, suite.ctx + params := pstakeApp.LiquidStakeIBCKeeper.GetParams(ctx) + params.AdminAddress = suite.chainA.SenderAccount.GetAddress().String() + suite.app.LiquidStakeIBCKeeper.SetParams(ctx, params) + epoch := suite.app.EpochsKeeper.GetEpochInfo(ctx, types.DelegationEpoch).CurrentEpoch pstakeApp.LiquidStakeIBCKeeper.DepositWorkflow(ctx, epoch) } diff --git a/x/liquidstakeibc/keeper/msg_server_test.go b/x/liquidstakeibc/keeper/msg_server_test.go new file mode 100644 index 000000000..94bbe1b37 --- /dev/null +++ b/x/liquidstakeibc/keeper/msg_server_test.go @@ -0,0 +1,282 @@ +package keeper_test + +import ( + "context" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/persistenceOne/pstake-native/v2/x/liquidstakeibc/keeper" + "github.com/persistenceOne/pstake-native/v2/x/liquidstakeibc/types" + "reflect" + "testing" +) + +func (suite *IntegrationTestSuite) Test_msgServer_LiquidStake() { + pstakeapp, ctx := suite.app, suite.ctx + hc, found := pstakeapp.LiquidStakeIBCKeeper.GetHostChain(ctx, suite.chainB.ChainID) + suite.Require().True(found) + type args struct { + goCtx context.Context + msg *types.MsgLiquidStake + } + tests := []struct { + name string + args args + want *types.MsgLiquidStakeResponse + wantErr bool + }{ + { + name: "Success", + args: args{ + goCtx: ctx, + msg: &types.MsgLiquidStake{ + DelegatorAddress: suite.chainA.SenderAccount.GetAddress().String(), + Amount: sdk.NewInt64Coin(hc.IBCDenom(), 1000), + }, + }, + want: &types.MsgLiquidStakeResponse{}, + wantErr: false, + }, + } + for _, tt := range tests { + suite.T().Run(tt.name, func(t *testing.T) { + k := keeper.NewMsgServerImpl(suite.app.LiquidStakeIBCKeeper) + + got, err := k.LiquidStake(tt.args.goCtx, tt.args.msg) + if (err != nil) != tt.wantErr { + t.Errorf("LiquidStake() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("LiquidStake() got = %v, want %v", got, tt.want) + } + }) + } +} + +func (suite *IntegrationTestSuite) Test_msgServer_LiquidUnstake() { + pstakeapp, ctx := suite.app, suite.ctx + hc, found := pstakeapp.LiquidStakeIBCKeeper.GetHostChain(ctx, suite.chainB.ChainID) + suite.Require().True(found) + type args struct { + goCtx context.Context + msg *types.MsgLiquidUnstake + } + tests := []struct { + name string + args args + want *types.MsgLiquidUnstakeResponse + wantErr bool + }{ + { + name: "No tokens to unstake", + args: args{ + goCtx: ctx, + msg: &types.MsgLiquidUnstake{ + DelegatorAddress: suite.chainA.SenderAccount.GetAddress().String(), + Amount: sdk.NewInt64Coin(hc.MintDenom(), 100), + }, + }, + want: nil, + wantErr: true, + }, + } + for _, tt := range tests { + suite.T().Run(tt.name, func(t *testing.T) { + k := keeper.NewMsgServerImpl(suite.app.LiquidStakeIBCKeeper) + + got, err := k.LiquidUnstake(tt.args.goCtx, tt.args.msg) + if (err != nil) != tt.wantErr { + t.Errorf("LiquidUnstake() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("LiquidUnstake() got = %v, want %v", got, tt.want) + } + }) + } +} + +func (suite *IntegrationTestSuite) Test_msgServer_Redeem() { + pstakeapp, ctx := suite.app, suite.ctx + hc, found := pstakeapp.LiquidStakeIBCKeeper.GetHostChain(ctx, suite.chainB.ChainID) + suite.Require().True(found) + + type args struct { + goCtx context.Context + msg *types.MsgRedeem + } + tests := []struct { + name string + args args + want *types.MsgRedeemResponse + wantErr bool + }{ + { + name: "No staked tokens to redeem", + args: args{ + goCtx: ctx, + msg: &types.MsgRedeem{ + DelegatorAddress: suite.chainA.SenderAccount.GetAddress().String(), + Amount: sdk.NewInt64Coin(hc.HostDenom, 100), + }, + }, + want: nil, + wantErr: true, + }} + for _, tt := range tests { + suite.T().Run(tt.name, func(t *testing.T) { + k := keeper.NewMsgServerImpl(pstakeapp.LiquidStakeIBCKeeper) + + got, err := k.Redeem(tt.args.goCtx, tt.args.msg) + if (err != nil) != tt.wantErr { + t.Errorf("Redeem() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("Redeem() got = %v, want %v", got, tt.want) + } + }) + } +} + +func (suite *IntegrationTestSuite) Test_msgServer_RegisterHostChain() { + pstakeapp, ctx := suite.app, suite.ctx + + type args struct { + goCtx context.Context + msg *types.MsgRegisterHostChain + } + tests := []struct { + name string + args args + want *types.MsgRegisterHostChainResponse + wantErr bool + }{ + { + name: "success", + args: args{ + goCtx: ctx, + msg: &types.MsgRegisterHostChain{ + Authority: suite.chainA.SenderAccount.GetAddress().String(), + ConnectionId: suite.transferPathAC.EndpointA.ConnectionID, + DepositFee: sdk.ZeroDec(), + RestakeFee: sdk.ZeroDec(), + UnstakeFee: sdk.ZeroDec(), + RedemptionFee: sdk.ZeroDec(), + ChannelId: suite.transferPathAC.EndpointA.ChannelID, + PortId: suite.transferPathAC.EndpointA.ChannelConfig.PortID, + HostDenom: "uosmo", + MinimumDeposit: sdk.OneInt(), + UnbondingFactor: 4, + AutoCompoundFactor: 2, + }, + }, + want: &types.MsgRegisterHostChainResponse{}, + wantErr: false, + }} + for _, tt := range tests { + suite.T().Run(tt.name, func(t *testing.T) { + k := keeper.NewMsgServerImpl(pstakeapp.LiquidStakeIBCKeeper) + + got, err := k.RegisterHostChain(tt.args.goCtx, tt.args.msg) + if (err != nil) != tt.wantErr { + t.Errorf("RegisterHostChain() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("RegisterHostChain() got = %v, want %v", got, tt.want) + } + }) + } +} + +func (suite *IntegrationTestSuite) Test_msgServer_UpdateHostChain() { + pstakeapp, ctx := suite.app, suite.ctx + hc, found := pstakeapp.LiquidStakeIBCKeeper.GetHostChain(ctx, suite.chainB.ChainID) + suite.Require().True(found) + + type args struct { + goCtx context.Context + msg *types.MsgUpdateHostChain + } + tests := []struct { + name string + args args + want *types.MsgUpdateHostChainResponse + wantErr bool + }{ + { + name: "success", + args: args{ + goCtx: ctx, + msg: &types.MsgUpdateHostChain{ + Authority: suite.chainA.SenderAccount.GetAddress().String(), + ChainId: hc.ChainId, + Updates: []*types.KVUpdate{{ + Key: types.KeyActive, + Value: "true", + }}, + }, + }, + want: &types.MsgUpdateHostChainResponse{}, + wantErr: false, + }} + for _, tt := range tests { + suite.T().Run(tt.name, func(t *testing.T) { + k := keeper.NewMsgServerImpl(pstakeapp.LiquidStakeIBCKeeper) + + got, err := k.UpdateHostChain(tt.args.goCtx, tt.args.msg) + if (err != nil) != tt.wantErr { + t.Errorf("UpdateHostChain() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("UpdateHostChain() got = %v, want %v", got, tt.want) + } + }) + } +} + +func (suite *IntegrationTestSuite) Test_msgServer_UpdateParams() { + pstakeapp, ctx := suite.app, suite.ctx + + type args struct { + goCtx context.Context + msg *types.MsgUpdateParams + } + tests := []struct { + name string + args args + want *types.MsgUpdateParamsResponse + wantErr bool + }{ + { + name: "success", + args: args{ + goCtx: ctx, + msg: &types.MsgUpdateParams{ + Authority: suite.chainA.SenderAccount.GetAddress().String(), + Params: types.Params{ + AdminAddress: suite.chainA.SenderAccount.GetAddress().String(), + FeeAddress: suite.chainA.SenderAccount.GetAddress().String(), + UpperCValueLimit: sdk.OneDec(), + LowerCValueLimit: sdk.ZeroDec(), + }, + }, + }, + want: &types.MsgUpdateParamsResponse{}, + wantErr: false, + }} + for _, tt := range tests { + suite.T().Run(tt.name, func(t *testing.T) { + k := keeper.NewMsgServerImpl(pstakeapp.LiquidStakeIBCKeeper) + got, err := k.UpdateParams(tt.args.goCtx, tt.args.msg) + if (err != nil) != tt.wantErr { + t.Errorf("UpdateParams() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("UpdateParams() got = %v, want %v", got, tt.want) + } + }) + } +} From cf1a75e50072b3987503848942f4776d4d6dcb9a Mon Sep 17 00:00:00 2001 From: puneetmahajan Date: Thu, 13 Jul 2023 17:24:10 +0530 Subject: [PATCH 028/100] move setup part to its own file --- x/liquidstakeibc/keeper/keeper_test.go | 266 ------------------ x/liquidstakeibc/keeper/msg_server_test.go | 4 +- x/liquidstakeibc/keeper/setup_suite_test.go | 290 ++++++++++++++++++++ 3 files changed, 292 insertions(+), 268 deletions(-) create mode 100644 x/liquidstakeibc/keeper/setup_suite_test.go diff --git a/x/liquidstakeibc/keeper/keeper_test.go b/x/liquidstakeibc/keeper/keeper_test.go index d3a1bafd2..f058373a7 100644 --- a/x/liquidstakeibc/keeper/keeper_test.go +++ b/x/liquidstakeibc/keeper/keeper_test.go @@ -1,282 +1,16 @@ package keeper_test import ( - "testing" - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/bank/testutil" - govtypes "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" - stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" - ibctransfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" connectiontypes "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" - channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" commitmenttypes "github.com/cosmos/ibc-go/v7/modules/core/23-commitment/types" ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" solomachine "github.com/cosmos/ibc-go/v7/modules/light-clients/06-solomachine" - ibctesting "github.com/cosmos/ibc-go/v7/testing" - "github.com/stretchr/testify/suite" - - "github.com/persistenceOne/pstake-native/v2/app" - "github.com/persistenceOne/pstake-native/v2/app/helpers" "github.com/persistenceOne/pstake-native/v2/x/liquidstakeibc/types" ) -var ( - HostDenom = "uatom" - MintDenom = "stk/uatom" - MinDeposit = sdk.NewInt(5) - PstakeFeeAddress = "persistence1xruvjju28j0a5ud5325rfdak8f5a04h0s30mld" - // TestVersion defines a reusable interchainaccounts version string for testing purposes - TestVersion = string(icatypes.ModuleCdc.MustMarshalJSON(&icatypes.Metadata{ - Version: icatypes.Version, - ControllerConnectionId: ibctesting.FirstConnectionID, - HostConnectionId: ibctesting.FirstConnectionID, - Encoding: icatypes.EncodingProtobuf, - TxType: icatypes.TxTypeSDKMultiMsg, - })) -) - -func init() { - ibctesting.DefaultTestingAppInit = helpers.SetupTestingApp -} - -type IntegrationTestSuite struct { - suite.Suite - - app *app.PstakeApp - ctx sdk.Context - govHandler govtypes.Handler - - coordinator *ibctesting.Coordinator - chainA *ibctesting.TestChain //pstake chain - chainB *ibctesting.TestChain //host chain, run tests of active chains - chainC *ibctesting.TestChain //host chain 2, run tests of to activate chains - - transferPathAB *ibctesting.Path // chainA - chainB transfer path - transferPathAC *ibctesting.Path // chainA - chainC transfer path -} - -func TestKeeperTestSuite(t *testing.T) { - suite.Run(t, new(IntegrationTestSuite)) -} - -func (suite *IntegrationTestSuite) SetupTest() { - - suite.coordinator = ibctesting.NewCoordinator(suite.T(), 0) - - ibctesting.DefaultTestingAppInit = helpers.SetupTestingApp - sdk.DefaultBondDenom = "uxprt" - suite.chainA = ibctesting.NewTestChain(suite.T(), suite.coordinator, ibctesting.GetChainID(1)) - - ibctesting.DefaultTestingAppInit = ibctesting.SetupTestingApp - sdk.DefaultBondDenom = HostDenom - suite.chainB = ibctesting.NewTestChain(suite.T(), suite.coordinator, ibctesting.GetChainID(2)) - sdk.DefaultBondDenom = "uosmo" - suite.chainC = ibctesting.NewTestChain(suite.T(), suite.coordinator, ibctesting.GetChainID(3)) - - suite.coordinator.Chains = map[string]*ibctesting.TestChain{ - ibctesting.GetChainID(1): suite.chainA, - ibctesting.GetChainID(2): suite.chainB, - ibctesting.GetChainID(3): suite.chainC, - } - - suite.transferPathAB = NewTransferPath(suite.chainA, suite.chainB) - suite.coordinator.Setup(suite.transferPathAB) - - suite.transferPathAC = NewTransferPath(suite.chainA, suite.chainC) - suite.coordinator.Setup(suite.transferPathAC) - - suite.app = suite.chainA.App.(*app.PstakeApp) - suite.ctx = suite.chainA.GetContext() - - suite.SetupHostChainAB() - suite.SetupICAChannelsAB() - - suite.Transfer(suite.transferPathAB, "uatom") - suite.Transfer(suite.transferPathAC, "uosmo") - - suite.CleanupSetup() -} - -func (suite *IntegrationTestSuite) CleanupSetup() { - pstakeApp, ctx := suite.app, suite.ctx - params := pstakeApp.LiquidStakeIBCKeeper.GetParams(ctx) - params.AdminAddress = suite.chainA.SenderAccount.GetAddress().String() - suite.app.LiquidStakeIBCKeeper.SetParams(ctx, params) - - epoch := suite.app.EpochsKeeper.GetEpochInfo(ctx, types.DelegationEpoch).CurrentEpoch - pstakeApp.LiquidStakeIBCKeeper.DepositWorkflow(ctx, epoch) -} - -func (suite *IntegrationTestSuite) SetupHostChainAB() { - // set host chain params - depositFee, err := sdk.NewDecFromStr("0.01") - suite.NoError(err) - - restakeFee, err := sdk.NewDecFromStr("0.02") - suite.NoError(err) - - unstakeFee, err := sdk.NewDecFromStr("0.03") - suite.NoError(err) - - redemptionFee, err := sdk.NewDecFromStr("0.03") - suite.NoError(err) - - hostChainLSParams := &types.HostChainLSParams{ - DepositFee: depositFee, - RestakeFee: restakeFee, - UnstakeFee: unstakeFee, - RedemptionFee: redemptionFee, - } - - validators := make([]*types.Validator, 0) - for _, validator := range suite.chainB.Vals.Validators { - validators = append(validators, &types.Validator{ - OperatorAddress: validator.Address.String(), - Status: stakingtypes.Bonded.String(), - Weight: sdk.ZeroDec(), - DelegatedAmount: sdk.ZeroInt(), - }) - } - - hc := &types.HostChain{ - ChainId: suite.chainB.ChainID, - ConnectionId: suite.transferPathAB.EndpointA.ConnectionID, - Params: hostChainLSParams, - HostDenom: HostDenom, - ChannelId: "channel-0", //suite.transferPathAB.EndpointA.ChannelID, - PortId: suite.transferPathAB.EndpointA.ChannelConfig.PortID, - DelegationAccount: &types.ICAAccount{ - Address: "cosmos1mykw6u6dq4z7qhw9aztpk5yp8j8y5n0c6usg9faqepw83y2u4nzq2qxaxc", //gets replaced - Balance: sdk.Coin{Denom: HostDenom, Amount: sdk.ZeroInt()}, - Owner: types.DefaultDelegateAccountPortOwner(suite.chainB.ChainID), - ChannelState: types.ICAAccount_ICA_CHANNEL_CREATED, - }, - RewardsAccount: &types.ICAAccount{ - Address: "cosmos19dade3sxq2wqvy6fenytxmn0y3njw8r2p88cn27pj4naxcyzzs8qgxrun3", //gets replaced - Balance: sdk.Coin{Denom: HostDenom, Amount: sdk.ZeroInt()}, - Owner: types.DefaultRewardsAccountPortOwner(suite.chainB.ChainID), - ChannelState: types.ICAAccount_ICA_CHANNEL_CREATED, - }, - Validators: validators, - MinimumDeposit: MinDeposit, - CValue: sdk.OneDec(), - UnbondingFactor: 4, - Active: true, - } - - suite.app.LiquidStakeIBCKeeper.SetHostChain(suite.ctx, hc) -} - -func NewTransferPath(chainA, chainB *ibctesting.TestChain) *ibctesting.Path { - path := ibctesting.NewPath(chainA, chainB) - path.EndpointA.ChannelConfig.PortID = ibctesting.TransferPort - path.EndpointB.ChannelConfig.PortID = ibctesting.TransferPort - path.EndpointA.ChannelConfig.Version = ibctransfertypes.Version - path.EndpointB.ChannelConfig.Version = ibctransfertypes.Version - - return path -} -func (suite *IntegrationTestSuite) Transfer(path *ibctesting.Path, denom string) { - coin := sdk.NewCoin(denom, sdk.NewInt(1000000000000)) - - transferMsg := ibctransfertypes.NewMsgTransfer(path.EndpointB.ChannelConfig.PortID, - path.EndpointB.ChannelID, coin, path.EndpointB.Chain.SenderAccount.GetAddress().String(), - path.EndpointA.Chain.SenderAccount.GetAddress().String(), path.EndpointA.Chain.GetTimeoutHeight(), - 0, "") - result, err := path.EndpointB.Chain.SendMsgs(transferMsg) - suite.Require().NoError(err) // message committed - - packet, err := ibctesting.ParsePacketFromEvents(result.GetEvents()) - suite.Require().NoError(err) - - err = path.RelayPacket(packet) - suite.Require().NoError(err) -} -func (suite *IntegrationTestSuite) SetupICAChannelsAB() { - icapath := NewICAPath(suite.chainA, suite.chainB) - icapath.EndpointA.ClientID = suite.transferPathAB.EndpointA.ClientID - icapath.EndpointB.ClientID = suite.transferPathAB.EndpointB.ClientID - icapath.EndpointA.ConnectionID = suite.transferPathAB.EndpointA.ConnectionID - icapath.EndpointB.ConnectionID = suite.transferPathAB.EndpointB.ConnectionID - icapath.EndpointA.ClientConfig = suite.transferPathAB.EndpointA.ClientConfig - icapath.EndpointB.ClientConfig = suite.transferPathAB.EndpointB.ClientConfig - icapath.EndpointA.ConnectionConfig = suite.transferPathAB.EndpointA.ConnectionConfig - icapath.EndpointB.ConnectionConfig = suite.transferPathAB.EndpointB.ConnectionConfig - - icapath2 := NewICAPath(suite.chainA, suite.chainB) - icapath2.EndpointA.ClientID = suite.transferPathAB.EndpointA.ClientID - icapath2.EndpointB.ClientID = suite.transferPathAB.EndpointB.ClientID - icapath2.EndpointA.ConnectionID = suite.transferPathAB.EndpointA.ConnectionID - icapath2.EndpointB.ConnectionID = suite.transferPathAB.EndpointB.ConnectionID - icapath2.EndpointA.ClientConfig = suite.transferPathAB.EndpointA.ClientConfig - icapath2.EndpointB.ClientConfig = suite.transferPathAB.EndpointB.ClientConfig - icapath2.EndpointA.ConnectionConfig = suite.transferPathAB.EndpointA.ConnectionConfig - icapath2.EndpointB.ConnectionConfig = suite.transferPathAB.EndpointB.ConnectionConfig - - err := suite.SetupICAPath(icapath, types.DefaultDelegateAccountPortOwner(suite.chainB.ChainID)) - suite.Require().NoError(err) - - err = suite.SetupICAPath(icapath2, types.DefaultRewardsAccountPortOwner(suite.chainB.ChainID)) - suite.Require().NoError(err) -} -func NewICAPath(chainA, chainB *ibctesting.TestChain) *ibctesting.Path { - path := ibctesting.NewPath(chainA, chainB) - path.EndpointA.ChannelConfig.PortID = icatypes.HostPortID - path.EndpointB.ChannelConfig.PortID = icatypes.HostPortID - path.EndpointA.ChannelConfig.Order = channeltypes.ORDERED - path.EndpointB.ChannelConfig.Order = channeltypes.ORDERED - path.EndpointA.ChannelConfig.Version = TestVersion - path.EndpointB.ChannelConfig.Version = TestVersion - - return path -} - -func (suite *IntegrationTestSuite) RegisterInterchainAccount(endpoint *ibctesting.Endpoint, owner string) error { - portID, err := icatypes.NewControllerPortID(owner) - if err != nil { - return err - } - - channelSequence := suite.app.GetIBCKeeper().ChannelKeeper.GetNextChannelSequence(endpoint.Chain.GetContext()) - - if err := suite.app.ICAControllerKeeper.RegisterInterchainAccount(endpoint.Chain.GetContext(), endpoint.ConnectionID, owner, TestVersion); err != nil { - return err - } - - // commit state changes for proof verification - endpoint.Chain.NextBlock() - - // update port/channel ids - endpoint.ChannelID = channeltypes.FormatChannelIdentifier(channelSequence) - endpoint.ChannelConfig.PortID = portID - endpoint.ChannelConfig.Version = TestVersion - - return nil -} - -// SetupICAPath invokes the InterchainAccounts entrypoint and subsequent channel handshake handlers -func (suite *IntegrationTestSuite) SetupICAPath(path *ibctesting.Path, owner string) error { - if err := suite.RegisterInterchainAccount(path.EndpointA, owner); err != nil { - return err - } - - if err := path.EndpointB.ChanOpenTry(); err != nil { - return err - } - - if err := path.EndpointA.ChanOpenAck(); err != nil { - return err - } - - if err := path.EndpointB.ChanOpenConfirm(); err != nil { - return err - } - - return nil -} - func (suite *IntegrationTestSuite) TestGetSetParams() { tc := []struct { name string diff --git a/x/liquidstakeibc/keeper/msg_server_test.go b/x/liquidstakeibc/keeper/msg_server_test.go index 94bbe1b37..ef5a1af4f 100644 --- a/x/liquidstakeibc/keeper/msg_server_test.go +++ b/x/liquidstakeibc/keeper/msg_server_test.go @@ -111,12 +111,12 @@ func (suite *IntegrationTestSuite) Test_msgServer_Redeem() { wantErr bool }{ { - name: "No staked tokens to redeem", + name: "success", args: args{ goCtx: ctx, msg: &types.MsgRedeem{ DelegatorAddress: suite.chainA.SenderAccount.GetAddress().String(), - Amount: sdk.NewInt64Coin(hc.HostDenom, 100), + Amount: sdk.NewInt64Coin(hc.MintDenom(), 100), }, }, want: nil, diff --git a/x/liquidstakeibc/keeper/setup_suite_test.go b/x/liquidstakeibc/keeper/setup_suite_test.go new file mode 100644 index 000000000..6edf8bdfb --- /dev/null +++ b/x/liquidstakeibc/keeper/setup_suite_test.go @@ -0,0 +1,290 @@ +package keeper_test + +import ( + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" + ibctransfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" + channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" + ibctesting "github.com/cosmos/ibc-go/v7/testing" + "github.com/stretchr/testify/suite" + + "github.com/persistenceOne/pstake-native/v2/app" + "github.com/persistenceOne/pstake-native/v2/app/helpers" + "github.com/persistenceOne/pstake-native/v2/x/liquidstakeibc/types" +) + +var ( + HostDenom = "uatom" + MintDenom = "stk/uatom" + MinDeposit = sdk.NewInt(5) + PstakeFeeAddress = "persistence1xruvjju28j0a5ud5325rfdak8f5a04h0s30mld" + // TestVersion defines a reusable interchainaccounts version string for testing purposes + TestVersion = string(icatypes.ModuleCdc.MustMarshalJSON(&icatypes.Metadata{ + Version: icatypes.Version, + ControllerConnectionId: ibctesting.FirstConnectionID, + HostConnectionId: ibctesting.FirstConnectionID, + Encoding: icatypes.EncodingProtobuf, + TxType: icatypes.TxTypeSDKMultiMsg, + })) +) + +func init() { + ibctesting.DefaultTestingAppInit = helpers.SetupTestingApp +} + +type IntegrationTestSuite struct { + suite.Suite + + app *app.PstakeApp + ctx sdk.Context + govHandler govtypes.Handler + + coordinator *ibctesting.Coordinator + chainA *ibctesting.TestChain //pstake chain + chainB *ibctesting.TestChain //host chain, run tests of active chains + chainC *ibctesting.TestChain //host chain 2, run tests of to activate chains + + transferPathAB *ibctesting.Path // chainA - chainB transfer path + transferPathAC *ibctesting.Path // chainA - chainC transfer path +} + +func TestKeeperTestSuite(t *testing.T) { + suite.Run(t, new(IntegrationTestSuite)) +} + +func (suite *IntegrationTestSuite) SetupTest() { + + suite.coordinator = ibctesting.NewCoordinator(suite.T(), 0) + + ibctesting.DefaultTestingAppInit = helpers.SetupTestingApp + sdk.DefaultBondDenom = "uxprt" + suite.chainA = ibctesting.NewTestChain(suite.T(), suite.coordinator, ibctesting.GetChainID(1)) + + ibctesting.DefaultTestingAppInit = ibctesting.SetupTestingApp + sdk.DefaultBondDenom = HostDenom + suite.chainB = ibctesting.NewTestChain(suite.T(), suite.coordinator, ibctesting.GetChainID(2)) + sdk.DefaultBondDenom = "uosmo" + suite.chainC = ibctesting.NewTestChain(suite.T(), suite.coordinator, ibctesting.GetChainID(3)) + + suite.coordinator.Chains = map[string]*ibctesting.TestChain{ + ibctesting.GetChainID(1): suite.chainA, + ibctesting.GetChainID(2): suite.chainB, + ibctesting.GetChainID(3): suite.chainC, + } + + suite.transferPathAB = NewTransferPath(suite.chainA, suite.chainB) + suite.coordinator.Setup(suite.transferPathAB) + + suite.transferPathAC = NewTransferPath(suite.chainA, suite.chainC) + suite.coordinator.Setup(suite.transferPathAC) + + suite.app = suite.chainA.App.(*app.PstakeApp) + suite.ctx = suite.chainA.GetContext() + + suite.SetupHostChainAB() + suite.SetupICAChannelsAB() + + suite.Transfer(suite.transferPathAB, "uatom") + suite.Transfer(suite.transferPathAC, "uosmo") + + suite.CleanupSetup() +} + +func (suite *IntegrationTestSuite) CleanupSetup() { + pstakeApp, ctx := suite.app, suite.ctx + params := pstakeApp.LiquidStakeIBCKeeper.GetParams(ctx) + params.AdminAddress = suite.chainA.SenderAccount.GetAddress().String() + suite.app.LiquidStakeIBCKeeper.SetParams(ctx, params) + + epoch := suite.app.EpochsKeeper.GetEpochInfo(ctx, types.DelegationEpoch).CurrentEpoch + pstakeApp.LiquidStakeIBCKeeper.DepositWorkflow(ctx, epoch) +} +func (suite *IntegrationTestSuite) TestOneFullFlow() { + pstakeApp, ctx := suite.app, suite.ctx + k := pstakeApp.LiquidStakeIBCKeeper + hc, ok := k.GetHostChain(ctx, suite.chainB.ChainID) + suite.True(ok) + senderAcc := suite.chainA.SenderAccount + //user liquidstakes + msgLiquidStake := types.NewMsgLiquidStake(sdk.NewInt64Coin(hc.IBCDenom(), 1000000), senderAcc.GetAddress()) + result, err := suite.chainA.SendMsgs(msgLiquidStake) + suite.NotNil(result) + suite.NoError(err) + + msgRedeem := types.NewMsgRedeem(sdk.NewInt64Coin(hc.MintDenom(), 100000), senderAcc.GetAddress()) + result, err = suite.chainA.SendMsgs(msgRedeem) + suite.NotNil(result) + suite.NoError(err) +} + +func (suite *IntegrationTestSuite) SetupHostChainAB() { + // set host chain params + depositFee, err := sdk.NewDecFromStr("0.01") + suite.NoError(err) + + restakeFee, err := sdk.NewDecFromStr("0.02") + suite.NoError(err) + + unstakeFee, err := sdk.NewDecFromStr("0.03") + suite.NoError(err) + + redemptionFee, err := sdk.NewDecFromStr("0.03") + suite.NoError(err) + + hostChainLSParams := &types.HostChainLSParams{ + DepositFee: depositFee, + RestakeFee: restakeFee, + UnstakeFee: unstakeFee, + RedemptionFee: redemptionFee, + } + + validators := make([]*types.Validator, 0) + for _, validator := range suite.chainB.Vals.Validators { + validators = append(validators, &types.Validator{ + OperatorAddress: validator.Address.String(), + Status: stakingtypes.Bonded.String(), + Weight: sdk.ZeroDec(), + DelegatedAmount: sdk.ZeroInt(), + }) + } + + hc := &types.HostChain{ + ChainId: suite.chainB.ChainID, + ConnectionId: suite.transferPathAB.EndpointA.ConnectionID, + Params: hostChainLSParams, + HostDenom: HostDenom, + ChannelId: "channel-0", //suite.transferPathAB.EndpointA.ChannelID, + PortId: suite.transferPathAB.EndpointA.ChannelConfig.PortID, + DelegationAccount: &types.ICAAccount{ + Address: "cosmos1mykw6u6dq4z7qhw9aztpk5yp8j8y5n0c6usg9faqepw83y2u4nzq2qxaxc", //gets replaced + Balance: sdk.Coin{Denom: HostDenom, Amount: sdk.ZeroInt()}, + Owner: types.DefaultDelegateAccountPortOwner(suite.chainB.ChainID), + ChannelState: types.ICAAccount_ICA_CHANNEL_CREATED, + }, + RewardsAccount: &types.ICAAccount{ + Address: "cosmos19dade3sxq2wqvy6fenytxmn0y3njw8r2p88cn27pj4naxcyzzs8qgxrun3", //gets replaced + Balance: sdk.Coin{Denom: HostDenom, Amount: sdk.ZeroInt()}, + Owner: types.DefaultRewardsAccountPortOwner(suite.chainB.ChainID), + ChannelState: types.ICAAccount_ICA_CHANNEL_CREATED, + }, + Validators: validators, + MinimumDeposit: MinDeposit, + CValue: sdk.OneDec(), + UnbondingFactor: 4, + Active: true, + } + + suite.app.LiquidStakeIBCKeeper.SetHostChain(suite.ctx, hc) +} + +func NewTransferPath(chainA, chainB *ibctesting.TestChain) *ibctesting.Path { + path := ibctesting.NewPath(chainA, chainB) + path.EndpointA.ChannelConfig.PortID = ibctesting.TransferPort + path.EndpointB.ChannelConfig.PortID = ibctesting.TransferPort + path.EndpointA.ChannelConfig.Version = ibctransfertypes.Version + path.EndpointB.ChannelConfig.Version = ibctransfertypes.Version + + return path +} +func (suite *IntegrationTestSuite) Transfer(path *ibctesting.Path, denom string) { + coin := sdk.NewCoin(denom, sdk.NewInt(1000000000000)) + + transferMsg := ibctransfertypes.NewMsgTransfer(path.EndpointB.ChannelConfig.PortID, + path.EndpointB.ChannelID, coin, path.EndpointB.Chain.SenderAccount.GetAddress().String(), + path.EndpointA.Chain.SenderAccount.GetAddress().String(), path.EndpointA.Chain.GetTimeoutHeight(), + 0, "") + result, err := path.EndpointB.Chain.SendMsgs(transferMsg) + suite.Require().NoError(err) // message committed + + packet, err := ibctesting.ParsePacketFromEvents(result.GetEvents()) + suite.Require().NoError(err) + + err = path.RelayPacket(packet) + suite.Require().NoError(err) +} +func (suite *IntegrationTestSuite) SetupICAChannelsAB() { + icapath := NewICAPath(suite.chainA, suite.chainB) + icapath.EndpointA.ClientID = suite.transferPathAB.EndpointA.ClientID + icapath.EndpointB.ClientID = suite.transferPathAB.EndpointB.ClientID + icapath.EndpointA.ConnectionID = suite.transferPathAB.EndpointA.ConnectionID + icapath.EndpointB.ConnectionID = suite.transferPathAB.EndpointB.ConnectionID + icapath.EndpointA.ClientConfig = suite.transferPathAB.EndpointA.ClientConfig + icapath.EndpointB.ClientConfig = suite.transferPathAB.EndpointB.ClientConfig + icapath.EndpointA.ConnectionConfig = suite.transferPathAB.EndpointA.ConnectionConfig + icapath.EndpointB.ConnectionConfig = suite.transferPathAB.EndpointB.ConnectionConfig + + icapath2 := NewICAPath(suite.chainA, suite.chainB) + icapath2.EndpointA.ClientID = suite.transferPathAB.EndpointA.ClientID + icapath2.EndpointB.ClientID = suite.transferPathAB.EndpointB.ClientID + icapath2.EndpointA.ConnectionID = suite.transferPathAB.EndpointA.ConnectionID + icapath2.EndpointB.ConnectionID = suite.transferPathAB.EndpointB.ConnectionID + icapath2.EndpointA.ClientConfig = suite.transferPathAB.EndpointA.ClientConfig + icapath2.EndpointB.ClientConfig = suite.transferPathAB.EndpointB.ClientConfig + icapath2.EndpointA.ConnectionConfig = suite.transferPathAB.EndpointA.ConnectionConfig + icapath2.EndpointB.ConnectionConfig = suite.transferPathAB.EndpointB.ConnectionConfig + + err := suite.SetupICAPath(icapath, types.DefaultDelegateAccountPortOwner(suite.chainB.ChainID)) + suite.Require().NoError(err) + + err = suite.SetupICAPath(icapath2, types.DefaultRewardsAccountPortOwner(suite.chainB.ChainID)) + suite.Require().NoError(err) +} +func NewICAPath(chainA, chainB *ibctesting.TestChain) *ibctesting.Path { + path := ibctesting.NewPath(chainA, chainB) + path.EndpointA.ChannelConfig.PortID = icatypes.HostPortID + path.EndpointB.ChannelConfig.PortID = icatypes.HostPortID + path.EndpointA.ChannelConfig.Order = channeltypes.ORDERED + path.EndpointB.ChannelConfig.Order = channeltypes.ORDERED + path.EndpointA.ChannelConfig.Version = TestVersion + path.EndpointB.ChannelConfig.Version = TestVersion + + return path +} + +func (suite *IntegrationTestSuite) RegisterInterchainAccount(endpoint *ibctesting.Endpoint, owner string) error { + portID, err := icatypes.NewControllerPortID(owner) + if err != nil { + return err + } + + channelSequence := suite.app.GetIBCKeeper().ChannelKeeper.GetNextChannelSequence(endpoint.Chain.GetContext()) + + if err := suite.app.ICAControllerKeeper.RegisterInterchainAccount(endpoint.Chain.GetContext(), endpoint.ConnectionID, owner, TestVersion); err != nil { + return err + } + + // commit state changes for proof verification + endpoint.Chain.NextBlock() + + // update port/channel ids + endpoint.ChannelID = channeltypes.FormatChannelIdentifier(channelSequence) + endpoint.ChannelConfig.PortID = portID + endpoint.ChannelConfig.Version = TestVersion + + return nil +} + +// SetupICAPath invokes the InterchainAccounts entrypoint and subsequent channel handshake handlers +func (suite *IntegrationTestSuite) SetupICAPath(path *ibctesting.Path, owner string) error { + if err := suite.RegisterInterchainAccount(path.EndpointA, owner); err != nil { + return err + } + + if err := path.EndpointB.ChanOpenTry(); err != nil { + return err + } + + if err := path.EndpointA.ChanOpenAck(); err != nil { + return err + } + + if err := path.EndpointB.ChanOpenConfirm(); err != nil { + return err + } + + return nil +} From f417335373093f59ae914e8da3f9057404153996 Mon Sep 17 00:00:00 2001 From: Puneet <59960662+puneet2019@users.noreply.github.com> Date: Fri, 14 Jul 2023 00:01:55 +0530 Subject: [PATCH 029/100] try simulating entire flow, finish delegation (#582) * try simulating entire flow, finish delegation * fix epochs * increase timeout --- .github/workflows/test.yml | 2 +- x/liquidstakeibc/keeper/deposit_test.go | 6 +- x/liquidstakeibc/keeper/keeper_test.go | 59 ++++ x/liquidstakeibc/keeper/msg_server_test.go | 59 +++- x/liquidstakeibc/keeper/setup_suite_test.go | 337 ++++++++++++++++++-- 5 files changed, 429 insertions(+), 34 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 6dad6c474..8c240c603 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -24,7 +24,7 @@ jobs: make test env: TEST_TARGET: "./x/..." - TEST_ARGS: "-timeout 5m -race -coverprofile=./coverage.out -covermode=atomic -v" + TEST_ARGS: "-timeout 10m -race -coverprofile=./coverage.out -covermode=atomic -v" - name: filter out DONTCOVER if: github.event_name == 'pull_request' diff --git a/x/liquidstakeibc/keeper/deposit_test.go b/x/liquidstakeibc/keeper/deposit_test.go index 4288026ae..7451f9701 100644 --- a/x/liquidstakeibc/keeper/deposit_test.go +++ b/x/liquidstakeibc/keeper/deposit_test.go @@ -11,7 +11,7 @@ func (suite *IntegrationTestSuite) TestGetSetDeposit() { suite.app.LiquidStakeIBCKeeper.SetDeposit(suite.ctx, &types.Deposit{ChainId: suite.chainB.ChainID}) deposits := suite.app.LiquidStakeIBCKeeper.GetAllDeposits(suite.ctx) - suite.Require().Equal(2, len(deposits)) + suite.Require().Equal(1, len(deposits)) suite.Require().Equal(suite.chainB.ChainID, deposits[0].ChainId) } @@ -23,7 +23,7 @@ func (suite *IntegrationTestSuite) TestDeleteDeposit() { deposits := suite.app.LiquidStakeIBCKeeper.GetAllDeposits(suite.ctx) // preexisting deposit - suite.Require().Equal(1, len(deposits)) + suite.Require().Equal(0, len(deposits)) } func (suite *IntegrationTestSuite) TestCreateDeposits() { @@ -377,7 +377,7 @@ func (suite *IntegrationTestSuite) TestGetPendingDepositsBeforeEpoch() { } hcs := suite.app.LiquidStakeIBCKeeper.GetPendingDepositsBeforeEpoch(suite.ctx, t.epoch) - suite.Require().Equal(len(t.expected)+1, len(hcs)) + suite.Require().Equal(len(t.expected), len(hcs)) for _, hc := range hcs { suite.Require().LessOrEqual(hc.Epoch, t.epoch) diff --git a/x/liquidstakeibc/keeper/keeper_test.go b/x/liquidstakeibc/keeper/keeper_test.go index f058373a7..c792f1d2c 100644 --- a/x/liquidstakeibc/keeper/keeper_test.go +++ b/x/liquidstakeibc/keeper/keeper_test.go @@ -2,6 +2,7 @@ package keeper_test import ( sdk "github.com/cosmos/cosmos-sdk/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" "github.com/cosmos/cosmos-sdk/x/bank/testutil" icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" connectiontypes "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" @@ -209,6 +210,11 @@ func (suite *IntegrationTestSuite) TestSetWithdrawAddress() { err := pstakeApp.LiquidStakeIBCKeeper.SetWithdrawAddress(ctx, hc) suite.Require().NoError(err) + + hc2 := hc + hc2.ConnectionId = "connection-3" + err = pstakeApp.LiquidStakeIBCKeeper.SetWithdrawAddress(ctx, hc2) + suite.Require().Error(err) } func (suite *IntegrationTestSuite) TestIsICAChannelActive() { pstakeApp, ctx := suite.app, suite.ctx @@ -219,3 +225,56 @@ func (suite *IntegrationTestSuite) TestIsICAChannelActive() { active := pstakeApp.LiquidStakeIBCKeeper.IsICAChannelActive(ctx, hc, pstakeApp.LiquidStakeIBCKeeper.GetPortID(hc.DelegationAccount.Owner)) suite.Require().Equal(true, active) } +func (suite *IntegrationTestSuite) TestSendICATransfer() { + pstakeApp, ctx := suite.app, suite.ctx + hc, found := pstakeApp.LiquidStakeIBCKeeper.GetHostChain(ctx, suite.chainB.ChainID) + suite.Require().Equal(true, found) + suite.Require().NotNil(hc) + + _, err := pstakeApp.LiquidStakeIBCKeeper.SendICATransfer(ctx, hc, sdk.NewInt64Coin(hc.HostDenom, 10), + hc.DelegationAccount.Address, authtypes.NewModuleAddress(types.UndelegationModuleAccount).String(), + hc.DelegationAccount.Owner) + suite.Require().NoError(err) + + _, err = pstakeApp.LiquidStakeIBCKeeper.SendICATransfer(ctx, hc, sdk.NewInt64Coin(hc.HostDenom, 10), + hc.DelegationAccount.Address, authtypes.NewModuleAddress(types.UndelegationModuleAccount).String(), + "invalid owner") + + hc2 := hc + hc2.PortId = "" + _, err = pstakeApp.LiquidStakeIBCKeeper.SendICATransfer(ctx, hc2, sdk.NewInt64Coin(hc.HostDenom, 10), + hc.DelegationAccount.Address, authtypes.NewModuleAddress(types.UndelegationModuleAccount).String(), + hc.DelegationAccount.Owner) + suite.Require().Error(err) +} +func (suite *IntegrationTestSuite) TestUpdateCValues() { + pstakeApp, ctx := suite.app, suite.ctx + hc, found := pstakeApp.LiquidStakeIBCKeeper.GetHostChain(ctx, suite.chainB.ChainID) + suite.Require().Equal(true, found) + suite.Require().NotNil(hc) + + suite.Require().NotPanics(func() { pstakeApp.LiquidStakeIBCKeeper.UpdateCValues(ctx) }) + + { + epoch := pstakeApp.EpochsKeeper.GetEpochInfo(suite.chainA.GetContext(), types.DelegationEpoch) + suite.NotNil(epoch) + err := pstakeApp.LiquidStakeIBCKeeper.BeforeEpochStart(suite.chainA.GetContext(), epoch.Identifier, epoch.CurrentEpoch) + suite.Require().NoError(err) + + senderAcc := suite.chainA.SenderAccount + //user liquidstakes + msgLiquidStake := types.NewMsgLiquidStake(sdk.NewInt64Coin(hc.IBCDenom(), 1000000), senderAcc.GetAddress()) + result, err := suite.app.MsgServiceRouter().Handler(msgLiquidStake)(suite.chainA.GetContext(), msgLiquidStake) + suite.NotNil(result) + suite.NoError(err) + } + suite.Require().NotPanics(func() { pstakeApp.LiquidStakeIBCKeeper.UpdateCValues(ctx) }) + + //lower limits so that chain goes out of limits + params := pstakeApp.LiquidStakeIBCKeeper.GetParams(ctx) + params.UpperCValueLimit = sdk.MustNewDecFromStr("0.5") + pstakeApp.LiquidStakeIBCKeeper.SetParams(ctx, params) + suite.Require().NotPanics(func() { pstakeApp.LiquidStakeIBCKeeper.UpdateCValues(ctx) }) + hc, _ = pstakeApp.LiquidStakeIBCKeeper.GetHostChain(ctx, suite.chainB.ChainID) + suite.Require().Equal(false, hc.Active) +} diff --git a/x/liquidstakeibc/keeper/msg_server_test.go b/x/liquidstakeibc/keeper/msg_server_test.go index ef5a1af4f..fea6d7960 100644 --- a/x/liquidstakeibc/keeper/msg_server_test.go +++ b/x/liquidstakeibc/keeper/msg_server_test.go @@ -2,17 +2,24 @@ package keeper_test import ( "context" + "reflect" + "testing" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/persistenceOne/pstake-native/v2/x/liquidstakeibc/keeper" "github.com/persistenceOne/pstake-native/v2/x/liquidstakeibc/types" - "reflect" - "testing" ) func (suite *IntegrationTestSuite) Test_msgServer_LiquidStake() { pstakeapp, ctx := suite.app, suite.ctx hc, found := pstakeapp.LiquidStakeIBCKeeper.GetHostChain(ctx, suite.chainB.ChainID) suite.Require().True(found) + epoch := pstakeapp.EpochsKeeper.GetEpochInfo(suite.chainA.GetContext(), types.DelegationEpoch) + suite.NotNil(epoch) + err := pstakeapp.LiquidStakeIBCKeeper.BeforeEpochStart(suite.chainA.GetContext(), epoch.Identifier, epoch.CurrentEpoch) + suite.Require().NoError(err) + type args struct { goCtx context.Context msg *types.MsgLiquidStake @@ -34,8 +41,53 @@ func (suite *IntegrationTestSuite) Test_msgServer_LiquidStake() { }, want: &types.MsgLiquidStakeResponse{}, wantErr: false, + }, { + name: "host chain with ibc denom not found", + args: args{ + goCtx: ctx, + msg: &types.MsgLiquidStake{ + DelegatorAddress: suite.chainA.SenderAccount.GetAddress().String(), + Amount: sdk.NewInt64Coin(hc.HostDenom, 1000), + }, + }, + want: nil, + wantErr: true, + }, { + name: "amount less than mint amount", + args: args{ + goCtx: ctx, + msg: &types.MsgLiquidStake{ + DelegatorAddress: suite.chainA.SenderAccount.GetAddress().String(), + Amount: sdk.NewInt64Coin(hc.IBCDenom(), 0), + }, + }, + want: nil, + wantErr: true, + }, { + name: "invalid delegator address", + args: args{ + goCtx: ctx, + msg: &types.MsgLiquidStake{ + DelegatorAddress: "invalidaddr", + Amount: sdk.NewInt64Coin(hc.IBCDenom(), 1000), + }, + }, + want: nil, + wantErr: true, + }, { + name: "failed to send tokens", + args: args{ + goCtx: ctx, + msg: &types.MsgLiquidStake{ + DelegatorAddress: suite.chainA.SenderAccounts[1].SenderAccount.GetAddress().String(), + Amount: sdk.NewInt64Coin(hc.IBCDenom(), 1000), + }, + }, + want: nil, + wantErr: true, }, } + for _, tt := range tests { suite.T().Run(tt.name, func(t *testing.T) { k := keeper.NewMsgServerImpl(suite.app.LiquidStakeIBCKeeper) @@ -214,6 +266,9 @@ func (suite *IntegrationTestSuite) Test_msgServer_UpdateHostChain() { Updates: []*types.KVUpdate{{ Key: types.KeyActive, Value: "true", + }, { + Key: types.KeyAutocompoundFactor, + Value: "20", }}, }, }, diff --git a/x/liquidstakeibc/keeper/setup_suite_test.go b/x/liquidstakeibc/keeper/setup_suite_test.go index 6edf8bdfb..8557c02fd 100644 --- a/x/liquidstakeibc/keeper/setup_suite_test.go +++ b/x/liquidstakeibc/keeper/setup_suite_test.go @@ -1,13 +1,20 @@ package keeper_test import ( + "fmt" + "strconv" "testing" + "time" + "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" + distributiontypes "github.com/cosmos/cosmos-sdk/x/distribution/types" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + "github.com/cosmos/gogoproto/proto" icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" ibctransfertypes "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" ibctesting "github.com/cosmos/ibc-go/v7/testing" "github.com/stretchr/testify/suite" @@ -50,6 +57,9 @@ type IntegrationTestSuite struct { transferPathAB *ibctesting.Path // chainA - chainB transfer path transferPathAC *ibctesting.Path // chainA - chainC transfer path + + delegationPathAB *ibctesting.Path // chainA - chain B delegation ica path + rewardsPathAB *ibctesting.Path // chainA - chainB rewards ica path } func TestKeeperTestSuite(t *testing.T) { @@ -63,7 +73,7 @@ func (suite *IntegrationTestSuite) SetupTest() { ibctesting.DefaultTestingAppInit = helpers.SetupTestingApp sdk.DefaultBondDenom = "uxprt" suite.chainA = ibctesting.NewTestChain(suite.T(), suite.coordinator, ibctesting.GetChainID(1)) - + suite.ResetEpochs() ibctesting.DefaultTestingAppInit = ibctesting.SetupTestingApp sdk.DefaultBondDenom = HostDenom suite.chainB = ibctesting.NewTestChain(suite.T(), suite.coordinator, ibctesting.GetChainID(2)) @@ -83,7 +93,6 @@ func (suite *IntegrationTestSuite) SetupTest() { suite.coordinator.Setup(suite.transferPathAC) suite.app = suite.chainA.App.(*app.PstakeApp) - suite.ctx = suite.chainA.GetContext() suite.SetupHostChainAB() suite.SetupICAChannelsAB() @@ -92,33 +101,36 @@ func (suite *IntegrationTestSuite) SetupTest() { suite.Transfer(suite.transferPathAC, "uosmo") suite.CleanupSetup() + suite.ctx = suite.chainA.GetContext() } func (suite *IntegrationTestSuite) CleanupSetup() { - pstakeApp, ctx := suite.app, suite.ctx - params := pstakeApp.LiquidStakeIBCKeeper.GetParams(ctx) + pstakeApp := suite.app + + params := pstakeApp.LiquidStakeIBCKeeper.GetParams(suite.chainA.GetContext()) params.AdminAddress = suite.chainA.SenderAccount.GetAddress().String() - suite.app.LiquidStakeIBCKeeper.SetParams(ctx, params) + suite.app.LiquidStakeIBCKeeper.SetParams(suite.chainA.GetContext(), params) - epoch := suite.app.EpochsKeeper.GetEpochInfo(ctx, types.DelegationEpoch).CurrentEpoch - pstakeApp.LiquidStakeIBCKeeper.DepositWorkflow(ctx, epoch) + epoch := suite.app.EpochsKeeper.GetEpochInfo(suite.chainA.GetContext(), types.DelegationEpoch).CurrentEpoch + pstakeApp.LiquidStakeIBCKeeper.DepositWorkflow(suite.chainA.GetContext(), epoch) } -func (suite *IntegrationTestSuite) TestOneFullFlow() { - pstakeApp, ctx := suite.app, suite.ctx - k := pstakeApp.LiquidStakeIBCKeeper - hc, ok := k.GetHostChain(ctx, suite.chainB.ChainID) - suite.True(ok) - senderAcc := suite.chainA.SenderAccount - //user liquidstakes - msgLiquidStake := types.NewMsgLiquidStake(sdk.NewInt64Coin(hc.IBCDenom(), 1000000), senderAcc.GetAddress()) - result, err := suite.chainA.SendMsgs(msgLiquidStake) - suite.NotNil(result) - suite.NoError(err) - - msgRedeem := types.NewMsgRedeem(sdk.NewInt64Coin(hc.MintDenom(), 100000), senderAcc.GetAddress()) - result, err = suite.chainA.SendMsgs(msgRedeem) - suite.NotNil(result) - suite.NoError(err) +func (suite *IntegrationTestSuite) ResetEpochs() { + ctx := suite.chainA.GetContext() + + //ctxCheck := app.BaseApp.NewContext(true, tmproto.Header{}) + epochsKeeper := suite.chainA.App.(*app.PstakeApp).EpochsKeeper + + for _, epoch := range epochsKeeper.AllEpochInfos(ctx) { + epoch.StartTime = ctx.BlockTime() + epoch.CurrentEpoch = int64(1) + epoch.CurrentEpochStartTime = ctx.BlockTime() + epoch.CurrentEpochStartHeight = ctx.BlockHeight() + epochsKeeper.DeleteEpochInfo(ctx, epoch.Identifier) + err := epochsKeeper.AddEpochInfo(ctx, epoch) + if err != nil { + panic(err) + } + } } func (suite *IntegrationTestSuite) SetupHostChainAB() { @@ -143,12 +155,14 @@ func (suite *IntegrationTestSuite) SetupHostChainAB() { } validators := make([]*types.Validator, 0) + equalWeight := sdk.OneDec().Quo(sdk.NewDecFromInt(sdk.NewInt(int64(len(suite.chainB.Vals.Validators))))) for _, validator := range suite.chainB.Vals.Validators { validators = append(validators, &types.Validator{ - OperatorAddress: validator.Address.String(), + OperatorAddress: sdk.MustBech32ifyAddressBytes(app.Bech32PrefixValAddr, validator.Address), Status: stakingtypes.Bonded.String(), - Weight: sdk.ZeroDec(), + Weight: equalWeight, DelegatedAmount: sdk.ZeroInt(), + ExchangeRate: sdk.OneDec(), }) } @@ -178,7 +192,7 @@ func (suite *IntegrationTestSuite) SetupHostChainAB() { Active: true, } - suite.app.LiquidStakeIBCKeeper.SetHostChain(suite.ctx, hc) + suite.app.LiquidStakeIBCKeeper.SetHostChain(suite.chainA.GetContext(), hc) } func NewTransferPath(chainA, chainB *ibctesting.TestChain) *ibctesting.Path { @@ -216,6 +230,7 @@ func (suite *IntegrationTestSuite) SetupICAChannelsAB() { icapath.EndpointB.ClientConfig = suite.transferPathAB.EndpointB.ClientConfig icapath.EndpointA.ConnectionConfig = suite.transferPathAB.EndpointA.ConnectionConfig icapath.EndpointB.ConnectionConfig = suite.transferPathAB.EndpointB.ConnectionConfig + suite.delegationPathAB = icapath icapath2 := NewICAPath(suite.chainA, suite.chainB) icapath2.EndpointA.ClientID = suite.transferPathAB.EndpointA.ClientID @@ -226,11 +241,12 @@ func (suite *IntegrationTestSuite) SetupICAChannelsAB() { icapath2.EndpointB.ClientConfig = suite.transferPathAB.EndpointB.ClientConfig icapath2.EndpointA.ConnectionConfig = suite.transferPathAB.EndpointA.ConnectionConfig icapath2.EndpointB.ConnectionConfig = suite.transferPathAB.EndpointB.ConnectionConfig + suite.rewardsPathAB = icapath2 - err := suite.SetupICAPath(icapath, types.DefaultDelegateAccountPortOwner(suite.chainB.ChainID)) + err := suite.SetupICAPath(suite.delegationPathAB, types.DefaultDelegateAccountPortOwner(suite.chainB.ChainID)) suite.Require().NoError(err) - err = suite.SetupICAPath(icapath2, types.DefaultRewardsAccountPortOwner(suite.chainB.ChainID)) + err = suite.SetupICAPath(suite.rewardsPathAB, types.DefaultRewardsAccountPortOwner(suite.chainB.ChainID)) suite.Require().NoError(err) } func NewICAPath(chainA, chainB *ibctesting.TestChain) *ibctesting.Path { @@ -288,3 +304,268 @@ func (suite *IntegrationTestSuite) SetupICAPath(path *ibctesting.Path, owner str return nil } + +func (suite *IntegrationTestSuite) TestOneFullFlow() { + pstakeApp := suite.app + k := pstakeApp.LiquidStakeIBCKeeper + hc, ok := k.GetHostChain(suite.chainA.GetContext(), suite.chainB.ChainID) + suite.True(ok) + + epoch := pstakeApp.EpochsKeeper.GetEpochInfo(suite.chainA.GetContext(), types.DelegationEpoch) + suite.NotNil(epoch) + err := k.BeforeEpochStart(suite.chainA.GetContext(), epoch.Identifier, epoch.CurrentEpoch) + suite.Require().NoError(err) + + senderAcc := suite.chainA.SenderAccount + //user liquidstakes + msgLiquidStake := types.NewMsgLiquidStake(sdk.NewInt64Coin(hc.IBCDenom(), 1000000), senderAcc.GetAddress()) + result, err := suite.app.MsgServiceRouter().Handler(msgLiquidStake)(suite.chainA.GetContext(), msgLiquidStake) + suite.NotNil(result) + suite.NoError(err) + + // user redeems + msgRedeem := types.NewMsgRedeem(sdk.NewInt64Coin(hc.MintDenom(), 100000), senderAcc.GetAddress()) + result, err = suite.app.MsgServiceRouter().Handler(msgRedeem)(suite.chainA.GetContext(), msgRedeem) + suite.NotNil(result) + suite.NoError(err) + + // Do ica staking + epoch = pstakeApp.EpochsKeeper.GetEpochInfo(suite.chainA.GetContext(), types.DelegationEpoch) + suite.NotNil(epoch) + + deposit, found := k.GetDepositForChainAndEpoch(suite.chainA.GetContext(), hc.ChainId, epoch.CurrentEpoch) + suite.Require().True(found) + suite.Require().Equal(types.Deposit_DEPOSIT_PENDING, deposit.State) + + ctx := suite.chainA.GetContext() //use separate context so we can fetch events out of it + err = k.AfterEpochEnd(ctx, epoch.Identifier, epoch.CurrentEpoch) + suite.NoError(err) + packets, err := ParsePacketsFromEvents(ctx.EventManager().Events()) + suite.NoError(err) + + deposit, found = k.GetDepositForChainAndEpoch(suite.chainA.GetContext(), hc.ChainId, epoch.CurrentEpoch) + suite.Require().True(found) + suite.Require().Equal(types.Deposit_DEPOSIT_SENT, deposit.State) + + suite.chainA.NextBlock() //commit the packets and their commitments so its available in context + + suite.RelayAllPacketsAB(packets) //also calls for Next Block causing Deposit_DEPOSIT_RECEIVED to just pass + + deposit, found = k.GetDepositForChainAndEpoch(suite.chainA.GetContext(), hc.ChainId, epoch.CurrentEpoch) + suite.Require().True(found) + suite.Require().Equal(types.Deposit_DEPOSIT_DELEGATING, deposit.State) + + timeoutTimestamp := uint64(suite.chainA.GetContext().BlockTime().UnixNano()) + uint64(types.ICATimeoutTimestamp.Nanoseconds()) - uint64(time.Second*5) //sub one b + data, err := suite.CreateICAData(deposit.Amount.Amount, hc, 0) + suite.NoError(err) + + packet, err := CreateICADelegatePacketHardcoded(data, + "1", "0-0", fmt.Sprintf("%d", timeoutTimestamp)) + suite.NoError(err) + suite.chainA.NextBlock() //commit the packets and their commitments so its available in context + suite.RelayAllPacketsAB([]channeltypes.Packet{packet}) + deposit, found = k.GetDepositForChainAndEpoch(suite.chainA.GetContext(), hc.ChainId, epoch.CurrentEpoch) + suite.Require().False(found) + suite.Require().Nil(deposit) + // ^ Fin staking + + // Do unstake + undelegateAmount := int64(100000) + msgUnstake := types.NewMsgLiquidUnstake(sdk.NewInt64Coin(hc.MintDenom(), undelegateAmount), senderAcc.GetAddress()) + result, err = suite.app.MsgServiceRouter().Handler(msgUnstake)(suite.chainA.GetContext(), msgUnstake) + suite.NotNil(result) + suite.NoError(err) + + epoch = pstakeApp.EpochsKeeper.GetEpochInfo(suite.chainA.GetContext(), types.DelegationEpoch) + suite.NotNil(epoch) + + userUnbonding, found := k.GetUserUnbonding(suite.chainA.GetContext(), hc.ChainId, senderAcc.GetAddress().String(), types.CurrentUnbondingEpoch(hc.UnbondingFactor, epoch.CurrentEpoch)) + suite.Require().True(found) + suite.Require().NotNil(userUnbonding) + + unbonding, found := k.GetUnbonding(suite.chainA.GetContext(), hc.ChainId, types.CurrentUnbondingEpoch(hc.UnbondingFactor, epoch.CurrentEpoch)) + suite.Require().True(found) + suite.Require().Equal(types.Unbonding_UNBONDING_PENDING, unbonding.State) + //Force undelegation by manipulating epoch number + ctx = suite.chainA.GetContext() + err = k.AfterEpochEnd(ctx, epoch.Identifier, types.CurrentUnbondingEpoch(hc.UnbondingFactor, epoch.CurrentEpoch)) + packets, err = ParsePacketsFromEvents(ctx.EventManager().Events()) + suite.NoError(err) + unbonding, found = k.GetUnbonding(suite.chainA.GetContext(), hc.ChainId, types.CurrentUnbondingEpoch(hc.UnbondingFactor, epoch.CurrentEpoch)) + suite.Require().True(found) + suite.Require().Equal(types.Unbonding_UNBONDING_INITIATED, unbonding.State) + + suite.chainA.NextBlock() //commit the packets and their commitments so its available in context + + suite.RelayAllPacketsAB(packets) + unbonding, found = k.GetUnbonding(suite.chainA.GetContext(), hc.ChainId, types.CurrentUnbondingEpoch(hc.UnbondingFactor, epoch.CurrentEpoch)) + suite.Require().True(found) + suite.Require().Equal(types.Unbonding_UNBONDING_MATURING, unbonding.State) +} + +func (suite *IntegrationTestSuite) RelayAllPacketsAB(packets []channeltypes.Packet) { + suite.Require().NotEqual(0, len(packets), "No packets to relay") + hc, _ := suite.app.LiquidStakeIBCKeeper.GetHostChain(suite.chainA.GetContext(), suite.chainB.ChainID) + for _, packet := range packets { + if packet.SourcePort == hc.PortId { + err := suite.transferPathAB.RelayPacket(packet) + suite.Require().NoError(err) + } else if packet.SourcePort == suite.app.LiquidStakeIBCKeeper.GetPortID(hc.DelegationAccount.Owner) { + err := suite.delegationPathAB.RelayPacket(packet) + suite.Require().NoError(err) + } else if packet.SourcePort == suite.app.LiquidStakeIBCKeeper.GetPortID(hc.RewardsAccount.Owner) { + err := suite.rewardsPathAB.RelayPacket(packet) + suite.Require().NoError(err) + } + } +} + +// ParsePacketsFromEvents parses events emitted from a MsgRecvPacket and returns the +// acknowledgement. +func ParsePacketsFromEvents(events sdk.Events) ([]channeltypes.Packet, error) { + packets := make([]channeltypes.Packet, 0) + for _, ev := range events { + if ev.Type == channeltypes.EventTypeSendPacket { + packet := channeltypes.Packet{} + for _, attr := range ev.Attributes { + switch attr.Key { + case channeltypes.AttributeKeyData: //nolint:staticcheck // DEPRECATED + packet.Data = []byte(attr.Value) + + case channeltypes.AttributeKeySequence: + seq, err := strconv.ParseUint(attr.Value, 10, 64) + if err != nil { + return []channeltypes.Packet{}, err + } + + packet.Sequence = seq + + case channeltypes.AttributeKeySrcPort: + packet.SourcePort = attr.Value + + case channeltypes.AttributeKeySrcChannel: + packet.SourceChannel = attr.Value + + case channeltypes.AttributeKeyDstPort: + packet.DestinationPort = attr.Value + + case channeltypes.AttributeKeyDstChannel: + packet.DestinationChannel = attr.Value + + case channeltypes.AttributeKeyTimeoutHeight: + height, err := clienttypes.ParseHeight(attr.Value) + if err != nil { + return []channeltypes.Packet{}, err + } + + packet.TimeoutHeight = height + + case channeltypes.AttributeKeyTimeoutTimestamp: + timestamp, err := strconv.ParseUint(attr.Value, 10, 64) + if err != nil { + return []channeltypes.Packet{}, err + } + + packet.TimeoutTimestamp = timestamp + + default: + continue + } + } + packets = append(packets, packet) + } + } + if len(packets) == 0 { + return []channeltypes.Packet{}, fmt.Errorf("acknowledgement event attribute not found") + } else { + return packets, nil + } +} + +func (suite *IntegrationTestSuite) CreateICAData(amount math.Int, hc *types.HostChain, txtype int) (string, error) { + + messages := make([]proto.Message, 0) + for _, vals := range hc.Validators { + var message proto.Message + switch txtype { + case 0: + message = &stakingtypes.MsgDelegate{ + DelegatorAddress: hc.DelegationAccount.Address, + ValidatorAddress: vals.OperatorAddress, + Amount: sdk.NewCoin(hc.HostDenom, vals.Weight.MulInt(amount).TruncateInt()), + } + case 1: + case 2: + message = &distributiontypes.MsgWithdrawDelegatorReward{ + DelegatorAddress: hc.DelegationAccount.Address, + ValidatorAddress: vals.OperatorAddress, + } + + } + + messages = append(messages, message) + } + msgData, err := icatypes.SerializeCosmosTx(suite.app.AppCodec(), messages) + if err != nil { + return "", err + } + + icaPacketData := icatypes.InterchainAccountPacketData{ + Type: icatypes.EXECUTE_TX, + Data: msgData, + } + return string(icaPacketData.GetBytes()), nil +} + +func CreateICADelegatePacketHardcoded(data, sequence, timeoutHeight, timeoutTimestamp string) (channeltypes.Packet, error) { + seq, err := strconv.ParseUint(sequence, 10, 64) + if err != nil { + return channeltypes.Packet{}, err + } + height, err := clienttypes.ParseHeight(timeoutHeight) + if err != nil { + return channeltypes.Packet{}, err + } + + timestamp, err := strconv.ParseUint(timeoutTimestamp, 10, 64) + if err != nil { + return channeltypes.Packet{}, err + } + packet := channeltypes.Packet{ + Sequence: seq, + SourcePort: "icacontroller-testchain2-1.delegate", + SourceChannel: "channel-2", + DestinationPort: "icahost", + DestinationChannel: "channel-1", + Data: []byte(data), + TimeoutHeight: height, + TimeoutTimestamp: timestamp, + } + return packet, nil +} +func CreateICARewardsPacketHardcoded(data, sequence, timeoutHeight, timeoutTimestamp string) (channeltypes.Packet, error) { + seq, err := strconv.ParseUint(sequence, 10, 64) + if err != nil { + return channeltypes.Packet{}, err + } + height, err := clienttypes.ParseHeight(timeoutHeight) + if err != nil { + return channeltypes.Packet{}, err + } + + timestamp, err := strconv.ParseUint(timeoutTimestamp, 10, 64) + if err != nil { + return channeltypes.Packet{}, err + } + packet := channeltypes.Packet{ + Sequence: seq, + SourcePort: "icacontroller-testchain2-1.rewards", + SourceChannel: "channel-3", + DestinationPort: "icahost", + DestinationChannel: "channel-2", + Data: []byte(data), + TimeoutHeight: height, + TimeoutTimestamp: timestamp, + } + return packet, nil +} From 5d6e24b43834daaef749aa2580a7745706794bfb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 14 Jul 2023 11:11:54 +0530 Subject: [PATCH 030/100] Bump coverallsapp/github-action from 2.2.0 to 2.2.1 (#584) Bumps [coverallsapp/github-action](https://github.com/coverallsapp/github-action) from 2.2.0 to 2.2.1. - [Release notes](https://github.com/coverallsapp/github-action/releases) - [Commits](https://github.com/coverallsapp/github-action/compare/v2.2.0...v2.2.1) --- updated-dependencies: - dependency-name: coverallsapp/github-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 8c240c603..1e1d546fe 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -45,7 +45,7 @@ jobs: - name: Coveralls if: github.event_name == 'pull_request' - uses: coverallsapp/github-action@v2.2.0 + uses: coverallsapp/github-action@v2.2.1 with: github-token: ${{ secrets.GITHUB_TOKEN }} path-to-lcov: coverage.lcov From 0a5b706d738cd8d727ebb18588206bd54cbae3fb Mon Sep 17 00:00:00 2001 From: Puneet <59960662+puneet2019@users.noreply.github.com> Date: Fri, 14 Jul 2023 13:50:31 +0530 Subject: [PATCH 031/100] icq tests, invariants tests. (#585) --- x/liquidstakeibc/keeper/icq_queries_test.go | 157 ++++++++++++ x/liquidstakeibc/keeper/icq_test.go | 271 ++++++++++++++++++++ x/liquidstakeibc/keeper/invariants.go | 2 +- x/liquidstakeibc/keeper/invariants_test.go | 22 ++ x/liquidstakeibc/keeper/setup_suite_test.go | 11 +- 5 files changed, 457 insertions(+), 6 deletions(-) create mode 100644 x/liquidstakeibc/keeper/icq_queries_test.go create mode 100644 x/liquidstakeibc/keeper/icq_test.go create mode 100644 x/liquidstakeibc/keeper/invariants_test.go diff --git a/x/liquidstakeibc/keeper/icq_queries_test.go b/x/liquidstakeibc/keeper/icq_queries_test.go new file mode 100644 index 000000000..ae507579d --- /dev/null +++ b/x/liquidstakeibc/keeper/icq_queries_test.go @@ -0,0 +1,157 @@ +package keeper_test + +import ( + "github.com/persistenceOne/pstake-native/v2/x/liquidstakeibc/types" +) + +func (suite *IntegrationTestSuite) TestKeeper_QueryHostChainValidator() { + pstakeApp, ctx := suite.app, suite.ctx + k := pstakeApp.LiquidStakeIBCKeeper + hc, found := k.GetHostChain(ctx, suite.chainB.ChainID) + suite.Require().Equal(found, true) + type args struct { + hc *types.HostChain + validatorAddress string + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "Success", + args: args{ + hc: hc, + validatorAddress: hc.Validators[0].OperatorAddress, + }, + wantErr: false, + }, + { + name: "Invalid oper addr", + args: args{ + hc: hc, + validatorAddress: "invalid addr", + }, + wantErr: true, + }, + } + for _, tt := range tests { + suite.Run(tt.name, func() { + + if err := k.QueryHostChainValidator(ctx, tt.args.hc, tt.args.validatorAddress); (err != nil) != tt.wantErr { + suite.T().Errorf("QueryHostChainValidator() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func (suite *IntegrationTestSuite) TestKeeper_QueryValidatorDelegation() { + pstakeApp, ctx := suite.app, suite.ctx + k := pstakeApp.LiquidStakeIBCKeeper + hc, found := k.GetHostChain(ctx, suite.chainB.ChainID) + suite.Require().Equal(found, true) + + hc2 := types.HostChain{DelegationAccount: &types.ICAAccount{Address: "invalid"}} + + type args struct { + hc *types.HostChain + validator *types.Validator + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "Success", + args: args{ + hc: hc, + validator: hc.Validators[0], + }, + wantErr: false, + }, { + name: "Invalid delegator addr", + args: args{ + hc: &hc2, + validator: hc.Validators[0], + }, + wantErr: true, + }} + for _, tt := range tests { + suite.Run(tt.name, func() { + if err := k.QueryValidatorDelegation(ctx, tt.args.hc, tt.args.validator); (err != nil) != tt.wantErr { + suite.T().Errorf("QueryValidatorDelegation() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func (suite *IntegrationTestSuite) TestKeeper_QueryDelegationHostChainAccountBalance() { + pstakeApp, ctx := suite.app, suite.ctx + k := pstakeApp.LiquidStakeIBCKeeper + hc, found := k.GetHostChain(ctx, suite.chainB.ChainID) + suite.Require().Equal(found, true) + + hc2 := types.HostChain{DelegationAccount: &types.ICAAccount{Address: "invalid"}} + + type args struct { + hc *types.HostChain + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "Success", + args: args{hc: hc}, + wantErr: false, + }, { + name: "Invalidadelegator addr", + args: args{hc: &hc2}, + wantErr: true, + }, + } + for _, tt := range tests { + suite.Run(tt.name, func() { + if err := k.QueryDelegationHostChainAccountBalance(ctx, tt.args.hc); (err != nil) != tt.wantErr { + suite.T().Errorf("QueryDelegationHostChainAccountBalance() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} +func (suite *IntegrationTestSuite) TestKeeper_QueryRewardsHostChainAccountBalance() { + pstakeApp, ctx := suite.app, suite.ctx + k := pstakeApp.LiquidStakeIBCKeeper + hc, found := k.GetHostChain(ctx, suite.chainB.ChainID) + suite.Require().Equal(found, true) + + hc2 := types.HostChain{RewardsAccount: &types.ICAAccount{Address: "invalid"}} + + type args struct { + hc *types.HostChain + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "Success", + args: args{hc: hc}, + wantErr: false, + }, { + name: "invalid rewards addr", + args: args{hc: &hc2}, + wantErr: true, + }, + } + for _, tt := range tests { + suite.Run(tt.name, func() { + + if err := k.QueryRewardsHostChainAccountBalance(ctx, tt.args.hc); (err != nil) != tt.wantErr { + suite.T().Errorf("QueryRewardsHostChainAccountBalance() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} diff --git a/x/liquidstakeibc/keeper/icq_test.go b/x/liquidstakeibc/keeper/icq_test.go new file mode 100644 index 000000000..0556c38a3 --- /dev/null +++ b/x/liquidstakeibc/keeper/icq_test.go @@ -0,0 +1,271 @@ +package keeper_test + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + icqtypes "github.com/persistenceOne/persistence-sdk/v2/x/interchainquery/types" + "github.com/persistenceOne/pstake-native/v2/x/liquidstakeibc/keeper" +) + +func (suite *IntegrationTestSuite) TestValidatorCallback() { + pstakeApp, ctx := suite.app, suite.ctx + k := pstakeApp.LiquidStakeIBCKeeper + hc, found := k.GetHostChain(ctx, suite.chainB.ChainID) + suite.Require().Equal(found, true) + + makeData := func(validator stakingtypes.Validator) []byte { + return stakingtypes.MustMarshalValidator(pstakeApp.AppCodec(), &validator) + } + type args struct { + ctx sdk.Context + data []byte + query icqtypes.Query + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "Success", + args: args{ + data: makeData(stakingtypes.Validator{ + OperatorAddress: hc.Validators[0].OperatorAddress, + Status: 0, + Tokens: sdk.NewInt(100), + DelegatorShares: sdk.NewDec(100), + }), + query: icqtypes.Query{ChainId: hc.ChainId}, + }, + wantErr: false, + }, + { + name: "Invalid Chain ID", + args: args{ + data: makeData(stakingtypes.Validator{ + OperatorAddress: hc.Validators[0].OperatorAddress, + Status: 0, + Tokens: sdk.NewInt(100), + DelegatorShares: sdk.NewDec(100), + }), + query: icqtypes.Query{ChainId: "invalid-1"}, + }, + wantErr: true, + }, { + name: "Invalid Data", + args: args{ + data: []byte("invalid data"), + query: icqtypes.Query{ChainId: hc.ChainId}, + }, + wantErr: true, + }, + } + for _, tt := range tests { + suite.Run(tt.name, func() { + if err := keeper.ValidatorCallback(k, ctx, tt.args.data, tt.args.query); (err != nil) != tt.wantErr { + suite.T().Errorf("ValidatorCallback() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func (suite *IntegrationTestSuite) TestDelegationCallback() { + pstakeApp, ctx := suite.app, suite.ctx + k := pstakeApp.LiquidStakeIBCKeeper + hc, found := k.GetHostChain(ctx, suite.chainB.ChainID) + suite.Require().Equal(found, true) + + for i := range hc.Validators { + hc.Validators[i].DelegatedAmount = sdk.NewInt(100) + } + k.SetHostChain(ctx, hc) + + makeData := func(delegation stakingtypes.Delegation) []byte { + return stakingtypes.MustMarshalDelegation(pstakeApp.AppCodec(), delegation) + + } + type args struct { + ctx sdk.Context + data []byte + query icqtypes.Query + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "Success", + args: args{ + data: makeData(stakingtypes.Delegation{ + DelegatorAddress: hc.DelegationAccount.Address, + ValidatorAddress: hc.Validators[0].OperatorAddress, + Shares: sdk.NewDec(100), + }), + query: icqtypes.Query{ChainId: hc.ChainId}, + }, + wantErr: false, + }, { + name: "slashed validator", + args: args{ + data: makeData(stakingtypes.Delegation{ + DelegatorAddress: hc.DelegationAccount.Address, + ValidatorAddress: hc.Validators[0].OperatorAddress, + Shares: sdk.NewDec(10), + }), + query: icqtypes.Query{ChainId: hc.ChainId}, + }, + wantErr: false, + }, { + name: "Invalid Chain ID", + args: args{ + data: makeData(stakingtypes.Delegation{ + DelegatorAddress: hc.DelegationAccount.Address, + ValidatorAddress: hc.Validators[0].OperatorAddress, + Shares: sdk.NewDec(100), + }), + query: icqtypes.Query{ChainId: "invalid-1"}, + }, + wantErr: true, + }, { + name: "Invalid Data", + args: args{ + data: []byte("invalid data"), + query: icqtypes.Query{ChainId: hc.ChainId}, + }, + wantErr: true, + }, { + name: "Invalid validator", + args: args{ + data: makeData(stakingtypes.Delegation{ + DelegatorAddress: hc.DelegationAccount.Address, + ValidatorAddress: "does not exist", + Shares: sdk.NewDec(100), + }), + query: icqtypes.Query{ChainId: hc.ChainId}, + }, + wantErr: true, + }, + } + for _, tt := range tests { + suite.Run(tt.name, func() { + if err := keeper.DelegationCallback(k, ctx, tt.args.data, tt.args.query); (err != nil) != tt.wantErr { + suite.T().Errorf("DelegationCallback() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func (suite *IntegrationTestSuite) TestDelegationAccountBalanceCallback() { + pstakeApp, ctx := suite.app, suite.ctx + k := pstakeApp.LiquidStakeIBCKeeper + hc, found := k.GetHostChain(ctx, suite.chainB.ChainID) + suite.Require().Equal(found, true) + + makeData := func(denom string, amount int64) []byte { + coin := sdk.NewInt64Coin(denom, amount) + return pstakeApp.AppCodec().MustMarshal(&coin) + } + type args struct { + data []byte + query icqtypes.Query + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "Success", + args: args{ + data: makeData(hc.HostDenom, 100), + query: icqtypes.Query{ChainId: hc.ChainId}, + }, + wantErr: false, + }, { + name: "invalid chain id", + args: args{ + data: makeData(hc.HostDenom, 100), + query: icqtypes.Query{ChainId: "Invalid Chain ID"}, + }, + wantErr: true, + }, { + name: "invalid data", + args: args{ + data: []byte("invalid"), + query: icqtypes.Query{ChainId: hc.ChainId}, + }, + wantErr: true, + }, + } + for _, tt := range tests { + suite.Run(tt.name, func() { + if err := keeper.DelegationAccountBalanceCallback(k, ctx, tt.args.data, tt.args.query); (err != nil) != tt.wantErr { + suite.T().Errorf("DelegationAccountBalanceCallback() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func (suite *IntegrationTestSuite) TestRewardsAccountBalanceCallback() { + pstakeApp, ctx := suite.app, suite.ctx + k := pstakeApp.LiquidStakeIBCKeeper + hc, found := k.GetHostChain(ctx, suite.chainB.ChainID) + suite.Require().Equal(found, true) + + makeData := func(denom string, amount int64) []byte { + coin := sdk.NewInt64Coin(denom, amount) + return pstakeApp.AppCodec().MustMarshal(&coin) + } + for i := range hc.Validators { + hc.Validators[i].DelegatedAmount = sdk.NewInt(1000000) + } + k.SetHostChain(ctx, hc) + type args struct { + ctx sdk.Context + data []byte + query icqtypes.Query + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "Success, hits the cap", + args: args{ + data: makeData(hc.HostDenom, 100), + query: icqtypes.Query{ChainId: hc.ChainId}, + }, + wantErr: false, + }, { + name: "Success, does not hit the cap", + args: args{ + data: makeData(hc.HostDenom, 1), + query: icqtypes.Query{ChainId: hc.ChainId}, + }, + wantErr: false, + }, { + name: "invalid chain id", + args: args{ + data: makeData(hc.HostDenom, 100), + query: icqtypes.Query{ChainId: "Invalid Chain ID"}, + }, + wantErr: true, + }, { + name: "invalid data", + args: args{ + data: []byte("invalid"), + query: icqtypes.Query{ChainId: hc.ChainId}, + }, + wantErr: true, + }, + } + for _, tt := range tests { + suite.Run(tt.name, func() { + if err := keeper.RewardsAccountBalanceCallback(k, ctx, tt.args.data, tt.args.query); (err != nil) != tt.wantErr { + suite.T().Errorf("RewardsAccountBalanceCallback() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} diff --git a/x/liquidstakeibc/keeper/invariants.go b/x/liquidstakeibc/keeper/invariants.go index 854486db6..24522eb2c 100644 --- a/x/liquidstakeibc/keeper/invariants.go +++ b/x/liquidstakeibc/keeper/invariants.go @@ -28,7 +28,7 @@ func CValueLimits(k Keeper) sdk.Invariant { } return sdk.FormatInvariant( types.ModuleName, "cvalue-limits", - fmt.Sprintf("cvalue out of bounds as follows \n%s ", str), + fmt.Sprintf("cvalue out of bounds: %v, values as follows \n %s ", broken, str), ), broken } } diff --git a/x/liquidstakeibc/keeper/invariants_test.go b/x/liquidstakeibc/keeper/invariants_test.go new file mode 100644 index 000000000..6b7fc187a --- /dev/null +++ b/x/liquidstakeibc/keeper/invariants_test.go @@ -0,0 +1,22 @@ +package keeper_test + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/persistenceOne/pstake-native/v2/x/liquidstakeibc/keeper" +) + +func (suite *IntegrationTestSuite) TestCValueLimits() { + pstakeApp, ctx := suite.app, suite.ctx + k := pstakeApp.LiquidStakeIBCKeeper + hc, found := k.GetHostChain(ctx, suite.chainB.ChainID) + suite.Require().Equal(found, true) + str, broken := keeper.CValueLimits(k)(ctx) + suite.False(broken) + suite.Equal("liquidstakeibc: cvalue-limits invariant\ncvalue out of bounds: false, values as follows \n \n", str) + + hc.CValue = sdk.MustNewDecFromStr("2") + k.SetHostChain(ctx, hc) + str, broken = keeper.CValueLimits(k)(ctx) + suite.True(broken) + suite.Equal("liquidstakeibc: cvalue-limits invariant\ncvalue out of bounds: true, values as follows \n chainID: testchain2-1, cValue: 2.000000000000000000 \n \n", str) +} diff --git a/x/liquidstakeibc/keeper/setup_suite_test.go b/x/liquidstakeibc/keeper/setup_suite_test.go index 8557c02fd..a12fef8c7 100644 --- a/x/liquidstakeibc/keeper/setup_suite_test.go +++ b/x/liquidstakeibc/keeper/setup_suite_test.go @@ -185,11 +185,12 @@ func (suite *IntegrationTestSuite) SetupHostChainAB() { Owner: types.DefaultRewardsAccountPortOwner(suite.chainB.ChainID), ChannelState: types.ICAAccount_ICA_CHANNEL_CREATED, }, - Validators: validators, - MinimumDeposit: MinDeposit, - CValue: sdk.OneDec(), - UnbondingFactor: 4, - Active: true, + Validators: validators, + MinimumDeposit: MinDeposit, + CValue: sdk.OneDec(), + UnbondingFactor: 4, + AutoCompoundFactor: suite.app.LiquidStakeIBCKeeper.CalculateAutocompoundLimit(sdk.NewDec(20)), + Active: true, } suite.app.LiquidStakeIBCKeeper.SetHostChain(suite.chainA.GetContext(), hc) From ec274be869ee296991f45eb855fe4b16815181e1 Mon Sep 17 00:00:00 2001 From: Marc Puig Date: Fri, 14 Jul 2023 15:58:09 +0200 Subject: [PATCH 032/100] [LiquidStakeIbc] e2e test setup (#587) * e2e test setup * unify test workflow * update tag * fix --- .github/workflows/test.yml | 109 +- Makefile | 37 +- chains.yaml | 13 + docker/Makefile | 15 +- docker/pstake/Dockerfile | 6 +- interchaintest/chain_start_test.go | 27 + interchaintest/ci_integration.go | 23 + interchaintest/globals.go | 6 + interchaintest/go.mod | 264 ++++ interchaintest/go.sum | 2047 +++++++++++++++++++++++++++ interchaintest/ibc_transfer_test.go | 193 +++ interchaintest/setup.go | 138 ++ 12 files changed, 2852 insertions(+), 26 deletions(-) create mode 100644 chains.yaml create mode 100644 interchaintest/chain_start_test.go create mode 100644 interchaintest/ci_integration.go create mode 100644 interchaintest/globals.go create mode 100644 interchaintest/go.mod create mode 100644 interchaintest/go.sum create mode 100644 interchaintest/ibc_transfer_test.go create mode 100644 interchaintest/setup.go diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 1e1d546fe..341adbe29 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,15 +1,32 @@ name: Test on: - push: + pull_request: branches: - main - pull_request: + types: + - opened + - synchronize + - reopened + - ready_for_review + + push: branches: - main + release: + types: + - created + +env: + TAR_PATH: heighliner.tar + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: - module-test-coverage-upload: + unit-test-coverage: runs-on: ubuntu-latest steps: @@ -19,14 +36,14 @@ jobs: - uses: actions/checkout@v3 - - name: test & coverage report creation + - name: Unit Tests run: | make test env: TEST_TARGET: "./x/..." TEST_ARGS: "-timeout 10m -race -coverprofile=./coverage.out -covermode=atomic -v" - - name: filter out DONTCOVER + - name: Filter out DONTCOVER if: github.event_name == 'pull_request' run: | excludelist="$(find ./ -type f -name '*.go' | xargs grep -l 'DONTCOVER')" @@ -57,20 +74,82 @@ jobs: github-token: ${{ secrets.GITHUB_TOKEN }} lcov-file: coverage.lcov - e2e-test: + build-e2e-environment: runs-on: ubuntu-latest - steps: - - uses: actions/setup-go@v3 + - name: Get branch name + id: branch-name + uses: tj-actions/branch-names@v7 + + - name: Build Docker image + uses: strangelove-ventures/heighliner-build-action@v0.0.3 with: - go-version: 1.19 + registry: # empty registry, image only shared for e2e testing + tag: local # emulate local environment for consistency in interchaintest cases + tar-export-path: ${{ env.TAR_PATH }} # export a tarball that can be uploaded as an artifact for the e2e jobs + platform: linux/amd64 # test runner architecture only + git-ref: ${{ steps.branch-name.outputs.current_branch }} - - uses: actions/checkout@v3 + # Heighliner chains.yaml config + chain: pstake + dockerfile: cosmos + build-target: make install + binaries: | + - /go/bin/pstaked + build-env: | + - LEDGER_ENABLED=false + - BUILD_TAGS=muslc + + # Use github actions artifacts for temporary storage of the docker image tarball + - name: Publish Tarball as Artifact + uses: actions/upload-artifact@v3 + with: + name: pstake-docker-image + path: ${{ env.TAR_PATH }} - - name: test & coverage report creation + - name: Setup Go with cache + uses: magnetikonline/action-golang-cache@v4 + with: + go-version: 1.20.0 + id: go + + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Download dependencies for interchaintest run: | - make test - env: - TEST_TARGET: "./tests/..." - TEST_ARGS: "-timeout 12m -race -v" + cd interchaintest && go mod download + + + e2e-tests: + needs: build-e2e-environment + runs-on: ubuntu-latest + strategy: + matrix: + # names of `make` commands to run tests + test: + - "e2e-test-basic" + - "e2e-test-ibc-transfer" + fail-fast: false + + steps: + # Load the docker image tarball from github actions artifacts and run tests (one runner per test due to matrix) + - name: Download Tarball Artifact + uses: actions/download-artifact@v3 + with: + name: pstake-docker-image + + - name: Load Docker Image + run: docker image load -i ${{ env.TAR_PATH }} + + - name: Setup Go with cache + uses: magnetikonline/action-golang-cache@v4 + with: + go-version: 1.20.0 + id: go + + - name: Checkout repository + uses: actions/checkout@v3 + - name: run test + run: make ${{ matrix.test }} diff --git a/Makefile b/Makefile index 30f177812..0bb0a330e 100644 --- a/Makefile +++ b/Makefile @@ -200,12 +200,43 @@ test-race: test-cover: @go test -mod=readonly -timeout 30m -race -coverprofile=coverage.out -covermode=atomic -v -tags='ledger test_ledger_mock' $(TEST_TARGET) $(TEST_ARGS) -test-e2e: - $(MAKE) test-cover TEST_TARGET=./tests/e2e/... - benchmark: @go test -mod=readonly -bench=. $(TEST_TARGET) $(TEST_ARGS) +############################################################################### +### Docker Build (heighliner) ### +############################################################################### + +get-heighliner: + git clone https://github.com/strangelove-ventures/heighliner.git + cd heighliner && go install + +local-image: +ifeq (,$(shell which heighliner)) + echo 'heighliner' binary not found. Consider running `make get-heighliner` +else + heighliner build -c pstake --local -f ./chains.yaml +endif + +.PHONY: get-heighliner local-image + +############################################################################### +### e2e interchain test ### +############################################################################### + +# Executes basic chain tests via interchaintest +e2e-test-basic: rm-testcache + cd interchaintest && go test -race -v -run TestBasicPersistenceStart . + +# Executes IBC tests via interchaintest +e2e-test-ibc-transfer: rm-testcache + cd interchaintest && go test -race -v -run TestPersistenceGaiaIBCTransfer . + +rm-testcache: + go clean -testcache + +.PHONY: e2e-test-basic e2e-test-ibc-transfer + ############################################################################### ### Linting ### diff --git a/chains.yaml b/chains.yaml new file mode 100644 index 000000000..6d48ca465 --- /dev/null +++ b/chains.yaml @@ -0,0 +1,13 @@ +# This file is used to create docker images using the heighliner binary. +# see: https://github.com/strangelove-ventures/heighliner + +- name: pstake + github-organization: persistenceOne + github-repo: pstake-native + dockerfile: cosmos + build-target: make install + binaries: + - /go/bin/pstaked + build-env: + - LEDGER_ENABLED=false + - BUILD_TAGS=muslc diff --git a/docker/Makefile b/docker/Makefile index bee140b28..3a721a661 100644 --- a/docker/Makefile +++ b/docker/Makefile @@ -1,8 +1,10 @@ -PROCESS=pstake -IMAGE_NAME=persistenceone/$(PROCESS) -TAG_NAME=latest -CONTAINER_NAME=container-$(PROCESS) -FILE=Dockerfile +PROCESS = pstake +IMAGE_NAME = persistenceone/$(PROCESS) +TAG_NAME = latest +CONTAINER_NAME = container-$(PROCESS) +DOCKER_FILE = Dockerfile + +DOCKER := $(shell which docker) _DOCKER_ENV=\ -e CHAIN_ID=pstake \ @@ -17,12 +19,13 @@ _DOCKER_VOLUME=\ _DOCKER_ARGS=\ -p 26656:26656 \ -p 26657:26657 \ + -p 8080:8080 \ --network=host \ $(DOCKER_ARGS) # Command for dockerization docker-build: - docker buildx build . --platform=linux/amd64 -f docker/$(PROCESS)/$(FILE) -t $(IMAGE_NAME):$(TAG_NAME) + docker buildx build . --platform=linux/amd64 -f docker/$(PROCESS)/$(DOCKER_FILE) -t $(IMAGE_NAME):$(TAG_NAME) docker-run: docker run --rm -it --name=$(CONTAINER_NAME) \ diff --git a/docker/pstake/Dockerfile b/docker/pstake/Dockerfile index 298bffd92..3d5aca03e 100644 --- a/docker/pstake/Dockerfile +++ b/docker/pstake/Dockerfile @@ -7,7 +7,7 @@ RUN apk add --no-cache curl make git libc-dev bash gcc linux-headers eudev-dev p WORKDIR /go/src/github.com/persistenceOne/pstake-native # Add source files -COPY . . +COPY ../.. . # Install minimum necessary dependencies, build Cosmos SDK, remove packages RUN make install @@ -24,4 +24,6 @@ WORKDIR /root # Copy over binaries from the build-env COPY --from=build-env /go/bin/pstaked /usr/bin/pstaked -EXPOSE 26657 \ No newline at end of file +EXPOSE 1317 26656 26657 9090 + +CMD ["/usr/bin/pstaked", "version", "--long"] \ No newline at end of file diff --git a/interchaintest/chain_start_test.go b/interchaintest/chain_start_test.go new file mode 100644 index 000000000..48139469d --- /dev/null +++ b/interchaintest/chain_start_test.go @@ -0,0 +1,27 @@ +package interchaintest + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +// TestBasicPersistenceStart is a basic test to assert that spinning up a Persistence network with one validator works properly. +func TestBasicPersistenceStart(t *testing.T) { + if testing.Short() { + t.Skip() + } + + t.Parallel() + + // Base setup + chains := CreateThisBranchChain(t, 1, 0) + ic, ctx, _, _ := BuildInitialChain(t, chains) + + require.NotNil(t, ic) + require.NotNil(t, ctx) + + t.Cleanup(func() { + _ = ic.Close() + }) +} diff --git a/interchaintest/ci_integration.go b/interchaintest/ci_integration.go new file mode 100644 index 000000000..db9120bf7 --- /dev/null +++ b/interchaintest/ci_integration.go @@ -0,0 +1,23 @@ +package interchaintest + +import ( + "os" + "strings" +) + +// GetDockerImageInfo returns the appropriate repo and branch version string for integration with the CI pipeline. +// The remote runner sets the BRANCH_CI env var. If present, interchaintest will use the docker image pushed up to the repo. +// If testing locally, user should run `make local-image` and interchaintest will use the local image. +func GetDockerImageInfo() (repo, version string) { + branchVersion, found := os.LookupEnv("BRANCH_CI") + repo = PstakeE2ERepo + if !found { + // make local-image + repo = "pstake" + branchVersion = "local" + } + + // github converts / to - for pushed docker images + branchVersion = strings.ReplaceAll(branchVersion, "/", "-") + return repo, branchVersion +} diff --git a/interchaintest/globals.go b/interchaintest/globals.go new file mode 100644 index 000000000..f317f4828 --- /dev/null +++ b/interchaintest/globals.go @@ -0,0 +1,6 @@ +package interchaintest + +const ( + PersistenceBondDenom = "uxprt" + PersistenceCoinType = 118 +) diff --git a/interchaintest/go.mod b/interchaintest/go.mod new file mode 100644 index 000000000..bf8050e77 --- /dev/null +++ b/interchaintest/go.mod @@ -0,0 +1,264 @@ +module github.com/persistenceOne/pstake-native/v2/interchaintest + +go 1.20 + +require ( + github.com/CosmWasm/wasmd v0.40.2 + github.com/cosmos/cosmos-sdk v0.47.3 + github.com/cosmos/go-bip39 v1.0.0 + github.com/cosmos/ibc-go/v7 v7.2.0 + github.com/docker/docker v24.0.1+incompatible + github.com/pkg/errors v0.9.1 + github.com/strangelove-ventures/interchaintest/v7 v7.0.0-20230628163313-cedf87f4624d + github.com/stretchr/testify v1.8.4 + go.uber.org/zap v1.24.0 +) + +require ( + cloud.google.com/go v0.110.0 // indirect + cloud.google.com/go/compute v1.19.1 // indirect + cloud.google.com/go/compute/metadata v0.2.3 // indirect + cloud.google.com/go/iam v0.13.0 // indirect + cloud.google.com/go/storage v1.30.1 // 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/log v1.1.0 // indirect + cosmossdk.io/math v1.0.1 // 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.2 // indirect + github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect + github.com/BurntSushi/toml v1.3.2 // indirect + 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.4 // 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.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/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 + github.com/chzyer/readline v1.5.1 // indirect + github.com/coinbase/rosetta-sdk-go v0.7.9 // indirect + github.com/cometbft/cometbft v0.37.2 // indirect + github.com/cometbft/cometbft-db v0.8.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/gogogateway v1.2.0 // indirect + github.com/cosmos/gogoproto v1.4.10 // indirect + github.com/cosmos/iavl v0.20.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 + 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.4 // indirect + github.com/decred/dcrd/crypto/blake256 v1.0.0 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v2 v2.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/ristretto v0.1.1 // indirect + github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // 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 + github.com/dvsekhvalnov/jose2go v1.5.0 // 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/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.6.0 // indirect + github.com/go-playground/validator/v10 v10.11.1 // 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 + github.com/gogo/protobuf v1.3.3 // indirect + github.com/golang/glog v1.1.0 // indirect + 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/google/btree v1.1.2 // indirect + github.com/google/go-cmp v0.5.9 // indirect + github.com/google/orderedcode v0.0.1 // indirect + github.com/google/s2a-go v0.1.3 // 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.8.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 + 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-cleanhttp v0.5.2 // 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-uuid v1.0.2 // 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.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/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/lib/pq v1.10.9 // 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/linxGnu/grocksdb v1.7.16 // indirect + github.com/magiconair/properties v1.8.7 // indirect + github.com/manifoldco/promptui v0.9.0 // indirect + github.com/mattn/go-colorable v0.1.13 // 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 + 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/mr-tron/base58 v1.2.0 // indirect + github.com/mtibben/percent v0.2.1 // 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.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/onsi/gomega v1.27.6 // indirect + github.com/opencontainers/go-digest v1.0.0 // indirect + github.com/opencontainers/image-spec v1.1.0-rc2 // indirect + github.com/opencontainers/runc v1.1.5 // indirect + github.com/pelletier/go-toml v1.9.5 // indirect + github.com/pelletier/go-toml/v2 v2.0.8 // indirect + github.com/petermattis/goid v0.0.0-20230317030725-371a4b8eda08 // indirect + github.com/pierrec/xxHash v0.1.5 // 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/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect + github.com/rogpeppe/go-internal v1.10.0 // indirect + github.com/rs/cors v1.8.3 // indirect + github.com/rs/zerolog v1.29.1 // indirect + github.com/sasha-s/go-deadlock v0.3.1 // indirect + github.com/sirupsen/logrus v1.9.3 // 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.5 // indirect + github.com/spf13/cast v1.5.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.16.0 // indirect + github.com/subosito/gotenv v1.4.2 // indirect + 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/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.7 // indirect + go.opencensus.io v0.24.0 // indirect + go.uber.org/atomic v1.10.0 // indirect + go.uber.org/multierr v1.11.0 // indirect + golang.org/x/crypto v0.10.0 // indirect + golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc // indirect + golang.org/x/mod v0.11.0 // indirect + golang.org/x/net v0.11.0 // indirect + golang.org/x/oauth2 v0.7.0 // indirect + golang.org/x/sync v0.3.0 // indirect + golang.org/x/sys v0.9.0 // indirect + golang.org/x/term v0.9.0 // indirect + golang.org/x/text v0.10.0 // indirect + golang.org/x/tools v0.10.0 // indirect + golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect + google.golang.org/api v0.122.0 // indirect + google.golang.org/appengine v1.6.7 // indirect + google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect + google.golang.org/grpc v1.56.1 // 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.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.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.23.1 // 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 ( + // use cosmos fork of keyring + github.com/99designs/keyring => github.com/cosmos/keyring v1.2.0 + // For interchaintest + 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 + // 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.7.7 + // Too early to get rid of this override + github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 + // Downgraded to avoid bugs in following commits which caused simulations to fail. + github.com/syndtr/goleveldb => github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 +) + +// use persistence's forks with LSM implemented +replace ( + github.com/CosmWasm/wasmd => github.com/persistenceOne/wasmd v0.40.1-lsm + github.com/cosmos/cosmos-sdk => github.com/persistenceOne/cosmos-sdk v0.47.3-lsm2 + github.com/cosmos/ibc-apps/middleware/packet-forward-middleware/v7 => github.com/persistenceOne/ibc-apps/middleware/packet-forward-middleware/v7 v7.0.0-20230712081317-ebc0729e000d + github.com/cosmos/ibc-apps/modules/ibc-hooks/v7 => github.com/persistenceOne/ibc-apps/modules/ibc-hooks/v7 v7.0.0-20230712081317-ebc0729e000d + github.com/cosmos/ibc-go/v7 => github.com/persistenceOne/ibc-go/v7 v7.2.0-lsm + github.com/skip-mev/pob => github.com/persistenceOne/pob v1.0.3-lsm +) diff --git a/interchaintest/go.sum b/interchaintest/go.sum new file mode 100644 index 000000000..b40057b44 --- /dev/null +++ b/interchaintest/go.sum @@ -0,0 +1,2047 @@ +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 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.19.1 h1:am86mquDUgjGNWxiGn+5PGLbmgiWXlE/yNWpIpNvuXY= +cloud.google.com/go/compute v1.19.1/go.mod h1:6ylj3a05WF8leseCdIf77NK0g1ey+nj5IKd5/kvShxE= +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.13.0 h1:+CmB+K0J/33d0zSQ9SlFWUeCCEn5XJA0ZMZ3pHE9u8k= +cloud.google.com/go/iam v0.13.0/go.mod h1:ljOg+rcNfzZ5d6f1nAUJ8ZIxOaZUVoS14bKCtaLZ/D0= +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.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= +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.30.1 h1:uOdMxAs8HExqBlnLtnQyP0YkvbiDpdGShGKtx6U/oNM= +cloud.google.com/go/storage v1.30.1/go.mod h1:NfxhC0UJE1aXSx7CIIbCf7y9HKT7BiccwkR7+P7gN8E= +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.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/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.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= +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/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-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= +github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= +github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +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/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/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/wasmvm v1.2.4 h1:6OfeZuEcEH/9iqwrg2pkeVtDCkMoj9U6PpKtcrCyVrQ= +github.com/CosmWasm/wasmvm v1.2.4/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.5.0/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= +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/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= +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/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/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/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/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.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/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= +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/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/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/checkpoint-restore/go-criu/v5 v5.3.0/go.mod h1:E/eQpaFtUKGOOSEBZgmKAcn+zUUwWxqcaKZlF54wK8E= +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/cilium/ebpf v0.7.0/go.mod h1:/oI2+1shJiTGAMgl6/RgJr36Eo1jzrRcAWbcXO2usCA= +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/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/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.2 h1:XB0yyHGT0lwmJlFmM4+rsRnczPlHoAKFX6K8Zgc2/Jc= +github.com/cometbft/cometbft v0.37.2/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= +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/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U= +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.2/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= +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/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.10 h1:QH/yT8X+c0F4ZDacDv3z+xE3WU1P1Z3wQoLMBRJoKuI= +github.com/cosmos/gogoproto v1.4.10/go.mod h1:3aAZzeRWpAwr+SS/LLkICX2/kDFyaYVzckBDzygIxek= +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/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= +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/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= +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 h1:sk9/l/KqpunDwP7pSjUg0keiOOLEnOBHzykLrsPppp4= +github.com/deckarep/golang-set v1.8.0/go.mod h1:5nI87KwE7wgsBU1F4GKAw2Qod7p5kyS383rP6+o6qqo= +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.1 h1:18HurQ6DfHeNvwIjvOmrgr44bPdtVaQAe/WWwHg9goM= +github.com/decred/dcrd/dcrec/secp256k1/v2 v2.0.1/go.mod h1:XmyzkaXBy7ZvHdrTAlXAjpog8qKSAWa3ze7yqzWmgmc= +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/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.0.3/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-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.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/docker v24.0.1+incompatible h1:NxN81beIxDlUaVt46iUQrYHD9/W3u9EGl52r86O/IGw= +github.com/docker/docker v24.0.1+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.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +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 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/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/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/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.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= +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.7.7 h1:3DoBmSbJbZAWqXJC3SLjAPfutPJJRN1U5pALB7EeTTs= +github.com/gin-gonic/gin v1.7.7/go.mod h1:axIBovoeJpVj8S3BwE0uPMTeReE4+AfFtqpqaZ1qq1U= +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.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.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= +github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= +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/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.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= +github.com/go-playground/validator/v10 v10.11.1 h1:prmOlTVv+YjZjmRmNSF3VmspqJIxJWXmqUsHwfTRRkQ= +github.com/go-playground/validator/v10 v10.11.1/go.mod h1:i+3WkQ1FvaUjjxh1kSvIA4dMGDBiPU55YFDl0WbKdWU= +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-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw= +github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4= +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/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/godbus/dbus/v5 v5.0.6/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 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-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.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= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= +github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +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.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/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.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= +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-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbuBVKCudVG457BR2GZFIz3uw3hQ= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/s2a-go v0.1.3 h1:FAgZmpLl/SXurPEZyCMPBIiiYeTbqfjlbdnCNTAkbGE= +github.com/google/s2a-go v0.1.3/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A= +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.8.0 h1:UBtEZqx1bjXtOQ5BVTkuYghXrr3N4V123VKJK67vJZc= +github.com/googleapis/gax-go/v2 v2.8.0/go.mod h1:4orTrqY6hXxxaUL4LHIPl6lGo8vAE38/qKbhSAKP6QI= +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.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.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-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-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-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/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.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/ipfs/go-cid v0.2.0 h1:01JTiihFq9en9Vz0lc0VDWvZe/uBonGpzo4THP0vcQ0= +github.com/ipfs/go-cid v0.2.0/go.mod h1:P+HXFDF4CVhaVayiEb4wkAy7zBHxBwsJyt0Y5U6MLro= +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.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= +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/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/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/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/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/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +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/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/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/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.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= +github.com/lib/pq v1.10.9/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 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/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= +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.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.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= +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-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y= +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/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-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/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.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/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU= +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/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.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= +github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= +github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ= +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.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.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/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/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.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +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.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE= +github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg= +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.5 h1:L44KXEpKmfWDcS02aeGm8QNTFXTo2D+8MYGDIJ/GDEs= +github.com/opencontainers/runc v1.1.5/go.mod h1:1J5XiS+vdZ3wCyZybsuxXZWGrgSr8fFJHLXuG2PsnNg= +github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opencontainers/selinux v1.10.0/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI= +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/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 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.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ= +github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4= +github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= +github.com/persistenceOne/cosmos-sdk v0.47.3-lsm2 h1:yLiCBSbY2MNREWTzhjgcxFLWwGNaqdQ1t0uI2Ruqxp0= +github.com/persistenceOne/cosmos-sdk v0.47.3-lsm2/go.mod h1:4oxikyyHyEe1wlYQFMGITfW/r01wYtfj8yjwru7bSWE= +github.com/persistenceOne/ibc-go/v7 v7.2.0-lsm h1:sss2le1eYjdcU00RvTbJDrQzUQ9/f00+E1/rDJVt8qU= +github.com/persistenceOne/ibc-go/v7 v7.2.0-lsm/go.mod h1:ddpiZBVQpzoeElQBTv/47/1E4VfxTV5vcyECVQ7r56I= +github.com/persistenceOne/wasmd v0.40.1-lsm h1:YWZcRGVC9xc5VDrGrIXp2xWXd0zQD4tW1MHtuo1TABM= +github.com/persistenceOne/wasmd v0.40.1-lsm/go.mod h1:uSKNAbF1A1GffCuR9tmR8uDXqMC5OkH7CBs3byHO8+Y= +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-20230317030725-371a4b8eda08 h1:hDSdbBuw3Lefr6R18ax0tZ2BJeNB3NehB3trOwYBsdU= +github.com/petermattis/goid v0.0.0-20230317030725-371a4b8eda08/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= +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/pierrec/xxHash v0.1.5 h1:n/jBpwTHiER4xYvK3/CdPVnLDPchj8eTJFFLUb4QHBo= +github.com/pierrec/xxHash v0.1.5/go.mod h1:w2waW5Zoa/Wc4Yqe0wgrIYAGKqRMf7czn2HNKXmuL+I= +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.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= +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/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 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/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/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= +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/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.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= +github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= +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.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= +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/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg= +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 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.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/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= +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.5 h1:stMpOSZFs//0Lv29HduCmli3GUfpFoF3Y1Q/aXj/wVM= +github.com/spf13/afero v1.9.5/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= +github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +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= +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.16.0 h1:rGGH0XDZhdUOryiDWjmIvUSWpbNqisK8Wk0Vyefw8hc= +github.com/spf13/viper v1.16.0/go.mod h1:yg78JgCJcbrQOvV9YLXgkLaZqUidkY9K+Dd1FofRzQg= +github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4/go.mod h1:RZLeN1LMWmRsyYjvAu+I6Dm9QmlDaIIt+Y+4Kd7Tp+Q= +github.com/strangelove-ventures/interchaintest/v7 v7.0.0-20230628163313-cedf87f4624d h1:kCxlPmg8gPzIe6aaC7CbvBRDc7g+sNl+E3kvSplP+nE= +github.com/strangelove-ventures/interchaintest/v7 v7.0.0-20230628163313-cedf87f4624d/go.mod h1:Qjx/I21ELV/zHVxSMAkiWtEFQyjPc/hgbKL6lRRWgco= +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.1.5-0.20170601210322-f6abca593680/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +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/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/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/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= +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/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= +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/tklauser/go-sysconf v0.3.5/go.mod h1:MkWzOF4RMCshBAMXuhXJs64Rte09mITnppBXY/rYEFI= +github.com/tklauser/go-sysconf v0.3.10 h1:IJ1AZGZRWbY8T5Vfk04D9WOA5WSejdflXxP03OUqALw= +github.com/tklauser/numcpus v0.2.2/go.mod h1:x3qojaO3uyYt0i56EW/VUYs7uBvdl2fkfZFu0T9wgjM= +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-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.0.1-0.20181017060643-dbb3b84ba2ef/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs= +github.com/tyler-smith/go-bip39 v1.0.2/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs= +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/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/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/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/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= +github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= +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/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= +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.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.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +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= +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-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-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM= +golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I= +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-20230515195305-f3d0a9c9a5cc h1:mCRnTeVUjcrhlRmO0VK8a6k6Rrf6TF9htwo2pJVSjIU= +golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w= +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/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.11.0 h1:bUO06HqtnRcc/7l71XBe4WcqTZ+3AH1J59zWDDwLKgU= +golang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +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-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-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-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.0.0-20211112202133-69e39bad7dc2/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.11.0 h1:Gi2tvZIJyBtO9SDr1q9h5hEQCp/4L2RQ+ar0qjx2oNU= +golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ= +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-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.7.0 h1:qe6s0zUXlPX80/dITx3440hWZ7GwMwgDDyrSGTPJG/g= +golang.org/x/oauth2 v0.7.0/go.mod h1:hPLQkd9LyjfXTiRohC/41GhcFqxisoUQ99sCUOHO9x4= +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.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.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= +golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +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-20190606203320-7fc4e5ec1444/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-20191115151921-52ab43148777/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-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210316164454-77fc1eacc6aa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210420205809-ac73e9fd8988/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210819135213-f52c844e1c1c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/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-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.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.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s= +golang.org/x/sys v0.9.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.9.0 h1:GRRCnKYhdQrD8kfRAdQ6Zcw1P0OcELxGLKJvtjVMZ28= +golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo= +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.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58= +golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +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= +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-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-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.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.10.0 h1:tvDr/iQoUqNdohiYm0LmmKcBk+q86lb9EprIUFhHHGg= +golang.org/x/tools v0.10.0/go.mod h1:UJwyiVBsOA2uwvK/e5OY3GTpDUJriEd+/YlqAwLPmyM= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= +gonum.org/v1/gonum v0.0.0-20181121035319-3f7ecaa7e8ca/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= +gonum.org/v1/gonum v0.6.0/go.mod h1:9mxDZsDKxgMAuccQkewq682L+0eCu4dCN2yonUJTCLU= +gonum.org/v1/netlib v0.0.0-20181029234149-ec6d1f5cefe6/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= +gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= +gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc= +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/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.122.0 h1:zDobeejm3E7pEG1mNHvdxvjs5XJoCMzyNH+CmwL94Es= +google.golang.org/api v0.122.0/go.mod h1:gcitW0lvnyWjSp9nKxAbdHKIZ6vF4aajGueeslZOyms= +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= +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-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-20230410155749-daa745c078e1 h1:KpwkzHKEF7B9Zxg18WzOa7djJ+Ha5DzthMyZYQfEn2A= +google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU= +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= +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.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.56.1 h1:z0dNfjIl0VpaZ9iSVjA6daGatAYwPGstTjt5vkRMFkQ= +google.golang.org/grpc v1.56.1/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s= +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= +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.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= +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 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= +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= +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/httpfs v1.0.6 h1:AAgIpFZRXuYnkjftxTAZwMIiwEqAfk8aVB2/oA6nAeM= +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= +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.23.1 h1:nrSBg4aRQQwq59JpvGEQ15tNxoO5pX/kUjcRNwSAGQM= +modernc.org/sqlite v1.23.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.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.3 h1:zDJf6iHjrnB+WRD88stbXokugjyc0/pB91ri1gO6LZY= +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= +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= diff --git a/interchaintest/ibc_transfer_test.go b/interchaintest/ibc_transfer_test.go new file mode 100644 index 000000000..faffa4fc8 --- /dev/null +++ b/interchaintest/ibc_transfer_test.go @@ -0,0 +1,193 @@ +package interchaintest + +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/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" + "go.uber.org/zap/zaptest" +) + +// TestPersistenceGaiaIBCTransfer spins up a Persistence and Gaia network, initializes an IBC connection between them, +// and sends an ICS20 token transfer from Persistence->Gaia and then back from Gaia->Persistence. +func TestPersistenceGaiaIBCTransfer(t *testing.T) { + if testing.Short() { + t.Skip() + } + + t.Parallel() + + // Create chain factory with Persistence and Gaia + numVals := 1 + numFullNodes := 1 + + cf := interchaintest.NewBuiltinChainFactory(zaptest.NewLogger(t), []*interchaintest.ChainSpec{ + { + Name: "pstake", + ChainConfig: pstakeConfig, + NumValidators: &numVals, + NumFullNodes: &numFullNodes, + }, + { + Name: "gaia", + Version: "v9.1.0", + NumValidators: &numVals, + NumFullNodes: &numFullNodes, + }, + }) + + const ( + path = "ibc-path" + ) + + // Get chains from the chain factory + chains, err := cf.Chains(t.Name()) + require.NoError(t, err) + + client, network := interchaintest.DockerSetup(t) + + persistenceChain, gaiaChain := chains[0].(*cosmos.CosmosChain), chains[1].(*cosmos.CosmosChain) + + relayerType, relayerName := ibc.CosmosRly, "relay" + + // Get a relayer instance + rf := interchaintest.NewBuiltinRelayerFactory( + relayerType, + zaptest.NewLogger(t), + interchaintestrelayer.CustomDockerImage(IBCRelayerImage, IBCRelayerVersion, "100:1000"), + interchaintestrelayer.StartupFlags("--processor", "events", "--block-history", "100"), + ) + + r := rf.Build(t, client, network) + + ic := interchaintest.NewInterchain(). + AddChain(persistenceChain). + AddChain(gaiaChain). + AddRelayer(r, relayerName). + AddLink(interchaintest.InterchainLink{ + Chain1: persistenceChain, + Chain2: gaiaChain, + Relayer: r, + Path: path, + }) + + ctx := context.Background() + + rep := testreporter.NewNopReporter() + eRep := rep.RelayerExecReporter(t) + + require.NoError(t, ic.Build(ctx, eRep, interchaintest.InterchainBuildOptions{ + TestName: t.Name(), + Client: client, + NetworkID: network, + BlockDatabaseFile: interchaintest.DefaultBlockDatabaseFilepath(), + SkipPathCreation: false, + })) + t.Cleanup(func() { + _ = ic.Close() + }) + + // Create some user accounts on both chains + users := interchaintest.GetAndFundTestUsers(t, ctx, t.Name(), genesisWalletAmount, persistenceChain, gaiaChain) + + // Wait a few blocks for relayer to start and for user accounts to be created + err = testutil.WaitForBlocks(ctx, 5, persistenceChain, gaiaChain) + require.NoError(t, err) + + // Get our Bech32 encoded user addresses + persistenceUser, gaiaUser := users[0], users[1] + + persistenceUserAddr := persistenceUser.FormattedAddress() + gaiaUserAddr := gaiaUser.FormattedAddress() + + // Get original account balances + persistenceOrigBal, err := persistenceChain.GetBalance(ctx, persistenceUserAddr, persistenceChain.Config().Denom) + require.NoError(t, err) + require.Equal(t, genesisWalletAmount, persistenceOrigBal) + + gaiaOrigBal, err := gaiaChain.GetBalance(ctx, gaiaUserAddr, gaiaChain.Config().Denom) + require.NoError(t, err) + require.Equal(t, genesisWalletAmount, gaiaOrigBal) + + // Compose an IBC transfer and send from Persistence -> Gaia + const transferAmount = int64(1_000) + transfer := ibc.WalletAmount{ + Address: gaiaUserAddr, + Denom: persistenceChain.Config().Denom, + Amount: transferAmount, + } + + channel, err := ibc.GetTransferChannel(ctx, r, eRep, persistenceChain.Config().ChainID, gaiaChain.Config().ChainID) + require.NoError(t, err) + + persistenceHeight, err := persistenceChain.Height(ctx) + require.NoError(t, err) + + transferTx, err := persistenceChain.SendIBCTransfer(ctx, channel.ChannelID, persistenceUserAddr, transfer, ibc.TransferOptions{}) + require.NoError(t, err) + + err = r.StartRelayer(ctx, eRep, path) + require.NoError(t, err) + + t.Cleanup( + func() { + err := r.StopRelayer(ctx, eRep) + if err != nil { + t.Logf("an error occured while stopping the relayer: %s", err) + } + }, + ) + + // Poll for the ack to know the transfer was successful + _, err = testutil.PollForAck(ctx, persistenceChain, persistenceHeight, persistenceHeight+50, transferTx.Packet) + require.NoError(t, err) + + err = testutil.WaitForBlocks(ctx, 10, persistenceChain) + require.NoError(t, err) + + // Get the IBC denom for uxprt on Gaia + persistenceTokenDenom := transfertypes.GetPrefixedDenom(channel.Counterparty.PortID, channel.Counterparty.ChannelID, persistenceChain.Config().Denom) + persistenceIBCDenom := transfertypes.ParseDenomTrace(persistenceTokenDenom).IBCDenom() + + // Assert that the funds are no longer present in user acc on Persistence and are in the user acc on Gaia + persistenceUpdateBal, err := persistenceChain.GetBalance(ctx, persistenceUserAddr, persistenceChain.Config().Denom) + require.NoError(t, err) + require.Equal(t, persistenceOrigBal-transferAmount, persistenceUpdateBal) + + gaiaUpdateBal, err := gaiaChain.GetBalance(ctx, gaiaUserAddr, persistenceIBCDenom) + require.NoError(t, err) + require.Equal(t, transferAmount, gaiaUpdateBal) + + // Compose an IBC transfer and send from Gaia -> Persistence + transfer = ibc.WalletAmount{ + Address: persistenceUserAddr, + Denom: persistenceIBCDenom, + Amount: transferAmount, + } + + gaiaHeight, err := gaiaChain.Height(ctx) + require.NoError(t, err) + + transferTx, err = gaiaChain.SendIBCTransfer(ctx, channel.Counterparty.ChannelID, gaiaUserAddr, transfer, ibc.TransferOptions{}) + require.NoError(t, err) + + // Poll for the ack to know the transfer was successful + _, err = testutil.PollForAck(ctx, gaiaChain, gaiaHeight, gaiaHeight+25, transferTx.Packet) + require.NoError(t, err) + + // Assert that the funds are now back on Persistence and not on Gaia + persistenceUpdateBal, err = persistenceChain.GetBalance(ctx, persistenceUserAddr, persistenceChain.Config().Denom) + require.NoError(t, err) + require.Equal(t, persistenceOrigBal, persistenceUpdateBal) + + gaiaUpdateBal, err = gaiaChain.GetBalance(ctx, gaiaUserAddr, persistenceIBCDenom) + require.NoError(t, err) + require.Equal(t, int64(0), gaiaUpdateBal) +} diff --git a/interchaintest/setup.go b/interchaintest/setup.go new file mode 100644 index 000000000..f077959a1 --- /dev/null +++ b/interchaintest/setup.go @@ -0,0 +1,138 @@ +package interchaintest + +import ( + "context" + "fmt" + "testing" + + "github.com/docker/docker/client" + "github.com/stretchr/testify/require" + "go.uber.org/zap/zaptest" + + wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" + testutil "github.com/cosmos/cosmos-sdk/types/module/testutil" + ibclocalhost "github.com/cosmos/ibc-go/v7/modules/light-clients/09-localhost" + 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" +) + +var ( + VotingPeriod = "15s" + MaxDepositPeriod = "10s" + + PstakeE2ERepo = "persistenceone/pstake-native" + + IBCRelayerImage = "ghcr.io/cosmos/relayer" + IBCRelayerVersion = "main" + + appRepo, appVersion = GetDockerImageInfo() + + PersistenceCoreImage = ibc.DockerImage{ + Repository: appRepo, + Version: appVersion, + UidGid: "1025:1025", + } + + defaultGenesisOverridesKV = append([]cosmos.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: PersistenceBondDenom, + }, + }) + + pstakeConfig = ibc.ChainConfig{ + Type: "cosmos", + Name: "pstake", + ChainID: "e2e-test-core-1", + Images: []ibc.DockerImage{ + PersistenceCoreImage, + }, + Bin: "pstaked", + Bech32Prefix: "persistence", + Denom: PersistenceBondDenom, + CoinType: fmt.Sprintf("%d", PersistenceCoinType), + GasPrices: fmt.Sprintf("0%s", PersistenceBondDenom), + GasAdjustment: 1.5, + TrustingPeriod: "112h", + NoHostMount: false, + ConfigFileOverrides: nil, + EncodingConfig: persistenceEncoding(), + UsingNewGenesisCommand: false, + ModifyGenesis: cosmos.ModifyGenesis(defaultGenesisOverridesKV), + } + + genesisWalletAmount = int64(10_000_000) +) + +// persistenceEncoding registers the persistenceCore specific module codecs so that the associated types and msgs +// will be supported when writing to the blocksdb sqlite database. +func persistenceEncoding() *testutil.TestEncodingConfig { + cfg := cosmos.DefaultEncoding() + + // register custom types + ibclocalhost.RegisterInterfaces(cfg.InterfaceRegistry) + wasmtypes.RegisterInterfaces(cfg.InterfaceRegistry) + + return &cfg +} + +// Base chain, no relaying off this branch (or persistence:local if no branch is provided.) +func CreateThisBranchChain(t *testing.T, numVals, numFull int) []ibc.Chain { + // Create chain factory with persistence on this current branch + + cf := interchaintest.NewBuiltinChainFactory(zaptest.NewLogger(t), []*interchaintest.ChainSpec{ + { + Name: "pstake", + ChainName: "pstake", + Version: appVersion, + ChainConfig: pstakeConfig, + NumValidators: &numVals, + NumFullNodes: &numFull, + }, + }) + + // Get chains from the chain factory + chains, err := cf.Chains(t.Name()) + require.NoError(t, err) + + // chain := 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 = 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 +} From 87ab1c70ab2b190b4ad81bac012f06bb47a8c567 Mon Sep 17 00:00:00 2001 From: Marc Puig Date: Fri, 14 Jul 2023 16:04:12 +0200 Subject: [PATCH 033/100] [LiquidStakeIbc] Cleanup (#588) * cleanup * cleanup part two --- .build.sh | 44 - .gitattributes | 0 .github/CODEOWNERS | 1 + .github/stale.yml | 45 - .mergify.yml | 18 - Dockerfile | 27 - config.yml | 9 - contrib/Dockerfile.test | 35 - contrib/devtools/Makefile | 114 -- contrib/get_node.sh | 14 - contrib/localnet-blocks-test.sh | 57 - contrib/single-node.sh | 34 - contrib/statesync.bash | 40 - contrib/testnets/Makefile | 143 -- contrib/testnets/README.md | 6 - contrib/testnets/add-cluster.sh | 25 - contrib/testnets/add-datadog.sh | 14 - contrib/testnets/del-cluster.sh | 14 - contrib/testnets/del-datadog.sh | 13 - contrib/testnets/list.sh | 13 - contrib/testnets/local/Makefile | 7 - contrib/testnets/local/gaiadnode/Dockerfile | 24 - contrib/testnets/local/gaiadnode/wrapper.sh | 33 - contrib/testnets/new-testnet.sh | 30 - contrib/testnets/remote/ansible/.gitignore | 3 - contrib/testnets/remote/ansible/add-lcd.yml | 8 - .../testnets/remote/ansible/clear-config.yml | 8 - .../remote/ansible/extract-config.yml | 8 - .../remote/ansible/increase-openfiles.yml | 8 - .../remote/ansible/install-datadog-agent.yml | 12 - .../testnets/remote/ansible/inventory/COPYING | 675 ------- .../ansible/inventory/digital_ocean.ini | 34 - .../remote/ansible/inventory/digital_ocean.py | 471 ----- .../testnets/remote/ansible/inventory/ec2.ini | 209 --- .../testnets/remote/ansible/inventory/ec2.py | 1595 ----------------- contrib/testnets/remote/ansible/logzio.yml | 13 - .../remote/ansible/remove-datadog-agent.yml | 8 - .../ansible/roles/add-lcd/defaults/main.yml | 4 - .../ansible/roles/add-lcd/handlers/main.yml | 9 - .../ansible/roles/add-lcd/tasks/main.yml | 15 - .../add-lcd/templates/gaiacli.service.j2 | 17 - .../ansible/roles/clear-config/tasks/main.yml | 9 - .../roles/extract-config/defaults/main.yml | 4 - .../roles/extract-config/tasks/main.yml | 14 - .../roles/increase-openfiles/files/50-fs.conf | 1 - .../increase-openfiles/files/91-nofiles.conf | 3 - .../increase-openfiles/files/limits.conf | 3 - .../increase-openfiles/handlers/main.yml | 5 - .../roles/increase-openfiles/tasks/main.yml | 22 - .../install-datadog-agent/handlers/main.yml | 10 - .../install-datadog-agent/tasks/main.yml | 15 - .../roles/logzio/files/journalbeat.service | 15 - .../ansible/roles/logzio/handlers/main.yml | 8 - .../ansible/roles/logzio/tasks/main.yml | 27 - .../roles/logzio/templates/journalbeat.yml.j2 | 342 ---- .../roles/remove-datadog-agent/tasks/main.yml | 12 - .../roles/set-debug/files/sysconfig/gaiacli | 1 - .../roles/set-debug/files/sysconfig/gaiad | 1 - .../set-debug/files/sysctl.d/10-procdump | 3 - .../ansible/roles/set-debug/handlers/main.yml | 4 - .../ansible/roles/set-debug/tasks/main.yml | 9 - .../roles/setup-fullnodes/defaults/main.yml | 4 - .../roles/setup-fullnodes/files/gaiad.service | 17 - .../roles/setup-fullnodes/handlers/main.yml | 5 - .../roles/setup-fullnodes/tasks/main.yml | 61 - .../roles/setup-journald/handlers/main.yml | 5 - .../roles/setup-journald/tasks/main.yml | 26 - .../roles/setup-validators/defaults/main.yml | 4 - .../setup-validators/files/gaiad.service | 17 - .../roles/setup-validators/handlers/main.yml | 5 - .../roles/setup-validators/tasks/main.yml | 78 - .../remote/ansible/roles/start/tasks/main.yml | 5 - .../remote/ansible/roles/stop/tasks/main.yml | 5 - .../files/conf.d/http_check.d/conf.yml | 13 - .../files/conf.d/network.d/conf.yml | 9 - .../files/conf.d/process.d/conf.yml | 15 - .../files/conf.d/prometheus.d/conf.yml | 10 - .../update-datadog-agent/handlers/main.yml | 5 - .../roles/update-datadog-agent/tasks/main.yml | 10 - .../templates/datadog.yaml.j2 | 561 ------ .../roles/upgrade-gaiad/handlers/main.yml | 5 - .../roles/upgrade-gaiad/tasks/main.yml | 29 - contrib/testnets/remote/ansible/set-debug.yml | 8 - .../remote/ansible/setup-fullnodes.yml | 13 - .../remote/ansible/setup-journald.yml | 10 - .../remote/ansible/setup-validators.yml | 9 - contrib/testnets/remote/ansible/start.yml | 10 - contrib/testnets/remote/ansible/status.yml | 17 - contrib/testnets/remote/ansible/stop.yml | 10 - .../remote/ansible/update-datadog-agent.yml | 10 - .../testnets/remote/ansible/upgrade-gaia.yml | 9 - .../testnets/remote/ansible/upgrade-gaiad.yml | 11 - .../testnets/remote/terraform-app/.gitignore | 5 - .../remote/terraform-app/files/terraform.sh | 8 - .../remote/terraform-app/infra/attachment.tf | 21 - .../remote/terraform-app/infra/instance.tf | 58 - .../testnets/remote/terraform-app/infra/lb.tf | 52 - .../remote/terraform-app/infra/lcd.tf | 39 - .../remote/terraform-app/infra/outputs.tf | 24 - .../remote/terraform-app/infra/variables.tf | 39 - .../remote/terraform-app/infra/vpc.tf | 104 -- contrib/testnets/remote/terraform-app/main.tf | 73 - .../testnets/remote/terraform-aws/.gitignore | 5 - .../remote/terraform-aws/files/terraform.sh | 11 - contrib/testnets/remote/terraform-aws/main.tf | 249 --- .../remote/terraform-aws/nodes/main.tf | 104 -- .../remote/terraform-aws/nodes/outputs.tf | 15 - .../remote/terraform-aws/nodes/variables.tf | 42 - .../testnets/remote/terraform-do/.gitignore | 6 - contrib/testnets/remote/terraform-do/Makefile | 100 -- .../testnets/remote/terraform-do/README.md | 58 - .../remote/terraform-do/cluster/main.tf | 40 - .../remote/terraform-do/cluster/outputs.tf | 15 - .../remote/terraform-do/cluster/variables.tf | 30 - .../remote/terraform-do/files/terraform.sh | 8 - contrib/testnets/remote/terraform-do/main.tf | 43 - contrib/testnets/test_platform/README.md | 45 - .../test_platform/gaiad_config_manager.py | 233 --- .../templates/3924406.cosmoshub-3.json.tar.gz | Bin 9988219 -> 0 bytes .../testnets/test_platform/templates/app.toml | 177 -- .../test_platform/templates/config.toml | 393 ---- .../templates/replacement_defaults.txt | 31 - .../validator_replacement_example.json | 394 ---- contrib/testnets/upgrade-gaiad.sh | 14 - contrib/testnets/using-cleveldb.sh | 19 - docker-compose.yml | 68 - docker/explorer/Dockerfile | 12 - docker/exposer/Dockerfile | 28 - docker/exposer/Dockerfile.gaia | 28 - docker/exposer/node.go | 74 - docker/gaia/Dockerfile | 26 - docker/icq-relayer/Dockerfile | 23 - docker/pstake-e2e/Dockerfile | 19 - k8s/Makefile | 15 - k8s/README.md | 107 -- k8s/explorer/configmap.yml | 4 - k8s/explorer/configs/gaia.json | 19 - k8s/explorer/configs/pstake.json | 19 - k8s/explorer/explorer.yml | 62 - k8s/explorer/ingress.yml | 23 - k8s/explorer/kustomization.yml | 15 - k8s/faucet/configs/.cosmos.env | 13 - k8s/faucet/configs/.persistence.env | 13 - k8s/faucet/faucet.yml | 74 - k8s/faucet/ingress.yml | 47 - k8s/faucet/kustomization.yml | 16 - k8s/gaia/configmap.yml | 6 - k8s/gaia/configs/keys.json | 54 - k8s/gaia/configs/validators.json | 46 - k8s/gaia/genesis.yml | 214 --- k8s/gaia/ingress.yml | 78 - k8s/gaia/kustomization.yml | 17 - k8s/gaia/service.yml | 25 - k8s/gaia/validator.yml | 217 --- k8s/icq-relayer/configs/config.yaml | 33 - k8s/icq-relayer/configs/keys.json | 36 - k8s/icq-relayer/icq-relayer.yml | 78 - k8s/icq-relayer/kustomization.yml | 19 - k8s/icq-relayer/scripts/chain0.sh | 2 - k8s/icq-relayer/scripts/chain1.sh | 2 - k8s/icq-relayer/scripts/key-exp-script0.exp | 8 - k8s/icq-relayer/scripts/key-exp-script1.exp | 8 - k8s/pstake/configmap.yml | 6 - k8s/pstake/configs/keys.json | 44 - k8s/pstake/configs/validators.json | 46 - k8s/pstake/genesis.yml | 213 --- k8s/pstake/ingress.yml | 78 - k8s/pstake/kustomization.yml | 17 - k8s/pstake/service.yml | 25 - k8s/pstake/validator.yml | 217 --- k8s/relayer/configs/config.toml | 137 -- k8s/relayer/configs/keys.json | 37 - k8s/relayer/kustomization.yml | 13 - k8s/relayer/relayer.yml | 83 - scripts/account.sh | 10 - scripts/start.sh | 5 +- scripts/test_commands.sh | 21 - tests/e2e/chain.go | 126 -- tests/e2e/doc.go | 14 - tests/e2e/docker/hermes.Dockerfile | 12 - tests/e2e/e2e_setup_test.go | 424 ----- tests/e2e/e2e_test.go | 48 - tests/e2e/e2e_util_test.go | 185 -- tests/e2e/genesis.go | 110 -- tests/e2e/io.go | 43 - tests/e2e/keys.go | 56 - tests/e2e/scripts/hermes_bootstrap.sh | 81 - tests/e2e/util.go | 45 - tests/e2e/validator.go | 279 --- tools/tools.go | 12 - 190 files changed, 2 insertions(+), 11749 deletions(-) delete mode 100755 .build.sh delete mode 100644 .gitattributes delete mode 100644 .github/stale.yml delete mode 100644 .mergify.yml delete mode 100644 Dockerfile delete mode 100644 config.yml delete mode 100644 contrib/Dockerfile.test delete mode 100644 contrib/devtools/Makefile delete mode 100755 contrib/get_node.sh delete mode 100755 contrib/localnet-blocks-test.sh delete mode 100755 contrib/single-node.sh delete mode 100644 contrib/statesync.bash delete mode 100644 contrib/testnets/Makefile delete mode 100644 contrib/testnets/README.md delete mode 100755 contrib/testnets/add-cluster.sh delete mode 100755 contrib/testnets/add-datadog.sh delete mode 100755 contrib/testnets/del-cluster.sh delete mode 100755 contrib/testnets/del-datadog.sh delete mode 100755 contrib/testnets/list.sh delete mode 100644 contrib/testnets/local/Makefile delete mode 100644 contrib/testnets/local/gaiadnode/Dockerfile delete mode 100755 contrib/testnets/local/gaiadnode/wrapper.sh delete mode 100755 contrib/testnets/new-testnet.sh delete mode 100644 contrib/testnets/remote/ansible/.gitignore delete mode 100644 contrib/testnets/remote/ansible/add-lcd.yml delete mode 100644 contrib/testnets/remote/ansible/clear-config.yml delete mode 100644 contrib/testnets/remote/ansible/extract-config.yml delete mode 100644 contrib/testnets/remote/ansible/increase-openfiles.yml delete mode 100644 contrib/testnets/remote/ansible/install-datadog-agent.yml delete mode 100644 contrib/testnets/remote/ansible/inventory/COPYING delete mode 100644 contrib/testnets/remote/ansible/inventory/digital_ocean.ini delete mode 100755 contrib/testnets/remote/ansible/inventory/digital_ocean.py delete mode 100644 contrib/testnets/remote/ansible/inventory/ec2.ini delete mode 100755 contrib/testnets/remote/ansible/inventory/ec2.py delete mode 100644 contrib/testnets/remote/ansible/logzio.yml delete mode 100644 contrib/testnets/remote/ansible/remove-datadog-agent.yml delete mode 100644 contrib/testnets/remote/ansible/roles/add-lcd/defaults/main.yml delete mode 100644 contrib/testnets/remote/ansible/roles/add-lcd/handlers/main.yml delete mode 100644 contrib/testnets/remote/ansible/roles/add-lcd/tasks/main.yml delete mode 100644 contrib/testnets/remote/ansible/roles/add-lcd/templates/gaiacli.service.j2 delete mode 100644 contrib/testnets/remote/ansible/roles/clear-config/tasks/main.yml delete mode 100644 contrib/testnets/remote/ansible/roles/extract-config/defaults/main.yml delete mode 100644 contrib/testnets/remote/ansible/roles/extract-config/tasks/main.yml delete mode 100644 contrib/testnets/remote/ansible/roles/increase-openfiles/files/50-fs.conf delete mode 100644 contrib/testnets/remote/ansible/roles/increase-openfiles/files/91-nofiles.conf delete mode 100644 contrib/testnets/remote/ansible/roles/increase-openfiles/files/limits.conf delete mode 100644 contrib/testnets/remote/ansible/roles/increase-openfiles/handlers/main.yml delete mode 100644 contrib/testnets/remote/ansible/roles/increase-openfiles/tasks/main.yml delete mode 100644 contrib/testnets/remote/ansible/roles/install-datadog-agent/handlers/main.yml delete mode 100644 contrib/testnets/remote/ansible/roles/install-datadog-agent/tasks/main.yml delete mode 100644 contrib/testnets/remote/ansible/roles/logzio/files/journalbeat.service delete mode 100644 contrib/testnets/remote/ansible/roles/logzio/handlers/main.yml delete mode 100644 contrib/testnets/remote/ansible/roles/logzio/tasks/main.yml delete mode 100644 contrib/testnets/remote/ansible/roles/logzio/templates/journalbeat.yml.j2 delete mode 100644 contrib/testnets/remote/ansible/roles/remove-datadog-agent/tasks/main.yml delete mode 100644 contrib/testnets/remote/ansible/roles/set-debug/files/sysconfig/gaiacli delete mode 100644 contrib/testnets/remote/ansible/roles/set-debug/files/sysconfig/gaiad delete mode 100644 contrib/testnets/remote/ansible/roles/set-debug/files/sysctl.d/10-procdump delete mode 100644 contrib/testnets/remote/ansible/roles/set-debug/handlers/main.yml delete mode 100644 contrib/testnets/remote/ansible/roles/set-debug/tasks/main.yml delete mode 100644 contrib/testnets/remote/ansible/roles/setup-fullnodes/defaults/main.yml delete mode 100644 contrib/testnets/remote/ansible/roles/setup-fullnodes/files/gaiad.service delete mode 100644 contrib/testnets/remote/ansible/roles/setup-fullnodes/handlers/main.yml delete mode 100644 contrib/testnets/remote/ansible/roles/setup-fullnodes/tasks/main.yml delete mode 100644 contrib/testnets/remote/ansible/roles/setup-journald/handlers/main.yml delete mode 100644 contrib/testnets/remote/ansible/roles/setup-journald/tasks/main.yml delete mode 100644 contrib/testnets/remote/ansible/roles/setup-validators/defaults/main.yml delete mode 100644 contrib/testnets/remote/ansible/roles/setup-validators/files/gaiad.service delete mode 100644 contrib/testnets/remote/ansible/roles/setup-validators/handlers/main.yml delete mode 100644 contrib/testnets/remote/ansible/roles/setup-validators/tasks/main.yml delete mode 100644 contrib/testnets/remote/ansible/roles/start/tasks/main.yml delete mode 100644 contrib/testnets/remote/ansible/roles/stop/tasks/main.yml delete mode 100644 contrib/testnets/remote/ansible/roles/update-datadog-agent/files/conf.d/http_check.d/conf.yml delete mode 100644 contrib/testnets/remote/ansible/roles/update-datadog-agent/files/conf.d/network.d/conf.yml delete mode 100644 contrib/testnets/remote/ansible/roles/update-datadog-agent/files/conf.d/process.d/conf.yml delete mode 100644 contrib/testnets/remote/ansible/roles/update-datadog-agent/files/conf.d/prometheus.d/conf.yml delete mode 100644 contrib/testnets/remote/ansible/roles/update-datadog-agent/handlers/main.yml delete mode 100644 contrib/testnets/remote/ansible/roles/update-datadog-agent/tasks/main.yml delete mode 100644 contrib/testnets/remote/ansible/roles/update-datadog-agent/templates/datadog.yaml.j2 delete mode 100644 contrib/testnets/remote/ansible/roles/upgrade-gaiad/handlers/main.yml delete mode 100644 contrib/testnets/remote/ansible/roles/upgrade-gaiad/tasks/main.yml delete mode 100644 contrib/testnets/remote/ansible/set-debug.yml delete mode 100644 contrib/testnets/remote/ansible/setup-fullnodes.yml delete mode 100644 contrib/testnets/remote/ansible/setup-journald.yml delete mode 100644 contrib/testnets/remote/ansible/setup-validators.yml delete mode 100644 contrib/testnets/remote/ansible/start.yml delete mode 100644 contrib/testnets/remote/ansible/status.yml delete mode 100644 contrib/testnets/remote/ansible/stop.yml delete mode 100644 contrib/testnets/remote/ansible/update-datadog-agent.yml delete mode 100644 contrib/testnets/remote/ansible/upgrade-gaia.yml delete mode 100644 contrib/testnets/remote/ansible/upgrade-gaiad.yml delete mode 100644 contrib/testnets/remote/terraform-app/.gitignore delete mode 100644 contrib/testnets/remote/terraform-app/files/terraform.sh delete mode 100644 contrib/testnets/remote/terraform-app/infra/attachment.tf delete mode 100644 contrib/testnets/remote/terraform-app/infra/instance.tf delete mode 100644 contrib/testnets/remote/terraform-app/infra/lb.tf delete mode 100644 contrib/testnets/remote/terraform-app/infra/lcd.tf delete mode 100644 contrib/testnets/remote/terraform-app/infra/outputs.tf delete mode 100644 contrib/testnets/remote/terraform-app/infra/variables.tf delete mode 100644 contrib/testnets/remote/terraform-app/infra/vpc.tf delete mode 100644 contrib/testnets/remote/terraform-app/main.tf delete mode 100644 contrib/testnets/remote/terraform-aws/.gitignore delete mode 100644 contrib/testnets/remote/terraform-aws/files/terraform.sh delete mode 100644 contrib/testnets/remote/terraform-aws/main.tf delete mode 100644 contrib/testnets/remote/terraform-aws/nodes/main.tf delete mode 100644 contrib/testnets/remote/terraform-aws/nodes/outputs.tf delete mode 100644 contrib/testnets/remote/terraform-aws/nodes/variables.tf delete mode 100644 contrib/testnets/remote/terraform-do/.gitignore delete mode 100644 contrib/testnets/remote/terraform-do/Makefile delete mode 100644 contrib/testnets/remote/terraform-do/README.md delete mode 100644 contrib/testnets/remote/terraform-do/cluster/main.tf delete mode 100644 contrib/testnets/remote/terraform-do/cluster/outputs.tf delete mode 100644 contrib/testnets/remote/terraform-do/cluster/variables.tf delete mode 100644 contrib/testnets/remote/terraform-do/files/terraform.sh delete mode 100644 contrib/testnets/remote/terraform-do/main.tf delete mode 100644 contrib/testnets/test_platform/README.md delete mode 100644 contrib/testnets/test_platform/gaiad_config_manager.py delete mode 100644 contrib/testnets/test_platform/templates/3924406.cosmoshub-3.json.tar.gz delete mode 100644 contrib/testnets/test_platform/templates/app.toml delete mode 100644 contrib/testnets/test_platform/templates/config.toml delete mode 100644 contrib/testnets/test_platform/templates/replacement_defaults.txt delete mode 100644 contrib/testnets/test_platform/templates/validator_replacement_example.json delete mode 100755 contrib/testnets/upgrade-gaiad.sh delete mode 100644 contrib/testnets/using-cleveldb.sh delete mode 100644 docker-compose.yml delete mode 100644 docker/explorer/Dockerfile delete mode 100644 docker/exposer/Dockerfile delete mode 100644 docker/exposer/Dockerfile.gaia delete mode 100644 docker/exposer/node.go delete mode 100644 docker/gaia/Dockerfile delete mode 100644 docker/icq-relayer/Dockerfile delete mode 100644 docker/pstake-e2e/Dockerfile delete mode 100644 k8s/Makefile delete mode 100644 k8s/README.md delete mode 100644 k8s/explorer/configmap.yml delete mode 100644 k8s/explorer/configs/gaia.json delete mode 100644 k8s/explorer/configs/pstake.json delete mode 100644 k8s/explorer/explorer.yml delete mode 100644 k8s/explorer/ingress.yml delete mode 100644 k8s/explorer/kustomization.yml delete mode 100644 k8s/faucet/configs/.cosmos.env delete mode 100644 k8s/faucet/configs/.persistence.env delete mode 100644 k8s/faucet/faucet.yml delete mode 100644 k8s/faucet/ingress.yml delete mode 100644 k8s/faucet/kustomization.yml delete mode 100644 k8s/gaia/configmap.yml delete mode 100644 k8s/gaia/configs/keys.json delete mode 100644 k8s/gaia/configs/validators.json delete mode 100644 k8s/gaia/genesis.yml delete mode 100644 k8s/gaia/ingress.yml delete mode 100644 k8s/gaia/kustomization.yml delete mode 100644 k8s/gaia/service.yml delete mode 100644 k8s/gaia/validator.yml delete mode 100644 k8s/icq-relayer/configs/config.yaml delete mode 100644 k8s/icq-relayer/configs/keys.json delete mode 100644 k8s/icq-relayer/icq-relayer.yml delete mode 100644 k8s/icq-relayer/kustomization.yml delete mode 100755 k8s/icq-relayer/scripts/chain0.sh delete mode 100755 k8s/icq-relayer/scripts/chain1.sh delete mode 100755 k8s/icq-relayer/scripts/key-exp-script0.exp delete mode 100755 k8s/icq-relayer/scripts/key-exp-script1.exp delete mode 100644 k8s/pstake/configmap.yml delete mode 100644 k8s/pstake/configs/keys.json delete mode 100644 k8s/pstake/configs/validators.json delete mode 100644 k8s/pstake/genesis.yml delete mode 100644 k8s/pstake/ingress.yml delete mode 100644 k8s/pstake/kustomization.yml delete mode 100644 k8s/pstake/service.yml delete mode 100644 k8s/pstake/validator.yml delete mode 100644 k8s/relayer/configs/config.toml delete mode 100644 k8s/relayer/configs/keys.json delete mode 100644 k8s/relayer/kustomization.yml delete mode 100644 k8s/relayer/relayer.yml delete mode 100644 scripts/account.sh delete mode 100644 scripts/test_commands.sh delete mode 100644 tests/e2e/chain.go delete mode 100644 tests/e2e/doc.go delete mode 100644 tests/e2e/docker/hermes.Dockerfile delete mode 100644 tests/e2e/e2e_setup_test.go delete mode 100644 tests/e2e/e2e_test.go delete mode 100644 tests/e2e/e2e_util_test.go delete mode 100644 tests/e2e/genesis.go delete mode 100644 tests/e2e/io.go delete mode 100644 tests/e2e/keys.go delete mode 100755 tests/e2e/scripts/hermes_bootstrap.sh delete mode 100644 tests/e2e/util.go delete mode 100644 tests/e2e/validator.go delete mode 100644 tools/tools.go diff --git a/.build.sh b/.build.sh deleted file mode 100755 index 1f7a14883..000000000 --- a/.build.sh +++ /dev/null @@ -1,44 +0,0 @@ -#!/bin/bash - -set -ue - -# Expect the following envvars to be set: -# - APP -# - VERSION -# - COMMIT -# - TARGET_OS -# - LEDGER_ENABLED -# - DEBUG - -# Source builder's functions library -. /usr/local/share/tendermint/buildlib.sh - -# These variables are now available -# - BASEDIR -# - OUTDIR - -# Build for each os-architecture pair -for platform in ${TARGET_PLATFORMS} ; do - # This function sets GOOS, GOARCH, and OS_FILE_EXT environment variables - # according to the build target platform. OS_FILE_EXT is empty in all - # cases except when the target platform is 'windows'. - setup_build_env_for_platform "${platform}" - - make clean - echo Building for $(go env GOOS)/$(go env GOARCH) >&2 - GOROOT_FINAL="$(go env GOROOT)" \ - make build \ - LDFLAGS=-buildid=${VERSION} \ - VERSION=${VERSION} \ - COMMIT=${COMMIT} \ - LEDGER_ENABLED=${LEDGER_ENABLED} - mv ./build/${APP}${OS_FILE_EXT} ${OUTDIR}/${APP}-${VERSION}-$(go env GOOS)-$(go env GOARCH)${OS_FILE_EXT} - - # This function restore the build environment variables to their - # original state. - restore_build_env -done - -# Generate and display build report. -generate_build_report -cat ${OUTDIR}/build_report diff --git a/.gitattributes b/.gitattributes deleted file mode 100644 index e69de29bb..000000000 diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 279947690..8276d641c 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -2,5 +2,6 @@ # Primary repo maintainers * @puneet2019 +* @kruspy diff --git a/.github/stale.yml b/.github/stale.yml deleted file mode 100644 index 435cfeaaf..000000000 --- a/.github/stale.yml +++ /dev/null @@ -1,45 +0,0 @@ -# Configuration for probot-stale - https://github.com/probot/stale - -# Number of days of inactivity before an Issue or Pull Request becomes stale -daysUntilStale: 10 - -# Number of days of inactivity before an Issue or Pull Request with the stale label is closed. -# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale. -daysUntilClose: 4 - -# Only issues or pull requests with all of these labels are check if stale. Defaults to `[]` (disabled) -onlyLabels: [] - -# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable -exemptLabels: - - blocked - - pinned - - security - -# Set to true to ignore issues in a project (defaults to false) -exemptProjects: true - -# Set to true to ignore issues in a milestone (defaults to false) -exemptMilestones: true - -# Label to use when marking as stale -staleLabel: stale - -# Comment to post when marking as stale. Set to `false` to disable -markComment: > - This issue has been automatically marked as stale because it has not had - recent activity. It will be closed if no further activity occurs. Thank you - for your contributions. -# Limit the number of actions per hour, from 1-30. Default is 30 -limitPerRun: 30 - -# Limit to only `issues` or `pulls` -only: pulls - -# Optionally, specify configuration settings that are specific to just 'issues' or 'pulls': -pulls: - daysUntilStale: 30 - markComment: > - This pull request has been automatically marked as stale because it has not had - recent activity. It will be closed if no further activity occurs. Thank you - for your contributions. diff --git a/.mergify.yml b/.mergify.yml deleted file mode 100644 index ff476c8f9..000000000 --- a/.mergify.yml +++ /dev/null @@ -1,18 +0,0 @@ -pull_request_rules: - - name: automerge to main with label automerge and branch protection passing - conditions: - - "#approved-reviews-by>0" - - base=main - - label=automerge - actions: - merge: - method: squash - strict: true - - name: backport patches to v4.2.x branch - conditions: - - base=main - - label=backport/4.2.x - actions: - backport: - branches: - - release/v4.2.x \ No newline at end of file diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 0703aafab..000000000 --- a/Dockerfile +++ /dev/null @@ -1,27 +0,0 @@ -FROM golang:1.19-alpine AS build-env - -# Set up dependencies -RUN apk add --no-cache curl make git libc-dev bash gcc linux-headers eudev-dev python3 - -# Set working directory for the build -WORKDIR /go/src/github.com/persistenceOne/pstake-native - -# Add source files -COPY . . - -# Install minimum necessary dependencies, build Cosmos SDK, remove packages -RUN make install - -# Final image -FROM alpine:edge - -# Install ca-certificates -RUN apk add --update ca-certificates jq bash curl perl - -# Set working directory -WORKDIR /root - -# Copy over binaries from the build-env -COPY --from=build-env /go/bin/pstaked /usr/bin/pstaked - -EXPOSE 26657 diff --git a/config.yml b/config.yml deleted file mode 100644 index 1ddfcc94d..000000000 --- a/config.yml +++ /dev/null @@ -1,9 +0,0 @@ -version: 1 -accounts: - - name: alice - coins: ["1000token", "100000000stake"] - - name: bob - coins: ["500token"] -validator: - name: alice - staked: "100000000stake" diff --git a/contrib/Dockerfile.test b/contrib/Dockerfile.test deleted file mode 100644 index 3c48e7f85..000000000 --- a/contrib/Dockerfile.test +++ /dev/null @@ -1,35 +0,0 @@ -# Simple usage with a mounted data directory: -# > docker build -t pstake . -# > docker run -it -p 46657:46657 -p 46656:46656 -v ~/.pstaked:/root/.pstaked pstake pstaked init -# > docker run -it -p 46657:46657 -p 46656:46656 -v ~/.pstaked:/root/.pstaked pstake pstaked start -FROM golang:1.17-alpine AS build-env - -# Set up dependencies -ENV PACKAGES curl make git libc-dev bash gcc linux-headers eudev-dev python3 - -# Set working directory for the build -WORKDIR /go/src/github.com/persistenceOne/pstake-native - -# Add source files -COPY . . - -# Install minimum necessary dependencies, build Cosmos SDK, remove packages -RUN apk add --no-cache $PACKAGES && \ - make install - -# Final image -FROM alpine:edge - -# Install ca-certificates -RUN apk add --update ca-certificates -WORKDIR /root - -# Copy over binaries from the build-env -COPY --from=build-env /go/bin/pstaked /usr/bin/pstaked - -COPY ./contrib/single-node.sh . - -EXPOSE 26657 - -ENTRYPOINT [ "./single-node.sh" ] -# NOTE: to run this image, docker run -d -p 26657:26657 ./single-node.sh {{chain_id}} {{genesis_account}} diff --git a/contrib/devtools/Makefile b/contrib/devtools/Makefile deleted file mode 100644 index 8cfcc905a..000000000 --- a/contrib/devtools/Makefile +++ /dev/null @@ -1,114 +0,0 @@ -### -# Find OS and Go environment -# GO contains the Go binary -# FS contains the OS file separator -### -ifeq ($(OS),Windows_NT) - GO := $(shell where go.exe 2> NUL) - FS := \\ -else - GO := $(shell command -v go 2> /dev/null) - FS := / -endif - -ifeq ($(GO),) - $(error could not find go. Is it in PATH? $(GO)) -endif - -GOPATH ?= $(shell $(GO) env GOPATH) -GITHUBDIR := $(GOPATH)$(FS)src$(FS)github.com - -### -# Functions -### - -go_get = $(if $(findstring Windows_NT,$(OS)),\ -IF NOT EXIST $(GITHUBDIR)$(FS)$(1)$(FS) ( mkdir $(GITHUBDIR)$(FS)$(1) ) else (cd .) &\ -IF NOT EXIST $(GITHUBDIR)$(FS)$(1)$(FS)$(2)$(FS) ( cd $(GITHUBDIR)$(FS)$(1) && git clone https://github.com/$(1)/$(2) ) else (cd .) &\ -,\ -mkdir -p $(GITHUBDIR)$(FS)$(1) &&\ -(test ! -d $(GITHUBDIR)$(FS)$(1)$(FS)$(2) && cd $(GITHUBDIR)$(FS)$(1) && git clone https://github.com/$(1)/$(2)) || true &&\ -)\ -cd $(GITHUBDIR)$(FS)$(1)$(FS)$(2) && git fetch origin && git checkout -q $(3) - -go_install = $(call go_get,$(1),$(2),$(3)) && cd $(GITHUBDIR)$(FS)$(1)$(FS)$(2) && $(GO) install - -mkfile_path := $(abspath $(lastword $(MAKEFILE_LIST))) -mkfile_dir := $(shell cd $(shell dirname $(mkfile_path)); pwd) - -############################################################################### -### Tools ### -############################################################################### - -BIN ?= /usr/local/bin -UNAME_S ?= $(shell uname -s) -UNAME_M ?= $(shell uname -m) - -TOOLS_DESTDIR ?= $(GOPATH)/bin -RUNSIM = $(TOOLS_DESTDIR)/runsim - -BUF_VERSION ?= 0.7.0 -PROTOC_VERSION ?= 3.11.2 - -ifeq ($(UNAME_S),Linux) - PROTOC_ZIP ?= protoc-3.11.2-linux-x86_64.zip -endif -ifeq ($(UNAME_S),Darwin) - PROTOC_ZIP ?= protoc-3.11.2-osx-x86_64.zip -endif - -all: tools - -tools: tools-stamp - -tools-stamp: $(RUNSIM) - touch $@ - -# Install the runsim binary with a temporary workaround of entering an outside -# directory as the "go get" command ignores the -mod option and will polute the -# go.{mod, sum} files. -# -# ref: https://github.com/golang/go/issues/30515 -runsim: $(RUNSIM) -$(RUNSIM): - @echo "Installing runsim..." - @(cd /tmp && go get github.com/cosmos/tools/cmd/runsim@v1.0.0) - -protoc: - @echo "Installing protoc compiler..." - @(cd /tmp; \ - curl -sSOL "https://github.com/protocolbuffers/protobuf/releases/download/v${PROTOC_VERSION}/${PROTOC_ZIP}"; \ - unzip -o ${PROTOC_ZIP} -d /usr/local bin/protoc; \ - unzip -o ${PROTOC_ZIP} -d /usr/local 'include/*'; \ - rm -f ${PROTOC_ZIP}) - -protoc-gen-gocosmos: - @echo "Installing protoc-gen-gocosmos..." - @go install github.com/regen-network/cosmos-proto/protoc-gen-gocosmos - -buf: protoc-gen-buf-check-breaking protoc-gen-buf-check-lint - @echo "Installing buf..." - @(cd /tmp; \ - curl -sSOL "https://github.com/bufbuild/buf/releases/download/v${BUF_VERSION}/buf-${UNAME_S}-${UNAME_M}"; \ - mv buf-${UNAME_S}-${UNAME_M} "${BIN}/buf"; \ - chmod +x "${BIN}/buf") - -protoc-gen-buf-check-breaking: - @echo "Installing protoc-gen-buf-check-breaking..." - @(cd /tmp; \ - curl -sSOL "https://github.com/bufbuild/buf/releases/download/v${BUF_VERSION}/protoc-gen-buf-check-breaking-${UNAME_S}-${UNAME_M}"; \ - mv protoc-gen-buf-check-breaking-${UNAME_S}-${UNAME_M} "${BIN}/protoc-gen-buf-check-breaking"; \ - chmod +x "${BIN}/protoc-gen-buf-check-breaking") - -protoc-gen-buf-check-lint: - @echo "Installing protoc-gen-buf-check-lint..." - @(cd /tmp; \ - curl -sSOL "https://github.com/bufbuild/buf/releases/download/v${BUF_VERSION}/protoc-gen-buf-check-lint-${UNAME_S}-${UNAME_M}"; \ - mv protoc-gen-buf-check-lint-${UNAME_S}-${UNAME_M} "${BIN}/protoc-gen-buf-check-lint"; \ - chmod +x "${BIN}/protoc-gen-buf-check-lint") - -tools-clean: - rm -f $(RUNSIM) - rm -f tools-stamp - -.PHONY: all tools tools-clean protoc buf protoc-gen-buf-check-breaking protoc-gen-buf-check-lint protoc-gen-gocosmos diff --git a/contrib/get_node.sh b/contrib/get_node.sh deleted file mode 100755 index 7f0dd6e38..000000000 --- a/contrib/get_node.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env bash - -VERSION=v11.15.0 -NODE_FULL=node-${VERSION}-linux-x64 - -mkdir -p ~/.local/bin -mkdir -p ~/.local/node -wget http://nodejs.org/dist/${VERSION}/${NODE_FULL}.tar.gz -O ~/.local/node/${NODE_FULL}.tar.gz -tar -xzf ~/.local/node/${NODE_FULL}.tar.gz -C ~/.local/node/ -ln -s ~/.local/node/${NODE_FULL}/bin/node ~/.local/bin/node -ln -s ~/.local/node/${NODE_FULL}/bin/npm ~/.local/bin/npm -export PATH=~/.local/bin:$PATH -npm i -g dredd@11.0.1 -ln -s ~/.local/node/${NODE_FULL}/bin/dredd ~/.local/bin/dredd diff --git a/contrib/localnet-blocks-test.sh b/contrib/localnet-blocks-test.sh deleted file mode 100755 index cfa64993b..000000000 --- a/contrib/localnet-blocks-test.sh +++ /dev/null @@ -1,57 +0,0 @@ -#!/bin/bash - -CNT=0 -ITER=$1 -SLEEP=$2 -NUMBLOCKS=$3 -NODEADDR=$4 - -if [ -z "$1" ]; then - echo "Need to input number of iterations to run..." - exit 1 -fi - -if [ -z "$2" ]; then - echo "Need to input number of seconds to sleep between iterations" - exit 1 -fi - -if [ -z "$3" ]; then - echo "Need to input block height to declare completion..." - exit 1 -fi - -if [ -z "$4" ]; then - echo "Need to input node address to poll..." - exit 1 -fi - -docker_containers=( $(docker ps -q -f name=gaia --format='{{.Names}}') ) - -while [ ${CNT} -lt $ITER ]; do - curr_block=$(curl -s $NODEADDR:26657/status | jq -r '.result.sync_info.latest_block_height') - - if [ ! -z ${curr_block} ] ; then - echo "Number of Blocks: ${curr_block}" - fi - - if [ ! -z ${curr_block} ] && [ ${curr_block} -gt ${NUMBLOCKS} ]; then - echo "Number of blocks reached. Success!" - exit 0 - fi - - # Emulate network chaos: - # - # Every 10 blocks, pick a random container and restart it. - if ! ((${CNT} % 10)); then - rand_container=${docker_containers["$[RANDOM % ${#docker_containers[@]}]"]}; - echo "Restarting random docker container ${rand_container}" - docker restart ${rand_container} &>/dev/null & - fi - - let CNT=CNT+1 - sleep $SLEEP -done - -echo "Timeout reached. Failure!" -exit 1 diff --git a/contrib/single-node.sh b/contrib/single-node.sh deleted file mode 100755 index 95d6e0d2f..000000000 --- a/contrib/single-node.sh +++ /dev/null @@ -1,34 +0,0 @@ -#!/bin/sh - -set -o errexit -o nounset - -CHAINID=$1 -GENACCT=$2 - -if [ -z "$1" ]; then - echo "Need to input chain id..." - exit 1 -fi - -if [ -z "$2" ]; then - echo "Need to input genesis account address..." - exit 1 -fi - -# Build genesis file incl account for passed address -coins="100000000000000000stake" -pstaked init --chain-id $CHAINID $CHAINID -pstaked keys add validator --keyring-backend="test" -pstaked add-genesis-account $(pstaked keys show validator -a --keyring-backend="test") $coins -pstaked add-genesis-account $GENACCT $coins -pstaked gentx validator 5000000000stake --keyring-backend="test" --chain-id $CHAINID -pstaked collect-gentxs - -# Set proper defaults and change ports -sed -i 's#"tcp://127.0.0.1:26657"#"tcp://0.0.0.0:26657"#g' ~/.pstaked/config/config.toml -sed -i 's/timeout_commit = "5s"/timeout_commit = "1s"/g' ~/.gaia/config/config.toml -sed -i 's/timeout_propose = "3s"/timeout_propose = "1s"/g' ~/.gaia/config/config.toml -sed -i 's/index_all_keys = false/index_all_keys = true/g' ~/.pstaked/config/config.toml - -# Start the gaia -pstaked start --pruning=nothing diff --git a/contrib/statesync.bash b/contrib/statesync.bash deleted file mode 100644 index dccd28f34..000000000 --- a/contrib/statesync.bash +++ /dev/null @@ -1,40 +0,0 @@ -#!/bin/bash -# microtick and bitcanna contributed significantly here. -set -uxe - -# set environment variables -export GOPATH=~/go -export PATH=$PATH:~/go/bin - - -# Install Gaia -make install - -# MAKE HOME FOLDER AND GET GENESIS -gaiad init test -wget -O ~/.gaia/config/genesis.json https://cloudflare-ipfs.com/ipfs/Qmc54DreioPpPDUdJW6bBTYUKepmcPsscfqsfFcFmTaVig - -INTERVAL=1000 - -# GET TRUST HASH AND TRUST HEIGHT - -LATEST_HEIGHT=$(curl -s https://cosmoshub-4.technofractal.com/block | jq -r .result.block.header.height); -BLOCK_HEIGHT=$(($LATEST_HEIGHT-$INTERVAL)) -TRUST_HASH=$(curl -s "https://cosmoshub-4.technofractal.com/block?height=$BLOCK_HEIGHT" | jq -r .result.block_id.hash) - - -# TELL USER WHAT WE ARE DOING -echo "TRUST HEIGHT: $BLOCK_HEIGHT" -echo "TRUST HASH: $TRUST_HASH" - - -# export state sync vars -export GAIAD_STATESYNC_ENABLE=true -export GAIAD_P2P_MAX_NUM_OUTBOUND_PEERS=200 -export GAIAD_STATESYNC_RPC_SERVERS="https://cosmoshub-4.technofractal.com:443,https://cosmoshub-4.technofractal.com:443" -export GAIAD_STATESYNC_TRUST_HEIGHT=$BLOCK_HEIGHT -export GAIAD_STATESYNC_TRUST_HASH=$TRUST_HASH -export GAIAD_P2P_PERSISTENT_PEERS="2bb31c07148a689f0b2dd363e17631993eca1020@162.55.132.230:2010" -export GAIAD_P2P_SEEDS="bf8328b66dceb4987e5cd94430af66045e59899f@public-seed.cosmos.vitwit.com:26656,cfd785a4224c7940e9a10f6c1ab24c343e923bec@164.68.107.188:26656,d72b3011ed46d783e369fdf8ae2055b99a1e5074@173.249.50.25:26656,ba3bacc714817218562f743178228f23678b2873@public-seed-node.cosmoshub.certus.one:26656,3c7cad4154967a294b3ba1cc752e40e8779640ad@84.201.128.115:26656,366ac852255c3ac8de17e11ae9ec814b8c68bddb@51.15.94.196:26656" - -gaiad start --x-crisis-skip-assert-invariants diff --git a/contrib/testnets/Makefile b/contrib/testnets/Makefile deleted file mode 100644 index 4d3c2d7b5..000000000 --- a/contrib/testnets/Makefile +++ /dev/null @@ -1,143 +0,0 @@ -######################################## -### These targets were broken out of the main Makefile to enable easy setup of testnets. -### They use a form of terraform + ansible to build full nodes in AWS. -### The shell scripts in this folder are example uses of the targets. - -# Name of the testnet. Used in chain-id. -TESTNET_NAME?=remotenet - -# Name of the servers grouped together for management purposes. Used in tagging the servers in the cloud. -CLUSTER_NAME?=$(TESTNET_NAME) - -# Number of servers to put in one availability zone in AWS. -SERVERS?=1 - -# Number of regions to use in AWS. One region usually contains 2-3 availability zones. -REGION_LIMIT?=1 - -# Path to pstaked for deployment. Must be a Linux binary. -BINARY?=$(CURDIR)/../build/gaiad -GAIACLI_BINARY?=$(CURDIR)/../build/gaiacli - -# Path to the genesis.json and config.toml files to deploy on full nodes. -GENESISFILE?=$(CURDIR)/../build/genesis.json -CONFIGFILE?=$(CURDIR)/../build/config.toml - -# Name of application for app deployments -APP_NAME ?= faucettestnet1 -# Region to deploy VPC and application in AWS -REGION ?= us-east-2 - -all: - @echo "There is no all. Only sum of the ones." - -disclaimer: - @echo "WARNING: These are example network configuration scripts only and have not undergone security review. They should not be used for production deployments." - -######################################## -### Extract genesis.json and config.toml from a node in a cluster - -extract-config: disclaimer - #Make sure you have AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY or your IAM roles set for AWS API access. - @if ! [ -f $(HOME)/.ssh/id_rsa.pub ]; then ssh-keygen ; fi - cd remote/ansible && \ - ANSIBLE_HOST_KEY_CHECKING=False ansible-playbook \ - -i inventory/ec2.py \ - -l "tag_Environment_$(CLUSTER_NAME)" \ - -b -u centos \ - -e TESTNET_NAME="$(TESTNET_NAME)" \ - -e GENESISFILE="$(GENESISFILE)" \ - -e CONFIGFILE="$(CONFIGFILE)" \ - extract-config.yml - - -######################################## -### Remote validator nodes using terraform and ansible in AWS - -validators-start: disclaimer - #Make sure you have AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY or your IAM roles set for AWS API access. - @if ! [ -f $(HOME)/.ssh/id_rsa.pub ]; then ssh-keygen ; fi - @if [ -z "`file $(BINARY) | grep 'ELF 64-bit'`" ]; then echo "Please build a linux binary using 'make build-linux'." ; false ; fi - cd remote/terraform-aws && terraform init && (terraform workspace new "$(CLUSTER_NAME)" || terraform workspace select "$(CLUSTER_NAME)") && terraform apply -auto-approve -var SSH_PUBLIC_FILE="$(HOME)/.ssh/id_rsa.pub" -var SSH_PRIVATE_FILE="$(HOME)/.ssh/id_rsa" -var TESTNET_NAME="$(CLUSTER_NAME)" -var SERVERS="$(SERVERS)" -var REGION_LIMIT="$(REGION_LIMIT)" - cd remote/ansible && ANSIBLE_HOST_KEY_CHECKING=False ansible-playbook -i inventory/ec2.py -l "tag_Environment_$(CLUSTER_NAME)" -u centos -b -e BINARY=$(BINARY) -e TESTNET_NAME="$(TESTNET_NAME)" setup-validators.yml - cd remote/ansible && ansible-playbook -i inventory/ec2.py -l "tag_Environment_$(CLUSTER_NAME)" -u centos -b start.yml - -validators-stop: disclaimer - cd remote/terraform-aws && terraform workspace select "$(CLUSTER_NAME)" && terraform destroy -force -var SSH_PUBLIC_FILE="$(HOME)/.ssh/id_rsa.pub" -var SSH_PRIVATE_FILE="$(HOME)/.ssh/id_rsa" && terraform workspace select default && terraform workspace delete "$(CLUSTER_NAME)" - rm -rf remote/ansible/keys/ remote/ansible/files/ - -validators-status: disclaimer - cd remote/ansible && ansible-playbook -i inventory/ec2.py -l "tag_Environment_$(CLUSTER_NAME)" status.yml - -#validators-clear: -# cd remote/ansible && ansible-playbook -i inventory/ec2.py -l "tag_Environment_$(CLUSTER_NAME)" -u centos -b clear-config.yml - - -######################################## -### Remote full nodes using terraform and ansible in Amazon AWS - -fullnodes-start: disclaimer - #Make sure you have AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY or your IAM roles set for AWS API access. - @if ! [ -f $(HOME)/.ssh/id_rsa.pub ]; then ssh-keygen ; fi - @if [ -z "`file $(BINARY) | grep 'ELF 64-bit'`" ]; then echo "Please build a linux binary using 'make build-linux'." ; false ; fi - cd remote/terraform-aws && terraform init && (terraform workspace new "$(CLUSTER_NAME)" || terraform workspace select "$(CLUSTER_NAME)") && terraform apply -auto-approve -var SSH_PUBLIC_FILE="$(HOME)/.ssh/id_rsa.pub" -var SSH_PRIVATE_FILE="$(HOME)/.ssh/id_rsa" -var TESTNET_NAME="$(CLUSTER_NAME)" -var SERVERS="$(SERVERS)" -var REGION_LIMIT="$(REGION_LIMIT)" - cd remote/ansible && ANSIBLE_HOST_KEY_CHECKING=False ansible-playbook -i inventory/ec2.py -l "tag_Environment_$(CLUSTER_NAME)" -u centos -b -e BINARY=$(BINARY) -e TESTNET_NAME="$(TESTNET_NAME)" -e GENESISFILE="$(GENESISFILE)" -e CONFIGFILE="$(CONFIGFILE)" setup-fullnodes.yml - cd remote/ansible && ansible-playbook -i inventory/ec2.py -l "tag_Environment_$(CLUSTER_NAME)" -u centos -b start.yml - -fullnodes-stop: disclaimer - cd remote/terraform-aws && terraform workspace select "$(CLUSTER_NAME)" && terraform destroy -force -var SSH_PUBLIC_FILE="$(HOME)/.ssh/id_rsa.pub" -var SSH_PRIVATE_FILE="$(HOME)/.ssh/id_rsa" && terraform workspace select default && terraform workspace delete "$(CLUSTER_NAME)" - rm -rf remote/ansible/keys/ remote/ansible/files/ - -fullnodes-status: disclaimer - cd remote/ansible && ansible-playbook -i inventory/ec2.py -l "tag_Environment_$(CLUSTER_NAME)" status.yml - -######################################## -### Other calls - -upgrade-gaiad: disclaimer - #Make sure you have AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY or your IAM roles set for AWS API access. - @if ! [ -f $(HOME)/.ssh/id_rsa.pub ]; then ssh-keygen ; fi - @if [ -z "`file $(BINARY) | grep 'ELF 64-bit'`" ]; then echo "Please build a linux binary using 'make build-linux'." ; false ; fi - cd remote/ansible && ANSIBLE_HOST_KEY_CHECKING=False ansible-playbook -i inventory/ec2.py -l "tag_Environment_$(CLUSTER_NAME)" -u centos -b -e BINARY=$(BINARY) upgrade-gaiad.yml - -UNSAFE_RESET_ALL?=no -upgrade-seeds: disclaimer - #Make sure you have AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY or your IAM roles set for AWS API access. - @if ! [ -f $(HOME)/.ssh/id_rsa.pub ]; then ssh-keygen ; fi - @if [ -z "`file $(BINARY) | grep 'ELF 64-bit'`" ]; then echo "Please build a linux binary using 'make build-linux'." ; false ; fi - @if [ -z "`file $(GAIACLI_BINARY) | grep 'ELF 64-bit'`" ]; then echo "Please build a linux binary using 'make build-linux'." ; false ; fi - cd remote/ansible && ANSIBLE_HOST_KEY_CHECKING=False ansible-playbook -i inventory/ec2.py -l "tag_Environment_$(CLUSTER_NAME)" -u centos -b -e BINARY=$(BINARY) -e GAIACLI_BINARY=$(GAIACLI_BINARY) -e UNSAFE_RESET_ALL=$(UNSAFE_RESET_ALL) upgrade-gaia.yml - - -list: - remote/ansible/inventory/ec2.py | python -c 'import json,sys ; print "\n".join(json.loads("".join(sys.stdin.readlines()))["tag_Environment_$(CLUSTER_NAME)"])' - -install-datadog: disclaimer - #Make sure you have AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY or your IAM roles set for AWS API access. - @if [ -z "$(DD_API_KEY)" ]; then echo "DD_API_KEY environment variable not set." ; false ; fi - cd remote/ansible && ANSIBLE_HOST_KEY_CHECKING=False ansible-playbook -i inventory/ec2.py -l "tag_Environment_$(CLUSTER_NAME)" -u centos -b -e DD_API_KEY="$(DD_API_KEY)" -e TESTNET_NAME="$(TESTNET_NAME)" -e CLUSTER_NAME="$(CLUSTER_NAME)" install-datadog-agent.yml - -remove-datadog: disclaimer - #Make sure you have AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY or your IAM roles set for AWS API access. - cd remote/ansible && ANSIBLE_HOST_KEY_CHECKING=False ansible-playbook -i inventory/ec2.py -l "tag_Environment_$(CLUSTER_NAME)" -u centos -b remove-datadog-agent.yml - - -######################################## -### Application infrastructure setup - -app-start: disclaimer - #Make sure you have AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY or your IAM roles set for AWS API access. - @if ! [ -f $(HOME)/.ssh/id_rsa.pub ]; then ssh-keygen ; fi - @if [ -z "`file $(BINARY) | grep 'ELF 64-bit'`" ]; then echo "Please build a linux binary using 'make build-linux'." ; false ; fi - cd remote/terraform-app && terraform init && (terraform workspace new "$(APP_NAME)" || terraform workspace select "$(APP_NAME)") && terraform apply -auto-approve -var SSH_PUBLIC_FILE="$(HOME)/.ssh/id_rsa.pub" -var SSH_PRIVATE_FILE="$(HOME)/.ssh/id_rsa" -var APP_NAME="$(APP_NAME)" -var SERVERS="$(SERVERS)" -var REGION="$(REGION)" - cd remote/ansible && ANSIBLE_HOST_KEY_CHECKING=False ansible-playbook -i inventory/ec2.py -l "tag_Environment_$(APP_NAME)" -u centos -b -e BINARY=$(BINARY) -e TESTNET_NAME="$(TESTNET_NAME)" -e GENESISFILE="$(GENESISFILE)" -e CONFIGFILE="$(CONFIGFILE)" setup-fullnodes.yml - cd remote/ansible && ansible-playbook -i inventory/ec2.py -l "tag_Environment_$(APP_NAME)" -u centos -b start.yml - -app-stop: disclaimer - cd remote/terraform-app && terraform workspace select "$(APP_NAME)" && terraform destroy -force -var SSH_PUBLIC_FILE="$(HOME)/.ssh/id_rsa.pub" -var SSH_PRIVATE_FILE="$(HOME)/.ssh/id_rsa" -var APP_NAME=$(APP_NAME) && terraform workspace select default && terraform workspace delete "$(APP_NAME)" - rm -rf remote/ansible/keys/ remote/ansible/files/ - -# To avoid unintended conflicts with file names, always add to .PHONY -# unless there is a reason not to. -# https://www.gnu.org/software/make/manual/html_node/Phony-Targets.html -.PHONY: all extract-config validators-start validators-stop validators-status fullnodes-start fullnodes-stop fullnodes-status upgrade-gaiad list install-datadog remove-datadog app-start app-stop diff --git a/contrib/testnets/README.md b/contrib/testnets/README.md deleted file mode 100644 index f4a224f08..000000000 --- a/contrib/testnets/README.md +++ /dev/null @@ -1,6 +0,0 @@ -# Networks - -Here contains the files required for automated deployment of either local or remote testnets. - -Doing so is best accomplished using the `make` targets. For more information, see the -[networks documentation](../docs/hub-tutorials/deploy-testnet.md) diff --git a/contrib/testnets/add-cluster.sh b/contrib/testnets/add-cluster.sh deleted file mode 100755 index a8936a099..000000000 --- a/contrib/testnets/add-cluster.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/sh -# add-cluster - example make call to add a set of nodes to an existing testnet in AWS -# WARNING: Run it from the current directory - it uses relative paths to ship the binary and the genesis.json,config.toml files - -if [ $# -ne 4 ]; then - echo "Usage: ./add-cluster.sh " - exit 1 -fi -set -eux - -# The testnet name is the same on all nodes -export TESTNET_NAME=$1 -export CLUSTER_NAME=$2 -export REGION_LIMIT=$3 -export SERVERS=$4 - -# Build the AWS full nodes -rm -rf remote/ansible/keys -make fullnodes-start - -# Save the private key seed words from the nodes -SEEDFOLDER="${TESTNET_NAME}-${CLUSTER_NAME}-seedwords" -mkdir -p "${SEEDFOLDER}" -test ! -f "${SEEDFOLDER}/node0" && mv remote/ansible/keys/* "${SEEDFOLDER}" - diff --git a/contrib/testnets/add-datadog.sh b/contrib/testnets/add-datadog.sh deleted file mode 100755 index 6432cc9e4..000000000 --- a/contrib/testnets/add-datadog.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh -# add-datadog - add datadog agent to a set of nodes - -if [ $# -ne 2 ]; then - echo "Usage: ./add-datadog.sh " - exit 1 -fi -set -eux - -export TESTNET_NAME=$1 -export CLUSTER_NAME=$2 - -make install-datadog - diff --git a/contrib/testnets/del-cluster.sh b/contrib/testnets/del-cluster.sh deleted file mode 100755 index 0c4dec8d1..000000000 --- a/contrib/testnets/del-cluster.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh -# del-cluster - example make call to delete a set of nodes on an existing testnet in AWS - -if [ $# -ne 1 ]; then - echo "Usage: ./add-cluster.sh " - exit 1 -fi -set -eux - -export CLUSTER_NAME=$1 - -# Delete the AWS nodes -make fullnodes-stop - diff --git a/contrib/testnets/del-datadog.sh b/contrib/testnets/del-datadog.sh deleted file mode 100755 index c9bf33526..000000000 --- a/contrib/testnets/del-datadog.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/sh -# del-datadog - aremove datadog agent from a set of nodes - -if [ $# -ne 1 ]; then - echo "Usage: ./del-datadog.sh " - exit 1 -fi -set -eux - -export CLUSTER_NAME=$1 - -make remove-datadog - diff --git a/contrib/testnets/list.sh b/contrib/testnets/list.sh deleted file mode 100755 index fd1b132fa..000000000 --- a/contrib/testnets/list.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/sh -# list - list the IPs of a set of nodes - -if [ $# -ne 1 ]; then - echo "Usage: ./list.sh " - exit 1 -fi -set -eux - -export CLUSTER_NAME=$1 - -make list - diff --git a/contrib/testnets/local/Makefile b/contrib/testnets/local/Makefile deleted file mode 100644 index c707a168e..000000000 --- a/contrib/testnets/local/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -# Makefile for the "gaiadnode" docker image. - -all: - docker build --tag tendermint/gaiadnode gaiadnode - -.PHONY: all - diff --git a/contrib/testnets/local/gaiadnode/Dockerfile b/contrib/testnets/local/gaiadnode/Dockerfile deleted file mode 100644 index 72f02fa5d..000000000 --- a/contrib/testnets/local/gaiadnode/Dockerfile +++ /dev/null @@ -1,24 +0,0 @@ -#FROM alpine:3.10.2 -# -#RUN apk update && \ -# apk upgrade && \ -# apk --no-cache add curl jq file - -# Changed from Alpine to Ubuntu because the keyring PR is linking to libc -# Alpine uses muslc instead of libc - -FROM ubuntu:18.04 - -RUN apt-get update && \ - apt-get -y upgrade && \ - apt-get -y install curl jq file - -VOLUME [ /gaiad ] -WORKDIR /gaiad -EXPOSE 26656 26657 -ENTRYPOINT ["/usr/bin/wrapper.sh"] -CMD ["start"] -STOPSIGNAL SIGTERM - -COPY wrapper.sh /usr/bin/wrapper.sh - diff --git a/contrib/testnets/local/gaiadnode/wrapper.sh b/contrib/testnets/local/gaiadnode/wrapper.sh deleted file mode 100755 index f4e9a3d1a..000000000 --- a/contrib/testnets/local/gaiadnode/wrapper.sh +++ /dev/null @@ -1,33 +0,0 @@ -#!/usr/bin/env sh - -## -## Input parameters -## -BINARY=/pstaked/${BINARY:-pstaked} -ID=${ID:-0} -LOG=${LOG:-pstaked.log} - -## -## Assert linux binary -## -if ! [ -f "${BINARY}" ]; then - echo "The binary $(basename "${BINARY}") cannot be found. Please add the binary to the shared folder. Please use the BINARY environment variable if the name of the binary is not 'gaiad' E.g.: -e BINARY=gaiad_my_test_version" - exit 1 -fi -BINARY_CHECK="$(file "$BINARY" | grep 'ELF 64-bit LSB executable, x86-64')" -if [ -z "${BINARY_CHECK}" ]; then - echo "Binary needs to be OS linux, ARCH amd64" - exit 1 -fi - -## -## Run binary with all parameters -## -export GAIADHOME="/gaiad/node${ID}/gaiad" - -if [ -d "$(dirname "${GAIADHOME}"/"${LOG}")" ]; then - "${BINARY}" --home "${GAIADHOME}" "$@" | tee "${GAIADHOME}/${LOG}" -else - "${BINARY}" --home "${GAIADHOME}" "$@" -fi - diff --git a/contrib/testnets/new-testnet.sh b/contrib/testnets/new-testnet.sh deleted file mode 100755 index ae7b73dea..000000000 --- a/contrib/testnets/new-testnet.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/sh -# new-testnet - example make call to create a new set of validator nodes in AWS -# WARNING: Run it from the current directory - it uses relative paths to ship the binary - -if [ $# -ne 4 ]; then - echo "Usage: ./new-testnet.sh " - exit 1 -fi -set -eux - -if [ -z "`file ../build/gaiad | grep 'ELF 64-bit'`" ]; then - # Build the linux binary we're going to ship to the nodes - make -C .. build-linux -fi - -# The testnet name is the same on all nodes -export TESTNET_NAME=$1 -export CLUSTER_NAME=$2 -export REGION_LIMIT=$3 -export SERVERS=$4 - -# Build the AWS validator nodes and extract the genesis.json and config.toml from one of them -rm -rf remote/ansible/keys -make validators-start extract-config - -# Save the private key seed words from the validators -SEEDFOLDER="${TESTNET_NAME}-${CLUSTER_NAME}-seedwords" -mkdir -p "${SEEDFOLDER}" -test ! -f "${SEEDFOLDER}/node0" && mv remote/ansible/keys/* "${SEEDFOLDER}" - diff --git a/contrib/testnets/remote/ansible/.gitignore b/contrib/testnets/remote/ansible/.gitignore deleted file mode 100644 index bebb9186b..000000000 --- a/contrib/testnets/remote/ansible/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -*.retry -files/* -keys/* diff --git a/contrib/testnets/remote/ansible/add-lcd.yml b/contrib/testnets/remote/ansible/add-lcd.yml deleted file mode 100644 index bdc070348..000000000 --- a/contrib/testnets/remote/ansible/add-lcd.yml +++ /dev/null @@ -1,8 +0,0 @@ ---- - -- hosts: all - any_errors_fatal: true - gather_facts: no - roles: - - add-lcd - diff --git a/contrib/testnets/remote/ansible/clear-config.yml b/contrib/testnets/remote/ansible/clear-config.yml deleted file mode 100644 index 80831e75c..000000000 --- a/contrib/testnets/remote/ansible/clear-config.yml +++ /dev/null @@ -1,8 +0,0 @@ ---- - -- hosts: all - any_errors_fatal: true - gather_facts: no - roles: - - clear-config - diff --git a/contrib/testnets/remote/ansible/extract-config.yml b/contrib/testnets/remote/ansible/extract-config.yml deleted file mode 100644 index d901bb698..000000000 --- a/contrib/testnets/remote/ansible/extract-config.yml +++ /dev/null @@ -1,8 +0,0 @@ ---- - -- hosts: all - any_errors_fatal: true - gather_facts: no - roles: - - extract-config - diff --git a/contrib/testnets/remote/ansible/increase-openfiles.yml b/contrib/testnets/remote/ansible/increase-openfiles.yml deleted file mode 100644 index 1adcb821c..000000000 --- a/contrib/testnets/remote/ansible/increase-openfiles.yml +++ /dev/null @@ -1,8 +0,0 @@ ---- - -- hosts: all - any_errors_fatal: true - gather_facts: no - roles: - - increase-openfiles - diff --git a/contrib/testnets/remote/ansible/install-datadog-agent.yml b/contrib/testnets/remote/ansible/install-datadog-agent.yml deleted file mode 100644 index b88600eae..000000000 --- a/contrib/testnets/remote/ansible/install-datadog-agent.yml +++ /dev/null @@ -1,12 +0,0 @@ ---- - -#DD_API_KEY,TESTNET_NAME,CLUSTER_NAME required - -- hosts: all - any_errors_fatal: true - gather_facts: no - roles: - - setup-journald - - install-datadog-agent - - update-datadog-agent - diff --git a/contrib/testnets/remote/ansible/inventory/COPYING b/contrib/testnets/remote/ansible/inventory/COPYING deleted file mode 100644 index 10926e87f..000000000 --- a/contrib/testnets/remote/ansible/inventory/COPYING +++ /dev/null @@ -1,675 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. - diff --git a/contrib/testnets/remote/ansible/inventory/digital_ocean.ini b/contrib/testnets/remote/ansible/inventory/digital_ocean.ini deleted file mode 100644 index b809554b2..000000000 --- a/contrib/testnets/remote/ansible/inventory/digital_ocean.ini +++ /dev/null @@ -1,34 +0,0 @@ -# Ansible DigitalOcean external inventory script settings -# - -[digital_ocean] - -# The module needs your DigitalOcean API Token. -# It may also be specified on the command line via --api-token -# or via the environment variables DO_API_TOKEN or DO_API_KEY -# -#api_token = 123456abcdefg - - -# API calls to DigitalOcean may be slow. For this reason, we cache the results -# of an API call. Set this to the path you want cache files to be written to. -# One file will be written to this directory: -# - ansible-digital_ocean.cache -# -cache_path = /tmp - - -# The number of seconds a cache file is considered valid. After this many -# seconds, a new API call will be made, and the cache file will be updated. -# -cache_max_age = 300 - -# Use the private network IP address instead of the public when available. -# -use_private_network = False - -# Pass variables to every group, e.g.: -# -# group_variables = { 'ansible_user': 'root' } -# -group_variables = {} diff --git a/contrib/testnets/remote/ansible/inventory/digital_ocean.py b/contrib/testnets/remote/ansible/inventory/digital_ocean.py deleted file mode 100755 index 24ba64370..000000000 --- a/contrib/testnets/remote/ansible/inventory/digital_ocean.py +++ /dev/null @@ -1,471 +0,0 @@ -#!/usr/bin/env python - -''' -DigitalOcean external inventory script -====================================== - -Generates Ansible inventory of DigitalOcean Droplets. - -In addition to the --list and --host options used by Ansible, there are options -for generating JSON of other DigitalOcean data. This is useful when creating -droplets. For example, --regions will return all the DigitalOcean Regions. -This information can also be easily found in the cache file, whose default -location is /tmp/ansible-digital_ocean.cache). - -The --pretty (-p) option pretty-prints the output for better human readability. - ----- -Although the cache stores all the information received from DigitalOcean, -the cache is not used for current droplet information (in --list, --host, ---all, and --droplets). This is so that accurate droplet information is always -found. You can force this script to use the cache with --force-cache. - ----- -Configuration is read from `digital_ocean.ini`, then from environment variables, -then and command-line arguments. - -Most notably, the DigitalOcean API Token must be specified. It can be specified -in the INI file or with the following environment variables: - export DO_API_TOKEN='abc123' or - export DO_API_KEY='abc123' - -Alternatively, it can be passed on the command-line with --api-token. - -If you specify DigitalOcean credentials in the INI file, a handy way to -get them into your environment (e.g., to use the digital_ocean module) -is to use the output of the --env option with export: - export $(digital_ocean.py --env) - ----- -The following groups are generated from --list: - - ID (droplet ID) - - NAME (droplet NAME) - - image_ID - - image_NAME - - distro_NAME (distribution NAME from image) - - region_NAME - - size_NAME - - status_STATUS - -For each host, the following variables are registered: - - do_backup_ids - - do_created_at - - do_disk - - do_features - list - - do_id - - do_image - object - - do_ip_address - - do_private_ip_address - - do_kernel - object - - do_locked - - do_memory - - do_name - - do_networks - object - - do_next_backup_window - - do_region - object - - do_size - object - - do_size_slug - - do_snapshot_ids - list - - do_status - - do_tags - - do_vcpus - - do_volume_ids - ------ -``` -usage: digital_ocean.py [-h] [--list] [--host HOST] [--all] - [--droplets] [--regions] [--images] [--sizes] - [--ssh-keys] [--domains] [--pretty] - [--cache-path CACHE_PATH] - [--cache-max_age CACHE_MAX_AGE] - [--force-cache] - [--refresh-cache] - [--api-token API_TOKEN] - -Produce an Ansible Inventory file based on DigitalOcean credentials - -optional arguments: - -h, --help show this help message and exit - --list List all active Droplets as Ansible inventory - (default: True) - --host HOST Get all Ansible inventory variables about a specific - Droplet - --all List all DigitalOcean information as JSON - --droplets List Droplets as JSON - --regions List Regions as JSON - --images List Images as JSON - --sizes List Sizes as JSON - --ssh-keys List SSH keys as JSON - --domains List Domains as JSON - --pretty, -p Pretty-print results - --cache-path CACHE_PATH - Path to the cache files (default: .) - --cache-max_age CACHE_MAX_AGE - Maximum age of the cached items (default: 0) - --force-cache Only use data from the cache - --refresh-cache Force refresh of cache by making API requests to - DigitalOcean (default: False - use cache files) - --api-token API_TOKEN, -a API_TOKEN - DigitalOcean API Token -``` - -''' - -# (c) 2013, Evan Wies -# -# Inspired by the EC2 inventory plugin: -# https://github.com/ansible/ansible/blob/devel/contrib/inventory/ec2.py -# -# This file is part of Ansible, -# -# Ansible is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Ansible is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Ansible. If not, see . - -###################################################################### - -import os -import sys -import re -import argparse -from time import time -import ConfigParser -import ast - -try: - import json -except ImportError: - import simplejson as json - -try: - from dopy.manager import DoManager -except ImportError as e: - sys.exit("failed=True msg='`dopy` library required for this script'") - - -class DigitalOceanInventory(object): - - ########################################################################### - # Main execution path - ########################################################################### - - def __init__(self): - ''' Main execution path ''' - - # DigitalOceanInventory data - self.data = {} # All DigitalOcean data - self.inventory = {} # Ansible Inventory - - # Define defaults - self.cache_path = '.' - self.cache_max_age = 0 - self.use_private_network = False - self.group_variables = {} - - # Read settings, environment variables, and CLI arguments - self.read_settings() - self.read_environment() - self.read_cli_args() - - # Verify credentials were set - if not hasattr(self, 'api_token'): - sys.stderr.write('''Could not find values for DigitalOcean api_token. -They must be specified via either ini file, command line argument (--api-token), -or environment variables (DO_API_TOKEN)\n''') - sys.exit(-1) - - # env command, show DigitalOcean credentials - if self.args.env: - print("DO_API_TOKEN=%s" % self.api_token) - sys.exit(0) - - # Manage cache - self.cache_filename = self.cache_path + "/ansible-digital_ocean.cache" - self.cache_refreshed = False - - if self.is_cache_valid(): - self.load_from_cache() - if len(self.data) == 0: - if self.args.force_cache: - sys.stderr.write('''Cache is empty and --force-cache was specified\n''') - sys.exit(-1) - - self.manager = DoManager(None, self.api_token, api_version=2) - - # Pick the json_data to print based on the CLI command - if self.args.droplets: - self.load_from_digital_ocean('droplets') - json_data = {'droplets': self.data['droplets']} - elif self.args.regions: - self.load_from_digital_ocean('regions') - json_data = {'regions': self.data['regions']} - elif self.args.images: - self.load_from_digital_ocean('images') - json_data = {'images': self.data['images']} - elif self.args.sizes: - self.load_from_digital_ocean('sizes') - json_data = {'sizes': self.data['sizes']} - elif self.args.ssh_keys: - self.load_from_digital_ocean('ssh_keys') - json_data = {'ssh_keys': self.data['ssh_keys']} - elif self.args.domains: - self.load_from_digital_ocean('domains') - json_data = {'domains': self.data['domains']} - elif self.args.all: - self.load_from_digital_ocean() - json_data = self.data - elif self.args.host: - json_data = self.load_droplet_variables_for_host() - else: # '--list' this is last to make it default - self.load_from_digital_ocean('droplets') - self.build_inventory() - json_data = self.inventory - - if self.cache_refreshed: - self.write_to_cache() - - if self.args.pretty: - print(json.dumps(json_data, sort_keys=True, indent=2)) - else: - print(json.dumps(json_data)) - # That's all she wrote... - - ########################################################################### - # Script configuration - ########################################################################### - - def read_settings(self): - ''' Reads the settings from the digital_ocean.ini file ''' - config = ConfigParser.SafeConfigParser() - config.read(os.path.dirname(os.path.realpath(__file__)) + '/digital_ocean.ini') - - # Credentials - if config.has_option('digital_ocean', 'api_token'): - self.api_token = config.get('digital_ocean', 'api_token') - - # Cache related - if config.has_option('digital_ocean', 'cache_path'): - self.cache_path = config.get('digital_ocean', 'cache_path') - if config.has_option('digital_ocean', 'cache_max_age'): - self.cache_max_age = config.getint('digital_ocean', 'cache_max_age') - - # Private IP Address - if config.has_option('digital_ocean', 'use_private_network'): - self.use_private_network = config.getboolean('digital_ocean', 'use_private_network') - - # Group variables - if config.has_option('digital_ocean', 'group_variables'): - self.group_variables = ast.literal_eval(config.get('digital_ocean', 'group_variables')) - - def read_environment(self): - ''' Reads the settings from environment variables ''' - # Setup credentials - if os.getenv("DO_API_TOKEN"): - self.api_token = os.getenv("DO_API_TOKEN") - if os.getenv("DO_API_KEY"): - self.api_token = os.getenv("DO_API_KEY") - - def read_cli_args(self): - ''' Command line argument processing ''' - parser = argparse.ArgumentParser(description='Produce an Ansible Inventory file based on DigitalOcean credentials') - - parser.add_argument('--list', action='store_true', help='List all active Droplets as Ansible inventory (default: True)') - parser.add_argument('--host', action='store', help='Get all Ansible inventory variables about a specific Droplet') - - parser.add_argument('--all', action='store_true', help='List all DigitalOcean information as JSON') - parser.add_argument('--droplets', '-d', action='store_true', help='List Droplets as JSON') - parser.add_argument('--regions', action='store_true', help='List Regions as JSON') - parser.add_argument('--images', action='store_true', help='List Images as JSON') - parser.add_argument('--sizes', action='store_true', help='List Sizes as JSON') - parser.add_argument('--ssh-keys', action='store_true', help='List SSH keys as JSON') - parser.add_argument('--domains', action='store_true', help='List Domains as JSON') - - parser.add_argument('--pretty', '-p', action='store_true', help='Pretty-print results') - - parser.add_argument('--cache-path', action='store', help='Path to the cache files (default: .)') - parser.add_argument('--cache-max_age', action='store', help='Maximum age of the cached items (default: 0)') - parser.add_argument('--force-cache', action='store_true', default=False, help='Only use data from the cache') - parser.add_argument('--refresh-cache', '-r', action='store_true', default=False, - help='Force refresh of cache by making API requests to DigitalOcean (default: False - use cache files)') - - parser.add_argument('--env', '-e', action='store_true', help='Display DO_API_TOKEN') - parser.add_argument('--api-token', '-a', action='store', help='DigitalOcean API Token') - - self.args = parser.parse_args() - - if self.args.api_token: - self.api_token = self.args.api_token - - # Make --list default if none of the other commands are specified - if (not self.args.droplets and not self.args.regions and - not self.args.images and not self.args.sizes and - not self.args.ssh_keys and not self.args.domains and - not self.args.all and not self.args.host): - self.args.list = True - - ########################################################################### - # Data Management - ########################################################################### - - def load_from_digital_ocean(self, resource=None): - '''Get JSON from DigitalOcean API''' - if self.args.force_cache and os.path.isfile(self.cache_filename): - return - # We always get fresh droplets - if self.is_cache_valid() and not (resource == 'droplets' or resource is None): - return - if self.args.refresh_cache: - resource = None - - if resource == 'droplets' or resource is None: - self.data['droplets'] = self.manager.all_active_droplets() - self.cache_refreshed = True - if resource == 'regions' or resource is None: - self.data['regions'] = self.manager.all_regions() - self.cache_refreshed = True - if resource == 'images' or resource is None: - self.data['images'] = self.manager.all_images(filter=None) - self.cache_refreshed = True - if resource == 'sizes' or resource is None: - self.data['sizes'] = self.manager.sizes() - self.cache_refreshed = True - if resource == 'ssh_keys' or resource is None: - self.data['ssh_keys'] = self.manager.all_ssh_keys() - self.cache_refreshed = True - if resource == 'domains' or resource is None: - self.data['domains'] = self.manager.all_domains() - self.cache_refreshed = True - - def build_inventory(self): - '''Build Ansible inventory of droplets''' - self.inventory = { - 'all': { - 'hosts': [], - 'vars': self.group_variables - }, - '_meta': {'hostvars': {}} - } - - # add all droplets by id and name - for droplet in self.data['droplets']: - # when using private_networking, the API reports the private one in "ip_address". - if 'private_networking' in droplet['features'] and not self.use_private_network: - for net in droplet['networks']['v4']: - if net['type'] == 'public': - dest = net['ip_address'] - else: - continue - else: - dest = droplet['ip_address'] - - self.inventory['all']['hosts'].append(dest) - - self.inventory[droplet['id']] = [dest] - self.inventory[droplet['name']] = [dest] - - # groups that are always present - for group in ('region_' + droplet['region']['slug'], - 'image_' + str(droplet['image']['id']), - 'size_' + droplet['size']['slug'], - 'distro_' + self.to_safe(droplet['image']['distribution']), - 'status_' + droplet['status']): - if group not in self.inventory: - self.inventory[group] = {'hosts': [], 'vars': {}} - self.inventory[group]['hosts'].append(dest) - - # groups that are not always present - for group in (droplet['image']['slug'], - droplet['image']['name']): - if group: - image = 'image_' + self.to_safe(group) - if image not in self.inventory: - self.inventory[image] = {'hosts': [], 'vars': {}} - self.inventory[image]['hosts'].append(dest) - - if droplet['tags']: - for tag in droplet['tags']: - if tag not in self.inventory: - self.inventory[tag] = {'hosts': [], 'vars': {}} - self.inventory[tag]['hosts'].append(dest) - - # hostvars - info = self.do_namespace(droplet) - self.inventory['_meta']['hostvars'][dest] = info - - def load_droplet_variables_for_host(self): - '''Generate a JSON response to a --host call''' - host = int(self.args.host) - droplet = self.manager.show_droplet(host) - info = self.do_namespace(droplet) - return {'droplet': info} - - ########################################################################### - # Cache Management - ########################################################################### - - def is_cache_valid(self): - ''' Determines if the cache files have expired, or if it is still valid ''' - if os.path.isfile(self.cache_filename): - mod_time = os.path.getmtime(self.cache_filename) - current_time = time() - if (mod_time + self.cache_max_age) > current_time: - return True - return False - - def load_from_cache(self): - ''' Reads the data from the cache file and assigns it to member variables as Python Objects''' - try: - cache = open(self.cache_filename, 'r') - json_data = cache.read() - cache.close() - data = json.loads(json_data) - except IOError: - data = {'data': {}, 'inventory': {}} - - self.data = data['data'] - self.inventory = data['inventory'] - - def write_to_cache(self): - ''' Writes data in JSON format to a file ''' - data = {'data': self.data, 'inventory': self.inventory} - json_data = json.dumps(data, sort_keys=True, indent=2) - - cache = open(self.cache_filename, 'w') - cache.write(json_data) - cache.close() - - ########################################################################### - # Utilities - ########################################################################### - - def push(self, my_dict, key, element): - ''' Pushed an element onto an array that may not have been defined in the dict ''' - if key in my_dict: - my_dict[key].append(element) - else: - my_dict[key] = [element] - - def to_safe(self, word): - ''' Converts 'bad' characters in a string to underscores so they can be used as Ansible groups ''' - return re.sub("[^A-Za-z0-9\-\.]", "_", word) - - def do_namespace(self, data): - ''' Returns a copy of the dictionary with all the keys put in a 'do_' namespace ''' - info = {} - for k, v in data.items(): - info['do_' + k] = v - return info - - -########################################################################### -# Run the script -DigitalOceanInventory() diff --git a/contrib/testnets/remote/ansible/inventory/ec2.ini b/contrib/testnets/remote/ansible/inventory/ec2.ini deleted file mode 100644 index e11a69cc1..000000000 --- a/contrib/testnets/remote/ansible/inventory/ec2.ini +++ /dev/null @@ -1,209 +0,0 @@ -# Ansible EC2 external inventory script settings -# - -[ec2] - -# to talk to a private eucalyptus instance uncomment these lines -# and edit edit eucalyptus_host to be the host name of your cloud controller -#eucalyptus = True -#eucalyptus_host = clc.cloud.domain.org - -# AWS regions to make calls to. Set this to 'all' to make request to all regions -# in AWS and merge the results together. Alternatively, set this to a comma -# separated list of regions. E.g. 'us-east-1,us-west-1,us-west-2' and do not -# provide the 'regions_exclude' option. If this is set to 'auto', AWS_REGION or -# AWS_DEFAULT_REGION environment variable will be read to determine the region. -regions = all -regions_exclude = us-gov-west-1, cn-north-1 - -# When generating inventory, Ansible needs to know how to address a server. -# Each EC2 instance has a lot of variables associated with it. Here is the list: -# http://docs.pythonboto.org/en/latest/ref/ec2.html#module-boto.ec2.instance -# Below are 2 variables that are used as the address of a server: -# - destination_variable -# - vpc_destination_variable - -# This is the normal destination variable to use. If you are running Ansible -# from outside EC2, then 'public_dns_name' makes the most sense. If you are -# running Ansible from within EC2, then perhaps you want to use the internal -# address, and should set this to 'private_dns_name'. The key of an EC2 tag -# may optionally be used; however the boto instance variables hold precedence -# in the event of a collision. -destination_variable = public_dns_name - -# This allows you to override the inventory_name with an ec2 variable, instead -# of using the destination_variable above. Addressing (aka ansible_ssh_host) -# will still use destination_variable. Tags should be written as 'tag_TAGNAME'. -#hostname_variable = tag_Name - -# For server inside a VPC, using DNS names may not make sense. When an instance -# has 'subnet_id' set, this variable is used. If the subnet is public, setting -# this to 'ip_address' will return the public IP address. For instances in a -# private subnet, this should be set to 'private_ip_address', and Ansible must -# be run from within EC2. The key of an EC2 tag may optionally be used; however -# the boto instance variables hold precedence in the event of a collision. -# WARNING: - instances that are in the private vpc, _without_ public ip address -# will not be listed in the inventory until You set: -# vpc_destination_variable = private_ip_address -vpc_destination_variable = ip_address - -# The following two settings allow flexible ansible host naming based on a -# python format string and a comma-separated list of ec2 tags. Note that: -# -# 1) If the tags referenced are not present for some instances, empty strings -# will be substituted in the format string. -# 2) This overrides both destination_variable and vpc_destination_variable. -# -#destination_format = {0}.{1}.example.com -#destination_format_tags = Name,environment - -# To tag instances on EC2 with the resource records that point to them from -# Route53, set 'route53' to True. -route53 = False - -# To use Route53 records as the inventory hostnames, uncomment and set -# to equal the domain name you wish to use. You must also have 'route53' (above) -# set to True. -# route53_hostnames = .example.com - -# To exclude RDS instances from the inventory, uncomment and set to False. -#rds = False - -# To exclude ElastiCache instances from the inventory, uncomment and set to False. -#elasticache = False - -# Additionally, you can specify the list of zones to exclude looking up in -# 'route53_excluded_zones' as a comma-separated list. -# route53_excluded_zones = samplezone1.com, samplezone2.com - -# By default, only EC2 instances in the 'running' state are returned. Set -# 'all_instances' to True to return all instances regardless of state. -all_instances = False - -# By default, only EC2 instances in the 'running' state are returned. Specify -# EC2 instance states to return as a comma-separated list. This -# option is overridden when 'all_instances' is True. -# instance_states = pending, running, shutting-down, terminated, stopping, stopped - -# By default, only RDS instances in the 'available' state are returned. Set -# 'all_rds_instances' to True return all RDS instances regardless of state. -all_rds_instances = False - -# Include RDS cluster information (Aurora etc.) -include_rds_clusters = False - -# By default, only ElastiCache clusters and nodes in the 'available' state -# are returned. Set 'all_elasticache_clusters' and/or 'all_elastic_nodes' -# to True return all ElastiCache clusters and nodes, regardless of state. -# -# Note that all_elasticache_nodes only applies to listed clusters. That means -# if you set all_elastic_clusters to false, no node will be return from -# unavailable clusters, regardless of the state and to what you set for -# all_elasticache_nodes. -all_elasticache_replication_groups = False -all_elasticache_clusters = False -all_elasticache_nodes = False - -# API calls to EC2 are slow. For this reason, we cache the results of an API -# call. Set this to the path you want cache files to be written to. Two files -# will be written to this directory: -# - ansible-ec2.cache -# - ansible-ec2.index -cache_path = ~/.ansible/tmp - -# The number of seconds a cache file is considered valid. After this many -# seconds, a new API call will be made, and the cache file will be updated. -# To disable the cache, set this value to 0 -cache_max_age = 300 - -# Organize groups into a nested/hierarchy instead of a flat namespace. -nested_groups = False - -# Replace - tags when creating groups to avoid issues with ansible -replace_dash_in_groups = True - -# If set to true, any tag of the form "a,b,c" is expanded into a list -# and the results are used to create additional tag_* inventory groups. -expand_csv_tags = False - -# The EC2 inventory output can become very large. To manage its size, -# configure which groups should be created. -group_by_instance_id = True -group_by_region = True -group_by_availability_zone = True -group_by_aws_account = False -group_by_ami_id = True -group_by_instance_type = True -group_by_instance_state = False -group_by_key_pair = True -group_by_vpc_id = True -group_by_security_group = True -group_by_tag_keys = True -group_by_tag_none = True -group_by_route53_names = True -group_by_rds_engine = True -group_by_rds_parameter_group = True -group_by_elasticache_engine = True -group_by_elasticache_cluster = True -group_by_elasticache_parameter_group = True -group_by_elasticache_replication_group = True - -# If you only want to include hosts that match a certain regular expression -# pattern_include = staging-* - -# If you want to exclude any hosts that match a certain regular expression -# pattern_exclude = staging-* - -# Instance filters can be used to control which instances are retrieved for -# inventory. For the full list of possible filters, please read the EC2 API -# docs: http://docs.aws.amazon.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeInstances.html#query-DescribeInstances-filters -# Filters are key/value pairs separated by '=', to list multiple filters use -# a list separated by commas. See examples below. - -# If you want to apply multiple filters simultaneously, set stack_filters to -# True. Default behaviour is to combine the results of all filters. Stacking -# allows the use of multiple conditions to filter down, for example by -# environment and type of host. -stack_filters = False - -# Retrieve only instances with (key=value) env=staging tag -# instance_filters = tag:env=staging - -# Retrieve only instances with role=webservers OR role=dbservers tag -# instance_filters = tag:role=webservers,tag:role=dbservers - -# Retrieve only t1.micro instances OR instances with tag env=staging -# instance_filters = instance-type=t1.micro,tag:env=staging - -# You can use wildcards in filter values also. Below will list instances which -# tag Name value matches webservers1* -# (ex. webservers15, webservers1a, webservers123 etc) -# instance_filters = tag:Name=webservers1* - -# An IAM role can be assumed, so all requests are run as that role. -# This can be useful for connecting across different accounts, or to limit user -# access -# iam_role = role-arn - -# A boto configuration profile may be used to separate out credentials -# see http://boto.readthedocs.org/en/latest/boto_config_tut.html -# boto_profile = some-boto-profile-name - - -[credentials] - -# The AWS credentials can optionally be specified here. Credentials specified -# here are ignored if the environment variable AWS_ACCESS_KEY_ID or -# AWS_PROFILE is set, or if the boto_profile property above is set. -# -# Supplying AWS credentials here is not recommended, as it introduces -# non-trivial security concerns. When going down this route, please make sure -# to set access permissions for this file correctly, e.g. handle it the same -# way as you would a private SSH key. -# -# Unlike the boto and AWS configure files, this section does not support -# profiles. -# -# aws_access_key_id = AXXXXXXXXXXXXXX -# aws_secret_access_key = XXXXXXXXXXXXXXXXXXX -# aws_security_token = XXXXXXXXXXXXXXXXXXXXXXXXXXXX diff --git a/contrib/testnets/remote/ansible/inventory/ec2.py b/contrib/testnets/remote/ansible/inventory/ec2.py deleted file mode 100755 index 9614c5fe9..000000000 --- a/contrib/testnets/remote/ansible/inventory/ec2.py +++ /dev/null @@ -1,1595 +0,0 @@ -#!/usr/bin/env python - -''' -EC2 external inventory script -================================= - -Generates inventory that Ansible can understand by making API request to -AWS EC2 using the Boto library. - -NOTE: This script assumes Ansible is being executed where the environment -variables needed for Boto have already been set: - export AWS_ACCESS_KEY_ID='AK123' - export AWS_SECRET_ACCESS_KEY='abc123' - -optional region environement variable if region is 'auto' - -This script also assumes there is an ec2.ini file alongside it. To specify a -different path to ec2.ini, define the EC2_INI_PATH environment variable: - - export EC2_INI_PATH=/path/to/my_ec2.ini - -If you're using eucalyptus you need to set the above variables and -you need to define: - - export EC2_URL=http://hostname_of_your_cc:port/services/Eucalyptus - -If you're using boto profiles (requires boto>=2.24.0) you can choose a profile -using the --boto-profile command line argument (e.g. ec2.py --boto-profile prod) or using -the AWS_PROFILE variable: - - AWS_PROFILE=prod ansible-playbook -i ec2.py myplaybook.yml - -For more details, see: http://docs.pythonboto.org/en/latest/boto_config_tut.html - -When run against a specific host, this script returns the following variables: - - ec2_ami_launch_index - - ec2_architecture - - ec2_association - - ec2_attachTime - - ec2_attachment - - ec2_attachmentId - - ec2_block_devices - - ec2_client_token - - ec2_deleteOnTermination - - ec2_description - - ec2_deviceIndex - - ec2_dns_name - - ec2_eventsSet - - ec2_group_name - - ec2_hypervisor - - ec2_id - - ec2_image_id - - ec2_instanceState - - ec2_instance_type - - ec2_ipOwnerId - - ec2_ip_address - - ec2_item - - ec2_kernel - - ec2_key_name - - ec2_launch_time - - ec2_monitored - - ec2_monitoring - - ec2_networkInterfaceId - - ec2_ownerId - - ec2_persistent - - ec2_placement - - ec2_platform - - ec2_previous_state - - ec2_private_dns_name - - ec2_private_ip_address - - ec2_publicIp - - ec2_public_dns_name - - ec2_ramdisk - - ec2_reason - - ec2_region - - ec2_requester_id - - ec2_root_device_name - - ec2_root_device_type - - ec2_security_group_ids - - ec2_security_group_names - - ec2_shutdown_state - - ec2_sourceDestCheck - - ec2_spot_instance_request_id - - ec2_state - - ec2_state_code - - ec2_state_reason - - ec2_status - - ec2_subnet_id - - ec2_tenancy - - ec2_virtualization_type - - ec2_vpc_id - -These variables are pulled out of a boto.ec2.instance object. There is a lack of -consistency with variable spellings (camelCase and underscores) since this -just loops through all variables the object exposes. It is preferred to use the -ones with underscores when multiple exist. - -In addition, if an instance has AWS Tags associated with it, each tag is a new -variable named: - - ec2_tag_[Key] = [Value] - -Security groups are comma-separated in 'ec2_security_group_ids' and -'ec2_security_group_names'. -''' - -# (c) 2012, Peter Sankauskas -# -# This file is part of Ansible, -# -# Ansible is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Ansible is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Ansible. If not, see . - -###################################################################### - -import sys -import os -import argparse -import re -from time import time -import boto -from boto import ec2 -from boto import rds -from boto import elasticache -from boto import route53 -from boto import sts -import six - -from ansible.module_utils import ec2 as ec2_utils - -HAS_BOTO3 = False -try: - import boto3 - HAS_BOTO3 = True -except ImportError: - pass - -from six.moves import configparser -from collections import defaultdict - -try: - import json -except ImportError: - import simplejson as json - - -class Ec2Inventory(object): - - def _empty_inventory(self): - return {"_meta": {"hostvars": {}}} - - def __init__(self): - ''' Main execution path ''' - - # Inventory grouped by instance IDs, tags, security groups, regions, - # and availability zones - self.inventory = self._empty_inventory() - - self.aws_account_id = None - - # Index of hostname (address) to instance ID - self.index = {} - - # Boto profile to use (if any) - self.boto_profile = None - - # AWS credentials. - self.credentials = {} - - # Read settings and parse CLI arguments - self.parse_cli_args() - self.read_settings() - - # Make sure that profile_name is not passed at all if not set - # as pre 2.24 boto will fall over otherwise - if self.boto_profile: - if not hasattr(boto.ec2.EC2Connection, 'profile_name'): - self.fail_with_error("boto version must be >= 2.24 to use profile") - - # Cache - if self.args.refresh_cache: - self.do_api_calls_update_cache() - elif not self.is_cache_valid(): - self.do_api_calls_update_cache() - - # Data to print - if self.args.host: - data_to_print = self.get_host_info() - - elif self.args.list: - # Display list of instances for inventory - if self.inventory == self._empty_inventory(): - data_to_print = self.get_inventory_from_cache() - else: - data_to_print = self.json_format_dict(self.inventory, True) - - print(data_to_print) - - def is_cache_valid(self): - ''' Determines if the cache files have expired, or if it is still valid ''' - - if os.path.isfile(self.cache_path_cache): - mod_time = os.path.getmtime(self.cache_path_cache) - current_time = time() - if (mod_time + self.cache_max_age) > current_time: - if os.path.isfile(self.cache_path_index): - return True - - return False - - def read_settings(self): - ''' Reads the settings from the ec2.ini file ''' - - scriptbasename = __file__ - scriptbasename = os.path.basename(scriptbasename) - scriptbasename = scriptbasename.replace('.py', '') - - defaults = { - 'ec2': { - 'ini_path': os.path.join(os.path.dirname(__file__), '%s.ini' % scriptbasename) - } - } - - if six.PY3: - config = configparser.ConfigParser() - else: - config = configparser.SafeConfigParser() - ec2_ini_path = os.environ.get('EC2_INI_PATH', defaults['ec2']['ini_path']) - ec2_ini_path = os.path.expanduser(os.path.expandvars(ec2_ini_path)) - config.read(ec2_ini_path) - - # is eucalyptus? - self.eucalyptus_host = None - self.eucalyptus = False - if config.has_option('ec2', 'eucalyptus'): - self.eucalyptus = config.getboolean('ec2', 'eucalyptus') - if self.eucalyptus and config.has_option('ec2', 'eucalyptus_host'): - self.eucalyptus_host = config.get('ec2', 'eucalyptus_host') - - # Regions - self.regions = [] - configRegions = config.get('ec2', 'regions') - if (configRegions == 'all'): - if self.eucalyptus_host: - self.regions.append(boto.connect_euca(host=self.eucalyptus_host).region.name, **self.credentials) - else: - configRegions_exclude = config.get('ec2', 'regions_exclude') - for regionInfo in ec2.regions(): - if regionInfo.name not in configRegions_exclude: - self.regions.append(regionInfo.name) - else: - self.regions = configRegions.split(",") - if 'auto' in self.regions: - env_region = os.environ.get('AWS_REGION') - if env_region is None: - env_region = os.environ.get('AWS_DEFAULT_REGION') - self.regions = [env_region] - - # Destination addresses - self.destination_variable = config.get('ec2', 'destination_variable') - self.vpc_destination_variable = config.get('ec2', 'vpc_destination_variable') - - if config.has_option('ec2', 'hostname_variable'): - self.hostname_variable = config.get('ec2', 'hostname_variable') - else: - self.hostname_variable = None - - if config.has_option('ec2', 'destination_format') and \ - config.has_option('ec2', 'destination_format_tags'): - self.destination_format = config.get('ec2', 'destination_format') - self.destination_format_tags = config.get('ec2', 'destination_format_tags').split(',') - else: - self.destination_format = None - self.destination_format_tags = None - - # Route53 - self.route53_enabled = config.getboolean('ec2', 'route53') - if config.has_option('ec2', 'route53_hostnames'): - self.route53_hostnames = config.get('ec2', 'route53_hostnames') - else: - self.route53_hostnames = None - self.route53_excluded_zones = [] - if config.has_option('ec2', 'route53_excluded_zones'): - self.route53_excluded_zones.extend( - config.get('ec2', 'route53_excluded_zones', '').split(',')) - - # Include RDS instances? - self.rds_enabled = True - if config.has_option('ec2', 'rds'): - self.rds_enabled = config.getboolean('ec2', 'rds') - - # Include RDS cluster instances? - if config.has_option('ec2', 'include_rds_clusters'): - self.include_rds_clusters = config.getboolean('ec2', 'include_rds_clusters') - else: - self.include_rds_clusters = False - - # Include ElastiCache instances? - self.elasticache_enabled = True - if config.has_option('ec2', 'elasticache'): - self.elasticache_enabled = config.getboolean('ec2', 'elasticache') - - # Return all EC2 instances? - if config.has_option('ec2', 'all_instances'): - self.all_instances = config.getboolean('ec2', 'all_instances') - else: - self.all_instances = False - - # Instance states to be gathered in inventory. Default is 'running'. - # Setting 'all_instances' to 'yes' overrides this option. - ec2_valid_instance_states = [ - 'pending', - 'running', - 'shutting-down', - 'terminated', - 'stopping', - 'stopped' - ] - self.ec2_instance_states = [] - if self.all_instances: - self.ec2_instance_states = ec2_valid_instance_states - elif config.has_option('ec2', 'instance_states'): - for instance_state in config.get('ec2', 'instance_states').split(','): - instance_state = instance_state.strip() - if instance_state not in ec2_valid_instance_states: - continue - self.ec2_instance_states.append(instance_state) - else: - self.ec2_instance_states = ['running'] - - # Return all RDS instances? (if RDS is enabled) - if config.has_option('ec2', 'all_rds_instances') and self.rds_enabled: - self.all_rds_instances = config.getboolean('ec2', 'all_rds_instances') - else: - self.all_rds_instances = False - - # Return all ElastiCache replication groups? (if ElastiCache is enabled) - if config.has_option('ec2', 'all_elasticache_replication_groups') and self.elasticache_enabled: - self.all_elasticache_replication_groups = config.getboolean('ec2', 'all_elasticache_replication_groups') - else: - self.all_elasticache_replication_groups = False - - # Return all ElastiCache clusters? (if ElastiCache is enabled) - if config.has_option('ec2', 'all_elasticache_clusters') and self.elasticache_enabled: - self.all_elasticache_clusters = config.getboolean('ec2', 'all_elasticache_clusters') - else: - self.all_elasticache_clusters = False - - # Return all ElastiCache nodes? (if ElastiCache is enabled) - if config.has_option('ec2', 'all_elasticache_nodes') and self.elasticache_enabled: - self.all_elasticache_nodes = config.getboolean('ec2', 'all_elasticache_nodes') - else: - self.all_elasticache_nodes = False - - # boto configuration profile (prefer CLI argument then environment variables then config file) - self.boto_profile = self.args.boto_profile or os.environ.get('AWS_PROFILE') - if config.has_option('ec2', 'boto_profile') and not self.boto_profile: - self.boto_profile = config.get('ec2', 'boto_profile') - - # AWS credentials (prefer environment variables) - if not (self.boto_profile or os.environ.get('AWS_ACCESS_KEY_ID') or - os.environ.get('AWS_PROFILE')): - if config.has_option('credentials', 'aws_access_key_id'): - aws_access_key_id = config.get('credentials', 'aws_access_key_id') - else: - aws_access_key_id = None - if config.has_option('credentials', 'aws_secret_access_key'): - aws_secret_access_key = config.get('credentials', 'aws_secret_access_key') - else: - aws_secret_access_key = None - if config.has_option('credentials', 'aws_security_token'): - aws_security_token = config.get('credentials', 'aws_security_token') - else: - aws_security_token = None - if aws_access_key_id: - self.credentials = { - 'aws_access_key_id': aws_access_key_id, - 'aws_secret_access_key': aws_secret_access_key - } - if aws_security_token: - self.credentials['security_token'] = aws_security_token - - # Cache related - cache_dir = os.path.expanduser(config.get('ec2', 'cache_path')) - if self.boto_profile: - cache_dir = os.path.join(cache_dir, 'profile_' + self.boto_profile) - if not os.path.exists(cache_dir): - os.makedirs(cache_dir) - - cache_name = 'ansible-ec2' - cache_id = self.boto_profile or os.environ.get('AWS_ACCESS_KEY_ID', self.credentials.get('aws_access_key_id')) - if cache_id: - cache_name = '%s-%s' % (cache_name, cache_id) - self.cache_path_cache = os.path.join(cache_dir, "%s.cache" % cache_name) - self.cache_path_index = os.path.join(cache_dir, "%s.index" % cache_name) - self.cache_max_age = config.getint('ec2', 'cache_max_age') - - if config.has_option('ec2', 'expand_csv_tags'): - self.expand_csv_tags = config.getboolean('ec2', 'expand_csv_tags') - else: - self.expand_csv_tags = False - - # Configure nested groups instead of flat namespace. - if config.has_option('ec2', 'nested_groups'): - self.nested_groups = config.getboolean('ec2', 'nested_groups') - else: - self.nested_groups = False - - # Replace dash or not in group names - if config.has_option('ec2', 'replace_dash_in_groups'): - self.replace_dash_in_groups = config.getboolean('ec2', 'replace_dash_in_groups') - else: - self.replace_dash_in_groups = True - - # IAM role to assume for connection - if config.has_option('ec2', 'iam_role'): - self.iam_role = config.get('ec2', 'iam_role') - else: - self.iam_role = None - - # Configure which groups should be created. - group_by_options = [ - 'group_by_instance_id', - 'group_by_region', - 'group_by_availability_zone', - 'group_by_ami_id', - 'group_by_instance_type', - 'group_by_instance_state', - 'group_by_key_pair', - 'group_by_vpc_id', - 'group_by_security_group', - 'group_by_tag_keys', - 'group_by_tag_none', - 'group_by_route53_names', - 'group_by_rds_engine', - 'group_by_rds_parameter_group', - 'group_by_elasticache_engine', - 'group_by_elasticache_cluster', - 'group_by_elasticache_parameter_group', - 'group_by_elasticache_replication_group', - 'group_by_aws_account', - ] - for option in group_by_options: - if config.has_option('ec2', option): - setattr(self, option, config.getboolean('ec2', option)) - else: - setattr(self, option, True) - - # Do we need to just include hosts that match a pattern? - try: - pattern_include = config.get('ec2', 'pattern_include') - if pattern_include and len(pattern_include) > 0: - self.pattern_include = re.compile(pattern_include) - else: - self.pattern_include = None - except configparser.NoOptionError: - self.pattern_include = None - - # Do we need to exclude hosts that match a pattern? - try: - pattern_exclude = config.get('ec2', 'pattern_exclude') - if pattern_exclude and len(pattern_exclude) > 0: - self.pattern_exclude = re.compile(pattern_exclude) - else: - self.pattern_exclude = None - except configparser.NoOptionError: - self.pattern_exclude = None - - # Do we want to stack multiple filters? - if config.has_option('ec2', 'stack_filters'): - self.stack_filters = config.getboolean('ec2', 'stack_filters') - else: - self.stack_filters = False - - # Instance filters (see boto and EC2 API docs). Ignore invalid filters. - self.ec2_instance_filters = defaultdict(list) - if config.has_option('ec2', 'instance_filters'): - - filters = [f for f in config.get('ec2', 'instance_filters').split(',') if f] - - for instance_filter in filters: - instance_filter = instance_filter.strip() - if not instance_filter or '=' not in instance_filter: - continue - filter_key, filter_value = [x.strip() for x in instance_filter.split('=', 1)] - if not filter_key: - continue - self.ec2_instance_filters[filter_key].append(filter_value) - - def parse_cli_args(self): - ''' Command line argument processing ''' - - parser = argparse.ArgumentParser(description='Produce an Ansible Inventory file based on EC2') - parser.add_argument('--list', action='store_true', default=True, - help='List instances (default: True)') - parser.add_argument('--host', action='store', - help='Get all the variables about a specific instance') - parser.add_argument('--refresh-cache', action='store_true', default=False, - help='Force refresh of cache by making API requests to EC2 (default: False - use cache files)') - parser.add_argument('--profile', '--boto-profile', action='store', dest='boto_profile', - help='Use boto profile for connections to EC2') - self.args = parser.parse_args() - - def do_api_calls_update_cache(self): - ''' Do API calls to each region, and save data in cache files ''' - - if self.route53_enabled: - self.get_route53_records() - - for region in self.regions: - self.get_instances_by_region(region) - if self.rds_enabled: - self.get_rds_instances_by_region(region) - if self.elasticache_enabled: - self.get_elasticache_clusters_by_region(region) - self.get_elasticache_replication_groups_by_region(region) - if self.include_rds_clusters: - self.include_rds_clusters_by_region(region) - - self.write_to_cache(self.inventory, self.cache_path_cache) - self.write_to_cache(self.index, self.cache_path_index) - - def connect(self, region): - ''' create connection to api server''' - if self.eucalyptus: - conn = boto.connect_euca(host=self.eucalyptus_host, **self.credentials) - conn.APIVersion = '2010-08-31' - else: - conn = self.connect_to_aws(ec2, region) - return conn - - def boto_fix_security_token_in_profile(self, connect_args): - ''' monkey patch for boto issue boto/boto#2100 ''' - profile = 'profile ' + self.boto_profile - if boto.config.has_option(profile, 'aws_security_token'): - connect_args['security_token'] = boto.config.get(profile, 'aws_security_token') - return connect_args - - def connect_to_aws(self, module, region): - connect_args = self.credentials - - # only pass the profile name if it's set (as it is not supported by older boto versions) - if self.boto_profile: - connect_args['profile_name'] = self.boto_profile - self.boto_fix_security_token_in_profile(connect_args) - - if self.iam_role: - sts_conn = sts.connect_to_region(region, **connect_args) - role = sts_conn.assume_role(self.iam_role, 'ansible_dynamic_inventory') - connect_args['aws_access_key_id'] = role.credentials.access_key - connect_args['aws_secret_access_key'] = role.credentials.secret_key - connect_args['security_token'] = role.credentials.session_token - - conn = module.connect_to_region(region, **connect_args) - # connect_to_region will fail "silently" by returning None if the region name is wrong or not supported - if conn is None: - self.fail_with_error("region name: %s likely not supported, or AWS is down. connection to region failed." % region) - return conn - - def get_instances_by_region(self, region): - ''' Makes an AWS EC2 API call to the list of instances in a particular - region ''' - - try: - conn = self.connect(region) - reservations = [] - if self.ec2_instance_filters: - if self.stack_filters: - filters_dict = {} - for filter_key, filter_values in self.ec2_instance_filters.items(): - filters_dict[filter_key] = filter_values - reservations.extend(conn.get_all_instances(filters=filters_dict)) - else: - for filter_key, filter_values in self.ec2_instance_filters.items(): - reservations.extend(conn.get_all_instances(filters={filter_key: filter_values})) - else: - reservations = conn.get_all_instances() - - # Pull the tags back in a second step - # AWS are on record as saying that the tags fetched in the first `get_all_instances` request are not - # reliable and may be missing, and the only way to guarantee they are there is by calling `get_all_tags` - instance_ids = [] - for reservation in reservations: - instance_ids.extend([instance.id for instance in reservation.instances]) - - max_filter_value = 199 - tags = [] - for i in range(0, len(instance_ids), max_filter_value): - tags.extend(conn.get_all_tags(filters={'resource-type': 'instance', 'resource-id': instance_ids[i:i + max_filter_value]})) - - tags_by_instance_id = defaultdict(dict) - for tag in tags: - tags_by_instance_id[tag.res_id][tag.name] = tag.value - - if (not self.aws_account_id) and reservations: - self.aws_account_id = reservations[0].owner_id - - for reservation in reservations: - for instance in reservation.instances: - instance.tags = tags_by_instance_id[instance.id] - self.add_instance(instance, region) - - except boto.exception.BotoServerError as e: - if e.error_code == 'AuthFailure': - error = self.get_auth_error_message() - else: - backend = 'Eucalyptus' if self.eucalyptus else 'AWS' - error = "Error connecting to %s backend.\n%s" % (backend, e.message) - self.fail_with_error(error, 'getting EC2 instances') - - def get_rds_instances_by_region(self, region): - ''' Makes an AWS API call to the list of RDS instances in a particular - region ''' - - if not HAS_BOTO3: - self.fail_with_error("Working with RDS instances requires boto3 - please install boto3 and try again", - "getting RDS instances") - - client = ec2_utils.boto3_inventory_conn('client', 'rds', region, **self.credentials) - db_instances = client.describe_db_instances() - - try: - conn = self.connect_to_aws(rds, region) - if conn: - marker = None - while True: - instances = conn.get_all_dbinstances(marker=marker) - marker = instances.marker - for index, instance in enumerate(instances): - # Add tags to instances. - instance.arn = db_instances['DBInstances'][index]['DBInstanceArn'] - tags = client.list_tags_for_resource(ResourceName=instance.arn)['TagList'] - instance.tags = {} - for tag in tags: - instance.tags[tag['Key']] = tag['Value'] - - self.add_rds_instance(instance, region) - if not marker: - break - except boto.exception.BotoServerError as e: - error = e.reason - - if e.error_code == 'AuthFailure': - error = self.get_auth_error_message() - if not e.reason == "Forbidden": - error = "Looks like AWS RDS is down:\n%s" % e.message - self.fail_with_error(error, 'getting RDS instances') - - def include_rds_clusters_by_region(self, region): - if not HAS_BOTO3: - self.fail_with_error("Working with RDS clusters requires boto3 - please install boto3 and try again", - "getting RDS clusters") - - client = ec2_utils.boto3_inventory_conn('client', 'rds', region, **self.credentials) - - marker, clusters = '', [] - while marker is not None: - resp = client.describe_db_clusters(Marker=marker) - clusters.extend(resp["DBClusters"]) - marker = resp.get('Marker', None) - - account_id = boto.connect_iam().get_user().arn.split(':')[4] - c_dict = {} - for c in clusters: - # remove these datetime objects as there is no serialisation to json - # currently in place and we don't need the data yet - if 'EarliestRestorableTime' in c: - del c['EarliestRestorableTime'] - if 'LatestRestorableTime' in c: - del c['LatestRestorableTime'] - - if self.ec2_instance_filters == {}: - matches_filter = True - else: - matches_filter = False - - try: - # arn:aws:rds:::: - tags = client.list_tags_for_resource( - ResourceName='arn:aws:rds:' + region + ':' + account_id + ':cluster:' + c['DBClusterIdentifier']) - c['Tags'] = tags['TagList'] - - if self.ec2_instance_filters: - for filter_key, filter_values in self.ec2_instance_filters.items(): - # get AWS tag key e.g. tag:env will be 'env' - tag_name = filter_key.split(":", 1)[1] - # Filter values is a list (if you put multiple values for the same tag name) - matches_filter = any(d['Key'] == tag_name and d['Value'] in filter_values for d in c['Tags']) - - if matches_filter: - # it matches a filter, so stop looking for further matches - break - - except Exception as e: - if e.message.find('DBInstanceNotFound') >= 0: - # AWS RDS bug (2016-01-06) means deletion does not fully complete and leave an 'empty' cluster. - # Ignore errors when trying to find tags for these - pass - - # ignore empty clusters caused by AWS bug - if len(c['DBClusterMembers']) == 0: - continue - elif matches_filter: - c_dict[c['DBClusterIdentifier']] = c - - self.inventory['db_clusters'] = c_dict - - def get_elasticache_clusters_by_region(self, region): - ''' Makes an AWS API call to the list of ElastiCache clusters (with - nodes' info) in a particular region.''' - - # ElastiCache boto module doesn't provide a get_all_intances method, - # that's why we need to call describe directly (it would be called by - # the shorthand method anyway...) - try: - conn = self.connect_to_aws(elasticache, region) - if conn: - # show_cache_node_info = True - # because we also want nodes' information - response = conn.describe_cache_clusters(None, None, None, True) - - except boto.exception.BotoServerError as e: - error = e.reason - - if e.error_code == 'AuthFailure': - error = self.get_auth_error_message() - if not e.reason == "Forbidden": - error = "Looks like AWS ElastiCache is down:\n%s" % e.message - self.fail_with_error(error, 'getting ElastiCache clusters') - - try: - # Boto also doesn't provide wrapper classes to CacheClusters or - # CacheNodes. Because of that we can't make use of the get_list - # method in the AWSQueryConnection. Let's do the work manually - clusters = response['DescribeCacheClustersResponse']['DescribeCacheClustersResult']['CacheClusters'] - - except KeyError as e: - error = "ElastiCache query to AWS failed (unexpected format)." - self.fail_with_error(error, 'getting ElastiCache clusters') - - for cluster in clusters: - self.add_elasticache_cluster(cluster, region) - - def get_elasticache_replication_groups_by_region(self, region): - ''' Makes an AWS API call to the list of ElastiCache replication groups - in a particular region.''' - - # ElastiCache boto module doesn't provide a get_all_intances method, - # that's why we need to call describe directly (it would be called by - # the shorthand method anyway...) - try: - conn = self.connect_to_aws(elasticache, region) - if conn: - response = conn.describe_replication_groups() - - except boto.exception.BotoServerError as e: - error = e.reason - - if e.error_code == 'AuthFailure': - error = self.get_auth_error_message() - if not e.reason == "Forbidden": - error = "Looks like AWS ElastiCache [Replication Groups] is down:\n%s" % e.message - self.fail_with_error(error, 'getting ElastiCache clusters') - - try: - # Boto also doesn't provide wrapper classes to ReplicationGroups - # Because of that we can't make use of the get_list method in the - # AWSQueryConnection. Let's do the work manually - replication_groups = response['DescribeReplicationGroupsResponse']['DescribeReplicationGroupsResult']['ReplicationGroups'] - - except KeyError as e: - error = "ElastiCache [Replication Groups] query to AWS failed (unexpected format)." - self.fail_with_error(error, 'getting ElastiCache clusters') - - for replication_group in replication_groups: - self.add_elasticache_replication_group(replication_group, region) - - def get_auth_error_message(self): - ''' create an informative error message if there is an issue authenticating''' - errors = ["Authentication error retrieving ec2 inventory."] - if None in [os.environ.get('AWS_ACCESS_KEY_ID'), os.environ.get('AWS_SECRET_ACCESS_KEY')]: - errors.append(' - No AWS_ACCESS_KEY_ID or AWS_SECRET_ACCESS_KEY environment vars found') - else: - errors.append(' - AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment vars found but may not be correct') - - boto_paths = ['/etc/boto.cfg', '~/.boto', '~/.aws/credentials'] - boto_config_found = list(p for p in boto_paths if os.path.isfile(os.path.expanduser(p))) - if len(boto_config_found) > 0: - errors.append(" - Boto configs found at '%s', but the credentials contained may not be correct" % ', '.join(boto_config_found)) - else: - errors.append(" - No Boto config found at any expected location '%s'" % ', '.join(boto_paths)) - - return '\n'.join(errors) - - def fail_with_error(self, err_msg, err_operation=None): - '''log an error to std err for ansible-playbook to consume and exit''' - if err_operation: - err_msg = 'ERROR: "{err_msg}", while: {err_operation}'.format( - err_msg=err_msg, err_operation=err_operation) - sys.stderr.write(err_msg) - sys.exit(1) - - def get_instance(self, region, instance_id): - conn = self.connect(region) - - reservations = conn.get_all_instances([instance_id]) - for reservation in reservations: - for instance in reservation.instances: - return instance - - def add_instance(self, instance, region): - ''' Adds an instance to the inventory and index, as long as it is - addressable ''' - - # Only return instances with desired instance states - if instance.state not in self.ec2_instance_states: - return - - # Select the best destination address - if self.destination_format and self.destination_format_tags: - dest = self.destination_format.format(*[getattr(instance, 'tags').get(tag, '') for tag in self.destination_format_tags]) - elif instance.subnet_id: - dest = getattr(instance, self.vpc_destination_variable, None) - if dest is None: - dest = getattr(instance, 'tags').get(self.vpc_destination_variable, None) - else: - dest = getattr(instance, self.destination_variable, None) - if dest is None: - dest = getattr(instance, 'tags').get(self.destination_variable, None) - - if not dest: - # Skip instances we cannot address (e.g. private VPC subnet) - return - - # Set the inventory name - hostname = None - if self.hostname_variable: - if self.hostname_variable.startswith('tag_'): - hostname = instance.tags.get(self.hostname_variable[4:], None) - else: - hostname = getattr(instance, self.hostname_variable) - - # set the hostname from route53 - if self.route53_enabled and self.route53_hostnames: - route53_names = self.get_instance_route53_names(instance) - for name in route53_names: - if name.endswith(self.route53_hostnames): - hostname = name - - # If we can't get a nice hostname, use the destination address - if not hostname: - hostname = dest - # to_safe strips hostname characters like dots, so don't strip route53 hostnames - elif self.route53_enabled and self.route53_hostnames and hostname.endswith(self.route53_hostnames): - hostname = hostname.lower() - else: - hostname = self.to_safe(hostname).lower() - - # if we only want to include hosts that match a pattern, skip those that don't - if self.pattern_include and not self.pattern_include.match(hostname): - return - - # if we need to exclude hosts that match a pattern, skip those - if self.pattern_exclude and self.pattern_exclude.match(hostname): - return - - # Add to index - self.index[hostname] = [region, instance.id] - - # Inventory: Group by instance ID (always a group of 1) - if self.group_by_instance_id: - self.inventory[instance.id] = [hostname] - if self.nested_groups: - self.push_group(self.inventory, 'instances', instance.id) - - # Inventory: Group by region - if self.group_by_region: - self.push(self.inventory, region, hostname) - if self.nested_groups: - self.push_group(self.inventory, 'regions', region) - - # Inventory: Group by availability zone - if self.group_by_availability_zone: - self.push(self.inventory, instance.placement, hostname) - if self.nested_groups: - if self.group_by_region: - self.push_group(self.inventory, region, instance.placement) - self.push_group(self.inventory, 'zones', instance.placement) - - # Inventory: Group by Amazon Machine Image (AMI) ID - if self.group_by_ami_id: - ami_id = self.to_safe(instance.image_id) - self.push(self.inventory, ami_id, hostname) - if self.nested_groups: - self.push_group(self.inventory, 'images', ami_id) - - # Inventory: Group by instance type - if self.group_by_instance_type: - type_name = self.to_safe('type_' + instance.instance_type) - self.push(self.inventory, type_name, hostname) - if self.nested_groups: - self.push_group(self.inventory, 'types', type_name) - - # Inventory: Group by instance state - if self.group_by_instance_state: - state_name = self.to_safe('instance_state_' + instance.state) - self.push(self.inventory, state_name, hostname) - if self.nested_groups: - self.push_group(self.inventory, 'instance_states', state_name) - - # Inventory: Group by key pair - if self.group_by_key_pair and instance.key_name: - key_name = self.to_safe('key_' + instance.key_name) - self.push(self.inventory, key_name, hostname) - if self.nested_groups: - self.push_group(self.inventory, 'keys', key_name) - - # Inventory: Group by VPC - if self.group_by_vpc_id and instance.vpc_id: - vpc_id_name = self.to_safe('vpc_id_' + instance.vpc_id) - self.push(self.inventory, vpc_id_name, hostname) - if self.nested_groups: - self.push_group(self.inventory, 'vpcs', vpc_id_name) - - # Inventory: Group by security group - if self.group_by_security_group: - try: - for group in instance.groups: - key = self.to_safe("security_group_" + group.name) - self.push(self.inventory, key, hostname) - if self.nested_groups: - self.push_group(self.inventory, 'security_groups', key) - except AttributeError: - self.fail_with_error('\n'.join(['Package boto seems a bit older.', - 'Please upgrade boto >= 2.3.0.'])) - - # Inventory: Group by AWS account ID - if self.group_by_aws_account: - self.push(self.inventory, self.aws_account_id, dest) - if self.nested_groups: - self.push_group(self.inventory, 'accounts', self.aws_account_id) - - # Inventory: Group by tag keys - if self.group_by_tag_keys: - for k, v in instance.tags.items(): - if self.expand_csv_tags and v and ',' in v: - values = map(lambda x: x.strip(), v.split(',')) - else: - values = [v] - - for v in values: - if v: - key = self.to_safe("tag_" + k + "=" + v) - else: - key = self.to_safe("tag_" + k) - self.push(self.inventory, key, hostname) - if self.nested_groups: - self.push_group(self.inventory, 'tags', self.to_safe("tag_" + k)) - if v: - self.push_group(self.inventory, self.to_safe("tag_" + k), key) - - # Inventory: Group by Route53 domain names if enabled - if self.route53_enabled and self.group_by_route53_names: - route53_names = self.get_instance_route53_names(instance) - for name in route53_names: - self.push(self.inventory, name, hostname) - if self.nested_groups: - self.push_group(self.inventory, 'route53', name) - - # Global Tag: instances without tags - if self.group_by_tag_none and len(instance.tags) == 0: - self.push(self.inventory, 'tag_none', hostname) - if self.nested_groups: - self.push_group(self.inventory, 'tags', 'tag_none') - - # Global Tag: tag all EC2 instances - self.push(self.inventory, 'ec2', hostname) - - self.inventory["_meta"]["hostvars"][hostname] = self.get_host_info_dict_from_instance(instance) - self.inventory["_meta"]["hostvars"][hostname]['ansible_ssh_host'] = dest - - def add_rds_instance(self, instance, region): - ''' Adds an RDS instance to the inventory and index, as long as it is - addressable ''' - - # Only want available instances unless all_rds_instances is True - if not self.all_rds_instances and instance.status != 'available': - return - - # Select the best destination address - dest = instance.endpoint[0] - - if not dest: - # Skip instances we cannot address (e.g. private VPC subnet) - return - - # Set the inventory name - hostname = None - if self.hostname_variable: - if self.hostname_variable.startswith('tag_'): - hostname = instance.tags.get(self.hostname_variable[4:], None) - else: - hostname = getattr(instance, self.hostname_variable) - - # If we can't get a nice hostname, use the destination address - if not hostname: - hostname = dest - - hostname = self.to_safe(hostname).lower() - - # Add to index - self.index[hostname] = [region, instance.id] - - # Inventory: Group by instance ID (always a group of 1) - if self.group_by_instance_id: - self.inventory[instance.id] = [hostname] - if self.nested_groups: - self.push_group(self.inventory, 'instances', instance.id) - - # Inventory: Group by region - if self.group_by_region: - self.push(self.inventory, region, hostname) - if self.nested_groups: - self.push_group(self.inventory, 'regions', region) - - # Inventory: Group by availability zone - if self.group_by_availability_zone: - self.push(self.inventory, instance.availability_zone, hostname) - if self.nested_groups: - if self.group_by_region: - self.push_group(self.inventory, region, instance.availability_zone) - self.push_group(self.inventory, 'zones', instance.availability_zone) - - # Inventory: Group by instance type - if self.group_by_instance_type: - type_name = self.to_safe('type_' + instance.instance_class) - self.push(self.inventory, type_name, hostname) - if self.nested_groups: - self.push_group(self.inventory, 'types', type_name) - - # Inventory: Group by VPC - if self.group_by_vpc_id and instance.subnet_group and instance.subnet_group.vpc_id: - vpc_id_name = self.to_safe('vpc_id_' + instance.subnet_group.vpc_id) - self.push(self.inventory, vpc_id_name, hostname) - if self.nested_groups: - self.push_group(self.inventory, 'vpcs', vpc_id_name) - - # Inventory: Group by security group - if self.group_by_security_group: - try: - if instance.security_group: - key = self.to_safe("security_group_" + instance.security_group.name) - self.push(self.inventory, key, hostname) - if self.nested_groups: - self.push_group(self.inventory, 'security_groups', key) - - except AttributeError: - self.fail_with_error('\n'.join(['Package boto seems a bit older.', - 'Please upgrade boto >= 2.3.0.'])) - - # Inventory: Group by engine - if self.group_by_rds_engine: - self.push(self.inventory, self.to_safe("rds_" + instance.engine), hostname) - if self.nested_groups: - self.push_group(self.inventory, 'rds_engines', self.to_safe("rds_" + instance.engine)) - - # Inventory: Group by parameter group - if self.group_by_rds_parameter_group: - self.push(self.inventory, self.to_safe("rds_parameter_group_" + instance.parameter_group.name), hostname) - if self.nested_groups: - self.push_group(self.inventory, 'rds_parameter_groups', self.to_safe("rds_parameter_group_" + instance.parameter_group.name)) - - # Global Tag: all RDS instances - self.push(self.inventory, 'rds', hostname) - - self.inventory["_meta"]["hostvars"][hostname] = self.get_host_info_dict_from_instance(instance) - self.inventory["_meta"]["hostvars"][hostname]['ansible_ssh_host'] = dest - - def add_elasticache_cluster(self, cluster, region): - ''' Adds an ElastiCache cluster to the inventory and index, as long as - it's nodes are addressable ''' - - # Only want available clusters unless all_elasticache_clusters is True - if not self.all_elasticache_clusters and cluster['CacheClusterStatus'] != 'available': - return - - # Select the best destination address - if 'ConfigurationEndpoint' in cluster and cluster['ConfigurationEndpoint']: - # Memcached cluster - dest = cluster['ConfigurationEndpoint']['Address'] - is_redis = False - else: - # Redis sigle node cluster - # Because all Redis clusters are single nodes, we'll merge the - # info from the cluster with info about the node - dest = cluster['CacheNodes'][0]['Endpoint']['Address'] - is_redis = True - - if not dest: - # Skip clusters we cannot address (e.g. private VPC subnet) - return - - # Add to index - self.index[dest] = [region, cluster['CacheClusterId']] - - # Inventory: Group by instance ID (always a group of 1) - if self.group_by_instance_id: - self.inventory[cluster['CacheClusterId']] = [dest] - if self.nested_groups: - self.push_group(self.inventory, 'instances', cluster['CacheClusterId']) - - # Inventory: Group by region - if self.group_by_region and not is_redis: - self.push(self.inventory, region, dest) - if self.nested_groups: - self.push_group(self.inventory, 'regions', region) - - # Inventory: Group by availability zone - if self.group_by_availability_zone and not is_redis: - self.push(self.inventory, cluster['PreferredAvailabilityZone'], dest) - if self.nested_groups: - if self.group_by_region: - self.push_group(self.inventory, region, cluster['PreferredAvailabilityZone']) - self.push_group(self.inventory, 'zones', cluster['PreferredAvailabilityZone']) - - # Inventory: Group by node type - if self.group_by_instance_type and not is_redis: - type_name = self.to_safe('type_' + cluster['CacheNodeType']) - self.push(self.inventory, type_name, dest) - if self.nested_groups: - self.push_group(self.inventory, 'types', type_name) - - # Inventory: Group by VPC (information not available in the current - # AWS API version for ElastiCache) - - # Inventory: Group by security group - if self.group_by_security_group and not is_redis: - - # Check for the existence of the 'SecurityGroups' key and also if - # this key has some value. When the cluster is not placed in a SG - # the query can return None here and cause an error. - if 'SecurityGroups' in cluster and cluster['SecurityGroups'] is not None: - for security_group in cluster['SecurityGroups']: - key = self.to_safe("security_group_" + security_group['SecurityGroupId']) - self.push(self.inventory, key, dest) - if self.nested_groups: - self.push_group(self.inventory, 'security_groups', key) - - # Inventory: Group by engine - if self.group_by_elasticache_engine and not is_redis: - self.push(self.inventory, self.to_safe("elasticache_" + cluster['Engine']), dest) - if self.nested_groups: - self.push_group(self.inventory, 'elasticache_engines', self.to_safe(cluster['Engine'])) - - # Inventory: Group by parameter group - if self.group_by_elasticache_parameter_group: - self.push(self.inventory, self.to_safe("elasticache_parameter_group_" + cluster['CacheParameterGroup']['CacheParameterGroupName']), dest) - if self.nested_groups: - self.push_group(self.inventory, 'elasticache_parameter_groups', self.to_safe(cluster['CacheParameterGroup']['CacheParameterGroupName'])) - - # Inventory: Group by replication group - if self.group_by_elasticache_replication_group and 'ReplicationGroupId' in cluster and cluster['ReplicationGroupId']: - self.push(self.inventory, self.to_safe("elasticache_replication_group_" + cluster['ReplicationGroupId']), dest) - if self.nested_groups: - self.push_group(self.inventory, 'elasticache_replication_groups', self.to_safe(cluster['ReplicationGroupId'])) - - # Global Tag: all ElastiCache clusters - self.push(self.inventory, 'elasticache_clusters', cluster['CacheClusterId']) - - host_info = self.get_host_info_dict_from_describe_dict(cluster) - - self.inventory["_meta"]["hostvars"][dest] = host_info - - # Add the nodes - for node in cluster['CacheNodes']: - self.add_elasticache_node(node, cluster, region) - - def add_elasticache_node(self, node, cluster, region): - ''' Adds an ElastiCache node to the inventory and index, as long as - it is addressable ''' - - # Only want available nodes unless all_elasticache_nodes is True - if not self.all_elasticache_nodes and node['CacheNodeStatus'] != 'available': - return - - # Select the best destination address - dest = node['Endpoint']['Address'] - - if not dest: - # Skip nodes we cannot address (e.g. private VPC subnet) - return - - node_id = self.to_safe(cluster['CacheClusterId'] + '_' + node['CacheNodeId']) - - # Add to index - self.index[dest] = [region, node_id] - - # Inventory: Group by node ID (always a group of 1) - if self.group_by_instance_id: - self.inventory[node_id] = [dest] - if self.nested_groups: - self.push_group(self.inventory, 'instances', node_id) - - # Inventory: Group by region - if self.group_by_region: - self.push(self.inventory, region, dest) - if self.nested_groups: - self.push_group(self.inventory, 'regions', region) - - # Inventory: Group by availability zone - if self.group_by_availability_zone: - self.push(self.inventory, cluster['PreferredAvailabilityZone'], dest) - if self.nested_groups: - if self.group_by_region: - self.push_group(self.inventory, region, cluster['PreferredAvailabilityZone']) - self.push_group(self.inventory, 'zones', cluster['PreferredAvailabilityZone']) - - # Inventory: Group by node type - if self.group_by_instance_type: - type_name = self.to_safe('type_' + cluster['CacheNodeType']) - self.push(self.inventory, type_name, dest) - if self.nested_groups: - self.push_group(self.inventory, 'types', type_name) - - # Inventory: Group by VPC (information not available in the current - # AWS API version for ElastiCache) - - # Inventory: Group by security group - if self.group_by_security_group: - - # Check for the existence of the 'SecurityGroups' key and also if - # this key has some value. When the cluster is not placed in a SG - # the query can return None here and cause an error. - if 'SecurityGroups' in cluster and cluster['SecurityGroups'] is not None: - for security_group in cluster['SecurityGroups']: - key = self.to_safe("security_group_" + security_group['SecurityGroupId']) - self.push(self.inventory, key, dest) - if self.nested_groups: - self.push_group(self.inventory, 'security_groups', key) - - # Inventory: Group by engine - if self.group_by_elasticache_engine: - self.push(self.inventory, self.to_safe("elasticache_" + cluster['Engine']), dest) - if self.nested_groups: - self.push_group(self.inventory, 'elasticache_engines', self.to_safe("elasticache_" + cluster['Engine'])) - - # Inventory: Group by parameter group (done at cluster level) - - # Inventory: Group by replication group (done at cluster level) - - # Inventory: Group by ElastiCache Cluster - if self.group_by_elasticache_cluster: - self.push(self.inventory, self.to_safe("elasticache_cluster_" + cluster['CacheClusterId']), dest) - - # Global Tag: all ElastiCache nodes - self.push(self.inventory, 'elasticache_nodes', dest) - - host_info = self.get_host_info_dict_from_describe_dict(node) - - if dest in self.inventory["_meta"]["hostvars"]: - self.inventory["_meta"]["hostvars"][dest].update(host_info) - else: - self.inventory["_meta"]["hostvars"][dest] = host_info - - def add_elasticache_replication_group(self, replication_group, region): - ''' Adds an ElastiCache replication group to the inventory and index ''' - - # Only want available clusters unless all_elasticache_replication_groups is True - if not self.all_elasticache_replication_groups and replication_group['Status'] != 'available': - return - - # Skip clusters we cannot address (e.g. private VPC subnet or clustered redis) - if replication_group['NodeGroups'][0]['PrimaryEndpoint'] is None or \ - replication_group['NodeGroups'][0]['PrimaryEndpoint']['Address'] is None: - return - - # Select the best destination address (PrimaryEndpoint) - dest = replication_group['NodeGroups'][0]['PrimaryEndpoint']['Address'] - - # Add to index - self.index[dest] = [region, replication_group['ReplicationGroupId']] - - # Inventory: Group by ID (always a group of 1) - if self.group_by_instance_id: - self.inventory[replication_group['ReplicationGroupId']] = [dest] - if self.nested_groups: - self.push_group(self.inventory, 'instances', replication_group['ReplicationGroupId']) - - # Inventory: Group by region - if self.group_by_region: - self.push(self.inventory, region, dest) - if self.nested_groups: - self.push_group(self.inventory, 'regions', region) - - # Inventory: Group by availability zone (doesn't apply to replication groups) - - # Inventory: Group by node type (doesn't apply to replication groups) - - # Inventory: Group by VPC (information not available in the current - # AWS API version for replication groups - - # Inventory: Group by security group (doesn't apply to replication groups) - # Check this value in cluster level - - # Inventory: Group by engine (replication groups are always Redis) - if self.group_by_elasticache_engine: - self.push(self.inventory, 'elasticache_redis', dest) - if self.nested_groups: - self.push_group(self.inventory, 'elasticache_engines', 'redis') - - # Global Tag: all ElastiCache clusters - self.push(self.inventory, 'elasticache_replication_groups', replication_group['ReplicationGroupId']) - - host_info = self.get_host_info_dict_from_describe_dict(replication_group) - - self.inventory["_meta"]["hostvars"][dest] = host_info - - def get_route53_records(self): - ''' Get and store the map of resource records to domain names that - point to them. ''' - - if self.boto_profile: - r53_conn = route53.Route53Connection(profile_name=self.boto_profile) - else: - r53_conn = route53.Route53Connection() - all_zones = r53_conn.get_zones() - - route53_zones = [zone for zone in all_zones if zone.name[:-1] not in self.route53_excluded_zones] - - self.route53_records = {} - - for zone in route53_zones: - rrsets = r53_conn.get_all_rrsets(zone.id) - - for record_set in rrsets: - record_name = record_set.name - - if record_name.endswith('.'): - record_name = record_name[:-1] - - for resource in record_set.resource_records: - self.route53_records.setdefault(resource, set()) - self.route53_records[resource].add(record_name) - - def get_instance_route53_names(self, instance): - ''' Check if an instance is referenced in the records we have from - Route53. If it is, return the list of domain names pointing to said - instance. If nothing points to it, return an empty list. ''' - - instance_attributes = ['public_dns_name', 'private_dns_name', - 'ip_address', 'private_ip_address'] - - name_list = set() - - for attrib in instance_attributes: - try: - value = getattr(instance, attrib) - except AttributeError: - continue - - if value in self.route53_records: - name_list.update(self.route53_records[value]) - - return list(name_list) - - def get_host_info_dict_from_instance(self, instance): - instance_vars = {} - for key in vars(instance): - value = getattr(instance, key) - key = self.to_safe('ec2_' + key) - - # Handle complex types - # state/previous_state changed to properties in boto in https://github.com/boto/boto/commit/a23c379837f698212252720d2af8dec0325c9518 - if key == 'ec2__state': - instance_vars['ec2_state'] = instance.state or '' - instance_vars['ec2_state_code'] = instance.state_code - elif key == 'ec2__previous_state': - instance_vars['ec2_previous_state'] = instance.previous_state or '' - instance_vars['ec2_previous_state_code'] = instance.previous_state_code - elif isinstance(value, (int, bool)): - instance_vars[key] = value - elif isinstance(value, six.string_types): - instance_vars[key] = value.strip() - elif value is None: - instance_vars[key] = '' - elif key == 'ec2_region': - instance_vars[key] = value.name - elif key == 'ec2__placement': - instance_vars['ec2_placement'] = value.zone - elif key == 'ec2_tags': - for k, v in value.items(): - if self.expand_csv_tags and ',' in v: - v = list(map(lambda x: x.strip(), v.split(','))) - key = self.to_safe('ec2_tag_' + k) - instance_vars[key] = v - elif key == 'ec2_groups': - group_ids = [] - group_names = [] - for group in value: - group_ids.append(group.id) - group_names.append(group.name) - instance_vars["ec2_security_group_ids"] = ','.join([str(i) for i in group_ids]) - instance_vars["ec2_security_group_names"] = ','.join([str(i) for i in group_names]) - elif key == 'ec2_block_device_mapping': - instance_vars["ec2_block_devices"] = {} - for k, v in value.items(): - instance_vars["ec2_block_devices"][os.path.basename(k)] = v.volume_id - else: - pass - # TODO Product codes if someone finds them useful - # print key - # print type(value) - # print value - - instance_vars[self.to_safe('ec2_account_id')] = self.aws_account_id - - return instance_vars - - def get_host_info_dict_from_describe_dict(self, describe_dict): - ''' Parses the dictionary returned by the API call into a flat list - of parameters. This method should be used only when 'describe' is - used directly because Boto doesn't provide specific classes. ''' - - # I really don't agree with prefixing everything with 'ec2' - # because EC2, RDS and ElastiCache are different services. - # I'm just following the pattern used until now to not break any - # compatibility. - - host_info = {} - for key in describe_dict: - value = describe_dict[key] - key = self.to_safe('ec2_' + self.uncammelize(key)) - - # Handle complex types - - # Target: Memcached Cache Clusters - if key == 'ec2_configuration_endpoint' and value: - host_info['ec2_configuration_endpoint_address'] = value['Address'] - host_info['ec2_configuration_endpoint_port'] = value['Port'] - - # Target: Cache Nodes and Redis Cache Clusters (single node) - if key == 'ec2_endpoint' and value: - host_info['ec2_endpoint_address'] = value['Address'] - host_info['ec2_endpoint_port'] = value['Port'] - - # Target: Redis Replication Groups - if key == 'ec2_node_groups' and value: - host_info['ec2_endpoint_address'] = value[0]['PrimaryEndpoint']['Address'] - host_info['ec2_endpoint_port'] = value[0]['PrimaryEndpoint']['Port'] - replica_count = 0 - for node in value[0]['NodeGroupMembers']: - if node['CurrentRole'] == 'primary': - host_info['ec2_primary_cluster_address'] = node['ReadEndpoint']['Address'] - host_info['ec2_primary_cluster_port'] = node['ReadEndpoint']['Port'] - host_info['ec2_primary_cluster_id'] = node['CacheClusterId'] - elif node['CurrentRole'] == 'replica': - host_info['ec2_replica_cluster_address_' + str(replica_count)] = node['ReadEndpoint']['Address'] - host_info['ec2_replica_cluster_port_' + str(replica_count)] = node['ReadEndpoint']['Port'] - host_info['ec2_replica_cluster_id_' + str(replica_count)] = node['CacheClusterId'] - replica_count += 1 - - # Target: Redis Replication Groups - if key == 'ec2_member_clusters' and value: - host_info['ec2_member_clusters'] = ','.join([str(i) for i in value]) - - # Target: All Cache Clusters - elif key == 'ec2_cache_parameter_group': - host_info["ec2_cache_node_ids_to_reboot"] = ','.join([str(i) for i in value['CacheNodeIdsToReboot']]) - host_info['ec2_cache_parameter_group_name'] = value['CacheParameterGroupName'] - host_info['ec2_cache_parameter_apply_status'] = value['ParameterApplyStatus'] - - # Target: Almost everything - elif key == 'ec2_security_groups': - - # Skip if SecurityGroups is None - # (it is possible to have the key defined but no value in it). - if value is not None: - sg_ids = [] - for sg in value: - sg_ids.append(sg['SecurityGroupId']) - host_info["ec2_security_group_ids"] = ','.join([str(i) for i in sg_ids]) - - # Target: Everything - # Preserve booleans and integers - elif isinstance(value, (int, bool)): - host_info[key] = value - - # Target: Everything - # Sanitize string values - elif isinstance(value, six.string_types): - host_info[key] = value.strip() - - # Target: Everything - # Replace None by an empty string - elif value is None: - host_info[key] = '' - - else: - # Remove non-processed complex types - pass - - return host_info - - def get_host_info(self): - ''' Get variables about a specific host ''' - - if len(self.index) == 0: - # Need to load index from cache - self.load_index_from_cache() - - if self.args.host not in self.index: - # try updating the cache - self.do_api_calls_update_cache() - if self.args.host not in self.index: - # host might not exist anymore - return self.json_format_dict({}, True) - - (region, instance_id) = self.index[self.args.host] - - instance = self.get_instance(region, instance_id) - return self.json_format_dict(self.get_host_info_dict_from_instance(instance), True) - - def push(self, my_dict, key, element): - ''' Push an element onto an array that may not have been defined in - the dict ''' - group_info = my_dict.setdefault(key, []) - if isinstance(group_info, dict): - host_list = group_info.setdefault('hosts', []) - host_list.append(element) - else: - group_info.append(element) - - def push_group(self, my_dict, key, element): - ''' Push a group as a child of another group. ''' - parent_group = my_dict.setdefault(key, {}) - if not isinstance(parent_group, dict): - parent_group = my_dict[key] = {'hosts': parent_group} - child_groups = parent_group.setdefault('children', []) - if element not in child_groups: - child_groups.append(element) - - def get_inventory_from_cache(self): - ''' Reads the inventory from the cache file and returns it as a JSON - object ''' - - with open(self.cache_path_cache, 'r') as f: - json_inventory = f.read() - return json_inventory - - def load_index_from_cache(self): - ''' Reads the index from the cache file sets self.index ''' - - with open(self.cache_path_index, 'rb') as f: - self.index = json.load(f) - - def write_to_cache(self, data, filename): - ''' Writes data in JSON format to a file ''' - - json_data = self.json_format_dict(data, True) - with open(filename, 'w') as f: - f.write(json_data) - - def uncammelize(self, key): - temp = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', key) - return re.sub('([a-z0-9])([A-Z])', r'\1_\2', temp).lower() - - def to_safe(self, word): - ''' Converts 'bad' characters in a string to underscores so they can be used as Ansible groups ''' - regex = "[^A-Za-z0-9\_" - if not self.replace_dash_in_groups: - regex += "\-" - return re.sub(regex + "]", "_", word) - - def json_format_dict(self, data, pretty=False): - ''' Converts a dict to a JSON object and dumps it as a formatted - string ''' - - if pretty: - return json.dumps(data, sort_keys=True, indent=2) - else: - return json.dumps(data) - - -if __name__ == '__main__': - # Run the script - Ec2Inventory() diff --git a/contrib/testnets/remote/ansible/logzio.yml b/contrib/testnets/remote/ansible/logzio.yml deleted file mode 100644 index e7fa1d562..000000000 --- a/contrib/testnets/remote/ansible/logzio.yml +++ /dev/null @@ -1,13 +0,0 @@ ---- - -#Note: You need to add LOGZIO_TOKEN variable with your API key. Like this: ansible-playbook -e LOGZIO_TOKEN=ABCXYZ123456 - -- hosts: all - any_errors_fatal: true - gather_facts: no - vars: - - service: pstaked - - JOURNALBEAT_BINARY: "{{lookup('env', 'GOPATH')}}/bin/journalbeat" - roles: - - logzio - diff --git a/contrib/testnets/remote/ansible/remove-datadog-agent.yml b/contrib/testnets/remote/ansible/remove-datadog-agent.yml deleted file mode 100644 index 32679c3b2..000000000 --- a/contrib/testnets/remote/ansible/remove-datadog-agent.yml +++ /dev/null @@ -1,8 +0,0 @@ ---- - -- hosts: all - any_errors_fatal: true - gather_facts: no - roles: - - remove-datadog-agent - diff --git a/contrib/testnets/remote/ansible/roles/add-lcd/defaults/main.yml b/contrib/testnets/remote/ansible/roles/add-lcd/defaults/main.yml deleted file mode 100644 index 16a85e0dd..000000000 --- a/contrib/testnets/remote/ansible/roles/add-lcd/defaults/main.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- - -GAIACLI_ADDRESS: tcp://0.0.0.0:1317 - diff --git a/contrib/testnets/remote/ansible/roles/add-lcd/handlers/main.yml b/contrib/testnets/remote/ansible/roles/add-lcd/handlers/main.yml deleted file mode 100644 index 2ce6b83e5..000000000 --- a/contrib/testnets/remote/ansible/roles/add-lcd/handlers/main.yml +++ /dev/null @@ -1,9 +0,0 @@ ---- - -- name: systemctl - systemd: name=gaiacli enabled=yes daemon_reload=yes - -- name: restart gaiacli - service: name=gaiacli state=restarted - - diff --git a/contrib/testnets/remote/ansible/roles/add-lcd/tasks/main.yml b/contrib/testnets/remote/ansible/roles/add-lcd/tasks/main.yml deleted file mode 100644 index d0fbd8132..000000000 --- a/contrib/testnets/remote/ansible/roles/add-lcd/tasks/main.yml +++ /dev/null @@ -1,15 +0,0 @@ ---- - -- name: Copy binary - copy: - src: "{{GAIACLI_BINARY}}" - dest: /usr/bin/gaiacli - mode: 0755 - notify: restart gaiacli - -- name: Copy service - template: - src: gaiacli.service.j2 - dest: /etc/systemd/system/gaiacli.service - notify: systemctl - diff --git a/contrib/testnets/remote/ansible/roles/add-lcd/templates/gaiacli.service.j2 b/contrib/testnets/remote/ansible/roles/add-lcd/templates/gaiacli.service.j2 deleted file mode 100644 index 67cbeaee5..000000000 --- a/contrib/testnets/remote/ansible/roles/add-lcd/templates/gaiacli.service.j2 +++ /dev/null @@ -1,17 +0,0 @@ -[Unit] -Description=gaiacli -Requires=network-online.target -After=network-online.target - -[Service] -Restart=on-failure -User=gaiad -Group=gaiad -PermissionsStartOnly=true -ExecStart=/usr/bin/gaiacli rest-server --laddr {{GAIACLI_ADDRESS}} -ExecReload=/bin/kill -HUP $MAINPID -KillSignal=SIGTERM - -[Install] -WantedBy=multi-user.target - diff --git a/contrib/testnets/remote/ansible/roles/clear-config/tasks/main.yml b/contrib/testnets/remote/ansible/roles/clear-config/tasks/main.yml deleted file mode 100644 index d5375ef63..000000000 --- a/contrib/testnets/remote/ansible/roles/clear-config/tasks/main.yml +++ /dev/null @@ -1,9 +0,0 @@ ---- -- name: Stop service - service: name=pstaked state=stopped - -- name: Delete files - file: "path={{item}} state=absent" - with_items: - - /usr/bin/pstaked - - /home/pstaked/.gaia diff --git a/contrib/testnets/remote/ansible/roles/extract-config/defaults/main.yml b/contrib/testnets/remote/ansible/roles/extract-config/defaults/main.yml deleted file mode 100644 index a535d201d..000000000 --- a/contrib/testnets/remote/ansible/roles/extract-config/defaults/main.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- - -TESTNET_NAME: remotenet - diff --git a/contrib/testnets/remote/ansible/roles/extract-config/tasks/main.yml b/contrib/testnets/remote/ansible/roles/extract-config/tasks/main.yml deleted file mode 100644 index 0eee7d661..000000000 --- a/contrib/testnets/remote/ansible/roles/extract-config/tasks/main.yml +++ /dev/null @@ -1,14 +0,0 @@ ---- - -- name: Fetch genesis.json - fetch: "src=/home/pstaked/.gaia/config/genesis.json dest={{GENESISFILE}} flat=yes" - run_once: yes - become: yes - become_user: pstaked - -- name: Fetch config.toml - fetch: "src=/home/pstaked/.gaia/config/config.toml dest={{CONFIGFILE}} flat=yes" - run_once: yes - become: yes - become_user: pstaked - diff --git a/contrib/testnets/remote/ansible/roles/increase-openfiles/files/50-fs.conf b/contrib/testnets/remote/ansible/roles/increase-openfiles/files/50-fs.conf deleted file mode 100644 index 5193edd22..000000000 --- a/contrib/testnets/remote/ansible/roles/increase-openfiles/files/50-fs.conf +++ /dev/null @@ -1 +0,0 @@ -fs.file-max=262144 diff --git a/contrib/testnets/remote/ansible/roles/increase-openfiles/files/91-nofiles.conf b/contrib/testnets/remote/ansible/roles/increase-openfiles/files/91-nofiles.conf deleted file mode 100644 index 929081c6c..000000000 --- a/contrib/testnets/remote/ansible/roles/increase-openfiles/files/91-nofiles.conf +++ /dev/null @@ -1,3 +0,0 @@ -* soft nofile 262144 -* hard nofile 262144 - diff --git a/contrib/testnets/remote/ansible/roles/increase-openfiles/files/limits.conf b/contrib/testnets/remote/ansible/roles/increase-openfiles/files/limits.conf deleted file mode 100644 index d3fcd2e86..000000000 --- a/contrib/testnets/remote/ansible/roles/increase-openfiles/files/limits.conf +++ /dev/null @@ -1,3 +0,0 @@ -[Service] -LimitNOFILE=infinity -LimitMEMLOCK=infinity diff --git a/contrib/testnets/remote/ansible/roles/increase-openfiles/handlers/main.yml b/contrib/testnets/remote/ansible/roles/increase-openfiles/handlers/main.yml deleted file mode 100644 index d49602300..000000000 --- a/contrib/testnets/remote/ansible/roles/increase-openfiles/handlers/main.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- - -- name: reload systemctl - systemd: name=systemd daemon_reload=yes - diff --git a/contrib/testnets/remote/ansible/roles/increase-openfiles/tasks/main.yml b/contrib/testnets/remote/ansible/roles/increase-openfiles/tasks/main.yml deleted file mode 100644 index d5757dafa..000000000 --- a/contrib/testnets/remote/ansible/roles/increase-openfiles/tasks/main.yml +++ /dev/null @@ -1,22 +0,0 @@ ---- -# Based on: https://stackoverflow.com/questions/38155108/how-to-increase-limit-for-open-processes-and-files-using-ansible - -- name: Set sysctl File Limits - copy: - src: 50-fs.conf - dest: /etc/sysctl.d - -- name: Set Shell File Limits - copy: - src: 91-nofiles.conf - dest: /etc/security/limits.d - -- name: Set gaia filehandle Limits - copy: - src: limits.conf - dest: "/lib/systemd/system/{{item}}.service.d" - notify: reload systemctl - with_items: - - pstaked - - gaiacli - diff --git a/contrib/testnets/remote/ansible/roles/install-datadog-agent/handlers/main.yml b/contrib/testnets/remote/ansible/roles/install-datadog-agent/handlers/main.yml deleted file mode 100644 index 04f72b74d..000000000 --- a/contrib/testnets/remote/ansible/roles/install-datadog-agent/handlers/main.yml +++ /dev/null @@ -1,10 +0,0 @@ ---- - -- name: restart datadog-agent - service: name=datadog-agent state=restarted - -- name: restart rsyslog - service: name=rsyslog state=restarted - -- name: restart journald - service: name=systemd-journald state=restarted diff --git a/contrib/testnets/remote/ansible/roles/install-datadog-agent/tasks/main.yml b/contrib/testnets/remote/ansible/roles/install-datadog-agent/tasks/main.yml deleted file mode 100644 index 4d5aa1877..000000000 --- a/contrib/testnets/remote/ansible/roles/install-datadog-agent/tasks/main.yml +++ /dev/null @@ -1,15 +0,0 @@ ---- - -- name: Remove old datadog.yaml, if exist - file: path=/etc/datadog-agent/datadog.yaml state=absent - notify: restart datadog-agent - -- name: Download DataDog agent script - get_url: url=https://raw.githubusercontent.com/DataDog/datadog-agent/master/cmd/agent/install_script.sh dest=/tmp/datadog-agent-install.sh mode=0755 - -- name: Install DataDog agent - command: "/tmp/datadog-agent-install.sh" - environment: - DD_API_KEY: "{{DD_API_KEY}}" - DD_HOST_TAGS: "testnet:{{TESTNET_NAME}},cluster:{{CLUSTER_NAME}}" - diff --git a/contrib/testnets/remote/ansible/roles/logzio/files/journalbeat.service b/contrib/testnets/remote/ansible/roles/logzio/files/journalbeat.service deleted file mode 100644 index 3cb66a454..000000000 --- a/contrib/testnets/remote/ansible/roles/logzio/files/journalbeat.service +++ /dev/null @@ -1,15 +0,0 @@ -[Unit] -Description=journalbeat -#propagates activation, deactivation and activation fails. -Requires=network-online.target -After=network-online.target - -[Service] -Restart=on-failure -ExecStart=/usr/bin/journalbeat -c /etc/journalbeat/journalbeat.yml -path.home /usr/share/journalbeat -path.config /etc/journalbeat -path.data /var/lib/journalbeat -path.logs /var/log/journalbeat -Restart=always - -[Install] -WantedBy=multi-user.target - - diff --git a/contrib/testnets/remote/ansible/roles/logzio/handlers/main.yml b/contrib/testnets/remote/ansible/roles/logzio/handlers/main.yml deleted file mode 100644 index 0b371fc51..000000000 --- a/contrib/testnets/remote/ansible/roles/logzio/handlers/main.yml +++ /dev/null @@ -1,8 +0,0 @@ ---- - -- name: reload daemon - command: "systemctl daemon-reload" - -- name: restart journalbeat - service: name=journalbeat state=restarted - diff --git a/contrib/testnets/remote/ansible/roles/logzio/tasks/main.yml b/contrib/testnets/remote/ansible/roles/logzio/tasks/main.yml deleted file mode 100644 index ab3976f22..000000000 --- a/contrib/testnets/remote/ansible/roles/logzio/tasks/main.yml +++ /dev/null @@ -1,27 +0,0 @@ ---- - -- name: Copy journalbeat binary - copy: src="{{JOURNALBEAT_BINARY}}" dest=/usr/bin/journalbeat mode=0755 - notify: restart journalbeat - -- name: Create folders - file: "path={{item}} state=directory recurse=yes" - with_items: - - /etc/journalbeat - - /etc/pki/tls/certs - - /usr/share/journalbeat - - /var/log/journalbeat - -- name: Copy journalbeat config - template: src=journalbeat.yml.j2 dest=/etc/journalbeat/journalbeat.yml mode=0600 - notify: restart journalbeat - -- name: Get server certificate for Logz.io - get_url: "url=https://raw.githubusercontent.com/logzio/public-certificates/master/COMODORSADomainValidationSecureServerCA.crt force=yes dest=/etc/pki/tls/certs/COMODORSADomainValidationSecureServerCA.crt" - -- name: Copy journalbeat service config - copy: src=journalbeat.service dest=/etc/systemd/system/journalbeat.service - notify: - - reload daemon - - restart journalbeat - diff --git a/contrib/testnets/remote/ansible/roles/logzio/templates/journalbeat.yml.j2 b/contrib/testnets/remote/ansible/roles/logzio/templates/journalbeat.yml.j2 deleted file mode 100644 index af2ac4f13..000000000 --- a/contrib/testnets/remote/ansible/roles/logzio/templates/journalbeat.yml.j2 +++ /dev/null @@ -1,342 +0,0 @@ -#======================== Journalbeat Configuration ============================ - -journalbeat: - # What position in journald to seek to at start up - # options: cursor, tail, head (defaults to tail) - #seek_position: tail - - # If seek_position is set to cursor and seeking to cursor fails - # fall back to this method. If set to none will it will exit - # options: tail, head, none (defaults to tail) - #cursor_seek_fallback: tail - - # Store the cursor of the successfully published events - #write_cursor_state: true - - # Path to the file to store the cursor (defaults to ".journalbeat-cursor-state") - #cursor_state_file: .journalbeat-cursor-state - - # How frequently should we save the cursor to disk (defaults to 5s) - #cursor_flush_period: 5s - - # Path to the file to store the queue of events pending (defaults to ".journalbeat-pending-queue") - #pending_queue.file: .journalbeat-pending-queue - - # How frequently should we save the queue to disk (defaults to 1s). - # Pending queue represents the WAL of events queued to be published - # or being published and waiting for acknowledgement. In case of a - # regular restart of journalbeat all the events not yet acknowledged - # will be flushed to disk during the shutdown. - # In case of disaster most probably journalbeat won't get a chance to shutdown - # itself gracefully and this flush period option will serve you as a - # backup creation frequency option. - #pending_queue.flush_period: 1s - - # Lowercase and remove leading underscores, e.g. "_MESSAGE" -> "message" - # (defaults to false) - #clean_field_names: false - - # All journal entries are strings by default. You can try to convert them to numbers. - # (defaults to false) - #convert_to_numbers: false - - # Store all the fields of the Systemd Journal entry under this field - # Can be almost any string suitable to be a field name of an ElasticSearch document. - # Dots can be used to create nested fields. - # Two exceptions: - # - no repeated dots; - # - no trailing dots, e.g. "journal..field_name." will fail - # (defaults to "" hence stores on the upper level of the event) - #move_metadata_to_field: "" - - # Specific units to monitor. - units: ["{{service}}.service","gaiacli.service"] - - # Specify Journal paths to open. You can pass an array of paths to Systemd Journal paths. - # If you want to open Journal from directory just pass an array consisting of one element - # representing the path. See: https://www.freedesktop.org/software/systemd/man/sd_journal_open.html - # By default this setting is empty thus journalbeat will attempt to find all journal files automatically - #journal_paths: ["/var/log/journal"] - - #default_type: journal - -#================================ General ====================================== - -# The name of the shipper that publishes the network data. It can be used to group -# all the transactions sent by a single shipper in the web interface. -# If this options is not defined, the hostname is used. -#name: journalbeat - -# The tags of the shipper are included in their own field with each -# transaction published. Tags make it easy to group servers by different -# logical properties. -tags: ["{{service}}"] - -# Optional fields that you can specify to add additional information to the -# output. Fields can be scalar values, arrays, dictionaries, or any nested -# combination of these. -fields: - logzio_codec: plain - token: {{LOGZIO_TOKEN}} - -# If this option is set to true, the custom fields are stored as top-level -# fields in the output document instead of being grouped under a fields -# sub-dictionary. Default is false. -fields_under_root: true - -# Internal queue size for single events in processing pipeline -#queue_size: 1000 - -# The internal queue size for bulk events in the processing pipeline. -# Do not modify this value. -#bulk_queue_size: 0 - -# Sets the maximum number of CPUs that can be executing simultaneously. The -# default is the number of logical CPUs available in the system. -#max_procs: - -#================================ Processors =================================== - -# Processors are used to reduce the number of fields in the exported event or to -# enhance the event with external metadata. This section defines a list of -# processors that are applied one by one and the first one receives the initial -# event: -# -# event -> filter1 -> event1 -> filter2 ->event2 ... -# -# The supported processors are drop_fields, drop_event, include_fields, and -# add_cloud_metadata. -# -# For example, you can use the following processors to keep the fields that -# contain CPU load percentages, but remove the fields that contain CPU ticks -# values: -# -processors: -#- include_fields: -# fields: ["cpu"] -- drop_fields: - fields: ["beat.name", "beat.version", "logzio_codec", "SYSLOG_IDENTIFIER", "SYSLOG_FACILITY", "PRIORITY"] -# -# The following example drops the events that have the HTTP response code 200: -# -#processors: -#- drop_event: -# when: -# equals: -# http.code: 200 -# -# The following example enriches each event with metadata from the cloud -# provider about the host machine. It works on EC2, GCE, and DigitalOcean. -# -#processors: -#- add_cloud_metadata: -# - -#================================ Outputs ====================================== - -# Configure what outputs to use when sending the data collected by the beat. -# Multiple outputs may be used. - -#----------------------------- Logstash output --------------------------------- -output.logstash: - # Boolean flag to enable or disable the output module. - enabled: true - - # The Logstash hosts - hosts: ["listener.logz.io:5015"] - - # Number of workers per Logstash host. - #worker: 1 - - # Set gzip compression level. - #compression_level: 3 - - # Optional load balance the events between the Logstash hosts - #loadbalance: true - - # Number of batches to be send asynchronously to logstash while processing - # new batches. - #pipelining: 0 - - # Optional index name. The default index name is set to name of the beat - # in all lowercase. - #index: 'beatname' - - # SOCKS5 proxy server URL - #proxy_url: socks5://user:password@socks5-server:2233 - - # Resolve names locally when using a proxy server. Defaults to false. - #proxy_use_local_resolver: false - - # Enable SSL support. SSL is automatically enabled, if any SSL setting is set. - ssl.enabled: true - - # Configure SSL verification mode. If `none` is configured, all server hosts - # and certificates will be accepted. In this mode, SSL based connections are - # susceptible to man-in-the-middle attacks. Use only for testing. Default is - # `full`. - ssl.verification_mode: full - - # List of supported/valid TLS versions. By default all TLS versions 1.0 up to - # 1.2 are enabled. - #ssl.supported_protocols: [TLSv1.0, TLSv1.1, TLSv1.2] - - # Optional SSL configuration options. SSL is off by default. - # List of root certificates for HTTPS server verifications - ssl.certificate_authorities: ["/etc/pki/tls/certs/COMODORSADomainValidationSecureServerCA.crt"] - - # Certificate for SSL client authentication - #ssl.certificate: "/etc/pki/client/cert.pem" - - # Client Certificate Key - #ssl.key: "/etc/pki/client/cert.key" - - # Optional passphrase for decrypting the Certificate Key. - #ssl.key_passphrase: '' - - # Configure cipher suites to be used for SSL connections - #ssl.cipher_suites: [] - - # Configure curve types for ECDHE based cipher suites - #ssl.curve_types: [] - -#------------------------------- File output ----------------------------------- -#output.file: - # Boolean flag to enable or disable the output module. - #enabled: true - - # Path to the directory where to save the generated files. The option is - # mandatory. - #path: "/tmp/beatname" - - # Name of the generated files. The default is `beatname` and it generates - # files: `beatname`, `beatname.1`, `beatname.2`, etc. - #filename: beatname - - # Maximum size in kilobytes of each file. When this size is reached, and on - # every beatname restart, the files are rotated. The default value is 10240 - # kB. - #rotate_every_kb: 10000 - - # Maximum number of files under path. When this number of files is reached, - # the oldest file is deleted and the rest are shifted from last to first. The - # default is 7 files. - #number_of_files: 7 - - -#----------------------------- Console output --------------------------------- -#output.console: - # Boolean flag to enable or disable the output module. - #enabled: true - - # Pretty print json event - #pretty: false - -#================================= Paths ====================================== - -# The home path for the beatname installation. This is the default base path -# for all other path settings and for miscellaneous files that come with the -# distribution (for example, the sample dashboards). -# If not set by a CLI flag or in the configuration file, the default for the -# home path is the location of the binary. -#path.home: - -# The configuration path for the beatname installation. This is the default -# base path for configuration files, including the main YAML configuration file -# and the Elasticsearch template file. If not set by a CLI flag or in the -# configuration file, the default for the configuration path is the home path. -#path.config: ${path.home} - -# The data path for the beatname installation. This is the default base path -# for all the files in which beatname needs to store its data. If not set by a -# CLI flag or in the configuration file, the default for the data path is a data -# subdirectory inside the home path. -#path.data: ${path.home}/data - -# The logs path for a beatname installation. This is the default location for -# the Beat's log files. If not set by a CLI flag or in the configuration file, -# the default for the logs path is a logs subdirectory inside the home path. -#path.logs: ${path.home}/logs - -#============================== Dashboards ===================================== -# These settings control loading the sample dashboards to the Kibana index. Loading -# the dashboards is disabled by default and can be enabled either by setting the -# options here, or by using the `-setup` CLI flag. -#dashboards.enabled: false - -# The URL from where to download the dashboards archive. By default this URL -# has a value which is computed based on the Beat name and version. For released -# versions, this URL points to the dashboard archive on the artifacts.elastic.co -# website. -#dashboards.url: - -# The directory from where to read the dashboards. It is used instead of the URL -# when it has a value. -#dashboards.directory: - -# The file archive (zip file) from where to read the dashboards. It is used instead -# of the URL when it has a value. -#dashboards.file: - -# If this option is enabled, the snapshot URL is used instead of the default URL. -#dashboards.snapshot: false - -# The URL from where to download the snapshot version of the dashboards. By default -# this has a value which is computed based on the Beat name and version. -#dashboards.snapshot_url - -# In case the archive contains the dashboards from multiple Beats, this lets you -# select which one to load. You can load all the dashboards in the archive by -# setting this to the empty string. -#dashboards.beat: beatname - -# The name of the Kibana index to use for setting the configuration. Default is ".kibana" -#dashboards.kibana_index: .kibana - -# The Elasticsearch index name. This overwrites the index name defined in the -# dashboards and index pattern. Example: testbeat-* -#dashboards.index: - -#================================ Logging ====================================== -# There are three options for the log output: syslog, file, stderr. -# Under Windows systems, the log files are per default sent to the file output, -# under all other system per default to syslog. - -# Sets log level. The default log level is info. -# Available log levels are: critical, error, warning, info, debug -#logging.level: info - -# Enable debug output for selected components. To enable all selectors use ["*"] -# Other available selectors are "beat", "publish", "service" -# Multiple selectors can be chained. -#logging.selectors: [ ] - -# Send all logging output to syslog. The default is false. -#logging.to_syslog: true - -# If enabled, beatname periodically logs its internal metrics that have changed -# in the last period. For each metric that changed, the delta from the value at -# the beginning of the period is logged. Also, the total values for -# all non-zero internal metrics are logged on shutdown. The default is true. -#logging.metrics.enabled: true - -# The period after which to log the internal metrics. The default is 30s. -#logging.metrics.period: 30s - -# Logging to rotating files files. Set logging.to_files to false to disable logging to -# files. -logging.to_files: true -logging.files: - # Configure the path where the logs are written. The default is the logs directory - # under the home path (the binary location). - #path: /var/log/beatname - - # The name of the files where the logs are written to. - #name: beatname - - # Configure log file size limit. If limit is reached, log file will be - # automatically rotated - #rotateeverybytes: 10485760 # = 10MB - - # Number of rotated log files to keep. Oldest files will be deleted first. - #keepfiles: 7 diff --git a/contrib/testnets/remote/ansible/roles/remove-datadog-agent/tasks/main.yml b/contrib/testnets/remote/ansible/roles/remove-datadog-agent/tasks/main.yml deleted file mode 100644 index 73b027a22..000000000 --- a/contrib/testnets/remote/ansible/roles/remove-datadog-agent/tasks/main.yml +++ /dev/null @@ -1,12 +0,0 @@ ---- - -- name: Stop datadog service - failed_when: false - service: name=datadog-agent state=stopped - -- name: Uninstall datadg-agent - yum: name=datadog-agent state=absent - -- name: Remove datadog-agent folder - file: path=/etc/datadog-agent state=absent - diff --git a/contrib/testnets/remote/ansible/roles/set-debug/files/sysconfig/gaiacli b/contrib/testnets/remote/ansible/roles/set-debug/files/sysconfig/gaiacli deleted file mode 100644 index 8ef3a7e0c..000000000 --- a/contrib/testnets/remote/ansible/roles/set-debug/files/sysconfig/gaiacli +++ /dev/null @@ -1 +0,0 @@ -DAEMON_COREFILE_LIMIT='unlimited' diff --git a/contrib/testnets/remote/ansible/roles/set-debug/files/sysconfig/gaiad b/contrib/testnets/remote/ansible/roles/set-debug/files/sysconfig/gaiad deleted file mode 100644 index 8ef3a7e0c..000000000 --- a/contrib/testnets/remote/ansible/roles/set-debug/files/sysconfig/gaiad +++ /dev/null @@ -1 +0,0 @@ -DAEMON_COREFILE_LIMIT='unlimited' diff --git a/contrib/testnets/remote/ansible/roles/set-debug/files/sysctl.d/10-procdump b/contrib/testnets/remote/ansible/roles/set-debug/files/sysctl.d/10-procdump deleted file mode 100644 index fbbbe0512..000000000 --- a/contrib/testnets/remote/ansible/roles/set-debug/files/sysctl.d/10-procdump +++ /dev/null @@ -1,3 +0,0 @@ -kernel.core_uses_pid = 1 -kernel.core_pattern = /tmp/core-%e-%s-%u-%g-%p-%t -fs.suid_dumpable = 2 diff --git a/contrib/testnets/remote/ansible/roles/set-debug/handlers/main.yml b/contrib/testnets/remote/ansible/roles/set-debug/handlers/main.yml deleted file mode 100644 index 743ce09bc..000000000 --- a/contrib/testnets/remote/ansible/roles/set-debug/handlers/main.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- - -- name: reload sysctl - command: "/sbin/sysctl -p" diff --git a/contrib/testnets/remote/ansible/roles/set-debug/tasks/main.yml b/contrib/testnets/remote/ansible/roles/set-debug/tasks/main.yml deleted file mode 100644 index 7497dabd8..000000000 --- a/contrib/testnets/remote/ansible/roles/set-debug/tasks/main.yml +++ /dev/null @@ -1,9 +0,0 @@ ---- -# Based on https://www.cyberciti.biz/tips/linux-core-dumps.html - -- name: Copy sysctl and sysconfig files to enable app and daemon core dumps - file: src=. dest=/etc/ - notify: reload sysctl - -- name: Enable debugging for all apps - lineinfile: create=yes line="DAEMON_COREFILE_LIMIT='unlimited'" path=/etc/sysconfig/init regexp=^DAEMON_COREFILE_LIMIT= diff --git a/contrib/testnets/remote/ansible/roles/setup-fullnodes/defaults/main.yml b/contrib/testnets/remote/ansible/roles/setup-fullnodes/defaults/main.yml deleted file mode 100644 index a535d201d..000000000 --- a/contrib/testnets/remote/ansible/roles/setup-fullnodes/defaults/main.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- - -TESTNET_NAME: remotenet - diff --git a/contrib/testnets/remote/ansible/roles/setup-fullnodes/files/gaiad.service b/contrib/testnets/remote/ansible/roles/setup-fullnodes/files/gaiad.service deleted file mode 100644 index 697166567..000000000 --- a/contrib/testnets/remote/ansible/roles/setup-fullnodes/files/gaiad.service +++ /dev/null @@ -1,17 +0,0 @@ -[Unit] -Description=gaiad -Requires=network-online.target -After=network-online.target - -[Service] -Restart=on-failure -User=gaiad -Group=gaiad -PermissionsStartOnly=true -ExecStart=/usr/bin/gaiad start -ExecReload=/bin/kill -HUP $MAINPID -KillSignal=SIGTERM - -[Install] -WantedBy=multi-user.target - diff --git a/contrib/testnets/remote/ansible/roles/setup-fullnodes/handlers/main.yml b/contrib/testnets/remote/ansible/roles/setup-fullnodes/handlers/main.yml deleted file mode 100644 index 97281bff2..000000000 --- a/contrib/testnets/remote/ansible/roles/setup-fullnodes/handlers/main.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- - -- name: reload systemd - systemd: name=pstaked enabled=yes daemon_reload=yes - diff --git a/contrib/testnets/remote/ansible/roles/setup-fullnodes/tasks/main.yml b/contrib/testnets/remote/ansible/roles/setup-fullnodes/tasks/main.yml deleted file mode 100644 index 3d7df5af4..000000000 --- a/contrib/testnets/remote/ansible/roles/setup-fullnodes/tasks/main.yml +++ /dev/null @@ -1,61 +0,0 @@ ---- - -- name: Ensure keys folder exists locally - file: path=keys state=directory - connection: local - run_once: true - become: no - -- name: Create pstaked user - user: name=pstaked home=/home/pstaked shell=/bin/bash - -- name: Copy binary - copy: - src: "{{BINARY}}" - dest: /usr/bin - mode: 0755 - -- name: Copy service file - copy: src=pstaked.service dest=/etc/systemd/system/pstaked.service mode=0755 - notify: reload systemd - -- name: Get node ID - command: "cat /etc/nodeid" - changed_when: false - register: nodeid - -- name: pstaked init - command: "/usr/bin/pstaked init --chain-id={{TESTNET_NAME}} --name=fullnode{{nodeid.stdout_lines[0]}}" - become: yes - become_user: pstaked - register: initresult - args: - creates: /home/pstaked/.gaia/config - -- name: Get wallet word seed from result of initial transaction locally - when: initresult["changed"] - shell: "echo '{{initresult.stdout}}' | python -c 'import json,sys ; print json.loads(\"\".join(sys.stdin.readlines()))[\"app_message\"][\"secret\"]'" - changed_when: false - register: walletkey - connection: local - -- name: Write wallet word seed to local files - when: initresult["changed"] - copy: "content={{walletkey.stdout}} dest=keys/node{{nodeid.stdout_lines[0]}}" - become: no - connection: local - -- name: Copy genesis file - copy: - src: "{{GENESISFILE}}" - dest: /home/pstaked/.gaia/config/genesis.json - become: yes - become_user: pstaked - -- name: Copy config.toml file - copy: - src: "{{CONFIGFILE}}" - dest: /home/pstaked/.gaia/config/config.toml - become: yes - become_user: pstaked - diff --git a/contrib/testnets/remote/ansible/roles/setup-journald/handlers/main.yml b/contrib/testnets/remote/ansible/roles/setup-journald/handlers/main.yml deleted file mode 100644 index 14f3b3376..000000000 --- a/contrib/testnets/remote/ansible/roles/setup-journald/handlers/main.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- - -- name: restart journald - service: name=systemd-journald state=restarted - diff --git a/contrib/testnets/remote/ansible/roles/setup-journald/tasks/main.yml b/contrib/testnets/remote/ansible/roles/setup-journald/tasks/main.yml deleted file mode 100644 index 130da5200..000000000 --- a/contrib/testnets/remote/ansible/roles/setup-journald/tasks/main.yml +++ /dev/null @@ -1,26 +0,0 @@ ---- - -- name: Disable journald rate-limiting - lineinfile: "dest=/etc/systemd/journald.conf regexp={{item.regexp}} line='{{item.line}}'" - with_items: - - { regexp: "^#RateLimitInterval", line: "RateLimitInterval=0s" } - - { regexp: "^#RateLimitBurst", line: "RateLimitBurst=0" } - - { regexp: "^#SystemMaxFileSize", line: "SystemMaxFileSize=100M" } - - { regexp: "^#SystemMaxUse", line: "SystemMaxUse=500M" } - - { regexp: "^#SystemMaxFiles", line: "SystemMaxFiles=10" } - notify: restart journald - -- name: Change logrotate to daily - lineinfile: "dest=/etc/logrotate.conf regexp={{item.regexp}} line='{{item.line}}'" - with_items: - - { regexp: "^weekly", line: "daily" } - - { regexp: "^#compress", line: "compress" } - -- name: Create journal directory for permanent logs - file: path=/var/log/journal state=directory - notify: restart journald - -- name: Set journal folder with systemd-tmpfiles - command: "systemd-tmpfiles --create --prefix /var/log/journal" - notify: restart journald - diff --git a/contrib/testnets/remote/ansible/roles/setup-validators/defaults/main.yml b/contrib/testnets/remote/ansible/roles/setup-validators/defaults/main.yml deleted file mode 100644 index a535d201d..000000000 --- a/contrib/testnets/remote/ansible/roles/setup-validators/defaults/main.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- - -TESTNET_NAME: remotenet - diff --git a/contrib/testnets/remote/ansible/roles/setup-validators/files/gaiad.service b/contrib/testnets/remote/ansible/roles/setup-validators/files/gaiad.service deleted file mode 100644 index 697166567..000000000 --- a/contrib/testnets/remote/ansible/roles/setup-validators/files/gaiad.service +++ /dev/null @@ -1,17 +0,0 @@ -[Unit] -Description=gaiad -Requires=network-online.target -After=network-online.target - -[Service] -Restart=on-failure -User=gaiad -Group=gaiad -PermissionsStartOnly=true -ExecStart=/usr/bin/gaiad start -ExecReload=/bin/kill -HUP $MAINPID -KillSignal=SIGTERM - -[Install] -WantedBy=multi-user.target - diff --git a/contrib/testnets/remote/ansible/roles/setup-validators/handlers/main.yml b/contrib/testnets/remote/ansible/roles/setup-validators/handlers/main.yml deleted file mode 100644 index 97281bff2..000000000 --- a/contrib/testnets/remote/ansible/roles/setup-validators/handlers/main.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- - -- name: reload systemd - systemd: name=pstaked enabled=yes daemon_reload=yes - diff --git a/contrib/testnets/remote/ansible/roles/setup-validators/tasks/main.yml b/contrib/testnets/remote/ansible/roles/setup-validators/tasks/main.yml deleted file mode 100644 index 30c18aa86..000000000 --- a/contrib/testnets/remote/ansible/roles/setup-validators/tasks/main.yml +++ /dev/null @@ -1,78 +0,0 @@ ---- - -- name: Ensure keys folder exists locally - file: path=keys state=directory - connection: local - run_once: true - become: no - -- name: Create pstaked user - user: name=pstaked home=/home/pstaked shell=/bin/bash - -- name: Copy binary - copy: - src: "{{BINARY}}" - dest: /usr/bin - mode: 0755 - -- name: Copy service file - copy: src=pstaked.service dest=/etc/systemd/system/pstaked.service mode=0755 - notify: reload systemd - -- name: Get node ID - command: "cat /etc/nodeid" - changed_when: false - register: nodeid - -- name: Create initial transaction - command: "/usr/bin/pstaked init gen-tx --name=node{{nodeid.stdout_lines[0]}} --ip={{inventory_hostname}}" - register: gentxresult - become: yes - become_user: pstaked - args: - creates: /home/pstaked/.gaia/config/gentx - -- name: Get wallet word seed from result of initial transaction locally - when: gentxresult["changed"] - shell: "echo '{{gentxresult.stdout}}' | python -c 'import json,sys ; print json.loads(\"\".join(sys.stdin.readlines()))[\"app_message\"][\"secret\"]'" - changed_when: false - register: walletkey - connection: local - -- name: Write wallet word seed to local files - when: gentxresult["changed"] - copy: "content={{walletkey.stdout}} dest=keys/node{{nodeid.stdout_lines[0]}}" - become: no - connection: local - -- name: Find gentx file - command: "ls /home/pstaked/.gaia/config/gentx" - changed_when: false - register: gentxfile - -- name: Clear local gen-tx list - file: path=files/ state=absent - connection: local - run_once: yes - -- name: Get gen-tx file - fetch: - dest: files/ - src: "/home/pstaked/.gaia/config/gentx/{{gentxfile.stdout_lines[0]}}" - flat: yes - -- name: Compress gathered gen-tx files locally - archive: path=files/ exclude_path=files/gen-tx.tgz dest=files/gen-tx.tgz - run_once: yes - connection: local - -- name: Unpack gen-tx archive - unarchive: src=files/gen-tx.tgz dest=/home/pstaked/.gaia/config/gentx owner=pstaked - -- name: Generate genesis.json - command: "/usr/bin/pstaked init --with-txs --name=node{{nodeid.stdout_lines[0]}} --chain-id={{TESTNET_NAME}}" - become: yes - become_user: pstaked - args: - creates: /home/pstaked/.gaia/config/genesis.json - diff --git a/contrib/testnets/remote/ansible/roles/start/tasks/main.yml b/contrib/testnets/remote/ansible/roles/start/tasks/main.yml deleted file mode 100644 index 6bc611c91..000000000 --- a/contrib/testnets/remote/ansible/roles/start/tasks/main.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- - -- name: start service - service: "name={{service}} state=started" - diff --git a/contrib/testnets/remote/ansible/roles/stop/tasks/main.yml b/contrib/testnets/remote/ansible/roles/stop/tasks/main.yml deleted file mode 100644 index 7db356f22..000000000 --- a/contrib/testnets/remote/ansible/roles/stop/tasks/main.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- - -- name: stop service - service: "name={{service}} state=stopped" - diff --git a/contrib/testnets/remote/ansible/roles/update-datadog-agent/files/conf.d/http_check.d/conf.yml b/contrib/testnets/remote/ansible/roles/update-datadog-agent/files/conf.d/http_check.d/conf.yml deleted file mode 100644 index 43b172b3b..000000000 --- a/contrib/testnets/remote/ansible/roles/update-datadog-agent/files/conf.d/http_check.d/conf.yml +++ /dev/null @@ -1,13 +0,0 @@ -init_config: - -instances: - - name: pstaked - url: http://localhost:26657/status - timeout: 1 - content_match: '"latest_block_height": "0",' - reverse_content_match: true - - - name: gaiacli - url: http://localhost:1317/node_version - timeout: 1 - diff --git a/contrib/testnets/remote/ansible/roles/update-datadog-agent/files/conf.d/network.d/conf.yml b/contrib/testnets/remote/ansible/roles/update-datadog-agent/files/conf.d/network.d/conf.yml deleted file mode 100644 index b174490fc..000000000 --- a/contrib/testnets/remote/ansible/roles/update-datadog-agent/files/conf.d/network.d/conf.yml +++ /dev/null @@ -1,9 +0,0 @@ -init_config: - -instances: - - collect_connection_state: true - excluded_interfaces: - - lo - - lo0 - collect_rate_metrics: true - collect_count_metrics: true diff --git a/contrib/testnets/remote/ansible/roles/update-datadog-agent/files/conf.d/process.d/conf.yml b/contrib/testnets/remote/ansible/roles/update-datadog-agent/files/conf.d/process.d/conf.yml deleted file mode 100644 index eab499df2..000000000 --- a/contrib/testnets/remote/ansible/roles/update-datadog-agent/files/conf.d/process.d/conf.yml +++ /dev/null @@ -1,15 +0,0 @@ -init_config: - -instances: -- name: ssh - search_string: ['ssh', 'sshd'] - thresholds: - critical: [1, 5] -- name: pstaked - search_string: ['pstaked'] - thresholds: - critical: [1, 1] -- name: gaiacli - search_string: ['gaiacli'] - thresholds: - critical: [1, 1] diff --git a/contrib/testnets/remote/ansible/roles/update-datadog-agent/files/conf.d/prometheus.d/conf.yml b/contrib/testnets/remote/ansible/roles/update-datadog-agent/files/conf.d/prometheus.d/conf.yml deleted file mode 100644 index 20c04ceee..000000000 --- a/contrib/testnets/remote/ansible/roles/update-datadog-agent/files/conf.d/prometheus.d/conf.yml +++ /dev/null @@ -1,10 +0,0 @@ -init_config: - -instances: - - prometheus_url: http://127.0.0.1:26660 - metrics: - - go* - - mempool* - - p2p* - - process* - - promhttp* diff --git a/contrib/testnets/remote/ansible/roles/update-datadog-agent/handlers/main.yml b/contrib/testnets/remote/ansible/roles/update-datadog-agent/handlers/main.yml deleted file mode 100644 index 90e05c17d..000000000 --- a/contrib/testnets/remote/ansible/roles/update-datadog-agent/handlers/main.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- - -- name: restart datadog-agent - service: name=datadog-agent state=restarted - diff --git a/contrib/testnets/remote/ansible/roles/update-datadog-agent/tasks/main.yml b/contrib/testnets/remote/ansible/roles/update-datadog-agent/tasks/main.yml deleted file mode 100644 index c6174c6af..000000000 --- a/contrib/testnets/remote/ansible/roles/update-datadog-agent/tasks/main.yml +++ /dev/null @@ -1,10 +0,0 @@ ---- - -- name: Set datadog.yaml config - template: src=datadog.yaml.j2 dest=/etc/datadog-agent/datadog.yaml - notify: restart datadog-agent - -- name: Set metrics config - copy: src=conf.d/ dest=/etc/datadog-agent/conf.d/ - notify: restart datadog-agent - diff --git a/contrib/testnets/remote/ansible/roles/update-datadog-agent/templates/datadog.yaml.j2 b/contrib/testnets/remote/ansible/roles/update-datadog-agent/templates/datadog.yaml.j2 deleted file mode 100644 index 3c2e031dd..000000000 --- a/contrib/testnets/remote/ansible/roles/update-datadog-agent/templates/datadog.yaml.j2 +++ /dev/null @@ -1,561 +0,0 @@ - -# The host of the Datadog intake server to send Agent data to -dd_url: https://app.datadoghq.com - -# The Datadog api key to associate your Agent's data with your organization. -# Can be found here: -# https://app.datadoghq.com/account/settings -api_key: {{DD_API_KEY}} - -# If you need a proxy to connect to the Internet, provide it here (default: -# disabled). You can use the 'no_proxy' list to specify hosts that should -# bypass the proxy. These settings might impact your checks requests, please -# refer to the specific check documentation for more details. Environment -# variables HTTP_PROXY, HTTPS_PROXY and NO_PROXY (coma-separated string) will -# override the values set here. See https://docs.datadoghq.com/agent/proxy/. -# -# proxy: -# http: http(s)://user:password@proxy_for_http:port -# https: http(s)://user:password@proxy_for_https:port -# no_proxy: -# - host1 -# - host2 - -# Setting this option to "yes" will tell the agent to skip validation of SSL/TLS certificates. -# This may be necessary if the agent is running behind a proxy. See this page for details: -# https://github.com/DataDog/dd-agent/wiki/Proxy-Configuration#using-haproxy-as-a-proxy -# skip_ssl_validation: no - -# Setting this option to "yes" will force the agent to only use TLS 1.2 when -# pushing data to the url specified in "dd_url". -force_tls_12: yes - -# Force the hostname to whatever you want. (default: auto-detected) -hostname: {{inventory_hostname | replace ("_","-")}} - -# Make the agent use "hostname -f" on unix-based systems as a last resort -# way of determining the hostname instead of Golang "os.Hostname()" -# This will be enabled by default in version 6.4 -# More information at https://dtdg.co/flag-hostname-fqdn -# hostname_fqdn: false - -# Set the host's tags (optional) -tags: ['testnet:{{TESTNET_NAME}}','cluster:{{CLUSTER_NAME}}'] -# - mytag -# - env:prod -# - role:database - -# Histogram and Historate configuration -# -# Configure which aggregated value to compute. Possible values are: min, max, -# median, avg, sum and count. -# -# histogram_aggregates: ["max", "median", "avg", "count"] -# -# Configure which percentiles will be computed. Must be a list of float -# between 0 and 1. -# Warning: percentiles must be specified as yaml strings -# -# histogram_percentiles: ["0.95"] -# -# Copy histogram values to distributions for true global distributions (in beta) -# This will increase the number of custom metrics created -# histogram_copy_to_distribution: false -# -# A prefix to add to distribution metrics created when histogram_copy_to_distributions is true -# histogram_copy_to_distribution_prefix: "" - -# Forwarder timeout in seconds -# forwarder_timeout: 20 - -# The forwarder retries failed requests. Use this setting to change the -# maximum length of the forwarder's retry queue (each request in the queue -# takes no more than 2MB in memory) -# forwarder_retry_queue_max_size: 30 - -# The number of workers used by the forwarder. Please note each worker will -# open an outbound HTTP connection towards Datadog's metrics intake at every -# flush. -# forwarder_num_workers: 1 - -# Collect AWS EC2 custom tags as agent tags -collect_ec2_tags: true - -# The path containing check configuration files -# By default, uses the conf.d folder located in the agent configuration folder. -# confd_path: - -# Additional path where to search for Python checks -# By default, uses the checks.d folder located in the agent configuration folder. -# additional_checksd: - -# The port for the go_expvar server -# expvar_port: 5000 - -# The port on which the IPC api listens -# cmd_port: 5001 - -# The port for the browser GUI to be served -# Setting 'GUI_port: -1' turns off the GUI completely -# Default is '5002' on Windows and macOS ; turned off on Linux -# GUI_port: -1 - -# The Agent runs workers in parallel to execute checks. By default the number -# of workers is set to 1. If set to 0 the agent will automatically determine -# the best number of runners needed based on the number of checks running. This -# would optimize the check collection time but may produce CPU spikes. -# check_runners: 1 - -# Metadata collection should always be enabled, except if you are running several -# agents/dsd instances per host. In that case, only one agent should have it on. -# WARNING: disabling it on every agent will lead to display and billing issues -# enable_metadata_collection: true - -# Enable the gohai collection of systems data -# enable_gohai: true - -# IPC api server timeout in seconds -# server_timeout: 15 - -# Some environments may have the procfs file system mounted in a miscellaneous -# location. The procfs_path configuration parameter provides a mechanism to -# override the standard default location: '/proc' - this setting will trickle -# down to integrations and affect their behavior if they rely on the psutil -# python package. -# procfs_path: /proc - -# BETA: Encrypted Secrets (Linux only) -# -# This feature is in beta and its options or behaviour might break between -# minor or bugfix releases of the Agent. -# -# The agent can call an external command to fetch secrets. The command will be -# executed maximum once per instance containing an encrypted password. -# Secrets are cached by the agent, this will avoid executing again the -# secret_backend_command to fetch an already known secret (useful when combine -# with Autodiscovery). This feature is still in beta. -# -# For more information see: https://github.com/DataDog/datadog-agent/blob/master/docs/agent/secrets.md -# -# Path to the script to execute. The script must belong to the same user used -# to run the agent. Executable right must be given to the agent and no rights -# for 'group' or 'other'. -# secret_backend_command: /path/to/command -# -# A list of arguments to give to the command at each run (optional) -# secret_backend_arguments: -# - argument1 -# - argument2 -# -# The size in bytes of the buffer used to store the command answer (apply to -# both stdout and stderr) -# secret_backend_output_max_size: 1024 -# -# The timeout to execute the command in second -# secret_backend_timeout: 5 - - -# Metadata providers, add or remove from the list to enable or disable collection. -# Intervals are expressed in seconds. You can also set a provider's interval to 0 -# to disable it. -# metadata_providers: -# - name: k8s -# interval: 60 - -# DogStatsd -# -# If you don't want to enable the DogStatsd server, set this option to no -# use_dogstatsd: yes -# -# Make sure your client is sending to the same UDP port -# dogstatsd_port: 8125 -# -# The host to bind to receive external metrics (used only by the dogstatsd -# server for now). For dogstatsd this is ignored if -# 'dogstatsd_non_local_traffic' is set to true -# bind_host: localhost -# -# Dogstatsd can also listen for metrics on a Unix Socket (*nix only). -# Set to a valid filesystem path to enable. -# dogstatsd_socket: /var/run/dogstatsd/dsd.sock -# -# When using Unix Socket, dogstatsd can tag metrics with container metadata. -# If running dogstatsd in a container, host PID mode (e.g. with --pid=host) is required. -# dogstatsd_origin_detection: false -# -# The buffer size use to receive statsd packet, in bytes -# dogstatsd_buffer_size: 1024 -# -# Whether dogstatsd should listen to non local UDP traffic -# dogstatsd_non_local_traffic: no -# -# Publish dogstatsd's internal stats as Go expvars -# dogstatsd_stats_enable: no -# -# How many items in the dogstatsd's stats circular buffer -# dogstatsd_stats_buffer: 10 -# -# The port for the go_expvar server -# dogstatsd_stats_port: 5000 -# -# The number of bytes allocated to dogstatsd's socket receive buffer (POSIX -# system only). By default, this value is set by the system. If you need to -# increase the size of this buffer but keep the OS default value the same, you -# can set dogstatsd's receive buffer size here. The maximum accepted value -# might change depending on the OS. -# dogstatsd_so_rcvbuf: -# -# If you want to forward every packet received by the dogstatsd server -# to another statsd server, uncomment these lines. -# WARNING: Make sure that forwarded packets are regular statsd packets and not "dogstatsd" packets, -# as your other statsd server might not be able to handle them. -# statsd_forward_host: address_of_own_statsd_server -# statsd_forward_port: 8125 -# -# If you want all statsd metrics coming from this host to be namespaced -# you can configure the namspace below. Each metric received will be prefixed -# with the namespace before it's sent to Datadog. -# statsd_metric_namespace: - -# Logs agent -# -# Logs agent is disabled by default -#logs_enabled: true -# -# Enable logs collection for all containers, disabled by default -# logs_config: -# container_collect_all: false -# - -# JMX -# -# jmx_pipe_path: -# jmx_pipe_name: dd-auto_discovery -# -# If you only run Autodiscovery tests, jmxfetch might fail to pick up custom_jar_paths -# set in the check templates. If that is the case, you can force custom jars here. -# jmx_custom_jars: -# - /jmx-jars/jboss-cli-client.jar -# -# When running in a memory cgroup, openjdk 8u131 and higher can automatically adjust -# its heap memory usage in accordance to the cgroup/container's memory limit. -# Default is false: we'll set a Xmx of 200MB if none is configured. -# Note: older openjdk versions and other jvms might fail to start if this option is set -# -# jmx_use_cgroup_memory_limit: true -# - -# Autoconfig -# -# Directory containing configuration templates -# autoconf_template_dir: /datadog/check_configs -# -# The providers the Agent should call to collect checks configurations. -# Please note the File Configuration Provider is enabled by default and cannot -# be configured. -# config_providers: - -## The kubelet provider handles templates embedded in pod annotations, see -## https://docs.datadoghq.com/guides/autodiscovery/#template-source-kubernetes-pod-annotations -# - name: kubelet -# polling: true - -## The docker provider handles templates embedded in container labels, see -## https://docs.datadoghq.com/guides/autodiscovery/#template-source-docker-label-annotations -# - name: docker -# polling: true - -# - name: etcd -# polling: true -# template_dir: /datadog/check_configs -# template_url: http://127.0.0.1 -# username: -# password: - -# - name: consul -# polling: true -# template_dir: /datadog/check_configs -# template_url: http://127.0.0.1 -# ca_file: -# ca_path: -# cert_file: -# key_file: -# username: -# password: -# token: - -# - name: zookeeper -# polling: true -# template_dir: /datadog/check_configs -# template_url: 127.0.0.1 -# username: -# password: - -# Logging -# -# log_level: info -# log_file: /var/log/datadog/agent.log - -# Set to 'yes' to output logs in JSON format -# log_format_json: no - -# Set to 'no' to disable logging to stdout -# log_to_console: yes - -# Set to 'yes' to disable logging to the log file -# disable_file_logging: no - -# Set to 'yes' to enable logging to syslog. -# -# log_to_syslog: no -# -# If 'syslog_uri' is left undefined/empty, a local domain socket connection will be attempted -# -# syslog_uri: -# -# Set to 'yes' to output in an RFC 5424-compliant format -# -# syslog_rfc: no -# -# If TLS enabled, you must specify a path to a PEM certificate here -# -# syslog_pem: /path/to/certificate.pem -# -# If TLS enabled, you must specify a path to a private key here -# -# syslog_key: /path/to/key.pem -# -# If TLS enabled, you may enforce TLS verification here (defaults to true) -# -# syslog_tls_verify: yes -# - -# Autodiscovery -# -# Change the root directory to look at to get cgroup statistics. Useful when running inside a -# container with host directories mounted on a different folder. -# Default if environment variable "DOCKER_DD_AGENT" is set to "yes" -# "/host/sys/fs/cgroup" and "/sys/fs/cgroup" if not. -# -# container_cgroup_root: /host/sys/fs/cgroup/ -# -# Change the root directory to look at to get proc statistics. Useful when running inside a -# container with host directories mounted on a different folder. -# Default if environment variable "DOCKER_DD_AGENT" is set to "yes" -# "/host/proc" and "/proc" if not. -# -# container_proc_root: /host/proc -# -# Choose "auto" if you want to let the agent find any relevant listener on your host -# At the moment, the only auto listener supported is docker -# If you have already set docker anywhere in the listeners, the auto listener is ignored -# listeners: -# - name: auto -# - name: docker -# -# Exclude containers from metrics and AD based on their name or image: -# An excluded container will not get any individual container metric reported for it. -# Please note that the `docker.containers.running`, `.stopped`, `.running.total` and -# `.stopped.total` metrics are not affected by these settings and always count all -# containers. This does not affect your per-container billing. -# -# How it works: include first. -# If a container matches an exclude rule, it won't be included unless it first matches an include rule. -# -# Rules are regexp. -# -# Examples: -# exclude all, except containers based on the 'ubuntu' image or the 'debian' image. -# ac_exclude: ["image:.*"] -# ac_include: ["image:ubuntu", "image:debian"] -# -# include all, except containers based on the 'ubuntu' image. -# ac_exclude: ["image:ubuntu"] -# ac_include: [] -# -# exclude all debian images except containers with a name starting with 'frontend'. -# ac_exclude: ["image:debian"] -# ac_include: ["name:frontend.*"] -# -# ac_exclude: [] -# ac_include: [] -# -# -# Exclude default pause containers from orchestrators. -# -# By default the agent will not monitor kubernetes/openshift pause -# container. They will still be counted in the container count (just like -# excluded containers) since ignoring them would give a wrong impression -# about the docker daemon load. -# -# exclude_pause_container: true - -# Exclude default containers from DockerCloud: -# The following configuration will instruct the agent to ignore the containers from Docker Cloud. -# You can remove the ones you want to collect. -# ac_exclude: ["image:dockercloud/network-daemon","image:dockercloud/cleanup","image:dockercloud/logrotate","image:dockercloud/events","image:dockercloud/ntpd"] -# ac_include: [] -# -# You can also use the regex to ignore them all: -# ac_exclude: ["image:dockercloud/*"] -# ac_include: [] -# -# The default timeout value when connecting to the docker daemon -# is 5 seconds. It can be configured with this option. -# docker_query_timeout: 5 -# - -# Docker tag extraction -# -# We can extract container label or environment variables -# as metric tags. If you prefix your tag name with +, it -# will only be added to high cardinality metrics (docker check) -# -# docker_labels_as_tags: -# label_name: tag_name -# high_cardinality_label_name: +tag_name -# docker_env_as_tags: -# ENVVAR_NAME: tag_name -# -# Example: -# docker_labels_as_tags: -# com.docker.compose.service: service_name -# com.docker.compose.project: +project_name -# - -# Kubernetes tag extraction -# -# We can extract pod labels and annotations as metric tags. If you prefix your -# tag name with +, it will only be added to high cardinality metrics -# -# kubernetes_pod_labels_as_tags: -# app: kube_app -# pod-template-hash: +kube_pod-template-hash -# -# kubernetes_pod_annotations_as_tags: -# app: kube_app -# pod-template-hash: +kube_pod-template-hash -# - -# ECS integration -# -# URL where the ECS agent can be found. Standard cases will be autodetected. -# ecs_agent_url: http://localhost:51678 -# - -# Kubernetes kubelet connectivity -# -# The kubelet host and port should be autodetected when running inside a pod. -# If you run into connectivity issues, you can set these options according to -# your cluster setup: -# kubernetes_kubelet_host: autodetected -# kubernetes_http_kubelet_port: 10255 -# kubernetes_https_kubelet_port: 10250 -# -# When using HTTPS, we verify the kubelet's certificate, you can tune this: -# kubelet_tls_verify: true -# kubelet_client_ca: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt -# -# If authentication is needed, the agent will use the pod's serviceaccount's -# credentials. If you want to use a different account, or are running the agent -# on the host, you can set the credentials to use here: -# kubelet_auth_token_path: /path/to/file -# kubelet_client_crt: /path/to/key -# kubelet_client_key: /path/to/key -# - -# Kubernetes apiserver integration -# -# When running in a pod, the agent will automatically use the pod's serviceaccount -# to authenticate with the apiserver. If you wish to install the agent out of a pod -# or customise connection parameters, you can provide the path to a KubeConfig file -# see https://kubernetes.io/docs/tasks/access-application-cluster/configure-access-multiple-clusters/ -# -# kubernetes_kubeconfig_path: /path/to/file -# -# In order to collect Kubernetes service names, the agent needs certain rights (see RBAC documentation in -# [docker readme](https://github.com/DataDog/datadog-agent/blob/master/Dockerfiles/agent/README.md#kubernetes)). -# You can disable this option or set how often (in seconds) the agent refreshes the internal mapping of services to -# ContainerIDs with the following options: -# kubernetes_collect_metadata_tags: true -# kubernetes_metadata_tag_update_freq: 60 -# kubernetes_apiserver_client_timeout: 10 -# kubernetes_apiserver_poll_freq: 30 -# -# To collect Kubernetes events, leader election must be enabled and collect_kubernetes_events set to true. -# Only the leader will collect events. More details about events [here](https://github.com/DataDog/datadog-agent/blob/master/Dockerfilesagent/README.md#event-collection). -# collect_kubernetes_events: false -# -# -# Leader Election settings, more details about leader election [here](https://github.com/DataDog/datadog-agent/blob/master/Dockerfilesagent/README.md#leader-election) -# To enable the leader election on this node, set the leader_election variable to true. -# leader_election: false -# The leader election lease is an integer in seconds. -# leader_lease_duration: 60 -# -# Node labels that should be collected and their name in host tags. Off by default. -# Some of these labels are redundant with metadata collected by -# cloud provider crawlers (AWS, GCE, Azure) -# -# kubernetes_node_labels_as_tags: -# kubernetes.io/hostname: nodename -# beta.kubernetes.io/os: os - -# Process agent specific settings -# -process_config: -# A string indicating the enabled state of the Process Agent. -# If "false" (the default) it will only collect containers. -# If "true" it will collect containers and processes. -# If "disabled" it will be disabled altogether and won't start. - enabled: "true" -# The full path to the file where process-agent logs will be written. -# log_file: -# The interval, in seconds, at which we will run each check. If you want consistent -# behavior between real-time you may set the Container/ProcessRT intervals to 10. -# Defaults to 10s for normal checks and 2s for others. -# intervals: -# container: -# container_realtime: -# process: -# process_realtime: -# A list of regex patterns that will exclude a process if matched. -# blacklist_patterns: -# How many check results to buffer in memory when POST fails. The default is usually fine. -# queue_size: -# The maximum number of file descriptors to open when collecting net connections. -# Only change if you are running out of file descriptors from the Agent. -# max_proc_fds: -# The maximum number of processes or containers per message. -# Only change if the defaults are causing issues. -# max_per_message: -# Overrides the path to the Agent bin used for getting the hostname. The default is usually fine. -# dd_agent_bin: -# Overrides of the environment we pass to fetch the hostname. The default is usually fine. -# dd_agent_env: - -# Trace Agent Specific Settings -# -# apm_config: -# Whether or not the APM Agent should run -# enabled: true -# The environment tag that Traces should be tagged with -# Will inherit from "env" tag if none is applied here -# env: none -# The port that the Receiver should listen on -# receiver_port: 8126 -# Whether the Trace Agent should listen for non local traffic -# Only enable if Traces are being sent to this Agent from another host/container -# apm_non_local_traffic: false -# Extra global sample rate to apply on all the traces -# This sample rate is combined to the sample rate from the sampler logic, still promoting interesting traces -# From 1 (no extra rate) to 0 (don't sample at all) -# extra_sample_rate: 1.0 -# Maximum number of traces per second to sample. -# The limit is applied over an average over a few minutes ; much bigger spikes are possible. -# Set to 0 to disable the limit. -# max_traces_per_second: 10 -# A blacklist of regular expressions can be provided to disable certain traces based on their resource name -# all entries must be surrounded by double quotes and separated by commas -# Example: ["(GET|POST) /healthcheck", "GET /V1"] -# ignore_resources: [] diff --git a/contrib/testnets/remote/ansible/roles/upgrade-gaiad/handlers/main.yml b/contrib/testnets/remote/ansible/roles/upgrade-gaiad/handlers/main.yml deleted file mode 100644 index 7cca73d4d..000000000 --- a/contrib/testnets/remote/ansible/roles/upgrade-gaiad/handlers/main.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- - -- name: restart pstaked - service: name=pstaked state=restarted - diff --git a/contrib/testnets/remote/ansible/roles/upgrade-gaiad/tasks/main.yml b/contrib/testnets/remote/ansible/roles/upgrade-gaiad/tasks/main.yml deleted file mode 100644 index a35c4e537..000000000 --- a/contrib/testnets/remote/ansible/roles/upgrade-gaiad/tasks/main.yml +++ /dev/null @@ -1,29 +0,0 @@ ---- - -- name: Copy binary - copy: - src: "{{BINARY}}" - dest: /usr/bin/pstaked - mode: 0755 - notify: restart pstaked - -- name: Copy new genesis.json file, if available - when: "GENESISFILE is defined and GENESISFILE != ''" - copy: - src: "{{GENESISFILE}}" - dest: /home/pstaked/.gaia/config/genesis.json - notify: restart pstaked - -- name: Download genesis.json URL, if available - when: "GENESISURL is defined and GENESISURL != ''" - get_url: - url: "{{GENESISURL}}" - dest: /home/pstaked/.gaia/config/genesis.json - force: yes - notify: restart pstaked - -- name: Reset network - when: UNSAFE_RESET_ALL | default(false) | bool - command: "sudo -u pstaked pstaked unsafe-reset-all" - notify: restart pstaked - diff --git a/contrib/testnets/remote/ansible/set-debug.yml b/contrib/testnets/remote/ansible/set-debug.yml deleted file mode 100644 index 76ee1b357..000000000 --- a/contrib/testnets/remote/ansible/set-debug.yml +++ /dev/null @@ -1,8 +0,0 @@ ---- - -- hosts: all - any_errors_fatal: true - gather_facts: no - roles: - - set-debug - diff --git a/contrib/testnets/remote/ansible/setup-fullnodes.yml b/contrib/testnets/remote/ansible/setup-fullnodes.yml deleted file mode 100644 index da1810d1d..000000000 --- a/contrib/testnets/remote/ansible/setup-fullnodes.yml +++ /dev/null @@ -1,13 +0,0 @@ ---- - -#GENESISFILE required -#CONFIGFILE required -#BINARY required - -- hosts: all - any_errors_fatal: true - gather_facts: no - roles: - - increase-openfiles - - setup-fullnodes - diff --git a/contrib/testnets/remote/ansible/setup-journald.yml b/contrib/testnets/remote/ansible/setup-journald.yml deleted file mode 100644 index 369c483f3..000000000 --- a/contrib/testnets/remote/ansible/setup-journald.yml +++ /dev/null @@ -1,10 +0,0 @@ ---- - -#DD_API_KEY - -- hosts: all - any_errors_fatal: true - gather_facts: no - roles: - - setup-journald - diff --git a/contrib/testnets/remote/ansible/setup-validators.yml b/contrib/testnets/remote/ansible/setup-validators.yml deleted file mode 100644 index 0e6f2959a..000000000 --- a/contrib/testnets/remote/ansible/setup-validators.yml +++ /dev/null @@ -1,9 +0,0 @@ ---- - -- hosts: all - any_errors_fatal: true - gather_facts: no - roles: - - increase-openfiles - - setup-validators - diff --git a/contrib/testnets/remote/ansible/start.yml b/contrib/testnets/remote/ansible/start.yml deleted file mode 100644 index c590c14a8..000000000 --- a/contrib/testnets/remote/ansible/start.yml +++ /dev/null @@ -1,10 +0,0 @@ ---- - -- hosts: all - any_errors_fatal: true - gather_facts: no - vars: - - service: pstaked - roles: - - start - diff --git a/contrib/testnets/remote/ansible/status.yml b/contrib/testnets/remote/ansible/status.yml deleted file mode 100644 index ebd7f72ee..000000000 --- a/contrib/testnets/remote/ansible/status.yml +++ /dev/null @@ -1,17 +0,0 @@ ---- - -- hosts: all - connection: local - any_errors_fatal: true - gather_facts: no - - tasks: - - name: Gather status - uri: - body_format: json - url: "http://{{ansible_host}}:26657/status" - register: status - - - name: Print status - debug: var=status.json.result - diff --git a/contrib/testnets/remote/ansible/stop.yml b/contrib/testnets/remote/ansible/stop.yml deleted file mode 100644 index 7c8899d92..000000000 --- a/contrib/testnets/remote/ansible/stop.yml +++ /dev/null @@ -1,10 +0,0 @@ ---- - -- hosts: all - any_errors_fatal: true - gather_facts: no - vars: - - service: pstaked - roles: - - stop - diff --git a/contrib/testnets/remote/ansible/update-datadog-agent.yml b/contrib/testnets/remote/ansible/update-datadog-agent.yml deleted file mode 100644 index 3fe1e0006..000000000 --- a/contrib/testnets/remote/ansible/update-datadog-agent.yml +++ /dev/null @@ -1,10 +0,0 @@ ---- - -#DD_API_KEY,TESTNET_NAME,CLUSTER_NAME required - -- hosts: all - any_errors_fatal: true - gather_facts: no - roles: - - update-datadog-agent - diff --git a/contrib/testnets/remote/ansible/upgrade-gaia.yml b/contrib/testnets/remote/ansible/upgrade-gaia.yml deleted file mode 100644 index d46382201..000000000 --- a/contrib/testnets/remote/ansible/upgrade-gaia.yml +++ /dev/null @@ -1,9 +0,0 @@ ---- - -- hosts: all - any_errors_fatal: true - gather_facts: no - roles: - - upgrade-pstaked - - add-lcd - diff --git a/contrib/testnets/remote/ansible/upgrade-gaiad.yml b/contrib/testnets/remote/ansible/upgrade-gaiad.yml deleted file mode 100644 index caa4ee609..000000000 --- a/contrib/testnets/remote/ansible/upgrade-gaiad.yml +++ /dev/null @@ -1,11 +0,0 @@ ---- - -# Required: BINARY -# Optional: GENESISFILE, UNSAFE_RESET_ALL - -- hosts: all - any_errors_fatal: true - gather_facts: no - roles: - - upgrade-pstaked - diff --git a/contrib/testnets/remote/terraform-app/.gitignore b/contrib/testnets/remote/terraform-app/.gitignore deleted file mode 100644 index d882c9444..000000000 --- a/contrib/testnets/remote/terraform-app/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -.terraform -terraform.tfstate -terraform.tfstate.backup -terraform.tfstate.d -.terraform.tfstate.lock.info diff --git a/contrib/testnets/remote/terraform-app/files/terraform.sh b/contrib/testnets/remote/terraform-app/files/terraform.sh deleted file mode 100644 index ba7c6eeb0..000000000 --- a/contrib/testnets/remote/terraform-app/files/terraform.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash -# Script to initialize a testnet settings on a server - -#Usage: terraform.sh - -#Add pstaked node number for remote identification -echo "$2" > /etc/nodeid - diff --git a/contrib/testnets/remote/terraform-app/infra/attachment.tf b/contrib/testnets/remote/terraform-app/infra/attachment.tf deleted file mode 100644 index 1ba5f4fe5..000000000 --- a/contrib/testnets/remote/terraform-app/infra/attachment.tf +++ /dev/null @@ -1,21 +0,0 @@ -# This is the reason why we can't separate nodes and load balancer creation into different modules. -# https://github.com/hashicorp/terraform/issues/10857 -# In short: the list of instances coming from the nodes module is a generated variable -# and it should be the input for the load-balancer generation. However when attaching the instances -# to the load-balancer, aws_lb_target_group_attachment.count cannot be a generated value. - -#Instance Attachment (autoscaling is the future) -resource "aws_lb_target_group_attachment" "lb_attach" { - count = "${var.SERVERS*min(length(data.aws_availability_zones.zones.names),var.max_zones)}" - target_group_arn = "${aws_lb_target_group.lb_target_group.arn}" - target_id = "${element(aws_instance.node.*.id,count.index)}" - port = 26657 -} - -resource "aws_lb_target_group_attachment" "lb_attach_lcd" { - count = "${var.SERVERS*min(length(data.aws_availability_zones.zones.names),var.max_zones)}" - target_group_arn = "${aws_lb_target_group.lb_target_group_lcd.arn}" - target_id = "${element(aws_instance.node.*.id,count.index)}" - port = 1317 -} - diff --git a/contrib/testnets/remote/terraform-app/infra/instance.tf b/contrib/testnets/remote/terraform-app/infra/instance.tf deleted file mode 100644 index 53b21e62d..000000000 --- a/contrib/testnets/remote/terraform-app/infra/instance.tf +++ /dev/null @@ -1,58 +0,0 @@ -resource "aws_key_pair" "key" { - key_name = "${var.name}" - public_key = "${file(var.ssh_public_file)}" -} - -data "aws_ami" "linux" { - most_recent = true - filter { - name = "name" - values = ["${var.image_name}"] - } -} - -resource "aws_instance" "node" { -# depends_on = ["${element(aws_route_table_association.route_table_association.*,count.index)}"] - count = "${var.SERVERS*min(length(data.aws_availability_zones.zones.names),var.max_zones)}" - ami = "${data.aws_ami.linux.image_id}" - instance_type = "${var.instance_type}" - key_name = "${aws_key_pair.key.key_name}" - associate_public_ip_address = true - vpc_security_group_ids = [ "${aws_security_group.secgroup.id}" ] - subnet_id = "${element(aws_subnet.subnet.*.id,count.index)}" - availability_zone = "${element(data.aws_availability_zones.zones.names,count.index)}" - - tags { - Environment = "${var.name}" - Name = "${var.name}-${element(data.aws_availability_zones.zones.names,count.index)}" - } - - volume_tags { - Environment = "${var.name}" - Name = "${var.name}-${element(data.aws_availability_zones.zones.names,count.index)}-VOLUME" - } - - root_block_device { - volume_size = 40 - } - - connection { - user = "centos" - private_key = "${file(var.ssh_private_file)}" - timeout = "600s" - } - - provisioner "file" { - source = "files/terraform.sh" - destination = "/tmp/terraform.sh" - } - - provisioner "remote-exec" { - inline = [ - "chmod +x /tmp/terraform.sh", - "sudo /tmp/terraform.sh ${var.name} ${count.index}", - ] - } - -} - diff --git a/contrib/testnets/remote/terraform-app/infra/lb.tf b/contrib/testnets/remote/terraform-app/infra/lb.tf deleted file mode 100644 index 201a53ffd..000000000 --- a/contrib/testnets/remote/terraform-app/infra/lb.tf +++ /dev/null @@ -1,52 +0,0 @@ -resource "aws_lb" "lb" { - name = "${var.name}" - subnets = ["${aws_subnet.subnet.*.id}"] - security_groups = ["${aws_security_group.secgroup.id}"] - tags { - Name = "${var.name}" - } -# access_logs { -# bucket = "${var.s3_bucket}" -# prefix = "lblogs" -# } -} - -resource "aws_lb_listener" "lb_listener" { - load_balancer_arn = "${aws_lb.lb.arn}" - port = "443" - protocol = "HTTPS" - ssl_policy = "ELBSecurityPolicy-TLS-1-2-Ext-2018-06" - certificate_arn = "${var.certificate_arn}" - - default_action { - target_group_arn = "${aws_lb_target_group.lb_target_group.arn}" - type = "forward" - } -} - -resource "aws_lb_listener_rule" "listener_rule" { - listener_arn = "${aws_lb_listener.lb_listener.arn}" - priority = "100" - action { - type = "forward" - target_group_arn = "${aws_lb_target_group.lb_target_group.id}" - } - condition { - field = "path-pattern" - values = ["/"] - } -} - -resource "aws_lb_target_group" "lb_target_group" { - name = "${var.name}" - port = "26657" - protocol = "HTTP" - vpc_id = "${aws_vpc.vpc.id}" - tags { - name = "${var.name}" - } - health_check { - path = "/health" - } -} - diff --git a/contrib/testnets/remote/terraform-app/infra/lcd.tf b/contrib/testnets/remote/terraform-app/infra/lcd.tf deleted file mode 100644 index 5d09903d0..000000000 --- a/contrib/testnets/remote/terraform-app/infra/lcd.tf +++ /dev/null @@ -1,39 +0,0 @@ -resource "aws_lb_listener" "lb_listener_lcd" { - load_balancer_arn = "${aws_lb.lb.arn}" - port = "1317" - protocol = "HTTPS" - ssl_policy = "ELBSecurityPolicy-TLS-1-2-Ext-2018-06" - certificate_arn = "${var.certificate_arn}" - - default_action { - target_group_arn = "${aws_lb_target_group.lb_target_group_lcd.arn}" - type = "forward" - } -} - -resource "aws_lb_listener_rule" "listener_rule_lcd" { - listener_arn = "${aws_lb_listener.lb_listener_lcd.arn}" - priority = "100" - action { - type = "forward" - target_group_arn = "${aws_lb_target_group.lb_target_group_lcd.id}" - } - condition { - field = "path-pattern" - values = ["/"] - } -} - -resource "aws_lb_target_group" "lb_target_group_lcd" { - name = "${var.name}lcd" - port = "1317" - protocol = "HTTP" - vpc_id = "${aws_vpc.vpc.id}" - tags { - name = "${var.name}" - } - health_check { - path = "/node_version" - } -} - diff --git a/contrib/testnets/remote/terraform-app/infra/outputs.tf b/contrib/testnets/remote/terraform-app/infra/outputs.tf deleted file mode 100644 index fdb32611c..000000000 --- a/contrib/testnets/remote/terraform-app/infra/outputs.tf +++ /dev/null @@ -1,24 +0,0 @@ -// The cluster name -output "name" { - value = "${var.name}" -} - -// The list of cluster instance IDs -output "instances" { - value = ["${aws_instance.node.*.id}"] -} - -#output "instances_count" { -# value = "${length(aws_instance.node.*)}" -#} - -// The list of cluster instance public IPs -output "public_ips" { - value = ["${aws_instance.node.*.public_ip}"] -} - -// Name of the ALB -output "lb_name" { - value = "${aws_lb.lb.dns_name}" -} - diff --git a/contrib/testnets/remote/terraform-app/infra/variables.tf b/contrib/testnets/remote/terraform-app/infra/variables.tf deleted file mode 100644 index 0a96f1443..000000000 --- a/contrib/testnets/remote/terraform-app/infra/variables.tf +++ /dev/null @@ -1,39 +0,0 @@ -variable "name" { - description = "The testnet name, e.g cdn" -} - -variable "image_name" { - description = "Image name" - default = "CentOS Linux 7 x86_64 HVM EBS 1704_01" -} - -variable "instance_type" { - description = "The instance size to use" - default = "t2.small" -} - -variable "SERVERS" { - description = "Number of servers in an availability zone" - default = "1" -} - -variable "max_zones" { - description = "Maximum number of availability zones to use" - default = "1" -} - -variable "ssh_private_file" { - description = "SSH private key file to be used to connect to the nodes" - type = "string" -} - -variable "ssh_public_file" { - description = "SSH public key file to be used on the nodes" - type = "string" -} - -variable "certificate_arn" { - description = "Load-balancer SSL certificate AWS ARN" - type = "string" -} - diff --git a/contrib/testnets/remote/terraform-app/infra/vpc.tf b/contrib/testnets/remote/terraform-app/infra/vpc.tf deleted file mode 100644 index 638ccfe0b..000000000 --- a/contrib/testnets/remote/terraform-app/infra/vpc.tf +++ /dev/null @@ -1,104 +0,0 @@ -resource "aws_vpc" "vpc" { - cidr_block = "10.0.0.0/16" - - tags { - Name = "${var.name}" - } - -} - -resource "aws_internet_gateway" "internet_gateway" { - vpc_id = "${aws_vpc.vpc.id}" - - tags { - Name = "${var.name}" - } -} - -resource "aws_route_table" "route_table" { - vpc_id = "${aws_vpc.vpc.id}" - - route { - cidr_block = "0.0.0.0/0" - gateway_id = "${aws_internet_gateway.internet_gateway.id}" - } - - tags { - Name = "${var.name}" - } -} - -data "aws_availability_zones" "zones" { - state = "available" -} - -resource "aws_subnet" "subnet" { - count = "${min(length(data.aws_availability_zones.zones.names),var.max_zones)}" - vpc_id = "${aws_vpc.vpc.id}" - availability_zone = "${element(data.aws_availability_zones.zones.names,count.index)}" - cidr_block = "${cidrsubnet(aws_vpc.vpc.cidr_block, 8, count.index)}" - map_public_ip_on_launch = "true" - - tags { - Name = "${var.name}-${element(data.aws_availability_zones.zones.names,count.index)}" - } -} - -resource "aws_route_table_association" "route_table_association" { - count = "${min(length(data.aws_availability_zones.zones.names),var.max_zones)}" - subnet_id = "${element(aws_subnet.subnet.*.id,count.index)}" - route_table_id = "${aws_route_table.route_table.id}" -} - -resource "aws_security_group" "secgroup" { - name = "${var.name}" - vpc_id = "${aws_vpc.vpc.id}" - description = "Automated security group for application instances" - tags { - Name = "${var.name}" - } - - ingress { - from_port = 22 - to_port = 22 - protocol = "tcp" - cidr_blocks = ["0.0.0.0/0"] - } - - ingress { - from_port = 443 - to_port = 443 - protocol = "tcp" - cidr_blocks = ["0.0.0.0/0"] - } - - ingress { - from_port = 1317 - to_port = 1317 - protocol = "tcp" - cidr_blocks = ["0.0.0.0/0"] - } - - ingress { - from_port = 26656 - to_port = 26657 - protocol = "tcp" - cidr_blocks = ["0.0.0.0/0"] - } - - ingress { - from_port = 26660 - to_port = 26660 - protocol = "tcp" - cidr_blocks = ["0.0.0.0/0"] - } - - egress { - from_port = 0 - to_port = 0 - protocol = "-1" - cidr_blocks = ["0.0.0.0/0"] - - } -} - diff --git a/contrib/testnets/remote/terraform-app/main.tf b/contrib/testnets/remote/terraform-app/main.tf deleted file mode 100644 index 687e3b5b7..000000000 --- a/contrib/testnets/remote/terraform-app/main.tf +++ /dev/null @@ -1,73 +0,0 @@ -#Terraform Configuration - -variable "APP_NAME" { - description = "Name of the application" -} - -variable "SERVERS" { - description = "Number of servers in an availability zone" - default = "1" -} - -variable "MAX_ZONES" { - description = "Maximum number of availability zones to use" - default = "4" -} - -#See https://docs.aws.amazon.com/general/latest/gr/rande.html#ec2_region -#eu-west-3 does not contain CentOS images -variable "REGION" { - description = "AWS Regions" - default = "us-east-1" -} - -variable "SSH_PRIVATE_FILE" { - description = "SSH private key file to be used to connect to the nodes" - type = "string" -} - -variable "SSH_PUBLIC_FILE" { - description = "SSH public key file to be used on the nodes" - type = "string" -} - -variable "CERTIFICATE_ARN" { - description = "Load-balancer certificate AWS ARN" - type = "string" -} - -# ap-southeast-1 and ap-southeast-2 does not contain the newer CentOS 1704 image -variable "image" { - description = "AWS image name" - default = "CentOS Linux 7 x86_64 HVM EBS 1703_01" -} - -variable "instance_type" { - description = "AWS instance type" - default = "t2.large" -} - -provider "aws" { - region = "${var.REGION}" -} - -module "nodes" { - source = "infra" - name = "${var.APP_NAME}" - image_name = "${var.image}" - instance_type = "${var.instance_type}" - ssh_public_file = "${var.SSH_PUBLIC_FILE}" - ssh_private_file = "${var.SSH_PRIVATE_FILE}" - certificate_arn = "${var.CERTIFICATE_ARN}" - SERVERS = "${var.SERVERS}" - max_zones = "${var.MAX_ZONES}" -} - -output "public_ips" { - value = "${module.nodes.public_ips}", -} - -output "lb_name" { - value = "${module.nodes.lb_name}" -} - diff --git a/contrib/testnets/remote/terraform-aws/.gitignore b/contrib/testnets/remote/terraform-aws/.gitignore deleted file mode 100644 index d882c9444..000000000 --- a/contrib/testnets/remote/terraform-aws/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -.terraform -terraform.tfstate -terraform.tfstate.backup -terraform.tfstate.d -.terraform.tfstate.lock.info diff --git a/contrib/testnets/remote/terraform-aws/files/terraform.sh b/contrib/testnets/remote/terraform-aws/files/terraform.sh deleted file mode 100644 index aec130bc8..000000000 --- a/contrib/testnets/remote/terraform-aws/files/terraform.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/bash -# Script to initialize a testnet settings on a server - -#Usage: terraform.sh - -#Add pstaked node number for remote identification -REGION="$(($2 + 1))" -RNODE="$(($3 + 1))" -ID="$((${REGION} * 100 + ${RNODE}))" -echo "$ID" > /etc/nodeid - diff --git a/contrib/testnets/remote/terraform-aws/main.tf b/contrib/testnets/remote/terraform-aws/main.tf deleted file mode 100644 index 41e05995e..000000000 --- a/contrib/testnets/remote/terraform-aws/main.tf +++ /dev/null @@ -1,249 +0,0 @@ -#Terraform Configuration - -#See https://docs.aws.amazon.com/general/latest/gr/rande.html#ec2_region -#eu-west-3 does not contain CentOS images -#us-east-1 usually contains other infrastructure and creating keys and security groups might conflict with that -variable "REGIONS" { - description = "AWS Regions" - type = "list" - default = ["us-east-2", "us-west-1", "us-west-2", "ap-south-1", "ap-northeast-2", "ap-southeast-1", "ap-southeast-2", "ap-northeast-1", "ca-central-1", "eu-central-1", "eu-west-1", "eu-west-2", "sa-east-1"] -} - -variable "TESTNET_NAME" { - description = "Name of the testnet" - default = "remotenet" -} - -variable "REGION_LIMIT" { - description = "Number of regions to populate" - default = "1" -} - -variable "SERVERS" { - description = "Number of servers in an availability zone" - default = "1" -} - -variable "SSH_PRIVATE_FILE" { - description = "SSH private key file to be used to connect to the nodes" - type = "string" -} - -variable "SSH_PUBLIC_FILE" { - description = "SSH public key file to be used on the nodes" - type = "string" -} - - -# ap-southeast-1 and ap-southeast-2 does not contain the newer CentOS 1704 image -variable "image" { - description = "AWS image name" - default = "CentOS Linux 7 x86_64 HVM EBS 1703_01" -} - -variable "instance_type" { - description = "AWS instance type" - default = "t2.large" -} - -module "nodes-0" { - source = "nodes" - name = "${var.TESTNET_NAME}" - image_name = "${var.image}" - instance_type = "${var.instance_type}" - region = "${element(var.REGIONS,0)}" - multiplier = "0" - execute = "${var.REGION_LIMIT > 0}" - ssh_public_file = "${var.SSH_PUBLIC_FILE}" - ssh_private_file = "${var.SSH_PRIVATE_FILE}" - SERVERS = "${var.SERVERS}" -} - -module "nodes-1" { - source = "nodes" - name = "${var.TESTNET_NAME}" - image_name = "${var.image}" - instance_type = "${var.instance_type}" - region = "${element(var.REGIONS,1)}" - multiplier = "1" - execute = "${var.REGION_LIMIT > 1}" - ssh_public_file = "${var.SSH_PUBLIC_FILE}" - ssh_private_file = "${var.SSH_PRIVATE_FILE}" - SERVERS = "${var.SERVERS}" -} - -module "nodes-2" { - source = "nodes" - name = "${var.TESTNET_NAME}" - image_name = "${var.image}" - instance_type = "${var.instance_type}" - region = "${element(var.REGIONS,2)}" - multiplier = "2" - execute = "${var.REGION_LIMIT > 2}" - ssh_public_file = "${var.SSH_PUBLIC_FILE}" - ssh_private_file = "${var.SSH_PRIVATE_FILE}" - SERVERS = "${var.SERVERS}" -} - -module "nodes-3" { - source = "nodes" - name = "${var.TESTNET_NAME}" - image_name = "${var.image}" - instance_type = "${var.instance_type}" - region = "${element(var.REGIONS,3)}" - multiplier = "3" - execute = "${var.REGION_LIMIT > 3}" - ssh_public_file = "${var.SSH_PUBLIC_FILE}" - ssh_private_file = "${var.SSH_PRIVATE_FILE}" - SERVERS = "${var.SERVERS}" -} - -module "nodes-4" { - source = "nodes" - name = "${var.TESTNET_NAME}" - image_name = "${var.image}" - instance_type = "${var.instance_type}" - region = "${element(var.REGIONS,4)}" - multiplier = "4" - execute = "${var.REGION_LIMIT > 4}" - ssh_public_file = "${var.SSH_PUBLIC_FILE}" - ssh_private_file = "${var.SSH_PRIVATE_FILE}" - SERVERS = "${var.SERVERS}" -} - -module "nodes-5" { - source = "nodes" - name = "${var.TESTNET_NAME}" - image_name = "${var.image}" - instance_type = "${var.instance_type}" - region = "${element(var.REGIONS,5)}" - multiplier = "5" - execute = "${var.REGION_LIMIT > 5}" - ssh_public_file = "${var.SSH_PUBLIC_FILE}" - ssh_private_file = "${var.SSH_PRIVATE_FILE}" - SERVERS = "${var.SERVERS}" -} - -module "nodes-6" { - source = "nodes" - name = "${var.TESTNET_NAME}" - image_name = "${var.image}" - instance_type = "${var.instance_type}" - region = "${element(var.REGIONS,6)}" - multiplier = "6" - execute = "${var.REGION_LIMIT > 6}" - ssh_public_file = "${var.SSH_PUBLIC_FILE}" - ssh_private_file = "${var.SSH_PRIVATE_FILE}" - SERVERS = "${var.SERVERS}" -} - -module "nodes-7" { - source = "nodes" - name = "${var.TESTNET_NAME}" - image_name = "${var.image}" - instance_type = "${var.instance_type}" - region = "${element(var.REGIONS,7)}" - multiplier = "7" - execute = "${var.REGION_LIMIT > 7}" - ssh_public_file = "${var.SSH_PUBLIC_FILE}" - ssh_private_file = "${var.SSH_PRIVATE_FILE}" - SERVERS = "${var.SERVERS}" -} - -module "nodes-8" { - source = "nodes" - name = "${var.TESTNET_NAME}" - image_name = "${var.image}" - instance_type = "${var.instance_type}" - region = "${element(var.REGIONS,8)}" - multiplier = "8" - execute = "${var.REGION_LIMIT > 8}" - ssh_public_file = "${var.SSH_PUBLIC_FILE}" - ssh_private_file = "${var.SSH_PRIVATE_FILE}" - SERVERS = "${var.SERVERS}" -} - -module "nodes-9" { - source = "nodes" - name = "${var.TESTNET_NAME}" - image_name = "${var.image}" - instance_type = "${var.instance_type}" - region = "${element(var.REGIONS,9)}" - multiplier = "9" - execute = "${var.REGION_LIMIT > 9}" - ssh_public_file = "${var.SSH_PUBLIC_FILE}" - ssh_private_file = "${var.SSH_PRIVATE_FILE}" - SERVERS = "${var.SERVERS}" -} - -module "nodes-10" { - source = "nodes" - name = "${var.TESTNET_NAME}" - image_name = "${var.image}" - instance_type = "${var.instance_type}" - region = "${element(var.REGIONS,10)}" - multiplier = "10" - execute = "${var.REGION_LIMIT > 10}" - ssh_public_file = "${var.SSH_PUBLIC_FILE}" - ssh_private_file = "${var.SSH_PRIVATE_FILE}" - SERVERS = "${var.SERVERS}" -} - -module "nodes-11" { - source = "nodes" - name = "${var.TESTNET_NAME}" - image_name = "${var.image}" - instance_type = "${var.instance_type}" - region = "${element(var.REGIONS,11)}" - multiplier = "11" - execute = "${var.REGION_LIMIT > 11}" - ssh_public_file = "${var.SSH_PUBLIC_FILE}" - ssh_private_file = "${var.SSH_PRIVATE_FILE}" - SERVERS = "${var.SERVERS}" -} - -module "nodes-12" { - source = "nodes" - name = "${var.TESTNET_NAME}" - image_name = "${var.image}" - instance_type = "${var.instance_type}" - region = "${element(var.REGIONS,12)}" - multiplier = "12" - execute = "${var.REGION_LIMIT > 12}" - ssh_public_file = "${var.SSH_PUBLIC_FILE}" - ssh_private_file = "${var.SSH_PRIVATE_FILE}" - SERVERS = "${var.SERVERS}" -} - -module "nodes-13" { - source = "nodes" - name = "${var.TESTNET_NAME}" - image_name = "${var.image}" - instance_type = "${var.instance_type}" - region = "${element(var.REGIONS,13)}" - multiplier = "13" - execute = "${var.REGION_LIMIT > 13}" - ssh_public_file = "${var.SSH_PUBLIC_FILE}" - ssh_private_file = "${var.SSH_PRIVATE_FILE}" - SERVERS = "${var.SERVERS}" -} - -output "public_ips" { - value = "${concat( - module.nodes-0.public_ips, - module.nodes-1.public_ips, - module.nodes-2.public_ips, - module.nodes-3.public_ips, - module.nodes-4.public_ips, - module.nodes-5.public_ips, - module.nodes-6.public_ips, - module.nodes-7.public_ips, - module.nodes-8.public_ips, - module.nodes-9.public_ips, - module.nodes-10.public_ips, - module.nodes-11.public_ips, - module.nodes-12.public_ips, - module.nodes-13.public_ips - )}", -} - diff --git a/contrib/testnets/remote/terraform-aws/nodes/main.tf b/contrib/testnets/remote/terraform-aws/nodes/main.tf deleted file mode 100644 index 825be4af6..000000000 --- a/contrib/testnets/remote/terraform-aws/nodes/main.tf +++ /dev/null @@ -1,104 +0,0 @@ - -provider "aws" { - region = "${var.region}" -} - -resource "aws_key_pair" "testnets" { - count = "${var.execute?1:0}" - key_name = "testnets-${var.name}" - public_key = "${file(var.ssh_public_file)}" -} - -data "aws_ami" "linux" { - most_recent = true - filter { - name = "name" - values = ["${var.image_name}"] - } -} - -data "aws_availability_zones" "zones" { - state = "available" -} - -resource "aws_security_group" "secgroup" { - count = "${var.execute?1:0}" - name = "${var.name}" - description = "Automated security group for performance testing testnets" - tags { - Name = "testnets-${var.name}" - } - - ingress { - from_port = 22 - to_port = 22 - protocol = "tcp" - cidr_blocks = ["0.0.0.0/0"] - } - - ingress { - from_port = 26656 - to_port = 26657 - protocol = "tcp" - cidr_blocks = ["0.0.0.0/0"] - } - - ingress { - from_port = 26660 - to_port = 26660 - protocol = "tcp" - cidr_blocks = ["0.0.0.0/0"] - } - - egress { - from_port = 0 - to_port = 0 - protocol = "-1" - cidr_blocks = ["0.0.0.0/0"] - - } -} - -resource "aws_instance" "node" { - count = "${var.execute?var.SERVERS*length(data.aws_availability_zones.zones.names):0}" - ami = "${data.aws_ami.linux.image_id}" - instance_type = "${var.instance_type}" - key_name = "${aws_key_pair.testnets.key_name}" - associate_public_ip_address = true - security_groups = [ "${aws_security_group.secgroup.name}" ] - availability_zone = "${element(data.aws_availability_zones.zones.names,count.index)}" - - tags { - Environment = "${var.name}" - Name = "${var.name}-${element(data.aws_availability_zones.zones.names,count.index)}" - } - - volume_tags { - Environment = "${var.name}" - Name = "${var.name}-${element(data.aws_availability_zones.zones.names,count.index)}-VOLUME" - } - - root_block_device { - volume_size = 40 - } - - connection { - user = "centos" - private_key = "${file(var.ssh_private_file)}" - timeout = "600s" - } - - provisioner "file" { - source = "files/terraform.sh" - destination = "/tmp/terraform.sh" - } - - provisioner "remote-exec" { - inline = [ - "chmod +x /tmp/terraform.sh", - "sudo /tmp/terraform.sh ${var.name} ${var.multiplier} ${count.index}", - ] - } - -} - diff --git a/contrib/testnets/remote/terraform-aws/nodes/outputs.tf b/contrib/testnets/remote/terraform-aws/nodes/outputs.tf deleted file mode 100644 index 2a4451d69..000000000 --- a/contrib/testnets/remote/terraform-aws/nodes/outputs.tf +++ /dev/null @@ -1,15 +0,0 @@ -// The cluster name -output "name" { - value = "${var.name}" -} - -// The list of cluster instance IDs -output "instances" { - value = ["${aws_instance.node.*.id}"] -} - -// The list of cluster instance public IPs -output "public_ips" { - value = ["${aws_instance.node.*.public_ip}"] -} - diff --git a/contrib/testnets/remote/terraform-aws/nodes/variables.tf b/contrib/testnets/remote/terraform-aws/nodes/variables.tf deleted file mode 100644 index ef540e697..000000000 --- a/contrib/testnets/remote/terraform-aws/nodes/variables.tf +++ /dev/null @@ -1,42 +0,0 @@ -variable "name" { - description = "The testnet name, e.g cdn" -} - -variable "image_name" { - description = "Image name" - default = "CentOS Linux 7 x86_64 HVM EBS 1704_01" -} - -variable "instance_type" { - description = "The instance size to use" - default = "t2.small" -} - -variable "region" { - description = "AWS region to use" -} - -variable "multiplier" { - description = "Multiplier for node identification" -} - -variable "execute" { - description = "Set to false to disable the module" - default = true -} - -variable "SERVERS" { - description = "Number of servers in an availability zone" - default = "1" -} - -variable "ssh_private_file" { - description = "SSH private key file to be used to connect to the nodes" - type = "string" -} - -variable "ssh_public_file" { - description = "SSH public key file to be used on the nodes" - type = "string" -} - diff --git a/contrib/testnets/remote/terraform-do/.gitignore b/contrib/testnets/remote/terraform-do/.gitignore deleted file mode 100644 index 798052367..000000000 --- a/contrib/testnets/remote/terraform-do/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -.terraform -terraform.tfstate -terraform.tfstate.backup -terraform.tfstate.d -.terraform.tfstate.lock.info - diff --git a/contrib/testnets/remote/terraform-do/Makefile b/contrib/testnets/remote/terraform-do/Makefile deleted file mode 100644 index ad9275c73..000000000 --- a/contrib/testnets/remote/terraform-do/Makefile +++ /dev/null @@ -1,100 +0,0 @@ -######################################## -### WARNING: The DigitalOcean scripts are deprecated. They are still here because -### they might be useful for developers. - -# Name of the testnet. Used in chain-id. -TESTNET_NAME?=remotenet - -# Name of the servers grouped together for management purposes. Used in tagging the servers in the cloud. -CLUSTER_NAME?=$(TESTNET_NAME) - -# Number of servers deployed in Digital Ocean. -# Number of servers to put in one availability zone in AWS. -SERVERS?=1 - -# Path to pstaked for deployment. Must be a Linux binary. -BINARY?=$(CURDIR)/../build/gaiad - -# Path to the genesis.json and config.toml files to deploy on full nodes. -GENESISFILE?=$(CURDIR)/../build/genesis.json -CONFIGFILE?=$(CURDIR)/../build/config.toml - -all: - @echo "There is no all. Only sum of the ones." - - -######################################## -### Extract genesis.json and config.toml from a node in a cluster - -extract-config: - @if [ -z "$(DO_API_TOKEN)" ]; then echo "DO_API_TOKEN environment variable not set." ; false ; fi - @if ! [ -f $(HOME)/.ssh/id_rsa.pub ]; then ssh-keygen ; fi - cd remote/ansible && ANSIBLE_HOST_KEY_CHECKING=False ansible-playbook -i inventory/digital_ocean.py -l "$(CLUSTER_NAME)" -e TESTNET_NAME="$(TESTNET_NAME)" -e GENESISFILE="$(GENESISFILE)" -e CONFIGFILE="$(CONFIGFILE)" extract-config.yml - - -######################################## -### Remote validator nodes using terraform and ansible in Digital Ocean - -validators-start: - @if [ -z "$(DO_API_TOKEN)" ]; then echo "DO_API_TOKEN environment variable not set." ; false ; fi - @if ! [ -f $(HOME)/.ssh/id_rsa.pub ]; then ssh-keygen ; fi - @if [ -z "`file $(BINARY) | grep 'ELF 64-bit'`" ]; then echo "Please build a linux binary using 'make build-linux'." ; false ; fi - cd remote/terraform-do && terraform init && (terraform workspace new "$(CLUSTER_NAME)" || terraform workspace select "$(CLUSTER_NAME)") && terraform apply -auto-approve -var DO_API_TOKEN="$(DO_API_TOKEN)" -var SSH_PUBLIC_FILE="$(HOME)/.ssh/id_rsa.pub" -var SSH_PRIVATE_FILE="$(HOME)/.ssh/id_rsa" -var TESTNET_NAME="$(CLUSTER_NAME)" -var SERVERS="$(SERVERS)" - cd remote/ansible && ANSIBLE_HOST_KEY_CHECKING=False ansible-playbook -i inventory/digital_ocean.py -l "$(CLUSTER_NAME)" -u root -e BINARY=$(BINARY) -e TESTNET_NAME="$(TESTNET_NAME)" setup-validators.yml - cd remote/ansible && ansible-playbook -i inventory/digital_ocean.py -l "$(CLUSTER_NAME)" -u root start.yml - -validators-stop: - @if [ -z "$(DO_API_TOKEN)" ]; then echo "DO_API_TOKEN environment variable not set." ; false ; fi - cd remote/terraform-do && terraform workspace select "$(CLUSTER_NAME)" && terraform destroy -force -var DO_API_TOKEN="$(DO_API_TOKEN)" -var SSH_PUBLIC_FILE="$(HOME)/.ssh/id_rsa.pub" -var SSH_PRIVATE_FILE="$(HOME)/.ssh/id_rsa" && terraform workspace select default && terraform workspace delete "$(CLUSTER_NAME)" - rm -rf remote/ansible/keys/ - -validators-status: - cd remote/ansible && ansible-playbook -i inventory/digital_ocean.py -l "$(CLUSTER_NAME)" status.yml - - -######################################## -### Remote full nodes using terraform and ansible in Digital Ocean - -fullnodes-start: - @if [ -z "$(DO_API_TOKEN)" ]; then echo "DO_API_TOKEN environment variable not set." ; false ; fi - @if ! [ -f $(HOME)/.ssh/id_rsa.pub ]; then ssh-keygen ; fi - @if [ -z "`file $(BINARY) | grep 'ELF 64-bit'`" ]; then echo "Please build a linux binary using 'make build-linux'." ; false ; fi - cd remote/terraform-do && terraform init && (terraform workspace new "$(CLUSTER_NAME)" || terraform workspace select "$(CLUSTER_NAME)") && terraform apply -var DO_API_TOKEN="$(DO_API_TOKEN)" -var SSH_PUBLIC_FILE="$(HOME)/.ssh/id_rsa.pub" -var SSH_PRIVATE_FILE="$(HOME)/.ssh/id_rsa" -var TESTNET_NAME="$(CLUSTER_NAME)" -var SERVERS="$(SERVERS)" - cd remote/ansible && ANSIBLE_HOST_KEY_CHECKING=False ansible-playbook -i inventory/digital_ocean.py -l "$(CLUSTER_NAME)" -e BINARY=$(BINARY) -e TESTNET_NAME="$(TESTNET_NAME)" -e GENESISFILE="$(GENESISFILE)" -e CONFIGFILE="$(CONFIGFILE)" setup-fullnodes.yml - cd remote/ansible && ansible-playbook -i inventory/digital_ocean.py -l "$(CLUSTER_NAME)" -u root start.yml - -fullnodes-stop: - @if [ -z "$(DO_API_TOKEN)" ]; then echo "DO_API_TOKEN environment variable not set." ; false ; fi - cd remote/terraform-do && terraform workspace select "$(CLUSTER_NAME)" && terraform destroy -force -var DO_API_TOKEN="$(DO_API_TOKEN)" -var SSH_PUBLIC_FILE="$(HOME)/.ssh/id_rsa.pub" -var SSH_PRIVATE_FILE="$(HOME)/.ssh/id_rsa" && terraform workspace select default && terraform workspace delete "$(CLUSTER_NAME)" - -fullnodes-status: - cd remote/ansible && ansible-playbook -i inventory/digital_ocean.py -l "$(CLUSTER_NAME)" status.yml - - -######################################## -### Other calls - -upgrade-gaiad: - @if [ -z "$(DO_API_TOKEN)" ]; then echo "DO_API_TOKEN environment variable not set." ; false ; fi - @if ! [ -f $(HOME)/.ssh/id_rsa.pub ]; then ssh-keygen ; fi - @if [ -z "`file $(BINARY) | grep 'ELF 64-bit'`" ]; then echo "Please build a linux binary using 'make build-linux'." ; false ; fi - cd remote/ansible && ANSIBLE_HOST_KEY_CHECKING=False ansible-playbook -i inventory/digital_ocean.py -l "$(CLUSTER_NAME)" -e BINARY=$(BINARY) upgrade-gaiad.yml - -list: - remote/ansible/inventory/digital_ocean.py | python -c 'import json,sys ; print "\n".join(json.loads("".join(sys.stdin.readlines()))["$(CLUSTER_NAME)"]["hosts"])' - -install-datadog: - @if [ -z "$(DO_API_TOKEN)" ]; then echo "DO_API_TOKEN environment variable not set." ; false ; fi - @if [ -z "$(DD_API_KEY)" ]; then echo "DD_API_KEY environment variable not set." ; false ; fi - cd remote/ansible && ANSIBLE_HOST_KEY_CHECKING=False ansible-playbook -i inventory/digital_ocean.py -l "$(CLUSTER_NAME)" -u root -e DD_API_KEY="$(DD_API_KEY)" -e TESTNET_NAME=$(TESTNET_NAME) -e CLUSTER_NAME=$(CLUSTER_NAME) install-datadog-agent.yml - -remove-datadog: - @if [ -z "$(DO_API_TOKEN)" ]; then echo "DO_API_TOKEN environment variable not set." ; false ; fi - cd remote/ansible && ANSIBLE_HOST_KEY_CHECKING=False ansible-playbook -i inventory/digital_ocean.py -l "$(CLUSTER_NAME)" -u root remove-datadog-agent.yml - - -# To avoid unintended conflicts with file names, always add to .PHONY -# unless there is a reason not to. -# https://www.gnu.org/software/make/manual/html_node/Phony-Targets.html -.PHONY: all extract-config validators-start validators-stop validators-status fullnodes-start fullnodes-stop fullnodes-status upgrade-gaiad list-do install-datadog remove-datadog - diff --git a/contrib/testnets/remote/terraform-do/README.md b/contrib/testnets/remote/terraform-do/README.md deleted file mode 100644 index 0486a8bc4..000000000 --- a/contrib/testnets/remote/terraform-do/README.md +++ /dev/null @@ -1,58 +0,0 @@ -# Terraform & Ansible - -WARNING: The Digital Ocean scripts are obsolete. They are here because they might still be useful for developers. - -Automated deployments are done using [Terraform](https://www.terraform.io/) to create servers on Digital Ocean then -[Ansible](http://www.ansible.com/) to create and manage testnets on those servers. - -## Prerequisites - -- Install [Terraform](https://www.terraform.io/downloads.html) and [Ansible](http://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html) on a Linux machine. -- Create a [DigitalOcean API token](https://cloud.digitalocean.com/settings/api/tokens) with read and write capability. -- Install the python dopy package (`pip install dopy`) (This is necessary for the digitalocean.py script for ansible.) -- Create SSH keys - -``` -export DO_API_TOKEN="abcdef01234567890abcdef01234567890" -export TESTNET_NAME="remotenet" -export SSH_PRIVATE_FILE="$HOME/.ssh/id_rsa" -export SSH_PUBLIC_FILE="$HOME/.ssh/id_rsa.pub" -``` - -These will be used by both `terraform` and `ansible`. - -## Create a remote network - -``` -make remotenet-start -``` - -Optionally, you can set the number of servers you want to launch and the name of the testnet (which defaults to remotenet): - -``` -TESTNET_NAME="mytestnet" SERVERS=7 make remotenet-start -``` - -## Quickly see the /status endpoint - -``` -make remotenet-status -``` - -## Delete servers - -``` -make remotenet-stop -``` - -## Logging - -You can ship logs to Logz.io, an Elastic stack (Elastic search, Logstash and Kibana) service provider. You can set up your nodes to log there automatically. Create an account and get your API key from the notes on [this page](https://app.logz.io/#/dashboard/data-sources/Filebeat), then: - -``` -yum install systemd-devel || echo "This will only work on RHEL-based systems." -apt-get install libsystemd-dev || echo "This will only work on Debian-based systems." - -go get github.com/mheese/journalbeat -ansible-playbook -i inventory/digital_ocean.py -l remotenet logzio.yml -e LOGZIO_TOKEN=ABCDEFGHIJKLMNOPQRSTUVWXYZ012345 -``` diff --git a/contrib/testnets/remote/terraform-do/cluster/main.tf b/contrib/testnets/remote/terraform-do/cluster/main.tf deleted file mode 100644 index 07331ff3d..000000000 --- a/contrib/testnets/remote/terraform-do/cluster/main.tf +++ /dev/null @@ -1,40 +0,0 @@ -resource "digitalocean_tag" "cluster" { - name = "${var.name}" -} - -resource "digitalocean_ssh_key" "cluster" { - name = "${var.name}" - public_key = "${file(var.ssh_public_file)}" -} - -resource "digitalocean_droplet" "cluster" { - name = "${var.name}-node${count.index}" - image = "centos-7-x64" - size = "${var.instance_size}" - region = "${element(var.regions, count.index)}" - ssh_keys = ["${digitalocean_ssh_key.cluster.id}"] - count = "${var.servers}" - tags = ["${digitalocean_tag.cluster.id}"] - - lifecycle = { - prevent_destroy = false - } - - connection { - private_key = "${file(var.ssh_private_file)}" - } - - provisioner "file" { - source = "files/terraform.sh" - destination = "/tmp/terraform.sh" - } - - provisioner "remote-exec" { - inline = [ - "chmod +x /tmp/terraform.sh", - "/tmp/terraform.sh ${var.name} ${count.index}", - ] - } - -} - diff --git a/contrib/testnets/remote/terraform-do/cluster/outputs.tf b/contrib/testnets/remote/terraform-do/cluster/outputs.tf deleted file mode 100644 index 78291b6a9..000000000 --- a/contrib/testnets/remote/terraform-do/cluster/outputs.tf +++ /dev/null @@ -1,15 +0,0 @@ -// The cluster name -output "name" { - value = "${var.name}" -} - -// The list of cluster instance IDs -output "instances" { - value = ["${digitalocean_droplet.cluster.*.id}"] -} - -// The list of cluster instance public IPs -output "public_ips" { - value = ["${digitalocean_droplet.cluster.*.ipv4_address}"] -} - diff --git a/contrib/testnets/remote/terraform-do/cluster/variables.tf b/contrib/testnets/remote/terraform-do/cluster/variables.tf deleted file mode 100644 index e2654b11d..000000000 --- a/contrib/testnets/remote/terraform-do/cluster/variables.tf +++ /dev/null @@ -1,30 +0,0 @@ -variable "name" { - description = "The cluster name, e.g remotenet" -} - -variable "regions" { - description = "Regions to launch in" - type = "list" - default = ["AMS2", "TOR1", "LON1", "NYC3", "SFO2", "SGP1", "FRA1"] -} - -variable "ssh_private_file" { - description = "SSH private key filename to use to connect to the nodes" - type = "string" -} - -variable "ssh_public_file" { - description = "SSH public key filename to copy to the nodes" - type = "string" -} - -variable "instance_size" { - description = "The instance size to use" - default = "2gb" -} - -variable "servers" { - description = "Desired instance count" - default = 4 -} - diff --git a/contrib/testnets/remote/terraform-do/files/terraform.sh b/contrib/testnets/remote/terraform-do/files/terraform.sh deleted file mode 100644 index ba7c6eeb0..000000000 --- a/contrib/testnets/remote/terraform-do/files/terraform.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash -# Script to initialize a testnet settings on a server - -#Usage: terraform.sh - -#Add pstaked node number for remote identification -echo "$2" > /etc/nodeid - diff --git a/contrib/testnets/remote/terraform-do/main.tf b/contrib/testnets/remote/terraform-do/main.tf deleted file mode 100644 index fb78a3785..000000000 --- a/contrib/testnets/remote/terraform-do/main.tf +++ /dev/null @@ -1,43 +0,0 @@ -#Terraform Configuration - -variable "DO_API_TOKEN" { - description = "DigitalOcean Access Token" -} - -variable "TESTNET_NAME" { - description = "Name of the testnet" - default = "remotenet" -} - -variable "SSH_PRIVATE_FILE" { - description = "SSH private key file to be used to connect to the nodes" - type = "string" -} - -variable "SSH_PUBLIC_FILE" { - description = "SSH public key file to be used on the nodes" - type = "string" -} - -variable "SERVERS" { - description = "Number of nodes in testnet" - default = "4" -} - -provider "digitalocean" { - token = "${var.DO_API_TOKEN}" -} - -module "cluster" { - source = "./cluster" - name = "${var.TESTNET_NAME}" - ssh_private_file = "${var.SSH_PRIVATE_FILE}" - ssh_public_file = "${var.SSH_PUBLIC_FILE}" - servers = "${var.SERVERS}" -} - - -output "public_ips" { - value = "${module.cluster.public_ips}" -} - diff --git a/contrib/testnets/test_platform/README.md b/contrib/testnets/test_platform/README.md deleted file mode 100644 index a9172d5f1..000000000 --- a/contrib/testnets/test_platform/README.md +++ /dev/null @@ -1,45 +0,0 @@ -# Gaiad Testnet Tool - -This python tool starts multiple gaiad instances on the same machine without virtualization, i.e., non-conflicting ports are used. - -This tool aims to simplify testing of key Cosmos Hub operations, such as module deployments and upgrades. - -## Features - -1. All ports automatically incremented by 10 -1. Gaiad nodes peer with all other nodes -1. Gaiad nodes all started on one machine without conflict -1. All nodes generate, propose, and vote on blocks -1. Stopping app stops all instances -1. Support specifying a pre-existing genesis file -1. Supports taking a pre-existing genesis file and creating a network with a sufficient number of validators. The network - creates as many validators as needed to attain majority voting power on the new network (and produce new blocks with pre-existing genesis file). - The validators that are replaced is the set that provides at least 66% of the total voting power given in the genesis file. - - **This feature allows testing upgrades and module migrations of existing networks, using their pre-existing genesis** :star: - - -## Usage - -1. Configure `template/replacement_defaults.txt`: - 1. To create a network from scratch: - 1. Set `replacement_genesis` value to blank, e.g., `replacement_genesis=` - 1. Set `num_of_nodes_to_apply` to the _number of nodes to run_, e.g., `num_of_nodes_to_apply=4` - 1. To create a network based on an existing genesis file: - 1. Set `replacement_genesis` to the source genesis file; `.tar.gz` files are also supported - 1. Set `replacement_genesis_make_safe` to `True` in order to create as many nodes as needed to run a majority of validators. - 1. Otherwise, set `replacement_genesis_make_safe` value to blank to create `num_of_nodes_to_apply` nodes, e.g., `replacement_genesis_make_safe=`. - Important: if the `replacement_genesis_make_safe` is not set, then the validator keys in the genesis file aren't replaced and so the network may not produce new blocks. - 1. Optionally, set `LOG_LEVEL` to one of _(trace | debug | info | warn | error | fatal | panic)_; default _info_ -1. Start `gaiad_config_manager.py` - -Notes for `template/replacement_defaults.txt`: -- only the last occurrence of a key and it's value are used, i.e., earlier occurrences are overwritten. -- keys ending in `_PORT` are automatically incremented for each node - -## Upcoming features - -1. custom network architectures -1. custom failure testing -1. ibc integration testing -1. module integration testing \ No newline at end of file diff --git a/contrib/testnets/test_platform/gaiad_config_manager.py b/contrib/testnets/test_platform/gaiad_config_manager.py deleted file mode 100644 index 0c2693e93..000000000 --- a/contrib/testnets/test_platform/gaiad_config_manager.py +++ /dev/null @@ -1,233 +0,0 @@ -import json -import os -import shutil -import subprocess -import time - -working_directory = os.getcwd() + "/" - -template_input = working_directory + 'templates/replacement_defaults.txt' - -template_file_config = working_directory + 'templates/config.toml' -template_file_app = working_directory + 'templates/app.toml' - -target_dir = working_directory + 'mytestnet/node0/gaiad/config/' - -target_files = [] -target_configs = [] -target_apps = [] - -# port sequence parameters -port_sequence = 0 -port_increment = 10 - -# take a template -# replace template parameters -# increment ports -# set peers -# apply genesis if one is specified -# overwrite configs for each target - -# collect testnet validator pub keys -# copy genesis file to targets - -# get genesis validators info -# choose which validators to replace -# create pubkey_replacement file -# use pubkey_replacement option on start - -# read the template as a single string -with open(template_file_config, 'r') as file: - # template_config = file.read().replace('\n', '') - template_config = file.read() - -with open(template_file_app, 'r') as file: - template_app = file.read() - # .replace('\n', '') - -# populate template replacements from input file -template_replacements = {} -with open(template_input, 'r') as file: - template_lines = file.readlines() - for lin in template_lines: - lin = lin.strip() - if len(lin) == 0: - continue - line_separations = lin.split("=") - template_replacements[line_separations[0]] = line_separations[1] - - -def make_replacements(template, port_sequence): - intermediate_template = template - # make template replacements - for k in template_replacements: - # allow special care for ports and their increments - if k.endswith("_PORT"): - intermediate_template = intermediate_template.replace("<" + k + ">", str(int(template_replacements[k]) + port_sequence)) - else: - intermediate_template = intermediate_template.replace("<" + k + ">", template_replacements[k]) - return intermediate_template - - -local_sequence = 0 - - -def get_validator_pubkey(target_dir): - val_pub_key = subprocess.check_output(['gaiad', 'tendermint', 'show-validator', '--home', target_dir.rstrip('/config')]) - val_pub_key = val_pub_key.decode("utf-8").rstrip('\n') - return val_pub_key - - -def get_validator_id(target_dir): - global local_sequence - # subprocess.call(['gaiad', 'init', '--home', target_dir]) - nodeid = subprocess.check_output(['gaiad', 'tendermint', 'show-node-id', '--home', str(target_dir).rstrip("config/")]) - peer_id = str(nodeid.decode("utf-8").rstrip('\n') + '@' + template_replacements['P2P_PEERID_IP'] + ':' + str(int(template_replacements['P2P_LADDR_PORT']) + int(local_sequence))) - local_sequence += 10 - return peer_id - - -common_genesis = working_directory + template_replacements['replacement_genesis'] -# support compressed genesis files -if common_genesis.endswith(".tar.gz"): - unzip_cmd = "tar zxvf " + common_genesis + " --cd " + working_directory + "templates" - print("unzip_cmd:" + unzip_cmd) - subprocess.call(unzip_cmd, shell=True) - common_genesis = common_genesis.rstrip(".tar.gz") - -if len(template_replacements['replacement_genesis']) > 0: - # cat genesis.cosmoshub-4.json| jq -s '.[].validators[] | { address: .address, power: .power, name: .name }' - # genesis_validator_set = subprocess.check_output(['cat ' + str(common_genesis) + " | jq -s '.[].validators[] | { address: .address, power: .power, name: .name }'"], shell=True) - genesis_validator_set = subprocess.check_output(['cat ' + str(common_genesis) + " | jq -s '.[].app_state.staking.validators[] | { address: .operator_address, power: .tokens, name: .description.moniker }'"], shell=True) - print("genesis validator set:" + str(genesis_validator_set)) - genesis_valset_python = json.loads("[" + genesis_validator_set.decode("utf-8").replace("}", "},") + "{}]") - # sort validator records by decreasing power - # genesis_valset_sorted2 = sorted(genesis_valset_python[:-1], key=lambda k: print(k)) - genesis_valset_sorted2 = sorted(genesis_valset_python[:-1], key=lambda k: -int(k["power"])) - print("sorted valset:" + str(genesis_valset_sorted2)) - - total_power = 0 - for r in genesis_valset_sorted2: - total_power += int(r["power"]) - - safe_percentage = 0.66 - safe_absolute = total_power * safe_percentage - safe_index = 0 - safe_index_scan_stop = False - - rolling_percentage = 0 - print("rolling percentage:") - for i, r in enumerate(genesis_valset_sorted2): - rolling_percentage += int(r["power"]) / total_power - print(str(i) + ":" + str(rolling_percentage)) - if rolling_percentage > safe_percentage and not safe_index_scan_stop: - safe_index_scan_stop = True - safe_index = i - print("liveness index:" + str(safe_index)) - - if len(template_replacements['replacement_genesis_make_safe']) > 0: - # gaiad testnet --keyring-backend test --v 4 - print("Creating testnet subdirectories") - subprocess.call(['rm', '-rf', working_directory + 'mytestnet']) - subprocess.call(['gaiad', 'testnet', '--keyring-backend', 'test', '--v', str(safe_index)]) - - # specify the output - for node_num in range(safe_index): - target_file = target_dir.replace("node0", "node" + str(node_num)) - target_files.append(target_file) - # subprocess.call("gaiad init node" + str(node_num) + " -o --home "+target_file.rstrip('/config'), shell=True) - subprocess.call('gaiad unsafe-reset-all --home ' + target_file.rstrip('/config'), shell=True) - - print("target_files:"+str(target_files)) - - # collect validator pubkeys for replacement - testnet_validator_pubkeys = [get_validator_pubkey(t) for t in target_files] - print('testnet validator pubkeys:' + str(testnet_validator_pubkeys)) - - output_els = [] - for v_index in range(safe_index): - output_els.append({ - "validator_name": genesis_valset_sorted2[v_index]["name"], - "validator_address": genesis_valset_sorted2[v_index]["address"], - "stargate_consensus_public_key": testnet_validator_pubkeys[v_index] - }) - print("replacement keys:" + str(json.dumps(output_els))) - - with open(working_directory + 'templates/validator_replacement_output.json', 'w') as f: - f.write(str(json.dumps(output_els))) - - # gaiad migrate cosmoshub_3_genesis_export.json --chain-id=cosmoshub-4 --initial-height [last_cosmoshub-3_block+1] > genesis.json - print("migration genesis:" + str(common_genesis)) - cmd_string = 'gaiad migrate ' + common_genesis + ' --chain-id cosmoshub-4 --initial-height 0 --replacement-cons-keys ' + working_directory + 'templates/validator_replacement_output.json > ' + working_directory + 'templates/genesis_replaced.json' - print("cmd_string:" + cmd_string) - subprocess.call([cmd_string], shell=True) - - # compress genesis - subprocess.call('tar zcvf ' + working_directory + 'templates/genesis_replaced.json.tar.gz --cd ' + working_directory + 'templates genesis_replaced.json', shell=True) - - common_genesis = working_directory + 'templates/genesis_replaced.json' - - # create each target's config files - for target_file in target_files: - # copy genesis if a file path to a genesis file is set - print("common_genesis:" + common_genesis) - shutil.copy2(common_genesis, target_file + 'genesis.json') -else: - # gaiad testnet --keyring-backend test --v 4 - print("Creating testnet subdirectories") - subprocess.call(['rm', '-rf', working_directory + 'mytestnet']) - - num_of_nodes_to_apply = int(template_replacements["num_of_nodes_to_apply"]) - - # specify the output - # target_files = [] - for node_num in range(num_of_nodes_to_apply): - target_files.append(target_dir.replace("node0", "node" + str(node_num))) - - subprocess.call(['gaiad', 'testnet', '--keyring-backend', 'test', '--v', str(num_of_nodes_to_apply)]) - -peer_ids = [get_validator_id(t) for t in target_files] -peers = ",".join(peer_ids) -print("testnet peer ids:" + peers) -main_template_config = template_config.replace("", peers) - -# collect validator pubkeys for replacement -testnet_validator_pubkeys = [get_validator_pubkey(t) for t in target_files] -print('testnet validator pubkeys:' + str(testnet_validator_pubkeys)) - - -# give the node some time to start if this is a genesis file with a lot of state, Cosmos Hub 4 mainnet requires at least 10 minutes -# time.sleep(60 * 10) -# tendermint_validator_set = subprocess.check_output(['gaiad', 'query', 'tendermint-validator-set']).decode("utf-8").rstrip('\n') -# print("tendermint_validator_set:" + tendermint_validator_set) - -for target_file in target_files: - # make replacements to app and config toml files - current_template_config = make_replacements(main_template_config, port_sequence) - target_configs.append(current_template_config) - current_template_app = make_replacements(template_app, port_sequence) - target_apps.append(current_template_app) - port_sequence += port_increment - - # backup current file, but we choose to overwrite instead - # shutil.copy2(file, file+"-"+str(time.time_ns())+".bak") - - # print(current_template_config) - # print(current_template_app) - - # make sure target path exists - os.makedirs(os.path.dirname(target_file), exist_ok=True) - - # save the config.toml production - with open(target_file + 'config.toml', 'w') as f: - f.write(current_template_config) - - # save the app.toml production - with open(target_file + 'app.toml', 'w') as f: - f.write(current_template_app) - - proc = subprocess.Popen(['gaiad', 'start', '--home', target_file.rstrip('/config'), '--x-crisis-skip-assert-invariants']) - - # automatically terminate program (and thus all gaiad instances) after some time - -time.sleep(300) diff --git a/contrib/testnets/test_platform/templates/3924406.cosmoshub-3.json.tar.gz b/contrib/testnets/test_platform/templates/3924406.cosmoshub-3.json.tar.gz deleted file mode 100644 index 8fe8f2f30e4ce57cc29a4282a45d23913887ff48..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9988219 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�Cv|v0NqbQ*k(0a9f_Cj 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≶|)1-ZNbZY!_wqlhsw9kF?-yTEQ|~;N{s;geeYg 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%0D)J5pc$CC)}pp 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

kMw;8P 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

O)YK`?=j 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%0Di;qW&RqcQna9sYeQ#K9UVKeg(cm= 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 z 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

9yAF++E(H z@AT@;u1Dx&y)deM=#AhXu)rNBCVka)r|3v0T+f5R%&1O&yOVA!YR7ezbw~CWbXdp@ zyeDyDH3#Q8uVY|P5xH+{L7b=;`4B=0g2 zqc%f znJ?}B>EpY0m-T}!@E9#HiYIX*fJKiZwUk2>Uf)b|G)89sd-?0YqoSBTLHYy_aaN3007Wi2afjkqDxH>sXG)NylS@Ym=!<(?#*hh{g z(6W;^F*$A_EMUD#-5aaIXwm{fWBc1n?&rzB;UzraKb{(Z#@J6)I=R#{@vf~bq6RG;sr+Oj;Xfqr$?QOuXl)tE zh34-Ev>eNVaV;8IEVoMW5P1CUCod+1fCPU7af3c5CCs3{WR)xATRM?nFJCM$dRZ8$ zIEHJzGKk`nlhb1sKPO><7G?M~7na_bPX?;O2k18E3|$Cx)7KDjmcly;0Lnx!7L z%hb7FXNacsbQ;8U$4qPc;ZG+|)I56maUGh&0m^0s*w(=N|l>4?&7xKZ}9ixfwf>v}g zy8eI#7^0JjlsS`EXk@t+Jmd~^BFhmvKik?Dd1AX_JrP%ZG5&gy{|Hte{#KqwUC#JK zUDF&@-K9(3Zfjj+XT|hmV|YX7(ev3etM~W++fMJ}reBbmo>FD*^gUT@evhh1UlwFk zUF31dnkqCbFHr3i16#wEXN;=1yvyg?=rNI=k5C6{ICZ2n|?ut>X>T)obOQ1o>n(nx{Yga+-;sEH0!E<`Oo&vo)bxk^UCf+dEg0|9YJCjJ!s>LwGPs6*? zYUG~4M7spRFPRbi!+ZL>WH52LmTkqoijybIm09=qLF(%QIkC%AR!{M_kzQ1MLF4!N zMkAXP3}!6OV+JIaYZ+@@2HH+qf~|V!ShZ+%oh*Km_dX+|zjUVi_M}NwF~C5Gq{@!G z57zQH4iiUL{7hKvs_S|2`3+C)X|sz#IJx3&#-31cclpjPPU4CRB-?3O>jT>3sEeo{ zP4Ri`A{0*cPt5!F*!`bXd$09irfdmn$k}1VT2H*DwofNbcbW3}Uh=dp4uzOptuw+E zwjBLx*ygjAetN&`mgm%BR&<9J|Ab;H25>U8HNEe-`Mjb8u#>d&R9a|ixeh)?+N^8% zliT8t#V81&6X?Pv*@9F63M-pl9XxF?WXQf~!9DP66rW6kdM?K?JDO{@;nzKGz+6TV z02YYY#_t&E4tXr4?r5GCWJng*}uz;Nl#!?*V+`Jsqae% zYv+iyRN}FOZQJ19Lmr>JuK0M#3cb+e73f2@%dvp`QCG=ol^aWA5PWR`s)8}=zmN?D z6qDrvqlHKZxbhG?MjJRR59H{ZQ9ERJt&h|KC)YV&l+iCxQ+d9MH<=T(9f_PYHXeCsF%8ke!3Ow;KGh^t=G@fU2GGl@x8W9KDi+-i?^^+N z`j}K$B7n&KVYNboE7A^#g zoyRNIos_Pnmg-<2>bsixjhHj(=hWTa33n4$OwDjJay~)8_I*Gq?d*W}Zzn@L1OWR6 zVitOQ%5_@oE}1Q@uS9KTN1KFk7?ZkC@!U{{G%$i^0-K+2pQjNSay(g)HjB+FR^aK* zIlezpN(p*lH$&QOu@DC-9Xq$i4u=KIOQw7oP~6nB>jI6=)^qJJEWv;v}SJ z(P-dYUIK=CdX^6e!NnJhGoG4>6FRx>V-Vl`E;rSYi!i-U<(h3b)m-(igJ5qvZJ(?G z@_6Wl#f&hHK;3|AO*gfaep;dy0z50`bftTYLs@3}lLUPMetX=YBWyMoMB##^j4`gB zyTn&^5$4|bBrd^&_CM-+?&cg2TJ8(WRBW2J2Ayfv^wB2Rr5G-g`1 z5Q?8;%%cf?bw}5GVJEt!8YEU?$1sO{FRW;?P?tn!AI+qB8c!)Fvr>m}CnL%0o-teO z76~c<9GD!soCk;~V>GD;Ip7G>Z@AU|e8-m0I9DVkt*~?JC9Yz5a3a99-(A)Ga!hzj{q0t$79TihKTstLF6-q$sYT1ncM4}MF}d$bcZS3{`E zKJ26(3DZ*bdW~h60u38r8A8#8fXPc@Ul45{H=nqmGb#r0&K{r=*Wj@d5i?#ab*Jez z+91vgr25G|^0*Yl08g9*pN4FW-jCwC;{sC>TI3row>4OmCR(uMNnRFTp?>n1jB*3q zNlLZY*r*yS1T4g46mV`#c9fOB6k-_D#xz?(Ab9dAYvLi@87J@y{MFEpO$Tjp3LBd_A3%8*co#7H0QlvRnMZOt3HLC_Kh31kc*o7-+W3b8j9s6k1o2 zwdRd!3r$LDjz^kY-{vn4zF~juF}6Wuwp#0s3Qq=haIB}kvL3R_6P0+Vau?Od*$w<; z8mV~fC-;My_=)3pz3s2fDHDAej*2rCk@Ujb!UGuaDiaR(>?q`ng8+Olr)mK|r|K zC28Gpkh$t>wM9gDD0RkBudPnTU6@ev1=;i;I%<<1K0R%Li>qy47qc%;E~LQo_L$~v z1iJQXrawWyU>*GNJpd+V$en_7HF~!x;8O`e>r#OAnW*6wC2RMtrVoBaPc1+Nn_NLQ zRMngpPZb-1*i=Fb>B60I*CnjzsLV{-(gXpDzo5W-Jma|E(acR&y`S6S3CSZ~=t>7H zOzj#6q+%jNUUtGTegQ@~_=1_~V^`vYPoO(3_G;@~&rx#SYs^~n+j&xJhjM7sLT$=}qC*_LFLJv)qX8O(Td z8jLrwmVwkK6LlW@02VVrA69KzkLDe_2!jhhd@R<^gY$iQsFJ6ud5K@V~umEt%z#2fzTQ2D%y!4noaV|&QeGb8(w*qE|Asz4q?2^%3x(hqCxapnO)rzg-i7Vf zP*WC%NlKqwqdi|3hZB_!b&eY{SpiG*N(YuVTnCT@$vsGy-7)SezS4|dObSCkA)?`hH`E#&64M9u=Eh*<#?uz9E=C zen=Qh#0As^y}L_NfFM&H`2(}$AIGJxYcT6)W40Ft_tX1=rtjku?o><^0n`{- z9-TmcE`0d1K^o8N+LT-AW@ReMoS!WC^jv3ifDUpDv9^ z6x0Uz$*APH&fw(8oEp03W~t5^U4rc%En}~{UR*au@J-DG z5g-;6zr+{p6vC&mLO?zd4^jQZ6i1eO;2DFfQ$OTBHdtd44q@li|NJd~Dn|&8USE)T zpAMucV0_XM>5xmeZtH(V7of7*WXqW;@7slvG}iY`@>B9(n3q7 zFn~JUh&=~#Fjo4IPB)rEqinK#$6o|}K{@#RxWtUVu6W$CYqh0=x&j)rtQkptXbh?h zo#bViohoABt{%Pt#62dt^V#7mb!VvNuS9pG%f?*R?7D~~_a9F;fVsAH@c&I;{WKFi z&R~E~WJna>s}(J}SnqTWoGX~;iu2{c-tir^@2^i{&KGnH9t(=!DgN)Vw&Kc-wdQeg zijSh!J2EeLbAY={Daq$)W%ytZc^XPMgRe@F8<$qL#5lfqdFS2z~m~Tk`ya+k`owc zI;aHa=>ZFh|5Kj+a3ejwX^Ppjv7+19=yIGCzPvS#77ZK)@W&N%Yg$|vvCJg=4r zo7_oOIu!?3ztpTCFZ*~?h0Klx$T6{yc%h#vln9&+J0Lpbh;YwZi9TjwWxLlZHw~Ug*SP-le`84`^Q4an)Gw~~q0@#GVt8%p1_)QK{ z&cL?;)7`N+$nk(skfP@ z@Gp^yek{cTrycLi6VXCDo@8zfDq~Yc_M~28c6wBeFO$v-=74>{TYB0Pza5E9VonCo z@2-(*OLt48pgU|*QM3$$4q=I4b{2CeVBerH@wnBA>4XNWGP^+cg4$j1q9l*k-gd@; zq(1K2!Sg7e%xZdCR*TncEm+lf65XZu3$0b-Og!S&*X548&0y=OLK6rh-lr75;4wWl z5<>(`a9$N=ITaOZj{$)r9-Fi-Zg+X0I}lRo9sj~@%p1XwNjRyRul_JAWL0c+ZTc>; z5j#)}ogZ><7;KY}`=aOzoaC_v0h`^%RLc=^;XD<)Y~4bm%BCWUnG=Kx7M*rGS$7l^ zi7zOtpO31^q&u^Wyy$aWvG7sfzVSL!My6!?KRbH1M^JEzEUiQFWPy{?Bq$3C?i+-xv z1L~DtDO2W!Du8#%7kXs6^4Pt}oBHVOmB&dLzGih$EA?2z24w16$~a{pFHbZeU7_nx zw1LY_{N!7NJD>Nv$t0kHVaY|Z+OA_+e8JIJ+Z0~Kp*=*-Vm(!@{EmY9A51hEtpOR$ zo_ej#z)kL)V4j2EO6kFt1J{}s za&(liJ^1p;1K8)i?#Z^GO2(^gCHhqBv5qbBp;wg86~p@hE&H;bU?NCPzak}($Er8< z#V0u_Dem9hy+~Egsg~7CpTv#f5<0?0*F&}O15N@3nJr1B^)7-?SUkiFJK}*Us9h42q{#hBg2C(AjSrV=C2`o+=67{xYlI14_JV__^i^iK;Pf8VQw}$1U<*9g ztRWLzVM93}Sdtw*TQQ7ojt6w@XOZNDf{uNgvH!lL(tXTGf9t>hZKRzqt@t*!1+DvN za$RdZfV`@^iq#9QM$r%Ul7FaCCV^t7n!q5v7eqBC__^sDhWC2LxLATn=EvmL%ZmvB z=obhMlILsevsunwDnz^6!?wV1EXEnEuCv|f>R2{vur0?gw3x|M@?$R;F98ng<8kew z>9s%w_T}-ci2})XEde>XFGQN*i7Uc*l z@{{GR|G@<&Z{Q9Aix(>A6Z2NEy)gy3bmM)L)=G=;Ad~Jn|AJvHd^)W~FCb z;GJH7K|u^tHk;|Y4ztWyoc)IAY8`b{?rZnSLg{K1~5NoNm7@)~;z|_{Zwp z`z=k%Tr=)c?i^NvD>=Tdt3Ojm2k(!;;yed^?G8I!=USGY0Jm9qsgTb0bZEBz95=B zUMq*M**d6EQlp~;F%*OY7TGz^G)iP8X*b?=iRr(sL@^Zt|5Q9dgw8m3hJtN_x&~+Z z6_h?L)aXJ&QM~tyZw4(BUB4T@AofGfgxEBHn-G1#HisR+h!i>QCuT4Z(8$rjHSk5Z zzm4<-UA2EmN|Oe)s$45VFn9YY&&8+Gdd_iW2$j;8^;~{JQ2RE(r1!d>bZZyV)a>YNuIY8Y8QjLBqyK}EE)qo0OjxMVxoxPk8tmCt`9 zj~6L0om?1G6kU;Xhk5HjE;nA=juaHXPPTJw%;|BQ1rhQMoCo+=&5Xjy)ms%B9mup= z`N9eyoZEv32n9|gt8t9PKALIv)B+fR$rTfILs(UIy;lhI(4g?GZ4|+=9>u^;byndQ zrkxDX*96~&okl-SSwKCjPvRh6?JnKZlrsv54ONR1k(w04aTMIfNc#68S7h$ zU}s62*iW^beKlIn*3w?zQ3i{rkb@I8(^?K|2K24Py^rEM0HZoBH#@kD8Yih?7r!yc zLo-ksBtX4nX{F66gnZ+7f_5lZ2=@EgoXWaSj+Kuoa-5?{?GikRaW9Ru#C8lhIffyW zMlIXk6|C}%GkQCq4Dv6~p?iGph9Nj>td*WG8b+xkY-x)!!2ii21;68s$Y+@qWN9}z{18Y>1Kn8SBSy+LH{knEe1fGy5zGDgCDKNQxXtpdZQ4&08 zNp|Sd(({^#A8w=VIImE6s+NE935e&Hv-k|aGkd$m=|Eq{vc}aD+U^huUTDhcW@MjKN5mZyumU9`w}FyK9V9)VcsIuC*on zx0S?Kh-W<(-w-c0=@|LJUCl>FhM!lwGGh@tdV-@yEkrW4{6vv+L$}u?<@&a!b@!GL zNA0qX_lm=wl`gAp6_r!&Wa1<*L4kPTFBqObuXC`NpnQMlnM;amKUc@L`$gf^QDNG+ zW6`nj3&c1X9i#VV!FLpd&s)%J5}3W$nPiX4iTMCj>eX$XA8Dw{5x}}pIMKd*eL;)< zG3$}dYNhqeWxIg#95Y6)DDmPX7FPjOU8ZTe1^)|V9VT9rGH5+(2ZbBDR_mNyu}C=G zv8KhoEO$iF86Cf{O+yf$$Oy0J`=H-4$Xip|Sr!e>KB4MW>=J0{If$PO;h%R`$>dJ> zdMewMc3lw47zmN7z^!l$YWOCz1Sg8kmPMhhMk=P1tKPu3e9%o;2*mHpcDO+^&m!H?luXs5Iy1(_hoq&Kfns#i2rCN?-rT=?m|G#M;fWdE=Mn0|4Ae<~9 zuNUDf-Fht}P}(-E#5uI9?l=gGPSK=&|Jz2trTZpce6pXrMq!-WX=U26%N6Vk+E)e; zIG7KKi(@Yn6CsTGH|!GpLuoRzQC>!AD@B^(%}|JB&||?)r4jby*qcY6+%u^W9=q_#a}) zBqc>p;mFO8`_C}biOz=9u`Y~OpI6(moM~i3z`r1CKjvz_@T9Z4jx&kohCh$@K8_BB zcxGht(&mu0y#^Scd|mfxkxO4-GN!o;yR}^KI7AU-helu4=bi`*3&*;)*q6ouVsu^-O~#YxW~B z$OG`R(^`mrMa+E)@-d)%(tGSWVYKaB36BRFiDiKRQ0E1d3}o5zXtM|R9fLgh)RPzm zU}hvJR9t*blF0=rooSDE-M9(NnuZnY2FSof+<5IN`702yL_;ZYIAV`ZmR*c?Ih1K=82-1PV9Mbaw4NSc zIDvRVC13kafj&12#1Y++&ZP)LU<59=T(R6d-+w{v=LUI`YOs@?oCKeS?5y7YBC=1^ z5sZv9$ZT1sWhN&NUx0qY>iy$$hqsj`!Gwc)|M{4eJv`M|nSI@Gh1xmBL_x<*G0}~O@hOQVj_O06-fo0wWN-}QKr3=XE7vPu2OmYIjq_d#udY}r2 zl3p3v+z`7FZ*WJiv0W#3T7R;iJU(=D1BppIfmh>qY3u_{u=segL@UMth8i*ftFF%c zf*>g)vt8&FCgm6<2fbPaO9@_bAtG~k5mb{dmvQhHc3tm6XL7H7g?qgtCeodNBEq_& zqJhS+YPly3a-co`!u0q~7ZX$grSnS~ZtK)A&Wh2rT|Q^d$? zVu6etLC3Y8>Bwgm_Pjs*-i_KaRwSrx2>1&d@96)@VEknPQdfbtQ6Ohvc^~auF9lL% zCg36EhA;ie>fFy~-*CpHs(O11iFEI-sx!AoImgvS?-Ewjs(>tiGN15qJA-jNnMT!p z+lss4W3;RsP^CKv65xuLOGte?962ZLjNjt<3qCuHw^kyX5AKxSVQPWnL;}$EHQPev z33pJ(FBD*i@!4Rzx|jS1cH1G<@jNu19TbaS@qD^CyqD(PIg3 zie_}8R$YykAjZR^xW+9A*502*7RzHS0VV&*gsSHU0r=#lw0#3(*M}sOh$|{4s@SAj zybOK36(NDkRsx%-p-R)qAS0j1D5!iebf8 zpCX%RnKYaWM6v$LS(Jug@jy|4Rm8}x^}RgZ4GNt zD1>F1BorVZ_yAR^KWs(K$~izV1&>{@n3-z*P$1EbmJ6>i+LH<)%R6)V$Ad5ekV!NJ zu;T;*kn2)dgOdJZy9pO%}Sa5}Kx*R$Ha zJ2p8mbHjf4PcPxkU&`YtkQbfJac8{lC}fJeUJt!r>PkqjcmsUD(dyU&?dc2rgb6yM za+x)>{j95J4bYGTAXq9?gCiBlyuNPnoSxv0%bhfI1juR&6W!f(i$tR{B9*kKfy$QAVZUGOgfvu zx`JTUwv!eN>ZOZz0>vQ#cLon=Vj+rN{L6%%Z@w@ijpRffQpTIP@Bv+{nyDfkzM#CB zRI<9Q|Gld9ZWeevFvR(6`J1?*6BFJK1cS6TlDs;9D18FG>>k0vCZ2++_`kViT%r;m60FsgVqFtJNlpQp6Ql47d%nx!f62x42?**Iind*^c|e~7pfApCzLteg|$R_4OGE6;8tn7Cmfgi9H z`*;OOu!)NCf;~I;wz$<%ex}{wV+*IKZuj289#yk={SFVApcY@^S|q?_tq5Ic?U^Z8 z7(X-430GG5{tZ`3etH>`AmM=u7Z+sNPoL|E=OHQKtL)8^oE7SUegj$Lgw3La2lOO~ zSH4^56G;ov-Y-k6wqFPyvc%Z|4ov>lecwD#Jid&DUTkvCXYpv^i>&)jQ0n>^3=)Fv z?O46I0Qi_2+13H9Jk0=~paUGq78#64>yWgkINecJhaRgj&br(*bZ+n_58wSwwug z!|f=w3pfuJV#48ay0R--O~5_DcPjrL6Hy>0D#y!;qCV;=EkNm@fH?pbux@e$-~z^k zq2n8F3*1gJDRisBBuHk9`xb`2BMWArzy(Nne`~Q=ED-qJNnYTEK4O#au}B((v-wt4 z%uy|_jh>a7lvu(Nb)X~)7JyDpL*IEZ_74ni(p^?s8?Z_~D%}fAi`U&EI`DZe!qs7n zdFMjNW0ptRY_f0B_uFVyEuxr?luq^3i7L#wT5DVVX6U3LcE=t-#0S*N9lW-Q)$U*dT%nN2n>)H=WX2x?>r;pvO<_N<<*Ll1P7 zxFk8zzj^`u5ob!s<1tx`W_8u2Y7$nZq-{ssX_j(y+pKOqG-DASeVJ(M3y$Fj80qoE z{ry@d(2QQx9zl}o`DJNB7A(G2T(yeYcY%@v?_61Yj7%_?HALy5R|tb9`hG!r!RtbB zyCgqCJp6%E5!*McAPPLYe6>)Y?d94gq1DL>Rg#5i2g?oCRj{J1sLsaPK4Fslxv-Cz z^spiV8my@IA`AfjOcd%P@zZpj7~Is+XL5rt@%jW!%IDP*F^MD5$<$&!5xInCvT+#& zIZPu0EDPj6yl8;S7AvobQForGFpZz3^;M5 zpUYV<`~mpxv7K&bnj~(S4|8nVa;dR!hhAt{yjnxPmV$S*9wO_x64$vs_L z5R}cP!sH6Y5M%+8XmaD6jzvo1rj+M`fvz=b;omrOJw-2^@tMMB7z-$u8l5+nVLXBt zpmM*BjycLwUHFt%;{0 z7rbUCD#E%nqp_14J>_*-qTsr>4R##tV$^Q>|0Je&v%vFVY&fw1-Ju_n#w^pOhYwJy zJnlqvwxD6~Y6k>~UCl!ApTDT?XKV&<9ZF$Hli7nCPU@ zD?@ql?S4Duib1jp*E{jt*fhY%SeK}zcb->zyioZG?SX3I%P884)&%W)oM4Cvw!R&!! z-i z>CY@oq#)!^NYMcfNo7oDAcMd@b$5gOp9~BVy+` zU+fkrEp_BjO?I&RWp>HpGpO)m9Wwly=z-9l35V+$vp3qMb6Z_7JKS`UL*g5j@p!#6 z(Rm&z*rZQGyTc1gE<&)%e(doaeqWkLb#zh=)Qlb9pl(V4n@q}6j&67kuPnLRgJ3vh z9Ap(`T$OdK+={O7`#brWTw$NU^`3S#IizG#65xIn+ONCZ7He=IG41Ve zad{sp7q(zA84;%R1EdF@&tjp8eg`#Txg=~72W#C1GhAuxB8@9I=ps|;JoFp8$m1x1 zCd+Ho=pn=?n5dPMu)<(g$a*;2xeegL8GWA2?0v|s=|7lgQV4(t3+duyFjfM?qvPV# zjt;Wk_~h_MLh>8Nuo(FVpMJAIhnHAY8}%sN4c1KOt6P3rJO&SLt6#wvSm1Vn$$$yW zh@F6Xs!7Rp5&p*S&Q;;{*iun;>Fb2we8?+#S~0v$G=ZcL2~_AZ)(me?vUXVjko(~{ zzQO+Dir&x3i1Z7+UKD-61d8~Bl_pIZ=y@S6$=gIOLSq|kNSdmUw_8lr$zR z#3o0w;BXaMCk?L`MCc!JcymAbL-Lw5yo$!K;w>(xis)<$vR*!yi{7&)sYoj1j=#wcLp7g zOV5l?bUdg|6xPK%M3&VLePl=v)5b|PUAC}@>v-#vLeGyG;>ne^`-76MqUT|NsE&i& z@O*<^rU7Y@Wj|nBk8iL5oJsprAo6b4tC3Zn<;;Wc1CWxGhU3_a+zOcC1xf(AlPvoH zT=lq7g$bEpPvAmBF}cXXz8c8=MSjj5R)IZ4SZG}NS7>9Q*CbeEYqgYzOD7croi4Qv zSKBle6m!`J@Lw@Ug~3cnon{jwt={cmJ@!SwXc_@I>$6m)3aQr3bV^NQY=J+7iV3|)yTBIh2T|L6n**^Yd_Z;`s)RVYRNa88Ws@FwnlslzT3WMN$h%U^d!+}PKQ&66(C_! z^d#yE@e$3Ir@5Kp*}Xry9_w}ojiZPX9oSWyT4Nrt{|Y?+l? zm_JX$@F6h-C%B(MZ121v^apr3F+l9gmPFwFEK;ux?%2W5;+og84+Q%Cckk>2kFUwG z*Q}9Wcis%KsM)i*gqj)IU6C?!9iMxNX(q1Bn?)P0vy_$$Th zTKnSDMMbW;lcc1UGa0M*H_z*-&>2UBPF|5jW=ntpYl=)lG;p@sYChzai`z8-)lYUK zZm9keA8>8&Y02Y9Luc~Pq*wSjnKL#L&$Zb1?Zo`Fm(NgIRa`pQ8;6?5u#<@y@Me~5 zCk$0>Kw-WD+ag>Ryix=Z2FRH1CSw5b^$B&c#}a1(%<5tcm)i~c(s#656F?f6JtI{{@3BVB3R;DM>WdV}MF5Vx`2U)3f>`HJ89Le^u=L^OLOp;`}3 zYU~(9TsKLR=(;Q-*LH#Eojp>YY-3^sUi<@M=^r}a6Y>)GbK^EH#KOH1z81P0ii>T0 zulrd>7iybn9Rn!v2P~RBPB>`B@Z#eMrF0Z7;{s`z0au_c4%o0iaANYcv;GWb9k)Ij@H~b8@1t4OuWjCj@`S zCgJ0%+G}|}NvU8^M`E`H+D0w3 zeSkIk02>#boE#jEAvV6D33G>m-}`V;bXNeh%PTtr_o?i)JY!WK@2+po89eh9@w}^)W z9<3^JYR=^x;Ovv@7XlOf0hg;DkCjq9QJ{((s5F|P*-(|V(#INX(i=M0;YEnYVP+RX zK4anGaj66H$%a+50{FsNXVSoJ7#(%fTdGJ8P>fqLJYP~>s>Yb_XP^_Fi(Zg^#ER7)s_>Jo0cw~Fw_mAxoyQ)h2VbKag9?L)i)&YmJz9SA>f^1?qdVIUK92ISbi!X+S!vhbbq2F zL3=yIvRuq>$isZ?$7~+$GcE=`mQ$TuUE=r0O4ZvEb8pYkpmaFL$!TFO@T5oQL2lL`J)Mcu4eb5 zu>vDr%dlq}hbLj&>2|i){DPRX?|Mr&B%cf%MNN32ccQiO&bgrHq&gAIk3!>R#lBxA zPWF1y>&seN48A6}Hsbw`{BAl35!wVJJ2tv$hj($58X%zPY7^Fo(N6>51IiDNx61&Z z3<^hGi_?nvx+p`(wd%U9!p7RQ1*_)HEnguE#~`0<7R9r#+T3)iH#s5A5o@y z%m(RA2PZ}{-Y>BPtXoqkRez~BgaXTz>CpQ)PhWsS{U~K% z@fBl$FEVQ#WLqG}$JOzA1hqzLVmnxZTUVZjQF5l=&}PQyMQ0YkXw$q52M1I9Kv{aH zWbd1i;Yj`dF}`8k1iyfoG|*5#ov%koUEcU4GzsmvV`!>&q%GkyE!*{bs1O4FLp*OD zDxR+egV{t1A_P0$#$wrNm*f=)TITCIu_9qpx|M$ZZX}G*CoID~o^HG0*o0UjijzDk zZp?CLawp^DJaw8#(5m7}ES%itAc*o0kmGo)J;x!KRk0ip9uZiIf?#OtrGX$0x*Z|J zdIgGZUO7q30?8;)x67Zx)M z_+9VU+H#8vMIh}v*r0~A9;y%5^QdOB5GQUl^Y4Yext~18xM)I`TrA83rM7r6L-iJf zi&?O$87nre0ha%{VEAqZcwEe6WOBwcx@yP(EDgcy8N-fCSbEimVDfOf!VcU!cgCJ~ zMP||TMrTBy%e8at5Ylxmy`oX*&2@tD_$n&QcH%hX@DpYh9$#m9fyo8#+e&IUS=Nn$ za|zvV37se7xghVI*(r*3QlooOj(}kF1Nh({;>iT#C3{{poz#8* zR!)U;G9&cwOTM{*o))MeBa_q8F-fso3)Zr&WQarqCp+91OP$d*ro+NG8%N}TeFDOJ zYNXqXCUlDA*Q{H@VRLqBpwvr|kUZW_mnq_H%4*Vy1QDK10Q@?XF~zz@FQ+ zxSK?D!vSpFd_!?UP&|vt7%7iv4+K^w1X#TGjuv)kZ_GICzMwX76!Ajh1DZ=uQ6Qpp zB3Tx_TcqGIWD%N{_8=MYQFD`9$%j8E5#XH{1s*q-5S|>!h@R}uwYyp2>jP^bXT;#F$!Iw`dxlTVdEP7|RWNC5eO_S$0@ z3}&)!aqXRPar}sDxXIu^g9g=WdLNh$&Sg3Y`Y9z;6&jMFPy)LUat4B$2R202Ehy&BQ9C zs!YmUp>ATE;0`D__>38;$7TXxaw8+sIN-i%sd7kG?*tv2C(XyJ$E`J4j{}Ksa1>7P z%u%AMHx|Eti!a;EDRx%39ItABXC0Zx zZbI;E*djKR@y+9)JWpbd5xKgO96lr}7EF$M^O!fb!1Dvim`*A~@l@1#+x@;R+lr{? z`@w-BhAOmoz*UFeV1fG)Ov;C~kF?=kDK$hPj)(g@B9(ZyIW6KCuI}jfNO5y{@c~VA z_WYa@nmm)*PREcM=wd1YYfy~1MZK*oAbF_Gp#7bp*W)YNf=mud#j2ZYw!-Ru73-@`uCuBA_Kt_~<)66Yt2a&AhWf`BS2fF`9MtD^-0x^)7A7SgzL$c|!2BXZ8v8 z;Xll-%@nmHyZAX+ptw*P^U}PhIQJ8%U{AX3e8ic$GG|D9Ku79v0hJ3r@g;Uoqwv9$CnPFN=X}9Z|Rpw+)en(&p*HRB~(L@7ziHLl~Hp|HILR zzPTvr;-IFUeeD6I<*;QlgPJZ@G~;NWQ1g5|CB&x4GYAFfsg`UukB%SF9Esbe$Z*}o zFm$x#opIOWTuCXIAkT0o39;^>r9$&&`)0?<;>}o(Wb=qQ9PFKIo{zCNqq8BOAU)@Y z?$qCbA|bT;vu*q~NNmODexS}KI}>@$Y_ebNImy1+f@eE&OKkbQhFK z9~G%xRw^ERgR*6eW38@6B}I$8BK z!g`o^$ld~37hN=uYy5_~@a+P#C=m~^m|;Ug2karAMia;&BmwxV!$vL%VwNf)>{ zj$G%n790A2MDq9^I-X+E1Dul4gRcRcgSO>jUW9<5)^&+dg%ai0gWt2Ha5mVi`LvU0O*sd1KsTzsXtO0Av0|y_GxM z&P>#p9fg@Re6-*)I0h5rUd56)x%mx|cya(167T^#V~+*e1p^ZuwK~X&BtF5?kA)+8 zZp$efysW7XDYOPC7yrABFn@i5Jo)pHV>W$i*mDCM?bb@MR?@NbF56WEy@rjFZMpV0 zj>*rr<|bp5b@(C9)EI1}u^7o4?%7;}=+f!PhKS z3UTeao3#SDq=v7qcBrqRj~lp~z6HShH&_7OG=F9RBQ~#6+H5=n-w5*ixPhA6i&@eY z60Q0h+R*ehw*XQrkm1}`A4JF6lVlPSF&7*=W{4Cp)BfNLe*iRneuV+gXs%dycWj=z zZDFkjEp`qgJ<)ObpM%(;A}@cp(MyOAS4Mju#A`{v4+THHmpz8Dv5=oSdH_;!R^aQQGcy1?4Utob7SpD9uu6@}<4??j! zjz%v?))qx(=s>QI;rn6KF?lJ7(0{UdZ~jmo(>U;&ArIa(qBqVo=s3t?yy#%is{}KQ zTkB>=9N$nAx!q*)PI!pseh<>e1p>2is!QKM%icP39Jn(C-g%Mh@fJNJlkMPYVZ38P z=9+j+K-HjTb%4sF{;*5CatuP8PYUZF=WEU*JFsux%UH4ZN>KBY05NgplBv z91nO=^Z{|=53gkABPds}L+;KMP=1oO)ap!wKf{xeUk6S28}v9ZMSSKXi$cmDRq%_a z;tD+UPTUdpU0&$25HkYCS13u+^lanoRS4Rz=5r1P%rs+3K_1rEnc>{1@wWCG}PD}N<9K{kT;o(sR zfHN?z0l&Zi3_>=cU$BL(@pf4$bZT0b(g{;nW1GFeIZBE6ol!M>iWn(mlM{CpF1>L) zf<8~p^C5&gNN=z%gEb{tTZ5elu3#$Q2h26W$K!7tOcXk6*$(74y~z}6#vtFJ(ij9a z8b}x`uIScpC}|Q($;3?xqEhYs^v6P_qlIUSgKb8vRLIOd=yIYP{emwnKH)sdW6eB{ z*o=M@7kg-zS(Np=Q_UWwUu+en9W^twEmXYob+gAyT8K?%s%v5Aa#JnAb86CZU@yFz zf=nw(r<7VQ|8sry-7N5YzUwuS53lWrrfj|`ycD)A@**HRQtH9?vxN=}$CF7>j2Zg~ z{qU!0N3h93@Y-%lPKE~cXw*fen_n`55*4g87^q#Pe8&*nMCh!xur9SjfmeI8(yFQ_ zw0hLZamP}ky_Sobc*)Ib7>A!QF#CF1&tRBMG@R-U(2*i0;U%Kc&$O4;k5M*w;ZU)= z%4Oeqm+R@8%IztWDIe|km0)mq6Ovt4Bz&ozhNK`_76NbR0Vb-)1d`9V`u&*A2}&n< zN5=t2j+*9GiXuZi4c#12A#ObEVYQckXF|^&p8*17HdlM1rHDSVEP!Rh7M@5ga48Or zY&vWx>d9eI2mtucLG?HHl&5C8pVNf%o#f!gY~`x=t5VEXzOhqFli0x}#>k;_vhu_b z#ry*p4|?2h;&5_Msh&!R7>$QAt}996My~8E1?%399iO?j8Q%Y{h$8@n!if*$VXq>`zFZ-D z!Qg4tu#42J2-UF5d|_X~2nm>6!Kt|)+S*iH7$;j4-h$zh8#pddD;ZpnnFuH2;3kFO z1F9!ar#uh>la>97c9b!=dH@y3T#+$HjM7NC4U6J>Y?)5_b_}AAxXSQ+POJ zUBK_fYB}QQTe9DfcnF#rKyS8*!QyI>$d!j}ze)DZAU*EzpzEgEgbbk9>l60+pS~r` z1)Id>+eW5wS1C)?oiqi{56p(aD>gVI3UDm`mW14_rm%2@C7j7h{Tge`6wB6QWSt^@$*8E#*b3JYlvDXX=rk#(b zi7*B9WEBNkdL%%#_P|k5wH7eBs`Rr&^Z{P-d^ShS>R5@_)SM&K1$TC}4~NDuhyb}n zh<1fsoe*pGdchB{5qhdFO97nq*;1h<94BOT9ZAqumhHHb2W!mRPDn)7eFLv#fU`+m zJULI13tpfFLlZn9q)EQ4#UC~xchwBW?{4x!7^80j!UA$Q@e`6E3tmgU!K2X)9K}Y- z6ey9FVbwYYp6v+Vnd}4d_a7Q8lcqgUP{i7}?zck?Nmta(zV7Kdy56^_fd3Lf4l*I$ zL`9T{->)G{U@J4gL50FauiaOp7LaFGdKto>Q0>J}`;d^LiLh$L?b;dL@oI_JUN%y< z-HLNa-ij-0f=Ss)<`#nDPdK~uG~7To9Vf%go8_vD4`y4=%nMp{13sPOIDjX|w=VT-oaX4Xd7vFHqSlobY5>LEt9xZZ>7u0l3 zgn2ghaAKidU!>SWjc>gK{S=#U%qP_se;%DBh5}VJY?^2gl!<%8tQA}DSR$@TDHDSK z|Hu2si^q(Rv02U6djaT1sv}918c{V-!hr3faUP_td{+~!Pss<|PJP@!qJYlANsZeE z`nfK>D%GUzVhD9E-gUHqE#sZO^J99Nc{zE_b|2S*SgYLE3z zT_V5IA{zx&tA;ysUZ?I%4v~B3fQ_^E65yX8mGpQY9UwRf$Lg}`$}kYVlbkU>Dkz-Y zpS$G!XyZ;~_AB;BA)3`yR330qcRC_u4JL8pFy6;bNAV{#1Q6mU<3R+z0Q{nt#0Z%U zuPOo-SNq~5@whq)r4!x2y&zMsur4_HsiM};_VOoyo9Cx}W`p2Lx#KWob@;F&EUX*E zmorfsW8!X)K%#eE26%q;obySyTFLEp3l)TyhpKELqj9wOtDdA5xf)-t$#Rjnzvc&w z+C86dhOfz6TG|QLx*T`zhGRKF;Jx@8<7Qj@c4Ezs z=%ld(={2I{cWW0m^gFNYKUd0m&4w)(h4P@PT_-U6(AXK-`AKWT;zlYgvTb(I`*qVr zggO3zc>25-J-ItssZEwvd|hfsS1J5RXIE*z|J<_lx;O#&7dXmofJyt5+EuCrr8Zp4 z>2?yL8`!|k8!Y40q}B1x>Uw`Lz$Bm0;=JQc>$OB)bygT2N~sjC!R(bA5a69F^-u5m zV20TwSW+ZA2uq3^k4IyAgS*i=F92jbMwSMscLwNB^Ce|3IEwV(l@}0+Xp6v!w5-I0p(VC-paN60~70y zsJT0s&pKY<8?wbu5q?6zV$#E#O;bj$#lj-Xq5CFR7#{Lhb*PZ-v12sOD3b4aq|6sB1K1|> zR^l^yFpn?VBQ$GR%1cVvHVw(ojPP~v0=CQKX2{A7h&->yTXz_qj^)u8o9!vdvbU@A zgHnHl4Ypt}erB}CrJ`#U8@Se4a~}$FQ@al+5C4IHO{&APM0Z`MD|}soWhy(;^X{NP z%0|D{b%=LH6_1$_RtF+`<+|NcibtV{d(4^m(h0{oZw!cP2QX#^8XiEW>8x z4r{L?f^~)ZG|;ZwI~O*ehk?l|-j4xJo$wt817|g^yI)Us(UPUTk-6b!Mei)%@_4aV zu*nd%yzJ>^^hD+z$vA^VS;vk0tD1=rzfP1Ik``+~_(aib3XVc5If!)paeD2d~6`Ti}0|Bmw<^ z2G8Sl6oDrK=5lCGFlU!nR#lXMmsl(X#QPhe<0O|j2>sngw{H>j0rEre`8o=mL2I#Z z*(gl5a(``+50uHSXQ@L5IUHFR=<&8F zF4NHwd*`8v$BMLsO)kesA!{(1Ym*kbuKoTG3-0Hxj!mq}<}zxY3@dVgKR{&jY0^cA zP9&P72yNR%rbFPeW#;raZoCN@Q7PYv2S@5FAS7$O;Av?O1_a_J4*#&2PSZz7Q zT7aDb;gIg@J6}zCz68rBGrh7qkupRW7j>LF8F+6CSQZ)9GmSfVUTJw}3p}pHK{$h+ z-SZeXTL+h*3&hBxlQ?oQcfi=Kqr3GJZKW3=U$(M^z^tn-d$>HXAlPkNjqPn|Xdzu{ znum;lNpA4;wS;^3&F?PVBV79|AK+t2ATwuUXRzD*P~ z(ajJA`6_q11Mh_N^T^YgwqW1|7tGCa^bsKumR~!DvBxN9-h==apCF0yJUCD8lt{ym z?NImv$i*ePv9z-La)&Am&Kv(XG``k#rn*9U<8=aTXqO+3kPo+V;;ytX~3+RC|z z=8Yv{Nxebj&O8atz}S3^6!Cyyne)hzb90Xf7-IY*r@DUn|zao z3o_0iv?Ha6j*w&DghcWtQ}T_yNT)`{*-ldbLkb=HumFNIOfXvv}a zVKShbSaZ*PWfxn2w-84!0?{{}1^b~}6QXCstUwwIoQ=C~Cfg2&c7IlJUQnqW{_ZI7t13oVu!)AQ)XRPik%y2Q zS*z$l^BqWSl-M|_r@RV$XBFY6lfw+puG~u<>aiz(0h*Z`fN^@`E<(ZD+_hiJZn}Es zl>2yQ62KWrKXP83*&%C!DQ)e#42(TEC|NCtT5T zcHxJLa4Ynp;%cpR+|79a2;OY1ih;P?Cltl2dMKq zH@_bfGzun?0rJEWMHQXFtghV!78NC(chD`_*m>o)e*-;1h)<*#<;irqR%&jVo_a?c z4hxDW^v#D8wH`0+-#J_S0h~`B0f1#eQbuSSmF8R(GbSlDxT73LY6ynp_fYu);0qg3 zlbi}}+TKljjiPwV$jC#OCbKtg; z9;8y=u!&B71KVMM&FUhgUfdX;=xQkU30gz+nmti*^PGbH>}_@u=Ii3g{hB8AGu+B$ z)&{zh74`0p;n!5qHL$@gaCq@W{ca_QKS3(`Il@7+wQPUvM@tml2>9gJimCk>2Z?zp z^4c$Caw$xGAHp^4JdaKcegJW`W1?6hVk4 z@5F=FAdmKFK^)is$O9B>W`QBF-IV&+>^twIz8(ubGdhvpm)nH;EvUGYcH-1vNj`<{oaq>(P3?~{@V5xx9=z$Ok}R*>V4frl)<>mmE(d7WkX?4 zMC5ylSS;&1d%)uv5c0w^7g+Cfc|V0@%$~3WNrb(U6kTSzAQU#*Cnq{y01?3dJ+3#8 z6@P#gle)>Om^iUo#D>Z_it_7X_RcOi6yg_sl~)v*(LdTp!;6^p@6W5!Y&IC=#^ZhToM)0f{h z1we1QJAvp*xT~+{RnU^F#p|J$D)P2=77{}6xJsWL?-t@Sz{%6a5zHu<063LO;EgTZ z8N`hsu=jCba$#+N6I*i#PS(T`1{9DFC`A4te@{AODpbURzd_8>zydrwcA*!h+lYm7 zLNzAutd#o)2s`nTWgFWz;MloN$ti}mv!+e3i1KLBBQE4SugO1FqQh8B^3qanN-XYt96_W+a1pqR)YFd&{(!k29L~s?KUH;LpwVu(`&4u? zGjfYGeOa_@NR$c^Dr-U!%Z0LVtQkY$Ncd#^p~os@bLp9zVceh7k5aUfY5{v1RReY) zf^MUTlHLD&FanQPpYAv~N#$rfPm4kXArl|3Wi0sqX@P3rlP$LLs3*127r^9)m>1?` zawKk{upRN{567u`O2i54-1{tLDB5w<5AOC)E{;A=clm6xjza3lX}t&A0*rL>l**U` z$;J>ysj|I&bY<`<0tnBP%6u$9Xw4g@-Zq9WeE*S~KXdS```i=hlLQ67AOc@7&Hi-g z|7KM)jP?pRJPs-b&n|;qKyaGF^d>I8(7H1N{hjMvKtWkFYcWlzGhH)}E!SH(FAM4#y z3}#76HOH|H-xl&-&Nc=6!+@2lHH`xT;4?DjgAL_*v1W3rV_Evi`!%|z>vpFkc!xdu z5%PjN*O#vAKP!cQ*~#Y{$kUlRf#7U${|+1>9ho<`f@{f}SkF`&^E3xtAz~|WA3ewX z)IeScPRe-;rPgOE%NlwSOS3vDPfY9wFfJ{Jxc$lpBLM$HG?`Sh*Z_IMVKHf8vTW_L zct>a99tU;`Q1eMAS4v*rG44+ur?C{wdX_i)j)CvjB^QUusGS#|+VnO~SK=19y`TpWqr zX>q)ZI7L^lw=~WoTlNP+tIj)dpPYa`@BWCt9U+U>lsyD@9A&T+NhPMLYttqVQ8*Y- z=3g)YCSDT(4;J=)>nX%UFV-`?4!bPEifY?VPKuA9)kK|vQS?ilK!_BiG- ziB0cD%Qpz|p~nYY0hr9{GjV&2P;crkvqKj;uOw;PI4FzQkZiz9G1>fqkboEahQ-~- zTd9R?*M?ZXQZ;z-4B{(FCC7QK ztedj3OdNIrc>fC%4xAt|VJKZ6YX(B7Nc=(>nF;jzyNJs8;m?q206iRbh;4J?CT0yQ;j6D366e1TV*Kwz5$r`? z{0kcRk5?M-Yf?gEyk6ikaDXy!86%;1<;tN7y_nsxPS<@hhs`kht+t)OVlr38_N^DG zS`kh0NCR3-h1v)J8-nnnA?$sUKEIor0{<3J{2fXrK(!F)qWZNr+KC%LP%ec!g5p4e zYcU*zzk$LGy|DO#GQ;ydqFMU9Q>I{EHn87`BRqg2h4;%HAza|Za@&~s3FizLp1dbW zPPM?w1N4EksL$*0`p`8ZMjTN{~K`?AUKuIZE2xD%dZ zY+!Z!bs9WcJN6u>YG`dQ$BLkG5oNNU#{Yn`K>|z>7$zpGu=lRi z0xAUqrQ1^Ud0UQ%`aK)}0|-#gCPSL6Ko^`Jn-uay`w6jT(#37j8o`>KPP|Su1Tp2} z3*O0ps4UDNGB})QDcthnt2M_$_jG?lrNRJ?w>Cijd4PJl*{u!31J@Wbv{=gYyi_Oqv{p2p>}$qEp2{kGGG-7f@bh84nK@e9&`U&gI~e9o>DlMA6fr z1Ieu64mL}eG|Hhoz?O?bXvdyGKg{*MnMiO!vzNli>kDK@9y?S9z$9A+QVyaD>WW7T zaBtg=km{_?!sJCoFBxq(Op3t$N*tzChQ8J_KljA<2_``6^8ee?xp^mvU0zb2#C zECY*7s+&z`k#u<2$uJG>vh7E@h{kAqvKZEL1i-{0XH^wjYS@UlKlqZ)hVMsIPK2KsLg(5Rg8_?rU04kuh#M>AwK@+ox|MhmZ6F{V ziPsmrrsqLL>Jbkl8&TBY4kcrz>py>m!kJcp&x(8y3fniJI+f;Bk!aqXS45@2AH+ADozU#9xW?B*xyeDffwKuenGwev1Hh5I_iH=;hkwKb48EIJ|O+bghKh_8duC_2tf!j%(yK>#f_5 z7A<((Ko&0yCshM7NJ6K$6w{@yMCvGbs0%ek+=h|xQ1us9Cc4X<@g7gAt<=ALB`~BD9N>7$D>tYd^}uC(;d!V(~(+A1Xs5%qAD-nFSri zTp=`Nu>F2c-six>{cqScfQ1H~lQ#N`e#6|>>pE&=^7(tW3tOby_vtdWKk`x!tfQ#~!-y{_yf6}7NEazuma`*J{LJ)wjNk>N) zf8~x9BVD|Y{Lq8t0k3P7s;pzvSNYeh!KWecl*A*!XH`a>_kAtr&d)ZK13=sqPM(xg zl(-z;_DCn29#CNN1##)=$@!bT%#4J@s2edUHM)?LI=fD^*nYATmQst3)%*<+dEK#2 zfGQ0;Z3u7x}9-LRn>zxp-txB*SekXqM!JKQs(rlV! z*7wPK!t7>6U$9#Cw8AEcpp!!6nw#>d>V5IK$X4PJ|_*T7)XA`={=FR0f) z7h-0!^2=)d`@opW#AaRYj{&sx0h%4h)>o@bC9|aJPN}|NPVn*cI)=05JC%i(2oA6n za&4?yE;ZurcxR$cgoA=Kd2EO>^!frrdYX7bG1HA?RD0CeDS_dYZR{Y(ZOS;u!eQH< zH09LKJLv)p<-5#FO{O-g*m#HuVcl!4ubk-8k;=fbGsL zhKW6f%2UA~jKEV`b-PnMai?t4BV&iE9$4II%gw2ByAa$?a>rSP1=YVmtL{fIiKt8} z2zqX9F-_8a(IxZFK`JO6uvLoOGEqciTnK=_L2>A@vwYVJCor8WCXNBBv2M`qDqK*c zJn|5v-h6b|X424juY2+P34Xz-lqC6ZR@#38Q5RIdl z&cqcRbn(DuTW}4kW!VHfMla{7aoUmx@!zsMpN7CwzXO?=3F5gzG%-Wrwru3i`cAd- zLDG>=>n1QhRD>;wVZ`#4vy0hF$QfwQz2kq)H?xwg2}JS)Y*uaN6~TtGv3 z>T|tV6wrb1O77s|u`Z`NNWS(H4|x+BxBUW>zoReto5r~asbLTS(c-`rV%A+*jz%c~ zn@%z<}6xwScwzgyZf_5mulM`JoIyf$FPC-{nJryW8dFgl}sxK8euSrje z9xuwpONfW{}@dd0!_SCNXPqhiCDTCMqNGEG~ghqW2wBFORh&*zAC* z3xmTl5;ViH9_pQsj_QK&jarrCs5xGfb??_NAw*wda+T5r8SY#Fb6uQkoPwo*b%nYG zWSG%u=%zngU@pij9)7xE>n*i%L7Qdv#P7C;crFnV9;`h2Kf1mMRPf$?i*P-;En zIC4j%NyN3+S(Z)J{WvzP_py+DHnoa573>>^sGfr~F{x{(ES^!RzMqd?6Q-#Yq=$M~+Us&n^K70e&k# zM*#5&OyYv8-phV&MRcNU#r*5h z&TPQqv_x`}kPZzIaWR=fNvZp7^z@~W7vq1o zv0c~7E{PePZ$?IW*}3dk#$}^tYjVHSX9)jB31N&8_yX?nIH)oRC$_`|fifL5wiOq+ z=Qh|V&eOBEQQNwXWB-Mq3b~*&1P;e2)y8cm>(pch;9z8<`{JM+t3R^(#p!O5dJlmZIl!-5> zuRYekLU?jv$?fK#OWGL_hp{};eBfb(ty;4knT!t%*9l1Y{!L#X)$v#(3%%%M*VXM< zFV1U{lS3Zdw(0uaj%=1&%Y%&J#V1PC#Q)2ZuV@)y%>T;21lSCbf zHPqlo3#C0o00S~Bvciirf%eV;zHZ0j0vN2{ezx0|A~AK7>+u5!-2Qa(2#Qd-X>bb3 zs^9b?#D>a7KsZ=m&-Kpq=_ku#Kc?tt+D$J7lAQ=65QH>uX|FYs;2}5!q{jk9D8C@A zd7Ho_M=4-6BRIaYX4l|_8jyhX)JxqhGO)SDPI$*lfEOm;&?bKl(!@~|6V~D*m1V?b z-w0YM!>H#1RTOb;eNmshg!?#Lve!gX(iP%#mzfL^nn7dX>spFkf~0gW;bMcxPxcg# zTXKZGW{jZ?4c92Hp1`G)R*CKDRG@gq0AfI$zl&vM>H1&uYaa)}VJB+E&P*W7(vM^~lqHKhYm6S+IH6>P^5EE7RNivLjw|8R^R z@02kyQKq~xvir%;JAK=+-?wc?-awKZ9ET;ixFykF$WR!f6LnH2t3vV$$DNT_s?P2c z-#u6lvw~gA;jEN>@|MVpiC?l40mS4+lsg%a!Y9A%D%ba+g~}ZfS{Hni_#svw)GzEn zQ1Z{UgFg@eVHH7FhGk&yufW(Vx6 z8Vnw&YszUm>$)rOYoPZpIlfDM9CZ_9bE%sOfj)kLo8DG3;T)*$x4Z0n0b=N7z@yo! zw$Uy0>`ZD!IZhH?{6gaO`T{M?r!^BO2%b0-!%uk`-RmCLyl=Nh8JYQ@adWjS87d1t z`fAbBR2Pd`*~oy?M+s4~B;bb;` zypGTLOg!X(TCQn?ab_yLY@OLd)G9McE8YCE13nRjXAFLWSR{HHm>8Oag!k=8mRW*H zIeH`93Z9dbGe$S*eA=OajbL%R5sxA`DQFoJ1#*6>ojSxwd5bpF3n<)4PYe+XPN09=C?qkUa1A1g># zw~E%rE>O4KY~70V$?G-$p~XDoF1W#wkSBL_HyraNDpl)vb5> zNHJL$Rj2x31Rgs=PG;+vw(sYqJU&#kF6(e?Qtu#mAZ&0Haj@Z!E}J|a5O~clxH`)@ zJzFXWYIBa`jtIr0=4IcbgTW5DeRfapxeh3vDQ;MTlr_VJtk#8YTmc)$usE~Zwx zq{*~9e(`UpFg{(4{ZB*b?+)arxZ<`2vjoL(^|E z;i&~K!*ycTwV^$oVZ}?X5v4#cR%J^mmzvBvnev5ig~YGu zS3G?w43k;V(Nz%Ex?r0h;bH<7#gbt($pt8}iq`2TKb5Do!?&p9Wav!S&7}sTvn@vs z`??P-EQbE5N2>8W+%i!hWCY_cSg?AE5u09sb8m7UHZ650>uHwF==~t7pXmfmu2Q!P zelk0I9ChgnOv>;@u1@q)^Zd+1aG?3*MOl{DKX=ZB0Touo2q*|(G(TqW5CYH951N_K1K#Yjo&VLxrnh<#kt5F%XjDqyZ z93+u;ovmzR1hJ1!w_~ONEGR%7ohMrt3p!ZddF9=Kj!HOnC*eAjW zN6MhwJndWW0j!|_x1EcPd&z!GE?k^C!y@JU<-EW$fU9obP~zhK<^G;z7{^uau78|l=ZeG^U*iro==PXeNczTxF~#QL3vP%@cT^sUe~ON z5(On@xNFN|J{f_h#TCN;zGHhM!0aVgaiw!NbYN1y0u3+yL3PxYjmK!$RNE zFGyi=hW=h6zY*w~G!?i;yG9G@V_C1uXv1~9!rKtUHmN~k{=#3759~_T=>l~?tq`Vt>$rrN zLGSxj_(6|zeDGs>S`@%9_V)(H8v(VE7BzAQ+x)s1j%h0j`om=6UG3&#Q$u+n_yuP2 zbjFQxjwenxxkSvhmWEM2WAo>kM`wB;D5yBLi-&VUU*2~i1%Y3%h4H+W`?u;8k0LUe zuZ6*I_$8*iK~-(QTMKH5ZqpqFwlMoh^>uCYn<41?WHfyB}^P@INq^KO6Eqa_DX1a0!K{uE=2R<}za=Ig-5F z+X=1t7fK6I&{=He25wT`NgzV$YPFrxsACD%9|SE$C=AZ22nzg){m91>bp-w`iFt#B zNj}+jRtw^`7q}-?j@J4q0uPYq+xdR7H+eb-Mqm8zg2`|3&~|V+bXX%N5v-@okayQ0Ca^>Hq|Y^@&3jlz+i9dAvm| zz~74;H$=uGR{~mD*2X)|twQEHharR7%^~T;CqI+t-t_gimgS8=1?XHDqn*(fwn&Ch zq6a+k=?E5^4D}b{3Bi9KJ>_vLDBr1FP=~R;s^;LyR!ZEcrRO4K6#FMDuhHl1T+AZs zM!Iq$D83nU3LfE|>GA`g1r}nqBucC62Se}}f&Y_A{DA-rWTOJS-}}B(Ww1-9xI+ZS z%WVa+Ae}$?a@u447Qp`QZ{G;)R)Xu?;+@5}Ko`5vLp5MRu6x2d#D8uzd@2HuudO4& z#Dp`!tr7t?8}5Xoz}x>PqKG^P^^)@5RSxx&EA3CqUKpUiclK@sAb`nUn1&WOmY#Ni zjp}0@)hOvkOzM-v;nVUcB!bKkSeFVmwOqSsLTBXb8ps_3n}i$onT_Tq13^F5YoJJo zNw_F29>-z#(YvhR_N zu#j>N5j#0BDg8*QN^}*YHU8ko^mq`2TFl|BEh`B)oa)l_Bj;GtAsUO>A33hltwj!7!UrSpbQFjXI%8h4vUQK!9)TR| za=d5dhOLcfY!|djUpM*5^!ur+gp~a~UV0$Tl5b>+-fh4Oswrw|s0 z8r%BGb1siV3VHo~x%o!GB#QS?zz9y{pf9~F3J0LI%nRAqeqZ2}r@Dik|V|T?y+6 z$WD)hRj58UsQQ6!a%W;S`I99gpD%&K*8~9+YgHl%bcXF*P_}DQ_);sSF47f2s;>!& zrQ+s12z`SP`eR|@_pa>(r%MofQp9bs9;~RF*sk?bjRr~4VQX=pobLRGs>dWaBY7X)5etvBler*x53m#KDpBVoSq;s2|NhZLp6|+UkWM&0Wcx*=Cb-c zXvHVp)pBIP{dLA1wXosb+Xb!n(TVMlM!-zH4y(L5eV5)%r@d|-&%R*D`tf21q<`O8H6>y9@v}A!j7;Q*DN8pgd$Usw3%z2R8!w_P3;+PxP+S&|w17lr+Q zE?xf4L!spLx5D#{5#@HPPQ*LA$za__7qk^~Zd8Xo84*wU$!792FvFYWPuwY%3S?5i zk;bB7&-KoEuhVVHpKxKq#yk1_U<4iqlo$E?c*>1H4(6=z+>SfZ?aXIh7IFW*doj=v z&X(-<3)wyrP)x!FrrPFyjG+oX{oz4E zW5E@Lb-xy)7!^UdE*x)N5X4a4OVtDx!ExiGiz7Yib+$FzZm+0 z;`mcnNipUVN1-u{NAHH$g_e4uWU`_xGo>xK-^yumo2=C{j@TFEs88p#5k<49LA@4n zL4nXUa*+!wYxPTCiM`0?cLmKUK3VDiaq@v@f-mbPuMF6pkl&M~$7o3IR~dDONuUKC zh}XZ3M6jRAJ>I?T3F}hETXCL3FIJz9ZbPJCN}$P^!^ZpfZTsZ53i_qnm$wm3#vc^n zSPcRc49nHgr2%Q|FkK94&2oZ{zT8FGj_vHM_G^LY3HOq-QTfmSKn)FsD;YNIEuJ+CZd>S$RRf^?!s{rZBcGJI+y z;w9LG)==JEUj@1Ln#P^aEXp#YLxIX0Zq5T+`^l?g|G|??x)0R2ax}HErNDmN&xF+C zNTKqw(C^S=(I&j^1;{rn1pTwz^~g*x`ddf&Mu`;#c-iwQ$H3o zzi>vEQZgHm@u%vr1dsat?XuG@obZkaD+mfLHxQ!of7=P9_kSu7fZz*sg#QD-o7Bvz zX#KQq?L{b{05MCm(2f8%h^{V(%>9#PgdcAt3qD(kSTx?!DoG2;5-=+5x^wBeT;g%+ zV_Eh_v+p`jl(itj2>(_e z;!de&r57ejv_6r>O~s*^E3`fs6{zeAY?m>tOac_+;!YL5AVgvDSaA3LM3cOdZF;4q zGuC%VtA-oKtJn_GS&pFxwB0}X8z)TYHw+Oxm-l7}%s{H1bm&d-es#)}I{0#DP`76q z#lw)VrayUS@jpbTNr}qIHKZN4qf)QURVZoE%3W-QlsiQ@O5Q$MH03|=-M`&#h^HYt zYB0mCvh3+Wgar812tv){NrY-2J?i{?Ws$%BE*^yF0yUS^mB4j7-L?Kp=E!n$rZjU!%MB*kmSM%wpf>vmlkVj_O@#ipl(p9(nfDyd!| zO03UufZoiawX+%oVUw%-#vEqbCyS3fSLgowWI7L{WddYZbzR$7I};~`+N|8!qYTza zIFumUhcS+47WF#5HpdNEd@8u(fWS7+%X7Fqcg5+TbXmnlZlnQUhEs9 z^5exwLBwP?Gzh&Q73txt9wex^n}7#AD7%xx;KRVi&ALR8&@U*}K6W>Nuo*_K7^Oz0 zI|(qnirik0!gy?6)ma^9xNb&y3Jn+_I~*fhTwS}dR7wXHgvGjcdS)lO8~he%$;_t^j*!MgtMe zP(ojz1oXI03ubf4fwO2f6(R@=>%sJV#4LN}hz_0)kxG=Gyg~gq7shOI3L)&n13W0` z3ZMGU`!b?nS#5ObGO^sG#j*J^n-Kgv3b9X1Yh+r7-Mwj1xngaX;u52u>dt%Qb>@}C z0DR`-Ck}yAK3QlBTc>_Wz)E5{1DnH`9jYz>whOLdjG^OXhx)z0|66v#IhYZ&jpuRy z9~|g#=v>@b4jfKOx6?;r$I;^X3wwX}OPK+X8-Z&(E)aM@CdUO)vA}LFx1npV$6_Ze zo(N3D7nJJR^D6D+P*Z@-mIg6aTi&f%FryS-U^zqtYkH^0@|;v@Z{o|p0Hf!E^V4Pq ztp3u)h801@^oV!<2UufdvukmF2U^T3a6cwccbn0q_*8ZPSs`on@v=G`>^;0Aqgh~cEaH-a!a^3jiMW(7hsalN$8>EhPm1mxZ)^%GJ5-CS5OEdY?4$< z(tsIgCqNq}urBpt%-#tj?cG{TcSAloV|?5@6kxJm7bK>Toslj$;JCdv`2*UQbJ1B7 zgtNll%zB6S7rdidHm!HB(T8o|+PlfJ1YFNX2Z^k1`*{~L7>`i|?*Pf@xF++?8i)T|UUE~JcL zR${WO=-||#A(w{K*#Z3Ia{ki}@(sYmN&(oaAwbGDfS*XhJ^c2b^ zwKda42Edo3m%~`9Df)#e1B%2%V>{#us1!F(4|jaEFqx=Zw$6@ozzPbg^rL0ho;u1q zW1FbRgzVV1cTa-ymTc($yI(_fA!c|5aEc*}|Kz)B@G%50_?mDEBo2dDMS{L$J%j8a z!F@=)_7T;lPB@NF-amQl2RN8L1Juqd;N>z-58~Up7`*Wzl37-pv1!mF_II@4@7f~# zg2Ea64+;N7;31$R671Zyf;FX^m+M1sYX-Kg)-#Jz79hwRh&UO~Q{*95~jDEqU@#7*qn8~2LG4gbQyU--C z4i^|NvdHQ;zelV0?ehJT6>p!*36Y6~WHd`QbA;s{Q1ZiN|N+Uy#pUL4_Mq zMJ(kqUhb0G3?gNTDY&==3bol^pcJ>wB52m%}Ad-#s9ciNvFLJ+`*9J%Nc2u${@q^IZKUE0)A4gm0oTJxL>8Ka`-O7oF|aX}?<(Qc22> zgnQn%hFNq8Y->u_9tX0&FiVLcn2j5(u-_b8W~9ghE{YX9#8yEZA}m2IkghXbrr(<3 zCzwypvD^?9*o_bY7v6S|Z<>1TLbKjl1&KOq`D_^kF!BxK2v3O%BOFfr?TSS%2Bk}2 zUi2D03JX^!1_k1q z>wBzMdXzgq`s4+~=Ue{(O#G=DO?Zx!t+g+5jmi54ccuivhRdvPiZ}kkd2`Y+0<)momu40v=`iWmuKe+UjLki{dAC?VuW9_t#_pZ z&f+K=rl$wC+lDfz=THJj)MVN#ncQ6z1bu^s_G2-A1lc4mDSF<(;NI*)(Oy(gg zUgt`$G&-cvHJZ}66im`!nYW?CY*UqCOab}=7W;gll+Nr#S;S#r3qrn)x|pG0CgJ40 zG&Qyew)_h(g)uZmfK{`d8#_na(b*^>?2_^h(#4jyyyX38&cE%1pgSD|U$DpUT#;uw z`{0vE=dOm6isKXRgl$xia+Z{NkS##C{X(uoIGe>3f9E!+Zkh6<8lG+Q5!c@;VxhvDEYS3W=x7eDWRB$IV|jl_y&c>*z(OyjjJr6vRCsbGUSW z_9}Q@6kI2II`E$z_YV&iujeW$vs(O8g*dk^&INA_V9BTy>%l5KC^6c_T`%fyh+Y(M zPG9s3YKYHun%QislIhEnb1h7r;JULpC@-ZN8Jo|7EP`FZOtzjd!{`g-s~)@D7k^D` ziMeogge?m^)(>_#&jm2}Y$KgHiN`680CMXLoRyRe)DfdW z#EfHPwaw;}(allmH}q|u_qO0n^4mdeTd#(=R5qV2RzO0PkAwJ3$%Nx-suKc3O2F6e-{bp3|M}PtNxQM?=-Q7w6!D8PkWC z!r%}jm&mPqrrSB0xcD(W8A0G=!Rm@JoG32UsOb8VTn!S)7~sXr*vW>WoHf&bOHJjb zIDfyRD;l?M=;R!l{j;`&Xt|Pb<85A z!NdZOw%j&?L|Bz*$Hn*a7ZBiZGE95D7qE!i#3rFQEm>JQxZGAhk`5&-txEX|9Ss4& zMCI)o0!h+*HG*$oCompsZ|gbq9{F;#PSrXIIau6T0Q@0e!O(2z`WiT1oYsA3JJVHL zifwFYUM*v-=bMjesCox{Nh260V7OxQ7+;Q&qLTPf|b&*Gct-1NPQ3 z`T|3FemfUU^2JLydv zd8w)Z36P|_GK-C&dS;I!||)3v8w zKY4@YIqw`!Te+kMd?x}Og1Q}uW_EIHQg?oXj<9?(@On%+dd>7^MvK`V#bvDD zx1%p73TyXdf5 zsFgvqKD%@Jf|$O(L6GHXhZ5a(nv{CYx=03z`(|`GQ^EW&ouYsizU?Tn(9Ta5jeM%o z%Q&7~4IXWUqTFCq#%00S<=|@-Lm)}z0yAK{Zl9b}p6lFA7I{Wv$cB{5lIn&q6toH` zt;ZciuE0X;aeQ(W^Ze!@1CvLPeh@a3}VPJBabZ{s5LiGTE zpu>ejTmZ09D8u={gW+5(2eYqHLMr7;rti0PX8PFKcbP~nF8x=ro-l?477nr?{YuT z+O!lKR)wfdS?aG(E@dBYP5}Ozy_6N8;3AM(J8%QlOBKJ_rgO6UjnODX<`-THA`ngL z6i9@-k@$r!lTwLq^&>nK4V&tGTz+@r`ebI_^V{%~wbqe!ED(v>psUw)czve}l!UKR zpUbwkiqI!ZLOy*2HzEKt3&7CFY8U4fy5u-pHK=yRo#A(mIqD5fXGcJ8xB3Ev{@*zI zp)|>)l*#pe4wOqFi55y*V$#C4pxM&aOLGa-Y#xWHU|(i8#%;T6OtKq~eVy-nu(oa5s@tEJj zUt;1Us#ba^*bmne$FCTAuX4mh!6I0zMg`J{>nub>&Lft3JGn zwT|r<-U|U(OppcGb@0u4!%W>WxbAZPN_^dDuN%1Yt-0_-I*)t@1^Ka*6`S3U9cfE+ zJ4lYZ4FT-S5KB;?z<2FulWcaO6FuA4FSSPRv@>y{1nAh8rk6Y7>bxlzI~Io+97VM3 zdpov|R-k;`79;32vp{O4SA}!z=voZdm5#6^?_2>$b0y0*X`n+Y$QQK5UXO=Xn9t}^ zDQU*nI~b+LPHTZGNA`BP(gpC!aff98jS^WK!>=D}{2^zG1_H0!Qd=2Vl6qr&`eFM(XJ z7x;n|`NwZbpc$)f=ez7@B8w4MB1Ej`XmUGl@K1DY;j;Mn*+Mq}(}-<&!U1{mUxpBvRmD;2;;i__-`t3@46u-UUqI#c1kC z&ghfh$#d0a3}+TFt6Dcm;l+oN*KQ0b{mseEvAngOd#uxU0y)6q3no%eAvy-H$w~HM zg<1K_$;5h<5h-VeOm#h5ixzKeUFwEFgKK$H~T-;exKgqveJes`F^dZP%X8 z@dFmXFFcVMy)D30+fWayiCe;FygX|M(X{tPTrOhmXWDs8@c)_#A08{%bJ<=3CP>z> z+N>s9zEMoN?l2)m2CS*lOEF>@Wq~sk^Fox8*AF!s-&c|Tw$gHhfS1!=1bHGIIU8#5 zN_e@w3_G;BY(6=l{6i0Il2X>wZVW-M%K&0E=W4_b8-QcTofLfpL_S%v7CpxMFFHeL ztF`I=CRnu|?=;F_E5M(kf-oxI6u>ln^3LV+qylDD?@DVWv>gLodOd_ZOQ6bL`fS@N z@DZe=vnwr}5%>+a!QfLiE9BFqv-M~>(LBx*hT&7OmrI_nQRrhayO9#)Pd;e$_+Tes zGvyQtPH8GP@fnk`D=ns3@aC_k;XGhm5_*jEZ}# zn?B8Qg1pg@j(DOKsA%@R8x~OXdp*`)u)rM&Cl)AS^*m}E?$Ezuw%8StutDPcy76)j zjLato!p9aM|DoW&EHGR!f+o<(dboNy5?4TXsR8#Tv`+Q@3qEiM!Ukd6S^@sM2z6> z{x;EzaUs}O*y*w2GKXU3O8!k;U(2#x^1`NeAX&$*ZP{4VrOeA6YMTc!opljK zXLMu``6uhbJm${5;B5Dr)iZ0W@)jAc)U4ZbLcepm?-!58)craqeJ}ApDh9t4O)&oN z>-=S=70Q!#$}cUwJ)i_yo4YW~IRm--z5U8ud3#IU%5y z0_<)St(L^`$(nS}E%2Ik^%(01T(Xji>9(Y*kIc(m)>gQlH&Q)v!1)I(zyzR^SK!W} z8a`W=>j5KiwmD$yX7MSV^2`K2JMJe0;y-oU58i)Fj6^h~iS}-<+dilXx38c};Mg5o zd$bpnpPW-3Z@-AwjE(FFu9bDOaz54+!M1vREtH(hu6S?#!ecgf75_)o{=?mbKHa-y zn7(F@X_Y4-+o38`u#(J--LG8c5)}=2#QQC?jEMTEylUqZ!X+aBNuHYhU=w1Z8 z^z;iD_OAFRE)b&jSJIjGn75{HAa{n~%SG4F;32GI_LHeT&xxpPvMUzD#lwz?^zE+P zptu+sm4QX;&28;+#O5@~y1%7^3W=E9o4rl6#XEBx)^bQro%}_yE~d~%C_2Z=2A}L4 z;`c$fpW033FFLul8G}g{4SbxmrEB4*hILtwWJDKxO)Z>yOhkCzbFeR9^FG$9;(T(r zH-?3G#NL}SnqIK*!9(4Mw%gVNSgv)$@)yQ>1W!(l#xeGIv}0{yw=06<4z)w-m6dU4 z+_7qm;iMFT{0p$_^D^i)S+|R^a|GBK6B`}fVa9aQtUshNh9p5rH(}DJe^JiwRL{P^ zPEW%Pq_g{pF>19_2vMtr6S^3k3O`uZSoQ0;|DLPaoz2%BkqP;R-1Ri#K*DDrH(u{k z;S#w;`X~%td_49}TM1R>P+;y;clxEgB@mskons_vyFG|jkv3&S$e5jnGO;ivPQBFy z;z>mfU*AzHJ=Z&$sF%c8j!Zzx>fG8g>N`8x68W`cgNIwxF;=XMZ@(}TVGK{$&{3RnJ)*n>_YNlt_ECBTVTBTj zQSoMq`UMNzAb9pr1mJ7UtQUD)P?3aXA#jUOEnv;!0=k<|X1PAU89?X+zlc;Wv0YVE zx0L}g+@lia67V`MfCouP{6b01A({-)qgXn#_SCWJiyMCiq!xTGAnF0`--QdVrla9hr-se`gB}v3PyKHXeG4%s3O1sZeZ#=2qNw zh(=C)mx1hkclBy2pLyK1AwBtTEJe(E)ciCFQo5QOz7A0Ieo>Kek3z^hajf9n{)Zs_ z?FJC^H4!|EJc!^iJ}k;x&RuqD#R&E)5gr`?c*RmC(DN&3YyaRQ6GXwYOW`=J7V2cR zugoCLF6UD-HaolkZ$DX6sO7NChlQQRW7t!r~C;>_VA-x{e0i7AFXLLb4>C#%hO z$%8SW-{2{a&xSxSOS_vG?6Qs_QdjBvV407|&Kr90c6DTP?;m|8^YPRV5i*IWo7b*~ zBXcGLE(NXPO;PDGj@_(gJy3<8Y=XykG8saXCiI4}-gXAh9qGK;WjD#_%Lcfe<)8}% z*O=TPx&!L{TwdRBuj%oIw;&U;McmAmoQzvZO$TdN=zO^0*%2sQuC!{7_Q@_9LJYBQ zkb}oh-HBp2*~E$(g3%1LKyvHxp7({LT;dA2>gU!h8vCU0@dA*-_aW;qFx2B`$HfH5 zK#&Q{*RZXz1yzq-=`f4o-RiFuBIoz1{075c;7tE8YzLFj1XI?B@jZirFSH-TxVW_Uq2M6cJg)s$aLN|aCFDYKm!dlvyb4?L*$AjrOEhp@&;h($({rFzdi%g_N zV%BB3qif&5x)PM(Mz#VQx(JX&Eqm$9vP|BI5MR-2e$LAgXfh+rSL*Bli#1?yA;XEC zNZXdqh66f+6859TH~v9I4@_DExw@;IXk`O2r|?@=ao^aMaCZktD-PrM3J*k)h{)-%R&FCNi>v~>DKo`xP_3%eK`zGPaKABzq zT&!sZy%bz1yOQD>aWxbuM_nmp9oC`hR$72`qCf+`fGF@-y_enza`KW?^=1Gik42~( zb>Xwy#C$S^+KWKW*MrEvE%Ytxp^sC}TXSe)BrB}z!FKAo#drlpIe# zbU*qjGUKnwt;JaFzCmtLP<6kwfhJIYF+#_|sM%Xpzd@PCfXsLvK!kkQQ$k9%3J#~X z+y5^u$F@3X1VVuLAF#mtM%Uj4NQg_bE2Ex1@IF1csh_m@^?DPo5CkZBz>@>Jk|2T2u~!>VxpT8UD6uF zok2(TK_b%!yB`p4H>Su}X&-EX$Av6MGgy%vJXhv6waH=Z*%rPL**QJ!c94d8(LX_l z5g5;20ZLa8+--628;6s_#oHH-cxh^m1FLkMVbUAMoc@nS=ZA-i=Ysf@O>DHc18uu5 z`r1;x${kG2=>jH3oXy4VfzKbEQXVUKlZl{2-0w6Bujq?qpzVOc6GCee-pZX)2#`zB zpWO6&JiO&-aya6)fDvt3VmPGXC>GvzKB+isyrX3=kaRG~sselgnf+-tLF_f7{QIB= z)37y;tV@)^vfPhkJGDZ_Td?KqJ~^8_hMrK+Nn6w-U64uA0kv%CP%JE$U2M`PpxRuP zmh#EUkk9W^gP8#c-D+q>N;rIrmM3iX6)vkE)<>Avc71XM`q%&h%+jgHm)_RXhc$3l zwwlG3!W|;cQkRb96*is!4ihgd=r=?P^4LoAb`~++HN-Yym)cD|PGAt>9*5N*CvM8( z^2t2xr}F~@`3zFv49nOZ9ix*1NZ8`FUOpWdoT-MKH^64cR1w2pA>jU$Tz7|)$*2(% zRujR&#;e3d+E%ozEueK(Mr*ldvrp8%upnPxA^3Q{KxRqT2AKMGj3t$G2#$gYi&DuQ z48dbuUbp=xb~*r_Nv_zTJ$+xxs3+wCb$4N@&9;^Ej?!vhgSL}nqJn+Lg4jRg<;ld_ zZoPD`Qaw)+WiF{7hYwW(u!V92-({IRBz~8UuP=B?ugAkm0wxIGrlt_Rtk4G}cwHB- zMits0Aw~>p5VB23cQ5i4egvOx8on2mXYqzE!Ri7PvpVaI@+4z)i8zV02z7Ve*&m2E z6rowXF?_Qw!kw|AQm{2&cVP%Sb<2r+24LMz`nQ|FZ*Y=-ct;axV{}S5XQ9%?{n+SG zOCJcOtHJ^xv*@CewFyMOV7cgNGleoXQL?=)ggV%lpkww+S^UzB$9|5Qm4xvF1{DK<%h5j@bQy*BW2N$}HAUNDKZ%k~|K1=amJ+mqxsxnN!j&+yH9DIWeJG^4!kX`5}^Ku^#wHaZPc)1F3h5=5YwmSeW zx$6_`{TR^7!1jjP`OzAs?0HI^FgqyUed`MC93M-;TruO4+ePB%PSEO%mJ^QD>o)40 zF%bWPjPdw}=8Mt^hNo79#hW$=EO9|-FB?4<>aT0u@a!)5^7v!|$YTo#@|wWYW2?{; zu8P=|ThC3M*9JViKeMV9w$k?f7tWG!j%OL;sI{-)a#8wH-I|EEUb{^!XSaUYbyH;0 z5Woz7gJ|AkrL&h{6OPCM#@0kbOKPRpWR|u;*u5CG`*p)OmwmE`_X6POg!BcRkyDS| z34QQbQjW@EATg68U5<><77JN8z@%~VUIG6xJKZpqOlrQv9u$gG=yfIO+BOg(jy|*= zFP;x4jKiP2+WL6*N5JG3P%P-=o{VOzbH^g=ayBuV%a9e`<;dEhPhJXn++&1bazZl7 z!84>mK(j zisf&sd#IU7k{FFx)%?l>5hO@DHvc+4cBWF{*j z-}TCgF$AvX%OVK1h}#M(-}gn`IR=zZu4Wz!kx@G19ZKK*jm+{{ISm(dNu|gs*>&6o z%|%+?CY-a^|FqhFD5u^v--MbdS@mJrMQ|m(52jUL_T#Q$_7ip^570TA$TT4#zGEQq z4@R0q69%>Get1TCNrlBH5sxnXBNhmOpxrZX59<;+fIZcgug*2;juFzfhSLn?e$JSaos`)eqHhAm>H&d z#gy%#DYfHIrlmY*15Y{eE*~m&7*gXa*iDF?N}hlu+V>rj;oxj{0E7Qh{)cEaVmrteqeC`NZ6aC=;Z{85=e7PXH%J^hP!DIF2yKerQozqWn?X_nb zl%Z>sP_z}L+a@ul1?93bXeMwN-9-fbf;)AOjfCi=tJ_c4kwClP$JmwG2Ukwo;|v&u zV{|i;vE_r^9$fXeyF=}=g4Blm`o*Pf$;P>JrxxUa!^(M4u~?aA{n|T7<1gs_Kfd@V{?o<(!$w2i-k`IRS#Lw2 zu{ye;V`Ptz01Z|u_V5EQiSpTb+#bapj4eGfUy4C1YH(=ean(K?Xvae>`WH4;$V^|b z$GSr`u3fdOi{`E9!4iFWU;C+%qLf+x_cLK%b4K|&w|a8BzQ_9$HBkKMJBKhcJqnLp zaH>@!HfR9+WS0ZJ7y#d(l>K_V_XP==SUT?2D26GcL z2|)?`f*#ECs5?8y+`F%*{#XzXB@G7K@*Xg@PnOJj>L&!V35%zTK4??5 zXwEkWq6=(eLmyuDGn>?6U-t=qd3{B|`G>GPDTRb*cXo#4Y^QpkPEvB5HRjjOa z&sI&)%Ug06e?gNDKIV5IJXs#=LV|KXAUy5@0ML<@l3S9Nf*bXbpcUP=Pd*>}7{35E zVLA2INcU&tPEk`2vFQM+-D>f0wVAeq(ee|gQ2~U1&(M0i8b<00S)N2`a*Q`25_r1^ z3bs|GqU0~EJrMx$-;*o*nwNStB<#21+9sVm)icV;BSg|;3IW^mCsAT00vyL1`4U(?Ep**+PY zJ?@(T@tRAHS9*{wfm)d#HKcO#(D4$ut>uUH*hSY-zE z-4TEU>>aV3h+HPz9r|ME3u>6h*DCL{JF^i*V7V*coyFTu_ViK1AY`pF`96d~mVYwC z>-p>t&RPQeh;a9ww3XfU?MkCZq`(w(1H$SXkD6IHeIX(E7c>|jx9VRvME~1J+ZhnG zMiX*L*3Q&@lO!fOm|z~Jyqb0VZ6pQ+_@#^he?Wl0!>8?lEo>t5i~P^epNmJZu|pLx zF6UPe&=S{AJ~jQAlEUERw0+;26O<1`n=Km~HY((GO#lDm3*cN_{+|By}we(M4@+6&+{X(CII+aLG+=nOsECIoSlTFUU8KSDt2queXWT zRaj!>i5&*s94Av}lx(@eu>7iBw@+5*`-fLDX@+REiUfDL)rRSH6^8lZkELDy2q0uv z$MVU9;-?%E%E&~Mp=(=GCG0}$(K5{`&=nu9k1NErG-(#zX07GBB0%&Dh-?2)<<3IM zI(Y3J8@UY`&(pr|l(1MwT4fkZ_jdW@3rA0zA&^2gu>c$icyZup4i?WgP|wPv5D#b9 z#ha=*M-w*zl>CsBh!+-<3J1DEHj zb9ern^j>rCC#95cx9?p3IxmWi=JGi7DO~emqwDnU93lv!FCgPQ=jKl~efl+4PD==0 z1c+9Wj=k2N3l{|&Q6yi~jGO=B91}sr7reN~^K%3yJEr}@t!8K9wmY3#9YgQ?=CmGx zzQw1c&et!n&N0Umg^RA#o^Fid<)#Jk75K<>GhqIqzog*;oJSnUe zhi;@xuM=i@F(m$Mc5a@LSn`x8BCG}EB&HS)0tBJCk1lcc+gTv1e~#zhB5hdHNe zkn9`y1CI}VA~qw*R^5O$F`i*no9fYYv{dORsC_V=I1sPXId`hwouV_7N4 z;3VJzQsGuygVG=@)82LHE3*nj9eR;Jw=7hQCI-7Ld%=O~XqJy7FzPNDoVX zVQfa}l!%coCN$MxX=gsg*=6acmF)^v)g|_%3z*zN#P^3%D!#x^9=E6f!!tA04Ek*k zqf3IpXxJ*Nc?n3+!B|PB2cOK=czi*E-%n){P}1rUEP|1~hhtrOGklMkoI5|licLM6 znt(hG|2xI{;coIc>SFwwC_{GCaaV?;OM+FoL-NKQEPnF`bjFJFIP53iBzipZV6WL& z2z8rWSO#BDtzx%`*Ng%KhgkQ^)f>p{pWMxTJU%6p+qxYcP?JRHCiipSLb8rx13&@C zp2M+dk%;>Hoe=O1x}dM8CSriFiH&^9cZRVm2xOJELp& z{^Z0E^OYhyD!-6jB5rE6JLpuElL1BYCyPQpCe$N1YZ?&b_e9Tt)&?wtI4N=HwCmi~ zEFwkQkdtHWZw(QSDgFiy;A7rBnzG7q-N8tH#%=fgPB-12%vLG&lA^f3nYoL^t2UZZ{N(5KdOk&+2)lQjfLktJPjXNTCGd5{ zVzE16=V7dBW?QFJ)Gx9M{O#1mDXZiVYbiAyhb8@+0u{H5fs(TvdarC&G|h7p^|KA2igtbisC?-%I;AMY!j^mM9>_43_`@X741$BG7m&Pb38!CO_E zTKiZyDa)#451o5OF~WiMZR0;t?GiX~fpynpoK?B*^0sY`R3d`j-|K85FB;o3%?8Pg z-9`djd;`bp@s{z8VJE7Ief7d|+99EL}>;Cvq4{M4`_nWUN3>aVB-GNMmI#8 zp;)?Q3@=Hqg+t%aRj5WeC}OHWjvdBZdQ5C|=e*B1(c_>@W`k6!*%^a9fG*muOaL|R zm`u+T@BGeZ9F=YV;F$dU;xC#p!6;f7jQQ}>13KSdOFkl0oW$ED33Zi4>O!#A>ouaiuEjCzra

AVLkbXPjLog= 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

Etu&&9p$c3(Pv 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
eaUhwLyh`b)~^zc19(4UO) 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
rWR6vAl#6b5R*~Gom6;*ggRHci>ozOg1(k< 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