Merge PR #4686: v0.36 supply changes to genesis migration
This commit is contained in:
parent
257d3bfbf2
commit
a922dad346
@ -56,6 +56,16 @@ var (
|
||||
slashing.AppModuleBasic{},
|
||||
supply.AppModuleBasic{},
|
||||
)
|
||||
|
||||
// module account permissions
|
||||
maccPerms = map[string][]string{
|
||||
auth.FeeCollectorName: nil,
|
||||
distr.ModuleName: nil,
|
||||
mint.ModuleName: {supply.Minter},
|
||||
staking.BondedPoolName: {supply.Burner, supply.Staking},
|
||||
staking.NotBondedPoolName: {supply.Burner, supply.Staking},
|
||||
gov.ModuleName: {supply.Burner},
|
||||
}
|
||||
)
|
||||
|
||||
// custom tx codec
|
||||
@ -105,8 +115,10 @@ type SimApp struct {
|
||||
}
|
||||
|
||||
// NewSimApp returns a reference to an initialized SimApp.
|
||||
func NewSimApp(logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest bool,
|
||||
invCheckPeriod uint, baseAppOptions ...func(*bam.BaseApp)) *SimApp {
|
||||
func NewSimApp(
|
||||
logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest bool,
|
||||
invCheckPeriod uint, baseAppOptions ...func(*bam.BaseApp),
|
||||
) *SimApp {
|
||||
|
||||
cdc := MakeCodec()
|
||||
|
||||
@ -114,7 +126,7 @@ func NewSimApp(logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest bo
|
||||
bApp.SetCommitMultiStoreTracer(traceStore)
|
||||
bApp.SetAppVersion(version.Version)
|
||||
|
||||
var app = &SimApp{
|
||||
app := &SimApp{
|
||||
BaseApp: bApp,
|
||||
cdc: cdc,
|
||||
invCheckPeriod: invCheckPeriod,
|
||||
@ -143,16 +155,6 @@ func NewSimApp(logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest bo
|
||||
govSubspace := app.paramsKeeper.Subspace(gov.DefaultParamspace)
|
||||
crisisSubspace := app.paramsKeeper.Subspace(crisis.DefaultParamspace)
|
||||
|
||||
// account permissions
|
||||
maccPerms := map[string][]string{
|
||||
auth.FeeCollectorName: nil,
|
||||
distr.ModuleName: nil,
|
||||
mint.ModuleName: []string{supply.Minter},
|
||||
staking.BondedPoolName: []string{supply.Burner, supply.Staking},
|
||||
staking.NotBondedPoolName: []string{supply.Burner, supply.Staking},
|
||||
gov.ModuleName: []string{supply.Burner},
|
||||
}
|
||||
|
||||
// add keepers
|
||||
app.accountKeeper = auth.NewAccountKeeper(app.cdc, app.keyAccount, authSubspace, auth.ProtoBaseAccount)
|
||||
app.bankKeeper = bank.NewBaseKeeper(app.accountKeeper, bankSubspace, bank.DefaultCodespace)
|
||||
@ -202,9 +204,9 @@ func NewSimApp(logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest bo
|
||||
|
||||
// genutils must occur after staking so that pools are properly
|
||||
// initialized with tokens from genesis accounts.
|
||||
app.mm.SetOrderInitGenesis(genaccounts.ModuleName, supply.ModuleName, distr.ModuleName,
|
||||
app.mm.SetOrderInitGenesis(genaccounts.ModuleName, distr.ModuleName,
|
||||
staking.ModuleName, auth.ModuleName, bank.ModuleName, slashing.ModuleName,
|
||||
gov.ModuleName, mint.ModuleName, crisis.ModuleName, genutil.ModuleName)
|
||||
gov.ModuleName, mint.ModuleName, supply.ModuleName, crisis.ModuleName, genutil.ModuleName)
|
||||
|
||||
app.mm.RegisterInvariants(&app.crisisKeeper)
|
||||
app.mm.RegisterRoutes(app.Router(), app.QueryRouter())
|
||||
@ -250,3 +252,13 @@ func (app *SimApp) InitChainer(ctx sdk.Context, req abci.RequestInitChain) abci.
|
||||
func (app *SimApp) LoadHeight(height int64) error {
|
||||
return app.LoadVersion(height, app.keyMain)
|
||||
}
|
||||
|
||||
// ModuleAccountAddrs returns all the app's module account addresses.
|
||||
func (app *SimApp) ModuleAccountAddrs() map[string]bool {
|
||||
modAccAddrs := make(map[string]bool)
|
||||
for acc := range maccPerms {
|
||||
modAccAddrs[app.supplyKeeper.GetModuleAddress(acc).String()] = true
|
||||
}
|
||||
|
||||
return modAccAddrs
|
||||
}
|
||||
|
||||
@ -48,10 +48,11 @@ func init() {
|
||||
// helper function for populating input for SimulateFromSeed
|
||||
func getSimulateFromSeedInput(tb testing.TB, w io.Writer, app *SimApp) (
|
||||
testing.TB, io.Writer, *baseapp.BaseApp, simulation.AppStateFn, int64,
|
||||
simulation.WeightedOperations, sdk.Invariants, int, int, bool, bool, bool, bool) {
|
||||
simulation.WeightedOperations, sdk.Invariants, int, int, bool, bool, bool, bool, map[string]bool) {
|
||||
|
||||
return tb, w, app.BaseApp, appStateFn, seed,
|
||||
testAndRunTxs(app), invariants(app), numBlocks, blockSize, commit, lean, onOperation, allInvariants
|
||||
testAndRunTxs(app), invariants(app), numBlocks, blockSize, commit,
|
||||
lean, onOperation, allInvariants, app.ModuleAccountAddrs()
|
||||
}
|
||||
|
||||
func appStateFn(
|
||||
@ -604,6 +605,7 @@ func TestAppStateDeterminism(t *testing.T) {
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
app.ModuleAccountAddrs(),
|
||||
)
|
||||
appHash := app.LastCommitID().Hash
|
||||
appHashList[j] = appHash
|
||||
@ -630,6 +632,7 @@ func BenchmarkInvariants(b *testing.B) {
|
||||
_, err := simulation.SimulateFromSeed(
|
||||
b, ioutil.Discard, app.BaseApp, appStateFn, seed, testAndRunTxs(app),
|
||||
[]sdk.Invariant{}, numBlocks, blockSize, commit, lean, onOperation, false,
|
||||
app.ModuleAccountAddrs(),
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
|
||||
26
x/auth/legacy/v0_34/types.go
Normal file
26
x/auth/legacy/v0_34/types.go
Normal file
@ -0,0 +1,26 @@
|
||||
// DONTCOVER
|
||||
// nolint
|
||||
package v0_34
|
||||
|
||||
import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
const (
|
||||
ModuleName = "auth"
|
||||
)
|
||||
|
||||
type (
|
||||
Params struct {
|
||||
MaxMemoCharacters uint64 `json:"max_memo_characters"`
|
||||
TxSigLimit uint64 `json:"tx_sig_limit"`
|
||||
TxSizeCostPerByte uint64 `json:"tx_size_cost_per_byte"`
|
||||
SigVerifyCostED25519 uint64 `json:"sig_verify_cost_ed25519"`
|
||||
SigVerifyCostSecp256k1 uint64 `json:"sig_verify_cost_secp256k1"`
|
||||
}
|
||||
|
||||
GenesisState struct {
|
||||
CollectedFees sdk.Coins `json:"collected_fees"`
|
||||
Params Params `json:"params"`
|
||||
}
|
||||
)
|
||||
14
x/auth/legacy/v0_36/migrate.go
Normal file
14
x/auth/legacy/v0_36/migrate.go
Normal file
@ -0,0 +1,14 @@
|
||||
// DONTCOVER
|
||||
// nolint
|
||||
package v0_36
|
||||
|
||||
import (
|
||||
v034auth "github.com/cosmos/cosmos-sdk/x/auth/legacy/v0_34"
|
||||
)
|
||||
|
||||
// Migrate accepts exported genesis state from v0.34 and migrates it to v0.36
|
||||
// genesis state. This migration removes the CollectedFees coins from the old
|
||||
// FeeCollectorKeeper.
|
||||
func Migrate(oldGenState v034auth.GenesisState) GenesisState {
|
||||
return NewGenesisState(oldGenState.Params)
|
||||
}
|
||||
25
x/auth/legacy/v0_36/migrate_test.go
Normal file
25
x/auth/legacy/v0_36/migrate_test.go
Normal file
@ -0,0 +1,25 @@
|
||||
package v0_36
|
||||
|
||||
import (
|
||||
"github.com/cosmos/cosmos-sdk/types"
|
||||
v034auth "github.com/cosmos/cosmos-sdk/x/auth/legacy/v0_34"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestMigrate(t *testing.T) {
|
||||
var genesisState GenesisState
|
||||
require.NotPanics(t, func() {
|
||||
genesisState = Migrate(v034auth.GenesisState{
|
||||
CollectedFees: types.Coins{
|
||||
{
|
||||
Amount: types.NewInt(10),
|
||||
Denom: "stake",
|
||||
},
|
||||
},
|
||||
Params: v034auth.Params{}, // forwarded structure: filling and checking will be testing a no-op
|
||||
})
|
||||
})
|
||||
require.Equal(t, genesisState, GenesisState{Params: v034auth.Params{}})
|
||||
}
|
||||
19
x/auth/legacy/v0_36/types.go
Normal file
19
x/auth/legacy/v0_36/types.go
Normal file
@ -0,0 +1,19 @@
|
||||
// DONTCOVER
|
||||
// nolint
|
||||
package v0_36
|
||||
|
||||
import v034auth "github.com/cosmos/cosmos-sdk/x/auth/legacy/v0_34"
|
||||
|
||||
const (
|
||||
ModuleName = "auth"
|
||||
)
|
||||
|
||||
type (
|
||||
GenesisState struct {
|
||||
Params v034auth.Params `json:"params"`
|
||||
}
|
||||
)
|
||||
|
||||
func NewGenesisState(params v034auth.Params) GenesisState {
|
||||
return GenesisState{params}
|
||||
}
|
||||
@ -12,7 +12,7 @@ const (
|
||||
StoreKey = "acc"
|
||||
|
||||
// FeeCollectorName the root string for the fee collector account address
|
||||
FeeCollectorName = "FeeCollector"
|
||||
FeeCollectorName = "fee_collector"
|
||||
|
||||
// QuerierRoute is the querier route for acc
|
||||
QuerierRoute = StoreKey
|
||||
|
||||
@ -157,19 +157,9 @@ func (k Keeper) withdrawDelegationRewards(ctx sdk.Context, val exported.Validato
|
||||
val.GetOperator(), del.GetDelegatorAddr(), rewardsRaw, rewards))
|
||||
}
|
||||
|
||||
// decrement reference count of starting period
|
||||
startingInfo := k.GetDelegatorStartingInfo(ctx, del.GetValidatorAddr(), del.GetDelegatorAddr())
|
||||
startingPeriod := startingInfo.PreviousPeriod
|
||||
k.decrementReferenceCount(ctx, del.GetValidatorAddr(), startingPeriod)
|
||||
|
||||
// truncate coins, return remainder to community pool
|
||||
coins, remainder := rewards.TruncateDecimal()
|
||||
|
||||
k.SetValidatorOutstandingRewards(ctx, del.GetValidatorAddr(), outstanding.Sub(rewards))
|
||||
feePool := k.GetFeePool(ctx)
|
||||
feePool.CommunityPool = feePool.CommunityPool.Add(remainder)
|
||||
k.SetFeePool(ctx, feePool)
|
||||
|
||||
// add coins to user account
|
||||
if !coins.IsZero() {
|
||||
withdrawAddr := k.GetDelegatorWithdrawAddr(ctx, del.GetDelegatorAddr())
|
||||
@ -179,6 +169,18 @@ func (k Keeper) withdrawDelegationRewards(ctx sdk.Context, val exported.Validato
|
||||
}
|
||||
}
|
||||
|
||||
// update the outstanding rewards and the community pool only if the
|
||||
// transaction was successful
|
||||
k.SetValidatorOutstandingRewards(ctx, del.GetValidatorAddr(), outstanding.Sub(rewards))
|
||||
feePool := k.GetFeePool(ctx)
|
||||
feePool.CommunityPool = feePool.CommunityPool.Add(remainder)
|
||||
k.SetFeePool(ctx, feePool)
|
||||
|
||||
// decrement reference count of starting period
|
||||
startingInfo := k.GetDelegatorStartingInfo(ctx, del.GetValidatorAddr(), del.GetDelegatorAddr())
|
||||
startingPeriod := startingInfo.PreviousPeriod
|
||||
k.decrementReferenceCount(ctx, del.GetValidatorAddr(), startingPeriod)
|
||||
|
||||
// remove delegator starting info
|
||||
k.DeleteDelegatorStartingInfo(ctx, del.GetValidatorAddr(), del.GetDelegatorAddr())
|
||||
|
||||
|
||||
@ -8,68 +8,6 @@ import (
|
||||
// genesis state. All entries are identical except for validator slashing events
|
||||
// which now include the period.
|
||||
func Migrate(oldGenState v034distr.GenesisState) GenesisState {
|
||||
feePool := FeePool{CommunityPool: oldGenState.FeePool.CommunityPool}
|
||||
|
||||
dwifos := make([]DelegatorWithdrawInfo, len(oldGenState.DelegatorWithdrawInfos))
|
||||
for i, info := range oldGenState.DelegatorWithdrawInfos {
|
||||
dwifos[i] = DelegatorWithdrawInfo{
|
||||
DelegatorAddress: info.DelegatorAddress,
|
||||
WithdrawAddress: info.WithdrawAddress,
|
||||
}
|
||||
}
|
||||
|
||||
outRewards := make([]ValidatorOutstandingRewardsRecord, len(oldGenState.OutstandingRewards))
|
||||
for i, rew := range oldGenState.OutstandingRewards {
|
||||
outRewards[i] = ValidatorOutstandingRewardsRecord{
|
||||
ValidatorAddress: rew.ValidatorAddress,
|
||||
OutstandingRewards: rew.OutstandingRewards,
|
||||
}
|
||||
}
|
||||
|
||||
accumComm := make([]ValidatorAccumulatedCommissionRecord, len(oldGenState.ValidatorAccumulatedCommissions))
|
||||
for i, comm := range oldGenState.ValidatorAccumulatedCommissions {
|
||||
accumComm[i] = ValidatorAccumulatedCommissionRecord{
|
||||
ValidatorAddress: comm.ValidatorAddress,
|
||||
Accumulated: comm.Accumulated,
|
||||
}
|
||||
}
|
||||
|
||||
histRewards := make([]ValidatorHistoricalRewardsRecord, len(oldGenState.ValidatorHistoricalRewards))
|
||||
for i, rew := range oldGenState.ValidatorHistoricalRewards {
|
||||
histRewards[i] = ValidatorHistoricalRewardsRecord{
|
||||
ValidatorAddress: rew.ValidatorAddress,
|
||||
Period: rew.Period,
|
||||
Rewards: ValidatorHistoricalRewards{
|
||||
CumulativeRewardRatio: rew.Rewards.CumulativeRewardRatio,
|
||||
ReferenceCount: rew.Rewards.ReferenceCount,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
currRewards := make([]ValidatorCurrentRewardsRecord, len(oldGenState.ValidatorCurrentRewards))
|
||||
for i, rew := range oldGenState.ValidatorCurrentRewards {
|
||||
currRewards[i] = ValidatorCurrentRewardsRecord{
|
||||
ValidatorAddress: rew.ValidatorAddress,
|
||||
Rewards: ValidatorCurrentRewards{
|
||||
Rewards: rew.Rewards.Rewards,
|
||||
Period: rew.Rewards.Period,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
delStartingInfos := make([]DelegatorStartingInfoRecord, len(oldGenState.DelegatorStartingInfos))
|
||||
for i, delInfo := range oldGenState.DelegatorStartingInfos {
|
||||
delStartingInfos[i] = DelegatorStartingInfoRecord{
|
||||
DelegatorAddress: delInfo.DelegatorAddress,
|
||||
ValidatorAddress: delInfo.ValidatorAddress,
|
||||
StartingInfo: DelegatorStartingInfo{
|
||||
PreviousPeriod: delInfo.StartingInfo.PreviousPeriod,
|
||||
Stake: delInfo.StartingInfo.Stake,
|
||||
Height: delInfo.StartingInfo.Height,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// migrate slash events which now have the period included
|
||||
slashEvents := make([]ValidatorSlashEventRecord, len(oldGenState.ValidatorSlashEvents))
|
||||
for i, se := range oldGenState.ValidatorSlashEvents {
|
||||
@ -77,17 +15,16 @@ func Migrate(oldGenState v034distr.GenesisState) GenesisState {
|
||||
ValidatorAddress: se.ValidatorAddress,
|
||||
Height: se.Height,
|
||||
Period: se.Event.ValidatorPeriod,
|
||||
Event: ValidatorSlashEvent{
|
||||
ValidatorPeriod: se.Event.ValidatorPeriod,
|
||||
Fraction: se.Event.Fraction,
|
||||
},
|
||||
Event: se.Event,
|
||||
}
|
||||
}
|
||||
|
||||
return NewGenesisState(
|
||||
feePool, oldGenState.CommunityTax, oldGenState.BaseProposerReward,
|
||||
oldGenState.FeePool, oldGenState.CommunityTax, oldGenState.BaseProposerReward,
|
||||
oldGenState.BonusProposerReward, oldGenState.WithdrawAddrEnabled,
|
||||
dwifos, oldGenState.PreviousProposer, outRewards, accumComm,
|
||||
histRewards, currRewards, delStartingInfos, slashEvents,
|
||||
oldGenState.DelegatorWithdrawInfos, oldGenState.PreviousProposer,
|
||||
oldGenState.OutstandingRewards, oldGenState.ValidatorAccumulatedCommissions,
|
||||
oldGenState.ValidatorHistoricalRewards, oldGenState.ValidatorCurrentRewards,
|
||||
oldGenState.DelegatorStartingInfos, slashEvents,
|
||||
)
|
||||
}
|
||||
|
||||
63
x/distribution/legacy/v0_36/migrate_test.go
Normal file
63
x/distribution/legacy/v0_36/migrate_test.go
Normal file
@ -0,0 +1,63 @@
|
||||
package v0_36
|
||||
|
||||
import (
|
||||
"github.com/cosmos/cosmos-sdk/types"
|
||||
v034distr "github.com/cosmos/cosmos-sdk/x/distribution/legacy/v0_34"
|
||||
"github.com/tendermint/tendermint/crypto/secp256k1"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
var (
|
||||
priv = secp256k1.GenPrivKey()
|
||||
addr = types.AccAddress(priv.PubKey().Address())
|
||||
valAddr, _ = types.ValAddressFromBech32(addr.String())
|
||||
|
||||
event = v034distr.ValidatorSlashEvent{
|
||||
ValidatorPeriod: 1,
|
||||
Fraction: types.Dec{},
|
||||
}
|
||||
)
|
||||
|
||||
func TestMigrate(t *testing.T) {
|
||||
var genesisState GenesisState
|
||||
require.NotPanics(t, func() {
|
||||
genesisState = Migrate(v034distr.GenesisState{
|
||||
ValidatorSlashEvents: []v034distr.ValidatorSlashEventRecord{
|
||||
{
|
||||
ValidatorAddress: valAddr,
|
||||
Height: 1,
|
||||
Event: event,
|
||||
},
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
require.Equal(t, genesisState.ValidatorSlashEvents[0], ValidatorSlashEventRecord{
|
||||
ValidatorAddress: valAddr,
|
||||
Height: 1,
|
||||
Period: event.ValidatorPeriod,
|
||||
Event: event,
|
||||
})
|
||||
}
|
||||
|
||||
func TestMigrateEmptyRecord(t *testing.T) {
|
||||
var genesisState GenesisState
|
||||
|
||||
require.NotPanics(t, func() {
|
||||
genesisState = Migrate(v034distr.GenesisState{
|
||||
ValidatorSlashEvents: []v034distr.ValidatorSlashEventRecord{{}},
|
||||
})
|
||||
})
|
||||
|
||||
require.Equal(t, genesisState.ValidatorSlashEvents[0], ValidatorSlashEventRecord{
|
||||
ValidatorAddress: valAddr,
|
||||
Height: 0,
|
||||
Period: 0,
|
||||
Event: v034distr.ValidatorSlashEvent{
|
||||
ValidatorPeriod: 0,
|
||||
Fraction: types.Dec{},
|
||||
},
|
||||
})
|
||||
}
|
||||
@ -4,6 +4,7 @@ package v0_36
|
||||
|
||||
import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
v034distr "github.com/cosmos/cosmos-sdk/x/distribution/legacy/v0_34"
|
||||
)
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -17,93 +18,36 @@ const (
|
||||
type (
|
||||
ValidatorAccumulatedCommission = sdk.DecCoins
|
||||
|
||||
ValidatorCurrentRewards struct {
|
||||
Rewards sdk.DecCoins `json:"rewards"`
|
||||
Period uint64 `json:"period"`
|
||||
}
|
||||
|
||||
ValidatorHistoricalRewards struct {
|
||||
CumulativeRewardRatio sdk.DecCoins `json:"cumulative_reward_ratio"`
|
||||
ReferenceCount uint16 `json:"reference_count"`
|
||||
}
|
||||
|
||||
DelegatorWithdrawInfo struct {
|
||||
DelegatorAddress sdk.AccAddress `json:"delegator_address"`
|
||||
WithdrawAddress sdk.AccAddress `json:"withdraw_address"`
|
||||
}
|
||||
|
||||
ValidatorOutstandingRewardsRecord struct {
|
||||
ValidatorAddress sdk.ValAddress `json:"validator_address"`
|
||||
OutstandingRewards sdk.DecCoins `json:"outstanding_rewards"`
|
||||
}
|
||||
|
||||
ValidatorAccumulatedCommissionRecord struct {
|
||||
ValidatorAddress sdk.ValAddress `json:"validator_address"`
|
||||
Accumulated ValidatorAccumulatedCommission `json:"accumulated"`
|
||||
}
|
||||
|
||||
ValidatorHistoricalRewardsRecord struct {
|
||||
ValidatorAddress sdk.ValAddress `json:"validator_address"`
|
||||
Period uint64 `json:"period"`
|
||||
Rewards ValidatorHistoricalRewards `json:"rewards"`
|
||||
}
|
||||
|
||||
ValidatorCurrentRewardsRecord struct {
|
||||
ValidatorAddress sdk.ValAddress `json:"validator_address"`
|
||||
Rewards ValidatorCurrentRewards `json:"rewards"`
|
||||
}
|
||||
|
||||
DelegatorStartingInfo struct {
|
||||
PreviousPeriod uint64 `json:"previous_period"`
|
||||
Stake sdk.Dec `json:"stake"`
|
||||
Height uint64 `json:"creation_height"`
|
||||
}
|
||||
|
||||
DelegatorStartingInfoRecord struct {
|
||||
DelegatorAddress sdk.AccAddress `json:"delegator_address"`
|
||||
ValidatorAddress sdk.ValAddress `json:"validator_address"`
|
||||
StartingInfo DelegatorStartingInfo `json:"starting_info"`
|
||||
}
|
||||
|
||||
ValidatorSlashEvent struct {
|
||||
ValidatorPeriod uint64 `json:"validator_period"`
|
||||
Fraction sdk.Dec `json:"fraction"`
|
||||
}
|
||||
|
||||
ValidatorSlashEventRecord struct {
|
||||
ValidatorAddress sdk.ValAddress `json:"validator_address"`
|
||||
Height uint64 `json:"height"`
|
||||
Period uint64 `json:"period"`
|
||||
Event ValidatorSlashEvent `json:"validator_slash_event"`
|
||||
}
|
||||
|
||||
FeePool struct {
|
||||
CommunityPool sdk.DecCoins `json:"community_pool"`
|
||||
ValidatorAddress sdk.ValAddress `json:"validator_address"`
|
||||
Height uint64 `json:"height"`
|
||||
Period uint64 `json:"period"`
|
||||
Event v034distr.ValidatorSlashEvent `json:"validator_slash_event"`
|
||||
}
|
||||
|
||||
GenesisState struct {
|
||||
FeePool FeePool `json:"fee_pool"`
|
||||
CommunityTax sdk.Dec `json:"community_tax"`
|
||||
BaseProposerReward sdk.Dec `json:"base_proposer_reward"`
|
||||
BonusProposerReward sdk.Dec `json:"bonus_proposer_reward"`
|
||||
WithdrawAddrEnabled bool `json:"withdraw_addr_enabled"`
|
||||
DelegatorWithdrawInfos []DelegatorWithdrawInfo `json:"delegator_withdraw_infos"`
|
||||
PreviousProposer sdk.ConsAddress `json:"previous_proposer"`
|
||||
OutstandingRewards []ValidatorOutstandingRewardsRecord `json:"outstanding_rewards"`
|
||||
ValidatorAccumulatedCommissions []ValidatorAccumulatedCommissionRecord `json:"validator_accumulated_commissions"`
|
||||
ValidatorHistoricalRewards []ValidatorHistoricalRewardsRecord `json:"validator_historical_rewards"`
|
||||
ValidatorCurrentRewards []ValidatorCurrentRewardsRecord `json:"validator_current_rewards"`
|
||||
DelegatorStartingInfos []DelegatorStartingInfoRecord `json:"delegator_starting_infos"`
|
||||
ValidatorSlashEvents []ValidatorSlashEventRecord `json:"validator_slash_events"`
|
||||
FeePool v034distr.FeePool `json:"fee_pool"`
|
||||
CommunityTax sdk.Dec `json:"community_tax"`
|
||||
BaseProposerReward sdk.Dec `json:"base_proposer_reward"`
|
||||
BonusProposerReward sdk.Dec `json:"bonus_proposer_reward"`
|
||||
WithdrawAddrEnabled bool `json:"withdraw_addr_enabled"`
|
||||
DelegatorWithdrawInfos []v034distr.DelegatorWithdrawInfo `json:"delegator_withdraw_infos"`
|
||||
PreviousProposer sdk.ConsAddress `json:"previous_proposer"`
|
||||
OutstandingRewards []v034distr.ValidatorOutstandingRewardsRecord `json:"outstanding_rewards"`
|
||||
ValidatorAccumulatedCommissions []v034distr.ValidatorAccumulatedCommissionRecord `json:"validator_accumulated_commissions"`
|
||||
ValidatorHistoricalRewards []v034distr.ValidatorHistoricalRewardsRecord `json:"validator_historical_rewards"`
|
||||
ValidatorCurrentRewards []v034distr.ValidatorCurrentRewardsRecord `json:"validator_current_rewards"`
|
||||
DelegatorStartingInfos []v034distr.DelegatorStartingInfoRecord `json:"delegator_starting_infos"`
|
||||
ValidatorSlashEvents []ValidatorSlashEventRecord `json:"validator_slash_events"`
|
||||
}
|
||||
)
|
||||
|
||||
func NewGenesisState(
|
||||
feePool FeePool, communityTax, baseProposerReward, bonusProposerReward sdk.Dec,
|
||||
withdrawAddrEnabled bool, dwis []DelegatorWithdrawInfo, pp sdk.ConsAddress,
|
||||
r []ValidatorOutstandingRewardsRecord, acc []ValidatorAccumulatedCommissionRecord,
|
||||
historical []ValidatorHistoricalRewardsRecord, cur []ValidatorCurrentRewardsRecord,
|
||||
dels []DelegatorStartingInfoRecord, slashes []ValidatorSlashEventRecord,
|
||||
feePool v034distr.FeePool, communityTax, baseProposerReward, bonusProposerReward sdk.Dec,
|
||||
withdrawAddrEnabled bool, dwis []v034distr.DelegatorWithdrawInfo, pp sdk.ConsAddress,
|
||||
r []v034distr.ValidatorOutstandingRewardsRecord, acc []v034distr.ValidatorAccumulatedCommissionRecord,
|
||||
historical []v034distr.ValidatorHistoricalRewardsRecord, cur []v034distr.ValidatorCurrentRewardsRecord,
|
||||
dels []v034distr.DelegatorStartingInfoRecord, slashes []ValidatorSlashEventRecord,
|
||||
) GenesisState {
|
||||
|
||||
return GenesisState{
|
||||
|
||||
28
x/genaccounts/legacy/v0_34/types.go
Normal file
28
x/genaccounts/legacy/v0_34/types.go
Normal file
@ -0,0 +1,28 @@
|
||||
// DONTCOVER
|
||||
// nolint
|
||||
package v0_34
|
||||
|
||||
import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
const (
|
||||
ModuleName = "accounts"
|
||||
)
|
||||
|
||||
type (
|
||||
GenesisAccount struct {
|
||||
Address sdk.AccAddress `json:"address"`
|
||||
Coins sdk.Coins `json:"coins"`
|
||||
Sequence uint64 `json:"sequence_number"`
|
||||
AccountNumber uint64 `json:"account_number"`
|
||||
|
||||
OriginalVesting sdk.Coins `json:"original_vesting"`
|
||||
DelegatedFree sdk.Coins `json:"delegated_free"`
|
||||
DelegatedVesting sdk.Coins `json:"delegated_vesting"`
|
||||
StartTime int64 `json:"start_time"`
|
||||
EndTime int64 `json:"end_time"`
|
||||
}
|
||||
|
||||
GenesisState []GenesisAccount
|
||||
)
|
||||
179
x/genaccounts/legacy/v0_36/migrate.go
Normal file
179
x/genaccounts/legacy/v0_36/migrate.go
Normal file
@ -0,0 +1,179 @@
|
||||
// DONTCOVER
|
||||
// nolint
|
||||
package v0_36
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
v034distr "github.com/cosmos/cosmos-sdk/x/distribution/legacy/v0_34"
|
||||
v034accounts "github.com/cosmos/cosmos-sdk/x/genaccounts/legacy/v0_34"
|
||||
v034gov "github.com/cosmos/cosmos-sdk/x/gov/legacy/v0_34"
|
||||
v034staking "github.com/cosmos/cosmos-sdk/x/staking/legacy/v0_34"
|
||||
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
)
|
||||
|
||||
const (
|
||||
notBondedPoolName = "not_bonded_tokens_pool"
|
||||
bondedPoolName = "bonded_tokens_pool"
|
||||
feeCollectorName = "fee_collector"
|
||||
mintModuleName = "mint"
|
||||
|
||||
basic = "basic"
|
||||
minter = "minter"
|
||||
burner = "burner"
|
||||
staking = "staking"
|
||||
)
|
||||
|
||||
// Migrate accepts exported genesis state from v0.34 and migrates it to v0.36
|
||||
// genesis state. It deletes the governance base accounts and creates the new module accounts.
|
||||
// The remaining accounts are updated to the new GenesisAccount type from 0.36
|
||||
func Migrate(
|
||||
oldGenState v034accounts.GenesisState, fees sdk.Coins, communityPool sdk.DecCoins,
|
||||
deposits []v034gov.DepositWithMetadata, vals v034staking.Validators, ubds []v034staking.UnbondingDelegation,
|
||||
valOutRewards []v034distr.ValidatorOutstandingRewardsRecord, bondDenom, distrModuleName, govModuleName string,
|
||||
) GenesisState {
|
||||
|
||||
depositedCoinsAccAddr := sdk.AccAddress(crypto.AddressHash([]byte("govDepositedCoins")))
|
||||
burnedDepositCoinsAccAddr := sdk.AccAddress(crypto.AddressHash([]byte("govBurnedDepositCoins")))
|
||||
|
||||
bondedAmt := sdk.ZeroInt()
|
||||
notBondedAmt := sdk.ZeroInt()
|
||||
|
||||
// remove the two previous governance base accounts for deposits and burned
|
||||
// coins from rejected proposals add six new module accounts:
|
||||
// distribution, gov, mint, fee collector, bonded and not bonded pool
|
||||
var (
|
||||
newGenState GenesisState
|
||||
govCoins sdk.Coins
|
||||
extraAccounts = 6
|
||||
)
|
||||
|
||||
for _, acc := range oldGenState {
|
||||
switch {
|
||||
case acc.Address.Equals(depositedCoinsAccAddr):
|
||||
// remove gov deposits base account
|
||||
govCoins = acc.Coins
|
||||
extraAccounts -= 1
|
||||
|
||||
case acc.Address.Equals(burnedDepositCoinsAccAddr):
|
||||
// remove gov burned deposits base account
|
||||
extraAccounts -= 1
|
||||
|
||||
default:
|
||||
newGenState = append(
|
||||
newGenState,
|
||||
NewGenesisAccount(
|
||||
acc.Address, acc.Coins, acc.Sequence,
|
||||
acc.OriginalVesting, acc.DelegatedFree, acc.DelegatedVesting,
|
||||
acc.StartTime, acc.EndTime, "", []string{},
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
var expDeposits sdk.Coins
|
||||
for _, deposit := range deposits {
|
||||
expDeposits = expDeposits.Add(deposit.Deposit.Amount)
|
||||
}
|
||||
|
||||
if !expDeposits.IsEqual(govCoins) {
|
||||
panic(
|
||||
fmt.Sprintf(
|
||||
"pre migration deposit base account coins ≠ stored deposits coins (%s ≠ %s)",
|
||||
expDeposits.String(), govCoins.String(),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
// get staking module accounts coins
|
||||
for _, validator := range vals {
|
||||
switch validator.Status {
|
||||
case sdk.Bonded:
|
||||
bondedAmt = bondedAmt.Add(validator.Tokens)
|
||||
|
||||
case sdk.Unbonding, sdk.Unbonded:
|
||||
notBondedAmt = notBondedAmt.Add(validator.Tokens)
|
||||
|
||||
default:
|
||||
panic("invalid validator status")
|
||||
}
|
||||
}
|
||||
|
||||
for _, ubd := range ubds {
|
||||
for _, entry := range ubd.Entries {
|
||||
notBondedAmt = notBondedAmt.Add(entry.Balance)
|
||||
}
|
||||
}
|
||||
|
||||
bondedCoins := sdk.NewCoins(sdk.NewCoin(bondDenom, bondedAmt))
|
||||
notBondedCoins := sdk.NewCoins(sdk.NewCoin(bondDenom, notBondedAmt))
|
||||
|
||||
// get distr module account coins
|
||||
var distrDecCoins sdk.DecCoins
|
||||
for _, reward := range valOutRewards {
|
||||
distrDecCoins = distrDecCoins.Add(reward.OutstandingRewards)
|
||||
}
|
||||
|
||||
distrCoins, _ := distrDecCoins.Add(communityPool).TruncateDecimal()
|
||||
|
||||
// get module account addresses
|
||||
feeCollectorAddr := sdk.AccAddress(crypto.AddressHash([]byte(feeCollectorName)))
|
||||
govAddr := sdk.AccAddress(crypto.AddressHash([]byte(govModuleName)))
|
||||
bondedAddr := sdk.AccAddress(crypto.AddressHash([]byte(bondedPoolName)))
|
||||
notBondedAddr := sdk.AccAddress(crypto.AddressHash([]byte(notBondedPoolName)))
|
||||
distrAddr := sdk.AccAddress(crypto.AddressHash([]byte(distrModuleName)))
|
||||
mintAddr := sdk.AccAddress(crypto.AddressHash([]byte(mintModuleName)))
|
||||
|
||||
// create module genesis accounts
|
||||
feeCollectorModuleAcc := NewGenesisAccount(
|
||||
feeCollectorAddr, fees, 0,
|
||||
sdk.Coins{}, sdk.Coins{}, sdk.Coins{},
|
||||
0, 0, feeCollectorName, []string{basic},
|
||||
)
|
||||
govModuleAcc := NewGenesisAccount(
|
||||
govAddr, govCoins, 0,
|
||||
sdk.Coins{}, sdk.Coins{}, sdk.Coins{},
|
||||
0, 0, govModuleName, []string{burner},
|
||||
)
|
||||
distrModuleAcc := NewGenesisAccount(
|
||||
distrAddr, distrCoins, 0,
|
||||
sdk.Coins{}, sdk.Coins{}, sdk.Coins{},
|
||||
0, 0, distrModuleName, []string{basic},
|
||||
)
|
||||
bondedModuleAcc := NewGenesisAccount(
|
||||
bondedAddr, bondedCoins, 0,
|
||||
sdk.Coins{}, sdk.Coins{}, sdk.Coins{},
|
||||
0, 0, bondedPoolName, []string{burner, staking},
|
||||
)
|
||||
notBondedModuleAcc := NewGenesisAccount(
|
||||
notBondedAddr, notBondedCoins, 0,
|
||||
sdk.Coins{}, sdk.Coins{}, sdk.Coins{},
|
||||
0, 0, notBondedPoolName, []string{burner, staking},
|
||||
)
|
||||
mintModuleAcc := NewGenesisAccount(
|
||||
mintAddr, sdk.Coins{}, 0,
|
||||
sdk.Coins{}, sdk.Coins{}, sdk.Coins{},
|
||||
0, 0, mintModuleName, []string{minter},
|
||||
)
|
||||
|
||||
newGenState = append(
|
||||
newGenState,
|
||||
[]GenesisAccount{
|
||||
feeCollectorModuleAcc, govModuleAcc, distrModuleAcc,
|
||||
bondedModuleAcc, notBondedModuleAcc, mintModuleAcc,
|
||||
}...,
|
||||
)
|
||||
|
||||
// verify the total number of accounts is correct
|
||||
if len(newGenState) != len(oldGenState)+extraAccounts {
|
||||
panic(
|
||||
fmt.Sprintf(
|
||||
"invalid total number of genesis accounts; got: %d, expected: %d",
|
||||
len(newGenState), len(oldGenState)+extraAccounts),
|
||||
)
|
||||
}
|
||||
|
||||
return newGenState
|
||||
}
|
||||
123
x/genaccounts/legacy/v0_36/migrate_test.go
Normal file
123
x/genaccounts/legacy/v0_36/migrate_test.go
Normal file
@ -0,0 +1,123 @@
|
||||
package v0_36
|
||||
|
||||
import (
|
||||
"github.com/cosmos/cosmos-sdk/types"
|
||||
v034distr "github.com/cosmos/cosmos-sdk/x/distribution/legacy/v0_34"
|
||||
v034accounts "github.com/cosmos/cosmos-sdk/x/genaccounts/legacy/v0_34"
|
||||
v034gov "github.com/cosmos/cosmos-sdk/x/gov/legacy/v0_34"
|
||||
v034staking "github.com/cosmos/cosmos-sdk/x/staking/legacy/v0_34"
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
"github.com/tendermint/tendermint/crypto/secp256k1"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
var (
|
||||
priv = secp256k1.GenPrivKey()
|
||||
addr = types.AccAddress(priv.PubKey().Address())
|
||||
depositedCoinsAccAddr = types.AccAddress(crypto.AddressHash([]byte("govDepositedCoins")))
|
||||
burnedDepositCoinsAccAddr = types.AccAddress(crypto.AddressHash([]byte("govBurnedDepositCoins")))
|
||||
|
||||
coins = types.Coins{types.NewInt64Coin(types.DefaultBondDenom, 10)}
|
||||
halfCoins = types.Coins{types.NewInt64Coin(types.DefaultBondDenom, 5)}
|
||||
|
||||
accountDeposited = v034accounts.GenesisAccount{
|
||||
Address: depositedCoinsAccAddr,
|
||||
Coins: coins,
|
||||
Sequence: 1,
|
||||
AccountNumber: 1,
|
||||
|
||||
OriginalVesting: coins,
|
||||
DelegatedFree: coins,
|
||||
DelegatedVesting: coins,
|
||||
StartTime: 0,
|
||||
EndTime: 0,
|
||||
}
|
||||
|
||||
accountBurned = v034accounts.GenesisAccount{
|
||||
Address: burnedDepositCoinsAccAddr,
|
||||
Coins: coins,
|
||||
Sequence: 2,
|
||||
AccountNumber: 2,
|
||||
|
||||
OriginalVesting: coins,
|
||||
DelegatedFree: coins,
|
||||
DelegatedVesting: coins,
|
||||
StartTime: 0,
|
||||
EndTime: 0,
|
||||
}
|
||||
|
||||
deposit = v034gov.DepositWithMetadata{
|
||||
ProposalID: 1,
|
||||
Deposit: v034gov.Deposit{
|
||||
ProposalID: 1,
|
||||
Depositor: addr,
|
||||
Amount: coins,
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
func TestMigrateEmptyRecord(t *testing.T) {
|
||||
|
||||
type args struct {
|
||||
accounts v034accounts.GenesisState
|
||||
deposits []v034gov.DepositWithMetadata
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
}{
|
||||
{"No Accounts", args{v034accounts.GenesisState{}, []v034gov.DepositWithMetadata{}}},
|
||||
{"Deposited account", args{v034accounts.GenesisState{accountDeposited}, []v034gov.DepositWithMetadata{deposit}}},
|
||||
{"Burned account", args{v034accounts.GenesisState{accountBurned}, []v034gov.DepositWithMetadata{}}},
|
||||
{"Burned and deposited accounts", args{v034accounts.GenesisState{accountDeposited, accountBurned}, []v034gov.DepositWithMetadata{deposit}}},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
require.NotPanics(t, func() {
|
||||
Migrate(
|
||||
tt.args.accounts,
|
||||
types.Coins{},
|
||||
types.DecCoins{},
|
||||
tt.args.deposits,
|
||||
v034staking.Validators{},
|
||||
[]v034staking.UnbondingDelegation{},
|
||||
[]v034distr.ValidatorOutstandingRewardsRecord{},
|
||||
types.DefaultBondDenom,
|
||||
v034distr.ModuleName,
|
||||
v034gov.ModuleName,
|
||||
)
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestMigrateWrongDeposit(t *testing.T) {
|
||||
require.Panics(t, func() {
|
||||
Migrate(
|
||||
v034accounts.GenesisState{
|
||||
accountDeposited,
|
||||
accountBurned,
|
||||
},
|
||||
types.Coins{},
|
||||
types.DecCoins{},
|
||||
[]v034gov.DepositWithMetadata{
|
||||
{
|
||||
ProposalID: 1,
|
||||
Deposit: v034gov.Deposit{
|
||||
ProposalID: 1,
|
||||
Depositor: addr,
|
||||
Amount: halfCoins,
|
||||
},
|
||||
},
|
||||
},
|
||||
v034staking.Validators{},
|
||||
[]v034staking.UnbondingDelegation{},
|
||||
[]v034distr.ValidatorOutstandingRewardsRecord{},
|
||||
types.DefaultBondDenom,
|
||||
v034distr.ModuleName,
|
||||
v034gov.ModuleName,
|
||||
)
|
||||
})
|
||||
}
|
||||
53
x/genaccounts/legacy/v0_36/types.go
Normal file
53
x/genaccounts/legacy/v0_36/types.go
Normal file
@ -0,0 +1,53 @@
|
||||
// DONTCOVER
|
||||
// nolint
|
||||
package v0_36
|
||||
|
||||
import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
const (
|
||||
ModuleName = "accounts"
|
||||
)
|
||||
|
||||
type (
|
||||
GenesisAccount struct {
|
||||
Address sdk.AccAddress `json:"address" yaml:"address"`
|
||||
Coins sdk.Coins `json:"coins" yaml:"coins"`
|
||||
Sequence uint64 `json:"sequence_number" yaml:"sequence_number"`
|
||||
AccountNumber uint64 `json:"account_number" yaml:"account_number"`
|
||||
|
||||
OriginalVesting sdk.Coins `json:"original_vesting" yaml:"original_vesting"`
|
||||
DelegatedFree sdk.Coins `json:"delegated_free" yaml:"delegated_free"`
|
||||
DelegatedVesting sdk.Coins `json:"delegated_vesting" yaml:"delegated_vesting"`
|
||||
StartTime int64 `json:"start_time" yaml:"start_time"`
|
||||
EndTime int64 `json:"end_time" yaml:"end_time"`
|
||||
|
||||
ModuleName string `json:"module_name" yaml:"module_name"`
|
||||
ModulePermissions []string `json:"module_permissions" yaml:"module_permissions"`
|
||||
}
|
||||
|
||||
GenesisState []GenesisAccount
|
||||
)
|
||||
|
||||
// NewGenesisAccount creates a new GenesisAccount object
|
||||
func NewGenesisAccount(
|
||||
address sdk.AccAddress, coins sdk.Coins, sequence uint64,
|
||||
vestingAmount, delFree, delVesting sdk.Coins, vestingStartTime, vestingEndTime int64,
|
||||
module string, permissions []string,
|
||||
) GenesisAccount {
|
||||
|
||||
return GenesisAccount{
|
||||
Address: address,
|
||||
Coins: coins,
|
||||
Sequence: sequence,
|
||||
AccountNumber: 0, // ignored set by the account keeper during InitGenesis
|
||||
OriginalVesting: vestingAmount,
|
||||
DelegatedFree: delFree,
|
||||
DelegatedVesting: delVesting,
|
||||
StartTime: vestingStartTime,
|
||||
EndTime: vestingEndTime,
|
||||
ModuleName: module,
|
||||
ModulePermissions: permissions,
|
||||
}
|
||||
}
|
||||
@ -2,11 +2,18 @@ package v036
|
||||
|
||||
import (
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
v034auth "github.com/cosmos/cosmos-sdk/x/auth/legacy/v0_34"
|
||||
v036auth "github.com/cosmos/cosmos-sdk/x/auth/legacy/v0_36"
|
||||
v034distr "github.com/cosmos/cosmos-sdk/x/distribution/legacy/v0_34"
|
||||
v036distr "github.com/cosmos/cosmos-sdk/x/distribution/legacy/v0_36"
|
||||
v034genAccounts "github.com/cosmos/cosmos-sdk/x/genaccounts/legacy/v0_34"
|
||||
v036genAccounts "github.com/cosmos/cosmos-sdk/x/genaccounts/legacy/v0_36"
|
||||
"github.com/cosmos/cosmos-sdk/x/genutil"
|
||||
v034gov "github.com/cosmos/cosmos-sdk/x/gov/legacy/v034"
|
||||
v036gov "github.com/cosmos/cosmos-sdk/x/gov/legacy/v036"
|
||||
v034gov "github.com/cosmos/cosmos-sdk/x/gov/legacy/v0_34"
|
||||
v036gov "github.com/cosmos/cosmos-sdk/x/gov/legacy/v0_36"
|
||||
v034staking "github.com/cosmos/cosmos-sdk/x/staking/legacy/v0_34"
|
||||
v036staking "github.com/cosmos/cosmos-sdk/x/staking/legacy/v0_36"
|
||||
v036supply "github.com/cosmos/cosmos-sdk/x/supply/legacy/v0_36"
|
||||
)
|
||||
|
||||
// Migrate migrates exported state from v0.34 to a v0.36 genesis state.
|
||||
@ -16,17 +23,52 @@ func Migrate(appState genutil.AppMap) genutil.AppMap {
|
||||
|
||||
v036Codec := codec.New()
|
||||
codec.RegisterCrypto(v036Codec)
|
||||
v034gov.RegisterCodec(v034Codec)
|
||||
v036gov.RegisterCodec(v036Codec)
|
||||
|
||||
// migrate genesis state
|
||||
// migrate genesis accounts state
|
||||
if appState[v034genAccounts.ModuleName] != nil {
|
||||
var genAccs v034genAccounts.GenesisState
|
||||
v034Codec.MustUnmarshalJSON(appState[v034genAccounts.ModuleName], &genAccs)
|
||||
|
||||
var authGenState v034auth.GenesisState
|
||||
v034Codec.MustUnmarshalJSON(appState[v034auth.ModuleName], &authGenState)
|
||||
|
||||
var govGenState v034gov.GenesisState
|
||||
v034Codec.MustUnmarshalJSON(appState[v034gov.ModuleName], &govGenState)
|
||||
|
||||
var distrGenState v034distr.GenesisState
|
||||
v034Codec.MustUnmarshalJSON(appState[v034distr.ModuleName], &distrGenState)
|
||||
|
||||
var stakingGenState v034staking.GenesisState
|
||||
v034Codec.MustUnmarshalJSON(appState[v034staking.ModuleName], &stakingGenState)
|
||||
|
||||
delete(appState, v034genAccounts.ModuleName) // delete old key in case the name changed
|
||||
appState[v036genAccounts.ModuleName] = v036Codec.MustMarshalJSON(
|
||||
v036genAccounts.Migrate(
|
||||
genAccs, authGenState.CollectedFees, distrGenState.FeePool.CommunityPool, govGenState.Deposits,
|
||||
stakingGenState.Validators, stakingGenState.UnbondingDelegations, distrGenState.OutstandingRewards,
|
||||
stakingGenState.Params.BondDenom, v036distr.ModuleName, v036gov.ModuleName,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
// migrate auth state
|
||||
if appState[v034auth.ModuleName] != nil {
|
||||
var authGenState v034auth.GenesisState
|
||||
v034Codec.MustUnmarshalJSON(appState[v034auth.ModuleName], &authGenState)
|
||||
|
||||
delete(appState, v034auth.ModuleName) // delete old key in case the name changed
|
||||
appState[v036auth.ModuleName] = v036Codec.MustMarshalJSON(v036auth.Migrate(authGenState))
|
||||
}
|
||||
|
||||
// migrate gov state
|
||||
if appState[v034gov.ModuleName] != nil {
|
||||
v034gov.RegisterCodec(v034Codec)
|
||||
v036gov.RegisterCodec(v036Codec)
|
||||
|
||||
var govState v034gov.GenesisState
|
||||
v034Codec.MustUnmarshalJSON(appState[v034gov.ModuleName], &govState)
|
||||
var govGenState v034gov.GenesisState
|
||||
v034Codec.MustUnmarshalJSON(appState[v034gov.ModuleName], &govGenState)
|
||||
|
||||
delete(appState, v034gov.ModuleName) // delete old key in case the name changed
|
||||
appState[v036gov.ModuleName] = v036Codec.MustMarshalJSON(v036gov.MigrateGovernance(govState))
|
||||
appState[v036gov.ModuleName] = v036Codec.MustMarshalJSON(v036gov.Migrate(govGenState))
|
||||
}
|
||||
|
||||
// migrate distribution state
|
||||
@ -38,5 +80,16 @@ func Migrate(appState genutil.AppMap) genutil.AppMap {
|
||||
appState[v036distr.ModuleName] = v036Codec.MustMarshalJSON(v036distr.Migrate(slashingGenState))
|
||||
}
|
||||
|
||||
// migrate staking state
|
||||
if appState[v034staking.ModuleName] != nil {
|
||||
var stakingGenState v034staking.GenesisState
|
||||
v034Codec.MustUnmarshalJSON(appState[v034staking.ModuleName], &stakingGenState)
|
||||
|
||||
delete(appState, v034staking.ModuleName) // delete old key in case the name changed
|
||||
appState[v036staking.ModuleName] = v036Codec.MustMarshalJSON(v036staking.Migrate(stakingGenState))
|
||||
}
|
||||
|
||||
appState[v036supply.ModuleName] = v036Codec.MustMarshalJSON(v036supply.EmptyGenesisState())
|
||||
|
||||
return appState
|
||||
}
|
||||
|
||||
@ -1,513 +0,0 @@
|
||||
package v034
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
// Keys
|
||||
const (
|
||||
// ModuleName is the name of the module
|
||||
ModuleName = "gov"
|
||||
|
||||
// StoreKey is the store key string for gov
|
||||
StoreKey = ModuleName
|
||||
|
||||
// RouterKey is the message route for gov
|
||||
RouterKey = ModuleName
|
||||
|
||||
// QuerierRoute is the querier route for gov
|
||||
QuerierRoute = ModuleName
|
||||
|
||||
// DefaultParamspace default name for parameter store
|
||||
DefaultParamspace = ModuleName
|
||||
)
|
||||
|
||||
type GenesisState struct {
|
||||
StartingProposalID uint64 `json:"starting_proposal_id"`
|
||||
Deposits []DepositWithMetadata `json:"deposits"`
|
||||
Votes []VoteWithMetadata `json:"votes"`
|
||||
Proposals []Proposal `json:"proposals"`
|
||||
DepositParams DepositParams `json:"deposit_params"`
|
||||
VotingParams VotingParams `json:"voting_params"`
|
||||
TallyParams TallyParams `json:"tally_params"`
|
||||
}
|
||||
|
||||
type DepositWithMetadata struct {
|
||||
ProposalID uint64 `json:"proposal_id"`
|
||||
Deposit Deposit `json:"deposit"`
|
||||
}
|
||||
|
||||
type VoteWithMetadata struct {
|
||||
ProposalID uint64 `json:"proposal_id"`
|
||||
Vote Vote `json:"vote"`
|
||||
}
|
||||
|
||||
type Deposit struct {
|
||||
ProposalID uint64 `json:"proposal_id"` // proposalID of the proposal
|
||||
Depositor sdk.AccAddress `json:"depositor"` // Address of the depositor
|
||||
Amount sdk.Coins `json:"amount"` // Deposit amount
|
||||
}
|
||||
|
||||
type Deposits []Deposit
|
||||
|
||||
type Vote struct {
|
||||
ProposalID uint64 `json:"proposal_id"` // proposalID of the proposal
|
||||
Voter sdk.AccAddress `json:"voter"` // address of the voter
|
||||
Option VoteOption `json:"option"` // option from OptionSet chosen by the voter
|
||||
}
|
||||
|
||||
type Votes []Vote
|
||||
|
||||
// Param around deposits for governance
|
||||
type DepositParams struct {
|
||||
MinDeposit sdk.Coins `json:"min_deposit,omitempty"` // Minimum deposit for a proposal to enter voting period.
|
||||
MaxDepositPeriod time.Duration `json:"max_deposit_period,omitempty"` // Maximum period for Atom holders to deposit on a proposal. Initial value: 2 months
|
||||
}
|
||||
|
||||
type TallyParams struct {
|
||||
Quorum sdk.Dec `json:"quorum,omitempty"` // Minimum percentage of total stake needed to vote for a result to be considered valid
|
||||
Threshold sdk.Dec `json:"threshold,omitempty"` // Minimum proportion of Yes votes for proposal to pass. Initial value: 0.5
|
||||
Veto sdk.Dec `json:"veto,omitempty"` // Minimum value of Veto votes to Total votes ratio for proposal to be vetoed. Initial value: 1/3
|
||||
}
|
||||
|
||||
type VotingParams struct {
|
||||
VotingPeriod time.Duration `json:"voting_period,omitempty"` // Length of the voting period.
|
||||
}
|
||||
|
||||
type TallyResult struct {
|
||||
Yes sdk.Int `json:"yes"`
|
||||
Abstain sdk.Int `json:"abstain"`
|
||||
No sdk.Int `json:"no"`
|
||||
NoWithVeto sdk.Int `json:"no_with_veto"`
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// ProposalStatus
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// ProposalStatus is a type alias that represents a proposal status as a byte
|
||||
type ProposalStatus byte
|
||||
|
||||
//nolint
|
||||
const (
|
||||
StatusNil ProposalStatus = 0x00
|
||||
StatusDepositPeriod ProposalStatus = 0x01
|
||||
StatusVotingPeriod ProposalStatus = 0x02
|
||||
StatusPassed ProposalStatus = 0x03
|
||||
StatusRejected ProposalStatus = 0x04
|
||||
StatusFailed ProposalStatus = 0x05
|
||||
)
|
||||
|
||||
// ProposalStatusToString turns a string into a ProposalStatus
|
||||
func ProposalStatusFromString(str string) (ProposalStatus, error) {
|
||||
switch str {
|
||||
case "DepositPeriod":
|
||||
return StatusDepositPeriod, nil
|
||||
|
||||
case "VotingPeriod":
|
||||
return StatusVotingPeriod, nil
|
||||
|
||||
case "Passed":
|
||||
return StatusPassed, nil
|
||||
|
||||
case "Rejected":
|
||||
return StatusRejected, nil
|
||||
|
||||
case "Failed":
|
||||
return StatusFailed, nil
|
||||
|
||||
case "":
|
||||
return StatusNil, nil
|
||||
|
||||
default:
|
||||
return ProposalStatus(0xff), fmt.Errorf("'%s' is not a valid proposal status", str)
|
||||
}
|
||||
}
|
||||
|
||||
// Marshal needed for protobuf compatibility
|
||||
func (status ProposalStatus) Marshal() ([]byte, error) {
|
||||
return []byte{byte(status)}, nil
|
||||
}
|
||||
|
||||
// Unmarshal needed for protobuf compatibility
|
||||
func (status *ProposalStatus) Unmarshal(data []byte) error {
|
||||
*status = ProposalStatus(data[0])
|
||||
return nil
|
||||
}
|
||||
|
||||
// Marshals to JSON using string
|
||||
func (status ProposalStatus) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(status.String())
|
||||
}
|
||||
|
||||
// Unmarshals from JSON assuming Bech32 encoding
|
||||
func (status *ProposalStatus) UnmarshalJSON(data []byte) error {
|
||||
var s string
|
||||
err := json.Unmarshal(data, &s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
bz2, err := ProposalStatusFromString(s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*status = bz2
|
||||
return nil
|
||||
}
|
||||
|
||||
// String implements the Stringer interface.
|
||||
func (status ProposalStatus) String() string {
|
||||
switch status {
|
||||
case StatusDepositPeriod:
|
||||
return "DepositPeriod"
|
||||
|
||||
case StatusVotingPeriod:
|
||||
return "VotingPeriod"
|
||||
|
||||
case StatusPassed:
|
||||
return "Passed"
|
||||
|
||||
case StatusRejected:
|
||||
return "Rejected"
|
||||
|
||||
case StatusFailed:
|
||||
return "Failed"
|
||||
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
// Format implements the fmt.Formatter interface.
|
||||
// nolint: errcheck
|
||||
func (status ProposalStatus) Format(s fmt.State, verb rune) {
|
||||
switch verb {
|
||||
case 's':
|
||||
s.Write([]byte(status.String()))
|
||||
default:
|
||||
// TODO: Do this conversion more directly
|
||||
s.Write([]byte(fmt.Sprintf("%v", byte(status))))
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// VoteOption
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
type VoteOption byte
|
||||
|
||||
// Vote options
|
||||
const (
|
||||
OptionEmpty VoteOption = 0x00
|
||||
OptionYes VoteOption = 0x01
|
||||
OptionAbstain VoteOption = 0x02
|
||||
OptionNo VoteOption = 0x03
|
||||
OptionNoWithVeto VoteOption = 0x04
|
||||
)
|
||||
|
||||
// VoteOptionFromString returns a VoteOption from a string. It returns an error
|
||||
// if the string is invalid.
|
||||
func VoteOptionFromString(str string) (VoteOption, error) {
|
||||
switch str {
|
||||
case "Yes":
|
||||
return OptionYes, nil
|
||||
|
||||
case "Abstain":
|
||||
return OptionAbstain, nil
|
||||
|
||||
case "No":
|
||||
return OptionNo, nil
|
||||
|
||||
case "NoWithVeto":
|
||||
return OptionNoWithVeto, nil
|
||||
|
||||
default:
|
||||
return VoteOption(0xff), fmt.Errorf("'%s' is not a valid vote option", str)
|
||||
}
|
||||
}
|
||||
|
||||
// Marshal needed for protobuf compatibility.
|
||||
func (vo VoteOption) Marshal() ([]byte, error) {
|
||||
return []byte{byte(vo)}, nil
|
||||
}
|
||||
|
||||
// Unmarshal needed for protobuf compatibility.
|
||||
func (vo *VoteOption) Unmarshal(data []byte) error {
|
||||
*vo = VoteOption(data[0])
|
||||
return nil
|
||||
}
|
||||
|
||||
// Marshals to JSON using string.
|
||||
func (vo VoteOption) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(vo.String())
|
||||
}
|
||||
|
||||
// UnmarshalJSON decodes from JSON assuming Bech32 encoding.
|
||||
func (vo *VoteOption) UnmarshalJSON(data []byte) error {
|
||||
var s string
|
||||
err := json.Unmarshal(data, &s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
bz2, err := VoteOptionFromString(s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*vo = bz2
|
||||
return nil
|
||||
}
|
||||
|
||||
// String implements the Stringer interface.
|
||||
func (vo VoteOption) String() string {
|
||||
switch vo {
|
||||
case OptionYes:
|
||||
return "Yes"
|
||||
case OptionAbstain:
|
||||
return "Abstain"
|
||||
case OptionNo:
|
||||
return "No"
|
||||
case OptionNoWithVeto:
|
||||
return "NoWithVeto"
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
// Format implements the fmt.Formatter interface.
|
||||
// nolint: errcheck
|
||||
func (vo VoteOption) Format(s fmt.State, verb rune) {
|
||||
switch verb {
|
||||
case 's':
|
||||
s.Write([]byte(vo.String()))
|
||||
default:
|
||||
s.Write([]byte(fmt.Sprintf("%v", byte(vo))))
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Tally
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Equals returns if two proposals are equal.
|
||||
func (tr TallyResult) Equals(comp TallyResult) bool {
|
||||
return tr.Yes.Equal(comp.Yes) &&
|
||||
tr.Abstain.Equal(comp.Abstain) &&
|
||||
tr.No.Equal(comp.No) &&
|
||||
tr.NoWithVeto.Equal(comp.NoWithVeto)
|
||||
}
|
||||
|
||||
func (tr TallyResult) String() string {
|
||||
return fmt.Sprintf(`Tally Result:
|
||||
Yes: %s
|
||||
Abstain: %s
|
||||
No: %s
|
||||
NoWithVeto: %s`, tr.Yes, tr.Abstain, tr.No, tr.NoWithVeto)
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Proposal
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
type Proposal struct {
|
||||
ProposalContent `json:"proposal_content"` // Proposal content interface
|
||||
|
||||
ProposalID uint64 `json:"proposal_id"` // ID of the proposal
|
||||
|
||||
Status ProposalStatus `json:"proposal_status"` // Status of the Proposal {Pending, Active, Passed, Rejected}
|
||||
FinalTallyResult TallyResult `json:"final_tally_result"` // Result of Tallys
|
||||
|
||||
SubmitTime time.Time `json:"submit_time"` // Time of the block where TxGovSubmitProposal was included
|
||||
DepositEndTime time.Time `json:"deposit_end_time"` // Time that the Proposal would expire if deposit amount isn't met
|
||||
TotalDeposit sdk.Coins `json:"total_deposit"` // Current deposit on this proposal. Initial value is set at InitialDeposit
|
||||
|
||||
VotingStartTime time.Time `json:"voting_start_time"` // Time of the block where MinDeposit was reached. -1 if MinDeposit is not reached
|
||||
VotingEndTime time.Time `json:"voting_end_time"` // Time that the VotingPeriod for this proposal will end and votes will be tallied
|
||||
}
|
||||
|
||||
// nolint
|
||||
func (p Proposal) String() string {
|
||||
return fmt.Sprintf(`Proposal %d:
|
||||
Title: %s
|
||||
Type: %s
|
||||
Status: %s
|
||||
Submit Time: %s
|
||||
Deposit End Time: %s
|
||||
Total Deposit: %s
|
||||
Voting Start Time: %s
|
||||
Voting End Time: %s
|
||||
Description: %s`,
|
||||
p.ProposalID, p.GetTitle(), p.ProposalType(),
|
||||
p.Status, p.SubmitTime, p.DepositEndTime,
|
||||
p.TotalDeposit, p.VotingStartTime, p.VotingEndTime, p.GetDescription(),
|
||||
)
|
||||
}
|
||||
|
||||
// ProposalContent is an interface that has title, description, and proposaltype
|
||||
// that the governance module can use to identify them and generate human readable messages
|
||||
// ProposalContent can have additional fields, which will handled by ProposalHandlers
|
||||
// via type assertion, e.g. parameter change amount in ParameterChangeProposal
|
||||
type ProposalContent interface {
|
||||
GetTitle() string
|
||||
GetDescription() string
|
||||
ProposalType() ProposalKind
|
||||
}
|
||||
|
||||
// Proposals is an array of proposal
|
||||
type Proposals []Proposal
|
||||
|
||||
// nolint
|
||||
func (p Proposals) String() string {
|
||||
out := "ID - (Status) [Type] Title\n"
|
||||
for _, prop := range p {
|
||||
out += fmt.Sprintf("%d - (%s) [%s] %s\n",
|
||||
prop.ProposalID, prop.Status,
|
||||
prop.ProposalType(), prop.GetTitle())
|
||||
}
|
||||
return strings.TrimSpace(out)
|
||||
}
|
||||
|
||||
// Text Proposals
|
||||
type TextProposal struct {
|
||||
Title string `json:"title"` // Title of the proposal
|
||||
Description string `json:"description"` // Description of the proposal
|
||||
}
|
||||
|
||||
func NewTextProposal(title, description string) TextProposal {
|
||||
return TextProposal{
|
||||
Title: title,
|
||||
Description: description,
|
||||
}
|
||||
}
|
||||
|
||||
// Implements Proposal Interface
|
||||
var _ ProposalContent = TextProposal{}
|
||||
|
||||
// nolint
|
||||
func (tp TextProposal) GetTitle() string { return tp.Title }
|
||||
func (tp TextProposal) GetDescription() string { return tp.Description }
|
||||
func (tp TextProposal) ProposalType() ProposalKind { return ProposalTypeText }
|
||||
|
||||
// Software Upgrade Proposals
|
||||
type SoftwareUpgradeProposal struct {
|
||||
TextProposal
|
||||
}
|
||||
|
||||
func NewSoftwareUpgradeProposal(title, description string) SoftwareUpgradeProposal {
|
||||
return SoftwareUpgradeProposal{
|
||||
TextProposal: NewTextProposal(title, description),
|
||||
}
|
||||
}
|
||||
|
||||
// Implements Proposal Interface
|
||||
var _ ProposalContent = SoftwareUpgradeProposal{}
|
||||
|
||||
// nolint
|
||||
func (sup SoftwareUpgradeProposal) ProposalType() ProposalKind { return ProposalTypeSoftwareUpgrade }
|
||||
|
||||
// ProposalQueue
|
||||
type ProposalQueue []uint64
|
||||
|
||||
// ProposalKind
|
||||
|
||||
// Type that represents Proposal Type as a byte
|
||||
type ProposalKind byte
|
||||
|
||||
//nolint
|
||||
const (
|
||||
ProposalTypeNil ProposalKind = 0x00
|
||||
ProposalTypeText ProposalKind = 0x01
|
||||
ProposalTypeParameterChange ProposalKind = 0x02
|
||||
ProposalTypeSoftwareUpgrade ProposalKind = 0x03
|
||||
)
|
||||
|
||||
// String to proposalType byte. Returns 0xff if invalid.
|
||||
func ProposalTypeFromString(str string) (ProposalKind, error) {
|
||||
switch str {
|
||||
case "Text":
|
||||
return ProposalTypeText, nil
|
||||
case "ParameterChange":
|
||||
return ProposalTypeParameterChange, nil
|
||||
case "SoftwareUpgrade":
|
||||
return ProposalTypeSoftwareUpgrade, nil
|
||||
default:
|
||||
return ProposalKind(0xff), fmt.Errorf("'%s' is not a valid proposal type", str)
|
||||
}
|
||||
}
|
||||
|
||||
// Marshal needed for protobuf compatibility
|
||||
func (pt ProposalKind) Marshal() ([]byte, error) {
|
||||
return []byte{byte(pt)}, nil
|
||||
}
|
||||
|
||||
// Unmarshal needed for protobuf compatibility
|
||||
func (pt *ProposalKind) Unmarshal(data []byte) error {
|
||||
*pt = ProposalKind(data[0])
|
||||
return nil
|
||||
}
|
||||
|
||||
// Marshals to JSON using string
|
||||
func (pt ProposalKind) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(pt.String())
|
||||
}
|
||||
|
||||
// Unmarshals from JSON assuming Bech32 encoding
|
||||
func (pt *ProposalKind) UnmarshalJSON(data []byte) error {
|
||||
var s string
|
||||
err := json.Unmarshal(data, &s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
bz2, err := ProposalTypeFromString(s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*pt = bz2
|
||||
return nil
|
||||
}
|
||||
|
||||
// Turns VoteOption byte to String
|
||||
func (pt ProposalKind) String() string {
|
||||
switch pt {
|
||||
case ProposalTypeText:
|
||||
return "Text"
|
||||
case ProposalTypeParameterChange:
|
||||
return "ParameterChange"
|
||||
case ProposalTypeSoftwareUpgrade:
|
||||
return "SoftwareUpgrade"
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
// For Printf / Sprintf, returns bech32 when using %s
|
||||
// nolint: errcheck
|
||||
func (pt ProposalKind) Format(s fmt.State, verb rune) {
|
||||
switch verb {
|
||||
case 's':
|
||||
s.Write([]byte(pt.String()))
|
||||
default:
|
||||
// TODO: Do this conversion more directly
|
||||
s.Write([]byte(fmt.Sprintf("%v", byte(pt))))
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Codec
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
func RegisterCodec(cdc *codec.Codec) {
|
||||
cdc.RegisterInterface((*ProposalContent)(nil), nil)
|
||||
cdc.RegisterConcrete(TextProposal{}, "gov/TextProposal", nil)
|
||||
cdc.RegisterConcrete(SoftwareUpgradeProposal{}, "gov/SoftwareUpgradeProposal", nil)
|
||||
}
|
||||
@ -1,76 +0,0 @@
|
||||
package v036
|
||||
|
||||
import (
|
||||
v034gov "github.com/cosmos/cosmos-sdk/x/gov/legacy/v034"
|
||||
)
|
||||
|
||||
func MigrateGovernance(initialState v034gov.GenesisState) GenesisState {
|
||||
targetGov := GenesisState{
|
||||
StartingProposalID: initialState.StartingProposalID,
|
||||
DepositParams: DepositParams{
|
||||
MinDeposit: initialState.DepositParams.MinDeposit,
|
||||
MaxDepositPeriod: initialState.DepositParams.MaxDepositPeriod,
|
||||
},
|
||||
TallyParams: TallyParams{
|
||||
Quorum: initialState.TallyParams.Quorum,
|
||||
Threshold: initialState.TallyParams.Threshold,
|
||||
Veto: initialState.TallyParams.Veto,
|
||||
},
|
||||
VotingParams: VotingParams{
|
||||
VotingPeriod: initialState.VotingParams.VotingPeriod,
|
||||
},
|
||||
}
|
||||
|
||||
var deposits Deposits
|
||||
for _, p := range initialState.Deposits {
|
||||
deposits = append(deposits, Deposit{
|
||||
ProposalID: p.Deposit.ProposalID,
|
||||
Amount: p.Deposit.Amount,
|
||||
Depositor: p.Deposit.Depositor,
|
||||
})
|
||||
}
|
||||
|
||||
targetGov.Deposits = deposits
|
||||
|
||||
var votes Votes
|
||||
for _, p := range initialState.Votes {
|
||||
votes = append(votes, Vote{
|
||||
ProposalID: p.Vote.ProposalID,
|
||||
Option: VoteOption(p.Vote.Option),
|
||||
Voter: p.Vote.Voter,
|
||||
})
|
||||
}
|
||||
|
||||
targetGov.Votes = votes
|
||||
|
||||
var proposals Proposals
|
||||
for _, p := range initialState.Proposals {
|
||||
proposal := Proposal{
|
||||
Content: migrateContent(p.ProposalContent),
|
||||
ProposalID: p.ProposalID,
|
||||
Status: ProposalStatus(p.Status),
|
||||
FinalTallyResult: TallyResult(p.FinalTallyResult),
|
||||
SubmitTime: p.SubmitTime,
|
||||
DepositEndTime: p.DepositEndTime,
|
||||
TotalDeposit: p.TotalDeposit,
|
||||
VotingStartTime: p.VotingStartTime,
|
||||
VotingEndTime: p.VotingEndTime,
|
||||
}
|
||||
|
||||
proposals = append(proposals, proposal)
|
||||
}
|
||||
|
||||
targetGov.Proposals = proposals
|
||||
return targetGov
|
||||
}
|
||||
|
||||
func migrateContent(proposalContent v034gov.ProposalContent) (content Content) {
|
||||
switch proposalContent.ProposalType() {
|
||||
case v034gov.ProposalTypeText:
|
||||
return NewTextProposal(proposalContent.GetTitle(), proposalContent.GetDescription())
|
||||
case v034gov.ProposalTypeSoftwareUpgrade:
|
||||
return NewSoftwareUpgradeProposal(proposalContent.GetTitle(), proposalContent.GetDescription())
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
@ -1,454 +0,0 @@
|
||||
package v036
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
// Keys
|
||||
const (
|
||||
// ModuleName is the name of the module
|
||||
ModuleName = "gov"
|
||||
|
||||
// StoreKey is the store key string for gov
|
||||
StoreKey = ModuleName
|
||||
|
||||
// RouterKey is the message route for gov
|
||||
RouterKey = ModuleName
|
||||
|
||||
// QuerierRoute is the querier route for gov
|
||||
QuerierRoute = ModuleName
|
||||
|
||||
// DefaultParamspace default name for parameter store
|
||||
DefaultParamspace = ModuleName
|
||||
)
|
||||
|
||||
// GenesisState represents v0.34.x genesis state for the governance module.
|
||||
type GenesisState struct {
|
||||
StartingProposalID uint64 `json:"starting_proposal_id"`
|
||||
Deposits Deposits `json:"deposits"`
|
||||
Votes Votes `json:"votes"`
|
||||
Proposals []Proposal `json:"proposals"`
|
||||
DepositParams DepositParams `json:"deposit_params"`
|
||||
VotingParams VotingParams `json:"voting_params"`
|
||||
TallyParams TallyParams `json:"tally_params"`
|
||||
}
|
||||
|
||||
type Deposit struct {
|
||||
ProposalID uint64 `json:"proposal_id"` // proposalID of the proposal
|
||||
Depositor sdk.AccAddress `json:"depositor"` // Address of the depositor
|
||||
Amount sdk.Coins `json:"amount"` // Deposit amount
|
||||
}
|
||||
|
||||
type Deposits []Deposit
|
||||
|
||||
type Vote struct {
|
||||
ProposalID uint64 `json:"proposal_id"` // proposalID of the proposal
|
||||
Voter sdk.AccAddress `json:"voter"` // address of the voter
|
||||
Option VoteOption `json:"option"` // option from OptionSet chosen by the voter
|
||||
}
|
||||
|
||||
type Votes []Vote
|
||||
|
||||
// Param around deposits for governance
|
||||
type DepositParams struct {
|
||||
MinDeposit sdk.Coins `json:"min_deposit,omitempty"` // Minimum deposit for a proposal to enter voting period.
|
||||
MaxDepositPeriod time.Duration `json:"max_deposit_period,omitempty"` // Maximum period for Atom holders to deposit on a proposal. Initial value: 2 months
|
||||
}
|
||||
|
||||
type Content interface {
|
||||
GetTitle() string
|
||||
GetDescription() string
|
||||
ProposalRoute() string
|
||||
ProposalType() string
|
||||
ValidateBasic() sdk.Error
|
||||
String() string
|
||||
}
|
||||
|
||||
type Proposal struct {
|
||||
Content `json:"content"` // Proposal content interface
|
||||
|
||||
ProposalID uint64 `json:"id"` // ID of the proposal
|
||||
Status ProposalStatus `json:"proposal_status"` // Status of the Proposal {Pending, Active, Passed, Rejected}
|
||||
FinalTallyResult TallyResult `json:"final_tally_result"` // Result of Tallys
|
||||
|
||||
SubmitTime time.Time `json:"submit_time"` // Time of the block where TxGovSubmitProposal was included
|
||||
DepositEndTime time.Time `json:"deposit_end_time"` // Time that the Proposal would expire if deposit amount isn't met
|
||||
TotalDeposit sdk.Coins `json:"total_deposit"` // Current deposit on this proposal. Initial value is set at InitialDeposit
|
||||
|
||||
VotingStartTime time.Time `json:"voting_start_time"` // Time of the block where MinDeposit was reached. -1 if MinDeposit is not reached
|
||||
VotingEndTime time.Time `json:"voting_end_time"` // Time that the VotingPeriod for this proposal will end and votes will be tallied
|
||||
}
|
||||
|
||||
type Proposals []Proposal
|
||||
type ProposalQueue []uint64
|
||||
|
||||
type TallyParams struct {
|
||||
Quorum sdk.Dec `json:"quorum,omitempty"` // Minimum percentage of total stake needed to vote for a result to be considered valid
|
||||
Threshold sdk.Dec `json:"threshold,omitempty"` // Minimum proportion of Yes votes for proposal to pass. Initial value: 0.5
|
||||
Veto sdk.Dec `json:"veto,omitempty"` // Minimum value of Veto votes to Total votes ratio for proposal to be vetoed. Initial value: 1/3
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// ProposalStatus
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// ProposalStatus is a type alias that represents a proposal status as a byte
|
||||
type ProposalStatus byte
|
||||
|
||||
//nolint
|
||||
const (
|
||||
StatusNil ProposalStatus = 0x00
|
||||
StatusDepositPeriod ProposalStatus = 0x01
|
||||
StatusVotingPeriod ProposalStatus = 0x02
|
||||
StatusPassed ProposalStatus = 0x03
|
||||
StatusRejected ProposalStatus = 0x04
|
||||
StatusFailed ProposalStatus = 0x05
|
||||
)
|
||||
|
||||
// ProposalStatusToString turns a string into a ProposalStatus
|
||||
func ProposalStatusFromString(str string) (ProposalStatus, error) {
|
||||
switch str {
|
||||
case "DepositPeriod":
|
||||
return StatusDepositPeriod, nil
|
||||
|
||||
case "VotingPeriod":
|
||||
return StatusVotingPeriod, nil
|
||||
|
||||
case "Passed":
|
||||
return StatusPassed, nil
|
||||
|
||||
case "Rejected":
|
||||
return StatusRejected, nil
|
||||
|
||||
case "Failed":
|
||||
return StatusFailed, nil
|
||||
|
||||
case "":
|
||||
return StatusNil, nil
|
||||
|
||||
default:
|
||||
return ProposalStatus(0xff), fmt.Errorf("'%s' is not a valid proposal status", str)
|
||||
}
|
||||
}
|
||||
|
||||
// Marshal needed for protobuf compatibility
|
||||
func (status ProposalStatus) Marshal() ([]byte, error) {
|
||||
return []byte{byte(status)}, nil
|
||||
}
|
||||
|
||||
// Unmarshal needed for protobuf compatibility
|
||||
func (status *ProposalStatus) Unmarshal(data []byte) error {
|
||||
*status = ProposalStatus(data[0])
|
||||
return nil
|
||||
}
|
||||
|
||||
// Marshals to JSON using string
|
||||
func (status ProposalStatus) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(status.String())
|
||||
}
|
||||
|
||||
// Unmarshals from JSON assuming Bech32 encoding
|
||||
func (status *ProposalStatus) UnmarshalJSON(data []byte) error {
|
||||
var s string
|
||||
err := json.Unmarshal(data, &s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
bz2, err := ProposalStatusFromString(s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*status = bz2
|
||||
return nil
|
||||
}
|
||||
|
||||
// String implements the Stringer interface.
|
||||
func (status ProposalStatus) String() string {
|
||||
switch status {
|
||||
case StatusDepositPeriod:
|
||||
return "DepositPeriod"
|
||||
|
||||
case StatusVotingPeriod:
|
||||
return "VotingPeriod"
|
||||
|
||||
case StatusPassed:
|
||||
return "Passed"
|
||||
|
||||
case StatusRejected:
|
||||
return "Rejected"
|
||||
|
||||
case StatusFailed:
|
||||
return "Failed"
|
||||
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
// Format implements the fmt.Formatter interface.
|
||||
// nolint: errcheck
|
||||
func (status ProposalStatus) Format(s fmt.State, verb rune) {
|
||||
switch verb {
|
||||
case 's':
|
||||
s.Write([]byte(status.String()))
|
||||
default:
|
||||
// TODO: Do this conversion more directly
|
||||
s.Write([]byte(fmt.Sprintf("%v", byte(status))))
|
||||
}
|
||||
}
|
||||
|
||||
type VotingParams struct {
|
||||
VotingPeriod time.Duration `json:"voting_period,omitempty"` // Length of the voting period.
|
||||
}
|
||||
|
||||
type TallyResult struct {
|
||||
Yes sdk.Int `json:"yes"`
|
||||
Abstain sdk.Int `json:"abstain"`
|
||||
No sdk.Int `json:"no"`
|
||||
NoWithVeto sdk.Int `json:"no_with_veto"`
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// VoteOption
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
type VoteOption byte
|
||||
|
||||
// Vote options
|
||||
const (
|
||||
OptionEmpty VoteOption = 0x00
|
||||
OptionYes VoteOption = 0x01
|
||||
OptionAbstain VoteOption = 0x02
|
||||
OptionNo VoteOption = 0x03
|
||||
OptionNoWithVeto VoteOption = 0x04
|
||||
)
|
||||
|
||||
// VoteOptionFromString returns a VoteOption from a string. It returns an error
|
||||
// if the string is invalid.
|
||||
func VoteOptionFromString(str string) (VoteOption, error) {
|
||||
switch str {
|
||||
case "Yes":
|
||||
return OptionYes, nil
|
||||
|
||||
case "Abstain":
|
||||
return OptionAbstain, nil
|
||||
|
||||
case "No":
|
||||
return OptionNo, nil
|
||||
|
||||
case "NoWithVeto":
|
||||
return OptionNoWithVeto, nil
|
||||
|
||||
default:
|
||||
return VoteOption(0xff), fmt.Errorf("'%s' is not a valid vote option", str)
|
||||
}
|
||||
}
|
||||
|
||||
// Marshal needed for protobuf compatibility.
|
||||
func (vo VoteOption) Marshal() ([]byte, error) {
|
||||
return []byte{byte(vo)}, nil
|
||||
}
|
||||
|
||||
// Unmarshal needed for protobuf compatibility.
|
||||
func (vo *VoteOption) Unmarshal(data []byte) error {
|
||||
*vo = VoteOption(data[0])
|
||||
return nil
|
||||
}
|
||||
|
||||
// Marshals to JSON using string.
|
||||
func (vo VoteOption) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(vo.String())
|
||||
}
|
||||
|
||||
// UnmarshalJSON decodes from JSON assuming Bech32 encoding.
|
||||
func (vo *VoteOption) UnmarshalJSON(data []byte) error {
|
||||
var s string
|
||||
err := json.Unmarshal(data, &s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
bz2, err := VoteOptionFromString(s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*vo = bz2
|
||||
return nil
|
||||
}
|
||||
|
||||
// String implements the Stringer interface.
|
||||
func (vo VoteOption) String() string {
|
||||
switch vo {
|
||||
case OptionYes:
|
||||
return "Yes"
|
||||
case OptionAbstain:
|
||||
return "Abstain"
|
||||
case OptionNo:
|
||||
return "No"
|
||||
case OptionNoWithVeto:
|
||||
return "NoWithVeto"
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
// Format implements the fmt.Formatter interface.
|
||||
// nolint: errcheck
|
||||
func (vo VoteOption) Format(s fmt.State, verb rune) {
|
||||
switch verb {
|
||||
case 's':
|
||||
s.Write([]byte(vo.String()))
|
||||
default:
|
||||
s.Write([]byte(fmt.Sprintf("%v", byte(vo))))
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Tally
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Equals returns if two proposals are equal.
|
||||
func (tr TallyResult) Equals(comp TallyResult) bool {
|
||||
return tr.Yes.Equal(comp.Yes) &&
|
||||
tr.Abstain.Equal(comp.Abstain) &&
|
||||
tr.No.Equal(comp.No) &&
|
||||
tr.NoWithVeto.Equal(comp.NoWithVeto)
|
||||
}
|
||||
|
||||
func (tr TallyResult) String() string {
|
||||
return fmt.Sprintf(`Tally Result:
|
||||
Yes: %s
|
||||
Abstain: %s
|
||||
No: %s
|
||||
NoWithVeto: %s`, tr.Yes, tr.Abstain, tr.No, tr.NoWithVeto)
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Proposal
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Proposal types
|
||||
const (
|
||||
ProposalTypeText string = "Text"
|
||||
ProposalTypeSoftwareUpgrade string = "SoftwareUpgrade"
|
||||
)
|
||||
|
||||
// Text Proposal
|
||||
type TextProposal struct {
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description"`
|
||||
}
|
||||
|
||||
func NewTextProposal(title, description string) Content {
|
||||
return TextProposal{title, description}
|
||||
}
|
||||
|
||||
// Implements Proposal Interface
|
||||
var _ Content = TextProposal{}
|
||||
|
||||
// nolint
|
||||
func (tp TextProposal) GetTitle() string { return tp.Title }
|
||||
func (tp TextProposal) GetDescription() string { return tp.Description }
|
||||
func (tp TextProposal) ProposalRoute() string { return RouterKey }
|
||||
func (tp TextProposal) ProposalType() string { return ProposalTypeText }
|
||||
func (tp TextProposal) ValidateBasic() sdk.Error { return ValidateAbstract(DefaultCodespace, tp) }
|
||||
|
||||
const (
|
||||
DefaultCodespace sdk.CodespaceType = "gov"
|
||||
|
||||
CodeInvalidContent sdk.CodeType = 6
|
||||
CodeInvalidProposalType sdk.CodeType = 7
|
||||
)
|
||||
|
||||
func ErrInvalidProposalContent(cs sdk.CodespaceType, msg string) sdk.Error {
|
||||
return sdk.NewError(cs, CodeInvalidContent, fmt.Sprintf("invalid proposal content: %s", msg))
|
||||
}
|
||||
|
||||
func ErrInvalidProposalType(codespace sdk.CodespaceType, proposalType string) sdk.Error {
|
||||
return sdk.NewError(codespace, CodeInvalidProposalType, fmt.Sprintf("proposal type '%s' is not valid", proposalType))
|
||||
}
|
||||
|
||||
// ValidateAbstract validates a proposal's abstract contents returning an error
|
||||
// if invalid.
|
||||
func ValidateAbstract(codespace sdk.CodespaceType, c Content) sdk.Error {
|
||||
title := c.GetTitle()
|
||||
if len(strings.TrimSpace(title)) == 0 {
|
||||
return ErrInvalidProposalContent(codespace, "proposal title cannot be blank")
|
||||
}
|
||||
if len(title) > MaxTitleLength {
|
||||
return ErrInvalidProposalContent(codespace, fmt.Sprintf("proposal title is longer than max length of %d", MaxTitleLength))
|
||||
}
|
||||
|
||||
description := c.GetDescription()
|
||||
if len(description) == 0 {
|
||||
return ErrInvalidProposalContent(codespace, "proposal description cannot be blank")
|
||||
}
|
||||
if len(description) > MaxDescriptionLength {
|
||||
return ErrInvalidProposalContent(codespace, fmt.Sprintf("proposal description is longer than max length of %d", MaxDescriptionLength))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Constants pertaining to a Content object
|
||||
const (
|
||||
MaxDescriptionLength int = 5000
|
||||
MaxTitleLength int = 140
|
||||
)
|
||||
|
||||
func (tp TextProposal) String() string {
|
||||
return fmt.Sprintf(`Text Proposal:
|
||||
Title: %s
|
||||
Description: %s
|
||||
`, tp.Title, tp.Description)
|
||||
}
|
||||
|
||||
// Software Upgrade Proposals
|
||||
// TODO: We have to add fields for SUP specific arguments e.g. commit hash,
|
||||
// upgrade date, etc.
|
||||
type SoftwareUpgradeProposal struct {
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description"`
|
||||
}
|
||||
|
||||
func NewSoftwareUpgradeProposal(title, description string) Content {
|
||||
return SoftwareUpgradeProposal{title, description}
|
||||
}
|
||||
|
||||
// Implements Proposal Interface
|
||||
var _ Content = SoftwareUpgradeProposal{}
|
||||
|
||||
// nolint
|
||||
func (sup SoftwareUpgradeProposal) GetTitle() string { return sup.Title }
|
||||
func (sup SoftwareUpgradeProposal) GetDescription() string { return sup.Description }
|
||||
func (sup SoftwareUpgradeProposal) ProposalRoute() string { return RouterKey }
|
||||
func (sup SoftwareUpgradeProposal) ProposalType() string { return ProposalTypeSoftwareUpgrade }
|
||||
func (sup SoftwareUpgradeProposal) ValidateBasic() sdk.Error {
|
||||
return ValidateAbstract(DefaultCodespace, sup)
|
||||
}
|
||||
|
||||
func (sup SoftwareUpgradeProposal) String() string {
|
||||
return fmt.Sprintf(`Software Upgrade Proposal:
|
||||
Title: %s
|
||||
Description: %s
|
||||
`, sup.Title, sup.Description)
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Codec
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
func RegisterCodec(cdc *codec.Codec) {
|
||||
cdc.RegisterInterface((*Content)(nil), nil)
|
||||
cdc.RegisterConcrete(TextProposal{}, "cosmos-sdk/TextProposal", nil)
|
||||
cdc.RegisterConcrete(SoftwareUpgradeProposal{}, "cosmos-sdk/SoftwareUpgradeProposal", nil)
|
||||
}
|
||||
345
x/gov/legacy/v0_34/types.go
Normal file
345
x/gov/legacy/v0_34/types.go
Normal file
@ -0,0 +1,345 @@
|
||||
// DONTCOVER
|
||||
// nolint
|
||||
package v0_34
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
var (
|
||||
_ ProposalContent = TextProposal{}
|
||||
_ ProposalContent = SoftwareUpgradeProposal{}
|
||||
)
|
||||
|
||||
const (
|
||||
ModuleName = "gov"
|
||||
|
||||
StatusNil ProposalStatus = 0x00
|
||||
StatusDepositPeriod ProposalStatus = 0x01
|
||||
StatusVotingPeriod ProposalStatus = 0x02
|
||||
StatusPassed ProposalStatus = 0x03
|
||||
StatusRejected ProposalStatus = 0x04
|
||||
StatusFailed ProposalStatus = 0x05
|
||||
|
||||
OptionEmpty VoteOption = 0x00
|
||||
OptionYes VoteOption = 0x01
|
||||
OptionAbstain VoteOption = 0x02
|
||||
OptionNo VoteOption = 0x03
|
||||
OptionNoWithVeto VoteOption = 0x04
|
||||
|
||||
ProposalTypeNil ProposalKind = 0x00
|
||||
ProposalTypeText ProposalKind = 0x01
|
||||
ProposalTypeParameterChange ProposalKind = 0x02
|
||||
ProposalTypeSoftwareUpgrade ProposalKind = 0x03
|
||||
)
|
||||
|
||||
type (
|
||||
SoftwareUpgradeProposal struct {
|
||||
TextProposal
|
||||
}
|
||||
|
||||
ProposalQueue []uint64
|
||||
|
||||
ProposalKind byte
|
||||
|
||||
VoteOption byte
|
||||
ProposalStatus byte
|
||||
|
||||
ProposalContent interface {
|
||||
GetTitle() string
|
||||
GetDescription() string
|
||||
ProposalType() ProposalKind
|
||||
}
|
||||
|
||||
Proposals []Proposal
|
||||
|
||||
TextProposal struct {
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description"`
|
||||
}
|
||||
|
||||
Proposal struct {
|
||||
ProposalContent `json:"proposal_content"`
|
||||
|
||||
ProposalID uint64 `json:"proposal_id"`
|
||||
|
||||
Status ProposalStatus `json:"proposal_status"`
|
||||
FinalTallyResult TallyResult `json:"final_tally_result"`
|
||||
|
||||
SubmitTime time.Time `json:"submit_time"`
|
||||
DepositEndTime time.Time `json:"deposit_end_time"`
|
||||
TotalDeposit sdk.Coins `json:"total_deposit"`
|
||||
|
||||
VotingStartTime time.Time `json:"voting_start_time"`
|
||||
VotingEndTime time.Time `json:"voting_end_time"`
|
||||
}
|
||||
|
||||
TallyParams struct {
|
||||
Quorum sdk.Dec `json:"quorum,omitempty"`
|
||||
Threshold sdk.Dec `json:"threshold,omitempty"`
|
||||
Veto sdk.Dec `json:"veto,omitempty"`
|
||||
}
|
||||
|
||||
VotingParams struct {
|
||||
VotingPeriod time.Duration `json:"voting_period,omitempty"`
|
||||
}
|
||||
|
||||
TallyResult struct {
|
||||
Yes sdk.Int `json:"yes"`
|
||||
Abstain sdk.Int `json:"abstain"`
|
||||
No sdk.Int `json:"no"`
|
||||
NoWithVeto sdk.Int `json:"no_with_veto"`
|
||||
}
|
||||
|
||||
Deposits []Deposit
|
||||
|
||||
Vote struct {
|
||||
ProposalID uint64 `json:"proposal_id"`
|
||||
Voter sdk.AccAddress `json:"voter"`
|
||||
Option VoteOption `json:"option"`
|
||||
}
|
||||
|
||||
Votes []Vote
|
||||
|
||||
DepositParams struct {
|
||||
MinDeposit sdk.Coins `json:"min_deposit,omitempty"`
|
||||
MaxDepositPeriod time.Duration `json:"max_deposit_period,omitempty"`
|
||||
}
|
||||
|
||||
Deposit struct {
|
||||
ProposalID uint64 `json:"proposal_id"`
|
||||
Depositor sdk.AccAddress `json:"depositor"`
|
||||
Amount sdk.Coins `json:"amount"`
|
||||
}
|
||||
|
||||
DepositWithMetadata struct {
|
||||
ProposalID uint64 `json:"proposal_id"`
|
||||
Deposit Deposit `json:"deposit"`
|
||||
}
|
||||
|
||||
VoteWithMetadata struct {
|
||||
ProposalID uint64 `json:"proposal_id"`
|
||||
Vote Vote `json:"vote"`
|
||||
}
|
||||
|
||||
GenesisState struct {
|
||||
StartingProposalID uint64 `json:"starting_proposal_id"`
|
||||
Deposits []DepositWithMetadata `json:"deposits"`
|
||||
Votes []VoteWithMetadata `json:"votes"`
|
||||
Proposals []Proposal `json:"proposals"`
|
||||
DepositParams DepositParams `json:"deposit_params"`
|
||||
VotingParams VotingParams `json:"voting_params"`
|
||||
TallyParams TallyParams `json:"tally_params"`
|
||||
}
|
||||
)
|
||||
|
||||
func (tp TextProposal) GetTitle() string { return tp.Title }
|
||||
func (tp TextProposal) GetDescription() string { return tp.Description }
|
||||
func (tp TextProposal) ProposalType() ProposalKind { return ProposalTypeText }
|
||||
|
||||
func (sup SoftwareUpgradeProposal) ProposalType() ProposalKind { return ProposalTypeSoftwareUpgrade }
|
||||
|
||||
// ProposalStatusToString turns a string into a ProposalStatus
|
||||
func ProposalStatusFromString(str string) (ProposalStatus, error) {
|
||||
switch str {
|
||||
case "DepositPeriod":
|
||||
return StatusDepositPeriod, nil
|
||||
|
||||
case "VotingPeriod":
|
||||
return StatusVotingPeriod, nil
|
||||
|
||||
case "Passed":
|
||||
return StatusPassed, nil
|
||||
|
||||
case "Rejected":
|
||||
return StatusRejected, nil
|
||||
|
||||
case "Failed":
|
||||
return StatusFailed, nil
|
||||
|
||||
case "":
|
||||
return StatusNil, nil
|
||||
|
||||
default:
|
||||
return ProposalStatus(0xff), fmt.Errorf("'%s' is not a valid proposal status", str)
|
||||
}
|
||||
}
|
||||
|
||||
func (status ProposalStatus) Marshal() ([]byte, error) {
|
||||
return []byte{byte(status)}, nil
|
||||
}
|
||||
|
||||
func (status *ProposalStatus) Unmarshal(data []byte) error {
|
||||
*status = ProposalStatus(data[0])
|
||||
return nil
|
||||
}
|
||||
|
||||
func (status ProposalStatus) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(status.String())
|
||||
}
|
||||
|
||||
func (status *ProposalStatus) UnmarshalJSON(data []byte) error {
|
||||
var s string
|
||||
err := json.Unmarshal(data, &s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
bz2, err := ProposalStatusFromString(s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*status = bz2
|
||||
return nil
|
||||
}
|
||||
|
||||
func (status ProposalStatus) String() string {
|
||||
switch status {
|
||||
case StatusDepositPeriod:
|
||||
return "DepositPeriod"
|
||||
|
||||
case StatusVotingPeriod:
|
||||
return "VotingPeriod"
|
||||
|
||||
case StatusPassed:
|
||||
return "Passed"
|
||||
|
||||
case StatusRejected:
|
||||
return "Rejected"
|
||||
|
||||
case StatusFailed:
|
||||
return "Failed"
|
||||
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
func VoteOptionFromString(str string) (VoteOption, error) {
|
||||
switch str {
|
||||
case "Yes":
|
||||
return OptionYes, nil
|
||||
|
||||
case "Abstain":
|
||||
return OptionAbstain, nil
|
||||
|
||||
case "No":
|
||||
return OptionNo, nil
|
||||
|
||||
case "NoWithVeto":
|
||||
return OptionNoWithVeto, nil
|
||||
|
||||
default:
|
||||
return VoteOption(0xff), fmt.Errorf("'%s' is not a valid vote option", str)
|
||||
}
|
||||
}
|
||||
|
||||
func (vo VoteOption) Marshal() ([]byte, error) {
|
||||
return []byte{byte(vo)}, nil
|
||||
}
|
||||
|
||||
func (vo *VoteOption) Unmarshal(data []byte) error {
|
||||
*vo = VoteOption(data[0])
|
||||
return nil
|
||||
}
|
||||
|
||||
func (vo VoteOption) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(vo.String())
|
||||
}
|
||||
|
||||
func (vo *VoteOption) UnmarshalJSON(data []byte) error {
|
||||
var s string
|
||||
err := json.Unmarshal(data, &s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
bz2, err := VoteOptionFromString(s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*vo = bz2
|
||||
return nil
|
||||
}
|
||||
|
||||
func (vo VoteOption) String() string {
|
||||
switch vo {
|
||||
case OptionYes:
|
||||
return "Yes"
|
||||
case OptionAbstain:
|
||||
return "Abstain"
|
||||
case OptionNo:
|
||||
return "No"
|
||||
case OptionNoWithVeto:
|
||||
return "NoWithVeto"
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
func ProposalTypeFromString(str string) (ProposalKind, error) {
|
||||
switch str {
|
||||
case "Text":
|
||||
return ProposalTypeText, nil
|
||||
case "ParameterChange":
|
||||
return ProposalTypeParameterChange, nil
|
||||
case "SoftwareUpgrade":
|
||||
return ProposalTypeSoftwareUpgrade, nil
|
||||
default:
|
||||
return ProposalKind(0xff), fmt.Errorf("'%s' is not a valid proposal type", str)
|
||||
}
|
||||
}
|
||||
|
||||
func (pt ProposalKind) Marshal() ([]byte, error) {
|
||||
return []byte{byte(pt)}, nil
|
||||
}
|
||||
|
||||
func (pt *ProposalKind) Unmarshal(data []byte) error {
|
||||
*pt = ProposalKind(data[0])
|
||||
return nil
|
||||
}
|
||||
|
||||
func (pt ProposalKind) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(pt.String())
|
||||
}
|
||||
|
||||
func (pt *ProposalKind) UnmarshalJSON(data []byte) error {
|
||||
var s string
|
||||
err := json.Unmarshal(data, &s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
bz2, err := ProposalTypeFromString(s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*pt = bz2
|
||||
return nil
|
||||
}
|
||||
|
||||
func (pt ProposalKind) String() string {
|
||||
switch pt {
|
||||
case ProposalTypeText:
|
||||
return "Text"
|
||||
case ProposalTypeParameterChange:
|
||||
return "ParameterChange"
|
||||
case ProposalTypeSoftwareUpgrade:
|
||||
return "SoftwareUpgrade"
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
func RegisterCodec(cdc *codec.Codec) {
|
||||
cdc.RegisterInterface((*ProposalContent)(nil), nil)
|
||||
cdc.RegisterConcrete(TextProposal{}, "gov/TextProposal", nil)
|
||||
cdc.RegisterConcrete(SoftwareUpgradeProposal{}, "gov/SoftwareUpgradeProposal", nil)
|
||||
}
|
||||
51
x/gov/legacy/v0_36/migrate.go
Normal file
51
x/gov/legacy/v0_36/migrate.go
Normal file
@ -0,0 +1,51 @@
|
||||
package v0_36
|
||||
|
||||
import (
|
||||
v034gov "github.com/cosmos/cosmos-sdk/x/gov/legacy/v0_34"
|
||||
)
|
||||
|
||||
// Migrate accepts exported genesis state from v0.34 and migrates it to v0.36
|
||||
// genesis state. This migration flattens the deposits and votes and updates the
|
||||
// proposal content to the new
|
||||
func Migrate(oldGenState v034gov.GenesisState) GenesisState {
|
||||
deposits := make(v034gov.Deposits, len(oldGenState.Deposits))
|
||||
for i, deposit := range oldGenState.Deposits {
|
||||
deposits[i] = deposit.Deposit
|
||||
}
|
||||
|
||||
votes := make(v034gov.Votes, len(oldGenState.Votes))
|
||||
for i, vote := range oldGenState.Votes {
|
||||
votes[i] = vote.Vote
|
||||
}
|
||||
|
||||
proposals := make([]Proposal, len(oldGenState.Proposals))
|
||||
for i, proposal := range oldGenState.Proposals {
|
||||
proposals[i] = Proposal{
|
||||
Content: migrateContent(proposal.ProposalContent),
|
||||
ProposalID: proposal.ProposalID,
|
||||
Status: proposal.Status,
|
||||
FinalTallyResult: proposal.FinalTallyResult,
|
||||
SubmitTime: proposal.SubmitTime,
|
||||
DepositEndTime: proposal.DepositEndTime,
|
||||
TotalDeposit: proposal.TotalDeposit,
|
||||
VotingStartTime: proposal.VotingStartTime,
|
||||
VotingEndTime: proposal.VotingEndTime,
|
||||
}
|
||||
}
|
||||
|
||||
return NewGenesisState(
|
||||
oldGenState.StartingProposalID, deposits, votes, proposals,
|
||||
oldGenState.DepositParams, oldGenState.VotingParams, oldGenState.TallyParams,
|
||||
)
|
||||
}
|
||||
|
||||
func migrateContent(proposalContent v034gov.ProposalContent) (content Content) {
|
||||
switch proposalContent.ProposalType() {
|
||||
case v034gov.ProposalTypeText:
|
||||
return NewTextProposal(proposalContent.GetTitle(), proposalContent.GetDescription())
|
||||
case v034gov.ProposalTypeSoftwareUpgrade:
|
||||
return NewSoftwareUpgradeProposal(proposalContent.GetTitle(), proposalContent.GetDescription())
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
164
x/gov/legacy/v0_36/types.go
Normal file
164
x/gov/legacy/v0_36/types.go
Normal file
@ -0,0 +1,164 @@
|
||||
// DONTCOVER
|
||||
// nolint
|
||||
package v0_36
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
v034gov "github.com/cosmos/cosmos-sdk/x/gov/legacy/v0_34"
|
||||
)
|
||||
|
||||
const (
|
||||
ModuleName = "gov"
|
||||
RouterKey = ModuleName
|
||||
|
||||
DefaultCodespace sdk.CodespaceType = "gov"
|
||||
|
||||
ProposalTypeText string = "Text"
|
||||
ProposalTypeSoftwareUpgrade string = "SoftwareUpgrade"
|
||||
|
||||
MaxDescriptionLength int = 5000
|
||||
MaxTitleLength int = 140
|
||||
|
||||
CodeInvalidContent sdk.CodeType = 6
|
||||
)
|
||||
|
||||
var (
|
||||
_ Content = TextProposal{}
|
||||
_ Content = SoftwareUpgradeProposal{}
|
||||
)
|
||||
|
||||
type (
|
||||
Proposals []Proposal
|
||||
ProposalQueue []uint64
|
||||
|
||||
TextProposal struct {
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description"`
|
||||
}
|
||||
|
||||
SoftwareUpgradeProposal struct {
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description"`
|
||||
}
|
||||
|
||||
Content interface {
|
||||
GetTitle() string
|
||||
GetDescription() string
|
||||
ProposalRoute() string
|
||||
ProposalType() string
|
||||
ValidateBasic() sdk.Error
|
||||
String() string
|
||||
}
|
||||
|
||||
Proposal struct {
|
||||
Content `json:"content"`
|
||||
|
||||
ProposalID uint64 `json:"id"`
|
||||
Status v034gov.ProposalStatus `json:"proposal_status"`
|
||||
FinalTallyResult v034gov.TallyResult `json:"final_tally_result"`
|
||||
|
||||
SubmitTime time.Time `json:"submit_time"`
|
||||
DepositEndTime time.Time `json:"deposit_end_time"`
|
||||
TotalDeposit sdk.Coins `json:"total_deposit"`
|
||||
|
||||
VotingStartTime time.Time `json:"voting_start_time"`
|
||||
VotingEndTime time.Time `json:"voting_end_time"`
|
||||
}
|
||||
|
||||
GenesisState struct {
|
||||
StartingProposalID uint64 `json:"starting_proposal_id"`
|
||||
Deposits v034gov.Deposits `json:"deposits"`
|
||||
Votes v034gov.Votes `json:"votes"`
|
||||
Proposals []Proposal `json:"proposals"`
|
||||
DepositParams v034gov.DepositParams `json:"deposit_params"`
|
||||
VotingParams v034gov.VotingParams `json:"voting_params"`
|
||||
TallyParams v034gov.TallyParams `json:"tally_params"`
|
||||
}
|
||||
)
|
||||
|
||||
func NewGenesisState(
|
||||
startingProposalID uint64, deposits v034gov.Deposits, votes v034gov.Votes, proposals []Proposal,
|
||||
depositParams v034gov.DepositParams, votingParams v034gov.VotingParams, tallyParams v034gov.TallyParams,
|
||||
) GenesisState {
|
||||
|
||||
return GenesisState{
|
||||
StartingProposalID: startingProposalID,
|
||||
Deposits: deposits,
|
||||
Votes: votes,
|
||||
Proposals: proposals,
|
||||
DepositParams: depositParams,
|
||||
VotingParams: votingParams,
|
||||
TallyParams: tallyParams,
|
||||
}
|
||||
}
|
||||
|
||||
func NewTextProposal(title, description string) Content {
|
||||
return TextProposal{title, description}
|
||||
}
|
||||
|
||||
func (tp TextProposal) GetTitle() string { return tp.Title }
|
||||
func (tp TextProposal) GetDescription() string { return tp.Description }
|
||||
func (tp TextProposal) ProposalRoute() string { return RouterKey }
|
||||
func (tp TextProposal) ProposalType() string { return ProposalTypeText }
|
||||
func (tp TextProposal) ValidateBasic() sdk.Error { return ValidateAbstract(DefaultCodespace, tp) }
|
||||
|
||||
func (tp TextProposal) String() string {
|
||||
return fmt.Sprintf(`Text Proposal:
|
||||
Title: %s
|
||||
Description: %s
|
||||
`, tp.Title, tp.Description)
|
||||
}
|
||||
|
||||
func NewSoftwareUpgradeProposal(title, description string) Content {
|
||||
return SoftwareUpgradeProposal{title, description}
|
||||
}
|
||||
|
||||
func (sup SoftwareUpgradeProposal) GetTitle() string { return sup.Title }
|
||||
func (sup SoftwareUpgradeProposal) GetDescription() string { return sup.Description }
|
||||
func (sup SoftwareUpgradeProposal) ProposalRoute() string { return RouterKey }
|
||||
func (sup SoftwareUpgradeProposal) ProposalType() string { return ProposalTypeSoftwareUpgrade }
|
||||
func (sup SoftwareUpgradeProposal) ValidateBasic() sdk.Error {
|
||||
return ValidateAbstract(DefaultCodespace, sup)
|
||||
}
|
||||
|
||||
func (sup SoftwareUpgradeProposal) String() string {
|
||||
return fmt.Sprintf(`Software Upgrade Proposal:
|
||||
Title: %s
|
||||
Description: %s
|
||||
`, sup.Title, sup.Description)
|
||||
}
|
||||
|
||||
func ErrInvalidProposalContent(cs sdk.CodespaceType, msg string) sdk.Error {
|
||||
return sdk.NewError(cs, CodeInvalidContent, fmt.Sprintf("invalid proposal content: %s", msg))
|
||||
}
|
||||
|
||||
func ValidateAbstract(codespace sdk.CodespaceType, c Content) sdk.Error {
|
||||
title := c.GetTitle()
|
||||
if len(strings.TrimSpace(title)) == 0 {
|
||||
return ErrInvalidProposalContent(codespace, "proposal title cannot be blank")
|
||||
}
|
||||
if len(title) > MaxTitleLength {
|
||||
return ErrInvalidProposalContent(codespace, fmt.Sprintf("proposal title is longer than max length of %d", MaxTitleLength))
|
||||
}
|
||||
|
||||
description := c.GetDescription()
|
||||
if len(description) == 0 {
|
||||
return ErrInvalidProposalContent(codespace, "proposal description cannot be blank")
|
||||
}
|
||||
if len(description) > MaxDescriptionLength {
|
||||
return ErrInvalidProposalContent(codespace, fmt.Sprintf("proposal description is longer than max length of %d", MaxDescriptionLength))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func RegisterCodec(cdc *codec.Codec) {
|
||||
cdc.RegisterInterface((*Content)(nil), nil)
|
||||
cdc.RegisterConcrete(TextProposal{}, "cosmos-sdk/TextProposal", nil)
|
||||
cdc.RegisterConcrete(SoftwareUpgradeProposal{}, "cosmos-sdk/SoftwareUpgradeProposal", nil)
|
||||
}
|
||||
@ -47,6 +47,7 @@ func SimulateFromSeed(
|
||||
appStateFn AppStateFn, seed int64, ops WeightedOperations,
|
||||
invariants sdk.Invariants,
|
||||
numBlocks, blockSize int, commit, lean, onOperation, allInvariants bool,
|
||||
blackListedAccs map[string]bool,
|
||||
) (stopEarly bool, simError error) {
|
||||
|
||||
// in case we have to end early, don't os.Exit so that we can run cleanup code.
|
||||
@ -74,6 +75,16 @@ func SimulateFromSeed(
|
||||
return true, fmt.Errorf("must have greater than zero genesis accounts")
|
||||
}
|
||||
|
||||
// remove module account address if they exist in accs
|
||||
var tmpAccs []Account
|
||||
for _, acc := range accs {
|
||||
if !blackListedAccs[acc.Address.String()] {
|
||||
tmpAccs = append(tmpAccs, acc)
|
||||
}
|
||||
}
|
||||
|
||||
accs = tmpAccs
|
||||
|
||||
nextValidators := validators
|
||||
|
||||
header := abci.Header{
|
||||
|
||||
@ -151,7 +151,7 @@ func (k Keeper) HandleValidatorSignature(ctx sdk.Context, addr crypto.Address, p
|
||||
consAddr := sdk.ConsAddress(addr)
|
||||
pubkey, err := k.getPubkey(ctx, addr)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("Validator consensus-address %v not found", consAddr.String()))
|
||||
panic(fmt.Sprintf("Validator consensus-address %s not found", consAddr))
|
||||
}
|
||||
|
||||
// fetch signing info
|
||||
@ -193,7 +193,8 @@ func (k Keeper) HandleValidatorSignature(ctx sdk.Context, addr crypto.Address, p
|
||||
),
|
||||
)
|
||||
|
||||
logger.Info(fmt.Sprintf("Absent validator %s (%s) at height %d, %d missed, threshold %d", addr, pubkey, height, signInfo.MissedBlocksCounter, k.MinSignedPerWindow(ctx)))
|
||||
logger.Info(
|
||||
fmt.Sprintf("Absent validator %s (%s) at height %d, %d missed, threshold %d", consAddr, pubkey, height, signInfo.MissedBlocksCounter, k.MinSignedPerWindow(ctx)))
|
||||
}
|
||||
|
||||
minHeight := signInfo.StartHeight + k.SignedBlocksWindow(ctx)
|
||||
@ -206,7 +207,7 @@ func (k Keeper) HandleValidatorSignature(ctx sdk.Context, addr crypto.Address, p
|
||||
|
||||
// Downtime confirmed: slash and jail the validator
|
||||
logger.Info(fmt.Sprintf("Validator %s past min height of %d and below signed blocks threshold of %d",
|
||||
sdk.ConsAddress(pubkey.Address()), minHeight, k.MinSignedPerWindow(ctx)))
|
||||
consAddr, minHeight, k.MinSignedPerWindow(ctx)))
|
||||
|
||||
// We need to retrieve the stake distribution which signed the block, so we subtract ValidatorUpdateDelay from the evidence height,
|
||||
// and subtract an additional 1 since this is the LastCommit.
|
||||
@ -235,8 +236,9 @@ func (k Keeper) HandleValidatorSignature(ctx sdk.Context, addr crypto.Address, p
|
||||
k.clearValidatorMissedBlockBitArray(ctx, consAddr)
|
||||
} else {
|
||||
// Validator was (a) not found or (b) already jailed, don't slash
|
||||
logger.Info(fmt.Sprintf("Validator %s would have been slashed for downtime, but was either not found in store or already jailed",
|
||||
sdk.ConsAddress(pubkey.Address())))
|
||||
logger.Info(
|
||||
fmt.Sprintf("Validator %s would have been slashed for downtime, but was either not found in store or already jailed", consAddr),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
177
x/staking/legacy/v0_34/types.go
Normal file
177
x/staking/legacy/v0_34/types.go
Normal file
@ -0,0 +1,177 @@
|
||||
// DONTCOVER
|
||||
// nolint
|
||||
package v0_34
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
const (
|
||||
ModuleName = "staking"
|
||||
)
|
||||
|
||||
type (
|
||||
Pool struct {
|
||||
NotBondedTokens sdk.Int `json:"not_bonded_tokens"`
|
||||
BondedTokens sdk.Int `json:"bonded_tokens"`
|
||||
}
|
||||
|
||||
Params struct {
|
||||
UnbondingTime time.Duration `json:"unbonding_time"`
|
||||
MaxValidators uint16 `json:"max_validators"`
|
||||
MaxEntries uint16 `json:"max_entries"`
|
||||
BondDenom string `json:"bond_denom"`
|
||||
}
|
||||
|
||||
LastValidatorPower struct {
|
||||
Address sdk.ValAddress
|
||||
Power int64
|
||||
}
|
||||
|
||||
Description struct {
|
||||
Moniker string `json:"moniker"`
|
||||
Identity string `json:"identity"`
|
||||
Website string `json:"website"`
|
||||
Details string `json:"details"`
|
||||
}
|
||||
|
||||
Commission struct {
|
||||
CommissionRates CommissionRates `json:"commission_rates"`
|
||||
UpdateTime time.Time `json:"update_time"`
|
||||
}
|
||||
|
||||
CommissionRates struct {
|
||||
Rate sdk.Dec `json:"rate"`
|
||||
MaxRate sdk.Dec `json:"max_rate"`
|
||||
MaxChangeRate sdk.Dec `json:"max_change_rate"`
|
||||
}
|
||||
|
||||
bechValidator struct {
|
||||
OperatorAddress sdk.ValAddress `json:"operator_address"` // the bech32 address of the validator's operator
|
||||
ConsPubKey string `json:"consensus_pubkey"` // the bech32 consensus public key of the validator
|
||||
Jailed bool `json:"jailed"` // has the validator been jailed from bonded status?
|
||||
Status sdk.BondStatus `json:"status"` // validator status (bonded/unbonding/unbonded)
|
||||
Tokens sdk.Int `json:"tokens"` // delegated tokens (incl. self-delegation)
|
||||
DelegatorShares sdk.Dec `json:"delegator_shares"` // total shares issued to a validator's delegators
|
||||
Description Description `json:"description"` // description terms for the validator
|
||||
UnbondingHeight int64 `json:"unbonding_height"` // if unbonding, height at which this validator has begun unbonding
|
||||
UnbondingCompletionTime time.Time `json:"unbonding_time"` // if unbonding, min time for the validator to complete unbonding
|
||||
Commission Commission `json:"commission"` // commission parameters
|
||||
MinSelfDelegation sdk.Int `json:"min_self_delegation"` // minimum self delegation
|
||||
}
|
||||
|
||||
Validator struct {
|
||||
OperatorAddress sdk.ValAddress `json:"operator_address"`
|
||||
ConsPubKey crypto.PubKey `json:"consensus_pubkey"`
|
||||
Jailed bool `json:"jailed"`
|
||||
Status sdk.BondStatus `json:"status"`
|
||||
Tokens sdk.Int `json:"tokens"`
|
||||
DelegatorShares sdk.Dec `json:"delegator_shares"`
|
||||
Description Description `json:"description"`
|
||||
UnbondingHeight int64 `json:"unbonding_height"`
|
||||
UnbondingCompletionTime time.Time `json:"unbonding_time"`
|
||||
Commission Commission `json:"commission"`
|
||||
MinSelfDelegation sdk.Int `json:"min_self_delegation"`
|
||||
}
|
||||
|
||||
Validators []Validator
|
||||
|
||||
Delegation struct {
|
||||
DelegatorAddress sdk.AccAddress `json:"delegator_address"`
|
||||
ValidatorAddress sdk.ValAddress `json:"validator_address"`
|
||||
Shares sdk.Dec `json:"shares"`
|
||||
}
|
||||
|
||||
Delegations []Delegation
|
||||
|
||||
UnbondingDelegationEntry struct {
|
||||
CreationHeight int64 `json:"creation_height"`
|
||||
CompletionTime time.Time `json:"completion_time"`
|
||||
InitialBalance sdk.Int `json:"initial_balance"`
|
||||
Balance sdk.Int `json:"balance"`
|
||||
}
|
||||
|
||||
UnbondingDelegation struct {
|
||||
DelegatorAddress sdk.AccAddress `json:"delegator_address"`
|
||||
ValidatorAddress sdk.ValAddress `json:"validator_address"`
|
||||
Entries []UnbondingDelegationEntry `json:"entries"`
|
||||
}
|
||||
|
||||
RedelegationEntry struct {
|
||||
CreationHeight int64 `json:"creation_height"`
|
||||
CompletionTime time.Time `json:"completion_time"`
|
||||
InitialBalance sdk.Int `json:"initial_balance"`
|
||||
SharesDst sdk.Dec `json:"shares_dst"`
|
||||
}
|
||||
|
||||
Redelegation struct {
|
||||
DelegatorAddress sdk.AccAddress `json:"delegator_address"`
|
||||
ValidatorSrcAddress sdk.ValAddress `json:"validator_src_address"`
|
||||
ValidatorDstAddress sdk.ValAddress `json:"validator_dst_address"`
|
||||
Entries []RedelegationEntry `json:"entries"`
|
||||
}
|
||||
|
||||
GenesisState struct {
|
||||
Pool Pool `json:"pool"`
|
||||
Params Params `json:"params"`
|
||||
LastTotalPower sdk.Int `json:"last_total_power"`
|
||||
LastValidatorPowers []LastValidatorPower `json:"last_validator_powers"`
|
||||
Validators Validators `json:"validators"`
|
||||
Delegations Delegations `json:"delegations"`
|
||||
UnbondingDelegations []UnbondingDelegation `json:"unbonding_delegations"`
|
||||
Redelegations []Redelegation `json:"redelegations"`
|
||||
Exported bool `json:"exported"`
|
||||
}
|
||||
)
|
||||
|
||||
func (v Validator) MarshalJSON() ([]byte, error) {
|
||||
bechConsPubKey, err := sdk.Bech32ifyConsPub(v.ConsPubKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return codec.Cdc.MarshalJSON(bechValidator{
|
||||
OperatorAddress: v.OperatorAddress,
|
||||
ConsPubKey: bechConsPubKey,
|
||||
Jailed: v.Jailed,
|
||||
Status: v.Status,
|
||||
Tokens: v.Tokens,
|
||||
DelegatorShares: v.DelegatorShares,
|
||||
Description: v.Description,
|
||||
UnbondingHeight: v.UnbondingHeight,
|
||||
UnbondingCompletionTime: v.UnbondingCompletionTime,
|
||||
MinSelfDelegation: v.MinSelfDelegation,
|
||||
Commission: v.Commission,
|
||||
})
|
||||
}
|
||||
|
||||
// UnmarshalJSON unmarshals the validator from JSON using Bech32
|
||||
func (v *Validator) UnmarshalJSON(data []byte) error {
|
||||
bv := &bechValidator{}
|
||||
if err := codec.Cdc.UnmarshalJSON(data, bv); err != nil {
|
||||
return err
|
||||
}
|
||||
consPubKey, err := sdk.GetConsPubKeyBech32(bv.ConsPubKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*v = Validator{
|
||||
OperatorAddress: bv.OperatorAddress,
|
||||
ConsPubKey: consPubKey,
|
||||
Jailed: bv.Jailed,
|
||||
Tokens: bv.Tokens,
|
||||
Status: bv.Status,
|
||||
DelegatorShares: bv.DelegatorShares,
|
||||
Description: bv.Description,
|
||||
UnbondingHeight: bv.UnbondingHeight,
|
||||
UnbondingCompletionTime: bv.UnbondingCompletionTime,
|
||||
Commission: bv.Commission,
|
||||
MinSelfDelegation: bv.MinSelfDelegation,
|
||||
}
|
||||
return nil
|
||||
}
|
||||
23
x/staking/legacy/v0_36/migrate.go
Normal file
23
x/staking/legacy/v0_36/migrate.go
Normal file
@ -0,0 +1,23 @@
|
||||
// DONTCOVER
|
||||
// nolint
|
||||
package v0_36
|
||||
|
||||
import (
|
||||
v034staking "github.com/cosmos/cosmos-sdk/x/staking/legacy/v0_34"
|
||||
)
|
||||
|
||||
// Migrate accepts exported genesis state from v0.34 and migrates it to v0.36
|
||||
// genesis state. All entries are identical except for validator slashing events
|
||||
// which now include the period.
|
||||
func Migrate(oldGenState v034staking.GenesisState) GenesisState {
|
||||
return NewGenesisState(
|
||||
oldGenState.Params,
|
||||
oldGenState.LastTotalPower,
|
||||
oldGenState.LastValidatorPowers,
|
||||
oldGenState.Validators,
|
||||
oldGenState.Delegations,
|
||||
oldGenState.UnbondingDelegations,
|
||||
oldGenState.Redelegations,
|
||||
oldGenState.Exported,
|
||||
)
|
||||
}
|
||||
44
x/staking/legacy/v0_36/types.go
Normal file
44
x/staking/legacy/v0_36/types.go
Normal file
@ -0,0 +1,44 @@
|
||||
// DONTCOVER
|
||||
// nolint
|
||||
package v0_36
|
||||
|
||||
import (
|
||||
v034staking "github.com/cosmos/cosmos-sdk/x/staking/legacy/v0_34"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
const (
|
||||
ModuleName = "staking"
|
||||
)
|
||||
|
||||
type (
|
||||
GenesisState struct {
|
||||
Params v034staking.Params `json:"params"`
|
||||
LastTotalPower sdk.Int `json:"last_total_power"`
|
||||
LastValidatorPowers []v034staking.LastValidatorPower `json:"last_validator_powers"`
|
||||
Validators v034staking.Validators `json:"validators"`
|
||||
Delegations v034staking.Delegations `json:"delegations"`
|
||||
UnbondingDelegations []v034staking.UnbondingDelegation `json:"unbonding_delegations"`
|
||||
Redelegations []v034staking.Redelegation `json:"redelegations"`
|
||||
Exported bool `json:"exported"`
|
||||
}
|
||||
)
|
||||
|
||||
func NewGenesisState(
|
||||
params v034staking.Params, lastTotalPower sdk.Int, lastValPowers []v034staking.LastValidatorPower,
|
||||
validators v034staking.Validators, delegations v034staking.Delegations,
|
||||
ubds []v034staking.UnbondingDelegation, reds []v034staking.Redelegation, exported bool,
|
||||
) GenesisState {
|
||||
|
||||
return GenesisState{
|
||||
Params: params,
|
||||
LastTotalPower: lastTotalPower,
|
||||
LastValidatorPowers: lastValPowers,
|
||||
Validators: validators,
|
||||
Delegations: delegations,
|
||||
UnbondingDelegations: ubds,
|
||||
Redelegations: reds,
|
||||
Exported: exported,
|
||||
}
|
||||
}
|
||||
@ -159,7 +159,7 @@ func SimulateMsgUndelegate(m auth.AccountKeeper, k staking.Keeper) simulation.Op
|
||||
return simulation.NoOpMsg(), nil, nil
|
||||
}
|
||||
|
||||
msg := staking.NewMsgDelegate(
|
||||
msg := staking.NewMsgUndelegate(
|
||||
delegatorAddress, delegation.ValidatorAddress, sdk.NewCoin(k.GetParams(ctx).BondDenom, unbondAmt),
|
||||
)
|
||||
if msg.ValidateBasic() != nil {
|
||||
|
||||
@ -8,12 +8,12 @@ import (
|
||||
|
||||
// names used as root for pool module accounts:
|
||||
//
|
||||
// - NotBondedPool -> "NotBondedTokensPool"
|
||||
// - NotBondedPool -> "not_bonded_tokens_pool"
|
||||
//
|
||||
// - BondedPool -> "BondedTokensPool"
|
||||
// - BondedPool -> "bonded_tokens_pool"
|
||||
const (
|
||||
NotBondedPoolName = "NotBondedTokensPool"
|
||||
BondedPoolName = "BondedTokensPool"
|
||||
NotBondedPoolName = "not_bonded_tokens_pool"
|
||||
BondedPoolName = "bonded_tokens_pool"
|
||||
)
|
||||
|
||||
// Pool - tracking bonded and not-bonded token supply of the bond denomination
|
||||
|
||||
@ -7,6 +7,8 @@ import (
|
||||
)
|
||||
|
||||
// InitGenesis sets supply information for genesis.
|
||||
//
|
||||
// CONTRACT: all types of accounts must have been already initialized/created
|
||||
func InitGenesis(ctx sdk.Context, keeper Keeper, ak types.AccountKeeper, data GenesisState) {
|
||||
// manually set the total supply based on accounts if not provided
|
||||
if data.Supply.Total.Empty() {
|
||||
|
||||
@ -73,8 +73,7 @@ func (k Keeper) UndelegateCoinsFromModuleToAccount(ctx sdk.Context, senderModule
|
||||
recipientAddr sdk.AccAddress, amt sdk.Coins) sdk.Error {
|
||||
|
||||
acc := k.GetModuleAccount(ctx, senderModule)
|
||||
senderAddr := acc.GetAddress()
|
||||
if senderAddr == nil {
|
||||
if acc == nil {
|
||||
return sdk.ErrUnknownAddress(fmt.Sprintf("module account %s does not exist", senderModule))
|
||||
}
|
||||
|
||||
@ -82,7 +81,7 @@ func (k Keeper) UndelegateCoinsFromModuleToAccount(ctx sdk.Context, senderModule
|
||||
panic(fmt.Sprintf("module account %s does not have permissions to undelegate coins", senderModule))
|
||||
}
|
||||
|
||||
return k.bk.UndelegateCoins(ctx, senderAddr, recipientAddr, amt)
|
||||
return k.bk.UndelegateCoins(ctx, acc.GetAddress(), recipientAddr, amt)
|
||||
}
|
||||
|
||||
// MintCoins creates new coins from thin air and adds it to the module account.
|
||||
@ -95,13 +94,11 @@ func (k Keeper) MintCoins(ctx sdk.Context, moduleName string, amt sdk.Coins) sdk
|
||||
return sdk.ErrUnknownAddress(fmt.Sprintf("module account %s does not exist", moduleName))
|
||||
}
|
||||
|
||||
addr := acc.GetAddress()
|
||||
|
||||
if !acc.HasPermission(types.Minter) {
|
||||
panic(fmt.Sprintf("module account %s does not have permissions to mint tokens", moduleName))
|
||||
}
|
||||
|
||||
_, err := k.bk.AddCoins(ctx, addr, amt)
|
||||
_, err := k.bk.AddCoins(ctx, acc.GetAddress(), amt)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@ -121,9 +118,9 @@ func (k Keeper) MintCoins(ctx sdk.Context, moduleName string, amt sdk.Coins) sdk
|
||||
// Panics if the name maps to a non-burner module account or if the amount is invalid.
|
||||
func (k Keeper) BurnCoins(ctx sdk.Context, moduleName string, amt sdk.Coins) sdk.Error {
|
||||
|
||||
// create the account if it doesn't yet exist
|
||||
acc := k.GetModuleAccount(ctx, moduleName)
|
||||
addr := acc.GetAddress()
|
||||
if addr == nil {
|
||||
if acc == nil {
|
||||
return sdk.ErrUnknownAddress(fmt.Sprintf("module account %s does not exist", moduleName))
|
||||
}
|
||||
|
||||
@ -131,7 +128,7 @@ func (k Keeper) BurnCoins(ctx sdk.Context, moduleName string, amt sdk.Coins) sdk
|
||||
panic(fmt.Sprintf("module account %s does not have permissions to burn tokens", moduleName))
|
||||
}
|
||||
|
||||
_, err := k.bk.SubtractCoins(ctx, addr, amt)
|
||||
_, err := k.bk.SubtractCoins(ctx, acc.GetAddress(), amt)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
@ -118,7 +118,7 @@ func TestBurnCoins(t *testing.T) {
|
||||
initialSupply.Inflate(initCoins)
|
||||
keeper.SetSupply(ctx, initialSupply)
|
||||
|
||||
require.Panics(t, func() { keeper.BurnCoins(ctx, "", initCoins) }, "no module account")
|
||||
require.Error(t, keeper.BurnCoins(ctx, "", initCoins), "no module account")
|
||||
require.Panics(t, func() { keeper.BurnCoins(ctx, types.Minter, initCoins) }, "invalid permission")
|
||||
require.Panics(t, func() { keeper.BurnCoins(ctx, randomPerm, initialSupply.Total) }, "random permission")
|
||||
require.Panics(t, func() { keeper.BurnCoins(ctx, types.Burner, initialSupply.Total) }, "insufficient coins")
|
||||
|
||||
@ -9,7 +9,7 @@ import (
|
||||
|
||||
// Supply represents a struct that passively keeps track of the total supply amounts in the network
|
||||
type Supply struct {
|
||||
Total sdk.Coins `json:"total_supply" yaml:"total_supply"` // total supply of tokens registered on the chain
|
||||
Total sdk.Coins `json:"total" yaml:"total"` // total supply of tokens registered on the chain
|
||||
}
|
||||
|
||||
// NewSupply creates a new Supply instance
|
||||
|
||||
@ -21,7 +21,7 @@ func TestSupplyMarshalYAML(t *testing.T) {
|
||||
bzCoins, err := yaml.Marshal(coins)
|
||||
require.NoError(t, err)
|
||||
|
||||
want := fmt.Sprintf(`total_supply:
|
||||
want := fmt.Sprintf(`total:
|
||||
%s`, string(bzCoins))
|
||||
|
||||
require.Equal(t, want, string(bz))
|
||||
|
||||
27
x/supply/legacy/v0_36/types.go
Normal file
27
x/supply/legacy/v0_36/types.go
Normal file
@ -0,0 +1,27 @@
|
||||
// DONTCOVER
|
||||
// nolint
|
||||
package v0_36
|
||||
|
||||
import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
const ModuleName = "supply"
|
||||
|
||||
type (
|
||||
Supply struct {
|
||||
Total sdk.Coins `json:"total"`
|
||||
}
|
||||
|
||||
GenesisState struct {
|
||||
Supply Supply `json:"supply"`
|
||||
}
|
||||
)
|
||||
|
||||
func EmptyGenesisState() GenesisState {
|
||||
return GenesisState{
|
||||
Supply: Supply{
|
||||
Total: sdk.NewCoins(), // leave this empty as it's filled on initialization
|
||||
},
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user