cosmos-sdk/simapp/utils.go

743 lines
26 KiB
Go

//nolint
package simapp
import (
"bytes"
"encoding/binary"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"math/rand"
"time"
"github.com/tendermint/tendermint/crypto"
cmn "github.com/tendermint/tendermint/libs/common"
dbm "github.com/tendermint/tendermint/libs/db"
"github.com/tendermint/tendermint/libs/log"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/tendermint/tendermint/crypto/secp256k1"
tmtypes "github.com/tendermint/tendermint/types"
"github.com/cosmos/cosmos-sdk/baseapp"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth"
"github.com/cosmos/cosmos-sdk/x/bank"
"github.com/cosmos/cosmos-sdk/x/distribution"
"github.com/cosmos/cosmos-sdk/x/genaccounts"
"github.com/cosmos/cosmos-sdk/x/gov"
"github.com/cosmos/cosmos-sdk/x/mint"
"github.com/cosmos/cosmos-sdk/x/simulation"
"github.com/cosmos/cosmos-sdk/x/slashing"
"github.com/cosmos/cosmos-sdk/x/staking"
"github.com/cosmos/cosmos-sdk/x/supply"
)
var (
genesisFile string
paramsFile string
exportParamsPath string
exportParamsHeight int
exportStatePath string
seed int64
numBlocks int
blockSize int
enabled bool
verbose bool
lean bool
commit bool
period int
onOperation bool // TODO Remove in favor of binary search for invariant violation
allInvariants bool
genesisTime int64
)
// NewSimAppUNSAFE is used for debugging purposes only.
//
// NOTE: to not use this function with non-test code
func NewSimAppUNSAFE(logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest bool,
invCheckPeriod uint, baseAppOptions ...func(*baseapp.BaseApp),
) (gapp *SimApp, keyMain, keyStaking *sdk.KVStoreKey, stakingKeeper staking.Keeper) {
gapp = NewSimApp(logger, db, traceStore, loadLatest, invCheckPeriod, baseAppOptions...)
return gapp, gapp.keyMain, gapp.keyStaking, gapp.stakingKeeper
}
// AppStateFromGenesisFileFn util function to generate the genesis AppState
// from a genesis.json file
func AppStateFromGenesisFileFn(
r *rand.Rand, _ []simulation.Account, _ time.Time,
) (json.RawMessage, []simulation.Account, string) {
var genesis tmtypes.GenesisDoc
cdc := MakeCodec()
bytes, err := ioutil.ReadFile(genesisFile)
if err != nil {
panic(err)
}
cdc.MustUnmarshalJSON(bytes, &genesis)
var appState GenesisState
cdc.MustUnmarshalJSON(genesis.AppState, &appState)
accounts := genaccounts.GetGenesisStateFromAppState(cdc, appState)
var newAccs []simulation.Account
for _, acc := range accounts {
// Pick a random private key, since we don't know the actual key
// This should be fine as it's only used for mock Tendermint validators
// and these keys are never actually used to sign by mock Tendermint.
privkeySeed := make([]byte, 15)
r.Read(privkeySeed)
privKey := secp256k1.GenPrivKeySecp256k1(privkeySeed)
newAccs = append(newAccs, simulation.Account{privKey, privKey.PubKey(), acc.Address})
}
return genesis.AppState, newAccs, genesis.ChainID
}
// GenAuthGenesisState generates a random GenesisState for auth
func GenAuthGenesisState(cdc *codec.Codec, r *rand.Rand, ap simulation.AppParams, genesisState map[string]json.RawMessage) {
authGenesis := auth.NewGenesisState(
auth.NewParams(
func(r *rand.Rand) uint64 {
var v uint64
ap.GetOrGenerate(cdc, simulation.MaxMemoChars, &v, r,
func(r *rand.Rand) {
v = simulation.ModuleParamSimulator[simulation.MaxMemoChars](r).(uint64)
})
return v
}(r),
func(r *rand.Rand) uint64 {
var v uint64
ap.GetOrGenerate(cdc, simulation.TxSigLimit, &v, r,
func(r *rand.Rand) {
v = simulation.ModuleParamSimulator[simulation.TxSigLimit](r).(uint64)
})
return v
}(r),
func(r *rand.Rand) uint64 {
var v uint64
ap.GetOrGenerate(cdc, simulation.TxSizeCostPerByte, &v, r,
func(r *rand.Rand) {
v = simulation.ModuleParamSimulator[simulation.TxSizeCostPerByte](r).(uint64)
})
return v
}(r),
func(r *rand.Rand) uint64 {
var v uint64
ap.GetOrGenerate(cdc, simulation.SigVerifyCostED25519, &v, r,
func(r *rand.Rand) {
v = simulation.ModuleParamSimulator[simulation.SigVerifyCostED25519](r).(uint64)
})
return v
}(r),
func(r *rand.Rand) uint64 {
var v uint64
ap.GetOrGenerate(cdc, simulation.SigVerifyCostSECP256K1, &v, r,
func(r *rand.Rand) {
v = simulation.ModuleParamSimulator[simulation.SigVerifyCostSECP256K1](r).(uint64)
})
return v
}(r),
),
)
fmt.Printf("Selected randomly generated auth parameters:\n%s\n", codec.MustMarshalJSONIndent(cdc, authGenesis.Params))
genesisState[auth.ModuleName] = cdc.MustMarshalJSON(authGenesis)
}
// GenBankGenesisState generates a random GenesisState for bank
func GenBankGenesisState(cdc *codec.Codec, r *rand.Rand, ap simulation.AppParams, genesisState map[string]json.RawMessage) {
bankGenesis := bank.NewGenesisState(
func(r *rand.Rand) bool {
var v bool
ap.GetOrGenerate(cdc, simulation.SendEnabled, &v, r,
func(r *rand.Rand) {
v = simulation.ModuleParamSimulator[simulation.SendEnabled](r).(bool)
})
return v
}(r),
)
fmt.Printf("Selected randomly generated bank parameters:\n%s\n", codec.MustMarshalJSONIndent(cdc, bankGenesis))
genesisState[bank.ModuleName] = cdc.MustMarshalJSON(bankGenesis)
}
// GenSupplyGenesisState generates a random GenesisState for supply
func GenSupplyGenesisState(cdc *codec.Codec, amount, numInitiallyBonded, numAccs int64, genesisState map[string]json.RawMessage) {
totalSupply := sdk.NewInt(amount * (numAccs + numInitiallyBonded))
supplyGenesis := supply.NewGenesisState(
supply.NewSupply(sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, totalSupply))),
)
fmt.Printf("Generated supply parameters:\n%s\n", codec.MustMarshalJSONIndent(cdc, supplyGenesis))
genesisState[supply.ModuleName] = cdc.MustMarshalJSON(supplyGenesis)
}
// GenGenesisAccounts generates a random GenesisState for the genesis accounts
func GenGenesisAccounts(
cdc *codec.Codec, r *rand.Rand, accs []simulation.Account,
genesisTimestamp time.Time, amount, numInitiallyBonded int64,
genesisState map[string]json.RawMessage,
) {
var genesisAccounts []genaccounts.GenesisAccount
// randomly generate some genesis accounts
for i, acc := range accs {
coins := sdk.Coins{sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(amount))}
bacc := auth.NewBaseAccountWithAddress(acc.Address)
bacc.SetCoins(coins)
var gacc genaccounts.GenesisAccount
// Only consider making a vesting account once the initial bonded validator
// set is exhausted due to needing to track DelegatedVesting.
if int64(i) > numInitiallyBonded && r.Intn(100) < 50 {
var (
vacc auth.VestingAccount
endTime int64
)
startTime := genesisTimestamp.Unix()
// Allow for some vesting accounts to vest very quickly while others very slowly.
if r.Intn(100) < 50 {
endTime = int64(simulation.RandIntBetween(r, int(startTime), int(startTime+(60*60*24*30))))
} else {
endTime = int64(simulation.RandIntBetween(r, int(startTime), int(startTime+(60*60*12))))
}
if startTime == endTime {
endTime++
}
if r.Intn(100) < 50 {
vacc = auth.NewContinuousVestingAccount(&bacc, startTime, endTime)
} else {
vacc = auth.NewDelayedVestingAccount(&bacc, endTime)
}
var err error
gacc, err = genaccounts.NewGenesisAccountI(vacc)
if err != nil {
panic(err)
}
} else {
gacc = genaccounts.NewGenesisAccount(&bacc)
}
genesisAccounts = append(genesisAccounts, gacc)
}
genesisState[genaccounts.ModuleName] = cdc.MustMarshalJSON(genesisAccounts)
}
// GenGovGenesisState generates a random GenesisState for gov
func GenGovGenesisState(cdc *codec.Codec, r *rand.Rand, ap simulation.AppParams, genesisState map[string]json.RawMessage) {
var vp time.Duration
ap.GetOrGenerate(cdc, simulation.VotingParamsVotingPeriod, &vp, r,
func(r *rand.Rand) {
vp = simulation.ModuleParamSimulator[simulation.VotingParamsVotingPeriod](r).(time.Duration)
})
govGenesis := gov.NewGenesisState(
uint64(r.Intn(100)),
gov.NewDepositParams(
func(r *rand.Rand) sdk.Coins {
var v sdk.Coins
ap.GetOrGenerate(cdc, simulation.DepositParamsMinDeposit, &v, r,
func(r *rand.Rand) {
v = simulation.ModuleParamSimulator[simulation.DepositParamsMinDeposit](r).(sdk.Coins)
})
return v
}(r),
vp,
),
gov.NewVotingParams(vp),
gov.NewTallyParams(
func(r *rand.Rand) sdk.Dec {
var v sdk.Dec
ap.GetOrGenerate(cdc, simulation.TallyParamsQuorum, &v, r,
func(r *rand.Rand) {
v = simulation.ModuleParamSimulator[simulation.TallyParamsQuorum](r).(sdk.Dec)
})
return v
}(r),
func(r *rand.Rand) sdk.Dec {
var v sdk.Dec
ap.GetOrGenerate(cdc, simulation.TallyParamsThreshold, &v, r,
func(r *rand.Rand) {
v = simulation.ModuleParamSimulator[simulation.TallyParamsThreshold](r).(sdk.Dec)
})
return v
}(r),
func(r *rand.Rand) sdk.Dec {
var v sdk.Dec
ap.GetOrGenerate(cdc, simulation.TallyParamsVeto, &v, r,
func(r *rand.Rand) {
v = simulation.ModuleParamSimulator[simulation.TallyParamsVeto](r).(sdk.Dec)
})
return v
}(r),
),
)
fmt.Printf("Selected randomly generated governance parameters:\n%s\n", codec.MustMarshalJSONIndent(cdc, govGenesis))
genesisState[gov.ModuleName] = cdc.MustMarshalJSON(govGenesis)
}
// GenMintGenesisState generates a random GenesisState for mint
func GenMintGenesisState(cdc *codec.Codec, r *rand.Rand, ap simulation.AppParams, genesisState map[string]json.RawMessage) {
mintGenesis := mint.NewGenesisState(
mint.InitialMinter(
func(r *rand.Rand) sdk.Dec {
var v sdk.Dec
ap.GetOrGenerate(cdc, simulation.Inflation, &v, r,
func(r *rand.Rand) {
v = simulation.ModuleParamSimulator[simulation.Inflation](r).(sdk.Dec)
})
return v
}(r),
),
mint.NewParams(
sdk.DefaultBondDenom,
func(r *rand.Rand) sdk.Dec {
var v sdk.Dec
ap.GetOrGenerate(cdc, simulation.InflationRateChange, &v, r,
func(r *rand.Rand) {
v = simulation.ModuleParamSimulator[simulation.InflationRateChange](r).(sdk.Dec)
})
return v
}(r),
func(r *rand.Rand) sdk.Dec {
var v sdk.Dec
ap.GetOrGenerate(cdc, simulation.InflationMax, &v, r,
func(r *rand.Rand) {
v = simulation.ModuleParamSimulator[simulation.InflationMax](r).(sdk.Dec)
})
return v
}(r),
func(r *rand.Rand) sdk.Dec {
var v sdk.Dec
ap.GetOrGenerate(cdc, simulation.InflationMin, &v, r,
func(r *rand.Rand) {
v = simulation.ModuleParamSimulator[simulation.InflationMin](r).(sdk.Dec)
})
return v
}(r),
func(r *rand.Rand) sdk.Dec {
var v sdk.Dec
ap.GetOrGenerate(cdc, simulation.GoalBonded, &v, r,
func(r *rand.Rand) {
v = simulation.ModuleParamSimulator[simulation.GoalBonded](r).(sdk.Dec)
})
return v
}(r),
uint64(60*60*8766/5),
),
)
fmt.Printf("Selected randomly generated minting parameters:\n%s\n", codec.MustMarshalJSONIndent(cdc, mintGenesis.Params))
genesisState[mint.ModuleName] = cdc.MustMarshalJSON(mintGenesis)
}
// GenDistrGenesisState generates a random GenesisState for distribution
func GenDistrGenesisState(cdc *codec.Codec, r *rand.Rand, ap simulation.AppParams, genesisState map[string]json.RawMessage) {
distrGenesis := distribution.GenesisState{
FeePool: distribution.InitialFeePool(),
CommunityTax: func(r *rand.Rand) sdk.Dec {
var v sdk.Dec
ap.GetOrGenerate(cdc, simulation.CommunityTax, &v, r,
func(r *rand.Rand) {
v = simulation.ModuleParamSimulator[simulation.CommunityTax](r).(sdk.Dec)
})
return v
}(r),
BaseProposerReward: func(r *rand.Rand) sdk.Dec {
var v sdk.Dec
ap.GetOrGenerate(cdc, simulation.BaseProposerReward, &v, r,
func(r *rand.Rand) {
v = simulation.ModuleParamSimulator[simulation.BaseProposerReward](r).(sdk.Dec)
})
return v
}(r),
BonusProposerReward: func(r *rand.Rand) sdk.Dec {
var v sdk.Dec
ap.GetOrGenerate(cdc, simulation.BonusProposerReward, &v, r,
func(r *rand.Rand) {
v = simulation.ModuleParamSimulator[simulation.BonusProposerReward](r).(sdk.Dec)
})
return v
}(r),
}
fmt.Printf("Selected randomly generated distribution parameters:\n%s\n", codec.MustMarshalJSONIndent(cdc, distrGenesis))
genesisState[distribution.ModuleName] = cdc.MustMarshalJSON(distrGenesis)
}
// GenSlashingGenesisState generates a random GenesisState for slashing
func GenSlashingGenesisState(
cdc *codec.Codec, r *rand.Rand, stakingGen staking.GenesisState,
ap simulation.AppParams, genesisState map[string]json.RawMessage,
) {
slashingGenesis := slashing.NewGenesisState(
slashing.NewParams(
stakingGen.Params.UnbondingTime,
func(r *rand.Rand) int64 {
var v int64
ap.GetOrGenerate(cdc, simulation.SignedBlocksWindow, &v, r,
func(r *rand.Rand) {
v = simulation.ModuleParamSimulator[simulation.SignedBlocksWindow](r).(int64)
})
return v
}(r),
func(r *rand.Rand) sdk.Dec {
var v sdk.Dec
ap.GetOrGenerate(cdc, simulation.MinSignedPerWindow, &v, r,
func(r *rand.Rand) {
v = simulation.ModuleParamSimulator[simulation.MinSignedPerWindow](r).(sdk.Dec)
})
return v
}(r),
func(r *rand.Rand) time.Duration {
var v time.Duration
ap.GetOrGenerate(cdc, simulation.DowntimeJailDuration, &v, r,
func(r *rand.Rand) {
v = simulation.ModuleParamSimulator[simulation.DowntimeJailDuration](r).(time.Duration)
})
return v
}(r),
func(r *rand.Rand) sdk.Dec {
var v sdk.Dec
ap.GetOrGenerate(cdc, simulation.SlashFractionDoubleSign, &v, r,
func(r *rand.Rand) {
v = simulation.ModuleParamSimulator[simulation.SlashFractionDoubleSign](r).(sdk.Dec)
})
return v
}(r),
func(r *rand.Rand) sdk.Dec {
var v sdk.Dec
ap.GetOrGenerate(cdc, simulation.SlashFractionDowntime, &v, r,
func(r *rand.Rand) {
v = simulation.ModuleParamSimulator[simulation.SlashFractionDowntime](r).(sdk.Dec)
})
return v
}(r),
),
nil,
nil,
)
fmt.Printf("Selected randomly generated slashing parameters:\n%s\n", codec.MustMarshalJSONIndent(cdc, slashingGenesis.Params))
genesisState[slashing.ModuleName] = cdc.MustMarshalJSON(slashingGenesis)
}
// GenStakingGenesisState generates a random GenesisState for staking
func GenStakingGenesisState(
cdc *codec.Codec, r *rand.Rand, accs []simulation.Account, amount, numAccs, numInitiallyBonded int64,
ap simulation.AppParams, genesisState map[string]json.RawMessage,
) staking.GenesisState {
stakingGenesis := staking.NewGenesisState(
staking.NewParams(
func(r *rand.Rand) time.Duration {
var v time.Duration
ap.GetOrGenerate(cdc, simulation.UnbondingTime, &v, r,
func(r *rand.Rand) {
v = simulation.ModuleParamSimulator[simulation.UnbondingTime](r).(time.Duration)
})
return v
}(r),
func(r *rand.Rand) uint16 {
var v uint16
ap.GetOrGenerate(cdc, simulation.MaxValidators, &v, r,
func(r *rand.Rand) {
v = simulation.ModuleParamSimulator[simulation.MaxValidators](r).(uint16)
})
return v
}(r),
7,
sdk.DefaultBondDenom,
),
nil,
nil,
)
var (
validators []staking.Validator
delegations []staking.Delegation
)
valAddrs := make([]sdk.ValAddress, numInitiallyBonded)
for i := 0; i < int(numInitiallyBonded); i++ {
valAddr := sdk.ValAddress(accs[i].Address)
valAddrs[i] = valAddr
validator := staking.NewValidator(valAddr, accs[i].PubKey, staking.Description{})
validator.Tokens = sdk.NewInt(amount)
validator.DelegatorShares = sdk.NewDec(amount)
delegation := staking.NewDelegation(accs[i].Address, valAddr, sdk.NewDec(amount))
validators = append(validators, validator)
delegations = append(delegations, delegation)
}
stakingGenesis.Validators = validators
stakingGenesis.Delegations = delegations
fmt.Printf("Selected randomly generated staking parameters:\n%s\n", codec.MustMarshalJSONIndent(cdc, stakingGenesis.Params))
genesisState[staking.ModuleName] = cdc.MustMarshalJSON(stakingGenesis)
return stakingGenesis
}
// GetSimulationLog unmarshals the KVPair's Value to the corresponding type based on the
// each's module store key and the prefix bytes of the KVPair's key.
func GetSimulationLog(storeName string, cdcA, cdcB *codec.Codec, kvs []cmn.KVPair) (log string) {
var kvA, kvB cmn.KVPair
for i := 0; i < len(kvs); i += 2 {
kvA = kvs[i]
kvB = kvs[i+1]
if len(kvA.Value) == 0 && len(kvB.Value) == 0 {
// skip if the value doesn't have any bytes
continue
}
switch storeName {
case auth.StoreKey:
log += DecodeAccountStore(cdcA, cdcB, kvA, kvB)
case mint.StoreKey:
log += DecodeMintStore(cdcA, cdcB, kvA, kvB)
case staking.StoreKey:
log += DecodeStakingStore(cdcA, cdcB, kvA, kvB)
case slashing.StoreKey:
log += DecodeSlashingStore(cdcA, cdcB, kvA, kvB)
case gov.StoreKey:
log += DecodeGovStore(cdcA, cdcB, kvA, kvB)
case distribution.StoreKey:
log += DecodeDistributionStore(cdcA, cdcB, kvA, kvB)
case supply.StoreKey:
log += DecodeSupplyStore(cdcA, cdcB, kvA, kvB)
default:
log += fmt.Sprintf("store A %X => %X\nstore B %X => %X\n", kvA.Key, kvA.Value, kvB.Key, kvB.Value)
}
}
return
}
// DecodeAccountStore unmarshals the KVPair's Value to the corresponding auth type
func DecodeAccountStore(cdcA, cdcB *codec.Codec, kvA, kvB cmn.KVPair) string {
switch {
case bytes.Equal(kvA.Key[:1], auth.AddressStoreKeyPrefix):
var accA, accB auth.Account
cdcA.MustUnmarshalBinaryBare(kvA.Value, &accA)
cdcB.MustUnmarshalBinaryBare(kvB.Value, &accB)
return fmt.Sprintf("%v\n%v", accA, accB)
case bytes.Equal(kvA.Key, auth.GlobalAccountNumberKey):
var globalAccNumberA, globalAccNumberB uint64
cdcA.MustUnmarshalBinaryLengthPrefixed(kvA.Value, &globalAccNumberA)
cdcB.MustUnmarshalBinaryLengthPrefixed(kvB.Value, &globalAccNumberB)
return fmt.Sprintf("GlobalAccNumberA: %d\nGlobalAccNumberB: %d", globalAccNumberA, globalAccNumberB)
default:
panic(fmt.Sprintf("invalid account key %X", kvA.Key))
}
}
// DecodeMintStore unmarshals the KVPair's Value to the corresponding mint type
func DecodeMintStore(cdcA, cdcB *codec.Codec, kvA, kvB cmn.KVPair) string {
switch {
case bytes.Equal(kvA.Key, mint.MinterKey):
var minterA, minterB mint.Minter
cdcA.MustUnmarshalBinaryLengthPrefixed(kvA.Value, &minterA)
cdcB.MustUnmarshalBinaryLengthPrefixed(kvB.Value, &minterB)
return fmt.Sprintf("%v\n%v", minterA, minterB)
default:
panic(fmt.Sprintf("invalid mint key %X", kvA.Key))
}
}
// DecodeDistributionStore unmarshals the KVPair's Value to the corresponding distribution type
func DecodeDistributionStore(cdcA, cdcB *codec.Codec, kvA, kvB cmn.KVPair) string {
switch {
case bytes.Equal(kvA.Key[:1], distribution.FeePoolKey):
var feePoolA, feePoolB distribution.FeePool
cdcA.MustUnmarshalBinaryLengthPrefixed(kvA.Value, &feePoolA)
cdcB.MustUnmarshalBinaryLengthPrefixed(kvB.Value, &feePoolB)
return fmt.Sprintf("%v\n%v", feePoolA, feePoolB)
case bytes.Equal(kvA.Key[:1], distribution.ProposerKey):
return fmt.Sprintf("%v\n%v", sdk.ConsAddress(kvA.Value), sdk.ConsAddress(kvB.Value))
case bytes.Equal(kvA.Key[:1], distribution.ValidatorOutstandingRewardsPrefix):
var rewardsA, rewardsB distribution.ValidatorOutstandingRewards
cdcA.MustUnmarshalBinaryLengthPrefixed(kvA.Value, &rewardsA)
cdcB.MustUnmarshalBinaryLengthPrefixed(kvB.Value, &rewardsB)
return fmt.Sprintf("%v\n%v", rewardsA, rewardsB)
case bytes.Equal(kvA.Key[:1], distribution.DelegatorWithdrawAddrPrefix):
return fmt.Sprintf("%v\n%v", sdk.AccAddress(kvA.Value), sdk.AccAddress(kvB.Value))
case bytes.Equal(kvA.Key[:1], distribution.DelegatorStartingInfoPrefix):
var infoA, infoB distribution.DelegatorStartingInfo
cdcA.MustUnmarshalBinaryLengthPrefixed(kvA.Value, &infoA)
cdcB.MustUnmarshalBinaryLengthPrefixed(kvB.Value, &infoB)
return fmt.Sprintf("%v\n%v", infoA, infoB)
case bytes.Equal(kvA.Key[:1], distribution.ValidatorHistoricalRewardsPrefix):
var rewardsA, rewardsB distribution.ValidatorHistoricalRewards
cdcA.MustUnmarshalBinaryLengthPrefixed(kvA.Value, &rewardsA)
cdcB.MustUnmarshalBinaryLengthPrefixed(kvB.Value, &rewardsB)
return fmt.Sprintf("%v\n%v", rewardsA, rewardsB)
case bytes.Equal(kvA.Key[:1], distribution.ValidatorCurrentRewardsPrefix):
var rewardsA, rewardsB distribution.ValidatorCurrentRewards
cdcA.MustUnmarshalBinaryLengthPrefixed(kvA.Value, &rewardsA)
cdcB.MustUnmarshalBinaryLengthPrefixed(kvB.Value, &rewardsB)
return fmt.Sprintf("%v\n%v", rewardsA, rewardsB)
case bytes.Equal(kvA.Key[:1], distribution.ValidatorAccumulatedCommissionPrefix):
var commissionA, commissionB distribution.ValidatorAccumulatedCommission
cdcA.MustUnmarshalBinaryLengthPrefixed(kvA.Value, &commissionA)
cdcB.MustUnmarshalBinaryLengthPrefixed(kvB.Value, &commissionB)
return fmt.Sprintf("%v\n%v", commissionA, commissionB)
case bytes.Equal(kvA.Key[:1], distribution.ValidatorSlashEventPrefix):
var eventA, eventB distribution.ValidatorSlashEvent
cdcA.MustUnmarshalBinaryLengthPrefixed(kvA.Value, &eventA)
cdcB.MustUnmarshalBinaryLengthPrefixed(kvB.Value, &eventB)
return fmt.Sprintf("%v\n%v", eventA, eventB)
default:
panic(fmt.Sprintf("invalid distribution key prefix %X", kvA.Key[:1]))
}
}
// DecodeStakingStore unmarshals the KVPair's Value to the corresponding staking type
func DecodeStakingStore(cdcA, cdcB *codec.Codec, kvA, kvB cmn.KVPair) string {
switch {
case bytes.Equal(kvA.Key[:1], staking.LastTotalPowerKey):
var powerA, powerB sdk.Int
cdcA.MustUnmarshalBinaryLengthPrefixed(kvA.Value, &powerA)
cdcB.MustUnmarshalBinaryLengthPrefixed(kvB.Value, &powerB)
return fmt.Sprintf("%v\n%v", powerA, powerB)
case bytes.Equal(kvA.Key[:1], staking.ValidatorsKey):
var validatorA, validatorB staking.Validator
cdcA.MustUnmarshalBinaryLengthPrefixed(kvA.Value, &validatorA)
cdcB.MustUnmarshalBinaryLengthPrefixed(kvB.Value, &validatorB)
return fmt.Sprintf("%v\n%v", validatorA, validatorB)
case bytes.Equal(kvA.Key[:1], staking.LastValidatorPowerKey),
bytes.Equal(kvA.Key[:1], staking.ValidatorsByConsAddrKey),
bytes.Equal(kvA.Key[:1], staking.ValidatorsByPowerIndexKey):
return fmt.Sprintf("%v\n%v", sdk.ValAddress(kvA.Value), sdk.ValAddress(kvB.Value))
case bytes.Equal(kvA.Key[:1], staking.DelegationKey):
var delegationA, delegationB staking.Delegation
cdcA.MustUnmarshalBinaryLengthPrefixed(kvA.Value, &delegationA)
cdcB.MustUnmarshalBinaryLengthPrefixed(kvB.Value, &delegationB)
return fmt.Sprintf("%v\n%v", delegationA, delegationB)
case bytes.Equal(kvA.Key[:1], staking.UnbondingDelegationKey),
bytes.Equal(kvA.Key[:1], staking.UnbondingDelegationByValIndexKey):
var ubdA, ubdB staking.UnbondingDelegation
cdcA.MustUnmarshalBinaryLengthPrefixed(kvA.Value, &ubdA)
cdcB.MustUnmarshalBinaryLengthPrefixed(kvB.Value, &ubdB)
return fmt.Sprintf("%v\n%v", ubdA, ubdB)
case bytes.Equal(kvA.Key[:1], staking.RedelegationKey),
bytes.Equal(kvA.Key[:1], staking.RedelegationByValSrcIndexKey):
var redA, redB staking.Redelegation
cdcA.MustUnmarshalBinaryLengthPrefixed(kvA.Value, &redA)
cdcB.MustUnmarshalBinaryLengthPrefixed(kvB.Value, &redB)
return fmt.Sprintf("%v\n%v", redA, redB)
default:
panic(fmt.Sprintf("invalid staking key prefix %X", kvA.Key[:1]))
}
}
// DecodeSlashingStore unmarshals the KVPair's Value to the corresponding slashing type
func DecodeSlashingStore(cdcA, cdcB *codec.Codec, kvA, kvB cmn.KVPair) string {
switch {
case bytes.Equal(kvA.Key[:1], slashing.ValidatorSigningInfoKey):
var infoA, infoB slashing.ValidatorSigningInfo
cdcA.MustUnmarshalBinaryLengthPrefixed(kvA.Value, &infoA)
cdcB.MustUnmarshalBinaryLengthPrefixed(kvB.Value, &infoB)
return fmt.Sprintf("%v\n%v", infoA, infoB)
case bytes.Equal(kvA.Key[:1], slashing.ValidatorMissedBlockBitArrayKey):
var missedA, missedB bool
cdcA.MustUnmarshalBinaryLengthPrefixed(kvA.Value, &missedA)
cdcB.MustUnmarshalBinaryLengthPrefixed(kvB.Value, &missedB)
return fmt.Sprintf("missedA: %v\nmissedB: %v", missedA, missedB)
case bytes.Equal(kvA.Key[:1], slashing.AddrPubkeyRelationKey):
var pubKeyA, pubKeyB crypto.PubKey
cdcA.MustUnmarshalBinaryLengthPrefixed(kvA.Value, &pubKeyA)
cdcB.MustUnmarshalBinaryLengthPrefixed(kvB.Value, &pubKeyB)
bechPKA := sdk.MustBech32ifyAccPub(pubKeyA)
bechPKB := sdk.MustBech32ifyAccPub(pubKeyB)
return fmt.Sprintf("PubKeyA: %s\nPubKeyB: %s", bechPKA, bechPKB)
default:
panic(fmt.Sprintf("invalid slashing key prefix %X", kvA.Key[:1]))
}
}
// DecodeGovStore unmarshals the KVPair's Value to the corresponding gov type
func DecodeGovStore(cdcA, cdcB *codec.Codec, kvA, kvB cmn.KVPair) string {
switch {
case bytes.Equal(kvA.Key[:1], gov.ProposalsKeyPrefix):
var proposalA, proposalB gov.Proposal
cdcA.MustUnmarshalBinaryLengthPrefixed(kvA.Value, &proposalA)
cdcB.MustUnmarshalBinaryLengthPrefixed(kvB.Value, &proposalB)
return fmt.Sprintf("%v\n%v", proposalA, proposalB)
case bytes.Equal(kvA.Key[:1], gov.ActiveProposalQueuePrefix),
bytes.Equal(kvA.Key[:1], gov.InactiveProposalQueuePrefix),
bytes.Equal(kvA.Key[:1], gov.ProposalIDKey):
proposalIDA := binary.LittleEndian.Uint64(kvA.Value)
proposalIDB := binary.LittleEndian.Uint64(kvB.Value)
return fmt.Sprintf("proposalIDA: %d\nProposalIDB: %d", proposalIDA, proposalIDB)
case bytes.Equal(kvA.Key[:1], gov.DepositsKeyPrefix):
var depositA, depositB gov.Deposit
cdcA.MustUnmarshalBinaryLengthPrefixed(kvA.Value, &depositA)
cdcB.MustUnmarshalBinaryLengthPrefixed(kvB.Value, &depositB)
return fmt.Sprintf("%v\n%v", depositA, depositB)
case bytes.Equal(kvA.Key[:1], gov.VotesKeyPrefix):
var voteA, voteB gov.Vote
cdcA.MustUnmarshalBinaryLengthPrefixed(kvA.Value, &voteA)
cdcB.MustUnmarshalBinaryLengthPrefixed(kvB.Value, &voteB)
return fmt.Sprintf("%v\n%v", voteA, voteB)
default:
panic(fmt.Sprintf("invalid governance key prefix %X", kvA.Key[:1]))
}
}
// DecodeSupplyStore unmarshals the KVPair's Value to the corresponding supply type
func DecodeSupplyStore(cdcA, cdcB *codec.Codec, kvA, kvB cmn.KVPair) string {
switch {
case bytes.Equal(kvA.Key[:1], supply.SupplyKey):
var supplyA, supplyB supply.Supply
cdcA.MustUnmarshalBinaryLengthPrefixed(kvA.Value, &supplyA)
cdcB.MustUnmarshalBinaryLengthPrefixed(kvB.Value, &supplyB)
return fmt.Sprintf("%v\n%v", supplyB, supplyB)
default:
panic(fmt.Sprintf("invalid supply key %X", kvA.Key))
}
}