Merge branch 'develop' into rigel/sim-cleanup
This commit is contained in:
commit
8a58fdf634
|
@ -137,6 +137,24 @@ jobs:
|
||||||
export PATH="$GOBIN:$PATH"
|
export PATH="$GOBIN:$PATH"
|
||||||
make test_sim_gaia_fast
|
make test_sim_gaia_fast
|
||||||
|
|
||||||
|
test_sim_gaia_import_export:
|
||||||
|
<<: *defaults
|
||||||
|
parallelism: 1
|
||||||
|
steps:
|
||||||
|
- attach_workspace:
|
||||||
|
at: /tmp/workspace
|
||||||
|
- checkout
|
||||||
|
- run:
|
||||||
|
name: dependencies
|
||||||
|
command: |
|
||||||
|
export PATH="$GOBIN:$PATH"
|
||||||
|
make get_vendor_deps
|
||||||
|
- run:
|
||||||
|
name: Test Gaia import/export simulation
|
||||||
|
command: |
|
||||||
|
export PATH="$GOBIN:$PATH"
|
||||||
|
make test_sim_gaia_import_export
|
||||||
|
|
||||||
test_sim_gaia_multi_seed:
|
test_sim_gaia_multi_seed:
|
||||||
<<: *defaults
|
<<: *defaults
|
||||||
parallelism: 1
|
parallelism: 1
|
||||||
|
@ -259,6 +277,9 @@ workflows:
|
||||||
- test_sim_gaia_fast:
|
- test_sim_gaia_fast:
|
||||||
requires:
|
requires:
|
||||||
- setup_dependencies
|
- setup_dependencies
|
||||||
|
- test_sim_gaia_import_export:
|
||||||
|
requires:
|
||||||
|
- setup_dependencies
|
||||||
- test_sim_gaia_multi_seed:
|
- test_sim_gaia_multi_seed:
|
||||||
requires:
|
requires:
|
||||||
- setup_dependencies
|
- setup_dependencies
|
||||||
|
|
|
@ -47,13 +47,14 @@ BUG FIXES
|
||||||
* Gaia
|
* Gaia
|
||||||
* [\#2670](https://github.com/cosmos/cosmos-sdk/issues/2670) [x/stake] fixed incorrect `IterateBondedValidators` and split into two functions: `IterateBondedValidators` and `IterateLastBlockConsValidators`
|
* [\#2670](https://github.com/cosmos/cosmos-sdk/issues/2670) [x/stake] fixed incorrect `IterateBondedValidators` and split into two functions: `IterateBondedValidators` and `IterateLastBlockConsValidators`
|
||||||
* [\#2691](https://github.com/cosmos/cosmos-sdk/issues/2691) Fix local testnet creation by using a single canonical genesis time
|
* [\#2691](https://github.com/cosmos/cosmos-sdk/issues/2691) Fix local testnet creation by using a single canonical genesis time
|
||||||
|
* [\#2648](https://github.com/cosmos/cosmos-sdk/issues/2648) [gaiad] Fix `gaiad export` / `gaiad import` consistency, test in CI
|
||||||
|
|
||||||
* SDK
|
* SDK
|
||||||
* [\#2625](https://github.com/cosmos/cosmos-sdk/issues/2625) [x/gov] fix AppendTag function usage error
|
* [\#2625](https://github.com/cosmos/cosmos-sdk/issues/2625) [x/gov] fix AppendTag function usage error
|
||||||
* [\#2677](https://github.com/cosmos/cosmos-sdk/issues/2677) [x/stake, x/distribution] various staking/distribution fixes as found by the simulator
|
* [\#2677](https://github.com/cosmos/cosmos-sdk/issues/2677) [x/stake, x/distribution] various staking/distribution fixes as found by the simulator
|
||||||
* [\#2674](https://github.com/cosmos/cosmos-sdk/issues/2674) [types] Fix coin.IsLT() impl, coins.IsLT() impl, and renamed coins.Is\* to coins.IsAll\* (see [\#2686](https://github.com/cosmos/cosmos-sdk/issues/2686))
|
* [\#2674](https://github.com/cosmos/cosmos-sdk/issues/2674) [types] Fix coin.IsLT() impl, coins.IsLT() impl, and renamed coins.Is\* to coins.IsAll\* (see [\#2686](https://github.com/cosmos/cosmos-sdk/issues/2686))
|
||||||
* [\#2711](https://github.com/cosmos/cosmos-sdk/issues/2711) [x/stake] Add commission data to `MsgCreateValidator` signature bytes.
|
* [\#2711](https://github.com/cosmos/cosmos-sdk/issues/2711) [x/stake] Add commission data to `MsgCreateValidator` signature bytes.
|
||||||
|
* Temporarily disable insecure mode for Gaia Lite
|
||||||
|
|
||||||
## 0.25.0
|
## 0.25.0
|
||||||
|
|
||||||
|
|
12
Makefile
12
Makefile
|
@ -171,6 +171,15 @@ test_sim_gaia_fast:
|
||||||
@echo "Running quick Gaia simulation. This may take several minutes..."
|
@echo "Running quick Gaia simulation. This may take several minutes..."
|
||||||
@go test ./cmd/gaia/app -run TestFullGaiaSimulation -SimulationEnabled=true -SimulationNumBlocks=500 -SimulationBlockSize=200 -SimulationCommit=true -SimulationSeed=10 -v -timeout 24h
|
@go test ./cmd/gaia/app -run TestFullGaiaSimulation -SimulationEnabled=true -SimulationNumBlocks=500 -SimulationBlockSize=200 -SimulationCommit=true -SimulationSeed=10 -v -timeout 24h
|
||||||
|
|
||||||
|
test_sim_gaia_import_export:
|
||||||
|
@echo "Running Gaia import/export simulation. This may take several minutes..."
|
||||||
|
@go test ./cmd/gaia/app -run TestGaiaImportExport -SimulationEnabled=true -SimulationNumBlocks=50 -SimulationBlockSize=200 -SimulationCommit=true -SimulationSeed=4 -v -timeout 24h
|
||||||
|
@go test ./cmd/gaia/app -run TestGaiaImportExport -SimulationEnabled=true -SimulationNumBlocks=50 -SimulationBlockSize=200 -SimulationCommit=true -SimulationSeed=11 -v -timeout 24h
|
||||||
|
@go test ./cmd/gaia/app -run TestGaiaImportExport -SimulationEnabled=true -SimulationNumBlocks=50 -SimulationBlockSize=200 -SimulationCommit=true -SimulationSeed=12 -v -timeout 24h
|
||||||
|
@go test ./cmd/gaia/app -run TestGaiaImportExport -SimulationEnabled=true -SimulationNumBlocks=50 -SimulationBlockSize=200 -SimulationCommit=true -SimulationSeed=13 -v -timeout 24h
|
||||||
|
@go test ./cmd/gaia/app -run TestGaiaImportExport -SimulationEnabled=true -SimulationNumBlocks=50 -SimulationBlockSize=200 -SimulationCommit=true -SimulationSeed=414 -v -timeout 24h
|
||||||
|
@go test ./cmd/gaia/app -run TestGaiaImportExport -SimulationEnabled=true -SimulationNumBlocks=50 -SimulationBlockSize=200 -SimulationCommit=true -SimulationSeed=4142 -v -timeout 24h
|
||||||
|
|
||||||
test_sim_gaia_multi_seed:
|
test_sim_gaia_multi_seed:
|
||||||
@echo "Running multi-seed Gaia simulation. This may take awhile!"
|
@echo "Running multi-seed Gaia simulation. This may take awhile!"
|
||||||
@bash scripts/multisim.sh 25
|
@bash scripts/multisim.sh 25
|
||||||
|
@ -250,4 +259,5 @@ localnet-stop:
|
||||||
check_tools check_dev_tools get_tools get_dev_tools get_vendor_deps draw_deps test test_cli test_unit \
|
check_tools check_dev_tools get_tools get_dev_tools get_vendor_deps draw_deps test test_cli test_unit \
|
||||||
test_cover test_lint benchmark devdoc_init devdoc devdoc_save devdoc_update \
|
test_cover test_lint benchmark devdoc_init devdoc devdoc_save devdoc_update \
|
||||||
build-linux build-docker-gaiadnode localnet-start localnet-stop \
|
build-linux build-docker-gaiadnode localnet-start localnet-stop \
|
||||||
format check-ledger test_sim_gaia_nondeterminism test_sim_modules test_sim_gaia_fast test_sim_gaia_multi_seed update_tools update_dev_tools
|
format check-ledger test_sim_gaia_nondeterminism test_sim_modules test_sim_gaia_fast \
|
||||||
|
test_sim_gaia_multi_seed test_sim_gaia_import_export update_tools update_dev_tools
|
||||||
|
|
|
@ -35,7 +35,7 @@ IMPROVEMENTS
|
||||||
* Gaia
|
* Gaia
|
||||||
|
|
||||||
* SDK
|
* SDK
|
||||||
- [mock/simulation] [\#2720] major cleanup, introduction of helper objects, reorganization
|
- [x/mock/simulation] [\#2720] major cleanup, introduction of helper objects, reorganization
|
||||||
|
|
||||||
* Tendermint
|
* Tendermint
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,11 @@ package lcd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/client"
|
"github.com/cosmos/cosmos-sdk/client"
|
||||||
"github.com/cosmos/cosmos-sdk/client/context"
|
"github.com/cosmos/cosmos-sdk/client/context"
|
||||||
"github.com/cosmos/cosmos-sdk/client/keys"
|
"github.com/cosmos/cosmos-sdk/client/keys"
|
||||||
|
@ -20,9 +25,6 @@ import (
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
"github.com/tendermint/tendermint/libs/log"
|
"github.com/tendermint/tendermint/libs/log"
|
||||||
tmserver "github.com/tendermint/tendermint/rpc/lib/server"
|
tmserver "github.com/tendermint/tendermint/rpc/lib/server"
|
||||||
"net"
|
|
||||||
"net/http"
|
|
||||||
"os"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -46,7 +48,9 @@ func ServeCommand(cdc *codec.Codec) *cobra.Command {
|
||||||
RunE: func(cmd *cobra.Command, args []string) (err error) {
|
RunE: func(cmd *cobra.Command, args []string) (err error) {
|
||||||
listenAddr := viper.GetString(flagListenAddr)
|
listenAddr := viper.GetString(flagListenAddr)
|
||||||
handler := createHandler(cdc)
|
handler := createHandler(cdc)
|
||||||
|
|
||||||
registerSwaggerUI(handler)
|
registerSwaggerUI(handler)
|
||||||
|
|
||||||
logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)).With("module", "rest-server")
|
logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)).With("module", "rest-server")
|
||||||
maxOpen := viper.GetInt(flagMaxOpenConnections)
|
maxOpen := viper.GetInt(flagMaxOpenConnections)
|
||||||
sslHosts := viper.GetString(flagSSLHosts)
|
sslHosts := viper.GetString(flagSSLHosts)
|
||||||
|
@ -62,14 +66,20 @@ func ServeCommand(cdc *codec.Codec) *cobra.Command {
|
||||||
})
|
})
|
||||||
|
|
||||||
var cleanupFunc func()
|
var cleanupFunc func()
|
||||||
|
|
||||||
|
// TODO: re-enable insecure mode once #2715 has been addressed
|
||||||
if viper.GetBool(flagInsecure) {
|
if viper.GetBool(flagInsecure) {
|
||||||
listener, err = tmserver.StartHTTPServer(
|
fmt.Println(
|
||||||
listenAddr, handler, logger,
|
"Insecure mode is temporarily disabled, please locally generate an " +
|
||||||
tmserver.Config{MaxOpenConnections: maxOpen},
|
"SSL certificate to test. Support will be re-enabled soon!",
|
||||||
)
|
)
|
||||||
if err != nil {
|
// listener, err = tmserver.StartHTTPServer(
|
||||||
return
|
// listenAddr, handler, logger,
|
||||||
}
|
// tmserver.Config{MaxOpenConnections: maxOpen},
|
||||||
|
// )
|
||||||
|
// if err != nil {
|
||||||
|
// return
|
||||||
|
// }
|
||||||
} else {
|
} else {
|
||||||
if certFile != "" {
|
if certFile != "" {
|
||||||
// validateCertKeyFiles() is needed to work around tendermint/tendermint#2460
|
// validateCertKeyFiles() is needed to work around tendermint/tendermint#2460
|
||||||
|
@ -77,6 +87,7 @@ func ServeCommand(cdc *codec.Codec) *cobra.Command {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// cert/key pair is provided, read the fingerprint
|
// cert/key pair is provided, read the fingerprint
|
||||||
fingerprint, err = fingerprintFromFile(certFile)
|
fingerprint, err = fingerprintFromFile(certFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -88,10 +99,12 @@ func ServeCommand(cdc *codec.Codec) *cobra.Command {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
cleanupFunc = func() {
|
cleanupFunc = func() {
|
||||||
os.Remove(certFile)
|
os.Remove(certFile)
|
||||||
os.Remove(keyFile)
|
os.Remove(keyFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
defer cleanupFunc()
|
defer cleanupFunc()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,9 +117,12 @@ func ServeCommand(cdc *codec.Codec) *cobra.Command {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.Info(fingerprint)
|
logger.Info(fingerprint)
|
||||||
}
|
|
||||||
logger.Info("REST server started")
|
logger.Info("REST server started")
|
||||||
|
}
|
||||||
|
|
||||||
|
// logger.Info("REST server started")
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
|
@ -123,6 +139,7 @@ func ServeCommand(cdc *codec.Codec) *cobra.Command {
|
||||||
cmd.Flags().Int(flagMaxOpenConnections, 1000, "The number of maximum open connections")
|
cmd.Flags().Int(flagMaxOpenConnections, 1000, "The number of maximum open connections")
|
||||||
cmd.Flags().Bool(client.FlagTrustNode, false, "Trust connected full node (don't verify proofs for responses)")
|
cmd.Flags().Bool(client.FlagTrustNode, false, "Trust connected full node (don't verify proofs for responses)")
|
||||||
cmd.Flags().Bool(client.FlagIndentResponse, false, "Add indent to JSON response")
|
cmd.Flags().Bool(client.FlagIndentResponse, false, "Add indent to JSON response")
|
||||||
|
|
||||||
viper.BindPFlag(client.FlagTrustNode, cmd.Flags().Lookup(client.FlagTrustNode))
|
viper.BindPFlag(client.FlagTrustNode, cmd.Flags().Lookup(client.FlagTrustNode))
|
||||||
viper.BindPFlag(client.FlagChainID, cmd.Flags().Lookup(client.FlagChainID))
|
viper.BindPFlag(client.FlagChainID, cmd.Flags().Lookup(client.FlagChainID))
|
||||||
viper.BindPFlag(client.FlagNode, cmd.Flags().Lookup(client.FlagNode))
|
viper.BindPFlag(client.FlagNode, cmd.Flags().Lookup(client.FlagNode))
|
||||||
|
|
|
@ -210,9 +210,6 @@ func (app *GaiaApp) EndBlocker(ctx sdk.Context, req abci.RequestEndBlock) abci.R
|
||||||
tags := gov.EndBlocker(ctx, app.govKeeper)
|
tags := gov.EndBlocker(ctx, app.govKeeper)
|
||||||
validatorUpdates := stake.EndBlocker(ctx, app.stakeKeeper)
|
validatorUpdates := stake.EndBlocker(ctx, app.stakeKeeper)
|
||||||
|
|
||||||
// Add these new validators to the addr -> pubkey map.
|
|
||||||
app.slashingKeeper.AddValidators(ctx, validatorUpdates)
|
|
||||||
|
|
||||||
return abci.ResponseEndBlock{
|
return abci.ResponseEndBlock{
|
||||||
ValidatorUpdates: validatorUpdates,
|
ValidatorUpdates: validatorUpdates,
|
||||||
Tags: tags,
|
Tags: tags,
|
||||||
|
@ -231,6 +228,10 @@ func (app *GaiaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci
|
||||||
// return sdk.ErrGenesisParse("").TraceCause(err, "")
|
// return sdk.ErrGenesisParse("").TraceCause(err, "")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// sort by account number to maintain consistency
|
||||||
|
sort.Slice(genesisState.Accounts, func(i, j int) bool {
|
||||||
|
return genesisState.Accounts[i].AccountNumber < genesisState.Accounts[j].AccountNumber
|
||||||
|
})
|
||||||
// load the accounts
|
// load the accounts
|
||||||
for _, gacc := range genesisState.Accounts {
|
for _, gacc := range genesisState.Accounts {
|
||||||
acc := gacc.ToAccount()
|
acc := gacc.ToAccount()
|
||||||
|
@ -244,7 +245,8 @@ func (app *GaiaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci
|
||||||
panic(err) // TODO find a way to do this w/o panics
|
panic(err) // TODO find a way to do this w/o panics
|
||||||
}
|
}
|
||||||
|
|
||||||
// load the address to pubkey map
|
// initialize module-specific stores
|
||||||
|
auth.InitGenesis(ctx, app.feeCollectionKeeper, genesisState.AuthData)
|
||||||
slashing.InitGenesis(ctx, app.slashingKeeper, genesisState.SlashingData, genesisState.StakeData)
|
slashing.InitGenesis(ctx, app.slashingKeeper, genesisState.SlashingData, genesisState.StakeData)
|
||||||
gov.InitGenesis(ctx, app.govKeeper, genesisState.GovData)
|
gov.InitGenesis(ctx, app.govKeeper, genesisState.GovData)
|
||||||
mint.InitGenesis(ctx, app.mintKeeper, genesisState.MintData)
|
mint.InitGenesis(ctx, app.mintKeeper, genesisState.MintData)
|
||||||
|
@ -270,7 +272,6 @@ func (app *GaiaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci
|
||||||
|
|
||||||
validators = app.stakeKeeper.ApplyAndReturnValidatorSetUpdates(ctx)
|
validators = app.stakeKeeper.ApplyAndReturnValidatorSetUpdates(ctx)
|
||||||
}
|
}
|
||||||
app.slashingKeeper.AddValidators(ctx, validators)
|
|
||||||
|
|
||||||
// sanity check
|
// sanity check
|
||||||
if len(req.Validators) > 0 {
|
if len(req.Validators) > 0 {
|
||||||
|
@ -306,11 +307,12 @@ func (app *GaiaApp) ExportAppStateAndValidators() (appState json.RawMessage, val
|
||||||
app.accountKeeper.IterateAccounts(ctx, appendAccount)
|
app.accountKeeper.IterateAccounts(ctx, appendAccount)
|
||||||
genState := NewGenesisState(
|
genState := NewGenesisState(
|
||||||
accounts,
|
accounts,
|
||||||
stake.WriteGenesis(ctx, app.stakeKeeper),
|
auth.ExportGenesis(ctx, app.feeCollectionKeeper),
|
||||||
mint.WriteGenesis(ctx, app.mintKeeper),
|
stake.ExportGenesis(ctx, app.stakeKeeper),
|
||||||
distr.WriteGenesis(ctx, app.distrKeeper),
|
mint.ExportGenesis(ctx, app.mintKeeper),
|
||||||
gov.WriteGenesis(ctx, app.govKeeper),
|
distr.ExportGenesis(ctx, app.distrKeeper),
|
||||||
slashing.GenesisState{}, // TODO create write methods
|
gov.ExportGenesis(ctx, app.govKeeper),
|
||||||
|
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 {
|
||||||
|
@ -337,12 +339,15 @@ var _ sdk.StakingHooks = Hooks{}
|
||||||
// nolint
|
// nolint
|
||||||
func (h Hooks) OnValidatorCreated(ctx sdk.Context, valAddr sdk.ValAddress) {
|
func (h Hooks) OnValidatorCreated(ctx sdk.Context, valAddr sdk.ValAddress) {
|
||||||
h.dh.OnValidatorCreated(ctx, valAddr)
|
h.dh.OnValidatorCreated(ctx, valAddr)
|
||||||
|
h.sh.OnValidatorCreated(ctx, valAddr)
|
||||||
}
|
}
|
||||||
func (h Hooks) OnValidatorModified(ctx sdk.Context, valAddr sdk.ValAddress) {
|
func (h Hooks) OnValidatorModified(ctx sdk.Context, valAddr sdk.ValAddress) {
|
||||||
h.dh.OnValidatorModified(ctx, valAddr)
|
h.dh.OnValidatorModified(ctx, valAddr)
|
||||||
|
h.sh.OnValidatorModified(ctx, valAddr)
|
||||||
}
|
}
|
||||||
func (h Hooks) OnValidatorRemoved(ctx sdk.Context, valAddr sdk.ValAddress) {
|
func (h Hooks) OnValidatorRemoved(ctx sdk.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) {
|
||||||
h.dh.OnValidatorRemoved(ctx, valAddr)
|
h.dh.OnValidatorRemoved(ctx, consAddr, valAddr)
|
||||||
|
h.sh.OnValidatorRemoved(ctx, consAddr, valAddr)
|
||||||
}
|
}
|
||||||
func (h Hooks) OnValidatorBonded(ctx sdk.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) {
|
func (h Hooks) OnValidatorBonded(ctx sdk.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) {
|
||||||
h.dh.OnValidatorBonded(ctx, consAddr, valAddr)
|
h.dh.OnValidatorBonded(ctx, consAddr, valAddr)
|
||||||
|
@ -358,10 +363,13 @@ func (h Hooks) OnValidatorBeginUnbonding(ctx sdk.Context, consAddr sdk.ConsAddre
|
||||||
}
|
}
|
||||||
func (h Hooks) OnDelegationCreated(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) {
|
func (h Hooks) OnDelegationCreated(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) {
|
||||||
h.dh.OnDelegationCreated(ctx, delAddr, valAddr)
|
h.dh.OnDelegationCreated(ctx, delAddr, valAddr)
|
||||||
|
h.sh.OnDelegationCreated(ctx, delAddr, valAddr)
|
||||||
}
|
}
|
||||||
func (h Hooks) OnDelegationSharesModified(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) {
|
func (h Hooks) OnDelegationSharesModified(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) {
|
||||||
h.dh.OnDelegationSharesModified(ctx, delAddr, valAddr)
|
h.dh.OnDelegationSharesModified(ctx, delAddr, valAddr)
|
||||||
|
h.sh.OnDelegationSharesModified(ctx, delAddr, valAddr)
|
||||||
}
|
}
|
||||||
func (h Hooks) OnDelegationRemoved(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) {
|
func (h Hooks) OnDelegationRemoved(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) {
|
||||||
h.dh.OnDelegationRemoved(ctx, delAddr, valAddr)
|
h.dh.OnDelegationRemoved(ctx, delAddr, valAddr)
|
||||||
|
h.sh.OnDelegationRemoved(ctx, delAddr, valAddr)
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,7 @@ var (
|
||||||
// State to Unmarshal
|
// State to Unmarshal
|
||||||
type GenesisState struct {
|
type GenesisState struct {
|
||||||
Accounts []GenesisAccount `json:"accounts"`
|
Accounts []GenesisAccount `json:"accounts"`
|
||||||
|
AuthData auth.GenesisState `json:"auth"`
|
||||||
StakeData stake.GenesisState `json:"stake"`
|
StakeData stake.GenesisState `json:"stake"`
|
||||||
MintData mint.GenesisState `json:"mint"`
|
MintData mint.GenesisState `json:"mint"`
|
||||||
DistrData distr.GenesisState `json:"distr"`
|
DistrData distr.GenesisState `json:"distr"`
|
||||||
|
@ -40,11 +41,12 @@ type GenesisState struct {
|
||||||
GenTxs []json.RawMessage `json:"gentxs"`
|
GenTxs []json.RawMessage `json:"gentxs"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewGenesisState(accounts []GenesisAccount, stakeData stake.GenesisState, mintData mint.GenesisState,
|
func NewGenesisState(accounts []GenesisAccount, authData auth.GenesisState, stakeData stake.GenesisState, mintData mint.GenesisState,
|
||||||
distrData distr.GenesisState, govData gov.GenesisState, slashingData slashing.GenesisState) GenesisState {
|
distrData distr.GenesisState, govData gov.GenesisState, slashingData slashing.GenesisState) GenesisState {
|
||||||
|
|
||||||
return GenesisState{
|
return GenesisState{
|
||||||
Accounts: accounts,
|
Accounts: accounts,
|
||||||
|
AuthData: authData,
|
||||||
StakeData: stakeData,
|
StakeData: stakeData,
|
||||||
MintData: mintData,
|
MintData: mintData,
|
||||||
DistrData: distrData,
|
DistrData: distrData,
|
||||||
|
@ -53,16 +55,20 @@ func NewGenesisState(accounts []GenesisAccount, stakeData stake.GenesisState, mi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GenesisAccount doesn't need pubkey or sequence
|
// nolint
|
||||||
type GenesisAccount struct {
|
type GenesisAccount struct {
|
||||||
Address sdk.AccAddress `json:"address"`
|
Address sdk.AccAddress `json:"address"`
|
||||||
Coins sdk.Coins `json:"coins"`
|
Coins sdk.Coins `json:"coins"`
|
||||||
|
Sequence int64 `json:"sequence_number"`
|
||||||
|
AccountNumber int64 `json:"account_number"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewGenesisAccount(acc *auth.BaseAccount) GenesisAccount {
|
func NewGenesisAccount(acc *auth.BaseAccount) GenesisAccount {
|
||||||
return GenesisAccount{
|
return GenesisAccount{
|
||||||
Address: acc.Address,
|
Address: acc.Address,
|
||||||
Coins: acc.Coins,
|
Coins: acc.Coins,
|
||||||
|
AccountNumber: acc.AccountNumber,
|
||||||
|
Sequence: acc.Sequence,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,6 +76,8 @@ func NewGenesisAccountI(acc auth.Account) GenesisAccount {
|
||||||
return GenesisAccount{
|
return GenesisAccount{
|
||||||
Address: acc.GetAddress(),
|
Address: acc.GetAddress(),
|
||||||
Coins: acc.GetCoins(),
|
Coins: acc.GetCoins(),
|
||||||
|
AccountNumber: acc.GetAccountNumber(),
|
||||||
|
Sequence: acc.GetSequence(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,6 +86,8 @@ func (ga *GenesisAccount) ToAccount() (acc *auth.BaseAccount) {
|
||||||
return &auth.BaseAccount{
|
return &auth.BaseAccount{
|
||||||
Address: ga.Address,
|
Address: ga.Address,
|
||||||
Coins: ga.Coins.Sort(),
|
Coins: ga.Coins.Sort(),
|
||||||
|
AccountNumber: ga.AccountNumber,
|
||||||
|
Sequence: ga.Sequence,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@ import (
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
abci "github.com/tendermint/tendermint/abci/types"
|
||||||
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"
|
||||||
|
|
||||||
|
@ -266,6 +267,103 @@ func TestFullGaiaSimulation(t *testing.T) {
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestGaiaImportExport(t *testing.T) {
|
||||||
|
if !enabled {
|
||||||
|
t.Skip("Skipping Gaia import/export simulation")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setup Gaia application
|
||||||
|
var logger log.Logger
|
||||||
|
if verbose {
|
||||||
|
logger = log.TestingLogger()
|
||||||
|
} else {
|
||||||
|
logger = log.NewNopLogger()
|
||||||
|
}
|
||||||
|
var db dbm.DB
|
||||||
|
dir, _ := ioutil.TempDir("", "goleveldb-gaia-sim")
|
||||||
|
db, _ = dbm.NewGoLevelDB("Simulation", dir)
|
||||||
|
defer func() {
|
||||||
|
db.Close()
|
||||||
|
os.RemoveAll(dir)
|
||||||
|
}()
|
||||||
|
app := NewGaiaApp(logger, db, nil)
|
||||||
|
require.Equal(t, "GaiaApp", app.Name())
|
||||||
|
|
||||||
|
// Run randomized simulation
|
||||||
|
err := simulation.SimulateFromSeed(
|
||||||
|
t, app.BaseApp, appStateFn, seed,
|
||||||
|
testAndRunTxs(app),
|
||||||
|
[]simulation.RandSetup{},
|
||||||
|
invariants(app),
|
||||||
|
numBlocks,
|
||||||
|
blockSize,
|
||||||
|
commit,
|
||||||
|
)
|
||||||
|
if commit {
|
||||||
|
// for memdb:
|
||||||
|
// fmt.Println("Database Size", db.Stats()["database.size"])
|
||||||
|
fmt.Println("GoLevelDB Stats")
|
||||||
|
fmt.Println(db.Stats()["leveldb.stats"])
|
||||||
|
fmt.Println("GoLevelDB cached block size", db.Stats()["leveldb.cachedblock"])
|
||||||
|
}
|
||||||
|
require.Nil(t, err)
|
||||||
|
|
||||||
|
fmt.Printf("Exporting genesis...\n")
|
||||||
|
|
||||||
|
appState, _, err := app.ExportAppStateAndValidators()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("Importing genesis...\n")
|
||||||
|
|
||||||
|
newDir, _ := ioutil.TempDir("", "goleveldb-gaia-sim-2")
|
||||||
|
newDB, _ := dbm.NewGoLevelDB("Simulation-2", dir)
|
||||||
|
defer func() {
|
||||||
|
newDB.Close()
|
||||||
|
os.RemoveAll(newDir)
|
||||||
|
}()
|
||||||
|
newApp := NewGaiaApp(log.NewNopLogger(), newDB, nil)
|
||||||
|
require.Equal(t, "GaiaApp", newApp.Name())
|
||||||
|
request := abci.RequestInitChain{
|
||||||
|
AppStateBytes: appState,
|
||||||
|
}
|
||||||
|
newApp.InitChain(request)
|
||||||
|
newApp.Commit()
|
||||||
|
|
||||||
|
fmt.Printf("Comparing stores...\n")
|
||||||
|
ctxA := app.NewContext(true, abci.Header{})
|
||||||
|
ctxB := newApp.NewContext(true, abci.Header{})
|
||||||
|
type StoreKeysPrefixes struct {
|
||||||
|
A sdk.StoreKey
|
||||||
|
B sdk.StoreKey
|
||||||
|
Prefixes [][]byte
|
||||||
|
}
|
||||||
|
storeKeysPrefixes := []StoreKeysPrefixes{
|
||||||
|
{app.keyMain, newApp.keyMain, [][]byte{}},
|
||||||
|
{app.keyAccount, newApp.keyAccount, [][]byte{}},
|
||||||
|
{app.keyStake, newApp.keyStake, [][]byte{stake.UnbondingQueueKey, stake.RedelegationQueueKey, stake.ValidatorQueueKey}}, // ordering may change but it doesn't matter
|
||||||
|
{app.keySlashing, newApp.keySlashing, [][]byte{}},
|
||||||
|
{app.keyMint, newApp.keyMint, [][]byte{}},
|
||||||
|
{app.keyDistr, newApp.keyDistr, [][]byte{}},
|
||||||
|
{app.keyFeeCollection, newApp.keyFeeCollection, [][]byte{}},
|
||||||
|
{app.keyParams, newApp.keyParams, [][]byte{}},
|
||||||
|
{app.keyGov, newApp.keyGov, [][]byte{}},
|
||||||
|
}
|
||||||
|
for _, storeKeysPrefix := range storeKeysPrefixes {
|
||||||
|
storeKeyA := storeKeysPrefix.A
|
||||||
|
storeKeyB := storeKeysPrefix.B
|
||||||
|
prefixes := storeKeysPrefix.Prefixes
|
||||||
|
storeA := ctxA.KVStore(storeKeyA)
|
||||||
|
storeB := ctxB.KVStore(storeKeyB)
|
||||||
|
kvA, kvB, count, equal := sdk.DiffKVStores(storeA, storeB, prefixes)
|
||||||
|
fmt.Printf("Compared %d key/value pairs between %s and %s\n", count, storeKeyA, storeKeyB)
|
||||||
|
require.True(t, equal, "unequal stores: %s / %s:\nstore A %s (%X) => %s (%X)\nstore B %s (%X) => %s (%X)",
|
||||||
|
storeKeyA, storeKeyB, kvA.Key, kvA.Key, kvA.Value, kvA.Value, kvB.Key, kvB.Key, kvB.Value, kvB.Value)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// 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 gaia
|
||||||
func TestAppStateDeterminism(t *testing.T) {
|
func TestAppStateDeterminism(t *testing.T) {
|
||||||
|
|
|
@ -113,6 +113,6 @@ func genAppStateFromConfig(
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err = WriteGenesisFile(genFile, initCfg.ChainID, nil, appState)
|
err = ExportGenesisFile(genFile, initCfg.ChainID, nil, appState)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,7 +70,7 @@ func InitCmd(ctx *server.Context, cdc *codec.Codec, appInit server.AppInit) *cob
|
||||||
viper.GetBool(flagOverwrite)); err != nil {
|
viper.GetBool(flagOverwrite)); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err = WriteGenesisFile(genFile, chainID, nil, appState); err != nil {
|
if err = ExportGenesisFile(genFile, chainID, nil, appState); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -298,7 +298,7 @@ func collectGenFiles(
|
||||||
genFile := config.GenesisFile()
|
genFile := config.GenesisFile()
|
||||||
|
|
||||||
// overwrite each validator's genesis file to have a canonical genesis time
|
// overwrite each validator's genesis file to have a canonical genesis time
|
||||||
err = WriteGenesisFileWithTime(genFile, chainID, nil, appState, genTime)
|
err = ExportGenesisFileWithTime(genFile, chainID, nil, appState, genTime)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,9 +17,9 @@ import (
|
||||||
"github.com/tendermint/tendermint/types"
|
"github.com/tendermint/tendermint/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
// WriteGenesisFile creates and writes the genesis configuration to disk. An
|
// ExportGenesisFile creates and writes the genesis configuration to disk. An
|
||||||
// error is returned if building or writing the configuration to file fails.
|
// error is returned if building or writing the configuration to file fails.
|
||||||
func WriteGenesisFile(
|
func ExportGenesisFile(
|
||||||
genFile, chainID string, validators []types.GenesisValidator, appState json.RawMessage,
|
genFile, chainID string, validators []types.GenesisValidator, appState json.RawMessage,
|
||||||
) error {
|
) error {
|
||||||
|
|
||||||
|
@ -36,9 +36,9 @@ func WriteGenesisFile(
|
||||||
return genDoc.SaveAs(genFile)
|
return genDoc.SaveAs(genFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteGenesisFileWithTime creates and writes the genesis configuration to disk.
|
// ExportGenesisFileWithTime creates and writes the genesis configuration to disk.
|
||||||
// An error is returned if building or writing the configuration to file fails.
|
// An error is returned if building or writing the configuration to file fails.
|
||||||
func WriteGenesisFileWithTime(
|
func ExportGenesisFileWithTime(
|
||||||
genFile, chainID string, validators []types.GenesisValidator,
|
genFile, chainID string, validators []types.GenesisValidator,
|
||||||
appState json.RawMessage, genTime time.Time,
|
appState json.RawMessage, genTime time.Time,
|
||||||
) error {
|
) error {
|
||||||
|
|
|
@ -7,7 +7,7 @@ The staking module allow for the following hooks to be registered with staking e
|
||||||
type StakingHooks interface {
|
type StakingHooks interface {
|
||||||
OnValidatorCreated(ctx Context, address ValAddress) // Must be called when a validator is created
|
OnValidatorCreated(ctx Context, address ValAddress) // Must be called when a validator is created
|
||||||
OnValidatorModified(ctx Context, address ValAddress) // Must be called when a validator's state changes
|
OnValidatorModified(ctx Context, address ValAddress) // Must be called when a validator's state changes
|
||||||
OnValidatorRemoved(ctx Context, address ValAddress) // Must be called when a validator is deleted
|
OnValidatorRemoved(ctx Context, address ConsAddress, operator ValAddress) // Must be called when a validator is deleted
|
||||||
|
|
||||||
OnValidatorBonded(ctx Context, address ConsAddress) // called when a validator is bonded
|
OnValidatorBonded(ctx Context, address ConsAddress) // called when a validator is bonded
|
||||||
OnValidatorBeginUnbonding(ctx Context, address ConsAddress, operator ValAddress) // called when a validator begins unbonding
|
OnValidatorBeginUnbonding(ctx Context, address ConsAddress, operator ValAddress) // called when a validator begins unbonding
|
||||||
|
|
|
@ -108,7 +108,7 @@ func InitCmd(ctx *server.Context, cdc *codec.Codec, appInit server.AppInit) *cob
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
fmt.Fprintf(os.Stderr, "%s\n", string(out))
|
fmt.Fprintf(os.Stderr, "%s\n", string(out))
|
||||||
return gaiaInit.WriteGenesisFile(config.GenesisFile(), chainID,
|
return gaiaInit.ExportGenesisFile(config.GenesisFile(), chainID,
|
||||||
[]tmtypes.GenesisValidator{validator}, appStateJSON)
|
[]tmtypes.GenesisValidator{validator}, appStateJSON)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -186,8 +186,8 @@ func (app *DemocoinApp) ExportAppStateAndValidators() (appState json.RawMessage,
|
||||||
|
|
||||||
genState := types.GenesisState{
|
genState := types.GenesisState{
|
||||||
Accounts: accounts,
|
Accounts: accounts,
|
||||||
POWGenesis: pow.WriteGenesis(ctx, app.powKeeper),
|
POWGenesis: pow.ExportGenesis(ctx, app.powKeeper),
|
||||||
CoolGenesis: cool.WriteGenesis(ctx, app.coolKeeper),
|
CoolGenesis: cool.ExportGenesis(ctx, app.coolKeeper),
|
||||||
}
|
}
|
||||||
appState, err = codec.MarshalJSONIndent(app.cdc, genState)
|
appState, err = codec.MarshalJSONIndent(app.cdc, genState)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -115,7 +115,7 @@ func InitCmd(ctx *server.Context, cdc *codec.Codec, appInit server.AppInit) *cob
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
fmt.Fprintf(os.Stderr, "%s\n", string(out))
|
fmt.Fprintf(os.Stderr, "%s\n", string(out))
|
||||||
return gaiaInit.WriteGenesisFile(config.GenesisFile(), chainID,
|
return gaiaInit.ExportGenesisFile(config.GenesisFile(), chainID,
|
||||||
[]tmtypes.GenesisValidator{validator}, appStateJSON)
|
[]tmtypes.GenesisValidator{validator}, appStateJSON)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,8 +49,8 @@ func InitGenesis(ctx sdk.Context, k Keeper, data Genesis) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteGenesis - output the genesis trend
|
// ExportGenesis - output the genesis trend
|
||||||
func WriteGenesis(ctx sdk.Context, k Keeper) Genesis {
|
func ExportGenesis(ctx sdk.Context, k Keeper) Genesis {
|
||||||
trend := k.GetTrend(ctx)
|
trend := k.GetTrend(ctx)
|
||||||
return Genesis{trend}
|
return Genesis{trend}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,7 @@ func TestCoolKeeper(t *testing.T) {
|
||||||
err := InitGenesis(ctx, keeper, Genesis{"icy"})
|
err := InitGenesis(ctx, keeper, Genesis{"icy"})
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
|
|
||||||
genesis := WriteGenesis(ctx, keeper)
|
genesis := ExportGenesis(ctx, keeper)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
require.Equal(t, genesis, Genesis{"icy"})
|
require.Equal(t, genesis, Genesis{"icy"})
|
||||||
|
|
||||||
|
|
|
@ -43,8 +43,8 @@ func InitGenesis(ctx sdk.Context, k Keeper, genesis Genesis) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteGenesis for the PoW module
|
// ExportGenesis for the PoW module
|
||||||
func WriteGenesis(ctx sdk.Context, k Keeper) Genesis {
|
func ExportGenesis(ctx sdk.Context, k Keeper) Genesis {
|
||||||
difficulty, err := k.GetLastDifficulty(ctx)
|
difficulty, err := k.GetLastDifficulty(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
|
|
@ -41,7 +41,7 @@ func TestPowKeeperGetSet(t *testing.T) {
|
||||||
err := InitGenesis(ctx, keeper, Genesis{uint64(1), uint64(0)})
|
err := InitGenesis(ctx, keeper, Genesis{uint64(1), uint64(0)})
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
|
|
||||||
genesis := WriteGenesis(ctx, keeper)
|
genesis := ExportGenesis(ctx, keeper)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
require.Equal(t, genesis, Genesis{uint64(1), uint64(0)})
|
require.Equal(t, genesis, Genesis{uint64(1), uint64(0)})
|
||||||
|
|
||||||
|
|
|
@ -117,7 +117,7 @@ type DelegationSet interface {
|
||||||
type StakingHooks interface {
|
type StakingHooks interface {
|
||||||
OnValidatorCreated(ctx Context, valAddr ValAddress) // Must be called when a validator is created
|
OnValidatorCreated(ctx Context, valAddr ValAddress) // Must be called when a validator is created
|
||||||
OnValidatorModified(ctx Context, valAddr ValAddress) // Must be called when a validator's state changes
|
OnValidatorModified(ctx Context, valAddr ValAddress) // Must be called when a validator's state changes
|
||||||
OnValidatorRemoved(ctx Context, valAddr ValAddress) // Must be called when a validator is deleted
|
OnValidatorRemoved(ctx Context, consAddr ConsAddress, valAddr ValAddress) // Must be called when a validator is deleted
|
||||||
|
|
||||||
OnValidatorBonded(ctx Context, consAddr ConsAddress, valAddr ValAddress) // Must be called when a validator is bonded
|
OnValidatorBonded(ctx Context, consAddr ConsAddress, valAddr ValAddress) // Must be called when a validator is bonded
|
||||||
OnValidatorBeginUnbonding(ctx Context, consAddr ConsAddress, valAddr ValAddress) // Must be called when a validator begins unbonding
|
OnValidatorBeginUnbonding(ctx Context, consAddr ConsAddress, valAddr ValAddress) // Must be called when a validator begins unbonding
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package types
|
package types
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
|
@ -176,6 +177,43 @@ func KVStoreReversePrefixIterator(kvs KVStore, prefix []byte) Iterator {
|
||||||
return kvs.ReverseIterator(prefix, PrefixEndBytes(prefix))
|
return kvs.ReverseIterator(prefix, PrefixEndBytes(prefix))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Compare two KVstores, return either the first key/value pair
|
||||||
|
// at which they differ and whether or not they are equal, skipping
|
||||||
|
// value comparison for a set of provided prefixes
|
||||||
|
func DiffKVStores(a KVStore, b KVStore, prefixesToSkip [][]byte) (kvA cmn.KVPair, kvB cmn.KVPair, count int64, equal bool) {
|
||||||
|
iterA := a.Iterator(nil, nil)
|
||||||
|
iterB := b.Iterator(nil, nil)
|
||||||
|
count = int64(0)
|
||||||
|
for {
|
||||||
|
if !iterA.Valid() && !iterB.Valid() {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
var kvA, kvB cmn.KVPair
|
||||||
|
if iterA.Valid() {
|
||||||
|
kvA = cmn.KVPair{Key: iterA.Key(), Value: iterA.Value()}
|
||||||
|
iterA.Next()
|
||||||
|
}
|
||||||
|
if iterB.Valid() {
|
||||||
|
kvB = cmn.KVPair{Key: iterB.Key(), Value: iterB.Value()}
|
||||||
|
iterB.Next()
|
||||||
|
}
|
||||||
|
compareValue := true
|
||||||
|
for _, prefix := range prefixesToSkip {
|
||||||
|
if bytes.Equal(kvA.Key[:len(prefix)], prefix) {
|
||||||
|
compareValue = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !bytes.Equal(kvA.Key, kvB.Key) {
|
||||||
|
return kvA, kvB, count, false
|
||||||
|
}
|
||||||
|
if compareValue && !bytes.Equal(kvA.Value, kvB.Value) {
|
||||||
|
return kvA, kvB, count, false
|
||||||
|
}
|
||||||
|
count++
|
||||||
|
}
|
||||||
|
return cmn.KVPair{}, cmn.KVPair{}, count, true
|
||||||
|
}
|
||||||
|
|
||||||
// CacheKVStore cache-wraps a KVStore. After calling .Write() on
|
// CacheKVStore cache-wraps a KVStore. After calling .Write() on
|
||||||
// the CacheKVStore, all previously created CacheKVStores on the
|
// the CacheKVStore, all previously created CacheKVStores on the
|
||||||
// object expire.
|
// object expire.
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
package auth
|
||||||
|
|
||||||
|
import (
|
||||||
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GenesisState - all auth state that must be provided at genesis
|
||||||
|
type GenesisState struct {
|
||||||
|
CollectedFees sdk.Coins `json:"collected_fees"` // collected fees
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a new genesis state
|
||||||
|
func NewGenesisState(collectedFees sdk.Coins) GenesisState {
|
||||||
|
return GenesisState{
|
||||||
|
CollectedFees: collectedFees,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return a default genesis state
|
||||||
|
func DefaultGenesisState() GenesisState {
|
||||||
|
return NewGenesisState(sdk.Coins{})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Init store state from genesis data
|
||||||
|
func InitGenesis(ctx sdk.Context, keeper FeeCollectionKeeper, data GenesisState) {
|
||||||
|
keeper.setCollectedFees(ctx, data.CollectedFees)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExportGenesis returns a GenesisState for a given context and keeper
|
||||||
|
func ExportGenesis(ctx sdk.Context, keeper FeeCollectionKeeper) GenesisState {
|
||||||
|
collectedFees := keeper.GetCollectedFees(ctx)
|
||||||
|
return NewGenesisState(collectedFees)
|
||||||
|
}
|
|
@ -21,11 +21,12 @@ func InitGenesis(ctx sdk.Context, keeper Keeper, data types.GenesisState) {
|
||||||
for _, dw := range data.DelegatorWithdrawInfos {
|
for _, dw := range data.DelegatorWithdrawInfos {
|
||||||
keeper.SetDelegatorWithdrawAddr(ctx, dw.DelegatorAddr, dw.WithdrawAddr)
|
keeper.SetDelegatorWithdrawAddr(ctx, dw.DelegatorAddr, dw.WithdrawAddr)
|
||||||
}
|
}
|
||||||
|
keeper.SetPreviousProposerConsAddr(ctx, data.PreviousProposer)
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteGenesis returns a GenesisState for a given context and keeper. The
|
// ExportGenesis returns a GenesisState for a given context and keeper. The
|
||||||
// GenesisState will contain the pool, and validator/delegator distribution info's
|
// GenesisState will contain the pool, and validator/delegator distribution info's
|
||||||
func WriteGenesis(ctx sdk.Context, keeper Keeper) types.GenesisState {
|
func ExportGenesis(ctx sdk.Context, keeper Keeper) types.GenesisState {
|
||||||
feePool := keeper.GetFeePool(ctx)
|
feePool := keeper.GetFeePool(ctx)
|
||||||
communityTax := keeper.GetCommunityTax(ctx)
|
communityTax := keeper.GetCommunityTax(ctx)
|
||||||
baseProposerRewards := keeper.GetBaseProposerReward(ctx)
|
baseProposerRewards := keeper.GetBaseProposerReward(ctx)
|
||||||
|
@ -33,6 +34,7 @@ func WriteGenesis(ctx sdk.Context, keeper Keeper) types.GenesisState {
|
||||||
vdis := keeper.GetAllValidatorDistInfos(ctx)
|
vdis := keeper.GetAllValidatorDistInfos(ctx)
|
||||||
ddis := keeper.GetAllDelegationDistInfos(ctx)
|
ddis := keeper.GetAllDelegationDistInfos(ctx)
|
||||||
dwis := keeper.GetAllDelegatorWithdrawInfos(ctx)
|
dwis := keeper.GetAllDelegatorWithdrawInfos(ctx)
|
||||||
|
pp := keeper.GetPreviousProposerConsAddr(ctx)
|
||||||
return NewGenesisState(feePool, communityTax, baseProposerRewards,
|
return NewGenesisState(feePool, communityTax, baseProposerRewards,
|
||||||
bonusProposerRewards, vdis, ddis, dwis)
|
bonusProposerRewards, vdis, ddis, dwis, pp)
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,12 +36,12 @@ func (k Keeper) GetAllDelegationDistInfos(ctx sdk.Context) (ddis []types.Delegat
|
||||||
// Get the set of all delegator-withdraw addresses with no limits, used during genesis dump
|
// Get the set of all delegator-withdraw addresses with no limits, used during genesis dump
|
||||||
func (k Keeper) GetAllDelegatorWithdrawInfos(ctx sdk.Context) (dwis []types.DelegatorWithdrawInfo) {
|
func (k Keeper) GetAllDelegatorWithdrawInfos(ctx sdk.Context) (dwis []types.DelegatorWithdrawInfo) {
|
||||||
store := ctx.KVStore(k.storeKey)
|
store := ctx.KVStore(k.storeKey)
|
||||||
iterator := sdk.KVStorePrefixIterator(store, DelegationDistInfoKey)
|
iterator := sdk.KVStorePrefixIterator(store, DelegatorWithdrawInfoKey)
|
||||||
defer iterator.Close()
|
defer iterator.Close()
|
||||||
|
|
||||||
for ; iterator.Valid(); iterator.Next() {
|
for ; iterator.Valid(); iterator.Next() {
|
||||||
dw := types.DelegatorWithdrawInfo{
|
dw := types.DelegatorWithdrawInfo{
|
||||||
DelegatorAddr: sdk.AccAddress(iterator.Key()),
|
DelegatorAddr: GetDelegatorWithdrawInfoAddress(iterator.Key()),
|
||||||
WithdrawAddr: sdk.AccAddress(iterator.Value()),
|
WithdrawAddr: sdk.AccAddress(iterator.Value()),
|
||||||
}
|
}
|
||||||
dwis = append(dwis, dw)
|
dwis = append(dwis, dw)
|
||||||
|
|
|
@ -103,7 +103,7 @@ func (h Hooks) OnValidatorCreated(ctx sdk.Context, valAddr sdk.ValAddress) {
|
||||||
func (h Hooks) OnValidatorModified(ctx sdk.Context, valAddr sdk.ValAddress) {
|
func (h Hooks) OnValidatorModified(ctx sdk.Context, valAddr sdk.ValAddress) {
|
||||||
h.k.onValidatorModified(ctx, valAddr)
|
h.k.onValidatorModified(ctx, valAddr)
|
||||||
}
|
}
|
||||||
func (h Hooks) OnValidatorRemoved(ctx sdk.Context, valAddr sdk.ValAddress) {
|
func (h Hooks) OnValidatorRemoved(ctx sdk.Context, _ sdk.ConsAddress, valAddr sdk.ValAddress) {
|
||||||
h.k.onValidatorRemoved(ctx, valAddr)
|
h.k.onValidatorRemoved(ctx, valAddr)
|
||||||
}
|
}
|
||||||
func (h Hooks) OnDelegationCreated(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) {
|
func (h Hooks) OnDelegationCreated(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) {
|
||||||
|
|
|
@ -44,3 +44,12 @@ func GetDelegationDistInfosKey(delAddr sdk.AccAddress) []byte {
|
||||||
func GetDelegatorWithdrawAddrKey(delAddr sdk.AccAddress) []byte {
|
func GetDelegatorWithdrawAddrKey(delAddr sdk.AccAddress) []byte {
|
||||||
return append(DelegatorWithdrawInfoKey, delAddr.Bytes()...)
|
return append(DelegatorWithdrawInfoKey, delAddr.Bytes()...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// gets an address from a delegator's withdraw info key
|
||||||
|
func GetDelegatorWithdrawInfoAddress(key []byte) (delAddr sdk.AccAddress) {
|
||||||
|
addr := key[1:]
|
||||||
|
if len(addr) != sdk.AddrLen {
|
||||||
|
panic("unexpected key length")
|
||||||
|
}
|
||||||
|
return sdk.AccAddress(addr)
|
||||||
|
}
|
||||||
|
|
|
@ -18,10 +18,11 @@ type GenesisState struct {
|
||||||
ValidatorDistInfos []ValidatorDistInfo `json:"validator_dist_infos"`
|
ValidatorDistInfos []ValidatorDistInfo `json:"validator_dist_infos"`
|
||||||
DelegationDistInfos []DelegationDistInfo `json:"delegator_dist_infos"`
|
DelegationDistInfos []DelegationDistInfo `json:"delegator_dist_infos"`
|
||||||
DelegatorWithdrawInfos []DelegatorWithdrawInfo `json:"delegator_withdraw_infos"`
|
DelegatorWithdrawInfos []DelegatorWithdrawInfo `json:"delegator_withdraw_infos"`
|
||||||
|
PreviousProposer sdk.ConsAddress `json:"previous_proposer"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewGenesisState(feePool FeePool, communityTax, baseProposerReward, bonusProposerReward sdk.Dec,
|
func NewGenesisState(feePool FeePool, communityTax, baseProposerReward, bonusProposerReward sdk.Dec,
|
||||||
vdis []ValidatorDistInfo, ddis []DelegationDistInfo, dwis []DelegatorWithdrawInfo) GenesisState {
|
vdis []ValidatorDistInfo, ddis []DelegationDistInfo, dwis []DelegatorWithdrawInfo, pp sdk.ConsAddress) GenesisState {
|
||||||
|
|
||||||
return GenesisState{
|
return GenesisState{
|
||||||
FeePool: feePool,
|
FeePool: feePool,
|
||||||
|
@ -31,6 +32,7 @@ func NewGenesisState(feePool FeePool, communityTax, baseProposerReward, bonusPro
|
||||||
ValidatorDistInfos: vdis,
|
ValidatorDistInfos: vdis,
|
||||||
DelegationDistInfos: ddis,
|
DelegationDistInfos: ddis,
|
||||||
DelegatorWithdrawInfos: dwis,
|
DelegatorWithdrawInfos: dwis,
|
||||||
|
PreviousProposer: pp,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,12 +8,27 @@ import (
|
||||||
|
|
||||||
// GenesisState - all staking state that must be provided at genesis
|
// GenesisState - all staking state that must be provided at genesis
|
||||||
type GenesisState struct {
|
type GenesisState struct {
|
||||||
StartingProposalID uint64 `json:"starting_proposalID"`
|
StartingProposalID uint64 `json:"starting_proposal_id"`
|
||||||
|
Deposits []DepositWithMetadata `json:"deposits"`
|
||||||
|
Votes []VoteWithMetadata `json:"votes"`
|
||||||
|
Proposals []Proposal `json:"proposals"`
|
||||||
DepositParams DepositParams `json:"deposit_params"`
|
DepositParams DepositParams `json:"deposit_params"`
|
||||||
VotingParams VotingParams `json:"voting_params"`
|
VotingParams VotingParams `json:"voting_params"`
|
||||||
TallyParams TallyParams `json:"tally_params"`
|
TallyParams TallyParams `json:"tally_params"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DepositWithMetadata (just for genesis)
|
||||||
|
type DepositWithMetadata struct {
|
||||||
|
ProposalID uint64 `json:"proposal_id"`
|
||||||
|
Deposit Deposit `json:"deposit"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// VoteWithMetadata (just for genesis)
|
||||||
|
type VoteWithMetadata struct {
|
||||||
|
ProposalID uint64 `json:"proposal_id"`
|
||||||
|
Vote Vote `json:"vote"`
|
||||||
|
}
|
||||||
|
|
||||||
func NewGenesisState(startingProposalID uint64, dp DepositParams, vp VotingParams, tp TallyParams) GenesisState {
|
func NewGenesisState(startingProposalID uint64, dp DepositParams, vp VotingParams, tp TallyParams) GenesisState {
|
||||||
return GenesisState{
|
return GenesisState{
|
||||||
StartingProposalID: startingProposalID,
|
StartingProposalID: startingProposalID,
|
||||||
|
@ -52,17 +67,47 @@ func InitGenesis(ctx sdk.Context, k Keeper, data GenesisState) {
|
||||||
k.setDepositParams(ctx, data.DepositParams)
|
k.setDepositParams(ctx, data.DepositParams)
|
||||||
k.setVotingParams(ctx, data.VotingParams)
|
k.setVotingParams(ctx, data.VotingParams)
|
||||||
k.setTallyParams(ctx, data.TallyParams)
|
k.setTallyParams(ctx, data.TallyParams)
|
||||||
|
for _, deposit := range data.Deposits {
|
||||||
|
k.setDeposit(ctx, deposit.ProposalID, deposit.Deposit.Depositer, deposit.Deposit)
|
||||||
|
}
|
||||||
|
for _, vote := range data.Votes {
|
||||||
|
k.setVote(ctx, vote.ProposalID, vote.Vote.Voter, vote.Vote)
|
||||||
|
}
|
||||||
|
for _, proposal := range data.Proposals {
|
||||||
|
k.SetProposal(ctx, proposal)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteGenesis - output genesis parameters
|
// ExportGenesis - output genesis parameters
|
||||||
func WriteGenesis(ctx sdk.Context, k Keeper) GenesisState {
|
func ExportGenesis(ctx sdk.Context, k Keeper) GenesisState {
|
||||||
startingProposalID, _ := k.getNewProposalID(ctx)
|
startingProposalID, _ := k.peekCurrentProposalID(ctx)
|
||||||
depositParams := k.GetDepositParams(ctx)
|
depositParams := k.GetDepositParams(ctx)
|
||||||
votingParams := k.GetVotingParams(ctx)
|
votingParams := k.GetVotingParams(ctx)
|
||||||
tallyParams := k.GetTallyParams(ctx)
|
tallyParams := k.GetTallyParams(ctx)
|
||||||
|
var deposits []DepositWithMetadata
|
||||||
|
var votes []VoteWithMetadata
|
||||||
|
proposals := k.GetProposalsFiltered(ctx, nil, nil, StatusNil, 0)
|
||||||
|
for _, proposal := range proposals {
|
||||||
|
proposalID := proposal.GetProposalID()
|
||||||
|
depositsIterator := k.GetDeposits(ctx, proposalID)
|
||||||
|
for ; depositsIterator.Valid(); depositsIterator.Next() {
|
||||||
|
var deposit Deposit
|
||||||
|
k.cdc.MustUnmarshalBinaryLengthPrefixed(depositsIterator.Value(), &deposit)
|
||||||
|
deposits = append(deposits, DepositWithMetadata{proposalID, deposit})
|
||||||
|
}
|
||||||
|
votesIterator := k.GetVotes(ctx, proposalID)
|
||||||
|
for ; votesIterator.Valid(); votesIterator.Next() {
|
||||||
|
var vote Vote
|
||||||
|
k.cdc.MustUnmarshalBinaryLengthPrefixed(votesIterator.Value(), &vote)
|
||||||
|
votes = append(votes, VoteWithMetadata{proposalID, vote})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return GenesisState{
|
return GenesisState{
|
||||||
StartingProposalID: startingProposalID,
|
StartingProposalID: startingProposalID,
|
||||||
|
Deposits: deposits,
|
||||||
|
Votes: votes,
|
||||||
|
Proposals: proposals,
|
||||||
DepositParams: depositParams,
|
DepositParams: depositParams,
|
||||||
VotingParams: votingParams,
|
VotingParams: votingParams,
|
||||||
TallyParams: tallyParams,
|
TallyParams: tallyParams,
|
||||||
|
|
|
@ -107,8 +107,8 @@ func EndBlocker(ctx sdk.Context, keeper Keeper) (resTags sdk.Tags) {
|
||||||
var proposalID uint64
|
var proposalID uint64
|
||||||
keeper.cdc.MustUnmarshalBinaryLengthPrefixed(inactiveIterator.Value(), &proposalID)
|
keeper.cdc.MustUnmarshalBinaryLengthPrefixed(inactiveIterator.Value(), &proposalID)
|
||||||
inactiveProposal := keeper.GetProposal(ctx, proposalID)
|
inactiveProposal := keeper.GetProposal(ctx, proposalID)
|
||||||
keeper.RefundDeposits(ctx, proposalID)
|
|
||||||
keeper.DeleteProposal(ctx, proposalID)
|
keeper.DeleteProposal(ctx, proposalID)
|
||||||
|
keeper.DeleteDeposits(ctx, proposalID) // delete any associated deposits (burned)
|
||||||
|
|
||||||
resTags = resTags.AppendTag(tags.Action, tags.ActionProposalDropped)
|
resTags = resTags.AppendTag(tags.Action, tags.ActionProposalDropped)
|
||||||
resTags = resTags.AppendTag(tags.ProposalID, []byte(string(proposalID)))
|
resTags = resTags.AppendTag(tags.ProposalID, []byte(string(proposalID)))
|
||||||
|
|
|
@ -31,9 +31,9 @@ func InitGenesis(ctx sdk.Context, keeper Keeper, data GenesisState) {
|
||||||
keeper.SetParams(ctx, data.Params)
|
keeper.SetParams(ctx, data.Params)
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteGenesis returns a GenesisState for a given context and keeper. The
|
// ExportGenesis returns a GenesisState for a given context and keeper. The
|
||||||
// GenesisState will contain the pool, and validator/delegator distribution info's
|
// GenesisState will contain the pool, and validator/delegator distribution info's
|
||||||
func WriteGenesis(ctx sdk.Context, keeper Keeper) GenesisState {
|
func ExportGenesis(ctx sdk.Context, keeper Keeper) GenesisState {
|
||||||
|
|
||||||
minter := keeper.GetMinter(ctx)
|
minter := keeper.GetMinter(ctx)
|
||||||
params := keeper.GetParams(ctx)
|
params := keeper.GetParams(ctx)
|
||||||
|
|
|
@ -8,12 +8,24 @@ import (
|
||||||
// GenesisState - all slashing state that must be provided at genesis
|
// GenesisState - all slashing state that must be provided at genesis
|
||||||
type GenesisState struct {
|
type GenesisState struct {
|
||||||
Params Params
|
Params Params
|
||||||
|
SigningInfos map[string]ValidatorSigningInfo
|
||||||
|
MissedBlocks map[string][]MissedBlock
|
||||||
|
SlashingPeriods []ValidatorSlashingPeriod
|
||||||
|
}
|
||||||
|
|
||||||
|
// MissedBlock
|
||||||
|
type MissedBlock struct {
|
||||||
|
Index int64 `json:"index"`
|
||||||
|
Missed bool `json:"missed"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// HubDefaultGenesisState - default GenesisState used by Cosmos Hub
|
// HubDefaultGenesisState - default GenesisState used by Cosmos Hub
|
||||||
func DefaultGenesisState() GenesisState {
|
func DefaultGenesisState() GenesisState {
|
||||||
return GenesisState{
|
return GenesisState{
|
||||||
Params: DefaultParams(),
|
Params: DefaultParams(),
|
||||||
|
SigningInfos: make(map[string]ValidatorSigningInfo),
|
||||||
|
MissedBlocks: make(map[string][]MissedBlock),
|
||||||
|
SlashingPeriods: []ValidatorSlashingPeriod{},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,5 +36,64 @@ func InitGenesis(ctx sdk.Context, keeper Keeper, data GenesisState, sdata types.
|
||||||
keeper.addPubkey(ctx, validator.GetConsPubKey())
|
keeper.addPubkey(ctx, validator.GetConsPubKey())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for addr, info := range data.SigningInfos {
|
||||||
|
address, err := sdk.ConsAddressFromBech32(addr)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
keeper.setValidatorSigningInfo(ctx, address, info)
|
||||||
|
}
|
||||||
|
|
||||||
|
for addr, array := range data.MissedBlocks {
|
||||||
|
address, err := sdk.ConsAddressFromBech32(addr)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
for _, missed := range array {
|
||||||
|
keeper.setValidatorMissedBlockBitArray(ctx, address, missed.Index, missed.Missed)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, slashingPeriod := range data.SlashingPeriods {
|
||||||
|
keeper.addOrUpdateValidatorSlashingPeriod(ctx, slashingPeriod)
|
||||||
|
}
|
||||||
|
|
||||||
keeper.paramspace.SetParamSet(ctx, &data.Params)
|
keeper.paramspace.SetParamSet(ctx, &data.Params)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ExportGenesis writes the current store values
|
||||||
|
// to a genesis file, which can be imported again
|
||||||
|
// with InitGenesis
|
||||||
|
func ExportGenesis(ctx sdk.Context, keeper Keeper) (data GenesisState) {
|
||||||
|
var params Params
|
||||||
|
keeper.paramspace.GetParamSet(ctx, ¶ms)
|
||||||
|
|
||||||
|
signingInfos := make(map[string]ValidatorSigningInfo)
|
||||||
|
missedBlocks := make(map[string][]MissedBlock)
|
||||||
|
keeper.iterateValidatorSigningInfos(ctx, func(address sdk.ConsAddress, info ValidatorSigningInfo) (stop bool) {
|
||||||
|
bechAddr := address.String()
|
||||||
|
signingInfos[bechAddr] = info
|
||||||
|
array := []MissedBlock{}
|
||||||
|
|
||||||
|
keeper.iterateValidatorMissedBlockBitArray(ctx, address, func(index int64, missed bool) (stop bool) {
|
||||||
|
array = append(array, MissedBlock{index, missed})
|
||||||
|
return false
|
||||||
|
})
|
||||||
|
missedBlocks[bechAddr] = array
|
||||||
|
|
||||||
|
return false
|
||||||
|
})
|
||||||
|
|
||||||
|
slashingPeriods := []ValidatorSlashingPeriod{}
|
||||||
|
keeper.iterateValidatorSlashingPeriods(ctx, func(slashingPeriod ValidatorSlashingPeriod) (stop bool) {
|
||||||
|
slashingPeriods = append(slashingPeriods, slashingPeriod)
|
||||||
|
return false
|
||||||
|
})
|
||||||
|
|
||||||
|
return GenesisState{
|
||||||
|
Params: params,
|
||||||
|
SigningInfos: signingInfos,
|
||||||
|
MissedBlocks: missedBlocks,
|
||||||
|
SlashingPeriods: slashingPeriods,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -3,6 +3,8 @@ package slashing
|
||||||
import (
|
import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/tendermint/tendermint/crypto"
|
||||||
|
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -36,6 +38,17 @@ func (k Keeper) onValidatorBeginUnbonding(ctx sdk.Context, address sdk.ConsAddre
|
||||||
k.addOrUpdateValidatorSlashingPeriod(ctx, slashingPeriod)
|
k.addOrUpdateValidatorSlashingPeriod(ctx, slashingPeriod)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// When a validator is created, add the address-pubkey relation.
|
||||||
|
func (k Keeper) onValidatorCreated(ctx sdk.Context, valAddr sdk.ValAddress) {
|
||||||
|
validator := k.validatorSet.Validator(ctx, valAddr)
|
||||||
|
k.addPubkey(ctx, validator.GetConsPubKey())
|
||||||
|
}
|
||||||
|
|
||||||
|
// When a validator is removed, delete the address-pubkey relation.
|
||||||
|
func (k Keeper) onValidatorRemoved(ctx sdk.Context, address sdk.ConsAddress) {
|
||||||
|
k.deleteAddrPubkeyRelation(ctx, crypto.Address(address))
|
||||||
|
}
|
||||||
|
|
||||||
//_________________________________________________________________________________________
|
//_________________________________________________________________________________________
|
||||||
|
|
||||||
// Wrapper struct
|
// Wrapper struct
|
||||||
|
@ -60,12 +73,20 @@ func (h Hooks) OnValidatorBeginUnbonding(ctx sdk.Context, consAddr sdk.ConsAddre
|
||||||
h.k.onValidatorBeginUnbonding(ctx, consAddr, valAddr)
|
h.k.onValidatorBeginUnbonding(ctx, consAddr, valAddr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Implements sdk.ValidatorHooks
|
||||||
|
func (h Hooks) OnValidatorRemoved(ctx sdk.Context, consAddr sdk.ConsAddress, _ sdk.ValAddress) {
|
||||||
|
h.k.onValidatorRemoved(ctx, consAddr)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Implements sdk.ValidatorHooks
|
||||||
|
func (h Hooks) OnValidatorCreated(ctx sdk.Context, valAddr sdk.ValAddress) {
|
||||||
|
h.k.onValidatorCreated(ctx, valAddr)
|
||||||
|
}
|
||||||
|
|
||||||
// nolint - unused hooks
|
// nolint - unused hooks
|
||||||
func (h Hooks) OnValidatorPowerDidChange(ctx sdk.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) {
|
func (h Hooks) OnValidatorPowerDidChange(ctx sdk.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) {
|
||||||
}
|
}
|
||||||
func (h Hooks) OnValidatorCreated(_ sdk.Context, _ sdk.ValAddress) {}
|
|
||||||
func (h Hooks) OnValidatorModified(_ sdk.Context, _ sdk.ValAddress) {}
|
func (h Hooks) OnValidatorModified(_ sdk.Context, _ sdk.ValAddress) {}
|
||||||
func (h Hooks) OnValidatorRemoved(_ sdk.Context, _ sdk.ValAddress) {}
|
|
||||||
func (h Hooks) OnDelegationCreated(_ sdk.Context, _ sdk.AccAddress, _ sdk.ValAddress) {}
|
func (h Hooks) OnDelegationCreated(_ sdk.Context, _ sdk.AccAddress, _ sdk.ValAddress) {}
|
||||||
func (h Hooks) OnDelegationSharesModified(_ sdk.Context, _ sdk.AccAddress, _ sdk.ValAddress) {}
|
func (h Hooks) OnDelegationSharesModified(_ sdk.Context, _ sdk.AccAddress, _ sdk.ValAddress) {}
|
||||||
func (h Hooks) OnDelegationRemoved(_ sdk.Context, _ sdk.AccAddress, _ sdk.ValAddress) {}
|
func (h Hooks) OnDelegationRemoved(_ sdk.Context, _ sdk.AccAddress, _ sdk.ValAddress) {}
|
||||||
|
|
|
@ -4,13 +4,10 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
tmtypes "github.com/tendermint/tendermint/types"
|
|
||||||
|
|
||||||
"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/params"
|
"github.com/cosmos/cosmos-sdk/x/params"
|
||||||
stake "github.com/cosmos/cosmos-sdk/x/stake/types"
|
stake "github.com/cosmos/cosmos-sdk/x/stake/types"
|
||||||
abci "github.com/tendermint/tendermint/abci/types"
|
|
||||||
"github.com/tendermint/tendermint/crypto"
|
"github.com/tendermint/tendermint/crypto"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -174,19 +171,6 @@ func (k Keeper) handleValidatorSignature(ctx sdk.Context, addr crypto.Address, p
|
||||||
k.setValidatorSigningInfo(ctx, consAddr, signInfo)
|
k.setValidatorSigningInfo(ctx, consAddr, signInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddValidators adds the validators to the keepers validator addr to pubkey mapping.
|
|
||||||
func (k Keeper) AddValidators(ctx sdk.Context, vals []abci.ValidatorUpdate) {
|
|
||||||
for i := 0; i < len(vals); i++ {
|
|
||||||
val := vals[i]
|
|
||||||
pubkey, err := tmtypes.PB2TM.PubKey(val.PubKey)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
k.addPubkey(ctx, pubkey)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Make a method to remove the pubkey from the map when a validator is unbonded.
|
|
||||||
func (k Keeper) addPubkey(ctx sdk.Context, pubkey crypto.PubKey) {
|
func (k Keeper) addPubkey(ctx sdk.Context, pubkey crypto.PubKey) {
|
||||||
addr := pubkey.Address()
|
addr := pubkey.Address()
|
||||||
k.setAddrPubkeyRelation(ctx, addr, pubkey)
|
k.setAddrPubkeyRelation(ctx, addr, pubkey)
|
||||||
|
|
|
@ -34,8 +34,7 @@ func TestHandleDoubleSign(t *testing.T) {
|
||||||
operatorAddr, val, amt := addrs[0], pks[0], sdk.NewInt(amtInt)
|
operatorAddr, val, amt := addrs[0], pks[0], sdk.NewInt(amtInt)
|
||||||
got := stake.NewHandler(sk)(ctx, NewTestMsgCreateValidator(operatorAddr, val, amt))
|
got := stake.NewHandler(sk)(ctx, NewTestMsgCreateValidator(operatorAddr, val, amt))
|
||||||
require.True(t, got.IsOK())
|
require.True(t, got.IsOK())
|
||||||
validatorUpdates := stake.EndBlocker(ctx, sk)
|
stake.EndBlocker(ctx, sk)
|
||||||
keeper.AddValidators(ctx, validatorUpdates)
|
|
||||||
require.Equal(t, ck.GetCoins(ctx, sdk.AccAddress(operatorAddr)), sdk.Coins{{sk.GetParams(ctx).BondDenom, initCoins.Sub(amt)}})
|
require.Equal(t, ck.GetCoins(ctx, sdk.AccAddress(operatorAddr)), sdk.Coins{{sk.GetParams(ctx).BondDenom, initCoins.Sub(amt)}})
|
||||||
require.True(t, sdk.NewDecFromInt(amt).Equal(sk.Validator(ctx, operatorAddr).GetPower()))
|
require.True(t, sdk.NewDecFromInt(amt).Equal(sk.Validator(ctx, operatorAddr).GetPower()))
|
||||||
|
|
||||||
|
@ -75,9 +74,8 @@ func TestSlashingPeriodCap(t *testing.T) {
|
||||||
valConsPubKey, valConsAddr := pks[0], pks[0].Address()
|
valConsPubKey, valConsAddr := pks[0], pks[0].Address()
|
||||||
got := stake.NewHandler(sk)(ctx, NewTestMsgCreateValidator(operatorAddr, valConsPubKey, amt))
|
got := stake.NewHandler(sk)(ctx, NewTestMsgCreateValidator(operatorAddr, valConsPubKey, amt))
|
||||||
require.True(t, got.IsOK())
|
require.True(t, got.IsOK())
|
||||||
validatorUpdates := stake.EndBlocker(ctx, sk)
|
stake.EndBlocker(ctx, sk)
|
||||||
ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1)
|
ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1)
|
||||||
keeper.AddValidators(ctx, validatorUpdates)
|
|
||||||
require.Equal(t, ck.GetCoins(ctx, sdk.AccAddress(operatorAddr)), sdk.Coins{{sk.GetParams(ctx).BondDenom, initCoins.Sub(amt)}})
|
require.Equal(t, ck.GetCoins(ctx, sdk.AccAddress(operatorAddr)), sdk.Coins{{sk.GetParams(ctx).BondDenom, initCoins.Sub(amt)}})
|
||||||
require.True(t, sdk.NewDecFromInt(amt).Equal(sk.Validator(ctx, operatorAddr).GetPower()))
|
require.True(t, sdk.NewDecFromInt(amt).Equal(sk.Validator(ctx, operatorAddr).GetPower()))
|
||||||
|
|
||||||
|
@ -141,8 +139,7 @@ func TestHandleAbsentValidator(t *testing.T) {
|
||||||
slh := NewHandler(keeper)
|
slh := NewHandler(keeper)
|
||||||
got := sh(ctx, NewTestMsgCreateValidator(addr, val, amt))
|
got := sh(ctx, NewTestMsgCreateValidator(addr, val, amt))
|
||||||
require.True(t, got.IsOK())
|
require.True(t, got.IsOK())
|
||||||
validatorUpdates := stake.EndBlocker(ctx, sk)
|
stake.EndBlocker(ctx, sk)
|
||||||
keeper.AddValidators(ctx, validatorUpdates)
|
|
||||||
require.Equal(t, ck.GetCoins(ctx, sdk.AccAddress(addr)), sdk.Coins{{sk.GetParams(ctx).BondDenom, initCoins.Sub(amt)}})
|
require.Equal(t, ck.GetCoins(ctx, sdk.AccAddress(addr)), sdk.Coins{{sk.GetParams(ctx).BondDenom, initCoins.Sub(amt)}})
|
||||||
require.True(t, sdk.NewDecFromInt(amt).Equal(sk.Validator(ctx, addr).GetPower()))
|
require.True(t, sdk.NewDecFromInt(amt).Equal(sk.Validator(ctx, addr).GetPower()))
|
||||||
// will exist since the validator has been bonded
|
// will exist since the validator has been bonded
|
||||||
|
@ -298,8 +295,7 @@ func TestHandleNewValidator(t *testing.T) {
|
||||||
// Validator created
|
// Validator created
|
||||||
got := sh(ctx, NewTestMsgCreateValidator(addr, val, sdk.NewInt(amt)))
|
got := sh(ctx, NewTestMsgCreateValidator(addr, val, sdk.NewInt(amt)))
|
||||||
require.True(t, got.IsOK())
|
require.True(t, got.IsOK())
|
||||||
validatorUpdates := stake.EndBlocker(ctx, sk)
|
stake.EndBlocker(ctx, sk)
|
||||||
keeper.AddValidators(ctx, validatorUpdates)
|
|
||||||
require.Equal(t, ck.GetCoins(ctx, sdk.AccAddress(addr)), sdk.Coins{{sk.GetParams(ctx).BondDenom, initCoins.SubRaw(amt)}})
|
require.Equal(t, ck.GetCoins(ctx, sdk.AccAddress(addr)), sdk.Coins{{sk.GetParams(ctx).BondDenom, initCoins.SubRaw(amt)}})
|
||||||
require.Equal(t, sdk.NewDec(amt), sk.Validator(ctx, addr).GetPower())
|
require.Equal(t, sdk.NewDec(amt), sk.Validator(ctx, addr).GetPower())
|
||||||
|
|
||||||
|
@ -333,8 +329,7 @@ func TestHandleAlreadyJailed(t *testing.T) {
|
||||||
sh := stake.NewHandler(sk)
|
sh := stake.NewHandler(sk)
|
||||||
got := sh(ctx, NewTestMsgCreateValidator(addr, val, amt))
|
got := sh(ctx, NewTestMsgCreateValidator(addr, val, amt))
|
||||||
require.True(t, got.IsOK())
|
require.True(t, got.IsOK())
|
||||||
validatorUpdates := stake.EndBlocker(ctx, sk)
|
stake.EndBlocker(ctx, sk)
|
||||||
keeper.AddValidators(ctx, validatorUpdates)
|
|
||||||
|
|
||||||
// 1000 first blocks OK
|
// 1000 first blocks OK
|
||||||
height := int64(0)
|
height := int64(0)
|
||||||
|
@ -386,8 +381,7 @@ func TestValidatorDippingInAndOut(t *testing.T) {
|
||||||
sh := stake.NewHandler(sk)
|
sh := stake.NewHandler(sk)
|
||||||
got := sh(ctx, NewTestMsgCreateValidator(addr, val, amt))
|
got := sh(ctx, NewTestMsgCreateValidator(addr, val, amt))
|
||||||
require.True(t, got.IsOK())
|
require.True(t, got.IsOK())
|
||||||
validatorUpdates := stake.EndBlocker(ctx, sk)
|
stake.EndBlocker(ctx, sk)
|
||||||
keeper.AddValidators(ctx, validatorUpdates)
|
|
||||||
|
|
||||||
// 100 first blocks OK
|
// 100 first blocks OK
|
||||||
height := int64(0)
|
height := int64(0)
|
||||||
|
@ -400,9 +394,8 @@ func TestValidatorDippingInAndOut(t *testing.T) {
|
||||||
newAmt := int64(101)
|
newAmt := int64(101)
|
||||||
got = sh(ctx, NewTestMsgCreateValidator(addrs[1], pks[1], sdk.NewInt(newAmt)))
|
got = sh(ctx, NewTestMsgCreateValidator(addrs[1], pks[1], sdk.NewInt(newAmt)))
|
||||||
require.True(t, got.IsOK())
|
require.True(t, got.IsOK())
|
||||||
validatorUpdates = stake.EndBlocker(ctx, sk)
|
validatorUpdates := stake.EndBlocker(ctx, sk)
|
||||||
require.Equal(t, 2, len(validatorUpdates))
|
require.Equal(t, 2, len(validatorUpdates))
|
||||||
keeper.AddValidators(ctx, validatorUpdates)
|
|
||||||
validator, _ := sk.GetValidator(ctx, addr)
|
validator, _ := sk.GetValidator(ctx, addr)
|
||||||
require.Equal(t, sdk.Unbonding, validator.Status)
|
require.Equal(t, sdk.Unbonding, validator.Status)
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,15 @@ func GetValidatorSigningInfoKey(v sdk.ConsAddress) []byte {
|
||||||
return append(ValidatorSigningInfoKey, v.Bytes()...)
|
return append(ValidatorSigningInfoKey, v.Bytes()...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// extract the address from a validator signing info key
|
||||||
|
func GetValidatorSigningInfoAddress(key []byte) (v sdk.ConsAddress) {
|
||||||
|
addr := key[1:]
|
||||||
|
if len(addr) != sdk.AddrLen {
|
||||||
|
panic("unexpected key length")
|
||||||
|
}
|
||||||
|
return sdk.ConsAddress(addr)
|
||||||
|
}
|
||||||
|
|
||||||
// stored by *Tendermint* address (not operator address)
|
// stored by *Tendermint* address (not operator address)
|
||||||
func GetValidatorMissedBlockBitArrayPrefixKey(v sdk.ConsAddress) []byte {
|
func GetValidatorMissedBlockBitArrayPrefixKey(v sdk.ConsAddress) []byte {
|
||||||
return append(ValidatorMissedBlockBitArrayKey, v.Bytes()...)
|
return append(ValidatorMissedBlockBitArrayKey, v.Bytes()...)
|
||||||
|
|
|
@ -20,6 +20,21 @@ func (k Keeper) getValidatorSigningInfo(ctx sdk.Context, address sdk.ConsAddress
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Stored by *validator* address (not operator address)
|
||||||
|
func (k Keeper) iterateValidatorSigningInfos(ctx sdk.Context, handler func(address sdk.ConsAddress, info ValidatorSigningInfo) (stop bool)) {
|
||||||
|
store := ctx.KVStore(k.storeKey)
|
||||||
|
iter := sdk.KVStorePrefixIterator(store, ValidatorSigningInfoKey)
|
||||||
|
defer iter.Close()
|
||||||
|
for ; iter.Valid(); iter.Next() {
|
||||||
|
address := GetValidatorSigningInfoAddress(iter.Key())
|
||||||
|
var info ValidatorSigningInfo
|
||||||
|
k.cdc.MustUnmarshalBinaryLengthPrefixed(iter.Value(), &info)
|
||||||
|
if handler(address, info) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Stored by *validator* address (not operator address)
|
// Stored by *validator* address (not operator address)
|
||||||
func (k Keeper) setValidatorSigningInfo(ctx sdk.Context, address sdk.ConsAddress, info ValidatorSigningInfo) {
|
func (k Keeper) setValidatorSigningInfo(ctx sdk.Context, address sdk.ConsAddress, info ValidatorSigningInfo) {
|
||||||
store := ctx.KVStore(k.storeKey)
|
store := ctx.KVStore(k.storeKey)
|
||||||
|
@ -40,6 +55,24 @@ func (k Keeper) getValidatorMissedBlockBitArray(ctx sdk.Context, address sdk.Con
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Stored by *validator* address (not operator address)
|
||||||
|
func (k Keeper) iterateValidatorMissedBlockBitArray(ctx sdk.Context, address sdk.ConsAddress, handler func(index int64, missed bool) (stop bool)) {
|
||||||
|
store := ctx.KVStore(k.storeKey)
|
||||||
|
index := int64(0)
|
||||||
|
// Array may be sparse
|
||||||
|
for ; index < k.SignedBlocksWindow(ctx); index++ {
|
||||||
|
var missed bool
|
||||||
|
bz := store.Get(GetValidatorMissedBlockBitArrayKey(address, index))
|
||||||
|
if bz == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
k.cdc.MustUnmarshalBinaryLengthPrefixed(bz, &missed)
|
||||||
|
if handler(index, missed) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Stored by *validator* address (not operator address)
|
// Stored by *validator* address (not operator address)
|
||||||
func (k Keeper) setValidatorMissedBlockBitArray(ctx sdk.Context, address sdk.ConsAddress, index int64, missed bool) {
|
func (k Keeper) setValidatorMissedBlockBitArray(ctx sdk.Context, address sdk.ConsAddress, index int64, missed bool) {
|
||||||
store := ctx.KVStore(k.storeKey)
|
store := ctx.KVStore(k.storeKey)
|
||||||
|
|
|
@ -51,6 +51,21 @@ func (k Keeper) getValidatorSlashingPeriodForHeight(ctx sdk.Context, address sdk
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Iterate over all slashing periods in the store, calling on each
|
||||||
|
// decode slashing period a provided handler function
|
||||||
|
// Stop if the provided handler function returns true
|
||||||
|
func (k Keeper) iterateValidatorSlashingPeriods(ctx sdk.Context, handler func(slashingPeriod ValidatorSlashingPeriod) (stop bool)) {
|
||||||
|
store := ctx.KVStore(k.storeKey)
|
||||||
|
iter := sdk.KVStorePrefixIterator(store, ValidatorSlashingPeriodKey)
|
||||||
|
defer iter.Close()
|
||||||
|
for ; iter.Valid(); iter.Next() {
|
||||||
|
slashingPeriod := k.unmarshalSlashingPeriodKeyValue(iter.Key(), iter.Value())
|
||||||
|
if handler(slashingPeriod) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Stored by validator Tendermint address (not operator address)
|
// Stored by validator Tendermint address (not operator address)
|
||||||
// This function sets a validator slashing period for a particular validator,
|
// This function sets a validator slashing period for a particular validator,
|
||||||
// start height, end height, and current slashed-so-far total, or updates
|
// start height, end height, and current slashed-so-far total, or updates
|
||||||
|
|
|
@ -91,7 +91,7 @@ func createTestInput(t *testing.T, defaults Params) (sdk.Context, bank.Keeper, s
|
||||||
sk.SetHooks(keeper.Hooks())
|
sk.SetHooks(keeper.Hooks())
|
||||||
|
|
||||||
require.NotPanics(t, func() {
|
require.NotPanics(t, func() {
|
||||||
InitGenesis(ctx, keeper, GenesisState{defaults}, genesis)
|
InitGenesis(ctx, keeper, GenesisState{defaults, nil, nil, nil}, genesis)
|
||||||
})
|
})
|
||||||
|
|
||||||
return ctx, ck, sk, paramstore, keeper
|
return ctx, ck, sk, paramstore, keeper
|
||||||
|
|
|
@ -19,8 +19,7 @@ func TestBeginBlocker(t *testing.T) {
|
||||||
// bond the validator
|
// bond the validator
|
||||||
got := stake.NewHandler(sk)(ctx, NewTestMsgCreateValidator(addr, pk, amt))
|
got := stake.NewHandler(sk)(ctx, NewTestMsgCreateValidator(addr, pk, amt))
|
||||||
require.True(t, got.IsOK())
|
require.True(t, got.IsOK())
|
||||||
validatorUpdates := stake.EndBlocker(ctx, sk)
|
stake.EndBlocker(ctx, sk)
|
||||||
keeper.AddValidators(ctx, validatorUpdates)
|
|
||||||
require.Equal(t, ck.GetCoins(ctx, sdk.AccAddress(addr)), sdk.Coins{{sk.GetParams(ctx).BondDenom, initCoins.Sub(amt)}})
|
require.Equal(t, ck.GetCoins(ctx, sdk.AccAddress(addr)), sdk.Coins{{sk.GetParams(ctx).BondDenom, initCoins.Sub(amt)}})
|
||||||
require.True(t, sdk.NewDecFromInt(amt).Equal(sk.Validator(ctx, addr).GetPower()))
|
require.True(t, sdk.NewDecFromInt(amt).Equal(sk.Validator(ctx, addr).GetPower()))
|
||||||
|
|
||||||
|
|
|
@ -2,13 +2,13 @@ package stake
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"sort"
|
||||||
|
|
||||||
abci "github.com/tendermint/tendermint/abci/types"
|
abci "github.com/tendermint/tendermint/abci/types"
|
||||||
tmtypes "github.com/tendermint/tendermint/types"
|
tmtypes "github.com/tendermint/tendermint/types"
|
||||||
|
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
"github.com/cosmos/cosmos-sdk/x/stake/types"
|
"github.com/cosmos/cosmos-sdk/x/stake/types"
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// InitGenesis sets the pool and parameters for the provided keeper and
|
// InitGenesis sets the pool and parameters for the provided keeper and
|
||||||
|
@ -26,22 +26,33 @@ func InitGenesis(ctx sdk.Context, keeper Keeper, data types.GenesisState) (res [
|
||||||
|
|
||||||
keeper.SetPool(ctx, data.Pool)
|
keeper.SetPool(ctx, data.Pool)
|
||||||
keeper.SetParams(ctx, data.Params)
|
keeper.SetParams(ctx, data.Params)
|
||||||
|
keeper.SetIntraTxCounter(ctx, data.IntraTxCounter)
|
||||||
|
keeper.SetLastTotalPower(ctx, data.LastTotalPower)
|
||||||
|
|
||||||
|
// We only need to set this if we're starting from a list of validators, not a state export
|
||||||
|
setBondIntraTxCounter := true
|
||||||
|
for _, validator := range data.Validators {
|
||||||
|
if validator.BondIntraTxCounter != 0 {
|
||||||
|
setBondIntraTxCounter = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for i, validator := range data.Validators {
|
for i, validator := range data.Validators {
|
||||||
validator.BondIntraTxCounter = int16(i) // set the intra-tx counter to the order the validators are presented
|
// set the intra-tx counter to the order the validators are presented, if necessary
|
||||||
|
if setBondIntraTxCounter {
|
||||||
|
validator.BondIntraTxCounter = int16(i)
|
||||||
|
}
|
||||||
keeper.SetValidator(ctx, validator)
|
keeper.SetValidator(ctx, validator)
|
||||||
|
|
||||||
if validator.Tokens.IsZero() {
|
|
||||||
return res, errors.Errorf("genesis validator cannot have zero pool shares, validator: %v", validator)
|
|
||||||
}
|
|
||||||
if validator.DelegatorShares.IsZero() {
|
|
||||||
return res, errors.Errorf("genesis validator cannot have zero delegator shares, validator: %v", validator)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Manually set indices for the first time
|
// Manually set indices for the first time
|
||||||
keeper.SetValidatorByConsAddr(ctx, validator)
|
keeper.SetValidatorByConsAddr(ctx, validator)
|
||||||
keeper.SetValidatorByPowerIndex(ctx, validator, data.Pool)
|
keeper.SetValidatorByPowerIndex(ctx, validator, data.Pool)
|
||||||
keeper.OnValidatorCreated(ctx, validator.OperatorAddr)
|
keeper.OnValidatorCreated(ctx, validator.OperatorAddr)
|
||||||
|
|
||||||
|
// Set timeslice if necessary
|
||||||
|
if validator.Status == sdk.Unbonding {
|
||||||
|
keeper.InsertValidatorQueue(ctx, validator)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, delegation := range data.Bonds {
|
for _, delegation := range data.Bonds {
|
||||||
|
@ -49,24 +60,56 @@ func InitGenesis(ctx sdk.Context, keeper Keeper, data types.GenesisState) (res [
|
||||||
keeper.OnDelegationCreated(ctx, delegation.DelegatorAddr, delegation.ValidatorAddr)
|
keeper.OnDelegationCreated(ctx, delegation.DelegatorAddr, delegation.ValidatorAddr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sort.SliceStable(data.UnbondingDelegations[:], func(i, j int) bool {
|
||||||
|
return data.UnbondingDelegations[i].CreationHeight < data.UnbondingDelegations[j].CreationHeight
|
||||||
|
})
|
||||||
|
for _, ubd := range data.UnbondingDelegations {
|
||||||
|
keeper.SetUnbondingDelegation(ctx, ubd)
|
||||||
|
keeper.InsertUnbondingQueue(ctx, ubd)
|
||||||
|
}
|
||||||
|
|
||||||
|
sort.SliceStable(data.Redelegations[:], func(i, j int) bool {
|
||||||
|
return data.Redelegations[i].CreationHeight < data.Redelegations[j].CreationHeight
|
||||||
|
})
|
||||||
|
for _, red := range data.Redelegations {
|
||||||
|
keeper.SetRedelegation(ctx, red)
|
||||||
|
keeper.InsertRedelegationQueue(ctx, red)
|
||||||
|
}
|
||||||
|
|
||||||
res = keeper.ApplyAndReturnValidatorSetUpdates(ctx)
|
res = keeper.ApplyAndReturnValidatorSetUpdates(ctx)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteGenesis returns a GenesisState for a given context and keeper. The
|
// ExportGenesis returns a GenesisState for a given context and keeper. The
|
||||||
// GenesisState will contain the pool, params, validators, and bonds found in
|
// GenesisState will contain the pool, params, validators, and bonds found in
|
||||||
// the keeper.
|
// the keeper.
|
||||||
func WriteGenesis(ctx sdk.Context, keeper Keeper) types.GenesisState {
|
func ExportGenesis(ctx sdk.Context, keeper Keeper) types.GenesisState {
|
||||||
pool := keeper.GetPool(ctx)
|
pool := keeper.GetPool(ctx)
|
||||||
params := keeper.GetParams(ctx)
|
params := keeper.GetParams(ctx)
|
||||||
|
intraTxCounter := keeper.GetIntraTxCounter(ctx)
|
||||||
|
lastTotalPower := keeper.GetLastTotalPower(ctx)
|
||||||
validators := keeper.GetAllValidators(ctx)
|
validators := keeper.GetAllValidators(ctx)
|
||||||
bonds := keeper.GetAllDelegations(ctx)
|
bonds := keeper.GetAllDelegations(ctx)
|
||||||
|
var unbondingDelegations []types.UnbondingDelegation
|
||||||
|
keeper.IterateUnbondingDelegations(ctx, func(_ int64, ubd types.UnbondingDelegation) (stop bool) {
|
||||||
|
unbondingDelegations = append(unbondingDelegations, ubd)
|
||||||
|
return false
|
||||||
|
})
|
||||||
|
var redelegations []types.Redelegation
|
||||||
|
keeper.IterateRedelegations(ctx, func(_ int64, red types.Redelegation) (stop bool) {
|
||||||
|
redelegations = append(redelegations, red)
|
||||||
|
return false
|
||||||
|
})
|
||||||
|
|
||||||
return types.GenesisState{
|
return types.GenesisState{
|
||||||
Pool: pool,
|
Pool: pool,
|
||||||
Params: params,
|
Params: params,
|
||||||
|
IntraTxCounter: intraTxCounter,
|
||||||
|
LastTotalPower: lastTotalPower,
|
||||||
Validators: validators,
|
Validators: validators,
|
||||||
Bonds: bonds,
|
Bonds: bonds,
|
||||||
|
UnbondingDelegations: unbondingDelegations,
|
||||||
|
Redelegations: redelegations,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,11 +161,8 @@ func validateGenesisStateValidators(validators []types.Validator) (err error) {
|
||||||
if val.Jailed && val.Status == sdk.Bonded {
|
if val.Jailed && val.Status == sdk.Bonded {
|
||||||
return fmt.Errorf("validator is bonded and jailed in genesis state: moniker %v, Address %v", val.Description.Moniker, val.ConsAddress())
|
return fmt.Errorf("validator is bonded and jailed in genesis state: moniker %v, Address %v", val.Description.Moniker, val.ConsAddress())
|
||||||
}
|
}
|
||||||
if val.Tokens.IsZero() {
|
if val.DelegatorShares.IsZero() && val.Status != sdk.Unbonding {
|
||||||
return fmt.Errorf("genesis validator cannot have zero pool shares, validator: %v", val)
|
return fmt.Errorf("bonded/unbonded genesis validator cannot have zero delegator shares, validator: %v", val)
|
||||||
}
|
|
||||||
if val.DelegatorShares.IsZero() {
|
|
||||||
return fmt.Errorf("genesis validator cannot have zero delegator shares, validator: %v", val)
|
|
||||||
}
|
}
|
||||||
addrMap[strKey] = true
|
addrMap[strKey] = true
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,29 +22,28 @@ func TestInitGenesis(t *testing.T) {
|
||||||
pool.BondedTokens = sdk.NewDec(2)
|
pool.BondedTokens = sdk.NewDec(2)
|
||||||
|
|
||||||
params := keeper.GetParams(ctx)
|
params := keeper.GetParams(ctx)
|
||||||
|
validators := make([]Validator, 2)
|
||||||
var delegations []Delegation
|
var delegations []Delegation
|
||||||
|
|
||||||
validators := []Validator{
|
|
||||||
NewValidator(sdk.ValAddress(keep.Addrs[0]), keep.PKs[0], Description{Moniker: "hoop"}),
|
|
||||||
NewValidator(sdk.ValAddress(keep.Addrs[1]), keep.PKs[1], Description{Moniker: "bloop"}),
|
|
||||||
}
|
|
||||||
genesisState := types.NewGenesisState(pool, params, validators, delegations)
|
|
||||||
_, err := InitGenesis(ctx, keeper, genesisState)
|
|
||||||
require.Error(t, err)
|
|
||||||
|
|
||||||
// initialize the validators
|
// initialize the validators
|
||||||
|
validators[0].OperatorAddr = sdk.ValAddress(keep.Addrs[0])
|
||||||
|
validators[0].ConsPubKey = keep.PKs[0]
|
||||||
|
validators[0].Description = Description{Moniker: "hoop"}
|
||||||
validators[0].Status = sdk.Bonded
|
validators[0].Status = sdk.Bonded
|
||||||
validators[0].Tokens = sdk.OneDec()
|
validators[0].Tokens = sdk.OneDec()
|
||||||
validators[0].DelegatorShares = sdk.OneDec()
|
validators[0].DelegatorShares = sdk.OneDec()
|
||||||
|
validators[1].OperatorAddr = sdk.ValAddress(keep.Addrs[1])
|
||||||
|
validators[1].ConsPubKey = keep.PKs[1]
|
||||||
|
validators[1].Description = Description{Moniker: "bloop"}
|
||||||
validators[1].Status = sdk.Bonded
|
validators[1].Status = sdk.Bonded
|
||||||
validators[1].Tokens = sdk.OneDec()
|
validators[1].Tokens = sdk.OneDec()
|
||||||
validators[1].DelegatorShares = sdk.OneDec()
|
validators[1].DelegatorShares = sdk.OneDec()
|
||||||
|
|
||||||
genesisState = types.NewGenesisState(pool, params, validators, delegations)
|
genesisState := types.NewGenesisState(pool, params, validators, delegations)
|
||||||
vals, err := InitGenesis(ctx, keeper, genesisState)
|
vals, err := InitGenesis(ctx, keeper, genesisState)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
actualGenesis := WriteGenesis(ctx, keeper)
|
actualGenesis := ExportGenesis(ctx, keeper)
|
||||||
require.Equal(t, genesisState.Pool, actualGenesis.Pool)
|
require.Equal(t, genesisState.Pool, actualGenesis.Pool)
|
||||||
require.Equal(t, genesisState.Params, actualGenesis.Params)
|
require.Equal(t, genesisState.Params, actualGenesis.Params)
|
||||||
require.Equal(t, genesisState.Bonds, actualGenesis.Bonds)
|
require.Equal(t, genesisState.Bonds, actualGenesis.Bonds)
|
||||||
|
@ -126,10 +125,6 @@ func TestValidateGenesis(t *testing.T) {
|
||||||
(*data).Validators = genValidators1
|
(*data).Validators = genValidators1
|
||||||
(*data).Validators = append((*data).Validators, genValidators1[0])
|
(*data).Validators = append((*data).Validators, genValidators1[0])
|
||||||
}, true},
|
}, true},
|
||||||
{"no pool shares", func(data *types.GenesisState) {
|
|
||||||
(*data).Validators = genValidators1
|
|
||||||
(*data).Validators[0].Tokens = sdk.ZeroDec()
|
|
||||||
}, true},
|
|
||||||
{"no delegator shares", func(data *types.GenesisState) {
|
{"no delegator shares", func(data *types.GenesisState) {
|
||||||
(*data).Validators = genValidators1
|
(*data).Validators = genValidators1
|
||||||
(*data).Validators[0].DelegatorShares = sdk.ZeroDec()
|
(*data).Validators[0].DelegatorShares = sdk.ZeroDec()
|
||||||
|
|
|
@ -283,6 +283,21 @@ func (k Keeper) SetRedelegation(ctx sdk.Context, red types.Redelegation) {
|
||||||
store.Set(GetREDByValDstIndexKey(red.DelegatorAddr, red.ValidatorSrcAddr, red.ValidatorDstAddr), []byte{})
|
store.Set(GetREDByValDstIndexKey(red.DelegatorAddr, red.ValidatorSrcAddr, red.ValidatorDstAddr), []byte{})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// iterate through all redelegations
|
||||||
|
func (k Keeper) IterateRedelegations(ctx sdk.Context, fn func(index int64, red types.Redelegation) (stop bool)) {
|
||||||
|
store := ctx.KVStore(k.storeKey)
|
||||||
|
iterator := sdk.KVStorePrefixIterator(store, RedelegationKey)
|
||||||
|
defer iterator.Close()
|
||||||
|
|
||||||
|
for i := int64(0); iterator.Valid(); iterator.Next() {
|
||||||
|
red := types.MustUnmarshalRED(k.cdc, iterator.Key(), iterator.Value())
|
||||||
|
if stop := fn(i, red); stop {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// remove a redelegation object and associated index
|
// remove a redelegation object and associated index
|
||||||
func (k Keeper) RemoveRedelegation(ctx sdk.Context, red types.Redelegation) {
|
func (k Keeper) RemoveRedelegation(ctx sdk.Context, red types.Redelegation) {
|
||||||
store := ctx.KVStore(k.storeKey)
|
store := ctx.KVStore(k.storeKey)
|
||||||
|
|
|
@ -17,9 +17,9 @@ func (k Keeper) OnValidatorModified(ctx sdk.Context, valAddr sdk.ValAddress) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (k Keeper) OnValidatorRemoved(ctx sdk.Context, valAddr sdk.ValAddress) {
|
func (k Keeper) OnValidatorRemoved(ctx sdk.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) {
|
||||||
if k.hooks != nil {
|
if k.hooks != nil {
|
||||||
k.hooks.OnValidatorRemoved(ctx, valAddr)
|
k.hooks.OnValidatorRemoved(ctx, consAddr, valAddr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -191,11 +191,13 @@ func (k Keeper) bondValidator(ctx sdk.Context, validator types.Validator) types.
|
||||||
validator, pool = validator.UpdateStatus(pool, sdk.Bonded)
|
validator, pool = validator.UpdateStatus(pool, sdk.Bonded)
|
||||||
k.SetPool(ctx, pool)
|
k.SetPool(ctx, pool)
|
||||||
|
|
||||||
// save the now bonded validator record to the three referenced stores
|
// save the now bonded validator record to the two referenced stores
|
||||||
k.SetValidator(ctx, validator)
|
k.SetValidator(ctx, validator)
|
||||||
|
|
||||||
k.SetValidatorByPowerIndex(ctx, validator, pool)
|
k.SetValidatorByPowerIndex(ctx, validator, pool)
|
||||||
|
|
||||||
|
// delete from queue if present
|
||||||
|
k.DeleteValidatorQueue(ctx, validator)
|
||||||
|
|
||||||
// call the bond hook if present
|
// call the bond hook if present
|
||||||
if k.hooks != nil {
|
if k.hooks != nil {
|
||||||
k.hooks.OnValidatorBonded(ctx, validator.ConsAddress(), validator.OperatorAddr)
|
k.hooks.OnValidatorBonded(ctx, validator.ConsAddress(), validator.OperatorAddr)
|
||||||
|
@ -224,9 +226,8 @@ func (k Keeper) beginUnbondingValidator(ctx sdk.Context, validator types.Validat
|
||||||
validator.UnbondingMinTime = ctx.BlockHeader().Time.Add(params.UnbondingTime)
|
validator.UnbondingMinTime = ctx.BlockHeader().Time.Add(params.UnbondingTime)
|
||||||
validator.UnbondingHeight = ctx.BlockHeader().Height
|
validator.UnbondingHeight = ctx.BlockHeader().Height
|
||||||
|
|
||||||
// save the now unbonded validator record
|
// save the now unbonded validator record and power index
|
||||||
k.SetValidator(ctx, validator)
|
k.SetValidator(ctx, validator)
|
||||||
|
|
||||||
k.SetValidatorByPowerIndex(ctx, validator, pool)
|
k.SetValidatorByPowerIndex(ctx, validator, pool)
|
||||||
|
|
||||||
// Adds to unbonding validator queue
|
// Adds to unbonding validator queue
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package keeper
|
package keeper
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"container/list"
|
"container/list"
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
@ -201,6 +202,11 @@ func (k Keeper) RemoveValidator(ctx sdk.Context, address sdk.ValAddress) {
|
||||||
store.Delete(GetValidatorByConsAddrKey(sdk.ConsAddress(validator.ConsPubKey.Address())))
|
store.Delete(GetValidatorByConsAddrKey(sdk.ConsAddress(validator.ConsPubKey.Address())))
|
||||||
store.Delete(GetValidatorsByPowerIndexKey(validator, pool))
|
store.Delete(GetValidatorsByPowerIndexKey(validator, pool))
|
||||||
|
|
||||||
|
// call hook if present
|
||||||
|
if k.hooks != nil {
|
||||||
|
k.hooks.OnValidatorRemoved(ctx, validator.ConsAddress(), validator.OperatorAddr)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//___________________________________________________________________________
|
//___________________________________________________________________________
|
||||||
|
@ -320,6 +326,12 @@ func (k Keeper) SetValidatorQueueTimeSlice(ctx sdk.Context, timestamp time.Time,
|
||||||
store.Set(GetValidatorQueueTimeKey(timestamp), bz)
|
store.Set(GetValidatorQueueTimeKey(timestamp), bz)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Deletes a specific validator queue timeslice.
|
||||||
|
func (k Keeper) DeleteValidatorQueueTimeSlice(ctx sdk.Context, timestamp time.Time) {
|
||||||
|
store := ctx.KVStore(k.storeKey)
|
||||||
|
store.Delete(GetValidatorQueueTimeKey(timestamp))
|
||||||
|
}
|
||||||
|
|
||||||
// Insert an validator address to the appropriate timeslice in the validator queue
|
// Insert an validator address to the appropriate timeslice in the validator queue
|
||||||
func (k Keeper) InsertValidatorQueue(ctx sdk.Context, val types.Validator) {
|
func (k Keeper) InsertValidatorQueue(ctx sdk.Context, val types.Validator) {
|
||||||
timeSlice := k.GetValidatorQueueTimeSlice(ctx, val.UnbondingMinTime)
|
timeSlice := k.GetValidatorQueueTimeSlice(ctx, val.UnbondingMinTime)
|
||||||
|
@ -331,6 +343,22 @@ func (k Keeper) InsertValidatorQueue(ctx sdk.Context, val types.Validator) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Delete a validator address from the validator queue
|
||||||
|
func (k Keeper) DeleteValidatorQueue(ctx sdk.Context, val types.Validator) {
|
||||||
|
timeSlice := k.GetValidatorQueueTimeSlice(ctx, val.UnbondingMinTime)
|
||||||
|
newTimeSlice := []sdk.ValAddress{}
|
||||||
|
for _, addr := range timeSlice {
|
||||||
|
if !bytes.Equal(addr, val.OperatorAddr) {
|
||||||
|
newTimeSlice = append(newTimeSlice, addr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(newTimeSlice) == 0 {
|
||||||
|
k.DeleteValidatorQueueTimeSlice(ctx, val.UnbondingMinTime)
|
||||||
|
} else {
|
||||||
|
k.SetValidatorQueueTimeSlice(ctx, val.UnbondingMinTime, newTimeSlice)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Returns all the validator queue timeslices from time 0 until endTime
|
// Returns all the validator queue timeslices from time 0 until endTime
|
||||||
func (k Keeper) ValidatorQueueIterator(ctx sdk.Context, endTime time.Time) sdk.Iterator {
|
func (k Keeper) ValidatorQueueIterator(ctx sdk.Context, endTime time.Time) sdk.Iterator {
|
||||||
store := ctx.KVStore(k.storeKey)
|
store := ctx.KVStore(k.storeKey)
|
||||||
|
@ -358,9 +386,12 @@ func (k Keeper) UnbondAllMatureValidatorQueue(ctx sdk.Context) {
|
||||||
k.cdc.MustUnmarshalBinaryLengthPrefixed(validatorTimesliceIterator.Value(), ×lice)
|
k.cdc.MustUnmarshalBinaryLengthPrefixed(validatorTimesliceIterator.Value(), ×lice)
|
||||||
for _, valAddr := range timeslice {
|
for _, valAddr := range timeslice {
|
||||||
val, found := k.GetValidator(ctx, valAddr)
|
val, found := k.GetValidator(ctx, valAddr)
|
||||||
if !found || val.GetStatus() != sdk.Unbonding {
|
if !found {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
if val.GetStatus() != sdk.Unbonding {
|
||||||
|
panic("unexpected validator in unbonding queue, status was not unbonding")
|
||||||
|
}
|
||||||
k.unbondingToUnbonded(ctx, val)
|
k.unbondingToUnbonded(ctx, val)
|
||||||
if val.GetDelegatorShares().IsZero() {
|
if val.GetDelegatorShares().IsZero() {
|
||||||
k.RemoveValidator(ctx, val.OperatorAddr)
|
k.RemoveValidator(ctx, val.OperatorAddr)
|
||||||
|
|
|
@ -57,6 +57,9 @@ var (
|
||||||
GetREDsToValDstIndexKey = keeper.GetREDsToValDstIndexKey
|
GetREDsToValDstIndexKey = keeper.GetREDsToValDstIndexKey
|
||||||
GetREDsByDelToValDstIndexKey = keeper.GetREDsByDelToValDstIndexKey
|
GetREDsByDelToValDstIndexKey = keeper.GetREDsByDelToValDstIndexKey
|
||||||
TestingUpdateValidator = keeper.TestingUpdateValidator
|
TestingUpdateValidator = keeper.TestingUpdateValidator
|
||||||
|
UnbondingQueueKey = keeper.UnbondingQueueKey
|
||||||
|
RedelegationQueueKey = keeper.RedelegationQueueKey
|
||||||
|
ValidatorQueueKey = keeper.ValidatorQueueKey
|
||||||
|
|
||||||
DefaultParamspace = keeper.DefaultParamspace
|
DefaultParamspace = keeper.DefaultParamspace
|
||||||
KeyUnbondingTime = types.KeyUnbondingTime
|
KeyUnbondingTime = types.KeyUnbondingTime
|
||||||
|
|
|
@ -1,11 +1,19 @@
|
||||||
package types
|
package types
|
||||||
|
|
||||||
|
import (
|
||||||
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
)
|
||||||
|
|
||||||
// GenesisState - all staking state that must be provided at genesis
|
// GenesisState - all staking state that must be provided at genesis
|
||||||
type GenesisState struct {
|
type GenesisState struct {
|
||||||
Pool Pool `json:"pool"`
|
Pool Pool `json:"pool"`
|
||||||
Params Params `json:"params"`
|
Params Params `json:"params"`
|
||||||
|
IntraTxCounter int16 `json:"intra_tx_counter"`
|
||||||
|
LastTotalPower sdk.Int `json:"last_total_power"`
|
||||||
Validators []Validator `json:"validators"`
|
Validators []Validator `json:"validators"`
|
||||||
Bonds []Delegation `json:"bonds"`
|
Bonds []Delegation `json:"bonds"`
|
||||||
|
UnbondingDelegations []UnbondingDelegation `json:"unbonding_delegations"`
|
||||||
|
Redelegations []Redelegation `json:"redelegations"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewGenesisState(pool Pool, params Params, validators []Validator, bonds []Delegation) GenesisState {
|
func NewGenesisState(pool Pool, params Params, validators []Validator, bonds []Delegation) GenesisState {
|
||||||
|
|
Loading…
Reference in New Issue