Improve Import/Export Simulation Errors (#4607)
This commit is contained in:
parent
f9dea984c2
commit
4a0fbb3d6e
|
@ -27,6 +27,7 @@ mytestnet
|
|||
# Testing
|
||||
coverage.txt
|
||||
profile.out
|
||||
sim_log_file
|
||||
|
||||
# Vagrant
|
||||
.vagrant/
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
#4535 Improve import-export simulation errors by decoding the `KVPair.Value` into its
|
||||
respective type
|
|
@ -930,10 +930,7 @@ func TestAppImportExport(t *testing.T) {
|
|||
storeB := ctxB.KVStore(storeKeyB)
|
||||
kvA, kvB, count, equal := sdk.DiffKVStores(storeA, storeB, prefixes)
|
||||
fmt.Printf("Compared %d key/value pairs between %s and %s\n", count, storeKeyA, storeKeyB)
|
||||
require.True(t, equal,
|
||||
"unequal stores: %s / %s:\nstore A %X => %X\nstore B %X => %X",
|
||||
storeKeyA, storeKeyB, kvA.Key, kvA.Value, kvB.Key, kvB.Value,
|
||||
)
|
||||
require.True(t, equal, getSimulationLog(storeKeyA.Name(), app.cdc, newApp.cdc, kvA, kvB))
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
package simapp
|
||||
|
||||
import (
|
||||
"io"
|
||||
|
||||
dbm "github.com/tendermint/tendermint/libs/db"
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
|
||||
bam "github.com/cosmos/cosmos-sdk/baseapp"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/staking"
|
||||
)
|
||||
|
||||
// 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(*bam.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
|
||||
}
|
|
@ -0,0 +1,256 @@
|
|||
//nolint
|
||||
package simapp
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
cmn "github.com/tendermint/tendermint/libs/common"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
dbm "github.com/tendermint/tendermint/libs/db"
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
|
||||
bam "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/distribution"
|
||||
"github.com/cosmos/cosmos-sdk/x/gov"
|
||||
"github.com/cosmos/cosmos-sdk/x/mint"
|
||||
"github.com/cosmos/cosmos-sdk/x/slashing"
|
||||
"github.com/cosmos/cosmos-sdk/x/staking"
|
||||
)
|
||||
|
||||
// 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(*bam.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
|
||||
}
|
||||
|
||||
// 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, kvA, kvB cmn.KVPair) (log string) {
|
||||
log = fmt.Sprintf("store A %X => %X\nstore B %X => %X\n", kvA.Key, kvA.Value, kvB.Key, kvB.Value)
|
||||
|
||||
if len(kvA.Value) == 0 && len(kvB.Value) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
switch storeName {
|
||||
case auth.StoreKey:
|
||||
return decodeAccountStore(cdcA, cdcB, kvA, kvB)
|
||||
case mint.StoreKey:
|
||||
return decodeMintStore(cdcA, cdcB, kvA, kvB)
|
||||
case staking.StoreKey:
|
||||
return decodeStakingStore(cdcA, cdcB, kvA, kvB)
|
||||
case slashing.StoreKey:
|
||||
return decodeSlashingStore(cdcA, cdcB, kvA, kvB)
|
||||
case gov.StoreKey:
|
||||
return decodeGovStore(cdcA, cdcB, kvA, kvB)
|
||||
case distribution.StoreKey:
|
||||
return decodeDistributionStore(cdcA, cdcB, kvA, kvB)
|
||||
default:
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
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))
|
||||
}
|
||||
}
|
||||
|
||||
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))
|
||||
}
|
||||
}
|
||||
|
||||
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]))
|
||||
}
|
||||
}
|
||||
|
||||
func decodeStakingStore(cdcA, cdcB *codec.Codec, kvA, kvB cmn.KVPair) string {
|
||||
switch {
|
||||
case bytes.Equal(kvA.Key[:1], staking.PoolKey):
|
||||
var poolA, poolB staking.Pool
|
||||
cdcA.MustUnmarshalBinaryLengthPrefixed(kvA.Value, &poolA)
|
||||
cdcB.MustUnmarshalBinaryLengthPrefixed(kvB.Value, &poolB)
|
||||
return fmt.Sprintf("%v\n%v", poolA, poolB)
|
||||
|
||||
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]))
|
||||
}
|
||||
}
|
||||
|
||||
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]))
|
||||
}
|
||||
}
|
||||
|
||||
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]))
|
||||
}
|
||||
}
|
|
@ -0,0 +1,304 @@
|
|||
package simapp
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
"github.com/tendermint/tendermint/crypto/ed25519"
|
||||
cmn "github.com/tendermint/tendermint/libs/common"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||
"github.com/cosmos/cosmos-sdk/x/distribution"
|
||||
distr "github.com/cosmos/cosmos-sdk/x/distribution"
|
||||
"github.com/cosmos/cosmos-sdk/x/gov"
|
||||
"github.com/cosmos/cosmos-sdk/x/mint"
|
||||
"github.com/cosmos/cosmos-sdk/x/slashing"
|
||||
"github.com/cosmos/cosmos-sdk/x/staking"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
var (
|
||||
delPk1 = ed25519.GenPrivKey().PubKey()
|
||||
delAddr1 = sdk.AccAddress(delPk1.Address())
|
||||
valAddr1 = sdk.ValAddress(delPk1.Address())
|
||||
consAddr1 = sdk.ConsAddress(delPk1.Address().Bytes())
|
||||
)
|
||||
|
||||
func makeTestCodec() (cdc *codec.Codec) {
|
||||
cdc = codec.New()
|
||||
sdk.RegisterCodec(cdc)
|
||||
codec.RegisterCrypto(cdc)
|
||||
auth.RegisterCodec(cdc)
|
||||
distr.RegisterCodec(cdc)
|
||||
gov.RegisterCodec(cdc)
|
||||
staking.RegisterCodec(cdc)
|
||||
return
|
||||
}
|
||||
|
||||
func TestGetSimulationLog(t *testing.T) {
|
||||
cdc := makeTestCodec()
|
||||
|
||||
tests := []struct {
|
||||
store string
|
||||
kvPair cmn.KVPair
|
||||
}{
|
||||
{auth.StoreKey, cmn.KVPair{Key: auth.AddressStoreKey(delAddr1), Value: cdc.MustMarshalBinaryBare(auth.BaseAccount{})}},
|
||||
{mint.StoreKey, cmn.KVPair{Key: mint.MinterKey, Value: cdc.MustMarshalBinaryLengthPrefixed(mint.Minter{})}},
|
||||
{staking.StoreKey, cmn.KVPair{Key: staking.LastValidatorPowerKey, Value: valAddr1.Bytes()}},
|
||||
{gov.StoreKey, cmn.KVPair{Key: gov.VoteKey(1, delAddr1), Value: cdc.MustMarshalBinaryLengthPrefixed(gov.Vote{})}},
|
||||
{distribution.StoreKey, cmn.KVPair{Key: distr.ProposerKey, Value: consAddr1.Bytes()}},
|
||||
{slashing.StoreKey, cmn.KVPair{Key: slashing.GetValidatorMissedBlockBitArrayKey(consAddr1, 6), Value: cdc.MustMarshalBinaryLengthPrefixed(true)}},
|
||||
{"Empty", cmn.KVPair{}},
|
||||
{"OtherStore", cmn.KVPair{Key: []byte("key"), Value: []byte("value")}},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.store, func(t *testing.T) {
|
||||
require.NotPanics(t, func() { getSimulationLog(tt.store, cdc, cdc, tt.kvPair, tt.kvPair) }, tt.store)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecodeAccountStore(t *testing.T) {
|
||||
cdc := makeTestCodec()
|
||||
acc := auth.NewBaseAccountWithAddress(delAddr1)
|
||||
globalAccNumber := uint64(10)
|
||||
|
||||
kvPairs := cmn.KVPairs{
|
||||
cmn.KVPair{Key: auth.AddressStoreKey(delAddr1), Value: cdc.MustMarshalBinaryBare(acc)},
|
||||
cmn.KVPair{Key: auth.GlobalAccountNumberKey, Value: cdc.MustMarshalBinaryLengthPrefixed(globalAccNumber)},
|
||||
cmn.KVPair{Key: []byte{0x99}, Value: []byte{0x99}},
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
expectedLog string
|
||||
}{
|
||||
{"Minter", fmt.Sprintf("%v\n%v", acc, acc)},
|
||||
{"GlobalAccNumber", fmt.Sprintf("GlobalAccNumberA: %d\nGlobalAccNumberB: %d", globalAccNumber, globalAccNumber)},
|
||||
{"other", ""},
|
||||
}
|
||||
|
||||
for i, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
switch i {
|
||||
case len(tests) - 1:
|
||||
require.Panics(t, func() { decodeAccountStore(cdc, cdc, kvPairs[i], kvPairs[i]) }, tt.name)
|
||||
default:
|
||||
require.Equal(t, tt.expectedLog, decodeAccountStore(cdc, cdc, kvPairs[i], kvPairs[i]), tt.name)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecodeMintStore(t *testing.T) {
|
||||
cdc := makeTestCodec()
|
||||
minter := mint.NewMinter(sdk.OneDec(), sdk.NewDec(15))
|
||||
|
||||
kvPairs := cmn.KVPairs{
|
||||
cmn.KVPair{Key: mint.MinterKey, Value: cdc.MustMarshalBinaryLengthPrefixed(minter)},
|
||||
cmn.KVPair{Key: []byte{0x99}, Value: []byte{0x99}},
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
expectedLog string
|
||||
}{
|
||||
{"Minter", fmt.Sprintf("%v\n%v", minter, minter)},
|
||||
{"other", ""},
|
||||
}
|
||||
|
||||
for i, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
switch i {
|
||||
case len(tests) - 1:
|
||||
require.Panics(t, func() { decodeMintStore(cdc, cdc, kvPairs[i], kvPairs[i]) }, tt.name)
|
||||
default:
|
||||
require.Equal(t, tt.expectedLog, decodeMintStore(cdc, cdc, kvPairs[i], kvPairs[i]), tt.name)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecodeDistributionStore(t *testing.T) {
|
||||
cdc := makeTestCodec()
|
||||
|
||||
decCoins := sdk.DecCoins{sdk.NewDecCoinFromDec(sdk.DefaultBondDenom, sdk.OneDec())}
|
||||
feePool := distr.InitialFeePool()
|
||||
feePool.CommunityPool = decCoins
|
||||
info := distr.NewDelegatorStartingInfo(2, sdk.OneDec(), 200)
|
||||
outstanding := distr.ValidatorOutstandingRewards{decCoins[0]}
|
||||
commission := distr.ValidatorAccumulatedCommission{decCoins[0]}
|
||||
historicalRewards := distr.NewValidatorHistoricalRewards(decCoins, 100)
|
||||
currentRewards := distr.NewValidatorCurrentRewards(decCoins, 5)
|
||||
slashEvent := distr.NewValidatorSlashEvent(10, sdk.OneDec())
|
||||
|
||||
kvPairs := cmn.KVPairs{
|
||||
cmn.KVPair{Key: distr.FeePoolKey, Value: cdc.MustMarshalBinaryLengthPrefixed(feePool)},
|
||||
cmn.KVPair{Key: distr.ProposerKey, Value: consAddr1.Bytes()},
|
||||
cmn.KVPair{Key: distr.GetValidatorOutstandingRewardsKey(valAddr1), Value: cdc.MustMarshalBinaryLengthPrefixed(outstanding)},
|
||||
cmn.KVPair{Key: distr.GetDelegatorWithdrawAddrKey(delAddr1), Value: delAddr1.Bytes()},
|
||||
cmn.KVPair{Key: distr.GetDelegatorStartingInfoKey(valAddr1, delAddr1), Value: cdc.MustMarshalBinaryLengthPrefixed(info)},
|
||||
cmn.KVPair{Key: distr.GetValidatorHistoricalRewardsKey(valAddr1, 100), Value: cdc.MustMarshalBinaryLengthPrefixed(historicalRewards)},
|
||||
cmn.KVPair{Key: distr.GetValidatorCurrentRewardsKey(valAddr1), Value: cdc.MustMarshalBinaryLengthPrefixed(currentRewards)},
|
||||
cmn.KVPair{Key: distr.GetValidatorAccumulatedCommissionKey(valAddr1), Value: cdc.MustMarshalBinaryLengthPrefixed(commission)},
|
||||
cmn.KVPair{Key: distr.GetValidatorSlashEventKey(valAddr1, 13), Value: cdc.MustMarshalBinaryLengthPrefixed(slashEvent)},
|
||||
cmn.KVPair{Key: []byte{0x99}, Value: []byte{0x99}},
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
expectedLog string
|
||||
}{
|
||||
{"FeePool", fmt.Sprintf("%v\n%v", feePool, feePool)},
|
||||
{"Proposer", fmt.Sprintf("%v\n%v", consAddr1, consAddr1)},
|
||||
{"ValidatorOutstandingRewards", fmt.Sprintf("%v\n%v", outstanding, outstanding)},
|
||||
{"DelegatorWithdrawAddr", fmt.Sprintf("%v\n%v", delAddr1, delAddr1)},
|
||||
{"DelegatorStartingInfo", fmt.Sprintf("%v\n%v", info, info)},
|
||||
{"ValidatorHistoricalRewards", fmt.Sprintf("%v\n%v", historicalRewards, historicalRewards)},
|
||||
{"ValidatorCurrentRewards", fmt.Sprintf("%v\n%v", currentRewards, currentRewards)},
|
||||
{"ValidatorAccumulatedCommission", fmt.Sprintf("%v\n%v", commission, commission)},
|
||||
{"ValidatorSlashEvent", fmt.Sprintf("%v\n%v", slashEvent, slashEvent)},
|
||||
{"other", ""},
|
||||
}
|
||||
for i, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
switch i {
|
||||
case len(tests) - 1:
|
||||
require.Panics(t, func() { decodeDistributionStore(cdc, cdc, kvPairs[i], kvPairs[i]) }, tt.name)
|
||||
default:
|
||||
require.Equal(t, tt.expectedLog, decodeDistributionStore(cdc, cdc, kvPairs[i], kvPairs[i]), tt.name)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecodeStakingStore(t *testing.T) {
|
||||
cdc := makeTestCodec()
|
||||
|
||||
bondTime := time.Now().UTC()
|
||||
|
||||
pool := staking.InitialPool()
|
||||
val := staking.NewValidator(valAddr1, delPk1, staking.NewDescription("test", "test", "test", "test"))
|
||||
del := staking.NewDelegation(delAddr1, valAddr1, sdk.OneDec())
|
||||
ubd := staking.NewUnbondingDelegation(delAddr1, valAddr1, 15, bondTime, sdk.OneInt())
|
||||
red := staking.NewRedelegation(delAddr1, valAddr1, valAddr1, 12, bondTime, sdk.OneInt(), sdk.OneDec())
|
||||
|
||||
kvPairs := cmn.KVPairs{
|
||||
cmn.KVPair{Key: staking.PoolKey, Value: cdc.MustMarshalBinaryLengthPrefixed(pool)},
|
||||
cmn.KVPair{Key: staking.LastTotalPowerKey, Value: cdc.MustMarshalBinaryLengthPrefixed(sdk.OneInt())},
|
||||
cmn.KVPair{Key: staking.GetValidatorKey(valAddr1), Value: cdc.MustMarshalBinaryLengthPrefixed(val)},
|
||||
cmn.KVPair{Key: staking.LastValidatorPowerKey, Value: valAddr1.Bytes()},
|
||||
cmn.KVPair{Key: staking.GetDelegationKey(delAddr1, valAddr1), Value: cdc.MustMarshalBinaryLengthPrefixed(del)},
|
||||
cmn.KVPair{Key: staking.GetUBDKey(delAddr1, valAddr1), Value: cdc.MustMarshalBinaryLengthPrefixed(ubd)},
|
||||
cmn.KVPair{Key: staking.GetREDKey(delAddr1, valAddr1, valAddr1), Value: cdc.MustMarshalBinaryLengthPrefixed(red)},
|
||||
cmn.KVPair{Key: []byte{0x99}, Value: []byte{0x99}},
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
expectedLog string
|
||||
}{
|
||||
{"Pool", fmt.Sprintf("%v\n%v", pool, pool)},
|
||||
{"LastTotalPower", fmt.Sprintf("%v\n%v", sdk.OneInt(), sdk.OneInt())},
|
||||
{"Validator", fmt.Sprintf("%v\n%v", val, val)},
|
||||
{"LastValidatorPower/ValidatorsByConsAddr/ValidatorsByPowerIndex", fmt.Sprintf("%v\n%v", valAddr1, valAddr1)},
|
||||
{"Delegation", fmt.Sprintf("%v\n%v", del, del)},
|
||||
{"UnbondingDelegation", fmt.Sprintf("%v\n%v", ubd, ubd)},
|
||||
{"Redelegation", fmt.Sprintf("%v\n%v", red, red)},
|
||||
{"other", ""},
|
||||
}
|
||||
for i, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
switch i {
|
||||
case len(tests) - 1:
|
||||
require.Panics(t, func() { decodeStakingStore(cdc, cdc, kvPairs[i], kvPairs[i]) }, tt.name)
|
||||
default:
|
||||
require.Equal(t, tt.expectedLog, decodeStakingStore(cdc, cdc, kvPairs[i], kvPairs[i]), tt.name)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecodeSlashingStore(t *testing.T) {
|
||||
cdc := makeTestCodec()
|
||||
|
||||
info := slashing.NewValidatorSigningInfo(consAddr1, 0, 1, time.Now().UTC(), false, 0)
|
||||
bechPK := sdk.MustBech32ifyAccPub(delPk1)
|
||||
missed := true
|
||||
|
||||
kvPairs := cmn.KVPairs{
|
||||
cmn.KVPair{Key: slashing.GetValidatorSigningInfoKey(consAddr1), Value: cdc.MustMarshalBinaryLengthPrefixed(info)},
|
||||
cmn.KVPair{Key: slashing.GetValidatorMissedBlockBitArrayKey(consAddr1, 6), Value: cdc.MustMarshalBinaryLengthPrefixed(missed)},
|
||||
cmn.KVPair{Key: slashing.GetAddrPubkeyRelationKey(delAddr1), Value: cdc.MustMarshalBinaryLengthPrefixed(delPk1)},
|
||||
cmn.KVPair{Key: []byte{0x99}, Value: []byte{0x99}},
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
expectedLog string
|
||||
}{
|
||||
{"ValidatorSigningInfo", fmt.Sprintf("%v\n%v", info, info)},
|
||||
{"ValidatorMissedBlockBitArray", fmt.Sprintf("missedA: %v\nmissedB: %v", missed, missed)},
|
||||
{"AddrPubkeyRelation", fmt.Sprintf("PubKeyA: %s\nPubKeyB: %s", bechPK, bechPK)},
|
||||
{"other", ""},
|
||||
}
|
||||
for i, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
switch i {
|
||||
case len(tests) - 1:
|
||||
require.Panics(t, func() { decodeSlashingStore(cdc, cdc, kvPairs[i], kvPairs[i]) }, tt.name)
|
||||
default:
|
||||
require.Equal(t, tt.expectedLog, decodeSlashingStore(cdc, cdc, kvPairs[i], kvPairs[i]), tt.name)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecodeGovStore(t *testing.T) {
|
||||
cdc := makeTestCodec()
|
||||
|
||||
endTime := time.Now().UTC()
|
||||
|
||||
content := gov.ContentFromProposalType("test", "test", gov.ProposalTypeText)
|
||||
proposal := gov.NewProposal(content, 1, endTime, endTime.Add(24*time.Hour))
|
||||
proposalIDBz := make([]byte, 8)
|
||||
binary.LittleEndian.PutUint64(proposalIDBz, 1)
|
||||
deposit := gov.NewDeposit(1, delAddr1, sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.OneInt())))
|
||||
vote := gov.NewVote(1, delAddr1, gov.OptionYes)
|
||||
|
||||
kvPairs := cmn.KVPairs{
|
||||
cmn.KVPair{Key: gov.ProposalKey(1), Value: cdc.MustMarshalBinaryLengthPrefixed(proposal)},
|
||||
cmn.KVPair{Key: gov.InactiveProposalQueueKey(1, endTime), Value: proposalIDBz},
|
||||
cmn.KVPair{Key: gov.DepositKey(1, delAddr1), Value: cdc.MustMarshalBinaryLengthPrefixed(deposit)},
|
||||
cmn.KVPair{Key: gov.VoteKey(1, delAddr1), Value: cdc.MustMarshalBinaryLengthPrefixed(vote)},
|
||||
cmn.KVPair{Key: []byte{0x99}, Value: []byte{0x99}},
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
expectedLog string
|
||||
}{
|
||||
{"proposals", fmt.Sprintf("%v\n%v", proposal, proposal)},
|
||||
{"proposal IDs", "proposalIDA: 1\nProposalIDB: 1"},
|
||||
{"deposits", fmt.Sprintf("%v\n%v", deposit, deposit)},
|
||||
{"votes", fmt.Sprintf("%v\n%v", vote, vote)},
|
||||
{"other", ""},
|
||||
}
|
||||
|
||||
for i, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
switch i {
|
||||
case len(tests) - 1:
|
||||
require.Panics(t, func() { decodeGovStore(cdc, cdc, kvPairs[i], kvPairs[i]) }, tt.name)
|
||||
default:
|
||||
require.Equal(t, tt.expectedLog, decodeGovStore(cdc, cdc, kvPairs[i], kvPairs[i]), tt.name)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -12,7 +12,26 @@ const (
|
|||
DefaultParamspace = types.ModuleName
|
||||
)
|
||||
|
||||
// keys
|
||||
// Keys for distribution store
|
||||
// Items are stored with the following key: values
|
||||
//
|
||||
// - 0x00<proposalID_Bytes>: FeePol
|
||||
//
|
||||
// - 0x01: sdk.ConsAddress
|
||||
//
|
||||
// - 0x02<valAddr_Bytes>: ValidatorOutstandingRewards
|
||||
//
|
||||
// - 0x03<accAddr_Bytes>: sdk.AccAddress
|
||||
//
|
||||
// - 0x04<valAddr_Bytes><accAddr_Bytes>: DelegatorStartingInfo
|
||||
//
|
||||
// - 0x05<valAddr_Bytes><period_Bytes>: ValidatorHistoricalRewards
|
||||
//
|
||||
// - 0x06<valAddr_Bytes>: ValidatorCurrentRewards
|
||||
//
|
||||
// - 0x07<valAddr_Bytes>: ValidatorCurrentRewards
|
||||
//
|
||||
// - 0x08<valAddr_Bytes><height>: ValidatorSlashEvent
|
||||
var (
|
||||
FeePoolKey = []byte{0x00} // key for global distribution state
|
||||
ProposerKey = []byte{0x01} // key for the proposer operator address
|
||||
|
|
|
@ -46,8 +46,6 @@ var (
|
|||
GetValidatorSigningInfoAddress = types.GetValidatorSigningInfoAddress
|
||||
GetValidatorMissedBlockBitArrayPrefixKey = types.GetValidatorMissedBlockBitArrayPrefixKey
|
||||
GetValidatorMissedBlockBitArrayKey = types.GetValidatorMissedBlockBitArrayKey
|
||||
GetValidatorSlashingPeriodPrefix = types.GetValidatorSlashingPeriodPrefix
|
||||
GetValidatorSlashingPeriodKey = types.GetValidatorSlashingPeriodKey
|
||||
GetAddrPubkeyRelationKey = types.GetAddrPubkeyRelationKey
|
||||
NewMsgUnjail = types.NewMsgUnjail
|
||||
ParamKeyTable = types.ParamKeyTable
|
||||
|
@ -61,7 +59,6 @@ var (
|
|||
ModuleCdc = types.ModuleCdc
|
||||
ValidatorSigningInfoKey = types.ValidatorSigningInfoKey
|
||||
ValidatorMissedBlockBitArrayKey = types.ValidatorMissedBlockBitArrayKey
|
||||
ValidatorSlashingPeriodKey = types.ValidatorSlashingPeriodKey
|
||||
AddrPubkeyRelationKey = types.AddrPubkeyRelationKey
|
||||
DoubleSignJailEndTime = types.DoubleSignJailEndTime
|
||||
DefaultMinSignedPerWindow = types.DefaultMinSignedPerWindow
|
||||
|
|
|
@ -27,12 +27,18 @@ const (
|
|||
QuerySigningInfos = "signingInfos"
|
||||
)
|
||||
|
||||
// key prefix bytes
|
||||
// Keys for slashing store
|
||||
// Items are stored with the following key: values
|
||||
//
|
||||
// - 0x01<consAddress_Bytes>: ValidatorSigningInfo
|
||||
//
|
||||
// - 0x02<consAddress_Bytes><period_Bytes>: bool
|
||||
//
|
||||
// - 0x03<accAddr_Bytes>: crypto.PubKey
|
||||
var (
|
||||
ValidatorSigningInfoKey = []byte{0x01} // Prefix for signing info
|
||||
ValidatorMissedBlockBitArrayKey = []byte{0x02} // Prefix for missed block bit array
|
||||
ValidatorSlashingPeriodKey = []byte{0x03} // Prefix for slashing period
|
||||
AddrPubkeyRelationKey = []byte{0x04} // Prefix for address-pubkey relation
|
||||
AddrPubkeyRelationKey = []byte{0x03} // Prefix for address-pubkey relation
|
||||
)
|
||||
|
||||
// stored by *Consensus* address (not operator address)
|
||||
|
@ -61,19 +67,6 @@ func GetValidatorMissedBlockBitArrayKey(v sdk.ConsAddress, i int64) []byte {
|
|||
return append(GetValidatorMissedBlockBitArrayPrefixKey(v), b...)
|
||||
}
|
||||
|
||||
// stored by *Consensus* address (not operator address)
|
||||
func GetValidatorSlashingPeriodPrefix(v sdk.ConsAddress) []byte {
|
||||
return append(ValidatorSlashingPeriodKey, v.Bytes()...)
|
||||
}
|
||||
|
||||
// stored by *Consensus* address (not operator address) followed by start height
|
||||
func GetValidatorSlashingPeriodKey(v sdk.ConsAddress, startHeight int64) []byte {
|
||||
b := make([]byte, 8)
|
||||
// this needs to be height + ValidatorUpdateDelay because the slashing period for genesis validators starts at height -ValidatorUpdateDelay
|
||||
binary.BigEndian.PutUint64(b, uint64(startHeight+sdk.ValidatorUpdateDelay))
|
||||
return append(GetValidatorSlashingPeriodPrefix(v), b...)
|
||||
}
|
||||
|
||||
// get pubkey relation key used to get the pubkey from the address
|
||||
func GetAddrPubkeyRelationKey(address []byte) []byte {
|
||||
return append(AddrPubkeyRelationKey, address...)
|
||||
|
|
Loading…
Reference in New Issue