diff --git a/app/app.go b/app/app.go index 1cc799d8..1826378c 100644 --- a/app/app.go +++ b/app/app.go @@ -4,6 +4,8 @@ import ( "io" "os" + validatorvesting "github.com/kava-labs/kava/x/validator-vesting" + abci "github.com/tendermint/tendermint/abci/types" cmn "github.com/tendermint/tendermint/libs/common" "github.com/tendermint/tendermint/libs/log" @@ -42,6 +44,7 @@ var ( ModuleBasics = module.NewBasicManager( genutil.AppModuleBasic{}, auth.AppModuleBasic{}, + validatorvesting.AppModuleBasic{}, bank.AppModuleBasic{}, staking.AppModuleBasic{}, mint.AppModuleBasic{}, @@ -55,12 +58,13 @@ var ( // 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}, + 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}, + validatorvesting.ModuleName: {supply.Burner}, } ) @@ -86,6 +90,7 @@ type App struct { govKeeper gov.Keeper crisisKeeper crisis.Keeper paramsKeeper params.Keeper + vvKeeper validatorvesting.Keeper // the module manager mm *module.Manager @@ -108,7 +113,7 @@ func NewApp(logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest bool, keys := sdk.NewKVStoreKeys( bam.MainStoreKey, auth.StoreKey, staking.StoreKey, supply.StoreKey, mint.StoreKey, distr.StoreKey, slashing.StoreKey, - gov.StoreKey, params.StoreKey, + gov.StoreKey, params.StoreKey, validatorvesting.StoreKey, ) tkeys := sdk.NewTransientStoreKeys(params.TStoreKey) @@ -194,6 +199,13 @@ func NewApp(logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest bool, &stakingKeeper, gov.DefaultCodespace, govRouter) + app.vvKeeper = validatorvesting.NewKeeper( + app.cdc, + keys[validatorvesting.StoreKey], + app.accountKeeper, + app.bankKeeper, + app.supplyKeeper, + &stakingKeeper) // register the staking hooks // NOTE: stakingKeeper above is passed by reference, so that it will contain these hooks @@ -213,12 +225,13 @@ func NewApp(logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest bool, mint.NewAppModule(app.mintKeeper), slashing.NewAppModule(app.slashingKeeper, app.stakingKeeper), staking.NewAppModule(app.stakingKeeper, app.accountKeeper, app.supplyKeeper), + validatorvesting.NewAppModule(app.vvKeeper, app.accountKeeper), ) // During begin block slashing happens after distr.BeginBlocker so that // there is nothing left over in the validator fee pool, so as to keep the // CanWithdrawInvariant invariant. - app.mm.SetOrderBeginBlockers(mint.ModuleName, distr.ModuleName, slashing.ModuleName) + app.mm.SetOrderBeginBlockers(mint.ModuleName, distr.ModuleName, slashing.ModuleName, validatorvesting.ModuleName) app.mm.SetOrderEndBlockers(crisis.ModuleName, gov.ModuleName, staking.ModuleName) @@ -228,7 +241,7 @@ func NewApp(logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest bool, // Note: Changing the order of the auth module and modules that use module accounts // results in subtle changes to the way accounts are loaded from genesis. app.mm.SetOrderInitGenesis( - auth.ModuleName, distr.ModuleName, + auth.ModuleName, validatorvesting.ModuleName, distr.ModuleName, staking.ModuleName, bank.ModuleName, slashing.ModuleName, gov.ModuleName, mint.ModuleName, supply.ModuleName, crisis.ModuleName, genutil.ModuleName, ) @@ -242,6 +255,7 @@ func NewApp(logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest bool, // transactions. app.sm = module.NewSimulationManager( auth.NewAppModule(app.accountKeeper), + validatorvesting.NewAppModule(app.vvKeeper, app.accountKeeper), bank.NewAppModule(app.bankKeeper, app.accountKeeper), supply.NewAppModule(app.supplyKeeper, app.accountKeeper), gov.NewAppModule(app.govKeeper, app.supplyKeeper), diff --git a/go.mod b/go.mod index 68ed9437..6e688a90 100644 --- a/go.mod +++ b/go.mod @@ -4,10 +4,14 @@ go 1.13 require ( github.com/cosmos/cosmos-sdk v0.34.4-0.20190925161702-9d0bed8f4f4e + github.com/gorilla/mux v1.7.3 github.com/spf13/cobra v0.0.5 github.com/spf13/viper v1.4.0 github.com/stretchr/testify v1.4.0 github.com/tendermint/go-amino v0.15.0 github.com/tendermint/tendermint v0.32.3 github.com/tendermint/tm-db v0.2.0 + gopkg.in/yaml.v2 v2.2.2 ) + +replace github.com/cosmos/cosmos-sdk => ../../cosmos/cosmos-sdk diff --git a/go.sum b/go.sum index bd5b3aea..5ddef612 100644 --- a/go.sum +++ b/go.sum @@ -37,6 +37,7 @@ github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7 github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cosmos/cosmos-sdk v0.34.4-0.20190925161702-9d0bed8f4f4e h1:V8WpJTIAjajE2PE+1wWCG5LUYkWQal+aH6uqPUiZ9Qc= github.com/cosmos/cosmos-sdk v0.34.4-0.20190925161702-9d0bed8f4f4e/go.mod h1:gwKdI16dOjylNYJkaHbcx0TcEIHyRs1xyc5qROmjCJE= +github.com/cosmos/cosmos-sdk v0.37.1 h1:mz5W3Au32VIPPtrY65dheVYeVDSFfS3eSSmuIj+cXsI= 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/ledger-cosmos-go v0.10.3 h1:Qhi5yTR5Pg1CaTpd00pxlGwNl4sFRdtK1J96OTjeFFc= diff --git a/x/validator-vesting/abci.go b/x/validator-vesting/abci.go index ed5a567b..0300354f 100644 --- a/x/validator-vesting/abci.go +++ b/x/validator-vesting/abci.go @@ -4,14 +4,16 @@ import ( "bytes" "time" + tmtime "github.com/tendermint/tendermint/types/time" + sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/validator-vesting/internal/keeper" + "github.com/kava-labs/kava/x/validator-vesting/internal/keeper" abci "github.com/tendermint/tendermint/abci/types" ) // BeginBlocker updates the vote signing information for each validator vesting account, updates account when period changes, and updates the previousBlockTime value in the store. func BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock, k keeper.Keeper) { - previousBlockTime := time.Time{} + previousBlockTime := tmtime.Canonical(time.Unix(0, 0)) if ctx.BlockHeight() > 1 { previousBlockTime = k.GetPreviousBlockTime(ctx) } diff --git a/x/validator-vesting/abci_test.go b/x/validator-vesting/abci_test.go index 4c865775..918d2566 100644 --- a/x/validator-vesting/abci_test.go +++ b/x/validator-vesting/abci_test.go @@ -11,7 +11,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/staking" stakingexported "github.com/cosmos/cosmos-sdk/x/staking/exported" - "github.com/cosmos/cosmos-sdk/x/validator-vesting/internal/keeper" + "github.com/kava-labs/kava/x/validator-vesting/internal/keeper" ) func TestBeginBlockerSignedBlock(t *testing.T) { diff --git a/x/validator-vesting/alias.go b/x/validator-vesting/alias.go index 5685f88d..9f9914e9 100644 --- a/x/validator-vesting/alias.go +++ b/x/validator-vesting/alias.go @@ -3,8 +3,8 @@ package validatorvesting // nolint // DONTCOVER import ( - "github.com/cosmos/cosmos-sdk/x/validator-vesting/internal/keeper" - "github.com/cosmos/cosmos-sdk/x/validator-vesting/internal/types" + "github.com/kava-labs/kava/x/validator-vesting/internal/keeper" + "github.com/kava-labs/kava/x/validator-vesting/internal/types" ) const ( diff --git a/x/validator-vesting/genesis.go b/x/validator-vesting/genesis.go index f8b674b7..7ee5b460 100644 --- a/x/validator-vesting/genesis.go +++ b/x/validator-vesting/genesis.go @@ -2,23 +2,25 @@ package validatorvesting import ( sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/auth" - "github.com/cosmos/cosmos-sdk/x/validator-vesting/internal/types" + "github.com/kava-labs/kava/x/validator-vesting/internal/types" ) // InitGenesis stores the account address of each ValidatorVestingAccount in the validator vesting keeper, for faster lookup. -// CONTRACT: Accounts created by the account keeper must have already been initialized/created by AccountKeeper -func InitGenesis(ctx sdk.Context, keeper Keeper, data GenesisState) { - data.Accounts = auth.SanitizeGenesisAccounts(data.Accounts) - for _, a := range data.Accounts { +// CONTRACT: Accounts must have already been initialized/created by AccountKeeper +func InitGenesis(ctx sdk.Context, keeper Keeper, accountKeeper types.AccountKeeper, data GenesisState) { + + accounts := accountKeeper.GetAllAccounts(ctx) + for _, a := range accounts { vv, ok := a.(ValidatorVestingAccount) if ok { keeper.SetValidatorVestingAccountKey(ctx, vv.Address) } } + keeper.SetPreviousBlockTime(ctx, data.PreviousBlockTime) } // ExportGenesis returns empty genesis state because auth exports all the genesis state we need. func ExportGenesis(ctx sdk.Context, keeper Keeper) types.GenesisState { - return types.DefaultGenesisState() + prevBlockTime := keeper.GetPreviousBlockTime(ctx) + return GenesisState{PreviousBlockTime: prevBlockTime} } diff --git a/x/validator-vesting/internal/keeper/keeper.go b/x/validator-vesting/internal/keeper/keeper.go index be00172b..96fc2ecd 100644 --- a/x/validator-vesting/internal/keeper/keeper.go +++ b/x/validator-vesting/internal/keeper/keeper.go @@ -7,7 +7,7 @@ import ( "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" stakingexported "github.com/cosmos/cosmos-sdk/x/staking/exported" - "github.com/cosmos/cosmos-sdk/x/validator-vesting/internal/types" + "github.com/kava-labs/kava/x/validator-vesting/internal/types" "github.com/tendermint/tendermint/libs/log" ) diff --git a/x/validator-vesting/internal/keeper/keeper_test.go b/x/validator-vesting/internal/keeper/keeper_test.go index 3f73f32f..8299226a 100644 --- a/x/validator-vesting/internal/keeper/keeper_test.go +++ b/x/validator-vesting/internal/keeper/keeper_test.go @@ -73,6 +73,12 @@ func TestGetSetPreviousBlock(t *testing.T) { bpt := keeper.GetPreviousBlockTime(ctx) require.Equal(t, now, bpt) + // require that the zero value is safe + require.NotPanics(t, func() { keeper.SetPreviousBlockTime(ctx, tmtime.Canonical(time.Unix(0, 0))) }) + + bpt = keeper.GetPreviousBlockTime(ctx) + require.Equal(t, tmtime.Canonical(time.Unix(0, 0)), bpt) + } func TestGetEndTImes(t *testing.T) { diff --git a/x/validator-vesting/internal/keeper/test_common.go b/x/validator-vesting/internal/keeper/test_common.go index a783bb90..5ae88d3c 100644 --- a/x/validator-vesting/internal/keeper/test_common.go +++ b/x/validator-vesting/internal/keeper/test_common.go @@ -25,7 +25,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/params" "github.com/cosmos/cosmos-sdk/x/staking" "github.com/cosmos/cosmos-sdk/x/supply" - "github.com/cosmos/cosmos-sdk/x/validator-vesting/internal/types" + "github.com/kava-labs/kava/x/validator-vesting/internal/types" ) //nolint: deadcode unused diff --git a/x/validator-vesting/internal/types/expected_keepers.go b/x/validator-vesting/internal/types/expected_keepers.go index 572c767c..84b47ca9 100644 --- a/x/validator-vesting/internal/types/expected_keepers.go +++ b/x/validator-vesting/internal/types/expected_keepers.go @@ -4,15 +4,16 @@ import ( "time" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/auth/exported" + authexported "github.com/cosmos/cosmos-sdk/x/auth/exported" stakingexported "github.com/cosmos/cosmos-sdk/x/staking/exported" supplyexported "github.com/cosmos/cosmos-sdk/x/supply/exported" ) // AccountKeeper defines the expected account keeper (noalias) type AccountKeeper interface { - GetAccount(sdk.Context, sdk.AccAddress) exported.Account - SetAccount(sdk.Context, exported.Account) + GetAccount(sdk.Context, sdk.AccAddress) authexported.Account + SetAccount(sdk.Context, authexported.Account) + GetAllAccounts(ctx sdk.Context) (accounts []authexported.Account) } // BankKeeper defines the expected bank keeper (noalias) @@ -27,7 +28,6 @@ type StakingKeeper interface { Undelegate( ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress, sharesAmount sdk.Dec, ) (time.Time, sdk.Error) - } // SupplyKeeper defines the expected supply keeper for module accounts (noalias) diff --git a/x/validator-vesting/internal/types/genesis.go b/x/validator-vesting/internal/types/genesis.go index 5133271e..69007b44 100644 --- a/x/validator-vesting/internal/types/genesis.go +++ b/x/validator-vesting/internal/types/genesis.go @@ -2,25 +2,27 @@ package types import ( "bytes" + "fmt" + "time" - "github.com/cosmos/cosmos-sdk/x/auth/exported" + tmtime "github.com/tendermint/tendermint/types/time" ) // GenesisState - all auth state that must be provided at genesis type GenesisState struct { - Accounts exported.GenesisAccounts `json:"accounts" yaml:"accounts"` + PreviousBlockTime time.Time } // NewGenesisState - Create a new genesis state -func NewGenesisState(accounts exported.GenesisAccounts) GenesisState { +func NewGenesisState(prevBlockTime time.Time) GenesisState { return GenesisState{ - Accounts: accounts, + PreviousBlockTime: prevBlockTime, } } // DefaultGenesisState - Return a default genesis state func DefaultGenesisState() GenesisState { - return NewGenesisState(exported.GenesisAccounts{}) + return NewGenesisState(tmtime.Canonical(time.Unix(0, 0))) } // Equal checks whether two gov GenesisState structs are equivalent @@ -37,5 +39,8 @@ func (data GenesisState) IsEmpty() bool { // ValidateGenesis returns nil because accounts are validated by auth func ValidateGenesis(data GenesisState) error { + if data.PreviousBlockTime.Unix() < 0 { + return fmt.Errorf("Previous block time should be positive, is set to %v", data.PreviousBlockTime.Unix()) + } return nil } diff --git a/x/validator-vesting/module.go b/x/validator-vesting/module.go index 2855b02f..19c8f220 100644 --- a/x/validator-vesting/module.go +++ b/x/validator-vesting/module.go @@ -3,6 +3,7 @@ package validatorvesting import ( "encoding/json" "math/rand" + "os" "github.com/gorilla/mux" "github.com/spf13/cobra" @@ -13,8 +14,8 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" sim "github.com/cosmos/cosmos-sdk/x/simulation" - "github.com/cosmos/cosmos-sdk/x/validator-vesting/internal/types" - "github.com/cosmos/cosmos-sdk/x/validator-vesting/simulation" + "github.com/kava-labs/kava/x/validator-vesting/internal/types" + "github.com/kava-labs/kava/x/validator-vesting/simulation" ) var ( @@ -39,6 +40,7 @@ func (AppModuleBasic) RegisterCodec(cdc *codec.Codec) { // DefaultGenesis returns default genesis state as raw bytes for the validator-vesting // module. func (AppModuleBasic) DefaultGenesis() json.RawMessage { + types.ModuleCdc.PrintTypes(os.Stdout) return types.ModuleCdc.MustMarshalJSON(types.DefaultGenesisState()) } @@ -82,15 +84,17 @@ func (AppModuleSimulation) RandomizedParams(_ *rand.Rand) []sim.ParamChange { type AppModule struct { AppModuleBasic AppModuleSimulation - keeper Keeper + keeper Keeper + accountKeeper types.AccountKeeper } // NewAppModule creates a new AppModule object -func NewAppModule(keeper Keeper) AppModule { +func NewAppModule(keeper Keeper, ak types.AccountKeeper) AppModule { return AppModule{ AppModuleBasic: AppModuleBasic{}, AppModuleSimulation: AppModuleSimulation{}, keeper: keeper, + accountKeeper: ak, } } @@ -123,7 +127,7 @@ func (am AppModule) NewQuerierHandler() sdk.Querier { func (am AppModule) InitGenesis(ctx sdk.Context, data json.RawMessage) []abci.ValidatorUpdate { var genesisState GenesisState types.ModuleCdc.MustUnmarshalJSON(data, &genesisState) - InitGenesis(ctx, am.keeper, genesisState) + InitGenesis(ctx, am.keeper, am.accountKeeper, genesisState) return []abci.ValidatorUpdate{} } diff --git a/x/validator-vesting/simulation/decoder.go b/x/validator-vesting/simulation/decoder.go index 3171b200..f6c052f5 100644 --- a/x/validator-vesting/simulation/decoder.go +++ b/x/validator-vesting/simulation/decoder.go @@ -9,7 +9,7 @@ import ( "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/x/auth/exported" - "github.com/cosmos/cosmos-sdk/x/validator-vesting/internal/types" + "github.com/kava-labs/kava/x/validator-vesting/internal/types" ) // DecodeStore unmarshals the KVPair's Value to the corresponding auth type diff --git a/x/validator-vesting/simulation/genesis.go b/x/validator-vesting/simulation/genesis.go index 99f6c9e0..86c20a68 100644 --- a/x/validator-vesting/simulation/genesis.go +++ b/x/validator-vesting/simulation/genesis.go @@ -11,7 +11,7 @@ import ( vestexported "github.com/cosmos/cosmos-sdk/x/auth/vesting/exported" vestingtypes "github.com/cosmos/cosmos-sdk/x/auth/vesting/types" "github.com/cosmos/cosmos-sdk/x/simulation" - "github.com/cosmos/cosmos-sdk/x/validator-vesting/internal/types" + "github.com/kava-labs/kava/x/validator-vesting/internal/types" ) // RandomizedGenState generates a random GenesisState for validator-vesting diff --git a/x/validator-vesting/test_common.go b/x/validator-vesting/test_common.go index af0c3783..909ee0bb 100644 --- a/x/validator-vesting/test_common.go +++ b/x/validator-vesting/test_common.go @@ -12,14 +12,14 @@ import ( "github.com/tendermint/tendermint/crypto" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/auth" + authexported "github.com/cosmos/cosmos-sdk/x/auth/exported" "github.com/cosmos/cosmos-sdk/x/bank" "github.com/cosmos/cosmos-sdk/x/mock" "github.com/cosmos/cosmos-sdk/x/staking" "github.com/cosmos/cosmos-sdk/x/supply" supplyexported "github.com/cosmos/cosmos-sdk/x/supply/exported" - "github.com/cosmos/cosmos-sdk/x/validator-vesting/internal/keeper" - "github.com/cosmos/cosmos-sdk/x/validator-vesting/internal/types" + "github.com/kava-labs/kava/x/validator-vesting/internal/keeper" + "github.com/kava-labs/kava/x/validator-vesting/internal/types" ) var ( @@ -38,7 +38,7 @@ type testInput struct { privKeys []crypto.PrivKey } -func getMockApp(t *testing.T, numGenAccs int, genState types.GenesisState, genAccs []auth.Account) testInput { +func getMockApp(t *testing.T, numGenAccs int, genState types.GenesisState, genAccs []authexported.Account) testInput { mApp := mock.NewApp() staking.RegisterCodec(mApp.Cdc) @@ -105,7 +105,7 @@ func getBeginBlocker(keeper Keeper) sdk.BeginBlocker { } // gov and staking initchainer -func getInitChainer(mapp *mock.App, keeper Keeper, stakingKeeper staking.Keeper, supplyKeeper supply.Keeper, accs []auth.Account, genState GenesisState, +func getInitChainer(mapp *mock.App, keeper Keeper, stakingKeeper staking.Keeper, supplyKeeper supply.Keeper, accs []authexported.Account, genState GenesisState, blacklistedAddrs []supplyexported.ModuleAccountI) sdk.InitChainer { return func(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain { mapp.InitChainer(ctx, req) @@ -122,9 +122,9 @@ func getInitChainer(mapp *mock.App, keeper Keeper, stakingKeeper staking.Keeper, validators := staking.InitGenesis(ctx, stakingKeeper, mapp.AccountKeeper, supplyKeeper, stakingGenesis) if genState.IsEmpty() { - InitGenesis(ctx, keeper, types.DefaultGenesisState()) + InitGenesis(ctx, keeper, mapp.AccountKeeper, types.DefaultGenesisState()) } else { - InitGenesis(ctx, keeper, genState) + InitGenesis(ctx, keeper, mapp.AccountKeeper, genState) } return abci.ResponseInitChain{ Validators: validators,