Add EVM Support (#1215)

* ibc v3 upgrade

* ibc no longer uses confio

* add proofs proto for ibc/v3

* wip add ethermint module

* update cosmos to 0.45.0

* add ethermint proto & bug fixes

* remove todo

* update docs

* fix a number of bugs

* minor comments update

* fix breaking tests

* Wrap bank keeper for EVM to convert decimals (#1154)

* Add bankkeeper wrapper for evm

* Remove agas from init-new-chain.sh, use ukava for evm_denom

* Fix sdk.Coins conversion, require min 1 coin amount

* Remove gas from init script

idk how this happened lol

* Remove debug logging stmt

* Restore original init ukava amounts

* Fix inplace coins conversion

* Use evmtypes.BankKeeper interface insteadof banktypes

* Add TestGetBalance

* Add doc comments, remove temp actualAmt vars

actualAmt vars replaced with inline calls to make it more clear that the
converted value is being used, as opposed to accidentally reusing the
raw EVM amt.

* Add TestSetBalance

* Add TestIdempotentConversion

* Panic if converted coin from EVM is 0

This happens if a value is less than 1ukava

* Deep copy coins instead of in place modification

* Update test coins amount

* Add panic tests for small EVM amounts

* Use evmtypes.BankKeeper as NewEVMBankKeeper param

* Tidy test setup

* ensure sdk config is set when creating new apps

* Respond EVM bank keeper GetBalance with SpendableCoins

Co-authored-by: Nick DeLuca <nickdeluca08@gmail.com>

* further speed up docker builds

* feat: restore previous keys add defaults, add eth flag (#1172)

* feat: restore previous keys add defaults, add eth flag

* remove outdated comment

* fix: remove redundant flag default

* evm bank keeper with akava handling

* fix issues

* add remaining tests

* add emv module to app

* add missing imports

* clean up comments

* wip akava keeper

* evm keeper

* fix genesis import

* reduce module permissions

* add bank keeper tests

* cleanup tests

* genesis tests

* change defaults

* add eth faucet key & fix issues

* switch to kava ethermint

* add a lot of tests

* add balances invariant

* add evm tests

* Remove panic if Swagger disabled in config (#1155) (#1183)

Co-authored-by: Derrick Lee <derrick@dlee.dev>

* add invariant to catch any akava balance > 1 ukava

* clarify name of balances invariant

* connect invariants to app

* fix evmbankkeeper akava issues

* add spec for evmutil

* remove zero balance accounts from state

* minor adustments

* update to ethermint 0.10.0

* fix eth ante

* add missing godoc comment

* Update x/evmutil/spec/01_concepts.md

Co-authored-by: Kevin Davis <karzak@users.noreply.github.com>

* Update x/evmutil/spec/01_concepts.md

Co-authored-by: Kevin Davis <karzak@users.noreply.github.com>

* Update ethermint to v0.12 (#1203)

* update to ethermint v0.12.2

* use app.Options for new evm options

* fix missed references to app.Options

* use ethermint branch while waiting on upstream fix

* evm migrations for tesnet alpha 2 (#1206)

* update to ethermint v0.12.2

* use app.Options for new evm options

* fix missed references to app.Options

* use ethermint branch while waiting on upstream fix

* add upgrade handler for evm-alpha testnet 2

* v17 migration setup + evm modules

* refactor migrate states

* x/feemarket migration

* v17 migrations setup + evm modules migration (#1210)

* v17 migration setup + evm modules

* refactor migrate states

* update gen time

* fix: update genesis time in test output

Co-authored-by: karzak <kjydavis3@gmail.com>

* add savings module to app blockers

Co-authored-by: Derrick Lee <derrick@dlee.dev>
Co-authored-by: Nick DeLuca <nickdeluca08@gmail.com>
Co-authored-by: rhuairahrighairigh <ruaridh.odonnell@gmail.com>
Co-authored-by: Kevin Davis <karzak@users.noreply.github.com>
Co-authored-by: Ruaridh <rhuairahrighairidh@users.noreply.github.com>
Co-authored-by: karzak <kjydavis3@gmail.com>
This commit is contained in:
Draco Li 2022-04-21 16:16:28 -04:00 committed by GitHub
parent eaeaf20e83
commit c511c56560
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
88 changed files with 9875 additions and 240 deletions

View File

@ -10,17 +10,14 @@ RUN apk add bash git make libc-dev gcc linux-headers eudev-dev jq curl
WORKDIR /root/kava
# default home directory is /root
# Speed up later builds by caching the dependencies
COPY go.mod .
COPY go.sum .
RUN go mod download
# Add source files
COPY . .
#ENV LEDGER_ENABLED False
# Mount build container cache, persisted between builder invocations
# Mount go build and mod caches as container caches, persisted between builder invocations
RUN --mount=type=cache,target=/root/.cache/go-build \
--mount=type=cache,target=/go/pkg/mod \
make install
FROM alpine:3.15

View File

@ -188,7 +188,8 @@ GOGO_PATH := $(shell go list -m -f '{{.Dir}}' github.com/gogo/protobuf)
TENDERMINT_PATH := $(shell go list -m -f '{{.Dir}}' github.com/tendermint/tendermint)
COSMOS_PROTO_PATH := $(shell go list -m -f '{{.Dir}}' github.com/cosmos/cosmos-proto)
COSMOS_SDK_PATH := $(shell go list -m -f '{{.Dir}}' github.com/cosmos/cosmos-sdk)
IBC_GO_PATH := $(shell go list -m -f '{{.Dir}}' github.com/cosmos/ibc-go)
IBC_GO_PATH := $(shell go list -m -f '{{.Dir}}' github.com/cosmos/ibc-go/v3)
ETHERMINT_PATH := $(shell go list -m -f '{{.Dir}}' github.com/tharsis/ethermint)
proto-update-deps:
mkdir -p $(GOOGLE_PROTO_TYPES)
@ -210,7 +211,8 @@ proto-update-deps:
rsync -r --chmod 644 --include "*.proto" --include='*/' --exclude='*' $(TENDERMINT_PATH)/proto third_party
rsync -r --chmod 644 --include "*.proto" --include='*/' --exclude='*' $(COSMOS_SDK_PATH)/proto third_party
rsync -r --chmod 644 --include "*.proto" --include='*/' --exclude='*' $(IBC_GO_PATH)/proto third_party
rsync -r --chmod 644 --include "*.proto" --include='*/' --exclude='*' $(IBC_GO_PATH)/third_party/proto/proofs.proto third_party/proto
rsync -r --chmod 644 --include "*.proto" --include='*/' --exclude='*' $(ETHERMINT_PATH)/proto third_party
cp -f $(IBC_GO_PATH)/third_party/proto/proofs.proto third_party/proto/proofs.proto
.PHONY: proto-all proto-gen proto-gen-any proto-swagger-gen proto-format proto-lint proto-check-breaking proto-update-deps

View File

@ -1,62 +1,152 @@
package ante
import (
"fmt"
"runtime/debug"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/cosmos/cosmos-sdk/x/auth/ante"
authante "github.com/cosmos/cosmos-sdk/x/auth/ante"
authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing"
"github.com/cosmos/cosmos-sdk/x/auth/types"
channelkeeper "github.com/cosmos/ibc-go/modules/core/04-channel/keeper"
ibcante "github.com/cosmos/ibc-go/modules/core/ante"
ibcante "github.com/cosmos/ibc-go/v3/modules/core/ante"
ibckeeper "github.com/cosmos/ibc-go/v3/modules/core/keeper"
tmlog "github.com/tendermint/tendermint/libs/log"
evmante "github.com/tharsis/ethermint/app/ante"
evmtypes "github.com/tharsis/ethermint/x/evm/types"
)
// HandlerOptions extend the SDK's AnteHandler options by requiring the IBC
// channel keeper, EVM Keeper and Fee Market Keeper.
type HandlerOptions struct {
AccountKeeper evmtypes.AccountKeeper
BankKeeper evmtypes.BankKeeper
IBCKeeper *ibckeeper.Keeper
EvmKeeper evmante.EVMKeeper
FeegrantKeeper authante.FeegrantKeeper
SignModeHandler authsigning.SignModeHandler
SigGasConsumer authante.SignatureVerificationGasConsumer
FeeMarketKeeper evmtypes.FeeMarketKeeper
MaxTxGasWanted uint64
AddressFetchers []AddressFetcher
}
func (options HandlerOptions) Validate() error {
if options.AccountKeeper == nil {
return sdkerrors.Wrap(sdkerrors.ErrLogic, "account keeper is required for AnteHandler")
}
if options.BankKeeper == nil {
return sdkerrors.Wrap(sdkerrors.ErrLogic, "bank keeper is required for AnteHandler")
}
if options.SignModeHandler == nil {
return sdkerrors.Wrap(sdkerrors.ErrLogic, "sign mode handler is required for ante builder")
}
if options.EvmKeeper == nil {
return sdkerrors.Wrap(sdkerrors.ErrLogic, "evm keeper is required for AnteHandler")
}
return nil
}
// NewAnteHandler returns an 'AnteHandler' that will run actions before a tx is sent to a module's handler.
func NewAnteHandler(
accountKeeper ante.AccountKeeper,
bankKeeper types.BankKeeper,
feegrantKeeper ante.FeegrantKeeper,
ibcChannelKeeper channelkeeper.Keeper,
signModeHandler authsigning.SignModeHandler, sigGasConsumer ante.SignatureVerificationGasConsumer, addressFetchers ...AddressFetcher) (sdk.AnteHandler, error) {
if accountKeeper == nil {
return nil, sdkerrors.Wrap(sdkerrors.ErrLogic, "account keeper is required for ante builder")
func NewAnteHandler(options HandlerOptions) (sdk.AnteHandler, error) {
if err := options.Validate(); err != nil {
return nil, err
}
if bankKeeper == nil {
return nil, sdkerrors.Wrap(sdkerrors.ErrLogic, "bank keeper is required for ante builder")
}
return func(
ctx sdk.Context, tx sdk.Tx, sim bool,
) (newCtx sdk.Context, err error) {
var anteHandler sdk.AnteHandler
if signModeHandler == nil {
return nil, sdkerrors.Wrap(sdkerrors.ErrLogic, "sign mode handler is required for ante builder")
}
defer Recover(ctx.Logger(), &err)
if sigGasConsumer == nil {
sigGasConsumer = ante.DefaultSigVerificationGasConsumer
}
txWithExtensions, ok := tx.(authante.HasExtensionOptionsTx)
if ok {
opts := txWithExtensions.GetExtensionOptions()
if len(opts) > 0 {
switch typeURL := opts[0].GetTypeUrl(); typeURL {
case "/ethermint.evm.v1.ExtensionOptionsEthereumTx":
// handle as *evmtypes.MsgEthereumTx
anteHandler = newEthAnteHandler(options)
default:
return ctx, sdkerrors.Wrapf(
sdkerrors.ErrUnknownExtensionOptions,
"rejecting tx with unsupported extension option: %s", typeURL,
)
}
return anteHandler(ctx, tx, sim)
}
}
// handle as totally normal Cosmos SDK tx
switch tx.(type) {
case sdk.Tx:
anteHandler = newCosmosAnteHandler(options)
default:
return ctx, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid transaction type: %T", tx)
}
return anteHandler(ctx, tx, sim)
}, nil
}
func newCosmosAnteHandler(options HandlerOptions) sdk.AnteHandler {
decorators := []sdk.AnteDecorator{}
decorators = append(decorators,
ante.NewSetUpContextDecorator(), // outermost AnteDecorator. SetUpContext must be called first
ante.NewRejectExtensionOptionsDecorator(),
evmante.RejectMessagesDecorator{}, // reject MsgEthereumTxs
authante.NewSetUpContextDecorator(), // second decorator. SetUpContext must be called before other decorators
authante.NewRejectExtensionOptionsDecorator(),
)
if len(addressFetchers) > 0 {
decorators = append(decorators, NewAuthenticatedMempoolDecorator(addressFetchers...))
if len(options.AddressFetchers) > 0 {
decorators = append(decorators, NewAuthenticatedMempoolDecorator(options.AddressFetchers...))
}
decorators = append(decorators,
ante.NewMempoolFeeDecorator(),
authante.NewMempoolFeeDecorator(),
NewVestingAccountDecorator(),
ante.NewValidateBasicDecorator(),
ante.NewTxTimeoutHeightDecorator(),
ante.NewValidateMemoDecorator(accountKeeper),
ante.NewConsumeGasForTxSizeDecorator(accountKeeper),
ante.NewDeductFeeDecorator(accountKeeper, bankKeeper, feegrantKeeper),
ante.NewSetPubKeyDecorator(accountKeeper), // SetPubKeyDecorator must be called before all signature verification decorators
ante.NewValidateSigCountDecorator(accountKeeper),
ante.NewSigGasConsumeDecorator(accountKeeper, sigGasConsumer),
ante.NewSigVerificationDecorator(accountKeeper, signModeHandler),
ante.NewIncrementSequenceDecorator(accountKeeper), // innermost AnteDecorator
ibcante.NewAnteDecorator(ibcChannelKeeper),
authante.NewValidateBasicDecorator(),
authante.NewTxTimeoutHeightDecorator(),
authante.NewValidateMemoDecorator(options.AccountKeeper),
authante.NewConsumeGasForTxSizeDecorator(options.AccountKeeper),
authante.NewDeductFeeDecorator(options.AccountKeeper, options.BankKeeper, options.FeegrantKeeper),
authante.NewSetPubKeyDecorator(options.AccountKeeper), // SetPubKeyDecorator must be called before all signature verification decorators
authante.NewValidateSigCountDecorator(options.AccountKeeper),
authante.NewSigGasConsumeDecorator(options.AccountKeeper, options.SigGasConsumer),
authante.NewSigVerificationDecorator(options.AccountKeeper, options.SignModeHandler),
authante.NewIncrementSequenceDecorator(options.AccountKeeper), // innermost AnteDecorator
ibcante.NewAnteDecorator(options.IBCKeeper),
)
return sdk.ChainAnteDecorators(decorators...), nil
return sdk.ChainAnteDecorators(decorators...)
}
func newEthAnteHandler(options HandlerOptions) sdk.AnteHandler {
return sdk.ChainAnteDecorators(
evmante.NewEthSetUpContextDecorator(options.EvmKeeper), // outermost AnteDecorator. SetUpContext must be called first
evmante.NewEthMempoolFeeDecorator(options.EvmKeeper), // Check eth effective gas price against minimal-gas-prices
evmante.NewEthValidateBasicDecorator(options.EvmKeeper),
evmante.NewEthSigVerificationDecorator(options.EvmKeeper),
evmante.NewEthAccountVerificationDecorator(options.AccountKeeper, options.BankKeeper, options.EvmKeeper),
evmante.NewEthGasConsumeDecorator(options.EvmKeeper, options.MaxTxGasWanted),
evmante.NewCanTransferDecorator(options.EvmKeeper),
evmante.NewEthIncrementSenderSequenceDecorator(options.AccountKeeper), // innermost AnteDecorator.
)
}
func Recover(logger tmlog.Logger, err *error) {
if r := recover(); r != nil {
*err = sdkerrors.Wrapf(sdkerrors.ErrPanic, "%v", r)
if e, ok := r.(error); ok {
logger.Error(
"ante handler panicked",
"error", e,
"stack trace", string(debug.Stack()),
)
} else {
logger.Error(
"ante handler panicked",
"recover", fmt.Sprintf("%v", r),
)
}
}
}

View File

@ -31,6 +31,11 @@ func TestAppAnteHandler(t *testing.T) {
manualKeys := testPrivKeys[6:]
encodingConfig := app.MakeEncodingConfig()
opts := app.DefaultOptions
opts.MempoolEnableAuth = true
opts.MempoolAuthAddresses = manual
tApp := app.TestApp{
App: *app.NewApp(
log.NewNopLogger(),
@ -38,14 +43,11 @@ func TestAppAnteHandler(t *testing.T) {
app.DefaultNodeHome,
nil,
encodingConfig,
app.Options{
MempoolEnableAuth: true,
MempoolAuthAddresses: manual,
},
opts,
),
}
chainID := "internal-test-chain"
chainID := "kavatest_1-1"
tApp = tApp.InitializeFromGenesisStatesWithTimeAndChainID(
time.Date(1998, 1, 1, 0, 0, 0, 0, time.UTC),
chainID,

View File

@ -20,12 +20,11 @@ import (
"github.com/cosmos/cosmos-sdk/types/module"
"github.com/cosmos/cosmos-sdk/version"
"github.com/cosmos/cosmos-sdk/x/auth"
authante "github.com/cosmos/cosmos-sdk/x/auth/ante"
authrest "github.com/cosmos/cosmos-sdk/x/auth/client/rest"
authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
authtx "github.com/cosmos/cosmos-sdk/x/auth/tx"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
"github.com/cosmos/cosmos-sdk/x/auth/vesting"
vestingtypes "github.com/cosmos/cosmos-sdk/x/auth/vesting/types"
"github.com/cosmos/cosmos-sdk/x/bank"
bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
@ -65,20 +64,30 @@ import (
upgradeclient "github.com/cosmos/cosmos-sdk/x/upgrade/client"
upgradekeeper "github.com/cosmos/cosmos-sdk/x/upgrade/keeper"
upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
transfer "github.com/cosmos/ibc-go/modules/apps/transfer"
ibctransferkeeper "github.com/cosmos/ibc-go/modules/apps/transfer/keeper"
ibctransfertypes "github.com/cosmos/ibc-go/modules/apps/transfer/types"
ibc "github.com/cosmos/ibc-go/modules/core"
ibcclient "github.com/cosmos/ibc-go/modules/core/02-client"
ibcclientclient "github.com/cosmos/ibc-go/modules/core/02-client/client"
ibcclienttypes "github.com/cosmos/ibc-go/modules/core/02-client/types"
porttypes "github.com/cosmos/ibc-go/modules/core/05-port/types"
ibchost "github.com/cosmos/ibc-go/modules/core/24-host"
ibckeeper "github.com/cosmos/ibc-go/modules/core/keeper"
transfer "github.com/cosmos/ibc-go/v3/modules/apps/transfer"
ibctransferkeeper "github.com/cosmos/ibc-go/v3/modules/apps/transfer/keeper"
ibctransfertypes "github.com/cosmos/ibc-go/v3/modules/apps/transfer/types"
ibc "github.com/cosmos/ibc-go/v3/modules/core"
ibcclient "github.com/cosmos/ibc-go/v3/modules/core/02-client"
ibcclientclient "github.com/cosmos/ibc-go/v3/modules/core/02-client/client"
ibcclienttypes "github.com/cosmos/ibc-go/v3/modules/core/02-client/types"
porttypes "github.com/cosmos/ibc-go/v3/modules/core/05-port/types"
ibchost "github.com/cosmos/ibc-go/v3/modules/core/24-host"
ibckeeper "github.com/cosmos/ibc-go/v3/modules/core/keeper"
abci "github.com/tendermint/tendermint/abci/types"
tmjson "github.com/tendermint/tendermint/libs/json"
tmlog "github.com/tendermint/tendermint/libs/log"
dbm "github.com/tendermint/tm-db"
evmante "github.com/tharsis/ethermint/app/ante"
ethermintconfig "github.com/tharsis/ethermint/server/config"
ethermint "github.com/tharsis/ethermint/types"
"github.com/tharsis/ethermint/x/evm"
evmrest "github.com/tharsis/ethermint/x/evm/client/rest"
evmkeeper "github.com/tharsis/ethermint/x/evm/keeper"
evmtypes "github.com/tharsis/ethermint/x/evm/types"
"github.com/tharsis/ethermint/x/feemarket"
feemarketkeeper "github.com/tharsis/ethermint/x/feemarket/keeper"
feemarkettypes "github.com/tharsis/ethermint/x/feemarket/types"
"github.com/kava-labs/kava/app/ante"
kavaparams "github.com/kava-labs/kava/app/params"
@ -95,6 +104,9 @@ import (
committeeclient "github.com/kava-labs/kava/x/committee/client"
committeekeeper "github.com/kava-labs/kava/x/committee/keeper"
committeetypes "github.com/kava-labs/kava/x/committee/types"
evmutil "github.com/kava-labs/kava/x/evmutil"
evmutilkeeper "github.com/kava-labs/kava/x/evmutil/keeper"
evmutiltypes "github.com/kava-labs/kava/x/evmutil/types"
"github.com/kava-labs/kava/x/hard"
hardkeeper "github.com/kava-labs/kava/x/hard/keeper"
hardtypes "github.com/kava-labs/kava/x/hard/types"
@ -118,11 +130,12 @@ import (
swapkeeper "github.com/kava-labs/kava/x/swap/keeper"
swaptypes "github.com/kava-labs/kava/x/swap/types"
validatorvesting "github.com/kava-labs/kava/x/validator-vesting"
validatorvestingtypes "github.com/kava-labs/kava/x/validator-vesting/types"
)
const (
appName = "kava"
upgradeName = "v44"
upgradeName = "testnet-evm-alpha-2"
)
var (
@ -157,6 +170,8 @@ var (
evidence.AppModuleBasic{},
transfer.AppModuleBasic{},
vesting.AppModuleBasic{},
evm.AppModuleBasic{},
feemarket.AppModuleBasic{},
kavadist.AppModuleBasic{},
auction.AppModuleBasic{},
issuance.AppModuleBasic{},
@ -169,6 +184,7 @@ var (
incentive.AppModuleBasic{},
savings.AppModuleBasic{},
validatorvesting.AppModuleBasic{},
evmutil.AppModuleBasic{},
)
// module account permissions
@ -182,6 +198,8 @@ var (
stakingtypes.NotBondedPoolName: {authtypes.Burner, authtypes.Staking},
govtypes.ModuleName: {authtypes.Burner},
ibctransfertypes.ModuleName: {authtypes.Minter, authtypes.Burner},
evmtypes.ModuleName: {authtypes.Minter, authtypes.Burner}, // used for secure addition and subtraction of balance using module account
evmutiltypes.ModuleName: nil,
kavadisttypes.KavaDistMacc: {authtypes.Minter},
auctiontypes.ModuleName: nil,
issuancetypes.ModuleAccountName: {authtypes.Minter, authtypes.Burner},
@ -199,7 +217,6 @@ var (
var _ servertypes.Application = (*App)(nil)
// Options bundles several configuration params for an App.
// The zero value can be used as a sensible default.
type Options struct {
SkipLoadLatest bool
SkipUpgradeHeights map[int64]bool
@ -207,6 +224,14 @@ type Options struct {
InvariantCheckPeriod uint
MempoolEnableAuth bool
MempoolAuthAddresses []sdk.AccAddress
EVMTrace string
EVMMaxGasWanted uint64
}
// DefaultOptions is a sensible default Options value.
var DefaultOptions = Options{
EVMTrace: ethermintconfig.DefaultEVMTracer,
EVMMaxGasWanted: ethermintconfig.DefaultMaxTxGasWanted,
}
// App is the Kava ABCI application.
@ -235,6 +260,9 @@ type App struct {
crisisKeeper crisiskeeper.Keeper
slashingKeeper slashingkeeper.Keeper
ibcKeeper *ibckeeper.Keeper // IBC Keeper must be a pointer in the app, so we can SetRouter on it correctly
evmKeeper *evmkeeper.Keeper
evmutilKeeper evmutilkeeper.Keeper
feeMarketKeeper feemarketkeeper.Keeper
upgradeKeeper upgradekeeper.Keeper
evidenceKeeper evidencekeeper.Keeper
transferKeeper ibctransferkeeper.Keeper
@ -298,12 +326,14 @@ func NewApp(
minttypes.StoreKey, distrtypes.StoreKey, slashingtypes.StoreKey,
govtypes.StoreKey, paramstypes.StoreKey, ibchost.StoreKey,
upgradetypes.StoreKey, evidencetypes.StoreKey, ibctransfertypes.StoreKey,
evmtypes.StoreKey, feemarkettypes.StoreKey,
capabilitytypes.StoreKey, kavadisttypes.StoreKey, auctiontypes.StoreKey,
issuancetypes.StoreKey, bep3types.StoreKey, pricefeedtypes.StoreKey,
swaptypes.StoreKey, cdptypes.StoreKey, hardtypes.StoreKey,
committeetypes.StoreKey, incentivetypes.StoreKey, savingstypes.StoreKey,
committeetypes.StoreKey, incentivetypes.StoreKey, evmutiltypes.StoreKey,
savingstypes.StoreKey,
)
tkeys := sdk.NewTransientStoreKeys(paramstypes.TStoreKey)
tkeys := sdk.NewTransientStoreKeys(paramstypes.TStoreKey, evmtypes.TransientKey)
memKeys := sdk.NewMemoryStoreKeys(capabilitytypes.MemStoreKey)
var app = &App{
@ -343,6 +373,8 @@ func NewApp(
savingsSubspace := app.paramsKeeper.Subspace(savingstypes.ModuleName)
ibcSubspace := app.paramsKeeper.Subspace(ibchost.ModuleName)
ibctransferSubspace := app.paramsKeeper.Subspace(ibctransfertypes.ModuleName)
feemarketSubspace := app.paramsKeeper.Subspace(feemarkettypes.ModuleName)
evmSubspace := app.paramsKeeper.Subspace(evmtypes.ModuleName)
bApp.SetParamStore(
app.paramsKeeper.Subspace(baseapp.Paramspace).WithKeyTable(paramskeeper.ConsensusParamsKeyTable()),
@ -357,7 +389,7 @@ func NewApp(
appCodec,
keys[authtypes.StoreKey],
authSubspace,
authtypes.ProtoBaseAccount,
ethermint.ProtoAccount,
mAccPerms,
)
app.bankKeeper = bankkeeper.NewBaseKeeper(
@ -428,6 +460,23 @@ func NewApp(
scopedIBCKeeper,
)
// Create Ethermint keepers
app.feeMarketKeeper = feemarketkeeper.NewKeeper(
appCodec, keys[feemarkettypes.StoreKey], feemarketSubspace,
)
app.evmutilKeeper = evmutilkeeper.NewKeeper(
app.appCodec,
keys[evmutiltypes.StoreKey],
)
evmBankKeeper := evmutilkeeper.NewEvmBankKeeper(app.evmutilKeeper, app.bankKeeper, app.accountKeeper)
app.evmKeeper = evmkeeper.NewKeeper(
appCodec, keys[evmtypes.StoreKey], tkeys[evmtypes.TransientKey], evmSubspace,
app.accountKeeper, evmBankKeeper, app.stakingKeeper, app.feeMarketKeeper,
options.EVMTrace,
)
app.kavadistKeeper = kavadistkeeper.NewKeeper(
appCodec,
keys[kavadisttypes.StoreKey],
@ -461,16 +510,18 @@ func NewApp(
keys[ibctransfertypes.StoreKey],
ibctransferSubspace,
app.ibcKeeper.ChannelKeeper,
app.ibcKeeper.ChannelKeeper,
&app.ibcKeeper.PortKeeper,
app.accountKeeper,
app.bankKeeper,
scopedTransferKeeper,
)
transferModule := transfer.NewAppModule(app.transferKeeper)
transferIBCModule := transfer.NewIBCModule(app.transferKeeper)
// Create static IBC router, add transfer route, then set and seal it
ibcRouter := porttypes.NewRouter()
ibcRouter.AddRoute(ibctransfertypes.ModuleName, transferModule)
ibcRouter.AddRoute(ibctransfertypes.ModuleName, transferIBCModule)
app.ibcKeeper.SetRouter(ibcRouter)
app.auctionKeeper = auctionkeeper.NewKeeper(
@ -588,6 +639,8 @@ func NewApp(
crisis.NewAppModule(&app.crisisKeeper, options.SkipGenesisInvariants),
slashing.NewAppModule(appCodec, app.slashingKeeper, app.accountKeeper, app.bankKeeper, app.stakingKeeper),
ibc.NewAppModule(app.ibcKeeper),
evm.NewAppModule(app.evmKeeper, app.accountKeeper),
feemarket.NewAppModule(app.feeMarketKeeper),
upgrade.NewAppModule(app.upgradeKeeper),
evidence.NewAppModule(app.evidenceKeeper),
transferModule,
@ -604,6 +657,7 @@ func NewApp(
hard.NewAppModule(app.hardKeeper, app.accountKeeper, app.bankKeeper, app.pricefeedKeeper),
committee.NewAppModule(app.committeeKeeper, app.accountKeeper),
incentive.NewAppModule(app.incentiveKeeper, app.accountKeeper, app.bankKeeper, app.cdpKeeper),
evmutil.NewAppModule(app.evmutilKeeper, app.bankKeeper),
savings.NewAppModule(app.savingsKeeper, app.accountKeeper, app.bankKeeper),
)
@ -623,6 +677,8 @@ func NewApp(
slashingtypes.ModuleName,
evidencetypes.ModuleName,
stakingtypes.ModuleName,
feemarkettypes.ModuleName,
evmtypes.ModuleName,
kavadisttypes.ModuleName,
// Auction begin blocker will close out expired auctions and pay debt back to cdp.
// It should be run before cdp begin blocker which cancels out debt with stable and starts more auctions.
@ -633,6 +689,12 @@ func NewApp(
issuancetypes.ModuleName,
incentivetypes.ModuleName,
ibchost.ModuleName,
// Add all remaining modules with an empty begin blocker below since cosmos 0.45.0 requires it
swaptypes.ModuleName,
vestingtypes.ModuleName,
pricefeedtypes.ModuleName,
validatorvestingtypes.ModuleName,
authtypes.ModuleName, banktypes.ModuleName, govtypes.ModuleName, crisistypes.ModuleName, genutiltypes.ModuleName, ibctransfertypes.ModuleName, paramstypes.ModuleName, evmutiltypes.ModuleName, savingstypes.ModuleName,
)
// Warning: Some end blockers must run before others. Ensure the dependencies are understood before modifying this list.
@ -640,7 +702,31 @@ func NewApp(
crisistypes.ModuleName,
govtypes.ModuleName,
stakingtypes.ModuleName,
evmtypes.ModuleName,
// fee market module must go after evm module in order to retrieve the block gas used.
feemarkettypes.ModuleName,
pricefeedtypes.ModuleName,
// Add all remaining modules with an empty end blocker below since cosmos 0.45.0 requires it
capabilitytypes.ModuleName,
incentivetypes.ModuleName,
issuancetypes.ModuleName,
minttypes.ModuleName,
slashingtypes.ModuleName,
distrtypes.ModuleName,
auctiontypes.ModuleName,
bep3types.ModuleName,
cdptypes.ModuleName,
hardtypes.ModuleName,
committeetypes.ModuleName,
upgradetypes.ModuleName,
evidencetypes.ModuleName,
kavadisttypes.ModuleName,
swaptypes.ModuleName,
vestingtypes.ModuleName,
pricefeedtypes.ModuleName,
ibchost.ModuleName,
validatorvestingtypes.ModuleName,
authtypes.ModuleName, banktypes.ModuleName, govtypes.ModuleName, crisistypes.ModuleName, genutiltypes.ModuleName, ibctransfertypes.ModuleName, paramstypes.ModuleName, evmutiltypes.ModuleName, savingstypes.ModuleName,
)
// Warning: Some init genesis methods must run before others. Ensure the dependencies are understood before modifying this list
@ -656,6 +742,7 @@ func NewApp(
ibchost.ModuleName,
evidencetypes.ModuleName,
ibctransfertypes.ModuleName,
evmtypes.ModuleName, feemarkettypes.ModuleName,
kavadisttypes.ModuleName,
auctiontypes.ModuleName,
issuancetypes.ModuleName,
@ -669,6 +756,13 @@ func NewApp(
committeetypes.ModuleName,
genutiltypes.ModuleName, // runs arbitrary txs included in genisis state, so run after modules have been initialized
crisistypes.ModuleName, // runs the invariants at genesis, should run after other modules
// Add all remaining modules with an empty InitGenesis below since cosmos 0.45.0 requires it
vestingtypes.ModuleName,
paramstypes.ModuleName,
upgradetypes.ModuleName,
validatorvestingtypes.ModuleName,
evmutiltypes.ModuleName,
savingstypes.ModuleName,
)
app.mm.RegisterInvariants(&app.crisisKeeper)
@ -688,7 +782,8 @@ func NewApp(
// gov.NewAppModule(app.govKeeper, app.accountKeeper, app.accountKeeper, app.bankKeeper),
// mint.NewAppModule(app.mintKeeper),
// distr.NewAppModule(app.distrKeeper, app.accountKeeper, app.accountKeeper, app.bankKeeper, app.stakingKeeper),
// staking.NewAppModule(app.stakingKeeper, app.accountKeeper, app.accountKeeper, app.bankKeeper),
// staking.NewAppModule(app.stakingKeeper, app.accountKeeper, app.accountKeeper, app.bankKeeper),
// evm.NewAppModule(app.evmKeeper, app.accountKeeper),
// slashing.NewAppModule(app.slashingKeeper, app.accountKeeper, app.stakingKeeper),
// )
// app.sm.RegisterStoreDecoders()
@ -707,15 +802,20 @@ func NewApp(
app.pricefeedKeeper.GetAuthorizedAddresses,
)
}
antehandler, err := ante.NewAnteHandler(
app.accountKeeper,
app.bankKeeper,
nil,
app.ibcKeeper.ChannelKeeper,
encodingConfig.TxConfig.SignModeHandler(),
authante.DefaultSigVerificationGasConsumer,
fetchers...,
)
anteOptions := ante.HandlerOptions{
AccountKeeper: app.accountKeeper,
BankKeeper: app.bankKeeper,
EvmKeeper: app.evmKeeper,
IBCKeeper: app.ibcKeeper,
FeeMarketKeeper: app.feeMarketKeeper,
SignModeHandler: encodingConfig.TxConfig.SignModeHandler(),
SigGasConsumer: evmante.DefaultSigVerificationGasConsumer,
MaxTxGasWanted: options.EVMMaxGasWanted,
AddressFetchers: fetchers,
}
antehandler, err := ante.NewAnteHandler(anteOptions)
if err != nil {
panic(fmt.Sprintf("failed to create antehandler: %s", err))
}
@ -725,6 +825,15 @@ func NewApp(
app.SetBeginBlocker(app.BeginBlocker)
app.SetEndBlocker(app.EndBlocker)
app.upgradeKeeper.SetUpgradeHandler(
upgradeName,
func(ctx sdk.Context, _ upgradetypes.Plan, previousModuleVersions module.VersionMap) (module.VersionMap, error) {
return app.mm.RunMigrations(ctx, app.configurator, previousModuleVersions)
},
)
// TODO if we need modules added/removed, add upgrade store loader
// load store
if !options.SkipLoadLatest {
if err := app.LoadLatestVersion(); err != nil {
@ -755,8 +864,6 @@ func (app *App) InitChainer(ctx sdk.Context, req abci.RequestInitChain) abci.Res
panic(err)
}
app.upgradeKeeper.SetModuleVersionMap(ctx, app.mm.GetVersionMap())
return app.mm.InitGenesis(ctx, app.appCodec, genesisState)
}
@ -791,7 +898,7 @@ func (app *App) RegisterAPIRoutes(apiSvr *api.Server, apiConfig config.APIConfig
// Register legacy REST routes
rpc.RegisterRoutes(clientCtx, apiSvr.Router)
authrest.RegisterTxRoutes(clientCtx, apiSvr.Router)
evmrest.RegisterTxRoutes(clientCtx, apiSvr.Router)
ModuleBasics.RegisterRESTRoutes(clientCtx, apiSvr.Router)
RegisterLegacyTxRoutes(clientCtx, apiSvr.Router)

View File

@ -16,27 +16,28 @@ import (
)
func TestNewApp(t *testing.T) {
SetSDKConfig()
NewApp(
log.NewTMLogger(log.NewSyncWriter(os.Stdout)),
db.NewMemDB(),
DefaultNodeHome,
nil,
MakeEncodingConfig(),
Options{},
DefaultOptions,
)
}
func TestExport(t *testing.T) {
SetSDKConfig()
db := db.NewMemDB()
app := NewApp(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, DefaultNodeHome, nil, MakeEncodingConfig(), Options{})
app := NewApp(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, DefaultNodeHome, nil, MakeEncodingConfig(), DefaultOptions)
stateBytes, err := json.Marshal(NewDefaultGenesisState())
require.NoError(t, err)
initRequest := abci.RequestInitChain{
Time: time.Date(1998, 1, 1, 0, 0, 0, 0, time.UTC),
ChainId: "kava-test",
ChainId: "kavatest_1-1",
InitialHeight: 1,
ConsensusParams: tmtypes.TM2PB.ConsensusParams(tmtypes.DefaultConsensusParams()),
Validators: nil,
@ -69,7 +70,7 @@ func unmarshalJSONKeys(jsonBytes []byte) ([]string, error) {
}
keys := make([]string, 0, len(jsonMap))
for k, _ := range jsonMap {
for k := range jsonMap {
keys = append(keys, k)
}
sort.Strings(keys)

View File

@ -1,7 +1,7 @@
package app
import (
"github.com/cosmos/cosmos-sdk/std"
enccodec "github.com/tharsis/ethermint/encoding/codec"
"github.com/kava-labs/kava/app/params"
)
@ -9,8 +9,8 @@ import (
// MakeEncodingConfig creates an EncodingConfig and registers the app's types on it.
func MakeEncodingConfig() params.EncodingConfig {
encodingConfig := params.MakeEncodingConfig()
std.RegisterLegacyAminoCodec(encodingConfig.Amino)
std.RegisterInterfaces(encodingConfig.InterfaceRegistry)
enccodec.RegisterLegacyAminoCodec(encodingConfig.Amino)
enccodec.RegisterInterfaces(encodingConfig.InterfaceRegistry)
ModuleBasics.RegisterLegacyAminoCodec(encodingConfig.Amino)
ModuleBasics.RegisterInterfaces(encodingConfig.InterfaceRegistry)
return encodingConfig

View File

@ -22,17 +22,19 @@ import (
paramskeeper "github.com/cosmos/cosmos-sdk/x/params/keeper"
slashingkeeper "github.com/cosmos/cosmos-sdk/x/slashing/keeper"
stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
hardkeeper "github.com/kava-labs/kava/x/hard/keeper"
"github.com/stretchr/testify/require"
abci "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/libs/log"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
tmdb "github.com/tendermint/tm-db"
evmkeeper "github.com/tharsis/ethermint/x/evm/keeper"
auctionkeeper "github.com/kava-labs/kava/x/auction/keeper"
bep3keeper "github.com/kava-labs/kava/x/bep3/keeper"
cdpkeeper "github.com/kava-labs/kava/x/cdp/keeper"
committeekeeper "github.com/kava-labs/kava/x/committee/keeper"
evmutilkeeper "github.com/kava-labs/kava/x/evmutil/keeper"
hardkeeper "github.com/kava-labs/kava/x/hard/keeper"
incentivekeeper "github.com/kava-labs/kava/x/incentive/keeper"
issuancekeeper "github.com/kava-labs/kava/x/issuance/keeper"
kavadistkeeper "github.com/kava-labs/kava/x/kavadist/keeper"
@ -42,8 +44,8 @@ import (
)
var (
emptyTime time.Time
emptyChainID string
emptyTime time.Time
testChainID = "kavatest_1-1"
)
// TestApp is a simple wrapper around an App. It exposes internal keepers for use in integration tests.
@ -75,7 +77,7 @@ func NewTestAppFromSealed() TestApp {
encCfg := MakeEncodingConfig()
app := NewApp(log.NewNopLogger(), db, DefaultNodeHome, nil, encCfg, Options{})
app := NewApp(log.NewNopLogger(), db, DefaultNodeHome, nil, encCfg, DefaultOptions)
return TestApp{App: *app}
}
@ -100,6 +102,8 @@ func (tApp TestApp) GetCDPKeeper() cdpkeeper.Keeper { return tApp.cd
func (tApp TestApp) GetHardKeeper() hardkeeper.Keeper { return tApp.hardKeeper }
func (tApp TestApp) GetCommitteeKeeper() committeekeeper.Keeper { return tApp.committeeKeeper }
func (tApp TestApp) GetIncentiveKeeper() incentivekeeper.Keeper { return tApp.incentiveKeeper }
func (tApp TestApp) GetEvmutilKeeper() evmutilkeeper.Keeper { return tApp.evmutilKeeper }
func (tApp TestApp) GetEvmKeeper() *evmkeeper.Keeper { return tApp.evmKeeper }
func (tApp TestApp) GetSavingsKeeper() savingskeeper.Keeper { return tApp.savingsKeeper }
// LegacyAmino returns the app's amino codec.
@ -114,12 +118,12 @@ func (app *App) AppCodec() codec.Codec {
// InitializeFromGenesisStates calls InitChain on the app using the default genesis state, overwitten with any passed in genesis states
func (tApp TestApp) InitializeFromGenesisStates(genesisStates ...GenesisState) TestApp {
return tApp.InitializeFromGenesisStatesWithTimeAndChainID(emptyTime, emptyChainID, genesisStates...)
return tApp.InitializeFromGenesisStatesWithTimeAndChainID(emptyTime, testChainID, genesisStates...)
}
// InitializeFromGenesisStatesWithTime calls InitChain on the app using the default genesis state, overwitten with any passed in genesis states and genesis Time
func (tApp TestApp) InitializeFromGenesisStatesWithTime(genTime time.Time, genesisStates ...GenesisState) TestApp {
return tApp.InitializeFromGenesisStatesWithTimeAndChainID(genTime, emptyChainID, genesisStates...)
return tApp.InitializeFromGenesisStatesWithTimeAndChainID(genTime, testChainID, genesisStates...)
}
// InitializeFromGenesisStatesWithTimeAndChainID calls InitChain on the app using the default genesis state, overwitten with any passed in genesis states and genesis Time
@ -143,10 +147,21 @@ func (tApp TestApp) InitializeFromGenesisStatesWithTimeAndChainID(genTime time.T
Validators: []abci.ValidatorUpdate{},
AppStateBytes: stateBytes,
ChainId: chainID,
// Set consensus params, which is needed by x/feemarket
ConsensusParams: &abci.ConsensusParams{
Block: &abci.BlockParams{
MaxBytes: 200000,
MaxGas: 20000000,
},
},
},
)
tApp.Commit()
tApp.BeginBlock(abci.RequestBeginBlock{Header: tmproto.Header{Height: tApp.LastBlockHeight() + 1, Time: genTime}})
tApp.BeginBlock(abci.RequestBeginBlock{
Header: tmproto.Header{
Height: tApp.LastBlockHeight() + 1, Time: genTime, ChainID: chainID,
},
})
return tApp
}

108
client/keys.go Normal file
View File

@ -0,0 +1,108 @@
package client
import (
"bufio"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/client/keys"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/spf13/cobra"
"github.com/tendermint/tendermint/libs/cli"
"github.com/cosmos/cosmos-sdk/crypto/keyring"
ethclient "github.com/tharsis/ethermint/client"
clientkeys "github.com/tharsis/ethermint/client/keys"
"github.com/tharsis/ethermint/crypto/hd"
)
var (
ethFlag = "eth"
)
// KeyCommands registers a sub-tree of commands to interact with
// local private key storage.
func KeyCommands(defaultNodeHome string) *cobra.Command {
cmd := &cobra.Command{
Use: "keys",
Short: "Manage your application's keys",
Long: `Keyring management commands. These keys may be in any format supported by the
Tendermint crypto library and can be used by light-clients, full nodes, or any other application
that needs to sign with a private key.
The keyring supports the following backends:
os Uses the operating system's default credentials store.
file Uses encrypted file-based keystore within the app's configuration directory.
This keyring will request a password each time it is accessed, which may occur
multiple times in a single command resulting in repeated password prompts.
kwallet Uses KDE Wallet Manager as a credentials management application.
pass Uses the pass command line utility to store and retrieve keys.
test Stores keys insecurely to disk. It does not prompt for a password to be unlocked
and it should be use only for testing purposes.
kwallet and pass backends depend on external tools. Refer to their respective documentation for more
information:
KWallet https://github.com/KDE/kwallet
pass https://www.passwordstore.org/
The pass backend requires GnuPG: https://gnupg.org/
`,
}
// support adding Ethereum supported keys
addCmd := keys.AddKeyCommand()
addCmd.Flags().Bool(ethFlag, false, "use default evm coin-type (60) and key signing algorithm (\"eth_secp256k1\")")
addCmd.RunE = runAddCmd
cmd.AddCommand(
keys.MnemonicKeyCommand(),
addCmd,
keys.ExportKeyCommand(),
keys.ImportKeyCommand(),
keys.ListKeysCmd(),
keys.ShowKeysCmd(),
flags.LineBreak,
keys.DeleteKeyCommand(),
keys.ParseKeyStringCommand(),
keys.MigrateCommand(),
flags.LineBreak,
ethclient.UnsafeExportEthKeyCommand(),
ethclient.UnsafeImportKeyCommand(),
)
cmd.PersistentFlags().String(flags.FlagHome, defaultNodeHome, "The application home directory")
cmd.PersistentFlags().String(flags.FlagKeyringDir, "", "The client Keyring directory; if omitted, the default 'home' directory will be used")
cmd.PersistentFlags().String(flags.FlagKeyringBackend, keyring.BackendOS, "Select keyring's backend (os|file|test)")
cmd.PersistentFlags().String(cli.OutputFlag, "text", "Output format (text|json)")
return cmd
}
func runAddCmd(cmd *cobra.Command, args []string) error {
buf := bufio.NewReader(cmd.InOrStdin())
clientCtx := client.GetClientContextFromCmd(cmd)
var (
kr keyring.Keyring
err error
)
dryRun, _ := cmd.Flags().GetBool(flags.FlagDryRun)
if dryRun {
kr, err = keyring.New(sdk.KeyringServiceName(), keyring.BackendMemory, clientCtx.KeyringDir, buf, hd.EthSecp256k1Option())
clientCtx = clientCtx.WithKeyring(kr)
}
eth, _ := cmd.Flags().GetBool(ethFlag)
if eth {
cmd.Print("eth flag specified: using coin-type 60 and signing algorithm eth_secp256k1\n")
cmd.Flags().Set(flags.FlagKeyAlgorithm, string(hd.EthSecp256k1Type))
cmd.Flags().Set("coin-type", "60")
}
if err != nil {
return err
}
return clientkeys.RunAddCmd(clientCtx, cmd, args, buf)
}

View File

@ -18,6 +18,7 @@ import (
"github.com/spf13/cobra"
"github.com/tendermint/tendermint/libs/log"
db "github.com/tendermint/tm-db"
ethermintflags "github.com/tharsis/ethermint/server/flags"
"github.com/kava-labs/kava/app"
"github.com/kava-labs/kava/app/params"
@ -85,6 +86,8 @@ func (ac appCreator) newApp(
InvariantCheckPeriod: cast.ToUint(appOpts.Get(server.FlagInvCheckPeriod)),
MempoolEnableAuth: mempoolEnableAuth,
MempoolAuthAddresses: mempoolAuthAddresses,
EVMTrace: cast.ToString(appOpts.Get(ethermintflags.EVMTracer)),
EVMMaxGasWanted: cast.ToUint64(appOpts.Get(ethermintflags.EVMMaxTxGasWanted)),
},
baseapp.SetPruning(pruningOpts),
baseapp.SetMinGasPrices(cast.ToString(appOpts.Get(server.FlagMinGasPrices))),
@ -116,15 +119,19 @@ func (ac appCreator) appExport(
return servertypes.ExportedApp{}, errors.New("application home not set")
}
options := app.DefaultOptions
options.SkipLoadLatest = true
options.InvariantCheckPeriod = cast.ToUint(appOpts.Get(server.FlagInvCheckPeriod))
var tempApp *app.App
if height != -1 {
tempApp = app.NewApp(logger, db, homePath, traceStore, ac.encodingConfig, app.Options{SkipLoadLatest: true, InvariantCheckPeriod: cast.ToUint(appOpts.Get(server.FlagInvCheckPeriod))})
tempApp = app.NewApp(logger, db, homePath, traceStore, ac.encodingConfig, options)
if err := tempApp.LoadHeight(height); err != nil {
return servertypes.ExportedApp{}, err
}
} else {
tempApp = app.NewApp(logger, db, homePath, traceStore, ac.encodingConfig, app.Options{SkipLoadLatest: false, InvariantCheckPeriod: cast.ToUint(appOpts.Get(server.FlagInvCheckPeriod))})
tempApp = app.NewApp(logger, db, homePath, traceStore, ac.encodingConfig, options)
}
return tempApp.ExportAppStateAndValidators(forZeroHeight, jailAllowedAddrs)
}

207
cmd/kava/cmd/genaccounts.go Normal file
View File

@ -0,0 +1,207 @@
// Sourced from https://github.com/tharsis/ethermint/blob/main/cmd/ethermintd/genaccounts.go
package cmd
import (
"bufio"
"encoding/json"
"errors"
"fmt"
"github.com/ethereum/go-ethereum/common"
"github.com/spf13/cobra"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/crypto/keyring"
"github.com/cosmos/cosmos-sdk/server"
sdk "github.com/cosmos/cosmos-sdk/types"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
authvesting "github.com/cosmos/cosmos-sdk/x/auth/vesting/types"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
"github.com/cosmos/cosmos-sdk/x/genutil"
genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types"
"github.com/tharsis/ethermint/crypto/hd"
ethermint "github.com/tharsis/ethermint/types"
evmtypes "github.com/tharsis/ethermint/x/evm/types"
)
const (
flagVestingStart = "vesting-start-time"
flagVestingEnd = "vesting-end-time"
flagVestingAmt = "vesting-amount"
)
// AddGenesisAccountCmd returns add-genesis-account cobra Command.
func AddGenesisAccountCmd(defaultNodeHome string) *cobra.Command {
cmd := &cobra.Command{
Use: "add-genesis-account [address_or_key_name] [coin][,[coin]]",
Short: "Add a genesis account to genesis.json",
Long: `Add a genesis account to genesis.json. The provided account must specify
the account address or key name and a list of initial coins. If a key name is given,
the address will be looked up in the local Keybase. The list of initial tokens must
contain valid denominations. Accounts may optionally be supplied with vesting parameters.
`,
Args: cobra.ExactArgs(2),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx := client.GetClientContextFromCmd(cmd)
serverCtx := server.GetServerContextFromCmd(cmd)
config := serverCtx.Config
config.SetRoot(clientCtx.HomeDir)
var kr keyring.Keyring
addr, err := sdk.AccAddressFromBech32(args[0])
if err != nil {
inBuf := bufio.NewReader(cmd.InOrStdin())
keyringBackend, _ := cmd.Flags().GetString(flags.FlagKeyringBackend)
if keyringBackend != "" && clientCtx.Keyring == nil {
var err error
kr, err = keyring.New(
sdk.KeyringServiceName(),
keyringBackend,
clientCtx.HomeDir,
inBuf,
hd.EthSecp256k1Option(),
)
if err != nil {
return err
}
} else {
kr = clientCtx.Keyring
}
info, err := kr.Key(args[0])
if err != nil {
return fmt.Errorf("failed to get address from Keyring: %w", err)
}
addr = info.GetAddress()
}
coins, err := sdk.ParseCoinsNormalized(args[1])
if err != nil {
return fmt.Errorf("failed to parse coins: %w", err)
}
vestingStart, err := cmd.Flags().GetInt64(flagVestingStart)
if err != nil {
return err
}
vestingEnd, err := cmd.Flags().GetInt64(flagVestingEnd)
if err != nil {
return err
}
vestingAmtStr, err := cmd.Flags().GetString(flagVestingAmt)
if err != nil {
return err
}
vestingAmt, err := sdk.ParseCoinsNormalized(vestingAmtStr)
if err != nil {
return fmt.Errorf("failed to parse vesting amount: %w", err)
}
// create concrete account type based on input parameters
var genAccount authtypes.GenesisAccount
balances := banktypes.Balance{Address: addr.String(), Coins: coins.Sort()}
baseAccount := authtypes.NewBaseAccount(addr, nil, 0, 0)
if !vestingAmt.IsZero() {
baseVestingAccount := authvesting.NewBaseVestingAccount(baseAccount, vestingAmt.Sort(), vestingEnd)
if (balances.Coins.IsZero() && !baseVestingAccount.OriginalVesting.IsZero()) ||
baseVestingAccount.OriginalVesting.IsAnyGT(balances.Coins) {
return errors.New("vesting amount cannot be greater than total amount")
}
switch {
case vestingStart != 0 && vestingEnd != 0:
genAccount = authvesting.NewContinuousVestingAccountRaw(baseVestingAccount, vestingStart)
case vestingEnd != 0:
genAccount = authvesting.NewDelayedVestingAccountRaw(baseVestingAccount)
default:
return errors.New("invalid vesting parameters; must supply start and end time or end time")
}
} else {
genAccount = &ethermint.EthAccount{
BaseAccount: baseAccount,
CodeHash: common.BytesToHash(evmtypes.EmptyCodeHash).Hex(),
}
}
if err := genAccount.Validate(); err != nil {
return fmt.Errorf("failed to validate new genesis account: %w", err)
}
genFile := config.GenesisFile()
appState, genDoc, err := genutiltypes.GenesisStateFromGenFile(genFile)
if err != nil {
return fmt.Errorf("failed to unmarshal genesis state: %w", err)
}
authGenState := authtypes.GetGenesisStateFromAppState(clientCtx.Codec, appState)
accs, err := authtypes.UnpackAccounts(authGenState.Accounts)
if err != nil {
return fmt.Errorf("failed to get accounts from any: %w", err)
}
if accs.Contains(addr) {
return fmt.Errorf("cannot add account at existing address %s", addr)
}
// Add the new account to the set of genesis accounts and sanitize the
// accounts afterwards.
accs = append(accs, genAccount)
accs = authtypes.SanitizeGenesisAccounts(accs)
genAccs, err := authtypes.PackAccounts(accs)
if err != nil {
return fmt.Errorf("failed to convert accounts into any's: %w", err)
}
authGenState.Accounts = genAccs
authGenStateBz, err := clientCtx.Codec.MarshalJSON(&authGenState)
if err != nil {
return fmt.Errorf("failed to marshal auth genesis state: %w", err)
}
appState[authtypes.ModuleName] = authGenStateBz
bankGenState := banktypes.GetGenesisStateFromAppState(clientCtx.Codec, appState)
bankGenState.Balances = append(bankGenState.Balances, balances)
bankGenState.Balances = banktypes.SanitizeGenesisBalances(bankGenState.Balances)
bankGenState.Supply = bankGenState.Supply.Add(balances.Coins...)
bankGenStateBz, err := clientCtx.Codec.MarshalJSON(bankGenState)
if err != nil {
return fmt.Errorf("failed to marshal bank genesis state: %w", err)
}
appState[banktypes.ModuleName] = bankGenStateBz
appStateJSON, err := json.Marshal(appState)
if err != nil {
return fmt.Errorf("failed to marshal application genesis state: %w", err)
}
genDoc.AppState = appStateJSON
return genutil.ExportGenesisFile(genDoc, genFile)
},
}
cmd.Flags().String(flags.FlagHome, defaultNodeHome, "The application home directory")
cmd.Flags().String(flags.FlagKeyringBackend, flags.DefaultKeyringBackend, "Select keyring's backend (os|file|kwallet|pass|test)")
cmd.Flags().String(flagVestingAmt, "", "amount of coins for vesting accounts")
cmd.Flags().Int64(flagVestingStart, 0, "schedule start time (unix epoch) for vesting accounts")
cmd.Flags().Int64(flagVestingEnd, 0, "schedule end time (unix epoch) for vesting accounts")
flags.AddQueryFlagsToCmd(cmd)
return cmd
}

View File

@ -6,17 +6,21 @@ import (
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/config"
"github.com/cosmos/cosmos-sdk/client/debug"
"github.com/cosmos/cosmos-sdk/client/keys"
"github.com/cosmos/cosmos-sdk/server"
simdcmd "github.com/cosmos/cosmos-sdk/simapp/simd/cmd"
"github.com/cosmos/cosmos-sdk/x/auth/types"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
genutilcli "github.com/cosmos/cosmos-sdk/x/genutil/client/cli"
"github.com/spf13/cobra"
tmcli "github.com/tendermint/tendermint/libs/cli"
ethermintclient "github.com/tharsis/ethermint/client"
"github.com/tharsis/ethermint/crypto/hd"
ethermintserver "github.com/tharsis/ethermint/server"
servercfg "github.com/tharsis/ethermint/server/config"
"github.com/kava-labs/kava/app"
"github.com/kava-labs/kava/app/params"
kavaclient "github.com/kava-labs/kava/client"
)
// NewRootCmd creates a new root command for the kava blockchain.
@ -33,6 +37,7 @@ func NewRootCmd() *cobra.Command {
WithInput(os.Stdin).
WithAccountRetriever(types.AccountRetriever{}).
WithHomeDir(app.DefaultNodeHome).
WithKeyringOptions(hd.EthSecp256k1Option()).
WithViper("") // TODO this sets the env prefix
rootCmd := &cobra.Command{
@ -56,7 +61,9 @@ func NewRootCmd() *cobra.Command {
return err
}
return server.InterceptConfigsPreRunHandler(cmd, "", nil)
customAppTemplate, customAppConfig := servercfg.AppConfig("ukava")
return server.InterceptConfigsPreRunHandler(cmd, customAppTemplate, customAppConfig)
},
}
@ -68,14 +75,16 @@ func NewRootCmd() *cobra.Command {
// addSubCmds registers all the sub commands used by kava.
func addSubCmds(rootCmd *cobra.Command, encodingConfig params.EncodingConfig, defaultNodeHome string) {
rootCmd.AddCommand(
genutilcli.InitCmd(app.ModuleBasics, defaultNodeHome),
ethermintclient.ValidateChainID(
genutilcli.InitCmd(app.ModuleBasics, defaultNodeHome),
),
genutilcli.CollectGenTxsCmd(banktypes.GenesisBalancesIterator{}, defaultNodeHome),
// migrate.MigrateGenesisCmd(),
// migrate.AssertInvariantsCmd(encodingConfig),
genutilcli.GenTxCmd(app.ModuleBasics, encodingConfig.TxConfig, banktypes.GenesisBalancesIterator{}, defaultNodeHome),
genutilcli.ValidateGenesisCmd(app.ModuleBasics),
simdcmd.AddGenesisAccountCmd(defaultNodeHome), // TODO use kava version with vesting accounts
tmcli.NewCompletionCmd(rootCmd, true), // TODO add other shells, drop tmcli dependency, unhide?
AddGenesisAccountCmd(defaultNodeHome),
tmcli.NewCompletionCmd(rootCmd, true), // TODO add other shells, drop tmcli dependency, unhide?
// testnetCmd(app.ModuleBasics, banktypes.GenesisBalancesIterator{}), // TODO add
debug.Cmd(),
config.Cmd(),
@ -84,13 +93,15 @@ func addSubCmds(rootCmd *cobra.Command, encodingConfig params.EncodingConfig, de
ac := appCreator{
encodingConfig: encodingConfig,
}
server.AddCommands(rootCmd, defaultNodeHome, ac.newApp, ac.appExport, ac.addStartCmdFlags)
// ethermintserver adds additional flags to start the JSON-RPC server for evm support
ethermintserver.AddCommands(rootCmd, defaultNodeHome, ac.newApp, ac.appExport, ac.addStartCmdFlags)
// add keybase, auxiliary RPC, query, and tx child commands
rootCmd.AddCommand(
StatusCommand(),
newQueryCmd(),
newTxCmd(),
keys.Commands(defaultNodeHome),
kavaclient.KeyCommands(app.DefaultNodeHome),
)
}

View File

@ -1,13 +1,15 @@
#! /bin/bash
set -e
validatorMnemonic="equip town gesture square tomorrow volume nephew minute witness beef rich gadget actress egg sing secret pole winter alarm law today check violin uncover"
# kava1ffv7nhd3z6sych2qpqkk03ec6hzkmufy0r2s4c
# kava1ak4pa9z2aty94ze2cs06wsdnkg9hsvfkp40r02
faucetMnemonic="crash sort dwarf disease change advice attract clump avoid mobile clump right junior axis book fresh mask tube front require until face effort vault"
# kava1adkm6svtzjsxxvg7g6rshg6kj9qwej8gwqadqd
# kava123fxg0l602etulhhcdm0vt7l57qya5wjcrwhzz
evmFaucetMnemonic="hundred flash cattle inquiry gorilla quick enact lazy galaxy apple bitter liberty print sun hurdle oak town cash because round chalk marriage response success"
# 0x3C854F92F726A7897C8B23F55B2D6E2C482EF3E0
# kava18jz5lyhhy6ncjlyty064kttw93yzaulq7rlptu
DATA=~/.kava
# remove any old state and config
@ -16,12 +18,18 @@ rm -rf $DATA
BINARY=kava
# Create new data directory, overwriting any that alread existed
chainID="kava-localnet"
chainID="kavalocalnet_8888-1"
$BINARY init validator --chain-id $chainID
# hacky enable of rest api
sed -in-place='' 's/enable = false/enable = true/g' $DATA/config/app.toml
# Set evm tracer to json
sed -in-place='' 's/tracer = ""/tracer = "json"/g' $DATA/config/app.toml
# Set client chain id
sed -in-place='' 's/chain-id = ""/chain-id = "kavalocalnet_8888-1"/g' $DATA/config/client.toml
# avoid having to use password for keys
$BINARY config keyring-backend test
@ -35,6 +43,10 @@ faucetKeyName="faucet"
printf "$faucetMnemonic\n" | $BINARY keys add $faucetKeyName --recover
$BINARY add-genesis-account $faucetKeyName 1000000000ukava,100000000000bnb
evmFaucetKeyName="evm-faucet"
printf "$evmFaucetMnemonic\n" | $BINARY keys add $evmFaucetKeyName --eth --recover
$BINARY add-genesis-account $evmFaucetKeyName 1000000000ukava
# Create a delegation tx for the validator and add to genesis
$BINARY gentx $validatorKeyName 1000000000ukava --keyring-backend test --chain-id $chainID
$BINARY collect-gentxs
@ -42,5 +54,8 @@ $BINARY collect-gentxs
# Replace stake with ukava
sed -in-place='' 's/stake/ukava/g' $DATA/config/genesis.json
# Replace the default evm denom of aphoton with ukava
sed -in-place='' 's/aphoton/akava/g' $DATA/config/genesis.json
# Zero out the total supply so it gets recalculated during InitGenesis
jq '.app_state.bank.supply = []' $DATA/config/genesis.json|sponge $DATA/config/genesis.json
jq '.app_state.bank.supply = []' $DATA/config/genesis.json|sponge $DATA/config/genesis.json

View File

@ -178,6 +178,10 @@
- [Msg](#kava.committee.v1beta1.Msg)
- [kava/evmutil/v1beta1/genesis.proto](#kava/evmutil/v1beta1/genesis.proto)
- [Account](#kava.evmutil.v1beta1.Account)
- [GenesisState](#kava.evmutil.v1beta1.GenesisState)
- [kava/hard/v1beta1/hard.proto](#kava/hard/v1beta1/hard.proto)
- [Borrow](#kava.hard.v1beta1.Borrow)
- [BorrowInterestFactor](#kava.hard.v1beta1.BorrowInterestFactor)
@ -2703,6 +2707,53 @@ Msg defines the committee Msg service
<a name="kava/evmutil/v1beta1/genesis.proto"></a>
<p align="right"><a href="#top">Top</a></p>
## kava/evmutil/v1beta1/genesis.proto
<a name="kava.evmutil.v1beta1.Account"></a>
### Account
BalanceAccount defines an account in the evmutil module.
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| `address` | [bytes](#bytes) | | |
| `balance` | [string](#string) | | balance indicates the amount of akava owned by the address. |
<a name="kava.evmutil.v1beta1.GenesisState"></a>
### GenesisState
GenesisState defines the evmutil module's genesis state.
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| `accounts` | [Account](#kava.evmutil.v1beta1.Account) | repeated | |
<!-- end messages -->
<!-- end enums -->
<!-- end HasExtensions -->
<!-- end services -->
<a name="kava/hard/v1beta1/hard.proto"></a>
<p align="right"><a href="#top">Top</a></p>

89
go.mod
View File

@ -4,21 +4,23 @@ go 1.17
require (
github.com/cosmos/cosmos-proto v0.0.0-20211020182451-c7ca7198c2f8
github.com/cosmos/cosmos-sdk v0.44.5
github.com/cosmos/ibc-go v1.2.5
github.com/cosmos/cosmos-sdk v0.45.1
github.com/cosmos/ibc-go/v3 v3.0.0
github.com/ethereum/go-ethereum v1.10.16
github.com/gogo/protobuf v1.3.3
github.com/golang/mock v1.6.0
github.com/golang/protobuf v1.5.2
github.com/gorilla/mux v1.8.0
github.com/grpc-ecosystem/grpc-gateway v1.16.0
github.com/spf13/cast v1.4.1
github.com/spf13/cobra v1.2.1
github.com/stretchr/testify v1.7.0
github.com/spf13/cobra v1.4.0
github.com/stretchr/testify v1.7.1
github.com/tendermint/tendermint v0.34.15
github.com/tendermint/tm-db v0.6.6
google.golang.org/genproto v0.0.0-20210917145530-b395a37504d4
google.golang.org/grpc v1.42.0
google.golang.org/protobuf v1.27.1
github.com/tendermint/tm-db v0.6.7
github.com/tharsis/ethermint v0.12.2
google.golang.org/genproto v0.0.0-20220211171837-173942840c17
google.golang.org/grpc v1.44.0
google.golang.org/protobuf v1.28.0
sigs.k8s.io/yaml v1.2.0
)
@ -26,51 +28,66 @@ require (
filippo.io/edwards25519 v1.0.0-beta.2 // indirect
github.com/99designs/keyring v1.1.6 // indirect
github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d // indirect
github.com/DataDog/zstd v1.4.5 // indirect
github.com/DataDog/zstd v1.4.8 // indirect
github.com/StackExchange/wmi v1.2.1 // indirect
github.com/VictoriaMetrics/fastcache v1.6.0 // indirect
github.com/Workiva/go-datastructures v1.0.53 // indirect
github.com/armon/go-metrics v0.3.9 // indirect
github.com/armon/go-metrics v0.3.10 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/bgentry/speakeasy v0.1.0 // indirect
github.com/btcsuite/btcd v0.22.0-beta // indirect
github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce // indirect
github.com/cenkalti/backoff/v4 v4.1.1 // indirect
github.com/cespare/xxhash v1.1.0 // indirect
github.com/cespare/xxhash/v2 v2.1.2 // indirect
github.com/coinbase/rosetta-sdk-go v0.6.10 // indirect
github.com/confio/ics23/go v0.6.6 // indirect
github.com/coinbase/rosetta-sdk-go v0.7.0 // indirect
github.com/confio/ics23/go v0.7.0 // indirect
github.com/cosmos/btcutil v1.0.4 // indirect
github.com/cosmos/go-bip39 v1.0.0 // indirect
github.com/cosmos/gorocksdb v1.2.0 // indirect
github.com/cosmos/iavl v0.17.3 // indirect
github.com/cosmos/ledger-cosmos-go v0.11.1 // indirect
github.com/cosmos/ledger-go v0.9.2 // indirect
github.com/danieljoos/wincred v1.0.2 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/deckarep/golang-set v1.8.0 // indirect
github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect
github.com/dgraph-io/badger/v2 v2.2007.2 // indirect
github.com/dgraph-io/ristretto v0.0.3 // indirect
github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect
github.com/dustin/go-humanize v1.0.0 // indirect
github.com/dvsekhvalnov/jose2go v0.0.0-20200901110807-248326c1351b // indirect
github.com/edsrzf/mmap-go v1.0.0 // indirect
github.com/felixge/httpsnoop v1.0.1 // indirect
github.com/fsnotify/fsnotify v1.5.1 // indirect
github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff // indirect
github.com/go-kit/kit v0.12.0 // indirect
github.com/go-kit/log v0.2.0 // indirect
github.com/go-logfmt/logfmt v0.5.1 // indirect
github.com/go-ole/go-ole v1.2.5 // indirect
github.com/go-stack/stack v1.8.0 // indirect
github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect
github.com/gogo/gateway v1.1.0 // indirect
github.com/golang/snappy v0.0.3 // indirect
github.com/google/btree v1.0.0 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/google/btree v1.0.1 // indirect
github.com/google/orderedcode v0.0.1 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/gorilla/handlers v1.5.1 // indirect
github.com/gorilla/websocket v1.4.2 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect
github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect
github.com/gtank/merlin v0.1.1 // indirect
github.com/gtank/ristretto255 v0.1.2 // indirect
github.com/hashicorp/go-immutable-radix v1.3.1 // indirect
github.com/hashicorp/golang-lru v0.5.4 // indirect
github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/hdevalence/ed25519consensus v0.0.0-20210204194344-59a8610d2b87 // indirect
github.com/improbable-eng/grpc-web v0.14.1 // indirect
github.com/holiman/bloomfilter/v2 v2.0.3 // indirect
github.com/holiman/uint256 v1.2.0 // indirect
github.com/huin/goupnp v1.0.2 // indirect
github.com/improbable-eng/grpc-web v0.15.0 // indirect
github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/jackpal/go-nat-pmp v1.0.2 // indirect
github.com/jmhodges/levigo v1.0.0 // indirect
github.com/keybase/go-keychain v0.0.0-20190712205309-48d3d31d256d // indirect
github.com/klauspost/compress v1.13.6 // indirect
@ -78,11 +95,13 @@ require (
github.com/libp2p/go-buffer-pool v0.0.2 // indirect
github.com/magiconair/properties v1.8.5 // indirect
github.com/mattn/go-isatty v0.0.14 // indirect
github.com/mattn/go-runewidth v0.0.9 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643 // indirect
github.com/minio/highwayhash v1.0.2 // indirect
github.com/mitchellh/mapstructure v1.4.2 // indirect
github.com/mitchellh/mapstructure v1.4.3 // indirect
github.com/mtibben/percent v0.2.1 // indirect
github.com/olekukonko/tablewriter v0.0.5 // indirect
github.com/pelletier/go-toml v1.9.4 // indirect
github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 // indirect
github.com/pkg/errors v0.9.1 // indirect
@ -91,31 +110,40 @@ require (
github.com/prometheus/client_model v0.2.0 // indirect
github.com/prometheus/common v0.30.0 // indirect
github.com/prometheus/procfs v0.7.3 // indirect
github.com/prometheus/tsdb v0.7.1 // indirect
github.com/rakyll/statik v0.1.7 // indirect
github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0 // indirect
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect
github.com/regen-network/cosmos-proto v0.3.1 // indirect
github.com/rs/cors v1.8.0 // indirect
github.com/rs/zerolog v1.23.0 // indirect
github.com/rjeczalik/notify v0.9.1 // indirect
github.com/rs/cors v1.8.2 // indirect
github.com/rs/zerolog v1.26.0 // indirect
github.com/sasha-s/go-deadlock v0.2.1-0.20190427202633-1595213edefa // indirect
github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect
github.com/spf13/afero v1.6.0 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/spf13/viper v1.9.0 // indirect
github.com/spf13/viper v1.10.1 // indirect
github.com/status-im/keycard-go v0.0.0-20200402102358-957c09536969 // indirect
github.com/stretchr/objx v0.2.0 // indirect
github.com/subosito/gotenv v1.2.0 // indirect
github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca // indirect
github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c // indirect
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect
github.com/tendermint/btcd v0.1.1 // indirect
github.com/tendermint/crypto v0.0.0-20191022145703-50d29ede1e15 // indirect
github.com/tendermint/go-amino v0.16.0 // indirect
github.com/tklauser/go-sysconf v0.3.7 // indirect
github.com/tklauser/numcpus v0.2.3 // indirect
github.com/tyler-smith/go-bip39 v1.1.0 // indirect
github.com/zondax/hid v0.9.0 // indirect
go.etcd.io/bbolt v1.3.6 // indirect
golang.org/x/crypto v0.0.0-20210915214749-c084706c2272 // indirect
golang.org/x/net v0.0.0-20211005001312-d4b1ae081e3b // indirect
golang.org/x/sys v0.0.0-20211004093028-2c5d950f24ef // indirect
golang.org/x/crypto v0.0.0-20220213190939-1e6e3497d506 // indirect
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 // indirect
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
golang.org/x/sys v0.0.0-20211210111614-af8b64212486 // indirect
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 // indirect
golang.org/x/text v0.3.7 // indirect
gopkg.in/ini.v1 v1.63.2 // indirect
gopkg.in/ini.v1 v1.66.2 // indirect
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200619000410-60c24ae608a6 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
nhooyr.io/websocket v1.8.6 // indirect
@ -124,16 +152,13 @@ require (
replace (
// Use the cosmos keyring code
github.com/99designs/keyring => github.com/cosmos/keyring v1.1.7-0.20210622111912-ef00f8ac3d76
// Use patched version based on v0.44.5 - note: not state compatiable
github.com/cosmos/cosmos-sdk => github.com/kava-labs/cosmos-sdk v0.44.5-kava.1
// See https://github.com/cosmos/cosmos-sdk/pull/10401, https://github.com/cosmos/cosmos-sdk/commit/0592ba6158cd0bf49d894be1cef4faeec59e8320
github.com/gin-gonic/gin => github.com/gin-gonic/gin v1.7.0
// Use the cosmos modified protobufs
github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1
// Fix rocksdb for high traffic situations
github.com/tecbot/gorocksdb => github.com/cosmos/gorocksdb v1.2.0
// Make sure that only one version of tendermint is imported
github.com/tendermint/tendermint => github.com/tendermint/tendermint v0.34.15
github.com/tharsis/ethermint => github.com/Kava-Labs/ethermint v0.10.0-alpha1.0.20220330230123-b3b3bf2103bf
// Make sure that we use grpc compatible with cosmos
google.golang.org/grpc => google.golang.org/grpc v1.33.2
)

277
go.sum
View File

@ -1,11 +1,13 @@
bazil.org/fuse v0.0.0-20200407214033-5883e5a4b512/go.mod h1:FbcW6z/2VytnFDhZfumh8Ss8zxHE6qpMP5sHTRe0EaM=
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.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=
@ -29,6 +31,7 @@ cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvf
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
cloud.google.com/go/bigtable v1.2.0/go.mod h1:JcVAOl45lrTmQfLj7T6TxyMzIN/3FGGcFm+2xVAli2o=
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk=
@ -42,6 +45,7 @@ cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0Zeo
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=
collectd.org v0.3.0/go.mod h1:A/8DzQBkF6abtvrT2j/AU/4tiBgJWYyh0y/oB/4MlWE=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
filippo.io/edwards25519 v1.0.0-beta.2 h1:/BZRNzm8N4K4eWfK28dL4yescorxtO7YG1yun8fy+pI=
filippo.io/edwards25519 v1.0.0-beta.2/go.mod h1:X+pm78QAUPtFLi1z9PYIlS/bdDnvbCOGKtZ+ACWEf7o=
@ -65,12 +69,16 @@ github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbi
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d h1:nalkkPQcITbvhmL4+C4cKA87NW0tfm3Kl9VXRoPywFg=
github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d/go.mod h1:URdX5+vg25ts3aCh8H5IFZybJYKWhJHYMTnf+ULtoC4=
github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
github.com/DataDog/zstd v1.4.1/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo=
github.com/DataDog/zstd v1.4.5 h1:EndNeuB0l9syBZhut0wns3gV1hL8zX8LIu6ZiVHWLIQ=
github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo=
github.com/DataDog/zstd v1.4.8 h1:Rpmta4xZ/MgZnriKNd24iZMhGpP5dvUcs/uqfBapKZY=
github.com/DataDog/zstd v1.4.8/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw=
github.com/HdrHistogram/hdrhistogram-go v1.1.0/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo=
github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo=
github.com/Kava-Labs/ethermint v0.10.0-alpha1.0.20220330230123-b3b3bf2103bf h1:T+Lwa1xXfHvjuxyJE7zl+GMFxlRlkhcCsgV+JiefcJ4=
github.com/Kava-Labs/ethermint v0.10.0-alpha1.0.20220330230123-b3b3bf2103bf/go.mod h1:5gZCBCY9A0T7h8dO76u+Pm5Gz2liv/urEQ7jPpqWtWQ=
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
github.com/Microsoft/go-winio v0.5.0 h1:Elr9Wn+sGKPlkaBvwu4mTrxtmOp3F3yV9qhaHbXGjwU=
github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
@ -81,7 +89,11 @@ github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAE
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
github.com/StackExchange/wmi v1.2.1 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDOSA=
github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9SBzvHz7e8=
github.com/VictoriaMetrics/fastcache v1.5.7/go.mod h1:ptDBkNMQI4RtmVo8VS/XwRY6RoTu1dAWCbrk+6WsEM8=
github.com/VictoriaMetrics/fastcache v1.6.0 h1:C/3Oi3EiBCqufydp1neRZkqcwmEiuRT9c3fqvvgKm5o=
github.com/VictoriaMetrics/fastcache v1.6.0/go.mod h1:0qHz5QP0GMX4pfmMA/zt5RgfNuXJrTP0zS7DqpHGGTw=
github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE=
github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
github.com/Workiva/go-datastructures v1.0.53 h1:J6Y/52yX10Xc5JjXmGtWoSSxs3mZnGSaq37xZZh7Yig=
@ -97,16 +109,20 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy
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 h1:eMwmnE/GDgah4HI848JfFxHt+iPb26b4zyfspmqY0/8=
github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM=
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
github.com/apache/arrow/go/arrow v0.0.0-20191024131854-af6fa24be0db/go.mod h1:VTxUBvSJ3s3eHAg65PNgrsn5BtqCRPdmyXh6rAfdxN0=
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
github.com/aristanetworks/goarista v0.0.0-20170210015632-ea17b1a17847/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ=
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
github.com/armon/go-metrics v0.3.9 h1:O2sNqxBdvq8Eq5xmzljcYzAORli6RWCvEym4cJf9m18=
github.com/armon/go-metrics v0.3.9/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc=
github.com/armon/go-metrics v0.3.10 h1:FR+drcQStOe+32sYyJYyZ7FIdgoGGBnwLl+flodp8Uo=
github.com/armon/go-metrics v0.3.10/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc=
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A=
@ -115,8 +131,17 @@ github.com/aws/aws-sdk-go v1.25.48/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpi
github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
github.com/aws/aws-sdk-go v1.40.45/go.mod h1:585smgzpB/KqRA+K3y/NL/oYRqQvpNJYvLm+LY1U59Q=
github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g=
github.com/aws/aws-sdk-go-v2 v1.2.0/go.mod h1:zEQs02YRBw1DjK0PoJv3ygDYOFTre1ejlJWl8FwAuQo=
github.com/aws/aws-sdk-go-v2 v1.9.1/go.mod h1:cK/D0BBs0b/oWPIcX/Z/obahJK1TT7IPVjy53i/mX/4=
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/cloudwatch v1.8.1/go.mod h1:CM+19rL1+4dFWnOQKwDc7H1KwXTz+h61oUSHyhV0b3o=
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/aws/smithy-go v1.8.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E=
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
@ -127,6 +152,8 @@ github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQ
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA=
github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM=
github.com/bmizerany/pat v0.0.0-20170815010413-6226ea591a40/go.mod h1:8rLXio+WjiTceGBHIoTvn60HIbs7Hm7bcHjyrSqYB9c=
github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps=
github.com/btcsuite/btcd v0.0.0-20171128150713-2e60448ffcc6/go.mod h1:Dmm/EzmjnCiweXmzRIAiUWCInVmPgjkzgv5k4tVyXiQ=
github.com/btcsuite/btcd v0.0.0-20190115013929-ed77733ec07d/go.mod h1:d3C0AkH6BRcvO8T0UEPu53cnw4IbV63x1bEjildYhO0=
github.com/btcsuite/btcd v0.0.0-20190315201642-aa6e0f35703c/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8=
@ -148,12 +175,15 @@ github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku
github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc=
github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY=
github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs=
github.com/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/casbin/casbin/v2 v2.37.0/go.mod h1:vByNa/Fchek0KZUgG5wEsl7iFsiviAYKRtgrQfcJqHg=
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 h1:G2HAfAmvm/GcKan2oOQpBXOd2tT2G57ZnZGWa1PxPBQ=
github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/cp v0.1.0 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk=
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=
@ -170,13 +200,17 @@ github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp
github.com/clbanning/mxj v1.8.4/go.mod h1:BVjHeAH+rl9rs6f+QIpeRl0tfu10SXn1pUSa5PVGJng=
github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE=
github.com/cloudflare/cloudflare-go v0.10.2-0.20190916151808-a80f83b9add9/go.mod h1:1MxXX1Ux4x6mqPmjkUgTP1CdXIBXKX7T+Jk9Gxrmx+U=
github.com/cloudflare/cloudflare-go v0.14.0/go.mod h1:EnwdgGMaFOruiPZRFSgn+TsQ3hQ7C/YWzIGLeu5c304=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
github.com/coinbase/rosetta-sdk-go v0.6.10 h1:rgHD/nHjxLh0lMEdfGDqpTtlvtSBwULqrrZ2qPdNaCM=
github.com/coinbase/rosetta-sdk-go v0.6.10/go.mod h1:J/JFMsfcePrjJZkwQFLh+hJErkAmdm9Iyy3D5Y0LfXo=
github.com/confio/ics23/go v0.6.6 h1:pkOy18YxxJ/r0XFDCnrl4Bjv6h4LkBSpLS6F38mrKL8=
github.com/coinbase/rosetta-sdk-go v0.7.0 h1:lmTO/JEpCvZgpbkOITL95rA80CPKb5CtMzLaqF2mCNg=
github.com/coinbase/rosetta-sdk-go v0.7.0/go.mod h1:7nD3oBPIiHqhRprqvMgPoGxe/nyq3yftRmpsy29coWE=
github.com/confio/ics23/go v0.6.6/go.mod h1:E45NqnlpxGnpfTWL/xauN7MRwEE28T4Dd4uraToOaKg=
github.com/confio/ics23/go v0.7.0 h1:00d2kukk7sPoHWL4zZBZwzxnpA2pec1NPdwbSokJ5w8=
github.com/confio/ics23/go v0.7.0/go.mod h1:E45NqnlpxGnpfTWL/xauN7MRwEE28T4Dd4uraToOaKg=
github.com/consensys/bavard v0.1.8-0.20210406032232-f3452dc9b572/go.mod h1:Bpd0/3mZuaj6Sj+PqrmIquiOKy397AKGThQPaGzNXAQ=
github.com/consensys/gnark-crypto v0.4.1-0.20210426202927-39ac3d4b3f1f/go.mod h1:815PAHg3wvysy0SyIqanF8gZ0Y1wjk/hrDHD/iT88+Q=
github.com/containerd/console v1.0.2/go.mod h1:ytZPjGgY2oeTkAONYafi2kSj0aYggsf8acV1PGKCbzQ=
github.com/containerd/continuity v0.2.0 h1:j/9Wnn+hrEWjLvHuIxUU1YI5JjEjVlT2AA68cse9rwY=
github.com/containerd/continuity v0.2.0/go.mod h1:wCYX+dRqZdImhGucXOqTQn05AhX6EUDaGEMUzTFFpLg=
@ -194,6 +228,8 @@ github.com/cosmos/btcutil v1.0.4 h1:n7C2ngKXo7UC9gNyMNLbzqz7Asuf+7Qv4gnX/rOdQ44=
github.com/cosmos/btcutil v1.0.4/go.mod h1:Ffqc8Hn6TJUdDgHBwIZLtrLQC1KdJ9jGJl/TvgUaxbU=
github.com/cosmos/cosmos-proto v0.0.0-20211020182451-c7ca7198c2f8 h1:NYYAiqXciz9JMAibyzVV5SbaaoBOEtu25Wuh9rX2YdA=
github.com/cosmos/cosmos-proto v0.0.0-20211020182451-c7ca7198c2f8/go.mod h1:g2Q3cd94kOBVRAv7ahdtO27yUc4cpNuHGnI40qanl1k=
github.com/cosmos/cosmos-sdk v0.45.1 h1:PY79YxPea5qlRLExRnzg8/rT1Scc8GGgRs22p7DX99Q=
github.com/cosmos/cosmos-sdk v0.45.1/go.mod h1:XXS/asyCqWNWkx2rW6pSuen+EVcpAFxq6khrhnZgHaQ=
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=
@ -201,8 +237,8 @@ github.com/cosmos/gorocksdb v1.2.0 h1:d0l3jJG8M4hBouIZq0mDUHZ+zjOx044J3nGRskwTb4
github.com/cosmos/gorocksdb v1.2.0/go.mod h1:aaKvKItm514hKfNJpUJXnnOWeBnk2GL4+Qw9NHizILw=
github.com/cosmos/iavl v0.17.3 h1:s2N819a2olOmiauVa0WAhoIJq9EhSXE9HDBAoR9k+8Y=
github.com/cosmos/iavl v0.17.3/go.mod h1:prJoErZFABYZGDHka1R6Oay4z9PrNeFFiMKHDAMOi4w=
github.com/cosmos/ibc-go v1.2.5 h1:BiA48yKEDUcabBRkmp7qqSX41ZrgXTSNCtdjDURbLwE=
github.com/cosmos/ibc-go v1.2.5/go.mod h1:wkGkkX8Ou6yXgE8lO2xP9NOwo+Tl5x1dJaTTE6jBDpg=
github.com/cosmos/ibc-go/v3 v3.0.0 h1:XUNplHVS51Q2gMnTFsFsH9QJ7flsovMamnltKbEgPQ4=
github.com/cosmos/ibc-go/v3 v3.0.0/go.mod h1:Mb+1NXiPOLd+CPFlOC6BKeAUaxXlhuWenMmRiUiSmwY=
github.com/cosmos/keyring v1.1.7-0.20210622111912-ef00f8ac3d76 h1:DdzS1m6o/pCqeZ8VOAit/gyATedRgjvkVI+UCrLpyuU=
github.com/cosmos/keyring v1.1.7-0.20210622111912-ef00f8ac3d76/go.mod h1:0mkLWIoZuQ7uBoospo5Q9zIpqq6rYCPJDSUdeCJvPM8=
github.com/cosmos/ledger-cosmos-go v0.11.1 h1:9JIYsGnXP613pb2vPjFeMMjBI5lEDsEaF6oYorTy6J4=
@ -212,17 +248,24 @@ github.com/cosmos/ledger-go v0.9.2/go.mod h1:oZJ2hHAZROdlHiwTg4t7kP+GKIIkBT+o6c9
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.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4=
github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4=
github.com/danieljoos/wincred v1.0.2 h1:zf4bhty2iLuwgjgpraD2E9UbvO+fe54XXGJbOwe23fU=
github.com/danieljoos/wincred v1.0.2/go.mod h1:SnuYRW9lp1oJrZX/dXJqr0cPK5gYXqx3EJbmjhLdK9U=
github.com/dave/jennifer v1.2.0/go.mod h1:fIb+770HOpJ2fmN9EPPKOqm1vMGhB+TwXKMZhrIygKg=
github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/deckarep/golang-set v0.0.0-20180603214616-504e848d77ea/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ=
github.com/deckarep/golang-set v1.8.0 h1:sk9/l/KqpunDwP7pSjUg0keiOOLEnOBHzykLrsPppp4=
github.com/deckarep/golang-set v1.8.0/go.mod h1:5nI87KwE7wgsBU1F4GKAw2Qod7p5kyS383rP6+o6qqo=
github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218=
github.com/deepmap/oapi-codegen v1.6.0/go.mod h1:ryDa9AgbELGeB+YEXE1dR53yAjHwFvE9iAUlWl9Al3M=
github.com/deepmap/oapi-codegen v1.8.2/go.mod h1:YLgSKSDv/bZQB7N4ws6luhozi3cEdRktEqrX88CvjIw=
github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f h1:U5y3Y5UE0w7amNe7Z5G/twsBW0KEalRQXZzf8ufSh9I=
github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f/go.mod h1:xH/i4TFMt8koVQZ6WFms69WAsDWr2XsYL3Hkl7jkoLE=
github.com/dgraph-io/badger/v2 v2.2007.2 h1:EjjK0KqwaFMlPin1ajhP943VPENHJdEz1KLIegjaI3k=
@ -231,17 +274,21 @@ github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de/go.mod h1:KP
github.com/dgraph-io/ristretto v0.0.3 h1:jh22xisGBjrEVnRZ1DVTpBVQm0Xndu8sMl0CWDzSIBI=
github.com/dgraph-io/ristretto v0.0.3/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-bitstream v0.0.0-20180413035011-3522498ce2c8/go.mod h1:VMaSuZ+SZcx/wljOQKvp5srsbCiKDEb6K2wC4+PiBmQ=
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WAFKLNi6ZS0675eEUC9y3AlwSbQu1Y=
github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/dlclark/regexp2 v1.2.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
github.com/docker/docker v1.4.2-0.20180625184442-8e610b2b55bf/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw=
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/dop251/goja v0.0.0-20200721192441-a695b0cdd498/go.mod h1:Mw6PkjjMXWbTj+nnj4s3QPXq1jaT0s5pC0iFD4+BOAA=
github.com/dop251/goja v0.0.0-20211011172007-d99e4b8cbf48/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk=
github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y=
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
@ -251,19 +298,21 @@ github.com/dvyukov/go-fuzz v0.0.0-20200318091601-be3528f3a813/go.mod h1:11Gm+ccJ
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
github.com/eclipse/paho.mqtt.golang v1.2.0/go.mod h1:H9keYFcgq3Qr5OUJm/JZI/i6U7joQ8SYLhZwfeOo6Ts=
github.com/edsrzf/mmap-go v0.0.0-20160512033002-935e0e8a636c/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
github.com/edsrzf/mmap-go v1.0.0 h1:CEBF7HpRnUCSJgGUb5h1Gm7e3VkmVDrR8lvWVLtrOFw=
github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/ethereum/go-ethereum v1.9.25/go.mod h1:vMkFiYLHI4tgPw4k2j4MHKoovchFE8plZ0M9VMk4/oM=
github.com/ethereum/go-ethereum v1.10.16 h1:3oPrumn0bCW/idjcxMn5YYVCdK7VzJYIvwGZUGLEaoc=
github.com/ethereum/go-ethereum v1.10.16/go.mod h1:Anj6cxczl+AHy63o4X9O8yWNHuN5wMpfb8MAnHkWn7Y=
github.com/facebookgo/ensure v0.0.0-20160127193407-b4ab57deab51/go.mod h1:Yg+htXGokKKdzcwhuNDwVvN+uBxDGXJ7G/VN1d8fa64=
github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c h1:8ISkoahWXwZR41ois5lSJBSVw4D0OV19Ht/JSTzvSv0=
github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c/go.mod h1:Yg+htXGokKKdzcwhuNDwVvN+uBxDGXJ7G/VN1d8fa64=
github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 h1:JWuenKqqX8nojtoVVWjGfOF9635RETekkoH6Cc9SX0A=
github.com/facebookgo/stack v0.0.0-20160209184415-751773369052/go.mod h1:UbMTZqLaRiH3MsBH8va0n7s1pQYcu3uTb8G4tygF4Zg=
github.com/facebookgo/subset v0.0.0-20150612182917-8dac2c3c4870/go.mod h1:5tD+neXqOorC30/tWg0LCSkrqj/AR6gu8yY8/fpw1q0=
github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4 h1:7HZCaLC5+BZpmbhCOZJ293Lz68O7PYrF2EzeiFMwCLk=
github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4/go.mod h1:5tD+neXqOorC30/tWg0LCSkrqj/AR6gu8yY8/fpw1q0=
github.com/fatih/color v1.3.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
@ -272,6 +321,8 @@ github.com/fatih/color v1.12.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGE
github.com/felixge/httpsnoop v1.0.1 h1:lvB5Jl89CsZtGIWuTcDM1E/vkVs49/Ml7JJe07l8SPQ=
github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/fjl/memsize v0.0.0-20180418122429-ca190fb6ffbc/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0=
github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 h1:FtmdgXiUlNeRsoNMFlKLDt+S+6hbjVMEW6RGQ7aUf7c=
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/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g=
@ -283,12 +334,18 @@ github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMo
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/fsnotify/fsnotify v1.5.1 h1:mZcQUHVQUQWoPXXtuf9yuEXKudkV2sx1E06UadKWpgI=
github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU=
github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff h1:tY80oXqGNY4FhTFhk+o9oFHGINQ/+vhlm8HFzi6znCI=
github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww=
github.com/getkin/kin-openapi v0.53.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4=
github.com/getkin/kin-openapi v0.61.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-gonic/gin v1.7.0 h1:jGB9xAJQ12AIGNB4HguylppmDK1Am9ppF7XnGXXJuoU=
github.com/gin-gonic/gin v1.7.0/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY=
github.com/glycerine/go-unsnap-stream v0.0.0-20180323001048-9f0cb55181dd/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE=
github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24=
github.com/go-chi/chi/v5 v5.0.0/go.mod h1:BBug9lr0cqtdAhsu6R4AAdvufI0/XBzAQSsUqJpoZOs=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
@ -306,6 +363,10 @@ github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG
github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA=
github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8=
github.com/go-ole/go-ole v1.2.5 h1:t4MGB5xEDZvXI+0rMjjsfBsD7yAgp/s9ZDkL1JndXwY=
github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
@ -314,7 +375,10 @@ github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+
github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE=
github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4=
github.com/go-sourcemap/sourcemap v2.1.2+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg=
github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg=
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
github.com/go-zookeeper/zk v1.0.2/go.mod h1:nOB03cncLtlp4t+UAkGSV+9beXP/akpekBwL+UX1Qcw=
@ -327,10 +391,12 @@ github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/E
github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+Hoeu/iUR3ruzNvZ+yQfO03a0=
github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/gofrs/uuid v3.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
github.com/gogo/gateway v1.1.0 h1:u0SuhL9+Il+UbjM9VIE3ntfRujKbvVpFvNB4HbjeVQ0=
github.com/gogo/gateway v1.1.0/go.mod h1:S7rR8FRQyG3QFESeSv4l2WnsyzlCLG0CzBbUUo/mbic=
github.com/golang-jwt/jwt/v4 v4.0.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/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
@ -369,11 +435,15 @@ github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiu
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.3-0.20201103224600-674baa8c7fc3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.3 h1:fHPg5GQYlCeLIPB9BZqMVR5nR9A+IM5zcgeTdjMYmLA=
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 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4=
github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA=
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=
@ -415,6 +485,9 @@ github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm4
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.1.5/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/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=
@ -431,10 +504,12 @@ github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/gorilla/websocket v1.4.1-0.20190629185528-ae1634f6a989/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
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/gotestyourself/gotestyourself v2.2.0+incompatible/go.mod h1:zZKM6oeNM8k+FRljX1mnzVYeS8wiGgQyvST1/GafPbY=
github.com/graph-gophers/graphql-go v0.0.0-20191115155744-f33e81362277/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc=
github.com/graph-gophers/graphql-go v1.3.0/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
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=
@ -460,6 +535,8 @@ github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyN
github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-bexpr v0.1.10 h1:9kuI5PFotCboP3dkDYFr/wi0gg0QVbSNz5oFRpxn4uE=
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/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
@ -483,8 +560,9 @@ github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09
github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc=
github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d h1:dg1dEPuWpEqDnvIw251EVy4zlP8gWbsGj4BsUKCRpYs=
github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
@ -496,22 +574,42 @@ github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/J
github.com/hashicorp/serf v0.9.5/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKENpqIUyk=
github.com/hdevalence/ed25519consensus v0.0.0-20210204194344-59a8610d2b87 h1:uUjLpLt6bVvZ72SQc/B4dXcPBw4Vgd7soowdRl52qEM=
github.com/hdevalence/ed25519consensus v0.0.0-20210204194344-59a8610d2b87/go.mod h1:XGsKKeXxeRr95aEOgipvluMPlgjr7dGlk9ZTWOjcUcg=
github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao=
github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA=
github.com/holiman/uint256 v1.1.1/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw=
github.com/holiman/uint256 v1.2.0 h1:gpSYcPLWGv4sG43I2mVLiDZCNDh/EpGjSk8tmtxitHM=
github.com/holiman/uint256 v1.2.0/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg=
github.com/hudl/fargo v1.4.0/go.mod h1:9Ai6uvFy5fQNq6VPKtg+Ceq1+eTY4nKUlR2JElEOcDo=
github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc=
github.com/huin/goupnp v1.0.2 h1:RfGLP+h3mvisuWEyybxNq5Eft3NWhHLPeUN72kpKZoI=
github.com/huin/goupnp v1.0.2/go.mod h1:0dxJBVBHqTMjIUMkESDTNgOOx/Mw5wYIfyFmdzSamkM=
github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/improbable-eng/grpc-web v0.14.1 h1:NrN4PY71A6tAz2sKDvC5JCauENWp0ykG8Oq1H3cpFvw=
github.com/improbable-eng/grpc-web v0.14.1/go.mod h1:zEjGHa8DAlkoOXmswrNvhUGEYQA9UI7DhrGeHR1DMGU=
github.com/improbable-eng/grpc-web v0.15.0 h1:BN+7z6uNXZ1tQGcNAuaU1YjsLTApzkjt2tzCixLaUPQ=
github.com/improbable-eng/grpc-web v0.15.0/go.mod h1:1sy9HKV4Jt9aEs9JSnkWlRJPuPtwNr0l57L4f878wP8=
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/influxdata/flux v0.65.1/go.mod h1:J754/zds0vvpfwuq7Gc2wRdVwEodfpCFM7mYlOw2LqY=
github.com/influxdata/influxdb v1.2.3-0.20180221223340-01288bdb0883/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY=
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/influxdb1-client v0.0.0-20200827194710-b269163b24ab/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
github.com/influxdata/influxql v1.1.1-0.20200828144457-65d3ef77d385/go.mod h1:gHp9y86a/pxhjJ+zMjNXiQAA197Xk9wLxaz+fGG+kWk=
github.com/influxdata/line-protocol v0.0.0-20180522152040-32c6aa80de5e/go.mod h1:4kt73NQhadE3daL3WhR5EJ/J2ocX0PZzwxQ0gXJ7oFE=
github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo=
github.com/influxdata/line-protocol v0.0.0-20210311194329-9aa0e372d097/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo=
github.com/influxdata/promql/v2 v2.12.0/go.mod h1:fxOPu+DY0bqCTCECchSRtWfc+0X19ybifQhZoQNF5D8=
github.com/influxdata/roaring v0.4.13-0.20180809181101-fc520f41fab6/go.mod h1:bSgUQ7q5ZLSO+bKBGqJiCBGAl+9DxyW63zLTujjUlOE=
github.com/influxdata/tdigest v0.0.0-20181121200506-bf2b5ad3c0a9/go.mod h1:Js0mqiSBE6Ffsg94weZZ2c+v/ciT8QRHFOap7EKDrR0=
github.com/influxdata/usage-client v0.0.0-20160829180054-6d3895376368/go.mod h1:Wbbw6tYNvwa5dlB6304Sd+82Z3f7PmVZHVKU637d4po=
github.com/jackpal/go-nat-pmp v1.0.2-0.20160603034137-1fa385a6f458/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus=
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=
@ -535,38 +633,48 @@ github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnr
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
github.com/jsternberg/zap-logfmt v1.0.0/go.mod h1:uvPs/4X51zdkcm5jXl5SYoN+4RK21K8mysFmDaM/h+o=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/julienschmidt/httprouter v1.1.1-0.20170430222011-975b5c4c7c21/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes=
github.com/jwilder/encoding v0.0.0-20170811194829-b4e1701a28ef/go.mod h1:Ct9fl0F6iIOGgxJ5npU/IUOhOhqlVrGjyIZc8/MagT0=
github.com/karalabe/usb v0.0.0-20190919080040-51dc0efba356/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU=
github.com/kava-labs/cosmos-sdk v0.44.5-kava.1 h1:w3em9kQ5T34KqErLQuFE9KLEA+jts6c/Lkea4jaVCWk=
github.com/kava-labs/cosmos-sdk v0.44.5-kava.1/go.mod h1:maUA6m2TBxOJZkbwl0eRtEBgTX37kcaiOWU5t1HEGaY=
github.com/karalabe/usb v0.0.2/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU=
github.com/keybase/go-keychain v0.0.0-20190712205309-48d3d31d256d h1:Z+RDyXzjKE0i2sTjZ/b1uxiGtPhFy34Ou/Tk0qwN0kM=
github.com/keybase/go-keychain v0.0.0-20190712205309-48d3d31d256d/go.mod h1:JJNrCn9otv/2QP4D7SMJBgaleKpOf66PnW6F5WGNRIc=
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.13.4/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg=
github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc=
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
github.com/klauspost/cpuid v0.0.0-20170728055534-ae7887de9fa5/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
github.com/klauspost/crc32 v0.0.0-20161016154125-cb6bfca970f6/go.mod h1:+ZoRqAPRLkC4NPOvfYeR5KNOrY6TD+/sAC3HXPZgDYg=
github.com/klauspost/pgzip v1.0.2-0.20170402124221-0bf5dcad4ada/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
github.com/labstack/echo/v4 v4.2.1/go.mod h1:AA49e0DZ8kk5jTOOCKNuPR6oTnBS0dYiM4FW1e6jwpg=
github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k=
github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8=
github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/lib/pq v1.10.3/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/lib/pq v1.10.4 h1:SO9z7FRPzA03QhHKJrH5BXA6HU1rS4V2nIVrrNC1iYk=
@ -579,17 +687,24 @@ github.com/lucasjones/reggen v0.0.0-20180717132126-cdb49ff09d77/go.mod h1:5ELEyG
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/magiconair/properties v1.8.5 h1:b6kJs+EmPFMYGkow9GiUyCyOvIwYetYJ3fSaWak/Gls=
github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/matryer/moq v0.0.0-20190312154309-6cfb0558e1bd/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.0/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
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.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40=
github.com/mattn/go-ieproxy v0.0.0-20190610004146-91bb50d98149/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc=
github.com/mattn/go-ieproxy v0.0.0-20190702010315-6dee0af9227d/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc=
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.5-0.20180830101745-3fb116b82035/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
@ -598,11 +713,16 @@ github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27k
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 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/mattn/go-tty v0.0.0-20180907095812-13ff1204f104/go.mod h1:XPvLUNfbS4fJH25nqRHfWLMa1ONC8Amw+mIA639KxkE=
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso=
github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4=
github.com/miguelmota/go-ethereum-hdwallet v0.1.1 h1:zdXGlHao7idpCBjEGTXThVAtMKs+IxAgivZ75xqkWK0=
github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643 h1:hLDRPB66XQT/8+wG9WsDpiCvZf1yKO7sz7scAjSlBa0=
github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643/go.mod h1:43+3pMjjKimDBf5Kr4ZFNGbLql1zKkbImw+fZbw3geM=
github.com/minio/highwayhash v1.0.1/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY=
@ -619,8 +739,11 @@ github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:F
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/mitchellh/mapstructure v1.4.2 h1:6h7AQ0yhTcIsmFmnAwQls75jp2Gzs4iB8W7pjMO+rqo=
github.com/mitchellh/mapstructure v1.4.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/mitchellh/mapstructure v1.4.3 h1:OVowDSCllw/YjdLkam3/sm7wEtOy59d8ndGgCcyj8cs=
github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/mitchellh/pointerstructure v1.2.0 h1:O+i9nHnXS3l/9Wu7r4NrEdwA2VFTicjUEN1uBnDo34A=
github.com/mitchellh/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4=
github.com/moby/sys/mountinfo v0.4.1/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A=
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=
@ -630,6 +753,7 @@ github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3Rllmb
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/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/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
@ -652,7 +776,6 @@ github.com/nats-io/nkeys v0.2.0/go.mod h1:XdZpAbhgyyODYqjTawOnIOI7VlbKSarI9Gfy1t
github.com/nats-io/nkeys v0.3.0/go.mod h1:gvUNGjVcM2IPr5rCsRsC6Wb3Hr2CQAm08dsxtV6A5y4=
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
github.com/neilotoole/errgroup v0.1.5/go.mod h1:Q2nLGf+594h0CLBs/Mbg6qOr7GtqDK7C2S41udRnToE=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/nishanths/predeclared v0.0.0-20200524104333-86fad755b4d3/go.mod h1:nt3d53pc1VYcphSCIaYAJtnPYnr3Zyn8fMq2wvPGPso=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
@ -664,13 +787,15 @@ github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn
github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
github.com/olekukonko/tablewriter v0.0.2-0.20190409134802-7e037d187b0c/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
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.2/go.mod h1:CObGmKUOKaSC0RjmoAK7tKyn4Azo5P2IWuoMnvwxz1E=
github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc=
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
github.com/onsi/ginkgo v1.16.5 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=
@ -680,15 +805,16 @@ github.com/onsi/gomega v1.13.0/go.mod h1:lRk9szgn8TxENtWd0Tp4c3wjlRfMTMH27I+3Je4
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.0.1 h1:JMemWkRwHx4Zj+fVxWoMCFm/8sYGGrUVojFA6h/TRcI=
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
github.com/opencontainers/runc v1.0.2 h1:opHZMaswlyxz1OuGpBE53Dwe4/xF7EZTY0A2L/FpCOg=
github.com/opencontainers/image-spec v1.0.2 h1:9yCKha/T5XdGtO0q9Q9a6T5NUCsTn/DrBg0D7ufOcFM=
github.com/opencontainers/runc v1.0.2/go.mod h1:aTaHFFwQXuA71CiyxOdFFIorAoemI04suvGRQFzWTD0=
github.com/opencontainers/runc v1.0.3 h1:1hbqejyQWCJBvtKAfdO0b1FmaEf2z/bxnjqbARass5k=
github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/opencontainers/selinux v1.8.2/go.mod h1:MUIHuUEvKB1wtJjQdOyYRgOnLD2xAPP8dBsCoU0KuF8=
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/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc=
github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA=
@ -708,6 +834,7 @@ github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIw
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY=
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/paulbellamy/ratecounter v0.2.0/go.mod h1:Hfx1hDpSGoqxkVVpBi/IlYD7kChlfo5C6hzIHwPqfFE=
github.com/pborman/uuid v0.0.0-20170112150404-1b00554d8222/go.mod h1:VyrYX9gd7irzKovcSS6BIIEwPRkP2Wm2m9ufcdFSJ34=
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
@ -716,9 +843,11 @@ github.com/pelletier/go-toml v1.9.4 h1:tjENF6MfZAg8e4ZmZTeWaWiT2vXtsoO6+iuOjFhEC
github.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac=
github.com/performancecopilot/speed/v4 v4.0.0/go.mod h1:qxrSyuDGrTOWfV+uKRFhfxw6h/4HXRGUiZiufxo49BM=
github.com/peterh/liner v1.0.1-0.20180619022028-8c1271fcf47f/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc=
github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7/go.mod h1:CRroGNssyjTd/qIG2FyxByd2S8JEAZXBl4qUrZf8GS0=
github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 h1:q2e307iGHPdTGp0hoxKjt1H5pDo6utceo3dQVK3I5XQ=
github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o=
github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU=
github.com/philhofer/fwd v1.1.1/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU=
github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc=
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
@ -728,6 +857,7 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA=
github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=
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=
@ -752,6 +882,7 @@ github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7q
github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.4.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=
@ -771,30 +902,38 @@ github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1
github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU=
github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
github.com/prometheus/tsdb v0.6.2-0.20190402121629-4f204dcbc150/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/prometheus/tsdb v0.7.1 h1:YZcsG11NqnK4czYLrWd9mpEuAJIHVQLwdrleYfszMAA=
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-20200313005456-10cdbea86bc0 h1:MkV+77GLUNo5oJ0jf870itWm3D0Sjh7+Za9gazKc5LQ=
github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM=
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
github.com/regen-network/cosmos-proto v0.3.1 h1:rV7iM4SSFAagvy8RiyhiACbWEGotmqzywPxOvwMdxcg=
github.com/regen-network/cosmos-proto v0.3.1/go.mod h1:jO0sVX6a1B36nmE8C9xBFXpNwWejXC7QqCOnH3O0+YM=
github.com/regen-network/protobuf v1.3.3-alpha.regen.1 h1:OHEc+q5iIAXpqiqFKeLpu5NwTIkVXUs48vFMwzqpqY4=
github.com/regen-network/protobuf v1.3.3-alpha.regen.1/go.mod h1:2DjTFR1HhMQhiWC5sZ4OhQ3+NtdbZ6oBDKQwq5Ou+FI=
github.com/retailnext/hllpp v1.0.1-0.20180308014038-101a6d2f8b52/go.mod h1:RDpi1RftBQPUCDRw6SmxeaREsAaRKnOclghuzp/WRzc=
github.com/rjeczalik/notify v0.9.1 h1:CLCKso/QK1snAlnhNR/CNvNiFU2saUtjV0bx3EwNeCE=
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/rs/cors v0.0.0-20160617231935-a62a804a8a00/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
github.com/rs/cors v1.8.0 h1:P2KMzcFwrPoSjkF1WLRPsp3UMLyql8L4v9hQpVeK5so=
github.com/rs/cors v1.8.0/go.mod h1:EBwu+T5AvHOcXwvZIkQFjUN6s8Czyqw12GL/Y0tUyRM=
github.com/rs/cors v1.8.2 h1:KCooALfAYGs415Cwu5ABvv9n9509fSiG5SQJn/AQo4U=
github.com/rs/cors v1.8.2/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU=
github.com/rs/xhandler v0.0.0-20160618193221-ed27b6fd6521/go.mod h1:RvLn4FgxWubrpZHtQLnOf6EwhN2hEMusxZOhcW9H3UQ=
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
github.com/rs/zerolog v1.23.0 h1:UskrK+saS9P9Y789yNNulYKdARjPZuS35B8gJF2x60g=
github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/rs/zerolog v1.23.0/go.mod h1:6c7hFfxPOy7TacJc4Fcdi24/J0NKYGzjG8FWRI916Qo=
github.com/rs/zerolog v1.26.0 h1:ORM4ibhEZeTeQlCojCK2kPz1ogAY4bGs4tD+SaAdGaE=
github.com/rs/zerolog v1.26.0/go.mod h1:yBiM87lvSqX8h0Ww4sdzNSkVYZ8dL2xjZJG1lAuGZEo=
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/sagikazarmark/crypt v0.1.0/go.mod h1:B/mN0msZuINBtQ1zZLEQcegFJJf9vnYIR88KRMEuODE=
github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E=
@ -803,7 +942,12 @@ github.com/sasha-s/go-deadlock v0.2.1-0.20190427202633-1595213edefa/go.mod h1:F7
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo=
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 v2.20.5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
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=
@ -829,8 +973,9 @@ github.com/spf13/cast v1.4.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkU
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.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
github.com/spf13/cobra v1.2.1 h1:+KmjbUw1hriSNMF55oPrkZcb27aECyrj8V2ytv7kWDw=
github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk=
github.com/spf13/cobra v1.4.0 h1:y+wJpx64xcgO1V+RcnwW0LEHxTKRi2ZDPSBjWnrg88Q=
github.com/spf13/cobra v1.4.0/go.mod h1:Wo4iy3BUC+X2Fybo0PDqwJIv3dNRiZLHQymsfxlB84g=
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=
@ -841,9 +986,12 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns=
github.com/spf13/viper v1.9.0 h1:yR6EXjTp0y0cLN8OZg1CRZmOBdI88UcGkhgyJhu6nZk=
github.com/spf13/viper v1.9.0/go.mod h1:+i6ajR7OX2XaiBkrcZJFK21htRk7eDeLg7+O6bhUPP4=
github.com/spf13/viper v1.10.1 h1:nuJZuYpG7gTj/XqiUwg8bA0cp1+M2mC3J4g5luUYBKk=
github.com/spf13/viper v1.10.1/go.mod h1:IGlFPqhNAPKRxohIzWpI5QEy4kuI7tcl5WvR+8qy1rU=
github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4/go.mod h1:RZLeN1LMWmRsyYjvAu+I6Dm9QmlDaIIt+Y+4Kd7Tp+Q=
github.com/status-im/keycard-go v0.0.0-20200402102358-957c09536969 h1:Oo2KZNP70KE0+IUJSidPj/BFS/RXNHmKIJOdckzml2E=
github.com/status-im/keycard-go v0.0.0-20200402102358-957c09536969/go.mod h1:RZLeN1LMWmRsyYjvAu+I6Dm9QmlDaIIt+Y+4Kd7Tp+Q=
github.com/steakknife/bloomfilter v0.0.0-20180922174646-6819c0d2a570/go.mod h1:8OR4w3TdeIHIh1g6EMY5p0gVNOovcWC+1vpc7naMuAw=
github.com/steakknife/hamming v0.0.0-20180906055917-c99c65617cd3/go.mod h1:hpGUWaI9xL8pRQCTXQgocU38Qw1g0Us7n5PxxTwTCYU=
github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
@ -855,18 +1003,22 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48=
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
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 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca h1:Ld/zXl5t4+D69SiV4JoN7kkfvJdOWlPpfxrzxpLMoUk=
github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca/go.mod h1:u2MKkTVTVJWe5D1rCvame8WqhBd88EuIwODJZ1VHCPM=
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY=
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc=
github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c/go.mod h1:ahpPrc7HpcfEWDQRZEmnXMzHY03mLDYMCxeDzy46i+8=
github.com/tendermint/btcd v0.1.1 h1:0VcxPfflS2zZ3RiOAHkBiFUcPvbtRj5O7zHmcJWHV7s=
github.com/tendermint/btcd v0.1.1/go.mod h1:DC6/m53jtQzr/NFmMNEu0rxf18/ktVoVtMrnDD5pN+U=
github.com/tendermint/crypto v0.0.0-20191022145703-50d29ede1e15 h1:hqAk8riJvK4RMWx1aInLzndwxKalgi5rTqgfXxOxbEI=
@ -876,13 +1028,21 @@ github.com/tendermint/go-amino v0.16.0/go.mod h1:TQU0M1i/ImAo+tYpZi73AU3V/dKeCoM
github.com/tendermint/tendermint v0.34.15 h1:45OEYTBD/TL0YFn8MF7yYJvC5iubyN4AbEjctPi1UqA=
github.com/tendermint/tendermint v0.34.15/go.mod h1:/7EDAw02rD7GT8syC317cX9ZhZTCdaFVvYjU8W+yJSs=
github.com/tendermint/tm-db v0.6.4/go.mod h1:dptYhIpJ2M5kUuenLr+Yyf3zQOv1SgBZcl8/BmWlMBw=
github.com/tendermint/tm-db v0.6.6 h1:EzhaOfR0bdKyATqcd5PNeyeq8r+V4bRPHBfyFdD9kGM=
github.com/tendermint/tm-db v0.6.6/go.mod h1:wP8d49A85B7/erz/r4YbKssKw6ylsO/hKtFk7E1aWZI=
github.com/tendermint/tm-db v0.6.7 h1:fE00Cbl0jayAoqlExN6oyQJ7fR/ZtoVOmvPJ//+shu8=
github.com/tendermint/tm-db v0.6.7/go.mod h1:byQDzFkZV1syXr/ReXS808NxA2xvyuuVgXOJ/088L6I=
github.com/tidwall/gjson v1.6.7/go.mod h1:zeFuBCIqD4sN/gmqBzZ4j7Jd6UcA2Fc56x7QFsv+8fI=
github.com/tidwall/match v1.0.3/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
github.com/tidwall/pretty v1.0.2/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
github.com/tidwall/sjson v1.1.4/go.mod h1:wXpKXu8CtDjKAZ+3DrKY5ROCorDFahq8l0tey/Lx1fg=
github.com/tinylib/msgp v1.0.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE=
github.com/tinylib/msgp v1.1.5/go.mod h1:eQsjooMTnV42mHu917E26IogZ2930nFyBQdofk10Udg=
github.com/tklauser/go-sysconf v0.3.5/go.mod h1:MkWzOF4RMCshBAMXuhXJs64Rte09mITnppBXY/rYEFI=
github.com/tklauser/go-sysconf v0.3.7 h1:HT7h4+536gjqeq1ZIJPgOl1rg1XFatQGVZWp7Py53eg=
github.com/tklauser/go-sysconf v0.3.7/go.mod h1:JZIdXh4RmBvZDBZ41ld2bGxRV3n4daiiqA3skYhAoQ4=
github.com/tklauser/numcpus v0.2.2/go.mod h1:x3qojaO3uyYt0i56EW/VUYs7uBvdl2fkfZFu0T9wgjM=
github.com/tklauser/numcpus v0.2.3 h1:nQ0QYpiritP6ViFhrKYsiv6VVxOpum2Gks5GhnJbS/8=
github.com/tklauser/numcpus v0.2.3/go.mod h1:vpEPS/JC+oZGGQ/My/vJnNsvMDQL6PwOqt8dsCw5j+E=
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/ttacon/chalk v0.0.0-20160626202418-22c06c80ed31/go.mod h1:onvgF043R+lC5RZ8IT9rBXDaEDnpnw/Cl+HFiw+v/7Q=
@ -890,6 +1050,8 @@ github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqri
github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM=
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.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo=
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
@ -898,12 +1060,18 @@ github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
github.com/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.1.4/go.mod h1:C5gboKD0TJPqWDTVTtrQNfRbiBwHZGo8UTqP/9/XvLI=
github.com/vmihailenco/tagparser v0.1.2/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI=
github.com/willf/bitset v1.1.3/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208/go.mod h1:IotVbo4F+mw0EzQ08zFqg7pK3FebNXpaMsRy2RT+Ees=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/xlab/treeprint v0.0.0-20180616005107-d6fb6747feb6/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
github.com/ybbus/jsonrpc v2.1.2+incompatible/go.mod h1:XJrh1eMSzdIYFbM08flv0wp5G35eRniyeGut1z+LSiE=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
@ -911,6 +1079,7 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
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.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/zondax/hid v0.9.0 h1:eiT3P6vNxAEVxXMw66eZUAAnU2zD33JBkfG/EnfAKl8=
github.com/zondax/hid v0.9.0/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM=
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
@ -943,6 +1112,7 @@ go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
go.uber.org/multierr v1.7.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak=
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.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo=
@ -968,11 +1138,14 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh
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-20201117144127-c1f2f97bffc9/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/crypto v0.0.0-20210314154223-e6e6c4f2bb5b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20210915214749-c084706c2272 h1:3erb+vDS8lU1sxfDHF4/hhWyaXnhIaO+7RgL4fDZORA=
golang.org/x/crypto v0.0.0-20210915214749-c084706c2272/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20220213190939-1e6e3497d506 h1:EuGTJDfeg/PGZJp3gq1K+14eSLFTsrj1eg8KQuiUyKg=
golang.org/x/crypto v0.0.0-20220213190939-1e6e3497d506/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@ -1062,6 +1235,7 @@ golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwY
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=
@ -1069,9 +1243,11 @@ golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT
golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210917221730-978cfadd31cf/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211005001312-d4b1ae081e3b h1:SXy8Ld8oKlcogOvUAh0J5Pm5RKzgYBMMxLxt6n5XW50=
golang.org/x/net v0.0.0-20211005001312-d4b1ae081e3b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
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=
@ -1098,6 +1274,7 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@ -1121,8 +1298,10 @@ golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190712062909-fae7ac547cb7/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-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@ -1136,6 +1315,7 @@ golang.org/x/sys v0.0.0-20191210023423-ac6580df4449/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200107162124-548cf772de50/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@ -1157,6 +1337,7 @@ golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200824131525-c12d262b63d8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200826173525-f9321e4c35a6/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@ -1171,9 +1352,12 @@ golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210316164454-77fc1eacc6aa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210420205809-ac73e9fd8988/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@ -1184,10 +1368,13 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc
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-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210917161153-d61c044b1678/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211004093028-2c5d950f24ef h1:fPxZ3Umkct3LZ8gK9nbk+DWDJ9fstZa2grBn+lWVKPs=
golang.org/x/sys v0.0.0-20211004093028-2c5d950f24ef/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211210111614-af8b64212486 h1:5hpz5aRr+W1erYCL5JRhSUBJRph7l9XkNveoExlrKYk=
golang.org/x/sys v0.0.0-20211210111614-af8b64212486/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 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
@ -1206,6 +1393,9 @@ golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxb
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-20200416051211-89c76fbcd5d1/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.0.0-20210723032227-1f47c861a9ac h1:7zkz7BUtwNFFqcowJ+RIgu2MaV/MapERkDIy+mwPyjs=
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@ -1236,6 +1426,7 @@ golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtn
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200108203644-89082a384178/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200117012304-6edc0a871e69/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
@ -1272,13 +1463,17 @@ 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.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
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 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo=
gonum.org/v1/gonum v0.0.0-20181121035319-3f7ecaa7e8ca/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo=
gonum.org/v1/gonum v0.6.0/go.mod h1:9mxDZsDKxgMAuccQkewq682L+0eCu4dCN2yonUJTCLU=
gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0=
gonum.org/v1/netlib v0.0.0-20181029234149-ec6d1f5cefe6/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw=
gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw=
gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc=
google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
@ -1324,6 +1519,7 @@ google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRn
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s=
google.golang.org/genproto v0.0.0-20190716160619-c506a9f90610/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
@ -1331,6 +1527,7 @@ google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvx
google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200108215221-bd8f9a0ef82f/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
@ -1375,8 +1572,9 @@ google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKr
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-20210917145530-b395a37504d4 h1:ysnBoUyeL/H6RCvNRhWHjKoDEmguI+mPU+qHgK8qv/w=
google.golang.org/genproto v0.0.0-20210917145530-b395a37504d4/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
google.golang.org/genproto v0.0.0-20220211171837-173942840c17 h1:2X+CNIheCutWRyKRte8szGxrE5ggtV4U+NKAbh/oLhg=
google.golang.org/genproto v0.0.0-20220211171837-173942840c17/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=
google.golang.org/grpc v1.33.2 h1:EQyQC3sa8M+p6Ulc8yy9SWSS2GVwyRc83gAbG8lrl4o=
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
@ -1394,27 +1592,33 @@ google.golang.org/protobuf v1.25.1-0.20200805231151-a709e31e5d12/go.mod h1:9JNX7
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.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ=
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b h1:QRR6H1YWRnHb4Y/HeNFCTJLFVxaq6wH4YuVdsUOr75U=
gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
gopkg.in/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.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/ini.v1 v1.63.2 h1:tGK/CyBg7SMzb60vP1M03vNZ3VDu3wGQJwn7Sxi9r3c=
gopkg.in/ini.v1 v1.63.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/ini.v1 v1.66.2 h1:XfR1dOYubytKy4Shzc2LHrrGhU0lDCfDGG1yLPmpgsI=
gopkg.in/ini.v1 v1.66.2/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 h1:a6cXbcDDUkSBlpnkWV1bJ+vv3mOgQEltEJ2rPxroVu0=
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 h1:NdAVW6RYxDif9DhDHaAortIu956m2c0v+09AZBPTbE0=
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=
@ -1438,6 +1642,7 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las=
nhooyr.io/websocket v1.8.6 h1:s+C3xAMLwGmlI31Nyn/eAehUlZPwfYZu2JXM621Q5/k=
nhooyr.io/websocket v1.8.6/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=

View File

@ -14,15 +14,15 @@ import (
"github.com/kava-labs/kava/app"
"github.com/kava-labs/kava/app/params"
"github.com/kava-labs/kava/migrate/v0_16"
"github.com/kava-labs/kava/migrate/v0_17"
)
// MigrateGenesisCmd returns a command to execute genesis state migration.
func MigrateGenesisCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "migrate [genesis-file]",
Short: "Migrate genesis from v0.15 to v0.16",
Long: "Migrate the source genesis into v0.16 and print to STDOUT.",
Short: "Migrate genesis from v0.16 to v0.17",
Long: "Migrate the source genesis into v0.17 and print to STDOUT.",
Example: fmt.Sprintf(`%s migrate /path/to/genesis.json`, version.AppName),
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
@ -34,7 +34,7 @@ func MigrateGenesisCmd() *cobra.Command {
return fmt.Errorf("failed to read genesis document from file %s: %w", importGenesis, err)
}
newGenDoc, err := v0_16.Migrate(oldGenDoc, clientCtx)
newGenDoc, err := v0_17.Migrate(oldGenDoc, clientCtx)
if err != nil {
return fmt.Errorf("failed to run migration: %w", err)
}

View File

@ -11,10 +11,10 @@ import (
"github.com/stretchr/testify/require"
)
func TestMigrateGenesisCmd_V16_Success(t *testing.T) {
func TestMigrateGenesisCmd_V17_Success(t *testing.T) {
ctx := newCmdContext()
cmd := migrate.MigrateGenesisCmd()
file := filepath.Join("v0_16", "testdata", "genesis-v15.json")
file := filepath.Join("v0_17", "testdata", "genesis-v16.json")
cmd.SetArgs([]string{file})
err := cmd.ExecuteContext(ctx)
require.NoError(t, err)

View File

@ -34,9 +34,9 @@ import (
v040staking "github.com/cosmos/cosmos-sdk/x/staking/legacy/v040"
v038upgrade "github.com/cosmos/cosmos-sdk/x/upgrade/legacy/v038"
ibctransfertypes "github.com/cosmos/ibc-go/modules/apps/transfer/types"
ibchost "github.com/cosmos/ibc-go/modules/core/24-host"
ibctypes "github.com/cosmos/ibc-go/modules/core/types"
ibctransfertypes "github.com/cosmos/ibc-go/v3/modules/apps/transfer/types"
ibchost "github.com/cosmos/ibc-go/v3/modules/core/24-host"
ibctypes "github.com/cosmos/ibc-go/v3/modules/core/types"
v015kavadist "github.com/kava-labs/kava/x/kavadist/legacy/v0_15"
v015validatorvesting "github.com/kava-labs/kava/x/validator-vesting/legacy/v0_15"

36
migrate/v0_17/kava.go Normal file
View File

@ -0,0 +1,36 @@
package v0_17
import (
"github.com/cosmos/cosmos-sdk/client"
genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types"
evmtypes "github.com/tharsis/ethermint/x/evm/types"
feemarkettypes "github.com/tharsis/ethermint/x/feemarket/types"
evmutiltypes "github.com/kava-labs/kava/x/evmutil/types"
)
func migrateAppState(appState genutiltypes.AppMap, clientCtx client.Context) {
codec := clientCtx.Codec
// x/emvutil
evmUtilGenState := evmutiltypes.NewGenesisState([]evmutiltypes.Account{})
appState[evmutiltypes.ModuleName] = codec.MustMarshalJSON(evmUtilGenState)
// x/evm
evmGenState := &evmtypes.GenesisState{
Accounts: []evmtypes.GenesisAccount{},
Params: evmtypes.Params{
EvmDenom: "akava",
EnableCreate: true,
EnableCall: true,
ChainConfig: evmtypes.DefaultChainConfig(),
ExtraEIPs: nil,
},
}
appState[evmtypes.ModuleName] = codec.MustMarshalJSON(evmGenState)
// x/feemarket
feemarketState := feemarkettypes.DefaultGenesisState()
appState[feemarkettypes.ModuleName] = codec.MustMarshalJSON(feemarketState)
}

51
migrate/v0_17/migrate.go Normal file
View File

@ -0,0 +1,51 @@
package v0_17
import (
"encoding/json"
"fmt"
"time"
"github.com/cosmos/cosmos-sdk/client"
sdk "github.com/cosmos/cosmos-sdk/types"
genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types"
"github.com/kava-labs/kava/app"
tmtypes "github.com/tendermint/tendermint/types"
)
var (
// TODO: needs verification before release
GenesisTime = time.Date(2022, 5, 10, 17, 0, 0, 0, time.UTC)
ChainID = "kava-2222-10"
)
func setConfigIfUnsealed() {
config := sdk.GetConfig()
if config.GetBech32AccountAddrPrefix() == "kava" {
return
}
app.SetSDKConfig()
}
// Migrate converts v16 genesis doc to v17 genesis doc
func Migrate(genDoc *tmtypes.GenesisDoc, ctx client.Context) (*tmtypes.GenesisDoc, error) {
setConfigIfUnsealed()
var appState genutiltypes.AppMap
var err error
if err := json.Unmarshal(genDoc.AppState, &appState); err != nil {
return nil, fmt.Errorf("failed to marchal app state from genesis doc: %w", err)
}
migrateAppState(appState, ctx)
genDoc.AppState, err = json.Marshal(appState)
if err != nil {
return nil, err
}
genDoc.GenesisTime = GenesisTime
genDoc.ChainID = ChainID
genDoc.InitialHeight = 1
return genDoc, nil
}

View File

@ -0,0 +1,96 @@
package v0_17
import (
"io/ioutil"
"path/filepath"
"testing"
"github.com/kava-labs/kava/app"
"github.com/stretchr/testify/assert"
"github.com/cosmos/cosmos-sdk/client"
genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types"
tmjson "github.com/tendermint/tendermint/libs/json"
tmtypes "github.com/tendermint/tendermint/types"
evmtypes "github.com/tharsis/ethermint/x/evm/types"
feemarkettypes "github.com/tharsis/ethermint/x/feemarket/types"
evmutiltypes "github.com/kava-labs/kava/x/evmutil/types"
)
func TestMigrateGenesisDoc(t *testing.T) {
expected := getTestDataJSON("genesis-v17.json")
genDoc, err := tmtypes.GenesisDocFromFile(filepath.Join("testdata", "genesis-v16.json"))
assert.NoError(t, err)
actualGenDoc, err := Migrate(genDoc, newClientContext())
assert.NoError(t, err)
actualJson, err := tmjson.Marshal(actualGenDoc)
assert.NoError(t, err)
assert.JSONEq(t, expected, string(actualJson))
}
func TestMigrateEvmUtil(t *testing.T) {
appMap, ctx := migrateToV16AndGetAppMap(t)
var genstate evmutiltypes.GenesisState
err := ctx.Codec.UnmarshalJSON(appMap[evmutiltypes.ModuleName], &genstate)
assert.NoError(t, err)
assert.Len(t, genstate.Accounts, 0)
}
func TestMigrateEvm(t *testing.T) {
appMap, ctx := migrateToV16AndGetAppMap(t)
var genstate evmtypes.GenesisState
err := ctx.Codec.UnmarshalJSON(appMap[evmtypes.ModuleName], &genstate)
assert.NoError(t, err)
assert.Len(t, genstate.Accounts, 0)
assert.Equal(t, genstate.Params, evmtypes.Params{
EvmDenom: "akava",
EnableCreate: true,
EnableCall: true,
ChainConfig: evmtypes.DefaultChainConfig(),
ExtraEIPs: []int64{},
})
}
func TestMigrateFeeMarket(t *testing.T) {
appMap, ctx := migrateToV16AndGetAppMap(t)
var genstate feemarkettypes.GenesisState
err := ctx.Codec.UnmarshalJSON(appMap[feemarkettypes.ModuleName], &genstate)
assert.NoError(t, err)
assert.Equal(t, genstate, *feemarkettypes.DefaultGenesisState())
}
func migrateToV16AndGetAppMap(t *testing.T) (genutiltypes.AppMap, client.Context) {
genDoc, err := tmtypes.GenesisDocFromFile(filepath.Join("testdata", "genesis-v16.json"))
assert.NoError(t, err)
ctx := newClientContext()
actualGenDoc, err := Migrate(genDoc, ctx)
assert.NoError(t, err)
var appMap genutiltypes.AppMap
err = tmjson.Unmarshal(actualGenDoc.AppState, &appMap)
assert.NoError(t, err)
return appMap, ctx
}
func getTestDataJSON(filename string) string {
file := filepath.Join("testdata", filename)
data, err := ioutil.ReadFile(file)
if err != nil {
panic(err)
}
return string(data)
}
func newClientContext() client.Context {
config := app.MakeEncodingConfig()
return client.Context{}.
WithCodec(config.Marshaler).
WithLegacyAmino(config.Amino).
WithInterfaceRegistry(config.InterfaceRegistry)
}

2280
migrate/v0_17/testdata/genesis-v16.json vendored Normal file

File diff suppressed because it is too large Load Diff

2224
migrate/v0_17/testdata/genesis-v17.json vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,32 @@
syntax = "proto3";
package kava.evmutil.v1beta1;
import "gogoproto/gogo.proto";
import "cosmos_proto/cosmos.proto";
option go_package = "github.com/kava-labs/kava/x/evmutil/types";
// GenesisState defines the evmutil module's genesis state.
message GenesisState {
option (gogoproto.goproto_getters) = false;
repeated Account accounts = 1 [(gogoproto.nullable) = false];
}
// BalanceAccount defines an account in the evmutil module.
message Account {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;
bytes address = 1 [
(cosmos_proto.scalar) = "cosmos.AddressBytes",
(gogoproto.casttype) = "github.com/cosmos/cosmos-sdk/types.AccAddress"
];
// balance indicates the amount of akava owned by the address.
string balance = 2 [
(cosmos_proto.scalar) = "cosmos.Int",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.nullable) = false
];
}

View File

@ -0,0 +1,19 @@
syntax = "proto3";
package ethermint.crypto.v1.ethsecp256k1;
import "gogoproto/gogo.proto";
option go_package = "github.com/tharsis/ethermint/crypto/ethsecp256k1";
// PubKey defines a type alias for an ecdsa.PublicKey that implements
// Tendermint's PubKey interface. It represents the 33-byte compressed public
// key format.
message PubKey {
option (gogoproto.goproto_stringer) = false;
bytes key = 1;
}
// PrivKey defines a type alias for an ecdsa.PrivateKey that implements
// Tendermint's PrivateKey interface.
message PrivKey { bytes key = 1; }

View File

@ -0,0 +1,222 @@
syntax = "proto3";
package ethermint.evm.v1;
import "gogoproto/gogo.proto";
option go_package = "github.com/tharsis/ethermint/x/evm/types";
// Params defines the EVM module parameters
message Params {
// evm denom represents the token denomination used to run the EVM state
// transitions.
string evm_denom = 1 [ (gogoproto.moretags) = "yaml:\"evm_denom\"" ];
// enable create toggles state transitions that use the vm.Create function
bool enable_create = 2 [ (gogoproto.moretags) = "yaml:\"enable_create\"" ];
// enable call toggles state transitions that use the vm.Call function
bool enable_call = 3 [ (gogoproto.moretags) = "yaml:\"enable_call\"" ];
// extra eips defines the additional EIPs for the vm.Config
repeated int64 extra_eips = 4 [
(gogoproto.customname) = "ExtraEIPs",
(gogoproto.moretags) = "yaml:\"extra_eips\""
];
// chain config defines the EVM chain configuration parameters
ChainConfig chain_config = 5 [
(gogoproto.moretags) = "yaml:\"chain_config\"",
(gogoproto.nullable) = false
];
}
// ChainConfig defines the Ethereum ChainConfig parameters using *sdk.Int values
// instead of *big.Int.
message ChainConfig {
// Homestead switch block (nil no fork, 0 = already homestead)
string homestead_block = 1 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.moretags) = "yaml:\"homestead_block\""
];
// TheDAO hard-fork switch block (nil no fork)
string dao_fork_block = 2 [
(gogoproto.customname) = "DAOForkBlock",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.moretags) = "yaml:\"dao_fork_block\""
];
// Whether the nodes supports or opposes the DAO hard-fork
bool dao_fork_support = 3 [
(gogoproto.customname) = "DAOForkSupport",
(gogoproto.moretags) = "yaml:\"dao_fork_support\""
];
// EIP150 implements the Gas price changes
// (https://github.com/ethereum/EIPs/issues/150) EIP150 HF block (nil no fork)
string eip150_block = 4 [
(gogoproto.customname) = "EIP150Block",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.moretags) = "yaml:\"eip150_block\""
];
// EIP150 HF hash (needed for header only clients as only gas pricing changed)
string eip150_hash = 5 [
(gogoproto.customname) = "EIP150Hash",
(gogoproto.moretags) = "yaml:\"byzantium_block\""
];
// EIP155Block HF block
string eip155_block = 6 [
(gogoproto.customname) = "EIP155Block",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.moretags) = "yaml:\"eip155_block\""
];
// EIP158 HF block
string eip158_block = 7 [
(gogoproto.customname) = "EIP158Block",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.moretags) = "yaml:\"eip158_block\""
];
// Byzantium switch block (nil no fork, 0 = already on byzantium)
string byzantium_block = 8 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.moretags) = "yaml:\"byzantium_block\""
];
// Constantinople switch block (nil no fork, 0 = already activated)
string constantinople_block = 9 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.moretags) = "yaml:\"constantinople_block\""
];
// Petersburg switch block (nil same as Constantinople)
string petersburg_block = 10 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.moretags) = "yaml:\"petersburg_block\""
];
// Istanbul switch block (nil no fork, 0 = already on istanbul)
string istanbul_block = 11 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.moretags) = "yaml:\"istanbul_block\""
];
// Eip-2384 (bomb delay) switch block (nil no fork, 0 = already activated)
string muir_glacier_block = 12 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.moretags) = "yaml:\"muir_glacier_block\""
];
// Berlin switch block (nil = no fork, 0 = already on berlin)
string berlin_block = 13 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.moretags) = "yaml:\"berlin_block\""
];
// DEPRECATED: EWASM, YOLOV3 and Catalyst block have been deprecated
reserved 14, 15, 16;
reserved "yolo_v3_block", "ewasm_block", "catalyst_block";
// London switch block (nil = no fork, 0 = already on london)
string london_block = 17 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.moretags) = "yaml:\"london_block\""
];
}
// State represents a single Storage key value pair item.
message State {
string key = 1;
string value = 2;
}
// TransactionLogs define the logs generated from a transaction execution
// with a given hash. It it used for import/export data as transactions are not
// persisted on blockchain state after an upgrade.
message TransactionLogs {
string hash = 1;
repeated Log logs = 2;
}
// Log represents an protobuf compatible Ethereum Log that defines a contract
// log event. These events are generated by the LOG opcode and stored/indexed by
// the node.
message Log {
// Consensus fields:
// address of the contract that generated the event
string address = 1;
// list of topics provided by the contract.
repeated string topics = 2;
// supplied by the contract, usually ABI-encoded
bytes data = 3;
// Derived fields. These fields are filled in by the node
// but not secured by consensus.
// block in which the transaction was included
uint64 block_number = 4 [ (gogoproto.jsontag) = "blockNumber" ];
// hash of the transaction
string tx_hash = 5 [ (gogoproto.jsontag) = "transactionHash" ];
// index of the transaction in the block
uint64 tx_index = 6 [ (gogoproto.jsontag) = "transactionIndex" ];
// hash of the block in which the transaction was included
string block_hash = 7 [ (gogoproto.jsontag) = "blockHash" ];
// index of the log in the block
uint64 index = 8 [ (gogoproto.jsontag) = "logIndex" ];
// The Removed field is true if this log was reverted due to a chain
// reorganisation. You must pay attention to this field if you receive logs
// through a filter query.
bool removed = 9;
}
// TxResult stores results of Tx execution.
message TxResult {
option (gogoproto.goproto_getters) = false;
// contract_address contains the ethereum address of the created contract (if
// any). If the state transition is an evm.Call, the contract address will be
// empty.
string contract_address = 1
[ (gogoproto.moretags) = "yaml:\"contract_address\"" ];
// bloom represents the bloom filter bytes
bytes bloom = 2;
// tx_logs contains the transaction hash and the proto-compatible ethereum
// logs.
TransactionLogs tx_logs = 3 [
(gogoproto.moretags) = "yaml:\"tx_logs\"",
(gogoproto.nullable) = false
];
// ret defines the bytes from the execution.
bytes ret = 4;
// reverted flag is set to true when the call has been reverted
bool reverted = 5;
// gas_used notes the amount of gas consumed while execution
uint64 gas_used = 6;
}
// AccessTuple is the element type of an access list.
message AccessTuple {
option (gogoproto.goproto_getters) = false;
// hex formatted ethereum address
string address = 1;
// hex formatted hashes of the storage keys
repeated string storage_keys = 2 [ (gogoproto.jsontag) = "storageKeys" ];
}
// TraceConfig holds extra parameters to trace functions.
message TraceConfig {
// DEPRECATED: DisableMemory and DisableReturnData have been renamed to
// Enable*.
reserved 4, 7;
reserved "disable_memory", "disable_return_data";
// custom javascript tracer
string tracer = 1;
// overrides the default timeout of 5 seconds for JavaScript-based tracing
// calls
string timeout = 2;
// number of blocks the tracer is willing to go back
uint64 reexec = 3;
// disable stack capture
bool disable_stack = 5 [ (gogoproto.jsontag) = "disableStack" ];
// disable storage capture
bool disable_storage = 6 [ (gogoproto.jsontag) = "disableStorage" ];
// print output during capture end
bool debug = 8;
// maximum length of output, but zero means unlimited
int32 limit = 9;
// Chain overrides, can be used to execute a trace using future fork rules
ChainConfig overrides = 10;
// enable memory capture
bool enable_memory = 11 [ (gogoproto.jsontag) = "enableMemory" ];
// enable return data capture
bool enable_return_data = 12 [ (gogoproto.jsontag) = "enableReturnData" ];
}

View File

@ -0,0 +1,28 @@
syntax = "proto3";
package ethermint.evm.v1;
import "gogoproto/gogo.proto";
import "ethermint/evm/v1/evm.proto";
option go_package = "github.com/tharsis/ethermint/x/evm/types";
// GenesisState defines the evm module's genesis state.
message GenesisState {
// accounts is an array containing the ethereum genesis accounts.
repeated GenesisAccount accounts = 1 [ (gogoproto.nullable) = false ];
// params defines all the parameters of the module.
Params params = 2 [ (gogoproto.nullable) = false ];
}
// GenesisAccount defines an account to be initialized in the genesis state.
// Its main difference between with Geth's GenesisAccount is that it uses a
// custom storage type and that it doesn't contain the private key field.
message GenesisAccount {
// address defines an ethereum hex formated address of an account
string address = 1;
// code defines the hex bytes of the account code.
string code = 2;
// storage defines the set of state key values for the account.
repeated State storage = 3
[ (gogoproto.nullable) = false, (gogoproto.castrepeated) = "Storage" ];
}

View File

@ -0,0 +1,272 @@
syntax = "proto3";
package ethermint.evm.v1;
import "gogoproto/gogo.proto";
import "cosmos/base/query/v1beta1/pagination.proto";
import "google/api/annotations.proto";
import "ethermint/evm/v1/evm.proto";
import "ethermint/evm/v1/tx.proto";
import "google/protobuf/timestamp.proto";
option go_package = "github.com/tharsis/ethermint/x/evm/types";
// Query defines the gRPC querier service.
service Query {
// Account queries an Ethereum account.
rpc Account(QueryAccountRequest) returns (QueryAccountResponse) {
option (google.api.http).get = "/ethermint/evm/v1/account/{address}";
}
// CosmosAccount queries an Ethereum account's Cosmos Address.
rpc CosmosAccount(QueryCosmosAccountRequest)
returns (QueryCosmosAccountResponse) {
option (google.api.http).get = "/ethermint/evm/v1/cosmos_account/{address}";
}
// ValidatorAccount queries an Ethereum account's from a validator consensus
// Address.
rpc ValidatorAccount(QueryValidatorAccountRequest)
returns (QueryValidatorAccountResponse) {
option (google.api.http).get =
"/ethermint/evm/v1/validator_account/{cons_address}";
}
// Balance queries the balance of a the EVM denomination for a single
// EthAccount.
rpc Balance(QueryBalanceRequest) returns (QueryBalanceResponse) {
option (google.api.http).get = "/ethermint/evm/v1/balances/{address}";
}
// Storage queries the balance of all coins for a single account.
rpc Storage(QueryStorageRequest) returns (QueryStorageResponse) {
option (google.api.http).get = "/ethermint/evm/v1/storage/{address}/{key}";
}
// Code queries the balance of all coins for a single account.
rpc Code(QueryCodeRequest) returns (QueryCodeResponse) {
option (google.api.http).get = "/ethermint/evm/v1/codes/{address}";
}
// Params queries the parameters of x/evm module.
rpc Params(QueryParamsRequest) returns (QueryParamsResponse) {
option (google.api.http).get = "/ethermint/evm/v1/params";
}
// EthCall implements the `eth_call` rpc api
rpc EthCall(EthCallRequest) returns (MsgEthereumTxResponse) {
option (google.api.http).get = "/ethermint/evm/v1/eth_call";
}
// EstimateGas implements the `eth_estimateGas` rpc api
rpc EstimateGas(EthCallRequest) returns (EstimateGasResponse) {
option (google.api.http).get = "/ethermint/evm/v1/estimate_gas";
}
// TraceTx implements the `debug_traceTransaction` rpc api
rpc TraceTx(QueryTraceTxRequest) returns (QueryTraceTxResponse) {
option (google.api.http).get = "/ethermint/evm/v1/trace_tx";
}
// TraceBlock implements the `debug_traceBlockByNumber` and `debug_traceBlockByHash` rpc api
rpc TraceBlock(QueryTraceBlockRequest) returns (QueryTraceBlockResponse) {
option (google.api.http).get = "/ethermint/evm/v1/trace_block";
}
}
// QueryAccountRequest is the request type for the Query/Account RPC method.
message QueryAccountRequest {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;
// address is the ethereum hex address to query the account for.
string address = 1;
}
// QueryAccountResponse is the response type for the Query/Account RPC method.
message QueryAccountResponse {
// balance is the balance of the EVM denomination.
string balance = 1;
// code hash is the hex-formatted code bytes from the EOA.
string code_hash = 2;
// nonce is the account's sequence number.
uint64 nonce = 3;
}
// QueryCosmosAccountRequest is the request type for the Query/CosmosAccount RPC
// method.
message QueryCosmosAccountRequest {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;
// address is the ethereum hex address to query the account for.
string address = 1;
}
// QueryCosmosAccountResponse is the response type for the Query/CosmosAccount
// RPC method.
message QueryCosmosAccountResponse {
// cosmos_address is the cosmos address of the account.
string cosmos_address = 1;
// sequence is the account's sequence number.
uint64 sequence = 2;
// account_number is the account numbert
uint64 account_number = 3;
}
// QueryValidatorAccountRequest is the request type for the
// Query/ValidatorAccount RPC method.
message QueryValidatorAccountRequest {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;
// cons_address is the validator cons address to query the account for.
string cons_address = 1;
}
// QueryValidatorAccountResponse is the response type for the
// Query/ValidatorAccount RPC method.
message QueryValidatorAccountResponse {
// account_address is the cosmos address of the account in bech32 format.
string account_address = 1;
// sequence is the account's sequence number.
uint64 sequence = 2;
// account_number is the account number
uint64 account_number = 3;
}
// QueryBalanceRequest is the request type for the Query/Balance RPC method.
message QueryBalanceRequest {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;
// address is the ethereum hex address to query the balance for.
string address = 1;
}
// QueryBalanceResponse is the response type for the Query/Balance RPC method.
message QueryBalanceResponse {
// balance is the balance of the EVM denomination.
string balance = 1;
}
// QueryStorageRequest is the request type for the Query/Storage RPC method.
message QueryStorageRequest {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;
/// address is the ethereum hex address to query the storage state for.
string address = 1;
// key defines the key of the storage state
string key = 2;
}
// QueryStorageResponse is the response type for the Query/Storage RPC
// method.
message QueryStorageResponse {
// key defines the storage state value hash associated with the given key.
string value = 1;
}
// QueryCodeRequest is the request type for the Query/Code RPC method.
message QueryCodeRequest {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;
// address is the ethereum hex address to query the code for.
string address = 1;
}
// QueryCodeResponse is the response type for the Query/Code RPC
// method.
message QueryCodeResponse {
// code represents the code bytes from an ethereum address.
bytes code = 1;
}
// QueryTxLogsRequest is the request type for the Query/TxLogs RPC method.
message QueryTxLogsRequest {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;
// hash is the ethereum transaction hex hash to query the logs for.
string hash = 1;
// pagination defines an optional pagination for the request.
cosmos.base.query.v1beta1.PageRequest pagination = 2;
}
// QueryTxLogs is the response type for the Query/TxLogs RPC method.
message QueryTxLogsResponse {
// logs represents the ethereum logs generated from the given transaction.
repeated Log logs = 1;
// pagination defines the pagination in the response.
cosmos.base.query.v1beta1.PageResponse pagination = 2;
}
// QueryParamsRequest defines the request type for querying x/evm parameters.
message QueryParamsRequest {}
// QueryParamsResponse defines the response type for querying x/evm parameters.
message QueryParamsResponse {
// params define the evm module parameters.
Params params = 1 [ (gogoproto.nullable) = false ];
}
// EthCallRequest defines EthCall request
message EthCallRequest {
// same json format as the json rpc api.
bytes args = 1;
// the default gas cap to be used
uint64 gas_cap = 2;
}
// EstimateGasResponse defines EstimateGas response
message EstimateGasResponse {
// the estimated gas
uint64 gas = 1;
}
// QueryTraceTxRequest defines TraceTx request
message QueryTraceTxRequest {
// msgEthereumTx for the requested transaction
MsgEthereumTx msg = 1;
// transaction index
uint64 tx_index = 2;
// TraceConfig holds extra parameters to trace functions.
TraceConfig trace_config = 3;
// the predecessor transactions included in the same block
// need to be replayed first to get correct context for tracing.
repeated MsgEthereumTx predecessors = 4;
// block number of requested transaction
int64 block_number = 5;
// block hex hash of requested transaction
string block_hash = 6;
// block time of requested transaction
google.protobuf.Timestamp block_time = 7 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true];
}
// QueryTraceTxResponse defines TraceTx response
message QueryTraceTxResponse {
// response serialized in bytes
bytes data = 1;
}
// QueryTraceBlockRequest defines TraceTx request
message QueryTraceBlockRequest {
// txs messages in the block
repeated MsgEthereumTx txs = 1;
// TraceConfig holds extra parameters to trace functions.
TraceConfig trace_config = 3;
// block number
int64 block_number = 5;
// block hex hash
string block_hash = 6;
// block time
google.protobuf.Timestamp block_time = 7 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true];
}
// QueryTraceBlockResponse defines TraceBlock response
message QueryTraceBlockResponse {
bytes data = 1;
}

View File

@ -0,0 +1,172 @@
syntax = "proto3";
package ethermint.evm.v1;
import "gogoproto/gogo.proto";
import "google/api/annotations.proto";
import "google/protobuf/any.proto";
import "cosmos_proto/cosmos.proto";
import "ethermint/evm/v1/evm.proto";
option go_package = "github.com/tharsis/ethermint/x/evm/types";
// Msg defines the evm Msg service.
service Msg {
// EthereumTx defines a method submitting Ethereum transactions.
rpc EthereumTx(MsgEthereumTx) returns (MsgEthereumTxResponse) {
option (google.api.http).post = "/ethermint/evm/v1/ethereum_tx";
};
}
// MsgEthereumTx encapsulates an Ethereum transaction as an SDK message.
message MsgEthereumTx {
option (gogoproto.goproto_getters) = false;
// inner transaction data
google.protobuf.Any data = 1;
// caches
// encoded storage size of the transaction
double size = 2 [ (gogoproto.jsontag) = "-" ];
// transaction hash in hex format
string hash = 3 [ (gogoproto.moretags) = "rlp:\"-\"" ];
// ethereum signer address in hex format. This address value is checked
// against the address derived from the signature (V, R, S) using the
// secp256k1 elliptic curve
string from = 4;
}
// LegacyTx is the transaction data of regular Ethereum transactions.
message LegacyTx {
option (gogoproto.goproto_getters) = false;
option (cosmos_proto.implements_interface) = "TxData";
// nonce corresponds to the account nonce (transaction sequence).
uint64 nonce = 1;
// gas price defines the value for each gas unit
string gas_price = 2
[ (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int" ];
// gas defines the gas limit defined for the transaction.
uint64 gas = 3 [ (gogoproto.customname) = "GasLimit" ];
// hex formatted address of the recipient
string to = 4;
// value defines the unsigned integer value of the transaction amount.
string value = 5 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.customname) = "Amount"
];
// input defines the data payload bytes of the transaction.
bytes data = 6;
// v defines the signature value
bytes v = 7;
// r defines the signature value
bytes r = 8;
// s define the signature value
bytes s = 9;
}
// AccessListTx is the data of EIP-2930 access list transactions.
message AccessListTx {
option (gogoproto.goproto_getters) = false;
option (cosmos_proto.implements_interface) = "TxData";
// destination EVM chain ID
string chain_id = 1 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.customname) = "ChainID",
(gogoproto.jsontag) = "chainID"
];
// nonce corresponds to the account nonce (transaction sequence).
uint64 nonce = 2;
// gas price defines the value for each gas unit
string gas_price = 3
[ (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int" ];
// gas defines the gas limit defined for the transaction.
uint64 gas = 4 [ (gogoproto.customname) = "GasLimit" ];
// hex formatted address of the recipient
string to = 5;
// value defines the unsigned integer value of the transaction amount.
string value = 6 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.customname) = "Amount"
];
// input defines the data payload bytes of the transaction.
bytes data = 7;
repeated AccessTuple accesses = 8 [
(gogoproto.castrepeated) = "AccessList",
(gogoproto.jsontag) = "accessList",
(gogoproto.nullable) = false
];
// v defines the signature value
bytes v = 9;
// r defines the signature value
bytes r = 10;
// s define the signature value
bytes s = 11;
}
// DynamicFeeTx is the data of EIP-1559 dinamic fee transactions.
message DynamicFeeTx {
option (gogoproto.goproto_getters) = false;
option (cosmos_proto.implements_interface) = "TxData";
// destination EVM chain ID
string chain_id = 1 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.customname) = "ChainID",
(gogoproto.jsontag) = "chainID"
];
// nonce corresponds to the account nonce (transaction sequence).
uint64 nonce = 2;
// gas tip cap defines the max value for the gas tip
string gas_tip_cap = 3
[ (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int" ];
// gas fee cap defines the max value for the gas fee
string gas_fee_cap = 4
[ (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int" ];
// gas defines the gas limit defined for the transaction.
uint64 gas = 5 [ (gogoproto.customname) = "GasLimit" ];
// hex formatted address of the recipient
string to = 6;
// value defines the the transaction amount.
string value = 7 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.customname) = "Amount"
];
// input defines the data payload bytes of the transaction.
bytes data = 8;
repeated AccessTuple accesses = 9 [
(gogoproto.castrepeated) = "AccessList",
(gogoproto.jsontag) = "accessList",
(gogoproto.nullable) = false
];
// v defines the signature value
bytes v = 10;
// r defines the signature value
bytes r = 11;
// s define the signature value
bytes s = 12;
}
message ExtensionOptionsEthereumTx {
option (gogoproto.goproto_getters) = false;
}
// MsgEthereumTxResponse defines the Msg/EthereumTx response type.
message MsgEthereumTxResponse {
option (gogoproto.goproto_getters) = false;
// ethereum transaction hash in hex format. This hash differs from the
// Tendermint sha256 hash of the transaction bytes. See
// https://github.com/tendermint/tendermint/issues/6539 for reference
string hash = 1;
// logs contains the transaction hash and the proto-compatible ethereum
// logs.
repeated Log logs = 2;
// returned data from evm function (result or data supplied with revert
// opcode)
bytes ret = 3;
// vm error is the error returned by vm execution
string vm_error = 4;
// gas consumed by the transaction
uint64 gas_used = 5;
}

View File

@ -0,0 +1,20 @@
syntax = "proto3";
package ethermint.feemarket.v1;
option go_package = "github.com/tharsis/ethermint/x/feemarket/types";
// Params defines the EVM module parameters
message Params {
// no base fee forces the EIP-1559 base fee to 0 (needed for 0 price calls)
bool no_base_fee = 1;
// base fee change denominator bounds the amount the base fee can change
// between blocks.
uint32 base_fee_change_denominator = 2;
// elasticity multiplier bounds the maximum gas limit an EIP-1559 block may
// have.
uint32 elasticity_multiplier = 3;
// initial base fee for EIP-1559 blocks.
int64 initial_base_fee = 4;
// height at which the base fee calculation is enabled.
int64 enable_height = 5;
}

View File

@ -0,0 +1,22 @@
syntax = "proto3";
package ethermint.feemarket.v1;
import "gogoproto/gogo.proto";
import "ethermint/feemarket/v1/feemarket.proto";
option go_package = "github.com/tharsis/ethermint/x/feemarket/types";
// GenesisState defines the feemarket module's genesis state.
message GenesisState {
// params defines all the paramaters of the module.
Params params = 1 [ (gogoproto.nullable) = false ];
// base fee is the exported value from previous software version.
// Zero by default.
string base_fee = 2 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.nullable) = false
];
// block gas is the amount of gas used on the last block before the upgrade.
// Zero by default.
uint64 block_gas = 3;
}

View File

@ -0,0 +1,53 @@
syntax = "proto3";
package ethermint.feemarket.v1;
import "gogoproto/gogo.proto";
// import "cosmos/base/query/v1beta1/pagination.proto";
import "google/api/annotations.proto";
import "ethermint/feemarket/v1/feemarket.proto";
option go_package = "github.com/tharsis/ethermint/x/feemarket/types";
// Query defines the gRPC querier service.
service Query {
// Params queries the parameters of x/feemarket module.
rpc Params(QueryParamsRequest) returns (QueryParamsResponse) {
option (google.api.http).get = "/feemarket/evm/v1/params";
}
// BaseFee queries the base fee of the parent block of the current block.
rpc BaseFee(QueryBaseFeeRequest) returns (QueryBaseFeeResponse) {
option (google.api.http).get = "/feemarket/evm/v1/base_fee";
}
// BlockGas queries the gas used at a given block height
rpc BlockGas(QueryBlockGasRequest) returns (QueryBlockGasResponse) {
option (google.api.http).get = "/feemarket/evm/v1/block_gas";
}
}
// QueryParamsRequest defines the request type for querying x/evm parameters.
message QueryParamsRequest {}
// QueryParamsResponse defines the response type for querying x/evm parameters.
message QueryParamsResponse {
// params define the evm module parameters.
Params params = 1 [ (gogoproto.nullable) = false ];
}
// QueryBaseFeeRequest defines the request type for querying the EIP1559 base
// fee.
message QueryBaseFeeRequest {}
// BaseFeeResponse returns the EIP1559 base fee.
message QueryBaseFeeResponse {
string base_fee = 1
[ (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int" ];
}
// QueryBlockGasRequest defines the request type for querying the EIP1559 base
// fee.
message QueryBlockGasRequest {}
// QueryBlockGasResponse returns block gas used for a given height.
message QueryBlockGasResponse { int64 gas = 1; }

View File

@ -0,0 +1,25 @@
syntax = "proto3";
package ethermint.types.v1;
import "cosmos/auth/v1beta1/auth.proto";
import "cosmos_proto/cosmos.proto";
import "gogoproto/gogo.proto";
option go_package = "github.com/tharsis/ethermint/types";
// EthAccount implements the authtypes.AccountI interface and embeds an
// authtypes.BaseAccount type. It is compatible with the auth AccountKeeper.
message EthAccount {
option (gogoproto.goproto_getters) = false;
option (gogoproto.goproto_stringer) = false;
option (gogoproto.equal) = false;
option (cosmos_proto.implements_interface) =
"github.com/cosmos/cosmos-sdk/x/auth/types.AccountI";
cosmos.auth.v1beta1.BaseAccount base_account = 1 [
(gogoproto.embed) = true,
(gogoproto.moretags) = "yaml:\"base_account\""
];
string code_hash = 2 [ (gogoproto.moretags) = "yaml:\"code_hash\"" ];
}

View File

@ -0,0 +1,25 @@
syntax = "proto3";
package ethermint.types.v1;
import "gogoproto/gogo.proto";
option go_package = "github.com/tharsis/ethermint/types";
message ExtensionOptionsWeb3Tx {
option (gogoproto.goproto_getters) = false;
// typed data chain id used only in EIP712 Domain and should match
// Ethereum network ID in a Web3 provider (e.g. Metamask).
uint64 typed_data_chain_id = 1 [
(gogoproto.jsontag) = "typedDataChainID,omitempty",
(gogoproto.customname) = "TypedDataChainID"
];
// fee payer is an account address for the fee payer. It will be validated
// during EIP712 signature checking.
string fee_payer = 2 [ (gogoproto.jsontag) = "feePayer,omitempty" ];
// fee payer sig is a signature data from the fee paying account,
// allows to perform fee delegation when using EIP712 Domain.
bytes fee_payer_sig = 3 [ (gogoproto.jsontag) = "feePayerSig,omitempty" ];
}

View File

@ -0,0 +1,15 @@
syntax = "proto3";
package ibc.applications.interchain_accounts.controller.v1;
option go_package = "github.com/cosmos/ibc-go/v3/modules/apps/27-interchain-accounts/controller/types";
import "google/protobuf/any.proto";
import "gogoproto/gogo.proto";
// Params defines the set of on-chain interchain accounts parameters.
// The following parameters may be used to disable the controller submodule.
message Params {
// controller_enabled enables or disables the controller submodule.
bool controller_enabled = 1 [(gogoproto.moretags) = "yaml:\"controller_enabled\""];
}

View File

@ -0,0 +1,26 @@
syntax = "proto3";
package ibc.applications.interchain_accounts.controller.v1;
option go_package = "github.com/cosmos/ibc-go/v3/modules/apps/27-interchain-accounts/controller/types";
import "gogoproto/gogo.proto";
import "ibc/applications/interchain_accounts/controller/v1/controller.proto";
import "google/api/annotations.proto";
// Query provides defines the gRPC querier service.
service Query {
// Params queries all parameters of the ICA controller submodule.
rpc Params(QueryParamsRequest) returns (QueryParamsResponse) {
option (google.api.http).get = "/ibc/apps/interchain_accounts/controller/v1/params";
}
}
// QueryParamsRequest is the request type for the Query/Params RPC method.
message QueryParamsRequest {}
// QueryParamsResponse is the response type for the Query/Params RPC method.
message QueryParamsResponse {
// params defines the parameters of the module.
Params params = 1;
}

View File

@ -0,0 +1,17 @@
syntax = "proto3";
package ibc.applications.interchain_accounts.host.v1;
option go_package = "github.com/cosmos/ibc-go/v3/modules/apps/27-interchain-accounts/host/types";
import "google/protobuf/any.proto";
import "gogoproto/gogo.proto";
// Params defines the set of on-chain interchain accounts parameters.
// The following parameters may be used to disable the host submodule.
message Params {
// host_enabled enables or disables the host submodule.
bool host_enabled = 1 [(gogoproto.moretags) = "yaml:\"host_enabled\""];
// allow_messages defines a list of sdk message typeURLs allowed to be executed on a host chain.
repeated string allow_messages = 2 [(gogoproto.moretags) = "yaml:\"allow_messages\""];
}

View File

@ -0,0 +1,26 @@
syntax = "proto3";
package ibc.applications.interchain_accounts.host.v1;
option go_package = "github.com/cosmos/ibc-go/v3/modules/apps/27-interchain-accounts/host/types";
import "google/api/annotations.proto";
import "gogoproto/gogo.proto";
import "ibc/applications/interchain_accounts/host/v1/host.proto";
// Query provides defines the gRPC querier service.
service Query {
// Params queries all parameters of the ICA host submodule.
rpc Params(QueryParamsRequest) returns (QueryParamsResponse) {
option (google.api.http).get = "/ibc/apps/interchain_accounts/host/v1/params";
}
}
// QueryParamsRequest is the request type for the Query/Params RPC method.
message QueryParamsRequest {}
// QueryParamsResponse is the response type for the Query/Params RPC method.
message QueryParamsResponse {
// params defines the parameters of the module.
Params params = 1;
}

View File

@ -0,0 +1,20 @@
syntax = "proto3";
package ibc.applications.interchain_accounts.v1;
option go_package = "github.com/cosmos/ibc-go/v3/modules/apps/27-interchain-accounts/types";
import "cosmos_proto/cosmos.proto";
import "gogoproto/gogo.proto";
import "cosmos/auth/v1beta1/auth.proto";
// An InterchainAccount is defined as a BaseAccount & the address of the account owner on the controller chain
message InterchainAccount {
option (gogoproto.goproto_getters) = false;
option (gogoproto.goproto_stringer) = false;
option (cosmos_proto.implements_interface) = "InterchainAccountI";
cosmos.auth.v1beta1.BaseAccount base_account = 1
[(gogoproto.embed) = true, (gogoproto.moretags) = "yaml:\"base_account\""];
string account_owner = 2 [(gogoproto.moretags) = "yaml:\"account_owner\""];
}

View File

@ -0,0 +1,49 @@
syntax = "proto3";
package ibc.applications.interchain_accounts.v1;
option go_package = "github.com/cosmos/ibc-go/v3/modules/apps/27-interchain-accounts/types";
import "gogoproto/gogo.proto";
import "ibc/applications/interchain_accounts/controller/v1/controller.proto";
import "ibc/applications/interchain_accounts/host/v1/host.proto";
// GenesisState defines the interchain accounts genesis state
message GenesisState {
ControllerGenesisState controller_genesis_state = 1
[(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"controller_genesis_state\""];
HostGenesisState host_genesis_state = 2
[(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"host_genesis_state\""];
}
// ControllerGenesisState defines the interchain accounts controller genesis state
message ControllerGenesisState {
repeated ActiveChannel active_channels = 1
[(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"active_channels\""];
repeated RegisteredInterchainAccount interchain_accounts = 2
[(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"interchain_accounts\""];
repeated string ports = 3;
ibc.applications.interchain_accounts.controller.v1.Params params = 4 [(gogoproto.nullable) = false];
}
// HostGenesisState defines the interchain accounts host genesis state
message HostGenesisState {
repeated ActiveChannel active_channels = 1
[(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"active_channels\""];
repeated RegisteredInterchainAccount interchain_accounts = 2
[(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"interchain_accounts\""];
string port = 3;
ibc.applications.interchain_accounts.host.v1.Params params = 4 [(gogoproto.nullable) = false];
}
// ActiveChannel contains a pairing of port ID and channel ID for an active interchain accounts channel
message ActiveChannel {
string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""];
string channel_id = 2 [(gogoproto.moretags) = "yaml:\"channel_id\""];
}
// RegisteredInterchainAccount contains a pairing of controller port ID and associated interchain account address
message RegisteredInterchainAccount {
string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""];
string account_address = 2 [(gogoproto.moretags) = "yaml:\"account_address\""];
}

View File

@ -0,0 +1,31 @@
syntax = "proto3";
package ibc.applications.interchain_accounts.v1;
option go_package = "github.com/cosmos/ibc-go/v3/modules/apps/27-interchain-accounts/types";
import "google/protobuf/any.proto";
import "gogoproto/gogo.proto";
// Type defines a classification of message issued from a controller chain to its associated interchain accounts
// host
enum Type {
option (gogoproto.goproto_enum_prefix) = false;
// Default zero value enumeration
TYPE_UNSPECIFIED = 0 [(gogoproto.enumvalue_customname) = "UNSPECIFIED"];
// Execute a transaction on an interchain accounts host chain
TYPE_EXECUTE_TX = 1 [(gogoproto.enumvalue_customname) = "EXECUTE_TX"];
}
// InterchainAccountPacketData is comprised of a raw transaction, type of transaction and optional memo field.
message InterchainAccountPacketData {
Type type = 1;
bytes data = 2;
string memo = 3;
}
// CosmosTx contains a list of sdk.Msg's. It should be used when sending transactions to an SDK host chain.
message CosmosTx {
repeated google.protobuf.Any messages = 1;
}

View File

@ -2,7 +2,7 @@ syntax = "proto3";
package ibc.applications.transfer.v1;
option go_package = "github.com/cosmos/ibc-go/modules/apps/transfer/types";
option go_package = "github.com/cosmos/ibc-go/v3/modules/apps/transfer/types";
import "ibc/applications/transfer/v1/transfer.proto";
import "gogoproto/gogo.proto";

View File

@ -7,7 +7,7 @@ import "cosmos/base/query/v1beta1/pagination.proto";
import "ibc/applications/transfer/v1/transfer.proto";
import "google/api/annotations.proto";
option go_package = "github.com/cosmos/ibc-go/modules/apps/transfer/types";
option go_package = "github.com/cosmos/ibc-go/v3/modules/apps/transfer/types";
// Query provides defines the gRPC querier service.
service Query {

View File

@ -2,24 +2,10 @@ syntax = "proto3";
package ibc.applications.transfer.v1;
option go_package = "github.com/cosmos/ibc-go/modules/apps/transfer/types";
option go_package = "github.com/cosmos/ibc-go/v3/modules/apps/transfer/types";
import "gogoproto/gogo.proto";
// FungibleTokenPacketData defines a struct for the packet payload
// See FungibleTokenPacketData spec:
// https://github.com/cosmos/ics/tree/master/spec/ics-020-fungible-token-transfer#data-structures
message FungibleTokenPacketData {
// the token denomination to be transferred
string denom = 1;
// the token amount to be transferred
uint64 amount = 2;
// the sender address
string sender = 3;
// the recipient address on the destination chain
string receiver = 4;
}
// DenomTrace contains the base denomination for ICS20 fungible tokens and the
// source tracing information path.
message DenomTrace {

View File

@ -2,7 +2,7 @@ syntax = "proto3";
package ibc.applications.transfer.v1;
option go_package = "github.com/cosmos/ibc-go/modules/apps/transfer/types";
option go_package = "github.com/cosmos/ibc-go/v3/modules/apps/transfer/types";
import "gogoproto/gogo.proto";
import "cosmos/base/v1beta1/coin.proto";
@ -16,7 +16,7 @@ service Msg {
// MsgTransfer defines a msg to transfer fungible tokens (i.e Coins) between
// ICS20 enabled chains. See ICS Spec here:
// https://github.com/cosmos/ics/tree/master/spec/ics-020-fungible-token-transfer#data-structures
// https://github.com/cosmos/ibc/tree/master/spec/app/ics-020-fungible-token-transfer#data-structures
message MsgTransfer {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;

View File

@ -0,0 +1,19 @@
syntax = "proto3";
package ibc.applications.transfer.v2;
option go_package = "github.com/cosmos/ibc-go/v3/modules/apps/transfer/types";
// FungibleTokenPacketData defines a struct for the packet payload
// See FungibleTokenPacketData spec:
// https://github.com/cosmos/ibc/tree/master/spec/app/ics-020-fungible-token-transfer#data-structures
message FungibleTokenPacketData {
// the token denomination to be transferred
string denom = 1;
// the token amount to be transferred
string amount = 2;
// the sender address
string sender = 3;
// the recipient address on the destination chain
string receiver = 4;
}

View File

@ -2,7 +2,7 @@ syntax = "proto3";
package ibc.core.channel.v1;
option go_package = "github.com/cosmos/ibc-go/modules/core/04-channel/types";
option go_package = "github.com/cosmos/ibc-go/v3/modules/core/04-channel/types";
import "gogoproto/gogo.proto";
import "ibc/core/client/v1/client.proto";
@ -138,7 +138,7 @@ message PacketState {
// conflicts with other protobuf message formats used for acknowledgements.
// The first byte of any message with this format will be the non-ASCII values
// `0xaa` (result) or `0xb2` (error). Implemented as defined by ICS:
// https://github.com/cosmos/ics/tree/master/spec/ics-004-channel-and-packet-semantics#acknowledgement-envelope
// https://github.com/cosmos/ibc/tree/master/spec/core/ics-004-channel-and-packet-semantics#acknowledgement-envelope
message Acknowledgement {
// response contains either a result or an error and must be non-empty
oneof response {

View File

@ -2,7 +2,7 @@ syntax = "proto3";
package ibc.core.channel.v1;
option go_package = "github.com/cosmos/ibc-go/modules/core/04-channel/types";
option go_package = "github.com/cosmos/ibc-go/v3/modules/core/04-channel/types";
import "gogoproto/gogo.proto";
import "ibc/core/channel/v1/channel.proto";

View File

@ -2,7 +2,7 @@ syntax = "proto3";
package ibc.core.channel.v1;
option go_package = "github.com/cosmos/ibc-go/modules/core/04-channel/types";
option go_package = "github.com/cosmos/ibc-go/v3/modules/core/04-channel/types";
import "ibc/core/client/v1/client.proto";
import "cosmos/base/query/v1beta1/pagination.proto";

View File

@ -2,7 +2,7 @@ syntax = "proto3";
package ibc.core.channel.v1;
option go_package = "github.com/cosmos/ibc-go/modules/core/04-channel/types";
option go_package = "github.com/cosmos/ibc-go/v3/modules/core/04-channel/types";
import "gogoproto/gogo.proto";
import "ibc/core/client/v1/client.proto";
@ -57,7 +57,8 @@ message MsgChannelOpenInit {
message MsgChannelOpenInitResponse {}
// MsgChannelOpenInit defines a msg sent by a Relayer to try to open a channel
// on Chain B.
// on Chain B. The version field within the Channel field has been deprecated. Its
// value will be ignored by core IBC.
message MsgChannelOpenTry {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;
@ -65,7 +66,8 @@ message MsgChannelOpenTry {
string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""];
// in the case of crossing hello's, when both chains call OpenInit, we need
// the channel identifier of the previous channel in state INIT
string previous_channel_id = 2 [(gogoproto.moretags) = "yaml:\"previous_channel_id\""];
string previous_channel_id = 2 [(gogoproto.moretags) = "yaml:\"previous_channel_id\""];
// NOTE: the version field within the channel has been deprecated. Its value will be ignored by core IBC.
Channel channel = 3 [(gogoproto.nullable) = false];
string counterparty_version = 4 [(gogoproto.moretags) = "yaml:\"counterparty_version\""];
bytes proof_init = 5 [(gogoproto.moretags) = "yaml:\"proof_init\""];

View File

@ -2,7 +2,7 @@ syntax = "proto3";
package ibc.core.client.v1;
option go_package = "github.com/cosmos/ibc-go/modules/core/02-client/types";
option go_package = "github.com/cosmos/ibc-go/v3/modules/core/02-client/types";
import "gogoproto/gogo.proto";
import "google/protobuf/any.proto";

View File

@ -2,7 +2,7 @@ syntax = "proto3";
package ibc.core.client.v1;
option go_package = "github.com/cosmos/ibc-go/modules/core/02-client/types";
option go_package = "github.com/cosmos/ibc-go/v3/modules/core/02-client/types";
import "ibc/core/client/v1/client.proto";
import "gogoproto/gogo.proto";

View File

@ -2,7 +2,7 @@ syntax = "proto3";
package ibc.core.client.v1;
option go_package = "github.com/cosmos/ibc-go/modules/core/02-client/types";
option go_package = "github.com/cosmos/ibc-go/v3/modules/core/02-client/types";
import "cosmos/base/query/v1beta1/pagination.proto";
import "ibc/core/client/v1/client.proto";

View File

@ -2,7 +2,7 @@ syntax = "proto3";
package ibc.core.client.v1;
option go_package = "github.com/cosmos/ibc-go/modules/core/02-client/types";
option go_package = "github.com/cosmos/ibc-go/v3/modules/core/02-client/types";
import "gogoproto/gogo.proto";
import "google/protobuf/any.proto";

View File

@ -2,7 +2,7 @@ syntax = "proto3";
package ibc.core.commitment.v1;
option go_package = "github.com/cosmos/ibc-go/modules/core/23-commitment/types";
option go_package = "github.com/cosmos/ibc-go/v3/modules/core/23-commitment/types";
import "gogoproto/gogo.proto";
import "proofs.proto";

View File

@ -2,13 +2,13 @@ syntax = "proto3";
package ibc.core.connection.v1;
option go_package = "github.com/cosmos/ibc-go/modules/core/03-connection/types";
option go_package = "github.com/cosmos/ibc-go/v3/modules/core/03-connection/types";
import "gogoproto/gogo.proto";
import "ibc/core/commitment/v1/commitment.proto";
// ICS03 - Connection Data Structures as defined in
// https://github.com/cosmos/ics/tree/master/spec/ics-003-connection-semantics#data-structures
// https://github.com/cosmos/ibc/blob/master/spec/core/ics-003-connection-semantics#data-structures
// ConnectionEnd defines a stateful object on a chain connected to another
// separate one.

View File

@ -2,7 +2,7 @@ syntax = "proto3";
package ibc.core.connection.v1;
option go_package = "github.com/cosmos/ibc-go/modules/core/03-connection/types";
option go_package = "github.com/cosmos/ibc-go/v3/modules/core/03-connection/types";
import "gogoproto/gogo.proto";
import "ibc/core/connection/v1/connection.proto";

View File

@ -2,7 +2,7 @@ syntax = "proto3";
package ibc.core.connection.v1;
option go_package = "github.com/cosmos/ibc-go/modules/core/03-connection/types";
option go_package = "github.com/cosmos/ibc-go/v3/modules/core/03-connection/types";
import "gogoproto/gogo.proto";
import "cosmos/base/query/v1beta1/pagination.proto";

View File

@ -2,7 +2,7 @@ syntax = "proto3";
package ibc.core.connection.v1;
option go_package = "github.com/cosmos/ibc-go/modules/core/03-connection/types";
option go_package = "github.com/cosmos/ibc-go/v3/modules/core/03-connection/types";
import "gogoproto/gogo.proto";
import "google/protobuf/any.proto";

View File

@ -2,7 +2,7 @@ syntax = "proto3";
package ibc.core.types.v1;
option go_package = "github.com/cosmos/ibc-go/modules/core/types";
option go_package = "github.com/cosmos/ibc-go/v3/modules/core/types";
import "gogoproto/gogo.proto";
import "ibc/core/client/v1/genesis.proto";

View File

@ -2,7 +2,7 @@ syntax = "proto3";
package ibc.lightclients.localhost.v1;
option go_package = "github.com/cosmos/ibc-go/modules/light-clients/09-localhost/types";
option go_package = "github.com/cosmos/ibc-go/v3/modules/light-clients/09-localhost/types";
import "gogoproto/gogo.proto";
import "ibc/core/client/v1/client.proto";

View File

@ -2,7 +2,7 @@ syntax = "proto3";
package ibc.lightclients.solomachine.v1;
option go_package = "github.com/cosmos/ibc-go/modules/core/02-client/legacy/v100";
option go_package = "github.com/cosmos/ibc-go/v3/modules/core/02-client/legacy/v100";
import "ibc/core/connection/v1/connection.proto";
import "ibc/core/channel/v1/channel.proto";

View File

@ -2,7 +2,7 @@ syntax = "proto3";
package ibc.lightclients.solomachine.v2;
option go_package = "github.com/cosmos/ibc-go/modules/light-clients/06-solomachine/types";
option go_package = "github.com/cosmos/ibc-go/v3/modules/light-clients/06-solomachine/types";
import "ibc/core/connection/v1/connection.proto";
import "ibc/core/channel/v1/channel.proto";

View File

@ -2,7 +2,7 @@ syntax = "proto3";
package ibc.lightclients.tendermint.v1;
option go_package = "github.com/cosmos/ibc-go/modules/light-clients/07-tendermint/types";
option go_package = "github.com/cosmos/ibc-go/v3/modules/light-clients/07-tendermint/types";
import "tendermint/types/validator.proto";
import "tendermint/types/types.proto";

View File

@ -41,7 +41,7 @@ type liquidationTracker struct {
func (suite *SeizeTestSuite) SetupTest() {
tApp := app.NewTestApp()
ctx := tApp.NewContext(true, tmproto.Header{Height: 1, Time: tmtime.Now()})
ctx := tApp.NewContext(true, tmproto.Header{Height: 1, Time: tmtime.Now(), ChainID: "kavatest_1-1"})
tracker := liquidationTracker{}
coins := cs(c("btc", 100000000), c("xrp", 10000000000))
_, addrs := app.GeneratePrivKeyAddressPairs(100)

27
x/evmutil/genesis.go Normal file
View File

@ -0,0 +1,27 @@
package evmutil
import (
"fmt"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/kava-labs/kava/x/evmutil/keeper"
"github.com/kava-labs/kava/x/evmutil/types"
)
// InitGenesis initializes the store state from a genesis state.
func InitGenesis(ctx sdk.Context, keeper keeper.Keeper, gs *types.GenesisState) {
if err := gs.Validate(); err != nil {
panic(fmt.Sprintf("failed to validate %s genesis state: %s", types.ModuleName, err))
}
for _, account := range gs.Accounts {
keeper.SetAccount(ctx, account)
}
}
// ExportGenesis returns a GenesisState for a given context and keeper.
func ExportGenesis(ctx sdk.Context, keeper keeper.Keeper) *types.GenesisState {
accounts := keeper.GetAllAccounts(ctx)
return types.NewGenesisState(accounts)
}

59
x/evmutil/genesis_test.go Normal file
View File

@ -0,0 +1,59 @@
package evmutil_test
import (
"testing"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/stretchr/testify/suite"
"github.com/kava-labs/kava/x/evmutil"
"github.com/kava-labs/kava/x/evmutil/testutil"
"github.com/kava-labs/kava/x/evmutil/types"
)
type genesisTestSuite struct {
testutil.Suite
}
func (suite *genesisTestSuite) SetupTest() {
suite.Suite.SetupTest()
}
func (s *genesisTestSuite) TestInitGenesis_SetAccounts() {
gs := types.NewGenesisState([]types.Account{
{Address: s.Addrs[0], Balance: sdk.NewInt(100)},
})
accounts := s.Keeper.GetAllAccounts(s.Ctx)
s.Require().Len(accounts, 0)
evmutil.InitGenesis(s.Ctx, s.Keeper, gs)
accounts = s.Keeper.GetAllAccounts(s.Ctx)
s.Require().Len(accounts, 1)
account := s.Keeper.GetAccount(s.Ctx, s.Addrs[0])
s.Require().Equal(account.Address, s.Addrs[0])
s.Require().Equal(account.Balance, sdk.NewInt(100))
}
func (s *genesisTestSuite) TestInitGenesis_ValidateFail() {
gs := types.NewGenesisState([]types.Account{
{Address: s.Addrs[0], Balance: sdk.NewInt(-100)},
})
s.Require().Panics(func() {
evmutil.InitGenesis(s.Ctx, s.Keeper, gs)
})
}
func (s *genesisTestSuite) TestExportGenesis() {
accounts := []types.Account{
{Address: s.Addrs[0], Balance: sdk.NewInt(10)},
{Address: s.Addrs[1], Balance: sdk.NewInt(20)},
}
for _, account := range accounts {
s.Keeper.SetAccount(s.Ctx, account)
}
gs := evmutil.ExportGenesis(s.Ctx, s.Keeper)
s.Require().Equal(gs.Accounts, accounts)
}
func TestGenesisTestSuite(t *testing.T) {
suite.Run(t, new(genesisTestSuite))
}

View File

@ -0,0 +1,261 @@
package keeper
import (
"fmt"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
evmtypes "github.com/tharsis/ethermint/x/evm/types"
"github.com/kava-labs/kava/x/evmutil/types"
)
const (
// EvmDenom is the gas denom used by the evm
EvmDenom = "akava"
// CosmosDenom is the gas denom used by the kava app
CosmosDenom = "ukava"
)
// ConversionMultiplier is the conversion multiplier between akava and ukava
var ConversionMultiplier = sdk.NewInt(1_000_000_000_000)
var _ evmtypes.BankKeeper = EvmBankKeeper{}
// EvmBankKeeper is a BankKeeper wrapper for the x/evm module to allow the use
// of the 18 decimal akava coin on the evm.
// x/evm consumes gas and send coins by minting and burning akava coins in its module
// account and then sending the funds to the target account.
// This keeper uses both the ukava coin and a separate akava balance to manage the
// extra percision needed by the evm.
type EvmBankKeeper struct {
akavaKeeper Keeper
bk types.BankKeeper
ak types.AccountKeeper
}
func NewEvmBankKeeper(akavaKeeper Keeper, bk types.BankKeeper, ak types.AccountKeeper) EvmBankKeeper {
return EvmBankKeeper{
akavaKeeper: akavaKeeper,
bk: bk,
ak: ak,
}
}
// GetBalance returns the total **spendable** balance of akava for a given account by address.
func (k EvmBankKeeper) GetBalance(ctx sdk.Context, addr sdk.AccAddress, denom string) sdk.Coin {
if denom != EvmDenom {
panic(fmt.Errorf("only evm denom %s is supported by EvmBankKeeper", EvmDenom))
}
spendableCoins := k.bk.SpendableCoins(ctx, addr)
ukava := spendableCoins.AmountOf(CosmosDenom)
akava := k.akavaKeeper.GetBalance(ctx, addr)
total := ukava.Mul(ConversionMultiplier).Add(akava)
return sdk.NewCoin(EvmDenom, total)
}
// SendCoinsFromModuleToAccount transfers akava coins from a ModuleAccount to an AccAddress.
// It will panic if the module account does not exist. An error is returned if the recipient
// address is black-listed or if sending the tokens fails.
func (k EvmBankKeeper) SendCoinsFromModuleToAccount(ctx sdk.Context, senderModule string, recipientAddr sdk.AccAddress, amt sdk.Coins) error {
ukava, akava, err := SplitAkavaCoins(amt)
if err != nil {
return err
}
if ukava.Amount.IsPositive() {
if err := k.bk.SendCoinsFromModuleToAccount(ctx, senderModule, recipientAddr, sdk.NewCoins(ukava)); err != nil {
return err
}
}
senderAddr := k.GetModuleAddress(senderModule)
if err := k.ConvertOneUkavaToAkavaIfNeeded(ctx, senderAddr, akava); err != nil {
return err
}
if err := k.akavaKeeper.SendBalance(ctx, senderAddr, recipientAddr, akava); err != nil {
return err
}
return k.ConvertAkavaToUkava(ctx, recipientAddr)
}
// SendCoinsFromAccountToModule transfers akava coins from an AccAddress to a ModuleAccount.
// It will panic if the module account does not exist.
func (k EvmBankKeeper) SendCoinsFromAccountToModule(ctx sdk.Context, senderAddr sdk.AccAddress, recipientModule string, amt sdk.Coins) error {
ukava, akavaNeeded, err := SplitAkavaCoins(amt)
if err != nil {
return err
}
if ukava.IsPositive() {
if err := k.bk.SendCoinsFromAccountToModule(ctx, senderAddr, recipientModule, sdk.NewCoins(ukava)); err != nil {
return err
}
}
if err := k.ConvertOneUkavaToAkavaIfNeeded(ctx, senderAddr, akavaNeeded); err != nil {
return err
}
recipientAddr := k.GetModuleAddress(recipientModule)
if err := k.akavaKeeper.SendBalance(ctx, senderAddr, recipientAddr, akavaNeeded); err != nil {
return err
}
return k.ConvertAkavaToUkava(ctx, recipientAddr)
}
// MintCoins mints akava coins by minting the equivalent ukava coins and any remaining akava coins.
// It will panic if the module account does not exist or is unauthorized.
func (k EvmBankKeeper) MintCoins(ctx sdk.Context, moduleName string, amt sdk.Coins) error {
ukava, akava, err := SplitAkavaCoins(amt)
if err != nil {
return err
}
if ukava.IsPositive() {
if err := k.bk.MintCoins(ctx, moduleName, sdk.NewCoins(ukava)); err != nil {
return err
}
}
recipientAddr := k.GetModuleAddress(moduleName)
if err := k.akavaKeeper.AddBalance(ctx, recipientAddr, akava); err != nil {
return err
}
return k.ConvertAkavaToUkava(ctx, recipientAddr)
}
// BurnCoins burns akava coins by burning the equivalent ukava coins and any remaining akava coins.
// It will panic if the module account does not exist or is unauthorized.
func (k EvmBankKeeper) BurnCoins(ctx sdk.Context, moduleName string, amt sdk.Coins) error {
ukava, akava, err := SplitAkavaCoins(amt)
if err != nil {
return err
}
if ukava.IsPositive() {
if err := k.bk.BurnCoins(ctx, moduleName, sdk.NewCoins(ukava)); err != nil {
return err
}
}
moduleAddr := k.GetModuleAddress(moduleName)
if err := k.ConvertOneUkavaToAkavaIfNeeded(ctx, moduleAddr, akava); err != nil {
return err
}
return k.akavaKeeper.RemoveBalance(ctx, moduleAddr, akava)
}
// ConvertOneUkavaToAkavaIfNeeded converts 1 ukava to akava for an address if
// its akava balance is smaller than the akavaNeeded amount.
func (k EvmBankKeeper) ConvertOneUkavaToAkavaIfNeeded(ctx sdk.Context, addr sdk.AccAddress, akavaNeeded sdk.Int) error {
akavaBal := k.akavaKeeper.GetBalance(ctx, addr)
if akavaBal.GTE(akavaNeeded) {
return nil
}
ukavaToStore := sdk.NewCoins(sdk.NewCoin(CosmosDenom, sdk.OneInt()))
if err := k.bk.SendCoinsFromAccountToModule(ctx, addr, types.ModuleName, ukavaToStore); err != nil {
return err
}
// add 1ukava equivalent of akava to addr
akavaToReceive := ConversionMultiplier
if err := k.akavaKeeper.AddBalance(ctx, addr, akavaToReceive); err != nil {
return err
}
return nil
}
// ConvertAkavaToUkava converts all available akava to ukava for a given AccAddress.
func (k EvmBankKeeper) ConvertAkavaToUkava(ctx sdk.Context, addr sdk.AccAddress) error {
totalAkava := k.akavaKeeper.GetBalance(ctx, addr)
ukava, _, err := SplitAkavaCoins(sdk.NewCoins(sdk.NewCoin(EvmDenom, totalAkava)))
if err != nil {
return err
}
// do nothing if account does not have enough akava for a single ukava
ukavaToReceive := ukava.Amount
if !ukavaToReceive.IsPositive() {
return nil
}
// remove akava used for converting to ukava
akavaToBurn := ukavaToReceive.Mul(ConversionMultiplier)
finalBal := totalAkava.Sub(akavaToBurn)
if err := k.akavaKeeper.SetBalance(ctx, addr, finalBal); err != nil {
return err
}
fromAddr := k.GetModuleAddress(types.ModuleName)
if err := k.bk.SendCoins(ctx, fromAddr, addr, sdk.NewCoins(ukava)); err != nil {
return err
}
return nil
}
func (k EvmBankKeeper) GetModuleAddress(moduleName string) sdk.AccAddress {
addr := k.ak.GetModuleAddress(moduleName)
if addr == nil {
panic(sdkerrors.Wrapf(sdkerrors.ErrUnknownAddress, "module account %s does not exist", moduleName))
}
return addr
}
// SplitAkavaCoins splits akava coins to the equivalent ukava coins and any remaining akava balance.
// An error will be returned if the coins are not valid or if the coins are not the akava denom.
func SplitAkavaCoins(coins sdk.Coins) (sdk.Coin, sdk.Int, error) {
akava := sdk.ZeroInt()
ukava := sdk.NewCoin(CosmosDenom, sdk.ZeroInt())
if len(coins) == 0 {
return ukava, akava, nil
}
if err := ValidateEvmCoins(coins); err != nil {
return ukava, akava, err
}
// note: we should always have len(coins) == 1 here since coins cannot have dup denoms after we validate.
coin := coins[0]
remainingBalance := coin.Amount.Mod(ConversionMultiplier)
if remainingBalance.IsPositive() {
akava = remainingBalance
}
ukavaAmount := coin.Amount.Quo(ConversionMultiplier)
if ukavaAmount.IsPositive() {
ukava = sdk.NewCoin(CosmosDenom, ukavaAmount)
}
return ukava, akava, nil
}
// ValidateEvmCoins validates the coins from evm is valid and is the EvmDenom (akava).
func ValidateEvmCoins(coins sdk.Coins) error {
if len(coins) == 0 {
return nil
}
// validate that coins are non-negative, sorted, and no dup denoms
if err := coins.Validate(); err != nil {
return sdkerrors.Wrap(sdkerrors.ErrInvalidCoins, coins.String())
}
// validate that coin denom is akava
if len(coins) != 1 || coins[0].Denom != EvmDenom {
errMsg := fmt.Sprintf("invalid evm coin denom, only %s is supported", EvmDenom)
return sdkerrors.Wrap(sdkerrors.ErrInvalidCoins, errMsg)
}
return nil
}

View File

@ -0,0 +1,797 @@
package keeper_test
import (
"testing"
"time"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/stretchr/testify/suite"
tmtime "github.com/tendermint/tendermint/types/time"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
vesting "github.com/cosmos/cosmos-sdk/x/auth/vesting/types"
evmtypes "github.com/tharsis/ethermint/x/evm/types"
"github.com/kava-labs/kava/x/evmutil/keeper"
"github.com/kava-labs/kava/x/evmutil/testutil"
"github.com/kava-labs/kava/x/evmutil/types"
)
type evmBankKeeperTestSuite struct {
testutil.Suite
}
func (suite *evmBankKeeperTestSuite) SetupTest() {
suite.Suite.SetupTest()
}
func (suite *evmBankKeeperTestSuite) TestGetBalance_ReturnsSpendable() {
startingCoins := sdk.NewCoins(sdk.NewInt64Coin("ukava", 10))
startingAkava := sdk.NewInt(100)
now := tmtime.Now()
endTime := now.Add(24 * time.Hour)
bacc := authtypes.NewBaseAccountWithAddress(suite.Addrs[0])
vacc := vesting.NewContinuousVestingAccount(bacc, startingCoins, now.Unix(), endTime.Unix())
suite.AccountKeeper.SetAccount(suite.Ctx, vacc)
err := suite.App.FundAccount(suite.Ctx, suite.Addrs[0], startingCoins)
suite.Require().NoError(err)
err = suite.Keeper.SetBalance(suite.Ctx, suite.Addrs[0], startingAkava)
suite.Require().NoError(err)
coin := suite.EvmBankKeeper.GetBalance(suite.Ctx, suite.Addrs[0], "akava")
suite.Require().Equal(startingAkava, coin.Amount)
ctx := suite.Ctx.WithBlockTime(now.Add(12 * time.Hour))
coin = suite.EvmBankKeeper.GetBalance(ctx, suite.Addrs[0], "akava")
suite.Require().Equal(sdk.NewIntFromUint64(5_000_000_000_100), coin.Amount)
}
func (suite *evmBankKeeperTestSuite) TestGetBalance_NotEvmDenom() {
suite.Require().Panics(func() {
suite.EvmBankKeeper.GetBalance(suite.Ctx, suite.Addrs[0], "ukava")
})
suite.Require().Panics(func() {
suite.EvmBankKeeper.GetBalance(suite.Ctx, suite.Addrs[0], "busd")
})
}
func (suite *evmBankKeeperTestSuite) TestGetBalance() {
tests := []struct {
name string
startingAmount sdk.Coins
expAmount sdk.Int
}{
{
"ukava with akava",
sdk.NewCoins(
sdk.NewInt64Coin("akava", 100),
sdk.NewInt64Coin("ukava", 10),
),
sdk.NewInt(10_000_000_000_100),
},
{
"just akava",
sdk.NewCoins(
sdk.NewInt64Coin("akava", 100),
sdk.NewInt64Coin("busd", 100),
),
sdk.NewInt(100),
},
{
"just ukava",
sdk.NewCoins(
sdk.NewInt64Coin("ukava", 10),
sdk.NewInt64Coin("busd", 100),
),
sdk.NewInt(10_000_000_000_000),
},
{
"no ukava or akava",
sdk.NewCoins(),
sdk.ZeroInt(),
},
{
"with avaka that is more than 1 ukava",
sdk.NewCoins(
sdk.NewInt64Coin("akava", 20_000_000_000_220),
sdk.NewInt64Coin("ukava", 11),
),
sdk.NewInt(31_000_000_000_220),
},
}
for _, tt := range tests {
suite.Run(tt.name, func() {
suite.SetupTest()
suite.FundAccountWithKava(suite.Addrs[0], tt.startingAmount)
coin := suite.EvmBankKeeper.GetBalance(suite.Ctx, suite.Addrs[0], "akava")
suite.Require().Equal(tt.expAmount, coin.Amount)
})
}
}
func (suite *evmBankKeeperTestSuite) TestSendCoinsFromModuleToAccount() {
startingModuleCoins := sdk.NewCoins(
sdk.NewInt64Coin("akava", 200),
sdk.NewInt64Coin("ukava", 100),
)
tests := []struct {
name string
sendCoins sdk.Coins
startingAccBal sdk.Coins
expAccBal sdk.Coins
hasErr bool
}{
{
"send more than 1 ukava",
sdk.NewCoins(sdk.NewInt64Coin("akava", 12_000_000_000_010)),
sdk.Coins{},
sdk.NewCoins(
sdk.NewInt64Coin("akava", 10),
sdk.NewInt64Coin("ukava", 12),
),
false,
},
{
"send less than 1 ukava",
sdk.NewCoins(sdk.NewInt64Coin("akava", 122)),
sdk.Coins{},
sdk.NewCoins(
sdk.NewInt64Coin("akava", 122),
sdk.NewInt64Coin("ukava", 0),
),
false,
},
{
"send an exact amount of ukava",
sdk.NewCoins(sdk.NewInt64Coin("akava", 98_000_000_000_000)),
sdk.Coins{},
sdk.NewCoins(
sdk.NewInt64Coin("akava", 00),
sdk.NewInt64Coin("ukava", 98),
),
false,
},
{
"send no akava",
sdk.NewCoins(sdk.NewInt64Coin("akava", 0)),
sdk.Coins{},
sdk.NewCoins(
sdk.NewInt64Coin("akava", 0),
sdk.NewInt64Coin("ukava", 0),
),
false,
},
{
"errors if sending other coins",
sdk.NewCoins(sdk.NewInt64Coin("akava", 500), sdk.NewInt64Coin("busd", 1000)),
sdk.Coins{},
sdk.Coins{},
true,
},
{
"errors if not enough total akava to cover",
sdk.NewCoins(sdk.NewInt64Coin("akava", 100_000_000_001_000)),
sdk.Coins{},
sdk.Coins{},
true,
},
{
"errors if not enough ukava to cover",
sdk.NewCoins(sdk.NewInt64Coin("akava", 200_000_000_000_000)),
sdk.Coins{},
sdk.Coins{},
true,
},
{
"converts receiver's akava to ukava if there's enough akava after the transfer",
sdk.NewCoins(sdk.NewInt64Coin("akava", 99_000_000_000_200)),
sdk.NewCoins(
sdk.NewInt64Coin("akava", 999_999_999_900),
sdk.NewInt64Coin("ukava", 1),
),
sdk.NewCoins(
sdk.NewInt64Coin("akava", 100),
sdk.NewInt64Coin("ukava", 101),
),
false,
},
{
"converts all of receiver's akava to ukava even if somehow receiver has more than 1ukava of akava",
sdk.NewCoins(sdk.NewInt64Coin("akava", 12_000_000_000_100)),
sdk.NewCoins(
sdk.NewInt64Coin("akava", 5_999_999_999_990),
sdk.NewInt64Coin("ukava", 1),
),
sdk.NewCoins(
sdk.NewInt64Coin("akava", 90),
sdk.NewInt64Coin("ukava", 19),
),
false,
},
{
"swap 1 ukava for akava if module account doesn't have enough akava",
sdk.NewCoins(sdk.NewInt64Coin("akava", 99_000_000_001_000)),
sdk.NewCoins(
sdk.NewInt64Coin("akava", 200),
sdk.NewInt64Coin("ukava", 1),
),
sdk.NewCoins(
sdk.NewInt64Coin("akava", 1200),
sdk.NewInt64Coin("ukava", 100),
),
false,
},
}
for _, tt := range tests {
suite.Run(tt.name, func() {
suite.SetupTest()
suite.FundAccountWithKava(suite.Addrs[0], tt.startingAccBal)
suite.FundModuleAccountWithKava(evmtypes.ModuleName, startingModuleCoins)
// fund our module with some ukava to account for converting extra akava back to ukava
suite.FundModuleAccountWithKava(types.ModuleName, sdk.NewCoins(sdk.NewInt64Coin("ukava", 10)))
err := suite.EvmBankKeeper.SendCoinsFromModuleToAccount(suite.Ctx, evmtypes.ModuleName, suite.Addrs[0], tt.sendCoins)
if tt.hasErr {
suite.Require().Error(err)
return
} else {
suite.Require().NoError(err)
}
// check ukava
ukavaSender := suite.BankKeeper.GetBalance(suite.Ctx, suite.Addrs[0], "ukava")
suite.Require().Equal(tt.expAccBal.AmountOf("ukava").Int64(), ukavaSender.Amount.Int64())
// check akava
actualAkava := suite.Keeper.GetBalance(suite.Ctx, suite.Addrs[0])
suite.Require().Equal(tt.expAccBal.AmountOf("akava").Int64(), actualAkava.Int64())
})
}
}
func (suite *evmBankKeeperTestSuite) TestSendCoinsFromAccountToModule() {
startingAccCoins := sdk.NewCoins(
sdk.NewInt64Coin("akava", 200),
sdk.NewInt64Coin("ukava", 100),
)
startingModuleCoins := sdk.NewCoins(
sdk.NewInt64Coin("akava", 100_000_000_000),
)
tests := []struct {
name string
sendCoins sdk.Coins
expSenderCoins sdk.Coins
expModuleCoins sdk.Coins
hasErr bool
}{
{
"send more than 1 ukava",
sdk.NewCoins(sdk.NewInt64Coin("akava", 12_000_000_000_010)),
sdk.NewCoins(sdk.NewInt64Coin("akava", 190), sdk.NewInt64Coin("ukava", 88)),
sdk.NewCoins(sdk.NewInt64Coin("akava", 100_000_000_010), sdk.NewInt64Coin("ukava", 12)),
false,
},
{
"send less than 1 ukava",
sdk.NewCoins(sdk.NewInt64Coin("akava", 122)),
sdk.NewCoins(sdk.NewInt64Coin("akava", 78), sdk.NewInt64Coin("ukava", 100)),
sdk.NewCoins(sdk.NewInt64Coin("akava", 100_000_000_122), sdk.NewInt64Coin("ukava", 0)),
false,
},
{
"send an exact amount of ukava",
sdk.NewCoins(sdk.NewInt64Coin("akava", 98_000_000_000_000)),
sdk.NewCoins(sdk.NewInt64Coin("akava", 200), sdk.NewInt64Coin("ukava", 2)),
sdk.NewCoins(sdk.NewInt64Coin("akava", 100_000_000_000), sdk.NewInt64Coin("ukava", 98)),
false,
},
{
"send no akava",
sdk.NewCoins(sdk.NewInt64Coin("akava", 0)),
sdk.NewCoins(sdk.NewInt64Coin("akava", 200), sdk.NewInt64Coin("ukava", 100)),
sdk.NewCoins(sdk.NewInt64Coin("akava", 100_000_000_000), sdk.NewInt64Coin("ukava", 0)),
false,
},
{
"errors if sending other coins",
sdk.NewCoins(sdk.NewInt64Coin("akava", 500), sdk.NewInt64Coin("busd", 1000)),
sdk.Coins{},
sdk.Coins{},
true,
},
{
"errors if have dup coins",
sdk.Coins{
sdk.NewInt64Coin("akava", 12_000_000_000_000),
sdk.NewInt64Coin("akava", 2_000_000_000_000),
},
sdk.Coins{},
sdk.Coins{},
true,
},
{
"errors if not enough total akava to cover",
sdk.NewCoins(sdk.NewInt64Coin("akava", 100_000_000_001_000)),
sdk.Coins{},
sdk.Coins{},
true,
},
{
"errors if not enough ukava to cover",
sdk.NewCoins(sdk.NewInt64Coin("akava", 200_000_000_000_000)),
sdk.Coins{},
sdk.Coins{},
true,
},
{
"converts 1 ukava to akava if not enough akava to cover",
sdk.NewCoins(sdk.NewInt64Coin("akava", 99_001_000_000_000)),
sdk.NewCoins(sdk.NewInt64Coin("akava", 999_000_000_200), sdk.NewInt64Coin("ukava", 0)),
sdk.NewCoins(sdk.NewInt64Coin("akava", 101_000_000_000), sdk.NewInt64Coin("ukava", 99)),
false,
},
{
"converts receiver's akava to ukava if there's enough akava after the transfer",
sdk.NewCoins(sdk.NewInt64Coin("akava", 5_900_000_000_200)),
sdk.NewCoins(sdk.NewInt64Coin("akava", 100_000_000_000), sdk.NewInt64Coin("ukava", 94)),
sdk.NewCoins(sdk.NewInt64Coin("akava", 200), sdk.NewInt64Coin("ukava", 6)),
false,
},
}
for _, tt := range tests {
suite.Run(tt.name, func() {
suite.SetupTest()
suite.FundAccountWithKava(suite.Addrs[0], startingAccCoins)
suite.FundModuleAccountWithKava(evmtypes.ModuleName, startingModuleCoins)
err := suite.EvmBankKeeper.SendCoinsFromAccountToModule(suite.Ctx, suite.Addrs[0], evmtypes.ModuleName, tt.sendCoins)
if tt.hasErr {
suite.Require().Error(err)
return
} else {
suite.Require().NoError(err)
}
// check sender balance
ukavaSender := suite.BankKeeper.GetBalance(suite.Ctx, suite.Addrs[0], "ukava")
suite.Require().Equal(tt.expSenderCoins.AmountOf("ukava").Int64(), ukavaSender.Amount.Int64())
actualAkava := suite.Keeper.GetBalance(suite.Ctx, suite.Addrs[0])
suite.Require().Equal(tt.expSenderCoins.AmountOf("akava").Int64(), actualAkava.Int64())
// check module balance
moduleAddr := suite.AccountKeeper.GetModuleAddress(evmtypes.ModuleName)
ukavaSender = suite.BankKeeper.GetBalance(suite.Ctx, moduleAddr, "ukava")
suite.Require().Equal(tt.expModuleCoins.AmountOf("ukava").Int64(), ukavaSender.Amount.Int64())
actualAkava = suite.Keeper.GetBalance(suite.Ctx, moduleAddr)
suite.Require().Equal(tt.expModuleCoins.AmountOf("akava").Int64(), actualAkava.Int64())
})
}
}
func (suite *evmBankKeeperTestSuite) TestBurnCoins() {
startingUkava := sdk.NewInt(100)
tests := []struct {
name string
burnCoins sdk.Coins
expUkava sdk.Int
expAkava sdk.Int
hasErr bool
akavaStart sdk.Int
}{
{
"burn more than 1 ukava",
sdk.NewCoins(sdk.NewInt64Coin("akava", 12_021_000_000_002)),
sdk.NewInt(88),
sdk.NewInt(100_000_000_000),
false,
sdk.NewInt(121_000_000_002),
},
{
"burn less than 1 ukava",
sdk.NewCoins(sdk.NewInt64Coin("akava", 122)),
sdk.NewInt(100),
sdk.NewInt(878),
false,
sdk.NewInt(1000),
},
{
"burn an exact amount of ukava",
sdk.NewCoins(sdk.NewInt64Coin("akava", 98_000_000_000_000)),
sdk.NewInt(2),
sdk.NewInt(10),
false,
sdk.NewInt(10),
},
{
"burn no akava",
sdk.NewCoins(sdk.NewInt64Coin("akava", 0)),
startingUkava,
sdk.ZeroInt(),
false,
sdk.ZeroInt(),
},
{
"errors if burning other coins",
sdk.NewCoins(sdk.NewInt64Coin("akava", 500), sdk.NewInt64Coin("busd", 1000)),
startingUkava,
sdk.NewInt(100),
true,
sdk.NewInt(100),
},
{
"errors if have dup coins",
sdk.Coins{
sdk.NewInt64Coin("akava", 12_000_000_000_000),
sdk.NewInt64Coin("akava", 2_000_000_000_000),
},
startingUkava,
sdk.ZeroInt(),
true,
sdk.ZeroInt(),
},
{
"errors if burn amount is negative",
sdk.Coins{sdk.Coin{Denom: "akava", Amount: sdk.NewInt(-100)}},
startingUkava,
sdk.NewInt(50),
true,
sdk.NewInt(50),
},
{
"errors if not enough akava to cover burn",
sdk.NewCoins(sdk.NewInt64Coin("akava", 100_999_000_000_000)),
sdk.NewInt(0),
sdk.NewInt(99_000_000_000),
true,
sdk.NewInt(99_000_000_000),
},
{
"errors if not enough ukava to cover burn",
sdk.NewCoins(sdk.NewInt64Coin("akava", 200_000_000_000_000)),
sdk.NewInt(100),
sdk.ZeroInt(),
true,
sdk.ZeroInt(),
},
{
"converts 1 ukava to akava if not enough akava to cover",
sdk.NewCoins(sdk.NewInt64Coin("akava", 12_021_000_000_002)),
sdk.NewInt(87),
sdk.NewInt(980_000_000_000),
false,
sdk.NewInt(1_000_000_002),
},
}
for _, tt := range tests {
suite.Run(tt.name, func() {
suite.SetupTest()
startingCoins := sdk.NewCoins(
sdk.NewCoin("ukava", startingUkava),
sdk.NewCoin("akava", tt.akavaStart),
)
suite.FundModuleAccountWithKava(evmtypes.ModuleName, startingCoins)
err := suite.EvmBankKeeper.BurnCoins(suite.Ctx, evmtypes.ModuleName, tt.burnCoins)
if tt.hasErr {
suite.Require().Error(err)
return
} else {
suite.Require().NoError(err)
}
// check ukava
ukavaActual := suite.BankKeeper.GetBalance(suite.Ctx, suite.EvmModuleAddr, "ukava")
suite.Require().Equal(tt.expUkava, ukavaActual.Amount)
// check akava
akavaActual := suite.Keeper.GetBalance(suite.Ctx, suite.EvmModuleAddr)
suite.Require().Equal(tt.expAkava, akavaActual)
})
}
}
func (suite *evmBankKeeperTestSuite) TestMintCoins() {
tests := []struct {
name string
mintCoins sdk.Coins
ukava sdk.Int
akava sdk.Int
hasErr bool
akavaStart sdk.Int
}{
{
"mint more than 1 ukava",
sdk.NewCoins(sdk.NewInt64Coin("akava", 12_021_000_000_002)),
sdk.NewInt(12),
sdk.NewInt(21_000_000_002),
false,
sdk.ZeroInt(),
},
{
"mint less than 1 ukava",
sdk.NewCoins(sdk.NewInt64Coin("akava", 901_000_000_001)),
sdk.ZeroInt(),
sdk.NewInt(901_000_000_001),
false,
sdk.ZeroInt(),
},
{
"mint an exact amount of ukava",
sdk.NewCoins(sdk.NewInt64Coin("akava", 123_000_000_000_000_000)),
sdk.NewInt(123_000),
sdk.ZeroInt(),
false,
sdk.ZeroInt(),
},
{
"mint no akava",
sdk.NewCoins(sdk.NewInt64Coin("akava", 0)),
sdk.ZeroInt(),
sdk.ZeroInt(),
false,
sdk.ZeroInt(),
},
{
"errors if minting other coins",
sdk.NewCoins(sdk.NewInt64Coin("akava", 500), sdk.NewInt64Coin("busd", 1000)),
sdk.ZeroInt(),
sdk.NewInt(100),
true,
sdk.NewInt(100),
},
{
"errors if have dup coins",
sdk.Coins{
sdk.NewInt64Coin("akava", 12_000_000_000_000),
sdk.NewInt64Coin("akava", 2_000_000_000_000),
},
sdk.ZeroInt(),
sdk.ZeroInt(),
true,
sdk.ZeroInt(),
},
{
"errors if mint amount is negative",
sdk.Coins{sdk.Coin{Denom: "akava", Amount: sdk.NewInt(-100)}},
sdk.ZeroInt(),
sdk.NewInt(50),
true,
sdk.NewInt(50),
},
{
"adds to existing akava balance",
sdk.NewCoins(sdk.NewInt64Coin("akava", 12_021_000_000_002)),
sdk.NewInt(12),
sdk.NewInt(21_000_000_102),
false,
sdk.NewInt(100),
},
{
"convert akava balance to ukava if it exceeds 1 ukava",
sdk.NewCoins(sdk.NewInt64Coin("akava", 10_999_000_000_000)),
sdk.NewInt(12),
sdk.NewInt(1_200_000_001),
false,
sdk.NewInt(1_002_200_000_001),
},
}
for _, tt := range tests {
suite.Run(tt.name, func() {
suite.SetupTest()
suite.FundModuleAccountWithKava(types.ModuleName, sdk.NewCoins(sdk.NewInt64Coin("ukava", 10)))
suite.FundModuleAccountWithKava(evmtypes.ModuleName, sdk.NewCoins(sdk.NewCoin("akava", tt.akavaStart)))
err := suite.EvmBankKeeper.MintCoins(suite.Ctx, evmtypes.ModuleName, tt.mintCoins)
if tt.hasErr {
suite.Require().Error(err)
return
} else {
suite.Require().NoError(err)
}
// check ukava
ukavaActual := suite.BankKeeper.GetBalance(suite.Ctx, suite.EvmModuleAddr, "ukava")
suite.Require().Equal(tt.ukava, ukavaActual.Amount)
// check akava
akavaActual := suite.Keeper.GetBalance(suite.Ctx, suite.EvmModuleAddr)
suite.Require().Equal(tt.akava, akavaActual)
})
}
}
func (suite *evmBankKeeperTestSuite) TestValidateEvmCoins() {
tests := []struct {
name string
coins sdk.Coins
shouldErr bool
}{
{
"valid coins",
sdk.NewCoins(sdk.NewInt64Coin("akava", 500)),
false,
},
{
"dup coins",
sdk.Coins{sdk.NewInt64Coin("akava", 500), sdk.NewInt64Coin("akava", 500)},
true,
},
{
"not evm coins",
sdk.NewCoins(sdk.NewInt64Coin("ukava", 500)),
true,
},
{
"negative coins",
sdk.Coins{sdk.Coin{Denom: "akava", Amount: sdk.NewInt(-500)}},
true,
},
}
for _, tt := range tests {
suite.Run(tt.name, func() {
err := keeper.ValidateEvmCoins(tt.coins)
if tt.shouldErr {
suite.Require().Error(err)
} else {
suite.Require().NoError(err)
}
})
}
}
func (suite *evmBankKeeperTestSuite) TestConvertOneUkavaToAkavaIfNeeded() {
akavaNeeded := sdk.NewInt(200)
tests := []struct {
name string
startingCoins sdk.Coins
expectedCoins sdk.Coins
success bool
}{
{
"not enough ukava for conversion",
sdk.NewCoins(sdk.NewInt64Coin("akava", 100)),
sdk.NewCoins(sdk.NewInt64Coin("akava", 100)),
false,
},
{
"converts 1 ukava to akava",
sdk.NewCoins(sdk.NewInt64Coin("ukava", 10), sdk.NewInt64Coin("akava", 100)),
sdk.NewCoins(sdk.NewInt64Coin("ukava", 9), sdk.NewInt64Coin("akava", 1_000_000_000_100)),
true,
},
{
"conversion not needed",
sdk.NewCoins(sdk.NewInt64Coin("ukava", 10), sdk.NewInt64Coin("akava", 200)),
sdk.NewCoins(sdk.NewInt64Coin("ukava", 10), sdk.NewInt64Coin("akava", 200)),
true,
},
}
for _, tt := range tests {
suite.Run(tt.name, func() {
suite.SetupTest()
suite.FundAccountWithKava(suite.Addrs[0], tt.startingCoins)
err := suite.EvmBankKeeper.ConvertOneUkavaToAkavaIfNeeded(suite.Ctx, suite.Addrs[0], akavaNeeded)
moduleKava := suite.BankKeeper.GetBalance(suite.Ctx, suite.AccountKeeper.GetModuleAddress(types.ModuleName), "ukava")
if tt.success {
suite.Require().NoError(err)
if tt.startingCoins.AmountOf("akava").LT(akavaNeeded) {
suite.Require().Equal(sdk.OneInt(), moduleKava.Amount)
}
} else {
suite.Require().Error(err)
suite.Require().Equal(sdk.ZeroInt(), moduleKava.Amount)
}
akava := suite.Keeper.GetBalance(suite.Ctx, suite.Addrs[0])
suite.Require().Equal(tt.expectedCoins.AmountOf("akava"), akava)
ukava := suite.BankKeeper.GetBalance(suite.Ctx, suite.Addrs[0], "ukava")
suite.Require().Equal(tt.expectedCoins.AmountOf("ukava"), ukava.Amount)
})
}
}
func (suite *evmBankKeeperTestSuite) TestConvertAkavaToUkava() {
tests := []struct {
name string
startingCoins sdk.Coins
expectedCoins sdk.Coins
}{
{
"not enough ukava",
sdk.NewCoins(sdk.NewInt64Coin("akava", 100)),
sdk.NewCoins(sdk.NewInt64Coin("akava", 100), sdk.NewInt64Coin("ukava", 0)),
},
{
"converts akava for 1 ukava",
sdk.NewCoins(sdk.NewInt64Coin("ukava", 10), sdk.NewInt64Coin("akava", 1_000_000_000_003)),
sdk.NewCoins(sdk.NewInt64Coin("ukava", 11), sdk.NewInt64Coin("akava", 3)),
},
{
"converts more than 1 ukava of akava",
sdk.NewCoins(sdk.NewInt64Coin("ukava", 10), sdk.NewInt64Coin("akava", 8_000_000_000_123)),
sdk.NewCoins(sdk.NewInt64Coin("ukava", 18), sdk.NewInt64Coin("akava", 123)),
},
}
for _, tt := range tests {
suite.Run(tt.name, func() {
suite.SetupTest()
err := suite.App.FundModuleAccount(suite.Ctx, types.ModuleName, sdk.NewCoins(sdk.NewInt64Coin("ukava", 10)))
suite.Require().NoError(err)
suite.FundAccountWithKava(suite.Addrs[0], tt.startingCoins)
err = suite.EvmBankKeeper.ConvertAkavaToUkava(suite.Ctx, suite.Addrs[0])
suite.Require().NoError(err)
akava := suite.Keeper.GetBalance(suite.Ctx, suite.Addrs[0])
suite.Require().Equal(tt.expectedCoins.AmountOf("akava"), akava)
ukava := suite.BankKeeper.GetBalance(suite.Ctx, suite.Addrs[0], "ukava")
suite.Require().Equal(tt.expectedCoins.AmountOf("ukava"), ukava.Amount)
})
}
}
func (suite *evmBankKeeperTestSuite) TestSplitAkavaCoins() {
tests := []struct {
name string
coins sdk.Coins
expectedCoins sdk.Coins
shouldErr bool
}{
{
"invalid coins",
sdk.NewCoins(sdk.NewInt64Coin("ukava", 500)),
nil,
true,
},
{
"empty coins",
sdk.NewCoins(),
sdk.NewCoins(),
false,
},
{
"ukava & akava coins",
sdk.NewCoins(sdk.NewInt64Coin("akava", 8_000_000_000_123)),
sdk.NewCoins(sdk.NewInt64Coin("ukava", 8), sdk.NewInt64Coin("akava", 123)),
false,
},
{
"only akava",
sdk.NewCoins(sdk.NewInt64Coin("akava", 10_123)),
sdk.NewCoins(sdk.NewInt64Coin("akava", 10_123)),
false,
},
{
"only ukava",
sdk.NewCoins(sdk.NewInt64Coin("akava", 5_000_000_000_000)),
sdk.NewCoins(sdk.NewInt64Coin("ukava", 5)),
false,
},
}
for _, tt := range tests {
suite.Run(tt.name, func() {
ukava, akava, err := keeper.SplitAkavaCoins(tt.coins)
if tt.shouldErr {
suite.Require().Error(err)
} else {
suite.Require().NoError(err)
suite.Require().Equal(tt.expectedCoins.AmountOf("ukava"), ukava.Amount)
suite.Require().Equal(tt.expectedCoins.AmountOf("akava"), akava)
}
})
}
}
func TestEvmBankKeeperTestSuite(t *testing.T) {
suite.Run(t, new(evmBankKeeperTestSuite))
}

View File

@ -0,0 +1,137 @@
package keeper_test
import (
"math/big"
"testing"
"time"
sdk "github.com/cosmos/cosmos-sdk/types"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
vestingtypes "github.com/cosmos/cosmos-sdk/x/auth/vesting/types"
"github.com/stretchr/testify/suite"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
"github.com/tharsis/ethermint/tests"
etherminttypes "github.com/tharsis/ethermint/types"
"github.com/tharsis/ethermint/x/evm/statedb"
"github.com/tharsis/ethermint/x/evm/types"
"github.com/kava-labs/kava/x/evmutil/testutil"
)
type evmKeeperTestSuite struct {
testutil.Suite
}
func (suite *evmKeeperTestSuite) SetupTest() {
suite.Suite.SetupTest()
}
func (suite *evmKeeperTestSuite) StateDB() *statedb.StateDB {
return statedb.New(suite.Ctx, suite.App.GetEvmKeeper(), statedb.NewEmptyTxConfig(common.BytesToHash(suite.Ctx.HeaderHash().Bytes())))
}
func (suite *evmKeeperTestSuite) TestEvmKeeper_SetAccount() {
baseAddr := tests.GenerateAddress()
baseAcc := &authtypes.BaseAccount{Address: sdk.AccAddress(baseAddr.Bytes()).String()}
ethAddr := tests.GenerateAddress()
ethAcc := &etherminttypes.EthAccount{BaseAccount: &authtypes.BaseAccount{Address: sdk.AccAddress(ethAddr.Bytes()).String()}, CodeHash: common.BytesToHash(types.EmptyCodeHash).String()}
vestingAddr := tests.GenerateAddress()
vestingAcc := vestingtypes.NewBaseVestingAccount(&authtypes.BaseAccount{Address: sdk.AccAddress(vestingAddr.Bytes()).String()}, sdk.NewCoins(), time.Now().Unix())
testCases := []struct {
name string
address common.Address
account statedb.Account
expectedErr error
}{
{
"new account, non-contract account",
tests.GenerateAddress(),
statedb.Account{10, big.NewInt(100), types.EmptyCodeHash},
nil,
},
{
"new account, contract account",
tests.GenerateAddress(),
statedb.Account{10, big.NewInt(100), crypto.Keccak256Hash([]byte("some code hash")).Bytes()},
nil,
},
{
"existing eth account, non-contract account",
ethAddr,
statedb.Account{10, big.NewInt(1), types.EmptyCodeHash},
nil,
},
{
"existing eth account, contract account",
ethAddr,
statedb.Account{10, big.NewInt(0), crypto.Keccak256Hash([]byte("some code hash")).Bytes()},
nil,
},
{
"existing base account, non-contract account",
baseAddr,
statedb.Account{10, big.NewInt(10), types.EmptyCodeHash},
nil,
},
{
"existing base account, contract account",
baseAddr,
statedb.Account{10, big.NewInt(99), crypto.Keccak256Hash([]byte("some code hash")).Bytes()},
nil,
},
{
"existing vesting account, non-contract account",
vestingAddr,
statedb.Account{10, big.NewInt(1000), types.EmptyCodeHash},
nil,
},
{
"existing vesting account, contract account",
vestingAddr,
statedb.Account{10, big.NewInt(1001), crypto.Keccak256Hash([]byte("some code hash")).Bytes()},
types.ErrInvalidAccount,
},
}
for _, tc := range testCases {
suite.Run(tc.name, func() {
suite.SetupTest()
if tc.address == baseAddr {
suite.AccountKeeper.SetAccount(suite.Ctx, baseAcc)
}
if tc.address == ethAddr {
suite.AccountKeeper.SetAccount(suite.Ctx, ethAcc)
}
if tc.address == vestingAddr {
suite.AccountKeeper.SetAccount(suite.Ctx, vestingAcc)
}
vmdb := suite.StateDB()
err := vmdb.Keeper().SetAccount(suite.Ctx, tc.address, tc.account)
if tc.expectedErr == nil {
suite.Require().NoError(err)
} else {
suite.Require().Error(tc.expectedErr)
return
}
nonce := vmdb.GetNonce(tc.address)
suite.Equal(nonce, tc.account.Nonce, "expected nonce to be set")
hash := vmdb.GetCodeHash(tc.address)
suite.Equal(common.BytesToHash(tc.account.CodeHash), hash, "expected code hash to be set")
balance := vmdb.GetBalance(tc.address)
suite.Equal(balance, tc.account.Balance, "expected balance to be set")
})
}
}
func TestEvmKeeperTestSuite(t *testing.T) {
suite.Run(t, new(evmKeeperTestSuite))
}

View File

@ -0,0 +1,65 @@
package keeper
import (
sdk "github.com/cosmos/cosmos-sdk/types"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
"github.com/kava-labs/kava/x/evmutil/types"
)
// RegisterInvariants registers the swap module invariants
func RegisterInvariants(ir sdk.InvariantRegistry, bankK types.BankKeeper, k Keeper) {
ir.RegisterRoute(types.ModuleName, "fully-backed", FullyBackedInvariant(bankK, k))
ir.RegisterRoute(types.ModuleName, "small-balances", SmallBalancesInvariant(bankK, k))
}
// AllInvariants runs all invariants of the swap module
func AllInvariants(bankK types.BankKeeper, k Keeper) sdk.Invariant {
return func(ctx sdk.Context) (string, bool) {
if res, stop := FullyBackedInvariant(bankK, k)(ctx); stop {
return res, stop
}
res, stop := SmallBalancesInvariant(bankK, k)(ctx)
return res, stop
}
}
// FullyBackedInvariant ensures all minor balances are backed exactly by the coins in the module account.
func FullyBackedInvariant(bankK types.BankKeeper, k Keeper) sdk.Invariant {
broken := false
message := sdk.FormatInvariant(types.ModuleName, "fully backed broken", "minor balances do not match module account")
return func(ctx sdk.Context) (string, bool) {
totalMinorBalances := sdk.ZeroInt()
k.IterateAllAccounts(ctx, func(acc types.Account) bool {
totalMinorBalances = totalMinorBalances.Add(acc.Balance)
return false
})
bankAddr := authtypes.NewModuleAddress(types.ModuleName)
bankBalance := bankK.GetBalance(ctx, bankAddr, CosmosDenom).Amount.Mul(ConversionMultiplier)
broken = !totalMinorBalances.Equal(bankBalance)
return message, broken
}
}
// SmallBalancesInvariant ensures all minor balances are less than the overflow amount, beyond this they should be converted to the major denom.
func SmallBalancesInvariant(_ types.BankKeeper, k Keeper) sdk.Invariant {
broken := false
message := sdk.FormatInvariant(types.ModuleName, "small balances broken", "minor balances not all less than overflow")
return func(ctx sdk.Context) (string, bool) {
k.IterateAllAccounts(ctx, func(account types.Account) bool {
if account.Balance.GTE(ConversionMultiplier) {
broken = true
return true
}
return false
})
return message, broken
}
}

View File

@ -0,0 +1,119 @@
package keeper_test
import (
"testing"
sdk "github.com/cosmos/cosmos-sdk/types"
minttypes "github.com/cosmos/cosmos-sdk/x/mint/types"
"github.com/stretchr/testify/suite"
"github.com/kava-labs/kava/x/evmutil/keeper"
"github.com/kava-labs/kava/x/evmutil/testutil"
"github.com/kava-labs/kava/x/evmutil/types"
)
type invariantTestSuite struct {
testutil.Suite
invariants map[string]map[string]sdk.Invariant
}
func TestInvariantTestSuite(t *testing.T) {
suite.Run(t, new(invariantTestSuite))
}
func (suite *invariantTestSuite) SetupTest() {
suite.Suite.SetupTest()
suite.invariants = make(map[string]map[string]sdk.Invariant)
keeper.RegisterInvariants(suite, suite.BankKeeper, suite.Keeper)
}
func (suite *invariantTestSuite) SetupValidState() {
for i := 0; i < 4; i++ {
suite.Keeper.SetAccount(suite.Ctx, *types.NewAccount(
suite.Addrs[i],
keeper.ConversionMultiplier.QuoRaw(2),
))
}
suite.FundModuleAccountWithKava(
types.ModuleName,
sdk.NewCoins(
sdk.NewCoin("ukava", sdk.NewInt(2)), // ( sum of all minor balances ) / conversion multiplier
),
)
}
// RegisterRoutes implements sdk.InvariantRegistry
func (suite *invariantTestSuite) RegisterRoute(moduleName string, route string, invariant sdk.Invariant) {
_, exists := suite.invariants[moduleName]
if !exists {
suite.invariants[moduleName] = make(map[string]sdk.Invariant)
}
suite.invariants[moduleName][route] = invariant
}
func (suite *invariantTestSuite) runInvariant(route string, invariant func(bankKeeper types.BankKeeper, k keeper.Keeper) sdk.Invariant) (string, bool) {
ctx := suite.Ctx
registeredInvariant := suite.invariants[types.ModuleName][route]
suite.Require().NotNil(registeredInvariant)
// direct call
dMessage, dBroken := invariant(suite.BankKeeper, suite.Keeper)(ctx)
// registered call
rMessage, rBroken := registeredInvariant(ctx)
// all call
aMessage, aBroken := keeper.AllInvariants(suite.BankKeeper, suite.Keeper)(ctx)
// require matching values for direct call and registered call
suite.Require().Equal(dMessage, rMessage, "expected registered invariant message to match")
suite.Require().Equal(dBroken, rBroken, "expected registered invariant broken to match")
// require matching values for direct call and all invariants call if broken
suite.Require().Equal(dBroken, aBroken, "expected all invariant broken to match")
if dBroken {
suite.Require().Equal(dMessage, aMessage, "expected all invariant message to match")
}
return dMessage, dBroken
}
func (suite *invariantTestSuite) TestFullyBackedInvariant() {
// default state is valid
_, broken := suite.runInvariant("fully-backed", keeper.FullyBackedInvariant)
suite.Equal(false, broken)
suite.SetupValidState()
_, broken = suite.runInvariant("fully-backed", keeper.FullyBackedInvariant)
suite.Equal(false, broken)
// break invariant by decreasing minor balances without decreasing module balance
suite.Keeper.RemoveBalance(suite.Ctx, suite.Addrs[0], sdk.OneInt())
message, broken := suite.runInvariant("fully-backed", keeper.FullyBackedInvariant)
suite.Equal("evmutil: fully backed broken invariant\nminor balances do not match module account\n", message)
suite.Equal(true, broken)
}
func (suite *invariantTestSuite) TestSmallBalances() {
// default state is valid
_, broken := suite.runInvariant("small-balances", keeper.SmallBalancesInvariant)
suite.Equal(false, broken)
suite.SetupValidState()
_, broken = suite.runInvariant("small-balances", keeper.SmallBalancesInvariant)
suite.Equal(false, broken)
// increase minor balance at least above conversion multiplier
suite.Keeper.AddBalance(suite.Ctx, suite.Addrs[0], keeper.ConversionMultiplier)
// add same number of ukava to avoid breaking other invariants
amt := sdk.NewCoins(sdk.NewInt64Coin(keeper.CosmosDenom, 1))
suite.Require().NoError(
suite.BankKeeper.MintCoins(suite.Ctx, minttypes.ModuleName, amt),
)
suite.BankKeeper.SendCoinsFromModuleToModule(suite.Ctx, minttypes.ModuleName, types.ModuleName, amt)
message, broken := suite.runInvariant("small-balances", keeper.SmallBalancesInvariant)
suite.Equal("evmutil: small balances broken invariant\nminor balances not all less than overflow\n", message)
suite.Equal(true, broken)
}

160
x/evmutil/keeper/keeper.go Normal file
View File

@ -0,0 +1,160 @@
package keeper
import (
"fmt"
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/kava-labs/kava/x/evmutil/types"
)
// Keeper of the evmutil store.
// This keeper stores additional data related to evm accounts.
type Keeper struct {
cdc codec.Codec
storeKey sdk.StoreKey
}
// NewKeeper creates an evmutil keeper.
func NewKeeper(cdc codec.Codec, storeKey sdk.StoreKey) Keeper {
return Keeper{
cdc: cdc,
storeKey: storeKey,
}
}
// GetAllAccounts returns all accounts.
func (k Keeper) GetAllAccounts(ctx sdk.Context) (accounts []types.Account) {
k.IterateAllAccounts(ctx, func(account types.Account) bool {
accounts = append(accounts, account)
return false
})
return accounts
}
// IterateAllAccounts iterates over all accounts. If true is returned from the
// callback, iteration is halted.
func (k Keeper) IterateAllAccounts(ctx sdk.Context, cb func(types.Account) bool) {
store := ctx.KVStore(k.storeKey)
iterator := sdk.KVStorePrefixIterator(store, types.AccountStoreKeyPrefix)
defer iterator.Close()
for ; iterator.Valid(); iterator.Next() {
var acc types.Account
if err := k.cdc.Unmarshal(iterator.Value(), &acc); err != nil {
panic(err)
}
if cb(acc) {
break
}
}
}
// GetAccount returns the account for a given address.
func (k Keeper) GetAccount(ctx sdk.Context, addr sdk.AccAddress) *types.Account {
store := ctx.KVStore(k.storeKey)
var account types.Account
bz := store.Get(types.AccountStoreKey(addr))
if bz == nil {
return nil
}
if err := account.Unmarshal(bz); err != nil {
panic(err)
}
return &account
}
// SetAccount sets the account for a given address.
func (k Keeper) SetAccount(ctx sdk.Context, account types.Account) error {
if err := account.Validate(); err != nil {
return err
}
store := ctx.KVStore(k.storeKey)
accountKey := types.AccountStoreKey(account.Address)
// make sure we remove accounts with zero balance
if !account.Balance.IsPositive() {
if store.Has(accountKey) {
store.Delete(accountKey)
}
return nil
}
bz, err := k.cdc.Marshal(&account)
if err != nil {
panic(err)
}
store.Set(accountKey, bz)
return nil
}
// GetBalance returns the total balance of akava for a given account by address.
func (k Keeper) GetBalance(ctx sdk.Context, addr sdk.AccAddress) sdk.Int {
account := k.GetAccount(ctx, addr)
if account == nil {
return sdk.ZeroInt()
}
return account.Balance
}
// SetBalance sets the total balance of akava for a given account by address.
func (k Keeper) SetBalance(ctx sdk.Context, addr sdk.AccAddress, bal sdk.Int) error {
account := k.GetAccount(ctx, addr)
if account == nil {
account = types.NewAccount(addr, bal)
} else {
account.Balance = bal
}
if err := account.Validate(); err != nil {
return err
}
return k.SetAccount(ctx, *account)
}
// SendBalance transfers the akava balance from sender addr to recipient addr.
func (k Keeper) SendBalance(ctx sdk.Context, senderAddr sdk.AccAddress, recipientAddr sdk.AccAddress, amt sdk.Int) error {
if amt.IsNegative() {
return fmt.Errorf("cannot send a negative amount of akava: %d", amt)
}
if amt.IsZero() {
return nil
}
senderBal := k.GetBalance(ctx, senderAddr)
if senderBal.LT(amt) {
return sdkerrors.Wrapf(sdkerrors.ErrInsufficientFunds, "insufficient funds to send %s", amt.String())
}
if err := k.SetBalance(ctx, senderAddr, senderBal.Sub(amt)); err != nil {
return err
}
receiverBal := k.GetBalance(ctx, recipientAddr).Add(amt)
return k.SetBalance(ctx, recipientAddr, receiverBal)
}
// AddBalance increments the akava balance of an address.
func (k Keeper) AddBalance(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Int) error {
bal := k.GetBalance(ctx, addr)
return k.SetBalance(ctx, addr, amt.Add(bal))
}
// RemoveBalance decrements the akava balance of an address.
func (k Keeper) RemoveBalance(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Int) error {
if amt.IsNegative() {
return fmt.Errorf("cannot remove a negative amount from balance: %d", amt)
}
if amt.IsZero() {
return nil
}
bal := k.GetBalance(ctx, addr)
finalBal := bal.Sub(amt)
if finalBal.IsNegative() {
return sdkerrors.Wrapf(sdkerrors.ErrInsufficientFunds, "insufficient funds to send %s", amt.String())
}
return k.SetBalance(ctx, addr, finalBal)
}

View File

@ -0,0 +1,359 @@
package keeper_test
import (
"testing"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/stretchr/testify/suite"
"github.com/kava-labs/kava/x/evmutil/testutil"
"github.com/kava-labs/kava/x/evmutil/types"
)
type keeperTestSuite struct {
testutil.Suite
}
func (suite *keeperTestSuite) SetupTest() {
suite.Suite.SetupTest()
}
func (suite *keeperTestSuite) TestGetAllAccounts() {
tests := []struct {
name string
expAccounts []types.Account
}{
{
"no accounts",
[]types.Account{},
},
{
"with accounts",
[]types.Account{
{Address: suite.Addrs[0], Balance: sdk.NewInt(100)},
{Address: suite.Addrs[1], Balance: sdk.NewInt(200)},
},
},
}
for _, tt := range tests {
suite.Run(tt.name, func() {
suite.SetupTest()
for _, account := range tt.expAccounts {
suite.Keeper.SetBalance(suite.Ctx, account.Address, account.Balance)
}
accounts := suite.Suite.Keeper.GetAllAccounts(suite.Ctx)
if len(tt.expAccounts) == 0 {
suite.Require().Len(tt.expAccounts, 0)
} else {
suite.Require().Equal(tt.expAccounts, accounts)
}
})
}
}
func (suite *keeperTestSuite) TestSetAccount_ZeroBalance() {
existingAccount := types.Account{
Address: suite.Addrs[0],
Balance: sdk.NewInt(100),
}
err := suite.Keeper.SetAccount(suite.Ctx, existingAccount)
suite.Require().NoError(err)
err = suite.Keeper.SetAccount(suite.Ctx, types.Account{
Address: suite.Addrs[0],
Balance: sdk.ZeroInt(),
})
suite.Require().NoError(err)
bal := suite.Keeper.GetBalance(suite.Ctx, suite.Addrs[0])
suite.Require().Equal(sdk.ZeroInt(), bal)
expAcct := suite.Keeper.GetAccount(suite.Ctx, suite.Addrs[0])
suite.Require().Nil(expAcct)
}
func (suite *keeperTestSuite) TestSetAccount() {
existingAccount := types.Account{
Address: suite.Addrs[0],
Balance: sdk.NewInt(100),
}
tests := []struct {
name string
account types.Account
success bool
}{
{
"invalid address",
types.Account{Address: nil, Balance: sdk.NewInt(100)},
false,
},
{
"invalid balance",
types.Account{Address: suite.Addrs[0], Balance: sdk.NewInt(-100)},
false,
},
{
"empty account",
types.Account{},
false,
},
{
"valid account",
types.Account{Address: suite.Addrs[1], Balance: sdk.NewInt(100)},
true,
},
{
"replaces account",
types.Account{Address: suite.Addrs[0], Balance: sdk.NewInt(50)},
true,
},
}
for _, tt := range tests {
suite.Run(tt.name, func() {
suite.SetupTest()
err := suite.Keeper.SetAccount(suite.Ctx, existingAccount)
suite.Require().NoError(err)
err = suite.Keeper.SetAccount(suite.Ctx, tt.account)
if tt.success {
suite.Require().NoError(err)
expAcct := suite.Keeper.GetAccount(suite.Ctx, tt.account.Address)
suite.Require().Equal(tt.account, *expAcct)
} else {
suite.Require().Error(err)
suite.Require().Nil(suite.Keeper.GetAccount(suite.Ctx, suite.Addrs[1]))
}
})
}
}
func (suite *keeperTestSuite) TestSendBalance() {
startingSenderBal := sdk.NewInt(100)
startingRecipientBal := sdk.NewInt(50)
tests := []struct {
name string
amt sdk.Int
expSenderBal sdk.Int
expRecipientBal sdk.Int
success bool
}{
{
"fails when sending negative amount",
sdk.NewInt(-5),
sdk.ZeroInt(),
sdk.ZeroInt(),
false,
},
{
"send zero amount",
sdk.ZeroInt(),
startingSenderBal,
startingRecipientBal,
true,
},
{
"fails when sender does not have enough balance",
sdk.NewInt(101),
sdk.ZeroInt(),
sdk.ZeroInt(),
false,
},
{
"send valid amount",
sdk.NewInt(80),
sdk.NewInt(20),
sdk.NewInt(130),
true,
},
}
for _, tt := range tests {
suite.Run(tt.name, func() {
suite.SetupTest()
err := suite.Keeper.SetBalance(suite.Ctx, suite.Addrs[0], startingSenderBal)
suite.Require().NoError(err)
err = suite.Keeper.SetBalance(suite.Ctx, suite.Addrs[1], startingRecipientBal)
suite.Require().NoError(err)
err = suite.Keeper.SendBalance(suite.Ctx, suite.Addrs[0], suite.Addrs[1], tt.amt)
if tt.success {
suite.Require().NoError(err)
suite.Require().Equal(tt.expSenderBal, suite.Keeper.GetBalance(suite.Ctx, suite.Addrs[0]))
suite.Require().Equal(tt.expRecipientBal, suite.Keeper.GetBalance(suite.Ctx, suite.Addrs[1]))
} else {
suite.Require().Error(err)
}
})
}
}
func (suite *keeperTestSuite) TestSetBalance() {
existingAccount := types.Account{
Address: suite.Addrs[0],
Balance: sdk.NewInt(100),
}
tests := []struct {
name string
address sdk.AccAddress
balance sdk.Int
success bool
}{
{
"invalid balance",
suite.Addrs[0],
sdk.NewInt(-100),
false,
},
{
"set new account balance",
suite.Addrs[1],
sdk.NewInt(100),
true,
},
{
"replace account balance",
suite.Addrs[0],
sdk.NewInt(50),
true,
},
{
"invalid address",
nil,
sdk.NewInt(100),
false,
},
{
"zero balance",
suite.Addrs[0],
sdk.ZeroInt(),
true,
},
}
for _, tt := range tests {
suite.Run(tt.name, func() {
suite.SetupTest()
err := suite.Keeper.SetAccount(suite.Ctx, existingAccount)
suite.Require().NoError(err)
err = suite.Keeper.SetBalance(suite.Ctx, tt.address, tt.balance)
if tt.success {
suite.Require().NoError(err)
expBal := suite.Keeper.GetBalance(suite.Ctx, tt.address)
suite.Require().Equal(expBal, tt.balance)
if tt.balance.IsZero() {
account := suite.Keeper.GetAccount(suite.Ctx, tt.address)
suite.Require().Nil(account)
}
} else {
suite.Require().Error(err)
expBal := suite.Keeper.GetBalance(suite.Ctx, existingAccount.Address)
suite.Require().Equal(expBal, existingAccount.Balance)
}
})
}
}
func (suite *keeperTestSuite) TestRemoveBalance() {
existingAccount := types.Account{
Address: suite.Addrs[0],
Balance: sdk.NewInt(100),
}
tests := []struct {
name string
amt sdk.Int
expBal sdk.Int
success bool
}{
{
"fails if amount is negative",
sdk.NewInt(-10),
sdk.ZeroInt(),
false,
},
{
"remove zero amount",
sdk.ZeroInt(),
existingAccount.Balance,
true,
},
{
"not enough balance",
sdk.NewInt(101),
sdk.ZeroInt(),
false,
},
{
"remove full balance",
sdk.NewInt(100),
sdk.ZeroInt(),
true,
},
{
"remove some balance",
sdk.NewInt(10),
sdk.NewInt(90),
true,
},
}
for _, tt := range tests {
suite.Run(tt.name, func() {
suite.SetupTest()
err := suite.Keeper.SetAccount(suite.Ctx, existingAccount)
suite.Require().NoError(err)
err = suite.Keeper.RemoveBalance(suite.Ctx, existingAccount.Address, tt.amt)
if tt.success {
suite.Require().NoError(err)
expBal := suite.Keeper.GetBalance(suite.Ctx, existingAccount.Address)
suite.Require().Equal(expBal, tt.expBal)
} else {
suite.Require().Error(err)
expBal := suite.Keeper.GetBalance(suite.Ctx, existingAccount.Address)
suite.Require().Equal(expBal, existingAccount.Balance)
}
})
}
}
func (suite *keeperTestSuite) TestGetBalance() {
existingAccount := types.Account{
Address: suite.Addrs[0],
Balance: sdk.NewInt(100),
}
tests := []struct {
name string
addr sdk.AccAddress
expBal sdk.Int
}{
{
"returns 0 balance if account does not exist",
suite.Addrs[1],
sdk.ZeroInt(),
},
{
"returns account balance",
suite.Addrs[0],
sdk.NewInt(100),
},
}
for _, tt := range tests {
suite.Run(tt.name, func() {
suite.SetupTest()
err := suite.Keeper.SetAccount(suite.Ctx, existingAccount)
suite.Require().NoError(err)
balance := suite.Keeper.GetBalance(suite.Ctx, tt.addr)
suite.Require().Equal(tt.expBal, balance)
})
}
}
func TestKeeperTestSuite(t *testing.T) {
suite.Run(t, new(keeperTestSuite))
}

150
x/evmutil/module.go Normal file
View File

@ -0,0 +1,150 @@
package evmutil
import (
"encoding/json"
"github.com/gorilla/mux"
"github.com/grpc-ecosystem/grpc-gateway/runtime"
"github.com/spf13/cobra"
abci "github.com/tendermint/tendermint/abci/types"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/codec"
cdctypes "github.com/cosmos/cosmos-sdk/codec/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/module"
"github.com/kava-labs/kava/x/evmutil/keeper"
"github.com/kava-labs/kava/x/evmutil/types"
)
var (
_ module.AppModule = AppModule{}
_ module.AppModuleBasic = AppModuleBasic{}
)
// ----------------------------------------------------------------------------
// AppModuleBasic
// ----------------------------------------------------------------------------
// AppModuleBasic app module basics object
type AppModuleBasic struct{}
func NewAppModuleBasic() AppModuleBasic {
return AppModuleBasic{}
}
// Name get module name
func (AppModuleBasic) Name() string {
return types.ModuleName
}
// Registers legacy amino codec
func (AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) {}
// RegisterInterfaces registers the module's interface types
func (a AppModuleBasic) RegisterInterfaces(reg cdctypes.InterfaceRegistry) {}
// DefaultGenesis default genesis state
func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage {
gs := types.DefaultGenesisState()
return cdc.MustMarshalJSON(gs)
}
// ValidateGenesis module validate genesis
func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, config client.TxEncodingConfig, bz json.RawMessage) error {
var gs types.GenesisState
err := cdc.UnmarshalJSON(bz, &gs)
if err != nil {
return err
}
return gs.Validate()
}
// RegisterRESTRoutes registers evmutil module's REST service handlers.
func (AppModuleBasic) RegisterRESTRoutes(clientCtx client.Context, rtr *mux.Router) {}
// RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for evmutil module.
func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) {}
// GetTxCmd returns evmutil module's root tx command.
func (a AppModuleBasic) GetTxCmd() *cobra.Command { return nil }
// GetQueryCmd returns evmutil module's root query command.
func (AppModuleBasic) GetQueryCmd() *cobra.Command { return nil }
// ----------------------------------------------------------------------------
// AppModule
// ----------------------------------------------------------------------------
// AppModule implements the AppModule interface for evmutil module.
type AppModule struct {
AppModuleBasic
keeper keeper.Keeper
bankKeeper types.BankKeeper
}
// NewAppModule creates a new AppModule object
func NewAppModule(keeper keeper.Keeper, bankKeeper types.BankKeeper) AppModule {
return AppModule{
AppModuleBasic: NewAppModuleBasic(),
keeper: keeper,
bankKeeper: bankKeeper,
}
}
// Name returns evmutil module's name.
func (am AppModule) Name() string {
return am.AppModuleBasic.Name()
}
// Route returns evmutil module's message route.
func (am AppModule) Route() sdk.Route { return sdk.Route{} }
// QuerierRoute returns evmutil module's query routing key.
func (AppModule) QuerierRoute() string { return types.ModuleName }
// LegacyQuerierHandler returns evmutil module's Querier.
func (am AppModule) LegacyQuerierHandler(legacyQuerierCdc *codec.LegacyAmino) sdk.Querier {
return nil
}
// RegisterServices registers a GRPC query service to respond to the
// module-specific GRPC queries.
func (am AppModule) RegisterServices(cfg module.Configurator) {}
// RegisterInvariants registers evmutil module's invariants.
func (am AppModule) RegisterInvariants(ir sdk.InvariantRegistry) {
keeper.RegisterInvariants(ir, am.bankKeeper, am.keeper)
}
// InitGenesis performs evmutil module's genesis initialization It returns
// no validator updates.
func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, gs json.RawMessage) []abci.ValidatorUpdate {
var genState types.GenesisState
// Initialize global index to index in genesis state
cdc.MustUnmarshalJSON(gs, &genState)
InitGenesis(ctx, am.keeper, &genState)
return []abci.ValidatorUpdate{}
}
// ExportGenesis returns evmutil module's exported genesis state as raw JSON bytes.
func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.RawMessage {
gs := ExportGenesis(ctx, am.keeper)
return cdc.MustMarshalJSON(gs)
}
// ConsensusVersion implements ConsensusVersion.
func (AppModule) ConsensusVersion() uint64 { return 1 }
// BeginBlock executes all ABCI BeginBlock logic respective to evmutil module.
func (am AppModule) BeginBlock(ctx sdk.Context, _ abci.RequestBeginBlock) {}
// EndBlock executes all ABCI EndBlock logic respective to evmutil module. It
// returns no validator updates.
func (am AppModule) EndBlock(_ sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate {
return []abci.ValidatorUpdate{}
}

View File

@ -0,0 +1,45 @@
<!--
order: 1
-->
# Concepts
## EVM Gas Denom
In order to use the EVM and be compatible with existing clients, the gas denom used by the EVM must be in 18 decimals. Since `ukava` has 6 decimals of precision, it cannot be used as the EVM gas denom directly.
In order to use the Kava token on the EVM, the `evmutil` module provides an `EvmBankKeeper` that is responsible for the conversion of `ukava` and `akava`. A user's `akava` balance is stored in the `evmutil` store, while it's `ukava` balance remains stored in the cosmos-sdk `bank` module.
## `EvmBankKeeper` Overview
The `EvmBankKeeper` provides access to an account's **total** `akava` balance and the ability to transfer, mint, and burn `akava`. If anything other than the `akava` denom is requested, the `EvmBankKeeper` will panic.
```go
type BankKeeper interface {
evmtypes.BankKeeper
SpendableCoins(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins
SendCoins(ctx sdk.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins) error
}
```
The keeper implements the `x/evm` module's `BankKeeper` interface to enable the usage of `akava` denom on the EVM.
### `x/evm` Parameter
Since the EVM denom `akava` is required to use the `EvmBankKeeper`, it is necessary to set the `EVMDenom` param of the `x/evm` module to `akava`.
### `akava` Balance Calculation
The `akava` balance of an account is derived from an account's **spendable** `ukava` balance times 10^12 (to derive its `akava` equivalent), plus the account's excess `akava` balance that can be accessed by the module `Keeper`.
### Conversions Between `akava` & `ukava`
When an account does not have sufficient `akava` to cover a transfer or burn, the `EvmBankKeeper` will try to swap 1 `ukava` to its equivalent `akava` amount. It does this by transferring 1 `ukava` from the sender to the `evmutil` module account, then adding the equivalent `akava` amount to the sender's balance via the keeper's `AddBalance`.
In reverse, if an account has enough `akava` balance for one or more `ukava`, the excess `akava` balance will be converted to `ukava`. This is done by removing the excess `akava` balance tracked by `evmutil` module store, then transferring the equivalent `ukava` coins from the `evmutil` module account to the target account.
The swap logic ensures that all `akava` is backed by the equivalent `ukava` balance stored in the module account.
## Module Keeper
The module Keeper provides access to an account's excess `akava` balance and the ability to update the balance.

View File

@ -0,0 +1,33 @@
<!--
order: 2
-->
# State
## Genesis state
`GenesisState` defines the state that must be persisted when the blockchain stops/restarts in order for normal function of the committee module to resume.
```protobuf
message GenesisState {
repeated Account accounts = 1;
}
```
## Account
An `Account` is a struct representing the excess `akava` balance of an address.
Since an address's total `akava` balance is derived from its `ukava` balance and the excess `akava` balance stored by the `Account` struct, the `akava` balance here should never exceed 1 `ukava` (10^12 `akava`).
```protobuf
message Account {
bytes address = 1;
string balance = 2;
}
```
## Store
For complete implementation details for how items are stored, see [keys.go](../types/keys.go). The `evmutil` module store state consists of accounts.

27
x/evmutil/spec/README.md Normal file
View File

@ -0,0 +1,27 @@
<!--
order: 0
title: Evmutil Overview
parent:
title: "evmutil"
-->
# `evmutil`
## Table of Contents
<!-- TOC -->
1. **[Concepts](01_concepts.md)**
2. **[State](02_state.md)**
## Overview
The `evmutil` module provides additional functionalities on top of the `evm` module by storing additional state data for evm accounts and exposing an `EvmBankKeeper` that should be used by the `x/evm` keeper for bank operations.
Two keepers are exposed by the module, `EvmBankKeeper` and the module `Keeper`.
The main purpose of the `EvmBankKeeper` is to allow the usage of the `akava` balance on the EVM through an account's existing `ukava` balance.
This is needed because the EVM gas token use 18 decimals, and since `ukava` has 6 decimals, it cannot be used as the EVM gas denom directly.
The module `Keeper` provides access to an account's excess `akava` balance and the ability to update `akava` balances. This is needed by the `EvmBankKeeper` to store
excess `akava` balances since the `ukava` token only has 6 decimals of precision.

View File

@ -0,0 +1,74 @@
package testutil
import (
sdk "github.com/cosmos/cosmos-sdk/types"
authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
"github.com/stretchr/testify/suite"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
tmtime "github.com/tendermint/tendermint/types/time"
evmtypes "github.com/tharsis/ethermint/x/evm/types"
"github.com/kava-labs/kava/app"
"github.com/kava-labs/kava/x/evmutil/keeper"
)
type Suite struct {
suite.Suite
App app.TestApp
Ctx sdk.Context
BankKeeper bankkeeper.Keeper
AccountKeeper authkeeper.AccountKeeper
Keeper keeper.Keeper
EvmBankKeeper keeper.EvmBankKeeper
Addrs []sdk.AccAddress
EvmModuleAddr sdk.AccAddress
}
func (suite *Suite) SetupTest() {
tApp := app.NewTestApp()
suite.Ctx = tApp.NewContext(true, tmproto.Header{Height: 1, Time: tmtime.Now()})
suite.App = tApp
suite.BankKeeper = tApp.GetBankKeeper()
suite.AccountKeeper = tApp.GetAccountKeeper()
suite.Keeper = tApp.GetEvmutilKeeper()
suite.EvmBankKeeper = keeper.NewEvmBankKeeper(tApp.GetEvmutilKeeper(), suite.BankKeeper, suite.AccountKeeper)
suite.EvmModuleAddr = suite.AccountKeeper.GetModuleAddress(evmtypes.ModuleName)
_, addrs := app.GeneratePrivKeyAddressPairs(4)
suite.Addrs = addrs
evmGenesis := evmtypes.DefaultGenesisState()
evmGenesis.Params.EvmDenom = "akava"
gs := app.GenesisState{evmtypes.ModuleName: suite.App.AppCodec().MustMarshalJSON(evmGenesis)}
suite.App.InitializeFromGenesisStates(gs)
}
func (suite *Suite) FundAccountWithKava(addr sdk.AccAddress, coins sdk.Coins) {
ukava := coins.AmountOf("ukava")
if ukava.IsPositive() {
err := suite.App.FundAccount(suite.Ctx, addr, sdk.NewCoins(sdk.NewCoin("ukava", ukava)))
suite.Require().NoError(err)
}
akava := coins.AmountOf("akava")
if akava.IsPositive() {
err := suite.Keeper.SetBalance(suite.Ctx, addr, akava)
suite.Require().NoError(err)
}
}
func (suite *Suite) FundModuleAccountWithKava(moduleName string, coins sdk.Coins) {
ukava := coins.AmountOf("ukava")
if ukava.IsPositive() {
err := suite.App.FundModuleAccount(suite.Ctx, moduleName, sdk.NewCoins(sdk.NewCoin("ukava", ukava)))
suite.Require().NoError(err)
}
akava := coins.AmountOf("akava")
if akava.IsPositive() {
addr := suite.AccountKeeper.GetModuleAddress(moduleName)
err := suite.Keeper.SetBalance(suite.Ctx, addr, akava)
suite.Require().NoError(err)
}
}

View File

@ -0,0 +1,19 @@
package types
import (
sdk "github.com/cosmos/cosmos-sdk/types"
evmtypes "github.com/tharsis/ethermint/x/evm/types"
)
// AccountKeeper defines the expected account keeper interface
type AccountKeeper interface {
GetModuleAddress(moduleName string) sdk.AccAddress
}
// BankKeeper defines the expected bank keeper interface
type BankKeeper interface {
evmtypes.BankKeeper
SpendableCoins(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins
SendCoins(ctx sdk.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins) error
}

View File

@ -0,0 +1,55 @@
package types
import (
"fmt"
sdk "github.com/cosmos/cosmos-sdk/types"
)
// NewGenesisState returns a new genesis state object for the module.
func NewGenesisState(accounts []Account) *GenesisState {
return &GenesisState{
Accounts: accounts,
}
}
// DefaultGenesisState returns the default genesis state for the module.
func DefaultGenesisState() *GenesisState {
return NewGenesisState(
[]Account{},
)
}
// Validate performs basic validation of genesis data.
func (gs GenesisState) Validate() error {
seenAccounts := make(map[string]bool)
for _, account := range gs.Accounts {
if seenAccounts[account.Address.String()] {
return fmt.Errorf("duplicate account for address %s", account.Address)
}
if err := account.Validate(); err != nil {
return err
}
seenAccounts[account.Address.String()] = true
}
return nil
}
func NewAccount(addr sdk.AccAddress, balance sdk.Int) *Account {
return &Account{
Address: addr,
Balance: balance,
}
}
func (b Account) Validate() error {
if b.Address.Empty() {
return fmt.Errorf("address cannot be empty")
}
if b.Balance.IsNegative() {
return fmt.Errorf("balance amount cannot be negative; amount: %d", b.Balance)
}
return nil
}

View File

@ -0,0 +1,549 @@
// Code generated by protoc-gen-gogo. DO NOT EDIT.
// source: kava/evmutil/v1beta1/genesis.proto
package types
import (
fmt "fmt"
_ "github.com/cosmos/cosmos-proto"
github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types"
_ "github.com/gogo/protobuf/gogoproto"
proto "github.com/gogo/protobuf/proto"
io "io"
math "math"
math_bits "math/bits"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
// GenesisState defines the evmutil module's genesis state.
type GenesisState struct {
Accounts []Account `protobuf:"bytes,1,rep,name=accounts,proto3" json:"accounts"`
}
func (m *GenesisState) Reset() { *m = GenesisState{} }
func (m *GenesisState) String() string { return proto.CompactTextString(m) }
func (*GenesisState) ProtoMessage() {}
func (*GenesisState) Descriptor() ([]byte, []int) {
return fileDescriptor_d916ab97b8e628c2, []int{0}
}
func (m *GenesisState) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *GenesisState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_GenesisState.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (m *GenesisState) XXX_Merge(src proto.Message) {
xxx_messageInfo_GenesisState.Merge(m, src)
}
func (m *GenesisState) XXX_Size() int {
return m.Size()
}
func (m *GenesisState) XXX_DiscardUnknown() {
xxx_messageInfo_GenesisState.DiscardUnknown(m)
}
var xxx_messageInfo_GenesisState proto.InternalMessageInfo
// BalanceAccount defines an account in the evmutil module.
type Account struct {
Address github_com_cosmos_cosmos_sdk_types.AccAddress `protobuf:"bytes,1,opt,name=address,proto3,casttype=github.com/cosmos/cosmos-sdk/types.AccAddress" json:"address,omitempty"`
// balance indicates the amount of akava owned by the address.
Balance github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,2,opt,name=balance,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"balance"`
}
func (m *Account) Reset() { *m = Account{} }
func (m *Account) String() string { return proto.CompactTextString(m) }
func (*Account) ProtoMessage() {}
func (*Account) Descriptor() ([]byte, []int) {
return fileDescriptor_d916ab97b8e628c2, []int{1}
}
func (m *Account) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *Account) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_Account.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (m *Account) XXX_Merge(src proto.Message) {
xxx_messageInfo_Account.Merge(m, src)
}
func (m *Account) XXX_Size() int {
return m.Size()
}
func (m *Account) XXX_DiscardUnknown() {
xxx_messageInfo_Account.DiscardUnknown(m)
}
var xxx_messageInfo_Account proto.InternalMessageInfo
func init() {
proto.RegisterType((*GenesisState)(nil), "kava.evmutil.v1beta1.GenesisState")
proto.RegisterType((*Account)(nil), "kava.evmutil.v1beta1.Account")
}
func init() {
proto.RegisterFile("kava/evmutil/v1beta1/genesis.proto", fileDescriptor_d916ab97b8e628c2)
}
var fileDescriptor_d916ab97b8e628c2 = []byte{
// 331 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0xca, 0x4e, 0x2c, 0x4b,
0xd4, 0x4f, 0x2d, 0xcb, 0x2d, 0x2d, 0xc9, 0xcc, 0xd1, 0x2f, 0x33, 0x4c, 0x4a, 0x2d, 0x49, 0x34,
0xd4, 0x4f, 0x4f, 0xcd, 0x4b, 0x2d, 0xce, 0x2c, 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12,
0x01, 0xa9, 0xd1, 0x83, 0xaa, 0xd1, 0x83, 0xaa, 0x91, 0x12, 0x49, 0xcf, 0x4f, 0xcf, 0x07, 0x2b,
0xd0, 0x07, 0xb1, 0x20, 0x6a, 0xa5, 0x24, 0x93, 0xf3, 0x8b, 0x73, 0xf3, 0x8b, 0xe3, 0x21, 0x12,
0x10, 0x0e, 0x44, 0x4a, 0x29, 0x94, 0x8b, 0xc7, 0x1d, 0x62, 0x6e, 0x70, 0x49, 0x62, 0x49, 0xaa,
0x90, 0x3d, 0x17, 0x47, 0x62, 0x72, 0x72, 0x7e, 0x69, 0x5e, 0x49, 0xb1, 0x04, 0xa3, 0x02, 0xb3,
0x06, 0xb7, 0x91, 0xac, 0x1e, 0x36, 0x9b, 0xf4, 0x1c, 0x21, 0xaa, 0x9c, 0x58, 0x4e, 0xdc, 0x93,
0x67, 0x08, 0x82, 0x6b, 0xb2, 0x62, 0xe9, 0x58, 0x20, 0xcf, 0xa0, 0x74, 0x9e, 0x91, 0x8b, 0x1d,
0xaa, 0x42, 0x28, 0x89, 0x8b, 0x3d, 0x31, 0x25, 0xa5, 0x28, 0xb5, 0x18, 0x64, 0x22, 0xa3, 0x06,
0x8f, 0x93, 0xc7, 0xaf, 0x7b, 0xf2, 0xba, 0xe9, 0x99, 0x25, 0x19, 0xa5, 0x49, 0x7a, 0xc9, 0xf9,
0xb9, 0x50, 0x07, 0x41, 0x29, 0xdd, 0xe2, 0x94, 0x6c, 0xfd, 0x92, 0xca, 0x82, 0xd4, 0x62, 0x90,
0x15, 0x8e, 0x10, 0x8d, 0x97, 0xb6, 0xe8, 0x0a, 0x43, 0x9d, 0x0d, 0x15, 0x71, 0xaa, 0x2c, 0x49,
0x2d, 0x0e, 0x82, 0x19, 0x2c, 0x14, 0xc6, 0xc5, 0x9e, 0x94, 0x98, 0x93, 0x98, 0x97, 0x9c, 0x2a,
0xc1, 0xa4, 0xc0, 0xa8, 0xc1, 0xe9, 0x64, 0x03, 0x72, 0xd6, 0xad, 0x7b, 0xf2, 0x6a, 0x44, 0xd8,
0xe3, 0x99, 0x57, 0x72, 0x69, 0x8b, 0x2e, 0x17, 0xd4, 0x02, 0xcf, 0xbc, 0x92, 0x20, 0x98, 0x61,
0x56, 0x1c, 0x20, 0xdf, 0xbc, 0x58, 0x20, 0xcf, 0xe0, 0xe4, 0x7c, 0xe2, 0x91, 0x1c, 0xe3, 0x85,
0x47, 0x72, 0x8c, 0x0f, 0x1e, 0xc9, 0x31, 0x4e, 0x78, 0x2c, 0xc7, 0x70, 0xe1, 0xb1, 0x1c, 0xc3,
0x8d, 0xc7, 0x72, 0x0c, 0x51, 0x9a, 0x48, 0x56, 0x80, 0x82, 0x4a, 0x37, 0x27, 0x31, 0xa9, 0x18,
0xcc, 0xd2, 0xaf, 0x80, 0x47, 0x22, 0xd8, 0xa6, 0x24, 0x36, 0x70, 0xa0, 0x1b, 0x03, 0x02, 0x00,
0x00, 0xff, 0xff, 0x21, 0x8b, 0xca, 0xd4, 0xe1, 0x01, 0x00, 0x00,
}
func (m *GenesisState) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *GenesisState) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if len(m.Accounts) > 0 {
for iNdEx := len(m.Accounts) - 1; iNdEx >= 0; iNdEx-- {
{
size, err := m.Accounts[iNdEx].MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintGenesis(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0xa
}
}
return len(dAtA) - i, nil
}
func (m *Account) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *Account) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *Account) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
{
size := m.Balance.Size()
i -= size
if _, err := m.Balance.MarshalTo(dAtA[i:]); err != nil {
return 0, err
}
i = encodeVarintGenesis(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0x12
if len(m.Address) > 0 {
i -= len(m.Address)
copy(dAtA[i:], m.Address)
i = encodeVarintGenesis(dAtA, i, uint64(len(m.Address)))
i--
dAtA[i] = 0xa
}
return len(dAtA) - i, nil
}
func encodeVarintGenesis(dAtA []byte, offset int, v uint64) int {
offset -= sovGenesis(v)
base := offset
for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80)
v >>= 7
offset++
}
dAtA[offset] = uint8(v)
return base
}
func (m *GenesisState) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
if len(m.Accounts) > 0 {
for _, e := range m.Accounts {
l = e.Size()
n += 1 + l + sovGenesis(uint64(l))
}
}
return n
}
func (m *Account) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
l = len(m.Address)
if l > 0 {
n += 1 + l + sovGenesis(uint64(l))
}
l = m.Balance.Size()
n += 1 + l + sovGenesis(uint64(l))
return n
}
func sovGenesis(x uint64) (n int) {
return (math_bits.Len64(x|1) + 6) / 7
}
func sozGenesis(x uint64) (n int) {
return sovGenesis(uint64((x << 1) ^ uint64((int64(x) >> 63))))
}
func (m *GenesisState) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenesis
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: GenesisState: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: GenesisState: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Accounts", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenesis
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthGenesis
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthGenesis
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Accounts = append(m.Accounts, Account{})
if err := m.Accounts[len(m.Accounts)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipGenesis(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthGenesis
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *Account) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenesis
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: Account: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: Account: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType)
}
var byteLen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenesis
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
byteLen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if byteLen < 0 {
return ErrInvalidLengthGenesis
}
postIndex := iNdEx + byteLen
if postIndex < 0 {
return ErrInvalidLengthGenesis
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Address = append(m.Address[:0], dAtA[iNdEx:postIndex]...)
if m.Address == nil {
m.Address = []byte{}
}
iNdEx = postIndex
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Balance", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenesis
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthGenesis
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthGenesis
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
if err := m.Balance.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipGenesis(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthGenesis
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func skipGenesis(dAtA []byte) (n int, err error) {
l := len(dAtA)
iNdEx := 0
depth := 0
for iNdEx < l {
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowGenesis
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
wireType := int(wire & 0x7)
switch wireType {
case 0:
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowGenesis
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
iNdEx++
if dAtA[iNdEx-1] < 0x80 {
break
}
}
case 1:
iNdEx += 8
case 2:
var length int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowGenesis
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
length |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if length < 0 {
return 0, ErrInvalidLengthGenesis
}
iNdEx += length
case 3:
depth++
case 4:
if depth == 0 {
return 0, ErrUnexpectedEndOfGroupGenesis
}
depth--
case 5:
iNdEx += 4
default:
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
}
if iNdEx < 0 {
return 0, ErrInvalidLengthGenesis
}
if depth == 0 {
return iNdEx, nil
}
}
return 0, io.ErrUnexpectedEOF
}
var (
ErrInvalidLengthGenesis = fmt.Errorf("proto: negative length found during unmarshaling")
ErrIntOverflowGenesis = fmt.Errorf("proto: integer overflow")
ErrUnexpectedEndOfGroupGenesis = fmt.Errorf("proto: unexpected end of group")
)

View File

@ -0,0 +1,62 @@
package types_test
import (
"testing"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/stretchr/testify/require"
"github.com/kava-labs/kava/app"
"github.com/kava-labs/kava/x/evmutil/types"
)
func TestGenesisState_Validate(t *testing.T) {
_, addrs := app.GeneratePrivKeyAddressPairs(2)
tests := []struct {
name string
accounts []types.Account
success bool
}{
{
"dup addresses",
[]types.Account{
{Address: addrs[0], Balance: sdk.NewInt(100)},
{Address: addrs[0], Balance: sdk.NewInt(150)},
},
false,
},
{
"empty account address",
[]types.Account{
{Balance: sdk.NewInt(100)},
},
false,
},
{
"negative account balance",
[]types.Account{
{Address: addrs[0], Balance: sdk.NewInt(-100)},
},
false,
},
{
"valid state",
[]types.Account{
{Address: addrs[0], Balance: sdk.NewInt(100)},
{Address: addrs[1], Balance: sdk.NewInt(150)},
},
true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
gs := types.NewGenesisState(tt.accounts)
err := gs.Validate()
if tt.success {
require.NoError(t, err)
} else {
require.Error(t, err)
}
})
}
}

22
x/evmutil/types/keys.go Normal file
View File

@ -0,0 +1,22 @@
package types
import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/address"
)
const (
// ModuleName name that will be used throughout the module
ModuleName = "evmutil"
StoreKey = "utilevm" // cannot be emvutil due to collision with x/evm
)
var (
AccountStoreKeyPrefix = []byte{0x00} // prefix for keys that store accounts
)
// AccountStoreKey turns an address to a key used to get the account from the store
func AccountStoreKey(addr sdk.AccAddress) []byte {
return append(AccountStoreKeyPrefix, address.MustLengthPrefix(addr)...)
}

View File

@ -53,7 +53,7 @@ func (suite *DelegatorRewardsTestSuite) SetupApp() {
suite.keeper = suite.app.GetIncentiveKeeper()
suite.stakingKeeper = suite.app.GetStakingKeeper()
suite.ctx = suite.app.NewContext(true, tmproto.Header{Height: 1, Time: suite.genesisTime})
suite.ctx = suite.app.NewContext(true, tmproto.Header{Height: 1, Time: suite.genesisTime, ChainID: "kavatest_1-1"})
}
func (suite *DelegatorRewardsTestSuite) SetupWithGenState(authBuilder *app.AuthBankGenesisBuilder, incentBuilder testutil.IncentiveGenesisBuilder) {

View File

@ -29,6 +29,8 @@ import (
swaptypes "github.com/kava-labs/kava/x/swap/types"
)
var testChainID = "kavatest_1-1"
type IntegrationTester struct {
suite.Suite
App app.TestApp
@ -45,12 +47,13 @@ func (suite *IntegrationTester) SetApp() {
}
func (suite *IntegrationTester) StartChain(genesisTime time.Time, genesisStates ...app.GenesisState) {
suite.App.InitializeFromGenesisStatesWithTime(
suite.App.InitializeFromGenesisStatesWithTimeAndChainID(
genesisTime,
testChainID,
genesisStates...,
)
suite.Ctx = suite.App.NewContext(false, tmproto.Header{Height: 1, Time: genesisTime})
suite.Ctx = suite.App.NewContext(false, tmproto.Header{Height: 1, Time: genesisTime, ChainID: testChainID})
}
func (suite *IntegrationTester) NextBlockAt(blockTime time.Time) {
@ -61,7 +64,7 @@ func (suite *IntegrationTester) NextBlockAt(blockTime time.Time) {
_ = suite.App.EndBlocker(suite.Ctx, abcitypes.RequestEndBlock{})
suite.Ctx = suite.Ctx.WithBlockTime(blockTime).WithBlockHeight(blockHeight)
suite.Ctx = suite.Ctx.WithBlockTime(blockTime).WithBlockHeight(blockHeight).WithChainID(testChainID)
_ = suite.App.BeginBlocker(suite.Ctx, abcitypes.RequestBeginBlock{}) // height and time in RequestBeginBlock are ignored by module begin blockers
}

View File

@ -20,6 +20,7 @@ import (
abci "github.com/tendermint/tendermint/abci/types"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
tmtime "github.com/tendermint/tendermint/types/time"
ethermint "github.com/tharsis/ethermint/types"
)
var defaultSwapFee = sdk.MustNewDecFromStr("0.003")
@ -103,7 +104,7 @@ func (suite *Suite) NewAccountFromAddr(addr sdk.AccAddress, balance sdk.Coins) a
// CreateVestingAccount creates a new vesting account from the provided balance and vesting balance
func (suite *Suite) CreateVestingAccount(initialBalance sdk.Coins, vestingBalance sdk.Coins) authtypes.AccountI {
acc := suite.CreateAccount(initialBalance)
bacc := acc.(*authtypes.BaseAccount)
bacc := acc.(*ethermint.EthAccount)
periods := vestingtypes.Periods{
vestingtypes.Period{
@ -111,7 +112,7 @@ func (suite *Suite) CreateVestingAccount(initialBalance sdk.Coins, vestingBalanc
Amount: vestingBalance,
},
}
vacc := vestingtypes.NewPeriodicVestingAccount(bacc, initialBalance, time.Now().Unix(), periods) // TODO is initialBalance correct for originalVesting?
vacc := vestingtypes.NewPeriodicVestingAccount(bacc.BaseAccount, initialBalance, time.Now().Unix(), periods) // TODO is initialBalance correct for originalVesting?
return vacc
}