update sdk and app pkg

This commit is contained in:
rhuairahrighairigh 2019-07-18 18:36:31 +01:00
parent f1720eefc2
commit d73cfc7167
10 changed files with 713 additions and 1322 deletions

View File

@ -1,10 +1,8 @@
package app package app
import ( import (
"fmt"
"io" "io"
"os" "os"
"sort"
abci "github.com/tendermint/tendermint/abci/types" abci "github.com/tendermint/tendermint/abci/types"
cmn "github.com/tendermint/tendermint/libs/common" cmn "github.com/tendermint/tendermint/libs/common"
@ -14,30 +12,67 @@ import (
bam "github.com/cosmos/cosmos-sdk/baseapp" bam "github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types" sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/module"
"github.com/cosmos/cosmos-sdk/version"
"github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/auth"
"github.com/cosmos/cosmos-sdk/x/bank" "github.com/cosmos/cosmos-sdk/x/bank"
"github.com/cosmos/cosmos-sdk/x/crisis" "github.com/cosmos/cosmos-sdk/x/crisis"
distr "github.com/cosmos/cosmos-sdk/x/distribution" distr "github.com/cosmos/cosmos-sdk/x/distribution"
distrclient "github.com/cosmos/cosmos-sdk/x/distribution/client"
"github.com/cosmos/cosmos-sdk/x/genaccounts"
"github.com/cosmos/cosmos-sdk/x/genutil"
"github.com/cosmos/cosmos-sdk/x/gov" "github.com/cosmos/cosmos-sdk/x/gov"
"github.com/cosmos/cosmos-sdk/x/mint" "github.com/cosmos/cosmos-sdk/x/mint"
"github.com/cosmos/cosmos-sdk/x/params" "github.com/cosmos/cosmos-sdk/x/params"
paramsclient "github.com/cosmos/cosmos-sdk/x/params/client"
"github.com/cosmos/cosmos-sdk/x/slashing" "github.com/cosmos/cosmos-sdk/x/slashing"
"github.com/cosmos/cosmos-sdk/x/staking" "github.com/cosmos/cosmos-sdk/x/staking"
"github.com/cosmos/cosmos-sdk/x/supply"
) )
// TODO investigate monkey patch import
const ( const (
appName = "kava" appName = "kava"
// DefaultKeyPass contains the default key password for genesis transactions
DefaultKeyPass = "12345678"
Bech32MainPrefix = "kava" Bech32MainPrefix = "kava"
) )
// default home directories for expected binaries
var ( var (
// default home directories for expected binaries
DefaultCLIHome = os.ExpandEnv("$HOME/.kvcli") DefaultCLIHome = os.ExpandEnv("$HOME/.kvcli")
DefaultNodeHome = os.ExpandEnv("$HOME/.kvd") DefaultNodeHome = os.ExpandEnv("$HOME/.kvd")
// _ manages simple versions of full app modules. It's used for things such as codec registration and genesis file verification
ModuleBasics module.BasicManager // TODO rename
// module account permissions
mAccPerms = map[string][]string{
auth.FeeCollectorName: nil,
distr.ModuleName: nil,
mint.ModuleName: {supply.Minter},
staking.BondedPoolName: {supply.Burner, supply.Staking},
staking.NotBondedPoolName: {supply.Burner, supply.Staking},
gov.ModuleName: {supply.Burner},
}
) )
func init() {
ModuleBasics = module.NewBasicManager(
genaccounts.AppModuleBasic{},
genutil.AppModuleBasic{},
auth.AppModuleBasic{},
bank.AppModuleBasic{},
staking.AppModuleBasic{},
mint.AppModuleBasic{},
distr.AppModuleBasic{},
gov.NewAppModuleBasic(paramsclient.ProposalHandler, distrclient.ProposalHandler),
params.AppModuleBasic{},
crisis.AppModuleBasic{},
slashing.AppModuleBasic{},
supply.AppModuleBasic{},
)
}
// Extended ABCI application // Extended ABCI application
type App struct { type App struct {
*bam.BaseApp *bam.BaseApp
@ -48,6 +83,7 @@ type App struct {
// keys to access the substores // keys to access the substores
keyMain *sdk.KVStoreKey keyMain *sdk.KVStoreKey
keyAccount *sdk.KVStoreKey keyAccount *sdk.KVStoreKey
keySupply *sdk.KVStoreKey
keyStaking *sdk.KVStoreKey keyStaking *sdk.KVStoreKey
tkeyStaking *sdk.TransientStoreKey tkeyStaking *sdk.TransientStoreKey
keySlashing *sdk.KVStoreKey keySlashing *sdk.KVStoreKey
@ -55,14 +91,13 @@ type App struct {
keyDistr *sdk.KVStoreKey keyDistr *sdk.KVStoreKey
tkeyDistr *sdk.TransientStoreKey tkeyDistr *sdk.TransientStoreKey
keyGov *sdk.KVStoreKey keyGov *sdk.KVStoreKey
keyFeeCollection *sdk.KVStoreKey
keyParams *sdk.KVStoreKey keyParams *sdk.KVStoreKey
tkeyParams *sdk.TransientStoreKey tkeyParams *sdk.TransientStoreKey
// Manage getting and setting accounts // Manage getting and setting accounts
accountKeeper auth.AccountKeeper accountKeeper auth.AccountKeeper
feeCollectionKeeper auth.FeeCollectionKeeper
bankKeeper bank.Keeper bankKeeper bank.Keeper
supplyKeeper supply.Keeper
stakingKeeper staking.Keeper stakingKeeper staking.Keeper
slashingKeeper slashing.Keeper slashingKeeper slashing.Keeper
mintKeeper mint.Keeper mintKeeper mint.Keeper
@ -70,6 +105,9 @@ type App struct {
govKeeper gov.Keeper govKeeper gov.Keeper
crisisKeeper crisis.Keeper crisisKeeper crisis.Keeper
paramsKeeper params.Keeper paramsKeeper params.Keeper
// the module manager
mm *module.Manager
} }
// NewApp returns a reference to an initialized App. // NewApp returns a reference to an initialized App.
@ -81,6 +119,7 @@ func NewApp(logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest bool,
bApp := bam.NewBaseApp(appName, logger, db, auth.DefaultTxDecoder(cdc), baseAppOptions...) bApp := bam.NewBaseApp(appName, logger, db, auth.DefaultTxDecoder(cdc), baseAppOptions...)
bApp.SetCommitMultiStoreTracer(traceStore) bApp.SetCommitMultiStoreTracer(traceStore)
bApp.SetAppVersion(version.Version)
var app = &App{ var app = &App{
BaseApp: bApp, BaseApp: bApp,
@ -88,6 +127,7 @@ func NewApp(logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest bool,
invCheckPeriod: invCheckPeriod, invCheckPeriod: invCheckPeriod,
keyMain: sdk.NewKVStoreKey(bam.MainStoreKey), keyMain: sdk.NewKVStoreKey(bam.MainStoreKey),
keyAccount: sdk.NewKVStoreKey(auth.StoreKey), keyAccount: sdk.NewKVStoreKey(auth.StoreKey),
keySupply: sdk.NewKVStoreKey(supply.StoreKey),
keyStaking: sdk.NewKVStoreKey(staking.StoreKey), keyStaking: sdk.NewKVStoreKey(staking.StoreKey),
tkeyStaking: sdk.NewTransientStoreKey(staking.TStoreKey), tkeyStaking: sdk.NewTransientStoreKey(staking.TStoreKey),
keyMint: sdk.NewKVStoreKey(mint.StoreKey), keyMint: sdk.NewKVStoreKey(mint.StoreKey),
@ -95,106 +135,132 @@ func NewApp(logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest bool,
tkeyDistr: sdk.NewTransientStoreKey(distr.TStoreKey), tkeyDistr: sdk.NewTransientStoreKey(distr.TStoreKey),
keySlashing: sdk.NewKVStoreKey(slashing.StoreKey), keySlashing: sdk.NewKVStoreKey(slashing.StoreKey),
keyGov: sdk.NewKVStoreKey(gov.StoreKey), keyGov: sdk.NewKVStoreKey(gov.StoreKey),
keyFeeCollection: sdk.NewKVStoreKey(auth.FeeStoreKey),
keyParams: sdk.NewKVStoreKey(params.StoreKey), keyParams: sdk.NewKVStoreKey(params.StoreKey),
tkeyParams: sdk.NewTransientStoreKey(params.TStoreKey), tkeyParams: sdk.NewTransientStoreKey(params.TStoreKey),
} }
app.paramsKeeper = params.NewKeeper(app.cdc, app.keyParams, app.tkeyParams) // init params keeper and subspaces
app.paramsKeeper = params.NewKeeper(app.cdc, app.keyParams, app.tkeyParams, params.DefaultCodespace)
authSubspace := app.paramsKeeper.Subspace(auth.DefaultParamspace)
bankSubspace := app.paramsKeeper.Subspace(bank.DefaultParamspace)
stakingSubspace := app.paramsKeeper.Subspace(staking.DefaultParamspace)
mintSubspace := app.paramsKeeper.Subspace(mint.DefaultParamspace)
distrSubspace := app.paramsKeeper.Subspace(distr.DefaultParamspace)
slashingSubspace := app.paramsKeeper.Subspace(slashing.DefaultParamspace)
govSubspace := app.paramsKeeper.Subspace(gov.DefaultParamspace)
crisisSubspace := app.paramsKeeper.Subspace(crisis.DefaultParamspace)
// define the accountKeeper // add keepers
app.accountKeeper = auth.NewAccountKeeper( app.accountKeeper = auth.NewAccountKeeper(
app.cdc, app.cdc,
app.keyAccount, app.keyAccount,
app.paramsKeeper.Subspace(auth.DefaultParamspace), authSubspace,
auth.ProtoBaseAccount, auth.ProtoBaseAccount)
)
// add handlers
app.bankKeeper = bank.NewBaseKeeper( app.bankKeeper = bank.NewBaseKeeper(
app.accountKeeper, app.accountKeeper,
app.paramsKeeper.Subspace(bank.DefaultParamspace), bankSubspace,
bank.DefaultCodespace, bank.DefaultCodespace)
) app.supplyKeeper = supply.NewKeeper(
app.feeCollectionKeeper = auth.NewFeeCollectionKeeper(
app.cdc, app.cdc,
app.keyFeeCollection, app.keySupply,
) app.accountKeeper,
app.bankKeeper,
supply.DefaultCodespace,
mAccPerms)
stakingKeeper := staking.NewKeeper( stakingKeeper := staking.NewKeeper(
app.cdc, app.cdc,
app.keyStaking, app.tkeyStaking, app.keyStaking,
app.bankKeeper, app.paramsKeeper.Subspace(staking.DefaultParamspace), app.tkeyStaking,
staking.DefaultCodespace, app.supplyKeeper,
) stakingSubspace,
app.mintKeeper = mint.NewKeeper(app.cdc, app.keyMint, staking.DefaultCodespace)
app.paramsKeeper.Subspace(mint.DefaultParamspace), app.mintKeeper = mint.NewKeeper(
&stakingKeeper, app.feeCollectionKeeper, app.cdc,
) app.keyMint,
mintSubspace,
&stakingKeeper,
app.supplyKeeper,
auth.FeeCollectorName)
app.distrKeeper = distr.NewKeeper( app.distrKeeper = distr.NewKeeper(
app.cdc, app.cdc,
app.keyDistr, app.keyDistr,
app.paramsKeeper.Subspace(distr.DefaultParamspace), distrSubspace,
app.bankKeeper, &stakingKeeper, app.feeCollectionKeeper, &stakingKeeper,
app.supplyKeeper,
distr.DefaultCodespace, distr.DefaultCodespace,
) auth.FeeCollectorName)
app.slashingKeeper = slashing.NewKeeper( app.slashingKeeper = slashing.NewKeeper(
app.cdc, app.cdc,
app.keySlashing, app.keySlashing,
&stakingKeeper, app.paramsKeeper.Subspace(slashing.DefaultParamspace), &stakingKeeper,
slashing.DefaultCodespace, slashingSubspace,
) slashing.DefaultCodespace)
app.crisisKeeper = crisis.NewKeeper(
crisisSubspace,
invCheckPeriod,
app.supplyKeeper,
auth.FeeCollectorName)
govRouter := gov.NewRouter()
govRouter.
AddRoute(gov.RouterKey, gov.ProposalHandler).
AddRoute(params.RouterKey, params.NewParamChangeProposalHandler(app.paramsKeeper)).
AddRoute(distr.RouterKey, distr.NewCommunityPoolSpendProposalHandler(app.distrKeeper))
app.govKeeper = gov.NewKeeper( app.govKeeper = gov.NewKeeper(
app.cdc, app.cdc,
app.keyGov, app.keyGov,
app.paramsKeeper, app.paramsKeeper.Subspace(gov.DefaultParamspace), app.bankKeeper, &stakingKeeper, app.paramsKeeper,
govSubspace,
app.supplyKeeper,
&stakingKeeper,
gov.DefaultCodespace, gov.DefaultCodespace,
) govRouter)
app.crisisKeeper = crisis.NewKeeper(
app.paramsKeeper.Subspace(crisis.DefaultParamspace),
app.distrKeeper,
app.bankKeeper,
app.feeCollectionKeeper,
)
// register the staking hooks // register the staking hooks
// NOTE: The stakingKeeper above is passed by reference, so that it can be // NOTE: stakingKeeper above is passed by reference, so that it will contain these hooks
// modified like below:
app.stakingKeeper = *stakingKeeper.SetHooks( app.stakingKeeper = *stakingKeeper.SetHooks(
NewStakingHooks(app.distrKeeper.Hooks(), app.slashingKeeper.Hooks()), staking.NewMultiStakingHooks(app.distrKeeper.Hooks(), app.slashingKeeper.Hooks()))
// create the module manager
app.mm = module.NewManager(
genaccounts.NewAppModule(app.accountKeeper),
genutil.NewAppModule(app.accountKeeper, app.stakingKeeper, app.BaseApp.DeliverTx),
auth.NewAppModule(app.accountKeeper),
bank.NewAppModule(app.bankKeeper, app.accountKeeper),
crisis.NewAppModule(app.crisisKeeper),
supply.NewAppModule(app.supplyKeeper, app.accountKeeper),
distr.NewAppModule(app.distrKeeper, app.supplyKeeper),
gov.NewAppModule(app.govKeeper, app.supplyKeeper),
mint.NewAppModule(app.mintKeeper),
slashing.NewAppModule(app.slashingKeeper, app.stakingKeeper),
staking.NewAppModule(app.stakingKeeper, app.distrKeeper, app.accountKeeper, app.supplyKeeper),
) )
// register the crisis routes // During begin block slashing happens after distr.BeginBlocker so that
bank.RegisterInvariants(&app.crisisKeeper, app.accountKeeper) // there is nothing left over in the validator fee pool, so as to keep the
distr.RegisterInvariants(&app.crisisKeeper, app.distrKeeper, app.stakingKeeper) // CanWithdrawInvariant invariant.
staking.RegisterInvariants(&app.crisisKeeper, app.stakingKeeper, app.feeCollectionKeeper, app.distrKeeper, app.accountKeeper) app.mm.SetOrderBeginBlockers(mint.ModuleName, distr.ModuleName, slashing.ModuleName)
// register message routes app.mm.SetOrderEndBlockers(gov.ModuleName, staking.ModuleName)
app.Router().
AddRoute(bank.RouterKey, bank.NewHandler(app.bankKeeper)).
AddRoute(staking.RouterKey, staking.NewHandler(app.stakingKeeper)).
AddRoute(distr.RouterKey, distr.NewHandler(app.distrKeeper)).
AddRoute(slashing.RouterKey, slashing.NewHandler(app.slashingKeeper)).
AddRoute(gov.RouterKey, gov.NewHandler(app.govKeeper)).
AddRoute(crisis.RouterKey, crisis.NewHandler(app.crisisKeeper))
app.QueryRouter(). // genutils must occur after staking so that pools are properly
AddRoute(auth.QuerierRoute, auth.NewQuerier(app.accountKeeper)). // initialized with tokens from genesis accounts.
AddRoute(distr.QuerierRoute, distr.NewQuerier(app.distrKeeper)). app.mm.SetOrderInitGenesis(genaccounts.ModuleName, distr.ModuleName,
AddRoute(gov.QuerierRoute, gov.NewQuerier(app.govKeeper)). staking.ModuleName, auth.ModuleName, bank.ModuleName, slashing.ModuleName,
AddRoute(slashing.QuerierRoute, slashing.NewQuerier(app.slashingKeeper, app.cdc)). gov.ModuleName, mint.ModuleName, supply.ModuleName, crisis.ModuleName, genutil.ModuleName)
AddRoute(staking.QuerierRoute, staking.NewQuerier(app.stakingKeeper, app.cdc)).
AddRoute(mint.QuerierRoute, mint.NewQuerier(app.mintKeeper))
// initialize BaseApp app.mm.RegisterInvariants(&app.crisisKeeper)
app.MountStores(app.keyMain, app.keyAccount, app.keyStaking, app.keyMint, app.keyDistr, app.mm.RegisterRoutes(app.Router(), app.QueryRouter())
app.keySlashing, app.keyGov, app.keyFeeCollection, app.keyParams,
app.tkeyParams, app.tkeyStaking, app.tkeyDistr, // initialize the app
) app.MountStores(app.keyMain, app.keyAccount, app.keySupply, app.keyStaking,
app.SetInitChainer(app.initChainer) app.keyMint, app.keyDistr, app.keySlashing, app.keyGov, app.keyParams,
app.tkeyParams, app.tkeyStaking, app.tkeyDistr)
app.SetInitChainer(app.InitChainer)
app.SetBeginBlocker(app.BeginBlocker) app.SetBeginBlocker(app.BeginBlocker)
app.SetAnteHandler(auth.NewAnteHandler(app.accountKeeper, app.feeCollectionKeeper)) app.SetAnteHandler(auth.NewAnteHandler(app.accountKeeper, app.supplyKeeper, auth.DefaultSigVerificationGasConsumer))
app.SetEndBlocker(app.EndBlocker) app.SetEndBlocker(app.EndBlocker)
// load store
if loadLatest { if loadLatest {
err := app.LoadLatestVersion(app.keyMain) err := app.LoadLatestVersion(app.keyMain)
if err != nil { if err != nil {
@ -208,13 +274,7 @@ func NewApp(logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest bool,
// custom tx codec // custom tx codec
func MakeCodec() *codec.Codec { func MakeCodec() *codec.Codec {
var cdc = codec.New() var cdc = codec.New()
bank.RegisterCodec(cdc) ModuleBasics.RegisterCodec(cdc)
staking.RegisterCodec(cdc)
distr.RegisterCodec(cdc)
slashing.RegisterCodec(cdc)
gov.RegisterCodec(cdc)
auth.RegisterCodec(cdc)
crisis.RegisterCodec(cdc)
sdk.RegisterCodec(cdc) sdk.RegisterCodec(cdc)
codec.RegisterCrypto(cdc) codec.RegisterCrypto(cdc)
return cdc return cdc
@ -228,128 +288,19 @@ func SetBech32AddressPrefixes(config *sdk.Config) {
// application updates every end block // application updates every end block
func (app *App) BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock) abci.ResponseBeginBlock { func (app *App) BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock) abci.ResponseBeginBlock {
// mint new tokens for the previous block return app.mm.BeginBlock(ctx, req)
mint.BeginBlocker(ctx, app.mintKeeper)
// distribute rewards for the previous block
distr.BeginBlocker(ctx, req, app.distrKeeper)
// slash anyone who double signed.
// NOTE: This should happen after distr.BeginBlocker so that
// there is nothing left over in the validator fee pool,
// so as to keep the CanWithdrawInvariant invariant.
// TODO: This should really happen at EndBlocker.
tags := slashing.BeginBlocker(ctx, req, app.slashingKeeper)
return abci.ResponseBeginBlock{
Tags: tags.ToKVPairs(),
}
} }
// application updates every end block // application updates every end block
// nolint: unparam
func (app *App) EndBlocker(ctx sdk.Context, req abci.RequestEndBlock) abci.ResponseEndBlock { func (app *App) EndBlocker(ctx sdk.Context, req abci.RequestEndBlock) abci.ResponseEndBlock {
tags := gov.EndBlocker(ctx, app.govKeeper) return app.mm.EndBlock(ctx, req)
validatorUpdates, endBlockerTags := staking.EndBlocker(ctx, app.stakingKeeper)
tags = append(tags, endBlockerTags...)
if app.invCheckPeriod != 0 && ctx.BlockHeight()%int64(app.invCheckPeriod) == 0 {
app.assertRuntimeInvariants()
}
return abci.ResponseEndBlock{
ValidatorUpdates: validatorUpdates,
Tags: tags,
}
}
// initialize store from a genesis state
func (app *App) initFromGenesisState(ctx sdk.Context, genesisState GenesisState) []abci.ValidatorUpdate {
genesisState.Sanitize()
// load the accounts
for _, gacc := range genesisState.Accounts {
acc := gacc.ToAccount()
acc = app.accountKeeper.NewAccount(ctx, acc) // set account number
app.accountKeeper.SetAccount(ctx, acc)
}
// initialize distribution (must happen before staking)
distr.InitGenesis(ctx, app.distrKeeper, genesisState.DistrData)
// load the initial staking information
validators, err := staking.InitGenesis(ctx, app.stakingKeeper, genesisState.StakingData)
if err != nil {
panic(err) // TODO find a way to do this w/o panics
}
// initialize module-specific stores
auth.InitGenesis(ctx, app.accountKeeper, app.feeCollectionKeeper, genesisState.AuthData)
bank.InitGenesis(ctx, app.bankKeeper, genesisState.BankData)
slashing.InitGenesis(ctx, app.slashingKeeper, genesisState.SlashingData, genesisState.StakingData.Validators.ToSDKValidators())
gov.InitGenesis(ctx, app.govKeeper, genesisState.GovData)
crisis.InitGenesis(ctx, app.crisisKeeper, genesisState.CrisisData)
mint.InitGenesis(ctx, app.mintKeeper, genesisState.MintData)
// validate genesis state
if err := ValidateGenesisState(genesisState); err != nil {
panic(err) // TODO find a way to do this w/o panics
}
if len(genesisState.GenTxs) > 0 {
for _, genTx := range genesisState.GenTxs {
var tx auth.StdTx
err = app.cdc.UnmarshalJSON(genTx, &tx)
if err != nil {
panic(err)
}
bz := app.cdc.MustMarshalBinaryLengthPrefixed(tx)
res := app.BaseApp.DeliverTx(bz)
if !res.IsOK() {
panic(res.Log)
}
}
validators = app.stakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx)
}
return validators
} }
// custom logic for app initialization // custom logic for app initialization
func (app *App) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain { func (app *App) InitChainer(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain {
stateJSON := req.AppStateBytes
// TODO is this now the whole genesis file?
var genesisState GenesisState var genesisState GenesisState
err := app.cdc.UnmarshalJSON(stateJSON, &genesisState) app.cdc.MustUnmarshalJSON(req.AppStateBytes, &genesisState)
if err != nil { return app.mm.InitGenesis(ctx, genesisState)
panic(err) // TODO https://github.com/cosmos/cosmos-sdk/issues/468
// return sdk.ErrGenesisParse("").TraceCause(err, "")
}
validators := app.initFromGenesisState(ctx, genesisState)
// sanity check
if len(req.Validators) > 0 {
if len(req.Validators) != len(validators) {
panic(fmt.Errorf("len(RequestInitChain.Validators) != len(validators) (%d != %d)",
len(req.Validators), len(validators)))
}
sort.Sort(abci.ValidatorUpdates(req.Validators))
sort.Sort(abci.ValidatorUpdates(validators))
for i, val := range validators {
if !val.Equal(req.Validators[i]) {
panic(fmt.Errorf("validators[%d] != req.Validators[%d] ", i, i))
}
}
}
// assert runtime invariants
app.assertRuntimeInvariants()
return abci.ResponseInitChain{
Validators: validators,
}
} }
// load a particular height // load a particular height
@ -357,59 +308,13 @@ func (app *App) LoadHeight(height int64) error {
return app.LoadVersion(height, app.keyMain) return app.LoadVersion(height, app.keyMain)
} }
// ______________________________________________________________________________________________ // TODO only used in sim test, needed?
// ModuleAccountAddrs returns all the app's module account addresses.
func (app *App) ModuleAccountAddrs() map[string]bool {
modAccAddrs := make(map[string]bool)
for acc := range mAccPerms {
modAccAddrs[app.supplyKeeper.GetModuleAddress(acc).String()] = true
}
var _ sdk.StakingHooks = StakingHooks{} return modAccAddrs
// StakingHooks contains combined distribution and slashing hooks needed for the
// staking module.
type StakingHooks struct {
dh distr.Hooks
sh slashing.Hooks
}
func NewStakingHooks(dh distr.Hooks, sh slashing.Hooks) StakingHooks {
return StakingHooks{dh, sh}
}
// nolint
func (h StakingHooks) AfterValidatorCreated(ctx sdk.Context, valAddr sdk.ValAddress) {
h.dh.AfterValidatorCreated(ctx, valAddr)
h.sh.AfterValidatorCreated(ctx, valAddr)
}
func (h StakingHooks) BeforeValidatorModified(ctx sdk.Context, valAddr sdk.ValAddress) {
h.dh.BeforeValidatorModified(ctx, valAddr)
h.sh.BeforeValidatorModified(ctx, valAddr)
}
func (h StakingHooks) AfterValidatorRemoved(ctx sdk.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) {
h.dh.AfterValidatorRemoved(ctx, consAddr, valAddr)
h.sh.AfterValidatorRemoved(ctx, consAddr, valAddr)
}
func (h StakingHooks) AfterValidatorBonded(ctx sdk.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) {
h.dh.AfterValidatorBonded(ctx, consAddr, valAddr)
h.sh.AfterValidatorBonded(ctx, consAddr, valAddr)
}
func (h StakingHooks) AfterValidatorBeginUnbonding(ctx sdk.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) {
h.dh.AfterValidatorBeginUnbonding(ctx, consAddr, valAddr)
h.sh.AfterValidatorBeginUnbonding(ctx, consAddr, valAddr)
}
func (h StakingHooks) BeforeDelegationCreated(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) {
h.dh.BeforeDelegationCreated(ctx, delAddr, valAddr)
h.sh.BeforeDelegationCreated(ctx, delAddr, valAddr)
}
func (h StakingHooks) BeforeDelegationSharesModified(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) {
h.dh.BeforeDelegationSharesModified(ctx, delAddr, valAddr)
h.sh.BeforeDelegationSharesModified(ctx, delAddr, valAddr)
}
func (h StakingHooks) BeforeDelegationRemoved(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) {
h.dh.BeforeDelegationRemoved(ctx, delAddr, valAddr)
h.sh.BeforeDelegationRemoved(ctx, delAddr, valAddr)
}
func (h StakingHooks) AfterDelegationModified(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) {
h.dh.AfterDelegationModified(ctx, delAddr, valAddr)
h.sh.AfterDelegationModified(ctx, delAddr, valAddr)
}
func (h StakingHooks) BeforeValidatorSlashed(ctx sdk.Context, valAddr sdk.ValAddress, fraction sdk.Dec) {
h.dh.BeforeValidatorSlashed(ctx, valAddr, fraction)
h.sh.BeforeValidatorSlashed(ctx, valAddr, fraction)
} }

View File

@ -4,55 +4,15 @@ import (
"os" "os"
"testing" "testing"
"github.com/cosmos/cosmos-sdk/x/bank"
"github.com/cosmos/cosmos-sdk/x/crisis"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/tendermint/tendermint/libs/db" "github.com/tendermint/tendermint/libs/db"
"github.com/tendermint/tendermint/libs/log" "github.com/tendermint/tendermint/libs/log"
"github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/x/auth"
distr "github.com/cosmos/cosmos-sdk/x/distribution"
"github.com/cosmos/cosmos-sdk/x/gov"
"github.com/cosmos/cosmos-sdk/x/mint"
"github.com/cosmos/cosmos-sdk/x/slashing"
"github.com/cosmos/cosmos-sdk/x/staking"
abci "github.com/tendermint/tendermint/abci/types" abci "github.com/tendermint/tendermint/abci/types"
) )
func setGenesis(app *App, accs ...*auth.BaseAccount) error {
genaccs := make([]GenesisAccount, len(accs))
for i, acc := range accs {
genaccs[i] = NewGenesisAccount(acc)
}
genesisState := NewGenesisState(
genaccs,
auth.DefaultGenesisState(),
bank.DefaultGenesisState(),
staking.DefaultGenesisState(),
mint.DefaultGenesisState(),
distr.DefaultGenesisState(),
gov.DefaultGenesisState(),
crisis.DefaultGenesisState(),
slashing.DefaultGenesisState(),
)
stateBytes, err := codec.MarshalJSONIndent(app.cdc, genesisState)
if err != nil {
return err
}
// Initialize the chain
vals := []abci.ValidatorUpdate{}
app.InitChain(abci.RequestInitChain{Validators: vals, AppStateBytes: stateBytes})
app.Commit()
return nil
}
func TestExport(t *testing.T) { func TestExport(t *testing.T) {
db := db.NewMemDB() db := db.NewMemDB()
app := NewApp(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, nil, true, 0) app := NewApp(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, nil, true, 0)
@ -63,3 +23,23 @@ func TestExport(t *testing.T) {
_, _, err := newApp.ExportAppStateAndValidators(false, []string{}) _, _, err := newApp.ExportAppStateAndValidators(false, []string{})
require.NoError(t, err, "ExportAppStateAndValidators should not have an error") require.NoError(t, err, "ExportAppStateAndValidators should not have an error")
} }
func setGenesis(app *App) error {
genesisState := NewDefaultGenesisState()
stateBytes, err := codec.MarshalJSONIndent(app.cdc, genesisState)
if err != nil {
return err
}
// Initialize the chain
app.InitChain(
abci.RequestInitChain{
Validators: []abci.ValidatorUpdate{},
AppStateBytes: stateBytes,
},
)
app.Commit()
return nil
}

View File

@ -8,6 +8,7 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types" sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/auth"
"github.com/cosmos/cosmos-sdk/x/bank" "github.com/cosmos/cosmos-sdk/x/bank"
"github.com/kava-labs/kava/app" "github.com/kava-labs/kava/app"
) )

View File

@ -9,12 +9,6 @@ import (
"github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types" sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth"
"github.com/cosmos/cosmos-sdk/x/bank"
"github.com/cosmos/cosmos-sdk/x/crisis"
distr "github.com/cosmos/cosmos-sdk/x/distribution"
"github.com/cosmos/cosmos-sdk/x/gov"
"github.com/cosmos/cosmos-sdk/x/mint"
"github.com/cosmos/cosmos-sdk/x/slashing" "github.com/cosmos/cosmos-sdk/x/slashing"
"github.com/cosmos/cosmos-sdk/x/staking" "github.com/cosmos/cosmos-sdk/x/staking"
) )
@ -30,26 +24,8 @@ func (app *App) ExportAppStateAndValidators(forZeroHeight bool, jailWhiteList []
app.prepForZeroHeightGenesis(ctx, jailWhiteList) app.prepForZeroHeightGenesis(ctx, jailWhiteList)
} }
// iterate to get the accounts genState := app.mm.ExportGenesis(ctx)
accounts := []GenesisAccount{}
appendAccount := func(acc auth.Account) (stop bool) {
account := NewGenesisAccountI(acc)
accounts = append(accounts, account)
return false
}
app.accountKeeper.IterateAccounts(ctx, appendAccount)
genState := NewGenesisState(
accounts,
auth.ExportGenesis(ctx, app.accountKeeper, app.feeCollectionKeeper),
bank.ExportGenesis(ctx, app.bankKeeper),
staking.ExportGenesis(ctx, app.stakingKeeper),
mint.ExportGenesis(ctx, app.mintKeeper),
distr.ExportGenesis(ctx, app.distrKeeper),
gov.ExportGenesis(ctx, app.govKeeper),
crisis.ExportGenesis(ctx, app.crisisKeeper),
slashing.ExportGenesis(ctx, app.slashingKeeper),
)
appState, err = codec.MarshalJSONIndent(app.cdc, genState) appState, err = codec.MarshalJSONIndent(app.cdc, genState)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
@ -78,12 +54,12 @@ func (app *App) prepForZeroHeightGenesis(ctx sdk.Context, jailWhiteList []string
} }
/* Just to be safe, assert the invariants on current state. */ /* Just to be safe, assert the invariants on current state. */
app.assertRuntimeInvariantsOnContext(ctx) app.crisisKeeper.AssertInvariants(ctx)
/* Handle fee distribution state. */ /* Handle fee distribution state. */
// withdraw all validator commission // withdraw all validator commission
app.stakingKeeper.IterateValidators(ctx, func(_ int64, val sdk.Validator) (stop bool) { app.stakingKeeper.IterateValidators(ctx, func(_ int64, val staking.ValidatorI) (stop bool) {
_, _ = app.distrKeeper.WithdrawValidatorCommission(ctx, val.GetOperator()) _, _ = app.distrKeeper.WithdrawValidatorCommission(ctx, val.GetOperator())
return false return false
}) })
@ -105,7 +81,7 @@ func (app *App) prepForZeroHeightGenesis(ctx sdk.Context, jailWhiteList []string
ctx = ctx.WithBlockHeight(0) ctx = ctx.WithBlockHeight(0)
// reinitialize all validators // reinitialize all validators
app.stakingKeeper.IterateValidators(ctx, func(_ int64, val sdk.Validator) (stop bool) { app.stakingKeeper.IterateValidators(ctx, func(_ int64, val staking.ValidatorI) (stop bool) {
// donate any unwithdrawn outstanding reward fraction tokens to the community pool // donate any unwithdrawn outstanding reward fraction tokens to the community pool
scraps := app.distrKeeper.GetValidatorOutstandingRewards(ctx, val.GetOperator()) scraps := app.distrKeeper.GetValidatorOutstandingRewards(ctx, val.GetOperator())

View File

@ -2,416 +2,18 @@ package app
import ( import (
"encoding/json" "encoding/json"
"errors"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"sort"
"strings"
"time"
tmtypes "github.com/tendermint/tendermint/types"
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth"
"github.com/cosmos/cosmos-sdk/x/bank"
"github.com/cosmos/cosmos-sdk/x/crisis"
distr "github.com/cosmos/cosmos-sdk/x/distribution"
"github.com/cosmos/cosmos-sdk/x/gov"
"github.com/cosmos/cosmos-sdk/x/mint"
"github.com/cosmos/cosmos-sdk/x/slashing"
"github.com/cosmos/cosmos-sdk/x/staking"
) )
var ( // The genesis state of the blockchain is represented here as a map of raw json
// bonded tokens given to genesis validators/accounts // messages key'd by a identifier string.
freeTokensPerAcc = sdk.TokensFromTendermintPower(150) // The identifier is used to determine which module genesis information belongs
defaultBondDenom = sdk.DefaultBondDenom // to so it may be appropriately routed during init chain.
) // Within this application default genesis information is retrieved from
// the ModuleBasicManager which populates json from each BasicModule
// object provided to it during init.
type GenesisState map[string]json.RawMessage
// State to Unmarshal // NewDefaultGenesisState generates the default state for the application.
type GenesisState struct {
Accounts []GenesisAccount `json:"accounts"`
AuthData auth.GenesisState `json:"auth"`
BankData bank.GenesisState `json:"bank"`
StakingData staking.GenesisState `json:"staking"`
MintData mint.GenesisState `json:"mint"`
DistrData distr.GenesisState `json:"distr"`
GovData gov.GenesisState `json:"gov"`
CrisisData crisis.GenesisState `json:"crisis"`
SlashingData slashing.GenesisState `json:"slashing"`
GenTxs []json.RawMessage `json:"gentxs"`
}
func NewGenesisState(accounts []GenesisAccount, authData auth.GenesisState,
bankData bank.GenesisState,
stakingData staking.GenesisState, mintData mint.GenesisState,
distrData distr.GenesisState, govData gov.GenesisState, crisisData crisis.GenesisState,
slashingData slashing.GenesisState) GenesisState {
return GenesisState{
Accounts: accounts,
AuthData: authData,
BankData: bankData,
StakingData: stakingData,
MintData: mintData,
DistrData: distrData,
GovData: govData,
CrisisData: crisisData,
SlashingData: slashingData,
}
}
// Sanitize sorts accounts and coin sets.
func (gs GenesisState) Sanitize() {
sort.Slice(gs.Accounts, func(i, j int) bool {
return gs.Accounts[i].AccountNumber < gs.Accounts[j].AccountNumber
})
for _, acc := range gs.Accounts {
acc.Coins = acc.Coins.Sort()
}
}
// GenesisAccount defines an account initialized at genesis.
type GenesisAccount struct {
Address sdk.AccAddress `json:"address"`
Coins sdk.Coins `json:"coins"`
Sequence uint64 `json:"sequence_number"`
AccountNumber uint64 `json:"account_number"`
// vesting account fields
OriginalVesting sdk.Coins `json:"original_vesting"` // total vesting coins upon initialization
DelegatedFree sdk.Coins `json:"delegated_free"` // delegated vested coins at time of delegation
DelegatedVesting sdk.Coins `json:"delegated_vesting"` // delegated vesting coins at time of delegation
StartTime int64 `json:"start_time"` // vesting start time (UNIX Epoch time)
EndTime int64 `json:"end_time"` // vesting end time (UNIX Epoch time)
}
func NewGenesisAccount(acc *auth.BaseAccount) GenesisAccount {
return GenesisAccount{
Address: acc.Address,
Coins: acc.Coins,
AccountNumber: acc.AccountNumber,
Sequence: acc.Sequence,
}
}
func NewGenesisAccountI(acc auth.Account) GenesisAccount {
gacc := GenesisAccount{
Address: acc.GetAddress(),
Coins: acc.GetCoins(),
AccountNumber: acc.GetAccountNumber(),
Sequence: acc.GetSequence(),
}
vacc, ok := acc.(auth.VestingAccount)
if ok {
gacc.OriginalVesting = vacc.GetOriginalVesting()
gacc.DelegatedFree = vacc.GetDelegatedFree()
gacc.DelegatedVesting = vacc.GetDelegatedVesting()
gacc.StartTime = vacc.GetStartTime()
gacc.EndTime = vacc.GetEndTime()
}
return gacc
}
// convert GenesisAccount to auth.BaseAccount
func (ga *GenesisAccount) ToAccount() auth.Account {
bacc := &auth.BaseAccount{
Address: ga.Address,
Coins: ga.Coins.Sort(),
AccountNumber: ga.AccountNumber,
Sequence: ga.Sequence,
}
if !ga.OriginalVesting.IsZero() {
baseVestingAcc := &auth.BaseVestingAccount{
BaseAccount: bacc,
OriginalVesting: ga.OriginalVesting,
DelegatedFree: ga.DelegatedFree,
DelegatedVesting: ga.DelegatedVesting,
EndTime: ga.EndTime,
}
if ga.StartTime != 0 && ga.EndTime != 0 {
return &auth.ContinuousVestingAccount{
BaseVestingAccount: baseVestingAcc,
StartTime: ga.StartTime,
}
} else if ga.EndTime != 0 {
return &auth.DelayedVestingAccount{
BaseVestingAccount: baseVestingAcc,
}
} else {
panic(fmt.Sprintf("invalid genesis vesting account: %+v", ga))
}
}
return bacc
}
// Create the core parameters for genesis initialization for gaia
// note that the pubkey input is this machines pubkey
func AppGenState(cdc *codec.Codec, genDoc tmtypes.GenesisDoc, appGenTxs []json.RawMessage) (
genesisState GenesisState, err error) {
if err = cdc.UnmarshalJSON(genDoc.AppState, &genesisState); err != nil {
return genesisState, err
}
// if there are no gen txs to be processed, return the default empty state
if len(appGenTxs) == 0 {
return genesisState, errors.New("there must be at least one genesis tx")
}
stakingData := genesisState.StakingData
for i, genTx := range appGenTxs {
var tx auth.StdTx
if err := cdc.UnmarshalJSON(genTx, &tx); err != nil {
return genesisState, err
}
msgs := tx.GetMsgs()
if len(msgs) != 1 {
return genesisState, errors.New(
"must provide genesis StdTx with exactly 1 CreateValidator message")
}
if _, ok := msgs[0].(staking.MsgCreateValidator); !ok {
return genesisState, fmt.Errorf(
"Genesis transaction %v does not contain a MsgCreateValidator", i)
}
}
for _, acc := range genesisState.Accounts {
for _, coin := range acc.Coins {
if coin.Denom == genesisState.StakingData.Params.BondDenom {
stakingData.Pool.NotBondedTokens = stakingData.Pool.NotBondedTokens.
Add(coin.Amount) // increase the supply
}
}
}
genesisState.StakingData = stakingData
genesisState.GenTxs = appGenTxs
return genesisState, nil
}
// NewDefaultGenesisState generates the default state for gaia.
func NewDefaultGenesisState() GenesisState { func NewDefaultGenesisState() GenesisState {
return GenesisState{ return ModuleBasics.DefaultGenesis()
Accounts: nil,
AuthData: auth.DefaultGenesisState(),
BankData: bank.DefaultGenesisState(),
StakingData: staking.DefaultGenesisState(),
MintData: mint.DefaultGenesisState(),
DistrData: distr.DefaultGenesisState(),
GovData: gov.DefaultGenesisState(),
CrisisData: crisis.DefaultGenesisState(),
SlashingData: slashing.DefaultGenesisState(),
GenTxs: nil,
}
}
// ValidateGenesisState ensures that the genesis state obeys the expected invariants
// TODO: No validators are both bonded and jailed (#2088)
// TODO: Error if there is a duplicate validator (#1708)
// TODO: Ensure all state machine parameters are in genesis (#1704)
func ValidateGenesisState(genesisState GenesisState) error {
if err := validateGenesisStateAccounts(genesisState.Accounts); err != nil {
return err
}
// skip stakingData validation as genesis is created from txs
if len(genesisState.GenTxs) > 0 {
return nil
}
if err := auth.ValidateGenesis(genesisState.AuthData); err != nil {
return err
}
if err := bank.ValidateGenesis(genesisState.BankData); err != nil {
return err
}
if err := staking.ValidateGenesis(genesisState.StakingData); err != nil {
return err
}
if err := mint.ValidateGenesis(genesisState.MintData); err != nil {
return err
}
if err := distr.ValidateGenesis(genesisState.DistrData); err != nil {
return err
}
if err := gov.ValidateGenesis(genesisState.GovData); err != nil {
return err
}
if err := crisis.ValidateGenesis(genesisState.CrisisData); err != nil {
return err
}
return slashing.ValidateGenesis(genesisState.SlashingData)
}
// validateGenesisStateAccounts performs validation of genesis accounts. It
// ensures that there are no duplicate accounts in the genesis state and any
// provided vesting accounts are valid.
func validateGenesisStateAccounts(accs []GenesisAccount) error {
addrMap := make(map[string]bool, len(accs))
for _, acc := range accs {
addrStr := acc.Address.String()
// disallow any duplicate accounts
if _, ok := addrMap[addrStr]; ok {
return fmt.Errorf("duplicate account found in genesis state; address: %s", addrStr)
}
// validate any vesting fields
if !acc.OriginalVesting.IsZero() {
if acc.EndTime == 0 {
return fmt.Errorf("missing end time for vesting account; address: %s", addrStr)
}
if acc.StartTime >= acc.EndTime {
return fmt.Errorf(
"vesting start time must before end time; address: %s, start: %s, end: %s",
addrStr,
time.Unix(acc.StartTime, 0).UTC().Format(time.RFC3339),
time.Unix(acc.EndTime, 0).UTC().Format(time.RFC3339),
)
}
}
addrMap[addrStr] = true
}
return nil
}
// AppGenState but with JSON
func AppGenStateJSON(cdc *codec.Codec, genDoc tmtypes.GenesisDoc, appGenTxs []json.RawMessage) (
appState json.RawMessage, err error) {
// create the final app state
genesisState, err := AppGenState(cdc, genDoc, appGenTxs)
if err != nil {
return nil, err
}
return codec.MarshalJSONIndent(cdc, genesisState)
}
// CollectStdTxs processes and validates application's genesis StdTxs and returns
// the list of appGenTxs, and persistent peers required to generate genesis.json.
func CollectStdTxs(cdc *codec.Codec, moniker string, genTxsDir string, genDoc tmtypes.GenesisDoc) (
appGenTxs []auth.StdTx, persistentPeers string, err error) {
var fos []os.FileInfo
fos, err = ioutil.ReadDir(genTxsDir)
if err != nil {
return appGenTxs, persistentPeers, err
}
// prepare a map of all accounts in genesis state to then validate
// against the validators addresses
var appState GenesisState
if err := cdc.UnmarshalJSON(genDoc.AppState, &appState); err != nil {
return appGenTxs, persistentPeers, err
}
addrMap := make(map[string]GenesisAccount, len(appState.Accounts))
for i := 0; i < len(appState.Accounts); i++ {
acc := appState.Accounts[i]
addrMap[acc.Address.String()] = acc
}
// addresses and IPs (and port) validator server info
var addressesIPs []string
for _, fo := range fos {
filename := filepath.Join(genTxsDir, fo.Name())
if !fo.IsDir() && (filepath.Ext(filename) != ".json") {
continue
}
// get the genStdTx
var jsonRawTx []byte
if jsonRawTx, err = ioutil.ReadFile(filename); err != nil {
return appGenTxs, persistentPeers, err
}
var genStdTx auth.StdTx
if err = cdc.UnmarshalJSON(jsonRawTx, &genStdTx); err != nil {
return appGenTxs, persistentPeers, err
}
appGenTxs = append(appGenTxs, genStdTx)
// the memo flag is used to store
// the ip and node-id, for example this may be:
// "528fd3df22b31f4969b05652bfe8f0fe921321d5@192.168.2.37:26656"
nodeAddrIP := genStdTx.GetMemo()
if len(nodeAddrIP) == 0 {
return appGenTxs, persistentPeers, fmt.Errorf(
"couldn't find node's address and IP in %s", fo.Name())
}
// genesis transactions must be single-message
msgs := genStdTx.GetMsgs()
if len(msgs) != 1 {
return appGenTxs, persistentPeers, errors.New(
"each genesis transaction must provide a single genesis message")
}
msg := msgs[0].(staking.MsgCreateValidator)
// validate delegator and validator addresses and funds against the accounts in the state
delAddr := msg.DelegatorAddress.String()
valAddr := sdk.AccAddress(msg.ValidatorAddress).String()
delAcc, delOk := addrMap[delAddr]
_, valOk := addrMap[valAddr]
accsNotInGenesis := []string{}
if !delOk {
accsNotInGenesis = append(accsNotInGenesis, delAddr)
}
if !valOk {
accsNotInGenesis = append(accsNotInGenesis, valAddr)
}
if len(accsNotInGenesis) != 0 {
return appGenTxs, persistentPeers, fmt.Errorf(
"account(s) %v not in genesis.json: %+v", strings.Join(accsNotInGenesis, " "), addrMap)
}
if delAcc.Coins.AmountOf(msg.Value.Denom).LT(msg.Value.Amount) {
return appGenTxs, persistentPeers, fmt.Errorf(
"insufficient fund for delegation %v: %v < %v",
delAcc.Address, delAcc.Coins.AmountOf(msg.Value.Denom), msg.Value.Amount,
)
}
// exclude itself from persistent peers
if msg.Description.Moniker != moniker {
addressesIPs = append(addressesIPs, nodeAddrIP)
}
}
sort.Strings(addressesIPs)
persistentPeers = strings.Join(addressesIPs, ",")
return appGenTxs, persistentPeers, nil
}
func NewDefaultGenesisAccount(addr sdk.AccAddress) GenesisAccount {
accAuth := auth.NewBaseAccountWithAddress(addr)
coins := sdk.Coins{
sdk.NewCoin("footoken", sdk.NewInt(1000)),
sdk.NewCoin(defaultBondDenom, freeTokensPerAcc),
}
coins.Sort()
accAuth.Coins = coins
return NewGenesisAccount(&accAuth)
} }

View File

@ -1,188 +0,0 @@
package app
import (
"encoding/json"
"testing"
"time"
"github.com/stretchr/testify/require"
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/crypto/ed25519"
"github.com/tendermint/tendermint/crypto/secp256k1"
tmtypes "github.com/tendermint/tendermint/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth"
"github.com/cosmos/cosmos-sdk/x/staking"
)
var (
pk1 = ed25519.GenPrivKey().PubKey()
pk2 = ed25519.GenPrivKey().PubKey()
pk3 = ed25519.GenPrivKey().PubKey()
addr1 = sdk.ValAddress(pk1.Address())
addr2 = sdk.ValAddress(pk2.Address())
addr3 = sdk.ValAddress(pk3.Address())
emptyAddr sdk.ValAddress
emptyPubkey crypto.PubKey
)
func makeGenesisState(t *testing.T, genTxs []auth.StdTx) GenesisState {
// start with the default staking genesis state
appState := NewDefaultGenesisState()
stakingData := appState.StakingData
genAccs := make([]GenesisAccount, len(genTxs))
for i, genTx := range genTxs {
msgs := genTx.GetMsgs()
require.Equal(t, 1, len(msgs))
msg := msgs[0].(staking.MsgCreateValidator)
acc := auth.NewBaseAccountWithAddress(sdk.AccAddress(msg.ValidatorAddress))
acc.Coins = sdk.NewCoins(sdk.NewInt64Coin(defaultBondDenom, 150))
genAccs[i] = NewGenesisAccount(&acc)
stakingData.Pool.NotBondedTokens = stakingData.Pool.NotBondedTokens.Add(sdk.NewInt(150)) // increase the supply
}
// create the final app state
appState.Accounts = genAccs
return appState
}
func TestToAccount(t *testing.T) {
priv := ed25519.GenPrivKey()
addr := sdk.AccAddress(priv.PubKey().Address())
authAcc := auth.NewBaseAccountWithAddress(addr)
authAcc.SetCoins(sdk.NewCoins(sdk.NewInt64Coin(defaultBondDenom, 150)))
genAcc := NewGenesisAccount(&authAcc)
acc := genAcc.ToAccount()
require.IsType(t, &auth.BaseAccount{}, acc)
require.Equal(t, &authAcc, acc.(*auth.BaseAccount))
vacc := auth.NewContinuousVestingAccount(
&authAcc, time.Now().Unix(), time.Now().Add(24*time.Hour).Unix(),
)
genAcc = NewGenesisAccountI(vacc)
acc = genAcc.ToAccount()
require.IsType(t, &auth.ContinuousVestingAccount{}, acc)
require.Equal(t, vacc, acc.(*auth.ContinuousVestingAccount))
}
func TestAppGenTx(t *testing.T) {
cdc := MakeCodec()
_ = cdc
//TODO test that key overwrite flags work / no overwrites if set off
//TODO test validator created has provided pubkey
//TODO test the account created has the correct pubkey
}
func TestAppGenState(t *testing.T) {
cdc := MakeCodec()
_ = cdc
var genDoc tmtypes.GenesisDoc
// test unmarshalling error
_, err := AppGenState(cdc, genDoc, []json.RawMessage{})
require.Error(t, err)
appState := makeGenesisState(t, []auth.StdTx{})
genDoc.AppState, err = json.Marshal(appState)
require.NoError(t, err)
// test validation error
_, err = AppGenState(cdc, genDoc, []json.RawMessage{})
require.Error(t, err)
// TODO test must provide at least genesis transaction
// TODO test with both one and two genesis transactions:
// TODO correct: genesis account created, canididates created, pool token variance
}
func makeMsg(name string, pk crypto.PubKey) auth.StdTx {
desc := staking.NewDescription(name, "", "", "")
comm := staking.CommissionMsg{}
msg := staking.NewMsgCreateValidator(sdk.ValAddress(pk.Address()), pk, sdk.NewInt64Coin(defaultBondDenom,
50), desc, comm, sdk.OneInt())
return auth.NewStdTx([]sdk.Msg{msg}, auth.StdFee{}, nil, "")
}
func TestGenesisValidation(t *testing.T) {
genTxs := []auth.StdTx{makeMsg("test-0", pk1), makeMsg("test-1", pk2)}
dupGenTxs := []auth.StdTx{makeMsg("test-0", pk1), makeMsg("test-1", pk1)}
// require duplicate accounts fails validation
genesisState := makeGenesisState(t, dupGenTxs)
err := ValidateGenesisState(genesisState)
require.Error(t, err)
// require invalid vesting account fails validation (invalid end time)
genesisState = makeGenesisState(t, genTxs)
genesisState.Accounts[0].OriginalVesting = genesisState.Accounts[0].Coins
err = ValidateGenesisState(genesisState)
require.Error(t, err)
genesisState.Accounts[0].StartTime = 1548888000
genesisState.Accounts[0].EndTime = 1548775410
err = ValidateGenesisState(genesisState)
require.Error(t, err)
// require bonded + jailed validator fails validation
genesisState = makeGenesisState(t, genTxs)
val1 := staking.NewValidator(addr1, pk1, staking.NewDescription("test #2", "", "", ""))
val1.Jailed = true
val1.Status = sdk.Bonded
genesisState.StakingData.Validators = append(genesisState.StakingData.Validators, val1)
err = ValidateGenesisState(genesisState)
require.Error(t, err)
// require duplicate validator fails validation
val1.Jailed = false
genesisState = makeGenesisState(t, genTxs)
val2 := staking.NewValidator(addr1, pk1, staking.NewDescription("test #3", "", "", ""))
genesisState.StakingData.Validators = append(genesisState.StakingData.Validators, val1)
genesisState.StakingData.Validators = append(genesisState.StakingData.Validators, val2)
err = ValidateGenesisState(genesisState)
require.Error(t, err)
}
func TestNewDefaultGenesisAccount(t *testing.T) {
addr := secp256k1.GenPrivKeySecp256k1([]byte("")).PubKey().Address()
acc := NewDefaultGenesisAccount(sdk.AccAddress(addr))
require.Equal(t, sdk.NewInt(1000), acc.Coins.AmountOf("footoken"))
require.Equal(t, sdk.TokensFromTendermintPower(150), acc.Coins.AmountOf(defaultBondDenom))
}
func TestGenesisStateSanitize(t *testing.T) {
genesisState := makeGenesisState(t, nil)
require.Nil(t, ValidateGenesisState(genesisState))
addr1 := sdk.AccAddress(ed25519.GenPrivKey().PubKey().Address())
authAcc1 := auth.NewBaseAccountWithAddress(addr1)
authAcc1.SetCoins(sdk.Coins{
sdk.NewInt64Coin("bcoin", 150),
sdk.NewInt64Coin("acoin", 150),
})
authAcc1.SetAccountNumber(1)
genAcc1 := NewGenesisAccount(&authAcc1)
addr2 := sdk.AccAddress(ed25519.GenPrivKey().PubKey().Address())
authAcc2 := auth.NewBaseAccountWithAddress(addr2)
authAcc2.SetCoins(sdk.Coins{
sdk.NewInt64Coin("acoin", 150),
sdk.NewInt64Coin("bcoin", 150),
})
genAcc2 := NewGenesisAccount(&authAcc2)
genesisState.Accounts = []GenesisAccount{genAcc1, genAcc2}
require.True(t, genesisState.Accounts[0].AccountNumber > genesisState.Accounts[1].AccountNumber)
require.Equal(t, genesisState.Accounts[0].Coins[0].Denom, "bcoin")
require.Equal(t, genesisState.Accounts[0].Coins[1].Denom, "acoin")
require.Equal(t, genesisState.Accounts[1].Address, addr2)
genesisState.Sanitize()
require.False(t, genesisState.Accounts[0].AccountNumber > genesisState.Accounts[1].AccountNumber)
require.Equal(t, genesisState.Accounts[1].Address, addr1)
require.Equal(t, genesisState.Accounts[1].Coins[0].Denom, "acoin")
require.Equal(t, genesisState.Accounts[1].Coins[1].Denom, "bcoin")
}

View File

@ -1,31 +1,31 @@
package app package app
import ( // import (
"fmt" // "fmt"
"time" // "time"
abci "github.com/tendermint/tendermint/abci/types" // abci "github.com/tendermint/tendermint/abci/types"
sdk "github.com/cosmos/cosmos-sdk/types" // sdk "github.com/cosmos/cosmos-sdk/types"
) // )
func (app *App) assertRuntimeInvariants() { // func (app *App) assertRuntimeInvariants() {
ctx := app.NewContext(false, abci.Header{Height: app.LastBlockHeight() + 1}) // ctx := app.NewContext(false, abci.Header{Height: app.LastBlockHeight() + 1})
app.assertRuntimeInvariantsOnContext(ctx) // app.assertRuntimeInvariantsOnContext(ctx)
} // }
func (app *App) assertRuntimeInvariantsOnContext(ctx sdk.Context) { // func (app *App) assertRuntimeInvariantsOnContext(ctx sdk.Context) {
start := time.Now() // start := time.Now()
invarRoutes := app.crisisKeeper.Routes() // invarRoutes := app.crisisKeeper.Routes()
for _, ir := range invarRoutes { // for _, ir := range invarRoutes {
if err := ir.Invar(ctx); err != nil { // if err := ir.Invar(ctx); err != nil {
panic(fmt.Errorf("invariant broken: %s\n"+ // panic(fmt.Errorf("invariant broken: %s\n"+
"\tCRITICAL please submit the following transaction:\n"+ // "\tCRITICAL please submit the following transaction:\n"+
"\t\t kvcli tx crisis invariant-broken %v %v", err, ir.ModuleName, ir.Route)) // "\t\t kvcli tx crisis invariant-broken %v %v", err, ir.ModuleName, ir.Route))
} // }
} // }
end := time.Now() // end := time.Now()
diff := end.Sub(start) // diff := end.Sub(start)
app.BaseApp.Logger().With("module", "invariants").Info( // app.BaseApp.Logger().With("module", "invariants").Info(
"Asserted all invariants", "duration", diff, "height", app.LastBlockHeight()) // "Asserted all invariants", "duration", diff, "height", app.LastBlockHeight())
} // }

View File

@ -4,6 +4,7 @@ import (
"encoding/json" "encoding/json"
"flag" "flag"
"fmt" "fmt"
"io"
"io/ioutil" "io/ioutil"
"math/rand" "math/rand"
"os" "os"
@ -13,31 +14,48 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
abci "github.com/tendermint/tendermint/abci/types" abci "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/crypto/secp256k1"
dbm "github.com/tendermint/tendermint/libs/db" dbm "github.com/tendermint/tendermint/libs/db"
"github.com/tendermint/tendermint/libs/log" "github.com/tendermint/tendermint/libs/log"
tmtypes "github.com/tendermint/tendermint/types"
"github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/simapp" // TODO replace with types from app/genesis.go ?
sdk "github.com/cosmos/cosmos-sdk/types" sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth"
authsim "github.com/cosmos/cosmos-sdk/x/auth/simulation" authsim "github.com/cosmos/cosmos-sdk/x/auth/simulation"
"github.com/cosmos/cosmos-sdk/x/bank" "github.com/cosmos/cosmos-sdk/x/bank"
banksim "github.com/cosmos/cosmos-sdk/x/bank/simulation"
distr "github.com/cosmos/cosmos-sdk/x/distribution"
distrsim "github.com/cosmos/cosmos-sdk/x/distribution/simulation" distrsim "github.com/cosmos/cosmos-sdk/x/distribution/simulation"
"github.com/cosmos/cosmos-sdk/x/gov"
govsim "github.com/cosmos/cosmos-sdk/x/gov/simulation" govsim "github.com/cosmos/cosmos-sdk/x/gov/simulation"
"github.com/cosmos/cosmos-sdk/x/mint" paramsim "github.com/cosmos/cosmos-sdk/x/params/simulation"
"github.com/cosmos/cosmos-sdk/x/simulation" "github.com/cosmos/cosmos-sdk/x/simulation"
"github.com/cosmos/cosmos-sdk/x/slashing"
slashingsim "github.com/cosmos/cosmos-sdk/x/slashing/simulation" slashingsim "github.com/cosmos/cosmos-sdk/x/slashing/simulation"
"github.com/cosmos/cosmos-sdk/x/staking" "github.com/cosmos/cosmos-sdk/x/staking"
stakingsim "github.com/cosmos/cosmos-sdk/x/staking/simulation" stakingsim "github.com/cosmos/cosmos-sdk/x/staking/simulation"
) )
// Simulation parameter constants
const (
StakePerAccount = "stake_per_account"
InitiallyBondedValidators = "initially_bonded_validators"
OpWeightDeductFee = "op_weight_deduct_fee"
OpWeightMsgSend = "op_weight_msg_send"
OpWeightSingleInputMsgMultiSend = "op_weight_single_input_msg_multisend"
OpWeightMsgSetWithdrawAddress = "op_weight_msg_set_withdraw_address"
OpWeightMsgWithdrawDelegationReward = "op_weight_msg_withdraw_delegation_reward"
OpWeightMsgWithdrawValidatorCommission = "op_weight_msg_withdraw_validator_commission"
OpWeightSubmitVotingSlashingTextProposal = "op_weight_submit_voting_slashing_text_proposal"
OpWeightSubmitVotingSlashingCommunitySpendProposal = "op_weight_submit_voting_slashing_community_spend_proposal"
OpWeightSubmitVotingSlashingParamChangeProposal = "op_weight_submit_voting_slashing_param_change_proposal"
OpWeightMsgDeposit = "op_weight_msg_deposit"
OpWeightMsgCreateValidator = "op_weight_msg_create_validator"
OpWeightMsgEditValidator = "op_weight_msg_edit_validator"
OpWeightMsgDelegate = "op_weight_msg_delegate"
OpWeightMsgUndelegate = "op_weight_msg_undelegate"
OpWeightMsgBeginRedelegate = "op_weight_msg_begin_redelegate"
OpWeightMsgUnjail = "op_weight_msg_unjail"
)
var ( var (
genesisFile string genesisFile string
paramsFile string
seed int64 seed int64
numBlocks int numBlocks int
blockSize int blockSize int
@ -46,10 +64,13 @@ var (
lean bool lean bool
commit bool commit bool
period int period int
onOperation bool // TODO Remove in favor of binary search for invariant violation
allInvariants bool
) )
func init() { func init() {
flag.StringVar(&genesisFile, "SimulationGenesis", "", "custom simulation genesis file") flag.StringVar(&genesisFile, "SimulationGenesis", "", "custom simulation genesis file; cannot be used with params file")
flag.StringVar(&paramsFile, "SimulationParams", "", "custom simulation params file which overrides any random params; cannot be used with genesis")
flag.Int64Var(&seed, "SimulationSeed", 42, "simulation random seed") flag.Int64Var(&seed, "SimulationSeed", 42, "simulation random seed")
flag.IntVar(&numBlocks, "SimulationNumBlocks", 500, "number of blocks") flag.IntVar(&numBlocks, "SimulationNumBlocks", 500, "number of blocks")
flag.IntVar(&blockSize, "SimulationBlockSize", 200, "operations per block") flag.IntVar(&blockSize, "SimulationBlockSize", 200, "operations per block")
@ -58,207 +79,95 @@ func init() {
flag.BoolVar(&lean, "SimulationLean", false, "lean simulation log output") flag.BoolVar(&lean, "SimulationLean", false, "lean simulation log output")
flag.BoolVar(&commit, "SimulationCommit", false, "have the simulation commit") flag.BoolVar(&commit, "SimulationCommit", false, "have the simulation commit")
flag.IntVar(&period, "SimulationPeriod", 1, "run slow invariants only once every period assertions") flag.IntVar(&period, "SimulationPeriod", 1, "run slow invariants only once every period assertions")
flag.BoolVar(&onOperation, "SimulateEveryOperation", false, "run slow invariants every operation")
flag.BoolVar(&allInvariants, "PrintAllInvariants", false, "print all invariants if a broken invariant is found")
} }
// helper function for populating input for SimulateFromSeed // helper function for populating input for SimulateFromSeed
func getSimulateFromSeedInput(tb testing.TB, app *App) ( func getSimulateFromSeedInput(tb testing.TB, w io.Writer, app *App) (
testing.TB, *baseapp.BaseApp, simulation.AppStateFn, int64, testing.TB, io.Writer, *baseapp.BaseApp, simulation.AppStateFn, int64,
simulation.WeightedOperations, sdk.Invariants, int, int, bool, bool) { simulation.WeightedOperations, sdk.Invariants, int, int, bool, bool, bool, bool, map[string]bool,
) {
return tb, app.BaseApp, appStateFn, seed, return tb, w, app.BaseApp, appStateFn, seed,
testAndRunTxs(app), invariants(app), numBlocks, blockSize, commit, lean testAndRunTxs(app), invariants(app), numBlocks, blockSize, commit,
lean, onOperation, allInvariants, app.ModuleAccountAddrs()
} }
func appStateFromGenesisFileFn(r *rand.Rand, accs []simulation.Account, genesisTimestamp time.Time) (json.RawMessage, []simulation.Account, string) { func appStateFn(
var genesis tmtypes.GenesisDoc r *rand.Rand, accs []simulation.Account, genesisTimestamp time.Time,
) (appState json.RawMessage, simAccs []simulation.Account, chainID string) {
cdc := MakeCodec() cdc := MakeCodec()
bytes, err := ioutil.ReadFile(genesisFile)
switch {
case paramsFile != "" && genesisFile != "":
panic("cannot provide both a genesis file and a params file")
case genesisFile != "":
appState, simAccs, chainID = simapp.AppStateFromGenesisFileFn(r, accs, genesisTimestamp)
case paramsFile != "":
appParams := make(simulation.AppParams)
bz, err := ioutil.ReadFile(paramsFile)
if err != nil { if err != nil {
panic(err) panic(err)
} }
cdc.MustUnmarshalJSON(bytes, &genesis)
var appState GenesisState cdc.MustUnmarshalJSON(bz, &appParams)
cdc.MustUnmarshalJSON(genesis.AppState, &appState) appState, simAccs, chainID = appStateRandomizedFn(r, accs, genesisTimestamp, appParams)
var newAccs []simulation.Account
for _, acc := range appState.Accounts { default:
// Pick a random private key, since we don't know the actual key appParams := make(simulation.AppParams)
// This should be fine as it's only used for mock Tendermint validators appState, simAccs, chainID = appStateRandomizedFn(r, accs, genesisTimestamp, appParams)
// and these keys are never actually used to sign by mock Tendermint.
privkeySeed := make([]byte, 15)
r.Read(privkeySeed)
privKey := secp256k1.GenPrivKeySecp256k1(privkeySeed)
newAccs = append(newAccs, simulation.Account{privKey, privKey.PubKey(), acc.Address})
} }
return genesis.AppState, newAccs, genesis.ChainID
return appState, simAccs, chainID
} }
func appStateRandomizedFn(r *rand.Rand, accs []simulation.Account, genesisTimestamp time.Time) (json.RawMessage, []simulation.Account, string) { // TODO refactor out random initialization code to the modules
func appStateRandomizedFn(
r *rand.Rand, accs []simulation.Account, genesisTimestamp time.Time, appParams simulation.AppParams,
) (json.RawMessage, []simulation.Account, string) {
var genesisAccounts []GenesisAccount cdc := MakeCodec()
genesisState := simapp.NewDefaultGenesisState()
var (
amount int64
numInitiallyBonded int64
)
appParams.GetOrGenerate(cdc, StakePerAccount, &amount, r,
func(r *rand.Rand) { amount = int64(r.Intn(1e12)) })
appParams.GetOrGenerate(cdc, InitiallyBondedValidators, &amount, r,
func(r *rand.Rand) { numInitiallyBonded = int64(r.Intn(250)) })
amount := int64(r.Intn(1e12))
numInitiallyBonded := int64(r.Intn(250))
numAccs := int64(len(accs)) numAccs := int64(len(accs))
if numInitiallyBonded > numAccs { if numInitiallyBonded > numAccs {
numInitiallyBonded = numAccs numInitiallyBonded = numAccs
} }
fmt.Printf("Selected randomly generated parameters for simulated genesis:\n"+
"\t{amount of stake per account: %v, initially bonded validators: %v}\n",
amount, numInitiallyBonded)
// randomly generate some genesis accounts fmt.Printf(
for i, acc := range accs { `Selected randomly generated parameters for simulated genesis:
coins := sdk.Coins{sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(amount))} {
bacc := auth.NewBaseAccountWithAddress(acc.Address) stake_per_account: "%v",
bacc.SetCoins(coins) initially_bonded_validators: "%v"
}
var gacc GenesisAccount `, amount, numInitiallyBonded,
// Only consider making a vesting account once the initial bonded validator
// set is exhausted due to needing to track DelegatedVesting.
if int64(i) > numInitiallyBonded && r.Intn(100) < 50 {
var (
vacc auth.VestingAccount
endTime int64
) )
startTime := genesisTimestamp.Unix() simapp.GenGenesisAccounts(cdc, r, accs, genesisTimestamp, amount, numInitiallyBonded, genesisState)
simapp.GenAuthGenesisState(cdc, r, appParams, genesisState)
simapp.GenBankGenesisState(cdc, r, appParams, genesisState)
simapp.GenSupplyGenesisState(cdc, amount, numInitiallyBonded, int64(len(accs)), genesisState)
simapp.GenGovGenesisState(cdc, r, appParams, genesisState)
simapp.GenMintGenesisState(cdc, r, appParams, genesisState)
simapp.GenDistrGenesisState(cdc, r, appParams, genesisState)
stakingGen := simapp.GenStakingGenesisState(cdc, r, accs, amount, numAccs, numInitiallyBonded, appParams, genesisState)
simapp.GenSlashingGenesisState(cdc, r, stakingGen, appParams, genesisState)
// Allow for some vesting accounts to vest very quickly while others very appState, err := MakeCodec().MarshalJSON(genesisState)
// slowly.
if r.Intn(100) < 50 {
endTime = int64(simulation.RandIntBetween(r, int(startTime), int(startTime+(60*60*24*30))))
} else {
endTime = int64(simulation.RandIntBetween(r, int(startTime), int(startTime+(60*60*12))))
}
if startTime == endTime {
endTime += 1
}
if r.Intn(100) < 50 {
vacc = auth.NewContinuousVestingAccount(&bacc, startTime, endTime)
} else {
vacc = auth.NewDelayedVestingAccount(&bacc, endTime)
}
gacc = NewGenesisAccountI(vacc)
} else {
gacc = NewGenesisAccount(&bacc)
}
genesisAccounts = append(genesisAccounts, gacc)
}
authGenesis := auth.GenesisState{
Params: auth.Params{
MaxMemoCharacters: uint64(simulation.RandIntBetween(r, 100, 200)),
TxSigLimit: uint64(r.Intn(7) + 1),
TxSizeCostPerByte: uint64(simulation.RandIntBetween(r, 5, 15)),
SigVerifyCostED25519: uint64(simulation.RandIntBetween(r, 500, 1000)),
SigVerifyCostSecp256k1: uint64(simulation.RandIntBetween(r, 500, 1000)),
},
}
fmt.Printf("Selected randomly generated auth parameters:\n\t%+v\n", authGenesis)
bankGenesis := bank.NewGenesisState(r.Int63n(2) == 0)
fmt.Printf("Selected randomly generated bank parameters:\n\t%+v\n", bankGenesis)
// Random genesis states
vp := time.Duration(r.Intn(2*172800)) * time.Second
govGenesis := gov.GenesisState{
StartingProposalID: uint64(r.Intn(100)),
DepositParams: gov.DepositParams{
MinDeposit: sdk.Coins{sdk.NewInt64Coin(sdk.DefaultBondDenom, int64(r.Intn(1e3)))},
MaxDepositPeriod: vp,
},
VotingParams: gov.VotingParams{
VotingPeriod: vp,
},
TallyParams: gov.TallyParams{
Quorum: sdk.NewDecWithPrec(334, 3),
Threshold: sdk.NewDecWithPrec(5, 1),
Veto: sdk.NewDecWithPrec(334, 3),
},
}
fmt.Printf("Selected randomly generated governance parameters:\n\t%+v\n", govGenesis)
stakingGenesis := staking.GenesisState{
Pool: staking.InitialPool(),
Params: staking.Params{
UnbondingTime: time.Duration(simulation.RandIntBetween(r, 60, 60*60*24*3*2)) * time.Second,
MaxValidators: uint16(r.Intn(250) + 1),
BondDenom: sdk.DefaultBondDenom,
},
}
fmt.Printf("Selected randomly generated staking parameters:\n\t%+v\n", stakingGenesis)
slashingGenesis := slashing.GenesisState{
Params: slashing.Params{
MaxEvidenceAge: stakingGenesis.Params.UnbondingTime,
SignedBlocksWindow: int64(simulation.RandIntBetween(r, 10, 1000)),
MinSignedPerWindow: sdk.NewDecWithPrec(int64(r.Intn(10)), 1),
DowntimeJailDuration: time.Duration(simulation.RandIntBetween(r, 60, 60*60*24)) * time.Second,
SlashFractionDoubleSign: sdk.NewDec(1).Quo(sdk.NewDec(int64(r.Intn(50) + 1))),
SlashFractionDowntime: sdk.NewDec(1).Quo(sdk.NewDec(int64(r.Intn(200) + 1))),
},
}
fmt.Printf("Selected randomly generated slashing parameters:\n\t%+v\n", slashingGenesis)
mintGenesis := mint.GenesisState{
Minter: mint.InitialMinter(
sdk.NewDecWithPrec(int64(r.Intn(99)), 2)),
Params: mint.NewParams(
sdk.DefaultBondDenom,
sdk.NewDecWithPrec(int64(r.Intn(99)), 2),
sdk.NewDecWithPrec(20, 2),
sdk.NewDecWithPrec(7, 2),
sdk.NewDecWithPrec(67, 2),
uint64(60*60*8766/5)),
}
fmt.Printf("Selected randomly generated minting parameters:\n\t%+v\n", mintGenesis)
var validators []staking.Validator
var delegations []staking.Delegation
valAddrs := make([]sdk.ValAddress, numInitiallyBonded)
for i := 0; i < int(numInitiallyBonded); i++ {
valAddr := sdk.ValAddress(accs[i].Address)
valAddrs[i] = valAddr
validator := staking.NewValidator(valAddr, accs[i].PubKey, staking.Description{})
validator.Tokens = sdk.NewInt(amount)
validator.DelegatorShares = sdk.NewDec(amount)
delegation := staking.Delegation{accs[i].Address, valAddr, sdk.NewDec(amount)}
validators = append(validators, validator)
delegations = append(delegations, delegation)
}
stakingGenesis.Pool.NotBondedTokens = sdk.NewInt((amount * numAccs) + (numInitiallyBonded * amount))
stakingGenesis.Validators = validators
stakingGenesis.Delegations = delegations
distrGenesis := distr.GenesisState{
FeePool: distr.InitialFeePool(),
CommunityTax: sdk.NewDecWithPrec(1, 2).Add(sdk.NewDecWithPrec(int64(r.Intn(30)), 2)),
BaseProposerReward: sdk.NewDecWithPrec(1, 2).Add(sdk.NewDecWithPrec(int64(r.Intn(30)), 2)),
BonusProposerReward: sdk.NewDecWithPrec(1, 2).Add(sdk.NewDecWithPrec(int64(r.Intn(30)), 2)),
}
fmt.Printf("Selected randomly generated distribution parameters:\n\t%+v\n", distrGenesis)
genesis := GenesisState{
Accounts: genesisAccounts,
AuthData: authGenesis,
BankData: bankGenesis,
StakingData: stakingGenesis,
MintData: mintGenesis,
DistrData: distrGenesis,
SlashingData: slashingGenesis,
GovData: govGenesis,
}
// Marshal genesis
appState, err := MakeCodec().MarshalJSON(genesis)
if err != nil { if err != nil {
panic(err) panic(err)
} }
@ -266,39 +175,206 @@ func appStateRandomizedFn(r *rand.Rand, accs []simulation.Account, genesisTimest
return appState, accs, "simulation" return appState, accs, "simulation"
} }
func appStateFn(r *rand.Rand, accs []simulation.Account, genesisTimestamp time.Time) (json.RawMessage, []simulation.Account, string) {
if genesisFile != "" {
return appStateFromGenesisFileFn(r, accs, genesisTimestamp)
}
return appStateRandomizedFn(r, accs, genesisTimestamp)
}
func testAndRunTxs(app *App) []simulation.WeightedOperation { func testAndRunTxs(app *App) []simulation.WeightedOperation {
cdc := MakeCodec()
ap := make(simulation.AppParams)
if paramsFile != "" {
bz, err := ioutil.ReadFile(paramsFile)
if err != nil {
panic(err)
}
cdc.MustUnmarshalJSON(bz, &ap)
}
return []simulation.WeightedOperation{ return []simulation.WeightedOperation{
{5, authsim.SimulateDeductFee(app.accountKeeper, app.feeCollectionKeeper)}, {
{100, banksim.SimulateMsgSend(app.accountKeeper, app.bankKeeper)}, func(_ *rand.Rand) int {
{10, banksim.SimulateSingleInputMsgMultiSend(app.accountKeeper, app.bankKeeper)}, var v int
{50, distrsim.SimulateMsgSetWithdrawAddress(app.accountKeeper, app.distrKeeper)}, ap.GetOrGenerate(cdc, OpWeightDeductFee, &v, nil,
{50, distrsim.SimulateMsgWithdrawDelegatorReward(app.accountKeeper, app.distrKeeper)}, func(_ *rand.Rand) {
{50, distrsim.SimulateMsgWithdrawValidatorCommission(app.accountKeeper, app.distrKeeper)}, v = 5
{5, govsim.SimulateSubmittingVotingAndSlashingForProposal(app.govKeeper)}, })
{100, govsim.SimulateMsgDeposit(app.govKeeper)}, return v
{100, stakingsim.SimulateMsgCreateValidator(app.accountKeeper, app.stakingKeeper)}, }(nil),
{5, stakingsim.SimulateMsgEditValidator(app.stakingKeeper)}, authsim.SimulateDeductFee(app.accountKeeper, app.supplyKeeper),
{100, stakingsim.SimulateMsgDelegate(app.accountKeeper, app.stakingKeeper)}, },
{100, stakingsim.SimulateMsgUndelegate(app.accountKeeper, app.stakingKeeper)}, {
{100, stakingsim.SimulateMsgBeginRedelegate(app.accountKeeper, app.stakingKeeper)}, func(_ *rand.Rand) int {
{100, slashingsim.SimulateMsgUnjail(app.slashingKeeper)}, var v int
ap.GetOrGenerate(cdc, OpWeightMsgSend, &v, nil,
func(_ *rand.Rand) {
v = 100
})
return v
}(nil),
bank.SimulateMsgSend(app.accountKeeper, app.bankKeeper),
},
{
func(_ *rand.Rand) int {
var v int
ap.GetOrGenerate(cdc, OpWeightSingleInputMsgMultiSend, &v, nil,
func(_ *rand.Rand) {
v = 10
})
return v
}(nil),
bank.SimulateSingleInputMsgMultiSend(app.accountKeeper, app.bankKeeper),
},
{
func(_ *rand.Rand) int {
var v int
ap.GetOrGenerate(cdc, OpWeightMsgSetWithdrawAddress, &v, nil,
func(_ *rand.Rand) {
v = 50
})
return v
}(nil),
distrsim.SimulateMsgSetWithdrawAddress(app.accountKeeper, app.distrKeeper),
},
{
func(_ *rand.Rand) int {
var v int
ap.GetOrGenerate(cdc, OpWeightMsgWithdrawDelegationReward, &v, nil,
func(_ *rand.Rand) {
v = 50
})
return v
}(nil),
distrsim.SimulateMsgWithdrawDelegatorReward(app.accountKeeper, app.distrKeeper),
},
{
func(_ *rand.Rand) int {
var v int
ap.GetOrGenerate(cdc, OpWeightMsgWithdrawValidatorCommission, &v, nil,
func(_ *rand.Rand) {
v = 50
})
return v
}(nil),
distrsim.SimulateMsgWithdrawValidatorCommission(app.accountKeeper, app.distrKeeper),
},
{
func(_ *rand.Rand) int {
var v int
ap.GetOrGenerate(cdc, OpWeightSubmitVotingSlashingTextProposal, &v, nil,
func(_ *rand.Rand) {
v = 5
})
return v
}(nil),
govsim.SimulateSubmittingVotingAndSlashingForProposal(app.govKeeper, govsim.SimulateTextProposalContent),
},
{
func(_ *rand.Rand) int {
var v int
ap.GetOrGenerate(cdc, OpWeightSubmitVotingSlashingCommunitySpendProposal, &v, nil,
func(_ *rand.Rand) {
v = 5
})
return v
}(nil),
govsim.SimulateSubmittingVotingAndSlashingForProposal(app.govKeeper, distrsim.SimulateCommunityPoolSpendProposalContent(app.distrKeeper)),
},
{
func(_ *rand.Rand) int {
var v int
ap.GetOrGenerate(cdc, OpWeightSubmitVotingSlashingParamChangeProposal, &v, nil,
func(_ *rand.Rand) {
v = 5
})
return v
}(nil),
govsim.SimulateSubmittingVotingAndSlashingForProposal(app.govKeeper, paramsim.SimulateParamChangeProposalContent),
},
{
func(_ *rand.Rand) int {
var v int
ap.GetOrGenerate(cdc, OpWeightMsgDeposit, &v, nil,
func(_ *rand.Rand) {
v = 100
})
return v
}(nil),
govsim.SimulateMsgDeposit(app.govKeeper),
},
{
func(_ *rand.Rand) int {
var v int
ap.GetOrGenerate(cdc, OpWeightMsgCreateValidator, &v, nil,
func(_ *rand.Rand) {
v = 100
})
return v
}(nil),
stakingsim.SimulateMsgCreateValidator(app.accountKeeper, app.stakingKeeper),
},
{
func(_ *rand.Rand) int {
var v int
ap.GetOrGenerate(cdc, OpWeightMsgEditValidator, &v, nil,
func(_ *rand.Rand) {
v = 5
})
return v
}(nil),
stakingsim.SimulateMsgEditValidator(app.stakingKeeper),
},
{
func(_ *rand.Rand) int {
var v int
ap.GetOrGenerate(cdc, OpWeightMsgDelegate, &v, nil,
func(_ *rand.Rand) {
v = 100
})
return v
}(nil),
stakingsim.SimulateMsgDelegate(app.accountKeeper, app.stakingKeeper),
},
{
func(_ *rand.Rand) int {
var v int
ap.GetOrGenerate(cdc, OpWeightMsgUndelegate, &v, nil,
func(_ *rand.Rand) {
v = 100
})
return v
}(nil),
stakingsim.SimulateMsgUndelegate(app.accountKeeper, app.stakingKeeper),
},
{
func(_ *rand.Rand) int {
var v int
ap.GetOrGenerate(cdc, OpWeightMsgBeginRedelegate, &v, nil,
func(_ *rand.Rand) {
v = 100
})
return v
}(nil),
stakingsim.SimulateMsgBeginRedelegate(app.accountKeeper, app.stakingKeeper),
},
{
func(_ *rand.Rand) int {
var v int
ap.GetOrGenerate(cdc, OpWeightMsgUnjail, &v, nil,
func(_ *rand.Rand) {
v = 100
})
return v
}(nil),
slashingsim.SimulateMsgUnjail(app.slashingKeeper),
},
} }
} }
func invariants(app *App) []sdk.Invariant { func invariants(app *App) []sdk.Invariant {
return []sdk.Invariant{ // TODO: fix PeriodicInvariants, it doesn't seem to call individual invariants for a period of 1
simulation.PeriodicInvariant(bank.NonnegativeBalanceInvariant(app.accountKeeper), period, 0), // Ref: https://github.com/cosmos/cosmos-sdk/issues/4631
simulation.PeriodicInvariant(distr.AllInvariants(app.distrKeeper, app.stakingKeeper), period, 0), if period == 1 {
simulation.PeriodicInvariant(staking.AllInvariants(app.stakingKeeper, app.feeCollectionKeeper, return app.crisisKeeper.Invariants()
app.distrKeeper, app.accountKeeper), period, 0),
} }
return simulation.PeriodicInvariants(app.crisisKeeper.Invariants(), period, 0)
} }
// Pass this in as an option to use a dbStoreAdapter instead of an IAVLStore for simulation speed. // Pass this in as an option to use a dbStoreAdapter instead of an IAVLStore for simulation speed.
@ -307,13 +383,13 @@ func fauxMerkleModeOpt(bapp *baseapp.BaseApp) {
} }
// Profile with: // Profile with:
// /usr/local/go/bin/go test -benchmem -run=^$ github.com/cosmos/cosmos-sdk/cmd/gaia/app -bench ^BenchmarkFullGaiaSimulation$ -SimulationCommit=true -cpuprofile cpu.out // /usr/local/go/bin/go test -benchmem -run=^$ github.com/cosmos/cosmos-sdk/GaiaApp -bench ^BenchmarkFullAppSimulation$ -SimulationCommit=true -cpuprofile cpu.out
func BenchmarkFullGaiaSimulation(b *testing.B) { // TODO does this work
// Setup Gaia application func BenchmarkFullAppSimulation(b *testing.B) {
logger := log.NewNopLogger() logger := log.NewNopLogger()
var db dbm.DB var db dbm.DB
dir, _ := ioutil.TempDir("", "goleveldb-gaia-sim") dir, _ := ioutil.TempDir("", "goleveldb-app-sim")
db, _ = sdk.NewLevelDB("Simulation", dir) db, _ = sdk.NewLevelDB("Simulation", dir)
defer func() { defer func() {
db.Close() db.Close()
@ -323,7 +399,7 @@ func BenchmarkFullGaiaSimulation(b *testing.B) {
// Run randomized simulation // Run randomized simulation
// TODO parameterize numbers, save for a later PR // TODO parameterize numbers, save for a later PR
_, err := simulation.SimulateFromSeed(getSimulateFromSeedInput(b, app)) _, err := simulation.SimulateFromSeed(getSimulateFromSeedInput(b, os.Stdout, app))
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
b.Fail() b.Fail()
@ -335,30 +411,33 @@ func BenchmarkFullGaiaSimulation(b *testing.B) {
} }
} }
func TestFullGaiaSimulation(t *testing.T) { func TestFullAppSimulation(t *testing.T) {
if !enabled { if !enabled {
t.Skip("Skipping Gaia simulation") t.Skip("Skipping application simulation")
} }
// Setup Gaia application
var logger log.Logger var logger log.Logger
if verbose { if verbose {
logger = log.TestingLogger() logger = log.TestingLogger()
} else { } else {
logger = log.NewNopLogger() logger = log.NewNopLogger()
} }
var db dbm.DB var db dbm.DB
dir, _ := ioutil.TempDir("", "goleveldb-gaia-sim") dir, _ := ioutil.TempDir("", "goleveldb-app-sim")
db, _ = sdk.NewLevelDB("Simulation", dir) db, _ = sdk.NewLevelDB("Simulation", dir)
defer func() { defer func() {
db.Close() db.Close()
os.RemoveAll(dir) os.RemoveAll(dir)
}() }()
app := NewApp(logger, db, nil, true, 0, fauxMerkleModeOpt) app := NewApp(logger, db, nil, true, 0, fauxMerkleModeOpt)
require.Equal(t, "kava", app.Name()) require.Equal(t, "kava", app.Name())
// Run randomized simulation // Run randomized simulation
_, err := simulation.SimulateFromSeed(getSimulateFromSeedInput(t, app)) _, err := simulation.SimulateFromSeed(getSimulateFromSeedInput(t, os.Stdout, app))
if commit { if commit {
// for memdb: // for memdb:
// fmt.Println("Database Size", db.Stats()["database.size"]) // fmt.Println("Database Size", db.Stats()["database.size"])
@ -366,33 +445,36 @@ func TestFullGaiaSimulation(t *testing.T) {
fmt.Println(db.Stats()["leveldb.stats"]) fmt.Println(db.Stats()["leveldb.stats"])
fmt.Println("GoLevelDB cached block size", db.Stats()["leveldb.cachedblock"]) fmt.Println("GoLevelDB cached block size", db.Stats()["leveldb.cachedblock"])
} }
require.Nil(t, err) require.Nil(t, err)
} }
func TestGaiaImportExport(t *testing.T) { func TestAppImportExport(t *testing.T) {
if !enabled { if !enabled {
t.Skip("Skipping Gaia import/export simulation") t.Skip("Skipping application import/export simulation")
} }
// Setup Gaia application
var logger log.Logger var logger log.Logger
if verbose { if verbose {
logger = log.TestingLogger() logger = log.TestingLogger()
} else { } else {
logger = log.NewNopLogger() logger = log.NewNopLogger()
} }
var db dbm.DB var db dbm.DB
dir, _ := ioutil.TempDir("", "goleveldb-gaia-sim") dir, _ := ioutil.TempDir("", "goleveldb-app-sim")
db, _ = sdk.NewLevelDB("Simulation", dir) db, _ = sdk.NewLevelDB("Simulation", dir)
defer func() { defer func() {
db.Close() db.Close()
os.RemoveAll(dir) os.RemoveAll(dir)
}() }()
app := NewApp(logger, db, nil, true, 0, fauxMerkleModeOpt) app := NewApp(logger, db, nil, true, 0, fauxMerkleModeOpt)
require.Equal(t, "kava", app.Name()) require.Equal(t, "kava", app.Name())
// Run randomized simulation // Run randomized simulation
_, err := simulation.SimulateFromSeed(getSimulateFromSeedInput(t, app)) _, err := simulation.SimulateFromSeed(getSimulateFromSeedInput(t, os.Stdout, app))
if commit { if commit {
// for memdb: // for memdb:
@ -401,37 +483,43 @@ func TestGaiaImportExport(t *testing.T) {
fmt.Println(db.Stats()["leveldb.stats"]) fmt.Println(db.Stats()["leveldb.stats"])
fmt.Println("GoLevelDB cached block size", db.Stats()["leveldb.cachedblock"]) fmt.Println("GoLevelDB cached block size", db.Stats()["leveldb.cachedblock"])
} }
require.Nil(t, err)
require.Nil(t, err)
fmt.Printf("Exporting genesis...\n") fmt.Printf("Exporting genesis...\n")
appState, _, err := app.ExportAppStateAndValidators(false, []string{}) appState, _, err := app.ExportAppStateAndValidators(false, []string{})
require.NoError(t, err) require.NoError(t, err)
fmt.Printf("Importing genesis...\n") fmt.Printf("Importing genesis...\n")
newDir, _ := ioutil.TempDir("", "goleveldb-gaia-sim-2") newDir, _ := ioutil.TempDir("", "goleveldb-app-sim-2")
newDB, _ := sdk.NewLevelDB("Simulation-2", dir) newDB, _ := sdk.NewLevelDB("Simulation-2", dir)
defer func() { defer func() {
newDB.Close() newDB.Close()
os.RemoveAll(newDir) os.RemoveAll(newDir)
}() }()
newApp := NewApp(log.NewNopLogger(), newDB, nil, true, 0, fauxMerkleModeOpt) newApp := NewApp(log.NewNopLogger(), newDB, nil, true, 0, fauxMerkleModeOpt)
require.Equal(t, "kava", newApp.Name()) require.Equal(t, "kava", newApp.Name())
var genesisState GenesisState
var genesisState simapp.GenesisState
err = app.cdc.UnmarshalJSON(appState, &genesisState) err = app.cdc.UnmarshalJSON(appState, &genesisState)
if err != nil { if err != nil {
panic(err) panic(err)
} }
ctxB := newApp.NewContext(true, abci.Header{}) ctxB := newApp.NewContext(true, abci.Header{})
newApp.initFromGenesisState(ctxB, genesisState) newApp.mm.InitGenesis(ctxB, genesisState)
fmt.Printf("Comparing stores...\n") fmt.Printf("Comparing stores...\n")
ctxA := app.NewContext(true, abci.Header{}) ctxA := app.NewContext(true, abci.Header{})
type StoreKeysPrefixes struct { type StoreKeysPrefixes struct {
A sdk.StoreKey A sdk.StoreKey
B sdk.StoreKey B sdk.StoreKey
Prefixes [][]byte Prefixes [][]byte
} }
storeKeysPrefixes := []StoreKeysPrefixes{ storeKeysPrefixes := []StoreKeysPrefixes{
{app.keyMain, newApp.keyMain, [][]byte{}}, {app.keyMain, newApp.keyMain, [][]byte{}},
{app.keyAccount, newApp.keyAccount, [][]byte{}}, {app.keyAccount, newApp.keyAccount, [][]byte{}},
@ -440,10 +528,11 @@ func TestGaiaImportExport(t *testing.T) {
{app.keySlashing, newApp.keySlashing, [][]byte{}}, {app.keySlashing, newApp.keySlashing, [][]byte{}},
{app.keyMint, newApp.keyMint, [][]byte{}}, {app.keyMint, newApp.keyMint, [][]byte{}},
{app.keyDistr, newApp.keyDistr, [][]byte{}}, {app.keyDistr, newApp.keyDistr, [][]byte{}},
{app.keyFeeCollection, newApp.keyFeeCollection, [][]byte{}}, {app.keySupply, newApp.keySupply, [][]byte{}},
{app.keyParams, newApp.keyParams, [][]byte{}}, {app.keyParams, newApp.keyParams, [][]byte{}},
{app.keyGov, newApp.keyGov, [][]byte{}}, {app.keyGov, newApp.keyGov, [][]byte{}},
} }
for _, storeKeysPrefix := range storeKeysPrefixes { for _, storeKeysPrefix := range storeKeysPrefixes {
storeKeyA := storeKeysPrefix.A storeKeyA := storeKeysPrefix.A
storeKeyB := storeKeysPrefix.B storeKeyB := storeKeysPrefix.B
@ -452,37 +541,36 @@ func TestGaiaImportExport(t *testing.T) {
storeB := ctxB.KVStore(storeKeyB) storeB := ctxB.KVStore(storeKeyB)
kvA, kvB, count, equal := sdk.DiffKVStores(storeA, storeB, prefixes) kvA, kvB, count, equal := sdk.DiffKVStores(storeA, storeB, prefixes)
fmt.Printf("Compared %d key/value pairs between %s and %s\n", count, storeKeyA, storeKeyB) fmt.Printf("Compared %d key/value pairs between %s and %s\n", count, storeKeyA, storeKeyB)
require.True(t, equal, require.True(t, equal, simapp.GetSimulationLog(storeKeyA.Name(), app.cdc, newApp.cdc, kvA, kvB))
"unequal stores: %s / %s:\nstore A %X => %X\nstore B %X => %X",
storeKeyA, storeKeyB, kvA.Key, kvA.Value, kvB.Key, kvB.Value,
)
} }
} }
func TestGaiaSimulationAfterImport(t *testing.T) { func TestAppSimulationAfterImport(t *testing.T) {
if !enabled { if !enabled {
t.Skip("Skipping Gaia simulation after import") t.Skip("Skipping application simulation after import")
} }
// Setup Gaia application
var logger log.Logger var logger log.Logger
if verbose { if verbose {
logger = log.TestingLogger() logger = log.TestingLogger()
} else { } else {
logger = log.NewNopLogger() logger = log.NewNopLogger()
} }
dir, _ := ioutil.TempDir("", "goleveldb-gaia-sim")
dir, _ := ioutil.TempDir("", "goleveldb-app-sim")
db, _ := sdk.NewLevelDB("Simulation", dir) db, _ := sdk.NewLevelDB("Simulation", dir)
defer func() { defer func() {
db.Close() db.Close()
os.RemoveAll(dir) os.RemoveAll(dir)
}() }()
app := NewApp(logger, db, nil, true, 0, fauxMerkleModeOpt) app := NewApp(logger, db, nil, true, 0, fauxMerkleModeOpt)
require.Equal(t, "kava", app.Name()) require.Equal(t, "kava", app.Name())
// Run randomized simulation // Run randomized simulation
stopEarly, err := simulation.SimulateFromSeed(getSimulateFromSeedInput(t, app)) stopEarly, err := simulation.SimulateFromSeed(getSimulateFromSeedInput(t, os.Stdout, app))
if commit { if commit {
// for memdb: // for memdb:
@ -491,6 +579,7 @@ func TestGaiaSimulationAfterImport(t *testing.T) {
fmt.Println(db.Stats()["leveldb.stats"]) fmt.Println(db.Stats()["leveldb.stats"])
fmt.Println("GoLevelDB cached block size", db.Stats()["leveldb.cachedblock"]) fmt.Println("GoLevelDB cached block size", db.Stats()["leveldb.cachedblock"])
} }
require.Nil(t, err) require.Nil(t, err)
if stopEarly { if stopEarly {
@ -508,12 +597,14 @@ func TestGaiaSimulationAfterImport(t *testing.T) {
fmt.Printf("Importing genesis...\n") fmt.Printf("Importing genesis...\n")
newDir, _ := ioutil.TempDir("", "goleveldb-gaia-sim-2") newDir, _ := ioutil.TempDir("", "goleveldb-app-sim-2")
newDB, _ := sdk.NewLevelDB("Simulation-2", dir) newDB, _ := sdk.NewLevelDB("Simulation-2", dir)
defer func() { defer func() {
newDB.Close() newDB.Close()
os.RemoveAll(newDir) os.RemoveAll(newDir)
}() }()
newApp := NewApp(log.NewNopLogger(), newDB, nil, true, 0, fauxMerkleModeOpt) newApp := NewApp(log.NewNopLogger(), newDB, nil, true, 0, fauxMerkleModeOpt)
require.Equal(t, "kava", newApp.Name()) require.Equal(t, "kava", newApp.Name())
newApp.InitChain(abci.RequestInitChain{ newApp.InitChain(abci.RequestInitChain{
@ -521,16 +612,15 @@ func TestGaiaSimulationAfterImport(t *testing.T) {
}) })
// Run randomized simulation on imported app // Run randomized simulation on imported app
_, err = simulation.SimulateFromSeed(getSimulateFromSeedInput(t, newApp)) _, err = simulation.SimulateFromSeed(getSimulateFromSeedInput(t, os.Stdout, newApp))
require.Nil(t, err) require.Nil(t, err)
} }
// TODO: Make another test for the fuzzer itself, which just has noOp txs // TODO: Make another test for the fuzzer itself, which just has noOp txs
// and doesn't depend on gaia // and doesn't depend on the application.
func TestAppStateDeterminism(t *testing.T) { func TestAppStateDeterminism(t *testing.T) {
if !enabled { if !enabled {
t.Skip("Skipping Gaia simulation") t.Skip("Skipping application simulation")
} }
numSeeds := 3 numSeeds := 3
@ -544,21 +634,65 @@ func TestAppStateDeterminism(t *testing.T) {
db := dbm.NewMemDB() db := dbm.NewMemDB()
app := NewApp(logger, db, nil, true, 0) app := NewApp(logger, db, nil, true, 0)
// Run randomized simulation // run randomized simulation
simulation.SimulateFromSeed( simulation.SimulateFromSeed(
t, app.BaseApp, appStateFn, seed, t, os.Stdout, app.BaseApp, appStateFn, seed,
testAndRunTxs(app), testAndRunTxs(app),
[]sdk.Invariant{}, []sdk.Invariant{},
50, 50,
100, 100,
true, true,
false, false,
false,
false,
app.ModuleAccountAddrs(),
) )
appHash := app.LastCommitID().Hash appHash := app.LastCommitID().Hash
appHashList[j] = appHash appHashList[j] = appHash
} }
for k := 1; k < numTimesToRunPerSeed; k++ { for k := 1; k < numTimesToRunPerSeed; k++ {
require.Equal(t, appHashList[0], appHashList[k], "appHash list: %v", appHashList) require.Equal(t, appHashList[0], appHashList[k], "appHash list: %v", appHashList)
} }
} }
} }
func BenchmarkInvariants(b *testing.B) {
logger := log.NewNopLogger()
dir, _ := ioutil.TempDir("", "goleveldb-app-invariant-bench")
db, _ := sdk.NewLevelDB("simulation", dir)
defer func() {
db.Close()
os.RemoveAll(dir)
}()
app := NewApp(logger, db, nil, true, 0)
// 2. Run parameterized simulation (w/o invariants)
_, err := simulation.SimulateFromSeed(
b, ioutil.Discard, app.BaseApp, appStateFn, seed, testAndRunTxs(app),
[]sdk.Invariant{}, numBlocks, blockSize, commit, lean, onOperation, false,
app.ModuleAccountAddrs(),
)
if err != nil {
fmt.Println(err)
b.FailNow()
}
ctx := app.NewContext(true, abci.Header{Height: app.LastBlockHeight() + 1})
// 3. Benchmark each invariant separately
//
// NOTE: We use the crisis keeper as it has all the invariants registered with
// their respective metadata which makes it useful for testing/benchmarking.
for _, cr := range app.crisisKeeper.Routes() {
b.Run(fmt.Sprintf("%s/%s", cr.ModuleName, cr.Route), func(b *testing.B) {
if res, stop := cr.Invar(ctx); stop {
fmt.Printf("broken invariant at block %d of %d\n%s", ctx.BlockHeight()-1, numBlocks, res)
b.FailNow()
}
})
}
}

17
go.mod
View File

@ -3,13 +3,14 @@ module github.com/kava-labs/kava
go 1.12 go 1.12
require ( require (
github.com/cosmos/cosmos-sdk v0.34.7 bou.ke/monkey v1.0.1 // indirect
github.com/rakyll/statik v0.1.4 github.com/cosmos/cosmos-sdk v0.36.0-rc1
github.com/spf13/cobra v0.0.3 github.com/otiai10/copy v0.0.0-20180813032824-7e9a647135a1 // indirect
github.com/spf13/viper v1.0.3 github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95 // indirect
github.com/otiai10/mint v1.2.3 // indirect
github.com/spf13/cobra v0.0.5
github.com/spf13/viper v1.3.2
github.com/stretchr/testify v1.3.0 github.com/stretchr/testify v1.3.0
github.com/tendermint/go-amino v0.14.1 github.com/tendermint/go-amino v0.15.0
github.com/tendermint/tendermint v0.31.5 github.com/tendermint/tendermint v0.32.1
) )
replace golang.org/x/crypto => github.com/tendermint/crypto v0.0.0-20180820045704-3764759f34a5

140
go.sum
View File

@ -1,7 +1,9 @@
bou.ke/monkey v1.0.1 h1:zEMLInw9xvNakzUUPjfS4Ds6jYPqCFx3m7bRmG5NH2U=
bou.ke/monkey v1.0.1/go.mod h1:FgHuK96Rv2Nlf+0u1OOVDpCMdsWyOFmeeketDHE7LIg= bou.ke/monkey v1.0.1/go.mod h1:FgHuK96Rv2Nlf+0u1OOVDpCMdsWyOFmeeketDHE7LIg=
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= 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/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
@ -11,36 +13,30 @@ github.com/bartekn/go-bip39 v0.0.0-20171116152956-a05967ea095d h1:1aAija9gr0Hyv4
github.com/bartekn/go-bip39 v0.0.0-20171116152956-a05967ea095d/go.mod h1:icNx/6QdFblhsEjZehARqbNumymUT/ydwlLojFdv7Sk= github.com/bartekn/go-bip39 v0.0.0-20171116152956-a05967ea095d/go.mod h1:icNx/6QdFblhsEjZehARqbNumymUT/ydwlLojFdv7Sk=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 h1:xJ4a3vCFaGF/jqvzLMYoU8P317H5OQ+Via4RmuPwCS0= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 h1:xJ4a3vCFaGF/jqvzLMYoU8P317H5OQ+Via4RmuPwCS0=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY= github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY=
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
github.com/btcsuite/btcd v0.0.0-20190115013929-ed77733ec07d h1:xG8Pj6Y6J760xwETNmMzmlt38QSwz0BLp1cZ09g27uw= github.com/btcsuite/btcd v0.0.0-20190115013929-ed77733ec07d h1:xG8Pj6Y6J760xwETNmMzmlt38QSwz0BLp1cZ09g27uw=
github.com/btcsuite/btcd v0.0.0-20190115013929-ed77733ec07d/go.mod h1:d3C0AkH6BRcvO8T0UEPu53cnw4IbV63x1bEjildYhO0= github.com/btcsuite/btcd v0.0.0-20190115013929-ed77733ec07d/go.mod h1:d3C0AkH6BRcvO8T0UEPu53cnw4IbV63x1bEjildYhO0=
github.com/btcsuite/btcd v0.0.0-20190523000118-16327141da8c/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI=
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA=
github.com/btcsuite/btcutil v0.0.0-20180706230648-ab6388e0c60a h1:RQMUrEILyYJEoAT34XS/kLu40vC0+po/UfxrBBA4qZE= github.com/btcsuite/btcutil v0.0.0-20180706230648-ab6388e0c60a h1:RQMUrEILyYJEoAT34XS/kLu40vC0+po/UfxrBBA4qZE=
github.com/btcsuite/btcutil v0.0.0-20180706230648-ab6388e0c60a/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= github.com/btcsuite/btcutil v0.0.0-20180706230648-ab6388e0c60a/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg=
github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg=
github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg=
github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY=
github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc=
github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= 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/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/cosmos/cosmos-sdk v0.28.2-0.20190718124356-a922dad3468b h1:Xdy1RNh4+it+umYuygHprhzpgbmZIMJHykS11FVViVc=
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cosmos/cosmos-sdk v0.28.2-0.20190718124356-a922dad3468b/go.mod h1:UV765S3m9sxCg8rYaBr4XgeHZl2UP6y++Coz9mLlYFc=
github.com/cosmos/cosmos-sdk v0.28.2-0.20190606154315-3180e68c7b57/go.mod h1:MvaJDmjgAK7X1rTnpk8+c6tUFfIZ++iuNCp2sUWzprM=
github.com/cosmos/cosmos-sdk v0.34.7 h1:S6yMldhrAMB/SDMsR2Hvz05tpUpQQGCHf0INXAZ7VW0=
github.com/cosmos/cosmos-sdk v0.34.7/go.mod h1:ruF+G4D7hRf34uzZQvf/SIja9fsIThU5D7GirwTMQ9I=
github.com/cosmos/cosmos-sdk v0.35.0 h1:EPeie1aKHwnXtTzKggvabG7aAPN+DDmju2xquvjFwao= github.com/cosmos/cosmos-sdk v0.35.0 h1:EPeie1aKHwnXtTzKggvabG7aAPN+DDmju2xquvjFwao=
github.com/cosmos/cosmos-sdk v0.35.0/go.mod h1:ruF+G4D7hRf34uzZQvf/SIja9fsIThU5D7GirwTMQ9I=
github.com/cosmos/cosmos-sdk v0.36.0-rc1 h1:hgSXNeVwNYxD0+O9DxRrxJcir9Z7Q5zreLV6G7GrjYA=
github.com/cosmos/cosmos-sdk v0.36.0-rc1/go.mod h1:UV765S3m9sxCg8rYaBr4XgeHZl2UP6y++Coz9mLlYFc=
github.com/cosmos/go-bip39 v0.0.0-20180618194314-52158e4697b8 h1:Iwin12wRQtyZhH6FV3ykFcdGNlYEzoeR0jN8Vn+JWsI= github.com/cosmos/go-bip39 v0.0.0-20180618194314-52158e4697b8 h1:Iwin12wRQtyZhH6FV3ykFcdGNlYEzoeR0jN8Vn+JWsI=
github.com/cosmos/go-bip39 v0.0.0-20180618194314-52158e4697b8/go.mod h1:tSxLoYXyBmiFeKpvmq4dzayMdCjCnu8uqmCysIGBT2Y= github.com/cosmos/go-bip39 v0.0.0-20180618194314-52158e4697b8/go.mod h1:tSxLoYXyBmiFeKpvmq4dzayMdCjCnu8uqmCysIGBT2Y=
github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d/go.mod h1:tSxLoYXyBmiFeKpvmq4dzayMdCjCnu8uqmCysIGBT2Y=
github.com/cosmos/ledger-cosmos-go v0.10.3 h1:Qhi5yTR5Pg1CaTpd00pxlGwNl4sFRdtK1J96OTjeFFc= github.com/cosmos/ledger-cosmos-go v0.10.3 h1:Qhi5yTR5Pg1CaTpd00pxlGwNl4sFRdtK1J96OTjeFFc=
github.com/cosmos/ledger-cosmos-go v0.10.3/go.mod h1:J8//BsAGTo3OC/vDLjMRFLW6q0WAaXvHnVc7ZmE8iUY= github.com/cosmos/ledger-cosmos-go v0.10.3/go.mod h1:J8//BsAGTo3OC/vDLjMRFLW6q0WAaXvHnVc7ZmE8iUY=
github.com/cosmos/ledger-go v0.9.2 h1:Nnao/dLwaVTk1Q5U9THldpUMMXU94BOTWPddSmVB6pI= github.com/cosmos/ledger-go v0.9.2 h1:Nnao/dLwaVTk1Q5U9THldpUMMXU94BOTWPddSmVB6pI=
@ -50,88 +46,84 @@ github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2
github.com/davecgh/go-spew v1.1.0/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 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/etcd-io/bbolt v1.3.2/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw=
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/etcd-io/bbolt v1.3.3 h1:gSJmxrs37LgTqR/oyJBWok6k6SvXEUerFTbltIhXkBM=
github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw=
github.com/fortytw2/leaktest v1.2.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g=
github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw=
github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g=
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-kit/kit v0.6.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/kit v0.8.0 h1:Wz+5lgoB0kkuqLEc6NVmwRknTKP6dTGbSqvhZtBI/j0= github.com/go-kit/kit v0.8.0 h1:Wz+5lgoB0kkuqLEc6NVmwRknTKP6dTGbSqvhZtBI/j0=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0 h1:MP4Eh7ZCb31lleYCFuwm0oe4/YGak+5l1vA2NOE80nA= github.com/go-logfmt/logfmt v0.4.0 h1:MP4Eh7ZCb31lleYCFuwm0oe4/YGak+5l1vA2NOE80nA=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
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-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/gogo/protobuf v1.1.1 h1:72R+M5VuhED/KujmZVcIquuo8mBgX4oVda//DQb3PXo= github.com/gogo/protobuf v1.1.1 h1:72R+M5VuhED/KujmZVcIquuo8mBgX4oVda//DQb3PXo=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.3.1-0.20190508161146-9fa652df1129/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM= github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.0 h1:kbxbvI4Un1LUWKxufD+BiE6AEExYYgkQLQmLFqA1LFk=
github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0= github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf h1:+RRA9JqSOZFfKrOeqr2z77+8R2RKyh8PG66dcu1V0ck= github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf h1:+RRA9JqSOZFfKrOeqr2z77+8R2RKyh8PG66dcu1V0ck=
github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=
github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/gorilla/mux v1.7.0 h1:tOSd0UKHQd6urX6ApfOn4XdBMY6Sh1MfxV3kmaazO+U= github.com/gorilla/mux v1.7.0 h1:tOSd0UKHQd6urX6ApfOn4XdBMY6Sh1MfxV3kmaazO+U=
github.com/gorilla/mux v1.7.0/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.7.0/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/gorilla/mux v1.7.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/websocket v1.2.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q= github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q=
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= 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/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jmhodges/levigo v0.0.0-20161115193449-c42d9e0ca023/go.mod h1:Q6Qx+uH3RAqyK4rFQroq9RL7mdkABMcfhEI+nNuzMJQ=
github.com/jmhodges/levigo v1.0.0 h1:q5EC36kV79HWeTBWsod3mG11EgStG3qArTKcvlksN1U=
github.com/jmhodges/levigo v1.0.0/go.mod h1:Q6Qx+uH3RAqyK4rFQroq9RL7mdkABMcfhEI+nNuzMJQ= github.com/jmhodges/levigo v1.0.0/go.mod h1:Q6Qx+uH3RAqyK4rFQroq9RL7mdkABMcfhEI+nNuzMJQ=
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= 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/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4=
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.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj2vyii2bbUNDw3kt9VxK2EY=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= 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/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/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY= github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/mattn/go-isatty v0.0.6 h1:SrwhHcpV4nWrMGdNcC2kXpMfcBVYGDuTArqyhocJgvA= github.com/mattn/go-isatty v0.0.6 h1:SrwhHcpV4nWrMGdNcC2kXpMfcBVYGDuTArqyhocJgvA=
github.com/mattn/go-isatty v0.0.6/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.6/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= 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/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs=
github.com/onsi/ginkgo v1.7.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.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU=
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/otiai10/copy v0.0.0-20180813032824-7e9a647135a1/go.mod h1:pXzZSDlN+HPzSdyIBnKNN9ptD9Hx7iZMWIJPTwo4FPE= github.com/otiai10/copy v0.0.0-20180813032824-7e9a647135a1/go.mod h1:pXzZSDlN+HPzSdyIBnKNN9ptD9Hx7iZMWIJPTwo4FPE=
github.com/otiai10/copy v1.0.1/go.mod h1:8bMCJrAqOtN/d9oyh5HR7HhLQMvcGMpGdwRDYsfOCHc=
github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE=
github.com/otiai10/curr v0.0.0-20190513014714-f5a3d24e5776/go.mod h1:3HNVkVOU7vZeFXocWuvtcS0XSFLcf2XUSDHkq9t1jU4=
github.com/otiai10/mint v1.2.3/go.mod h1:YnfyPNhBvnY8bW4SGQHCs/aAFhkgySlMZbrF5U0bOVw= github.com/otiai10/mint v1.2.3/go.mod h1:YnfyPNhBvnY8bW4SGQHCs/aAFhkgySlMZbrF5U0bOVw=
github.com/otiai10/mint v1.2.4/go.mod h1:d+b7n/0R3tdyUYYylALXpWQ/kTN+QobSq/4SRGBkR3M=
github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc= github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
@ -140,54 +132,45 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v0.9.2 h1:awm861/B8OKDd2I/6o1dy3ra4BamzKhYOiGItCeZ740= github.com/prometheus/client_golang v0.9.2 h1:awm861/B8OKDd2I/6o1dy3ra4BamzKhYOiGItCeZ740=
github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM= github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM=
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90 h1:S/YWwWx/RA8rT8tKFRuGUZhuA90OyIBpPCXkcbwU8DE= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90 h1:S/YWwWx/RA8rT8tKFRuGUZhuA90OyIBpPCXkcbwU8DE=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.0.0-20181020173914-7e9e6cabbd39/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/common v0.2.0 h1:kUZDBDTdBVBYBj5Tmh2NZLlF60mfjA27rM34b+cVwNU= github.com/prometheus/common v0.2.0 h1:kUZDBDTdBVBYBj5Tmh2NZLlF60mfjA27rM34b+cVwNU=
github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= 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/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20190227231451-bbced9601137 h1:3l8oligPtjd4JuM+OZ+U8sjtwFGJs98cdWsqs6QZRWs= github.com/prometheus/procfs v0.0.0-20190227231451-bbced9601137 h1:3l8oligPtjd4JuM+OZ+U8sjtwFGJs98cdWsqs6QZRWs=
github.com/prometheus/procfs v0.0.0-20190227231451-bbced9601137/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.0-20190227231451-bbced9601137/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.0.0-20190523193104-a7aeb8df3389/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/rakyll/statik v0.1.4 h1:zCS/YQCxfo/fQjCtGVGIyWGFnRbQ18Y55mhS3XPE+Oo= github.com/rakyll/statik v0.1.4 h1:zCS/YQCxfo/fQjCtGVGIyWGFnRbQ18Y55mhS3XPE+Oo=
github.com/rakyll/statik v0.1.4/go.mod h1:OEi9wJV/fMUAGx1eNjq75DKDsJVuEv1U0oYdX6GX8Zs= github.com/rakyll/statik v0.1.4/go.mod h1:OEi9wJV/fMUAGx1eNjq75DKDsJVuEv1U0oYdX6GX8Zs=
github.com/rakyll/statik v0.1.6/go.mod h1:OEi9wJV/fMUAGx1eNjq75DKDsJVuEv1U0oYdX6GX8Zs=
github.com/rcrowley/go-metrics v0.0.0-20180503174638-e2704e165165 h1:nkcn14uNmFEuGCb2mBZbBb24RdNRL08b/wb+xBOYpuk= github.com/rcrowley/go-metrics v0.0.0-20180503174638-e2704e165165 h1:nkcn14uNmFEuGCb2mBZbBb24RdNRL08b/wb+xBOYpuk=
github.com/rcrowley/go-metrics v0.0.0-20180503174638-e2704e165165/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rcrowley/go-metrics v0.0.0-20180503174638-e2704e165165/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rs/cors v1.6.0 h1:G9tHG9lebljV9mfp9SNPDL36nCDxmo3zTlAf1YgvzmI= github.com/rs/cors v1.6.0 h1:G9tHG9lebljV9mfp9SNPDL36nCDxmo3zTlAf1YgvzmI=
github.com/rs/cors v1.6.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/rs/cors v1.6.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
github.com/spf13/afero v1.2.1 h1:qgMbHoJbPbw579P+1zVY+6n4nIFuIchaIjzZ/I/Yq8M= github.com/spf13/afero v1.2.1 h1:qgMbHoJbPbw579P+1zVY+6n4nIFuIchaIjzZ/I/Yq8M=
github.com/spf13/afero v1.2.1/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= github.com/spf13/afero v1.2.1/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8= github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8=
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cobra v0.0.1/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
github.com/spf13/cobra v0.0.3 h1:ZlrZ4XsMRm04Fr5pSFxBgfND2EBVa1nLpiy1stUsX/8= github.com/spf13/cobra v0.0.3 h1:ZlrZ4XsMRm04Fr5pSFxBgfND2EBVa1nLpiy1stUsX/8=
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
github.com/spf13/cobra v0.0.4/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s=
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= 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 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/viper v1.0.0/go.mod h1:A8kyI5cUJhb8N+3pkfONlcEcZbueH6nhAm0Fq7SrnBM=
github.com/spf13/viper v1.0.3 h1:z5LPUc2iz8VLT5Cw1UyrESG6FUUnOGecYGY08BLKSuc= github.com/spf13/viper v1.0.3 h1:z5LPUc2iz8VLT5Cw1UyrESG6FUUnOGecYGY08BLKSuc=
github.com/spf13/viper v1.0.3/go.mod h1:A8kyI5cUJhb8N+3pkfONlcEcZbueH6nhAm0Fq7SrnBM= github.com/spf13/viper v1.0.3/go.mod h1:A8kyI5cUJhb8N+3pkfONlcEcZbueH6nhAm0Fq7SrnBM=
github.com/spf13/viper v1.3.2 h1:VUFqw5KcqRf7i70GOzW7N+Q7+gxVBkSSqiXB12+JQ4M=
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= 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/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
@ -195,87 +178,84 @@ github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/syndtr/goleveldb v0.0.0-20180708030551-c4c61651e9e3 h1:sAlSBRDl4psFR3ysKXRSE8ss6Mt90+ma1zRTroTNBJA= github.com/syndtr/goleveldb v0.0.0-20180708030551-c4c61651e9e3 h1:sAlSBRDl4psFR3ysKXRSE8ss6Mt90+ma1zRTroTNBJA=
github.com/syndtr/goleveldb v0.0.0-20180708030551-c4c61651e9e3/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0= github.com/syndtr/goleveldb v0.0.0-20180708030551-c4c61651e9e3/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0=
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= github.com/syndtr/goleveldb v0.0.0-20181105012736-f9080354173f/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0=
github.com/syndtr/goleveldb v1.0.1-0.20190318030020-c3a204f8e965 h1:1oFLiOyVl+W7bnBzGhf7BbIv9loSFQcieWWYIjLqcAw=
github.com/syndtr/goleveldb v1.0.1-0.20190318030020-c3a204f8e965/go.mod h1:9OrXJhf154huy1nPWmuSrkgjPUtUNhA+Zmy+6AESzuA=
github.com/tendermint/btcd v0.1.1 h1:0VcxPfflS2zZ3RiOAHkBiFUcPvbtRj5O7zHmcJWHV7s= 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/btcd v0.1.1/go.mod h1:DC6/m53jtQzr/NFmMNEu0rxf18/ktVoVtMrnDD5pN+U=
github.com/tendermint/crypto v0.0.0-20180820045704-3764759f34a5 h1:u8i49c+BxloX3XQ55cvzFNXplizZP/q00i+IlttUjAU= github.com/tendermint/crypto v0.0.0-20180820045704-3764759f34a5 h1:u8i49c+BxloX3XQ55cvzFNXplizZP/q00i+IlttUjAU=
github.com/tendermint/crypto v0.0.0-20180820045704-3764759f34a5/go.mod h1:z4YtwM70uOnk8h0pjJYlj3zdYwi9l03By6iAIF5j/Pk= github.com/tendermint/crypto v0.0.0-20180820045704-3764759f34a5/go.mod h1:z4YtwM70uOnk8h0pjJYlj3zdYwi9l03By6iAIF5j/Pk=
github.com/tendermint/go-amino v0.14.1 h1:o2WudxNfdLNBwMyl2dqOJxiro5rfrEaU0Ugs6offJMk= github.com/tendermint/go-amino v0.14.1 h1:o2WudxNfdLNBwMyl2dqOJxiro5rfrEaU0Ugs6offJMk=
github.com/tendermint/go-amino v0.14.1/go.mod h1:i/UKE5Uocn+argJJBb12qTZsCDBcAYMbR92AaJVmKso= github.com/tendermint/go-amino v0.14.1/go.mod h1:i/UKE5Uocn+argJJBb12qTZsCDBcAYMbR92AaJVmKso=
github.com/tendermint/go-amino v0.15.0 h1:TC4e66P59W7ML9+bxio17CPKnxW3nKIRAYskntMAoRk=
github.com/tendermint/go-amino v0.15.0/go.mod h1:TQU0M1i/ImAo+tYpZi73AU3V/dKeCoMC9Sphe2ZwGME= github.com/tendermint/go-amino v0.15.0/go.mod h1:TQU0M1i/ImAo+tYpZi73AU3V/dKeCoMC9Sphe2ZwGME=
github.com/tendermint/iavl v0.12.1 h1:JDfyhM/Hhrumu1CL1Nxrypm8sNTPYqmeHo1IZLiJoXM= github.com/tendermint/iavl v0.12.1 h1:JDfyhM/Hhrumu1CL1Nxrypm8sNTPYqmeHo1IZLiJoXM=
github.com/tendermint/iavl v0.12.1/go.mod h1:EoKMMv++tDOL5qKKVnoIqtVPshRrEPeJ0WsgDOLAauM= github.com/tendermint/iavl v0.12.1/go.mod h1:EoKMMv++tDOL5qKKVnoIqtVPshRrEPeJ0WsgDOLAauM=
github.com/tendermint/iavl v0.12.2/go.mod h1:EoKMMv++tDOL5qKKVnoIqtVPshRrEPeJ0WsgDOLAauM= github.com/tendermint/iavl v0.12.3-0.20190712145259-c834d3192b52 h1:l3qTzz8KkhZZSeLTJGqh0+iONjGM/tS5vvbunXjAmnA=
github.com/tendermint/iavl v0.12.3-0.20190712145259-c834d3192b52/go.mod h1:A9IoWRVTibyXXlfZztHy52RloI85QOrIcsE9dyQh+DY=
github.com/tendermint/tendermint v0.31.5 h1:vTet8tCq3B9/J9Yo11dNZ8pOB7NtSy++bVSfkP4KzR4= github.com/tendermint/tendermint v0.31.5 h1:vTet8tCq3B9/J9Yo11dNZ8pOB7NtSy++bVSfkP4KzR4=
github.com/tendermint/tendermint v0.31.5/go.mod h1:ymcPyWblXCplCPQjbOYbrF1fWnpslATMVqiGgWbZrlc= github.com/tendermint/tendermint v0.31.5/go.mod h1:ymcPyWblXCplCPQjbOYbrF1fWnpslATMVqiGgWbZrlc=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tendermint/tendermint v0.31.7/go.mod h1:ymcPyWblXCplCPQjbOYbrF1fWnpslATMVqiGgWbZrlc=
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/tendermint/tendermint v0.32.1 h1:J8ddXMbCmG6GZjdCl/N1wgdXDU9uO91J2Y5CA9xYfGo=
github.com/tendermint/tendermint v0.32.1/go.mod h1:jmPDAKuNkev9793/ivn/fTBnfpA9mGBww8MPRNPNxnU=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
github.com/zondax/hid v0.9.0 h1:eiT3P6vNxAEVxXMw66eZUAAnU2zD33JBkfG/EnfAKl8= github.com/zondax/hid v0.9.0 h1:eiT3P6vNxAEVxXMw66eZUAAnU2zD33JBkfG/EnfAKl8=
github.com/zondax/hid v0.9.0/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= github.com/zondax/hid v0.9.0/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM=
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.3 h1:MUGmc65QhB3pIlaQ5bB4LwqSj6GIonVJXpZiaKNyaKk=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793 h1:u+LnwYTOOW7Ukr/fppxEb1Nwz0AtPflrblfvUudpo+I= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793 h1:u+LnwYTOOW7Ukr/fppxEb1Nwz0AtPflrblfvUudpo+I=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/crypto v0.0.0-20181126093934-9eb0be3963ea/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190228161510-8dd112bcdc25/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc h1:a3CU5tJYVj92DY2LaA1kUkrsqD5/3mLDhx2NcNqyW+0= golang.org/x/net v0.0.0-20181201002055-351d144fa1fc h1:a3CU5tJYVj92DY2LaA1kUkrsqD5/3mLDhx2NcNqyW+0=
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223 h1:DH4skfRX4EBpamg7iV4ZlCpblAHI6s6TDM39bFZumv8= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223 h1:DH4skfRX4EBpamg7iV4ZlCpblAHI6s6TDM39bFZumv8=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190527104216-9cd6430ef91e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8 h1:Nw54tB0rB7hY/N0NQvRW8DG4Yk3Q6T9cu9RcFQDu1tc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8 h1:Nw54tB0rB7hY/N0NQvRW8DG4Yk3Q6T9cu9RcFQDu1tc=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190522204451-c2c4e71fbf69/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2 h1:67iHsV9djwGdZpdZNbLuQj6FOzCaZe3w+vhLjn5AcFA=
google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/grpc v1.13.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.19.0 h1:cfg4PD8YEdSFnm7qLV4++93WcmhH2nIUhMjhdCvl3j8= google.golang.org/grpc v1.19.0 h1:cfg4PD8YEdSFnm7qLV4++93WcmhH2nIUhMjhdCvl3j8=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 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/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
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/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=