v0.8 Migration Scripts (#518)

* initial sketch

* add module migrations

* add migrations for all accout types

* test account migration

* add tendermint migration and migrate cmd

* remove need for errors pkg dependency

* add bech32 decoding fork

* add suggested params and cmd to write them

* add basic upgrade instructions

* fix tests

* address some migration todos

* tidy contrib folder

* finalize params values

* align cdp init genesis with other modules

* add tendermint and distribution test
add custom distribution migration to patch bug

* add staking migration test

* add slashing, evidence tests, refactor auth tests

* add full migration test

* remove go-amino dependency from go.mod
also tidy up unused indirect dependencies

* address remaining TODOs

* remove commented out code from legacy types

* add spot/liquidation markets ids to kava-3 params

* Apply suggestions from code review

Co-authored-by: Alexander Bezobchuk <alexanderbez@users.noreply.github.com>
Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com>

* address code review suggestions

* add validate genesis to migrate test

* refactor add params func

* remove commented out code from old types

* fix add params

* add deputy address

* add tests using exported kava-2 state

* incorporate new cdp params from master

* update params from review

Co-authored-by: Kevin Davis <karzak@users.noreply.github.com>

* add deputy account

* add committee permissions for new params

Co-authored-by: Alexander Bezobchuk <alexanderbez@users.noreply.github.com>
Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com>
Co-authored-by: Kevin Davis <karzak@users.noreply.github.com>
This commit is contained in:
Ruaridh 2020-06-03 20:35:00 +01:00 committed by GitHub
parent 2d7f5c4080
commit 4a8b5696cb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
68 changed files with 6046 additions and 12 deletions

View File

@ -24,6 +24,8 @@ import (
"github.com/cosmos/cosmos-sdk/x/staking"
"github.com/kava-labs/kava/app"
kava3 "github.com/kava-labs/kava/contrib/kava-3"
"github.com/kava-labs/kava/migrate"
)
// kvd custom flags
@ -50,7 +52,8 @@ func main() {
rootCmd.AddCommand(
genutilcli.InitCmd(ctx, cdc, app.ModuleBasics, app.DefaultNodeHome),
genutilcli.CollectGenTxsCmd(ctx, cdc, auth.GenesisAccountIterator{}, app.DefaultNodeHome),
genutilcli.MigrateGenesisCmd(ctx, cdc),
migrate.MigrateGenesisCmd(ctx, cdc),
kava3.WriteGenesisParamsCmd(cdc),
genutilcli.GenTxCmd(
ctx,
cdc,

77
contrib/kava-3/cmd.go Normal file
View File

@ -0,0 +1,77 @@
package kava3
import (
"fmt"
"time"
"github.com/spf13/cobra"
tmtypes "github.com/tendermint/tendermint/types"
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/version"
)
const (
defaultChainID = "kava-3"
defaultGenesisTime = "2020-06-01T14:00:00Z"
flagGenesisTime = "genesis-time"
flagChainID = "chain-id"
)
// WriteGenesisParamsCmd returns a command to write suggested kava-3 params to a genesis file.
func WriteGenesisParamsCmd(cdc *codec.Codec) *cobra.Command {
cmd := &cobra.Command{
Use: "write-params [genesis-file]",
Short: "Write suggested params to a genesis file",
Long: "Write suggested module parameters to a gensis file, sort it, and print to STDOUT.",
Example: fmt.Sprintf(`%s write-params /path/to/genesis.json`, version.ServerName),
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
// Unmarshal existing genesis.json
importGenesis := args[0]
genDoc, err := tmtypes.GenesisDocFromFile(importGenesis)
if err != nil {
return fmt.Errorf("failed to read genesis doc from file %s: %w", importGenesis, err)
}
// Unmarshal flags
chainID := cmd.Flag(flagChainID).Value.String()
genesisTime := cmd.Flag(flagGenesisTime).Value.String()
var parsedGenesisTime time.Time
if err := parsedGenesisTime.UnmarshalText([]byte(genesisTime)); err != nil {
return fmt.Errorf("failed to unmarshal genesis time: %w", err)
}
// Write new params to the genesis file
newGenDoc, err := AddSuggestedParams(cdc, *genDoc, chainID, parsedGenesisTime)
if err != nil {
return fmt.Errorf("failed to write params: %w", err)
}
// Marshal output a new genesis file
bz, err := cdc.MarshalJSONIndent(newGenDoc, "", " ")
if err != nil {
return fmt.Errorf("failed to marshal genesis doc: %w", err)
}
sortedBz, err := sdk.SortJSON(bz)
if err != nil {
return fmt.Errorf("failed to sort JSON genesis doc: %w", err)
}
fmt.Println(string(sortedBz))
return nil
},
}
cmd.Flags().String(flagGenesisTime, defaultGenesisTime, "override genesis time")
cmd.Flags().String(flagChainID, defaultChainID, "override chain-id")
return cmd
}

422
contrib/kava-3/params.go Normal file
View File

@ -0,0 +1,422 @@
// kava3 contains the suggested genesis parameters for the kava-3 mainnet.
package kava3
import (
"fmt"
"time"
tmtypes "github.com/tendermint/tendermint/types"
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth"
"github.com/cosmos/cosmos-sdk/x/genutil"
"github.com/cosmos/cosmos-sdk/x/supply"
"github.com/kava-labs/kava/x/auction"
"github.com/kava-labs/kava/x/bep3"
"github.com/kava-labs/kava/x/cdp"
"github.com/kava-labs/kava/x/committee"
"github.com/kava-labs/kava/x/incentive"
"github.com/kava-labs/kava/x/kavadist"
"github.com/kava-labs/kava/x/pricefeed"
)
const (
kavaDenom = "ukava"
bnbDenom = "bnb"
usdxDenom = "usdx"
referenceAsset = "usd"
bnbSpotMarketID = bnbDenom + ":" + referenceAsset
bnbLiquidationMarketID = bnbDenom + ":" + referenceAsset + ":" + "30"
debtDenom = "debt"
deputyAddressBech32 = "kava1r4v2zdhdalfj2ydazallqvrus9fkphmglhn6u6" // Binance deputy address
)
func AddSuggestedParams(cdc *codec.Codec, genDoc tmtypes.GenesisDoc, chainID string, genesisTime time.Time) (tmtypes.GenesisDoc, error) {
// Add tendermint params
genDoc.ChainID = chainID
genDoc.GenesisTime = genesisTime
// Add app params
var appState genutil.AppMap
if err := cdc.UnmarshalJSON(genDoc.AppState, &appState); err != nil {
return tmtypes.GenesisDoc{}, err
}
addAuctionState(cdc, appState)
addBep3DeputyAccount(cdc, appState)
addBep3State(cdc, appState)
addCDPState(cdc, appState)
addCommitteeState(cdc, appState)
addIncentiveState(cdc, appState)
addKavaDistState(cdc, appState)
addPricefeedState(cdc, appState)
marshaledAppState, err := cdc.MarshalJSON(appState)
if err != nil {
return tmtypes.GenesisDoc{}, err
}
genDoc.AppState = marshaledAppState
return genDoc, nil
}
func addBep3DeputyAccount(cdc *codec.Codec, appState genutil.AppMap) {
deputyCoins := sdk.NewCoins(sdk.NewInt64Coin(bnbDenom, 350_000_000_000_000))
// 1) Add account
var authGenState auth.GenesisState
cdc.MustUnmarshalJSON(appState[auth.ModuleName], &authGenState)
authGenState.Accounts = append(
authGenState.Accounts,
auth.NewBaseAccount(
mustAccAddressFromBech32(deputyAddressBech32),
deputyCoins,
nil, // pubkey is nil for new accounts, it's set when the account first sends a tx
0, // account numbers are reset on auth.InitGenesis, so this value doesn't matter
0, // sequence number starts at 0
),
)
appState[auth.ModuleName] = cdc.MustMarshalJSON(authGenState)
// 2) Update total supply
var supplyGenState supply.GenesisState
cdc.MustUnmarshalJSON(appState[supply.ModuleName], &supplyGenState)
supplyGenState.Supply = supplyGenState.Supply.Add(deputyCoins...)
appState[supply.ModuleName] = cdc.MustMarshalJSON(supplyGenState)
}
func addAuctionState(cdc *codec.Codec, appState genutil.AppMap) {
appState[auction.ModuleName] = cdc.MustMarshalJSON(auction.NewGenesisState(
auction.DefaultNextAuctionID,
auction.NewParams(
24*time.Hour,
8*time.Hour,
sdk.MustNewDecFromStr("0.01"),
sdk.MustNewDecFromStr("0.01"),
sdk.MustNewDecFromStr("0.01"),
),
auction.GenesisAuctions{},
))
}
func addBep3State(cdc *codec.Codec, appState genutil.AppMap) {
appState[bep3.ModuleName] = cdc.MustMarshalJSON(bep3.NewGenesisState(
bep3.NewParams(
mustAccAddressFromBech32(deputyAddressBech32),
1000,
bep3.DefaultMinBlockLock,
bep3.DefaultMaxBlockLock,
bep3.AssetParams{{
Denom: bnbDenom,
CoinID: 714,
Limit: sdk.NewInt(4_000_000_000_000),
Active: true,
}},
),
bep3.AtomicSwaps{},
bep3.AssetSupplies{},
))
}
func addCDPState(cdc *codec.Codec, appState genutil.AppMap) {
appState[cdp.ModuleName] = cdc.MustMarshalJSON(cdp.NewGenesisState(
cdp.NewParams(
sdk.NewInt64Coin(usdxDenom, 100_000_000_000),
cdp.CollateralParams{{
Denom: bnbDenom,
LiquidationRatio: sdk.MustNewDecFromStr("1.5"),
DebtLimit: sdk.NewInt64Coin(usdxDenom, 100_000_000_000),
StabilityFee: sdk.MustNewDecFromStr("1.000000001547125958"), // %5 apr
LiquidationPenalty: sdk.MustNewDecFromStr("0.075"),
AuctionSize: sdk.NewInt(50_000_000_000),
Prefix: 0x20,
ConversionFactor: sdk.NewInt(8),
SpotMarketID: bnbSpotMarketID,
LiquidationMarketID: bnbLiquidationMarketID,
}},
cdp.DebtParam{
Denom: usdxDenom,
ReferenceAsset: referenceAsset,
ConversionFactor: sdk.NewInt(6),
DebtFloor: sdk.NewInt(10_000_000),
SavingsRate: sdk.MustNewDecFromStr("0.9"),
},
// below values are usdx coin amounts
sdk.NewInt(200_000_000_000), // surplusThreshold
sdk.NewInt(10_000_000_000), // surplusLot
sdk.NewInt(50_000_000_000), // debtThreshold
sdk.NewInt(10_000_000_000), // debtLot
24*time.Hour,
false,
),
cdp.CDPs{},
cdp.Deposits{},
cdp.DefaultCdpStartingID,
debtDenom,
kavaDenom,
cdp.DefaultPreviousDistributionTime,
))
}
func addCommitteeState(cdc *codec.Codec, appState genutil.AppMap) {
appState[committee.ModuleName] = cdc.MustMarshalJSON(committee.NewGenesisState(
committee.DefaultNextProposalID,
[]committee.Committee{
committee.NewCommittee(
1,
"Kava Stability Committee",
[]sdk.AccAddress{
// addresses from governance proposal: https://ipfs.io/ipfs/QmSiQexKNixztPgLCe2cRSJ8ZLRjetRgzHPDTuBRCm9DZb/committee-nominations.pdf
mustAccAddressFromBech32("kava1gru35up50ql2wxhegr880qy6ynl63ujlv8gum2"),
mustAccAddressFromBech32("kava1sc3mh3pkas5e7xd269am4xm5mp6zweyzmhjagj"),
mustAccAddressFromBech32("kava1c9ye54e3pzwm3e0zpdlel6pnavrj9qqv6e8r4h"),
mustAccAddressFromBech32("kava1m7p6sjqrz6mylz776ct48wj6lpnpcd0z82209d"),
mustAccAddressFromBech32("kava1a9pmkzk570egv3sflu3uwdf3gejl7qfy9hghzl"),
},
[]committee.Permission{
committee.SubParamChangePermission{
AllowedParams: committee.AllowedParams{
{
Subspace: auction.ModuleName,
Key: string(auction.KeyBidDuration),
},
{
Subspace: auction.ModuleName,
Key: string(auction.KeyIncrementSurplus),
},
{
Subspace: auction.ModuleName,
Key: string(auction.KeyIncrementDebt),
},
{
Subspace: auction.ModuleName,
Key: string(auction.KeyIncrementCollateral),
},
{
Subspace: bep3.ModuleName,
Key: string(bep3.KeySupportedAssets),
},
{
Subspace: cdp.ModuleName,
Key: string(cdp.KeyGlobalDebtLimit),
},
{
Subspace: cdp.ModuleName,
Key: string(cdp.KeySurplusThreshold),
},
{
Subspace: cdp.ModuleName,
Key: string(cdp.KeySurplusLot),
},
{
Subspace: cdp.ModuleName,
Key: string(cdp.KeyDebtThreshold),
},
{
Subspace: cdp.ModuleName,
Key: string(cdp.KeyDebtLot),
},
{
Subspace: cdp.ModuleName,
Key: string(cdp.KeyDistributionFrequency),
},
{
Subspace: cdp.ModuleName,
Key: string(cdp.KeyCollateralParams),
},
{
Subspace: cdp.ModuleName,
Key: string(cdp.KeyDebtParam),
},
{
Subspace: incentive.ModuleName,
Key: string(incentive.KeyActive),
},
{
Subspace: kavadist.ModuleName,
Key: string(kavadist.KeyActive),
},
{
Subspace: pricefeed.ModuleName,
Key: string(pricefeed.KeyMarkets),
},
},
AllowedCollateralParams: committee.AllowedCollateralParams{{
Denom: bnbDenom,
LiquidationRatio: false,
DebtLimit: true,
StabilityFee: true,
AuctionSize: true,
LiquidationPenalty: false,
Prefix: false,
SpotMarketID: false,
LiquidationMarketID: false,
ConversionFactor: false,
}},
AllowedDebtParam: committee.AllowedDebtParam{
Denom: false,
ReferenceAsset: false,
ConversionFactor: false,
DebtFloor: true,
SavingsRate: true,
},
AllowedAssetParams: committee.AllowedAssetParams{{
Denom: bnbDenom,
CoinID: false,
Limit: true,
Active: true,
}},
AllowedMarkets: committee.AllowedMarkets{
{
MarketID: bnbSpotMarketID,
BaseAsset: false,
QuoteAsset: false,
Oracles: false,
Active: true,
},
{
MarketID: bnbLiquidationMarketID,
BaseAsset: false,
QuoteAsset: false,
Oracles: false,
Active: true,
},
},
},
committee.TextPermission{},
},
sdk.MustNewDecFromStr("0.5"), // 3 of 5
7*24*time.Hour,
),
committee.NewCommittee(
2,
"Kava Safety Committee",
[]sdk.AccAddress{
// address from governance proposal: https://ipfs.io/ipfs/QmPqfP1Fa8EyzubmctL5uT5TAcWTB7HBQd8pvrmSTG8yS1/safety-nominations.pdf
mustAccAddressFromBech32("kava1e0agyg6eug9r62fly9sls77ycjgw8ax6xk73es"),
},
[]committee.Permission{committee.SoftwareUpgradePermission{}},
sdk.MustNewDecFromStr("0.5"),
7*24*time.Hour,
),
},
[]committee.Proposal{},
[]committee.Vote{},
))
}
func addIncentiveState(cdc *codec.Codec, appState genutil.AppMap) {
appState[incentive.ModuleName] = cdc.MustMarshalJSON(incentive.NewGenesisState(
incentive.NewParams(
true,
incentive.Rewards{incentive.NewReward(
false,
kavaDenom,
sdk.NewInt64Coin(kavaDenom, 74_000_000_000),
1*7*24*time.Hour,
1*365*24*time.Hour,
1*7*24*time.Hour,
)},
),
incentive.DefaultPreviousBlockTime,
incentive.RewardPeriods{},
incentive.ClaimPeriods{},
incentive.Claims{},
incentive.GenesisClaimPeriodIDs{},
))
}
func addKavaDistState(cdc *codec.Codec, appState genutil.AppMap) {
appState[kavadist.ModuleName] = cdc.MustMarshalJSON(kavadist.NewGenesisState(
kavadist.NewParams(
true,
kavadist.Periods{
{
Start: time.Date(2020, 6, 1, 14, 0, 0, 0, time.UTC),
End: time.Date(2021, 6, 1, 14, 0, 0, 0, time.UTC),
Inflation: sdk.MustNewDecFromStr("1.000000004431822130"), // 15%
},
{
Start: time.Date(2021, 6, 1, 14, 0, 0, 0, time.UTC),
End: time.Date(2022, 6, 1, 14, 0, 0, 0, time.UTC),
Inflation: sdk.MustNewDecFromStr("1.000000002293273137"), // 7.5%
},
{
Start: time.Date(2022, 6, 1, 14, 0, 0, 0, time.UTC),
End: time.Date(2023, 6, 1, 14, 0, 0, 0, time.UTC),
Inflation: sdk.MustNewDecFromStr("1.000000001167363430"), // 3.75%
},
{
Start: time.Date(2023, 6, 1, 14, 0, 0, 0, time.UTC),
End: time.Date(2024, 6, 1, 14, 0, 0, 0, time.UTC),
Inflation: sdk.MustNewDecFromStr("1.000000000782997609"), // 2.5%
},
},
),
kavadist.DefaultPreviousBlockTime,
))
}
func addPricefeedState(cdc *codec.Codec, appState genutil.AppMap) {
appState[pricefeed.ModuleName] = cdc.MustMarshalJSON(pricefeed.NewGenesisState(
pricefeed.NewParams(
pricefeed.Markets{
{
MarketID: bnbSpotMarketID,
BaseAsset: bnbDenom,
QuoteAsset: referenceAsset,
Oracles: []sdk.AccAddress{
// addresses from governance proposal: https://ipfs.io/ipfs/QmXgSJ4Dcji8msKpDwYHLmfPSLjRxCEGX6egXQU9DzmFMK/oracle-nominations.pdf
mustAccAddressFromBech32("kava12dyshua9nkvx9w8ywp72wdnzrc4t4mnnycz0dl"),
mustAccAddressFromBech32("kava1tuxyepdrkwraa22k99w04c0wa64tgh70mv87fs"),
mustAccAddressFromBech32("kava1ueak7nzesm3pnev6lngp6lgk0ry02djz8pjpcg"),
mustAccAddressFromBech32("kava1sl62nqm89c780yxm3m9lp3tacmpnfljq6tytvl"),
mustAccAddressFromBech32("kava1ujfrlcd0ted58mzplnyxzklsw0sqevlgxndanp"),
mustAccAddressFromBech32("kava17fatl3wzxvk4rwfu3tqsctdp5x9vute67j9ufj"),
mustAccAddressFromBech32("kava19rjk5qmmwywnzfccwzyn02jywgpwjqf60afj92"),
mustAccAddressFromBech32("kava1xd39avn2f008jmvua0eupg39zsp2xn3wf802vn"),
mustAccAddressFromBech32("kava1pt6q4kdmwawr3thm9cd82pq7hml8u84rd0f3jy"),
mustAccAddressFromBech32("kava13tpwqygswyzupqfggfgh9dmtgthgucn5wpfksh"),
},
Active: true,
},
{
MarketID: bnbLiquidationMarketID,
BaseAsset: bnbDenom,
QuoteAsset: referenceAsset,
Oracles: []sdk.AccAddress{
// addresses from governance proposal: https://ipfs.io/ipfs/QmXgSJ4Dcji8msKpDwYHLmfPSLjRxCEGX6egXQU9DzmFMK/oracle-nominations.pdf
mustAccAddressFromBech32("kava12dyshua9nkvx9w8ywp72wdnzrc4t4mnnycz0dl"),
mustAccAddressFromBech32("kava1tuxyepdrkwraa22k99w04c0wa64tgh70mv87fs"),
mustAccAddressFromBech32("kava1ueak7nzesm3pnev6lngp6lgk0ry02djz8pjpcg"),
mustAccAddressFromBech32("kava1sl62nqm89c780yxm3m9lp3tacmpnfljq6tytvl"),
mustAccAddressFromBech32("kava1ujfrlcd0ted58mzplnyxzklsw0sqevlgxndanp"),
mustAccAddressFromBech32("kava17fatl3wzxvk4rwfu3tqsctdp5x9vute67j9ufj"),
mustAccAddressFromBech32("kava19rjk5qmmwywnzfccwzyn02jywgpwjqf60afj92"),
mustAccAddressFromBech32("kava1xd39avn2f008jmvua0eupg39zsp2xn3wf802vn"),
mustAccAddressFromBech32("kava1pt6q4kdmwawr3thm9cd82pq7hml8u84rd0f3jy"),
mustAccAddressFromBech32("kava13tpwqygswyzupqfggfgh9dmtgthgucn5wpfksh"),
},
Active: true,
},
},
),
pricefeed.PostedPrices{},
))
}
func mustAccAddressFromBech32(addrBech32 string) sdk.AccAddress {
addr, err := sdk.AccAddressFromBech32(addrBech32)
if err != nil {
panic(fmt.Errorf("couldn't decode address: %w", err))
}
return addr
}

View File

@ -0,0 +1,42 @@
package kava3
import (
"path/filepath"
"testing"
"time"
"github.com/stretchr/testify/require"
"github.com/cosmos/cosmos-sdk/x/genutil"
"github.com/kava-labs/kava/app"
"github.com/kava-labs/kava/migrate/v0_8"
v032tendermint "github.com/kava-labs/kava/migrate/v0_8/tendermint/v0_32"
)
func TestAddSuggestedParams(t *testing.T) {
tApp := app.NewTestApp() // also sets the bech32 prefix on sdk.Config
cdc := app.MakeCodec()
// 1) load an exported kava-2 state and migrate to kava v0.8 format (avoids storing v0.8 state that can get out of date)
oldGenDoc, err := v032tendermint.GenesisDocFromFile(filepath.Join("../../migrate/v0_8/testdata", "kava-2.json"))
require.NoError(t, err)
genDoc := v0_8.Migrate(*oldGenDoc)
// 2) add params
newGenDoc, err := AddSuggestedParams(cdc, genDoc, "new-chain-id", time.Date(1998, 1, 0, 0, 0, 0, 0, time.UTC))
require.NoError(t, err)
// 3) check new genesis is valid
var newAppState genutil.AppMap
require.NoError(t,
cdc.UnmarshalJSON(newGenDoc.AppState, &newAppState),
)
require.NoError(t,
app.ModuleBasics.ValidateGenesis(newAppState),
)
require.NotPanics(t, func() {
// this runs both InitGenesis for all modules (which panic on errors) and runs all invariants
tApp.InitializeFromGenesisStates(app.GenesisState(newAppState))
})
}

5
go.mod
View File

@ -3,7 +3,6 @@ module github.com/kava-labs/kava
go 1.13
require (
github.com/btcsuite/btcd v0.20.1-beta // indirect
github.com/cosmos/cosmos-sdk v0.38.4
github.com/gorilla/mux v1.7.3
github.com/spf13/cobra v0.0.6
@ -11,6 +10,8 @@ require (
github.com/stretchr/testify v1.5.1
github.com/tendermint/tendermint v0.33.3
github.com/tendermint/tm-db v0.5.0
golang.org/x/net v0.0.0-20190930134127-c5a3c61f89f3 // indirect
gopkg.in/yaml.v2 v2.2.8
)
// patch bech32 decoding to enable larger string lengths
replace github.com/btcsuite/btcutil => github.com/kava-labs/btcutil v0.0.0-20200522184203-886d33430f06

11
go.sum
View File

@ -37,13 +37,9 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY=
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
github.com/btcsuite/btcd v0.0.0-20190115013929-ed77733ec07d h1:xG8Pj6Y6J760xwETNmMzmlt38QSwz0BLp1cZ09g27uw=
github.com/btcsuite/btcd v0.0.0-20190115013929-ed77733ec07d/go.mod h1:d3C0AkH6BRcvO8T0UEPu53cnw4IbV63x1bEjildYhO0=
github.com/btcsuite/btcd v0.20.1-beta h1:Ik4hyJqN8Jfyv3S4AGBOmyouMsYE3EdYODkMbQjwPGw=
github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ=
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA=
github.com/btcsuite/btcutil v0.0.0-20180706230648-ab6388e0c60a/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg=
github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d h1:yJzD/yFppdVCf6ApMkVy8cUxV0XrxdP9rVf6D87/Mng=
github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg=
github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg=
github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY=
github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc=
@ -228,6 +224,8 @@ github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/u
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/kava-labs/btcutil v0.0.0-20200522184203-886d33430f06 h1:DphTLE0D9kzg1/lSF6VmVTxJrt04IoQq+VuYu1hRFF8=
github.com/kava-labs/btcutil v0.0.0-20200522184203-886d33430f06/go.mod h1:KX8QzQOxPvCErZUQgLdekcoihlDRaU+7teAvwkuPnE8=
github.com/keybase/go-keychain v0.0.0-20190712205309-48d3d31d256d h1:Z+RDyXzjKE0i2sTjZ/b1uxiGtPhFy34Ou/Tk0qwN0kM=
github.com/keybase/go-keychain v0.0.0-20190712205309-48d3d31d256d/go.mod h1:JJNrCn9otv/2QP4D7SMJBgaleKpOf66PnW6F5WGNRIc=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
@ -477,9 +475,8 @@ golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7 h1:fHDIZ2oxGnUZRN6WgWFCbYBjH9uqVPRCUVUDhs0wnbA=
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190930134127-c5a3c61f89f3 h1:6KET3Sqa7fkVfD63QnAM81ZeYg5n4HwApOJkufONnHA=
golang.org/x/net v0.0.0-20190930134127-c5a3c61f89f3/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=

83
migrate/cmd.go Normal file
View File

@ -0,0 +1,83 @@
package migrate
import (
"fmt"
"time"
"github.com/spf13/cobra"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/server"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/version"
"github.com/kava-labs/kava/migrate/v0_8"
v032tendermint "github.com/kava-labs/kava/migrate/v0_8/tendermint/v0_32"
)
const (
flagGenesisTime = "genesis-time"
flagChainID = "chain-id"
)
// MigrateGenesisCmd returns a command to execute genesis state migration.
func MigrateGenesisCmd(_ *server.Context, cdc *codec.Codec) *cobra.Command {
cmd := &cobra.Command{
Use: "migrate [genesis-file]",
Short: "Migrate genesis from kava v0.3 to v0.8",
Long: "Migrate the source genesis into the current version, sorts it, and print to STDOUT.",
Example: fmt.Sprintf(`%s migrate /path/to/genesis.json --chain-id=new-chain-id --genesis-time=1998-01-01T00:00:00Z`, version.ServerName),
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
// 1) Unmarshal existing genesis.json
importGenesis := args[0]
genDoc, err := v032tendermint.GenesisDocFromFile(importGenesis)
if err != nil {
return fmt.Errorf("failed to read genesis document from file %s: %w", importGenesis, err)
}
// 2) Migrate state from kava v0.3 to v0.8
newGenDoc := v0_8.Migrate(*genDoc)
// 3) Create and output a new genesis file
genesisTime := cmd.Flag(flagGenesisTime).Value.String()
if genesisTime != "" {
var t time.Time
err := t.UnmarshalText([]byte(genesisTime))
if err != nil {
return fmt.Errorf("failed to unmarshal genesis time: %w", err)
}
newGenDoc.GenesisTime = t
}
chainID := cmd.Flag(flagChainID).Value.String()
if chainID != "" {
newGenDoc.ChainID = chainID
}
bz, err := cdc.MarshalJSONIndent(newGenDoc, "", " ")
if err != nil {
return fmt.Errorf("failed to marshal genesis doc: %w", err)
}
sortedBz, err := sdk.SortJSON(bz)
if err != nil {
return fmt.Errorf("failed to sort JSON genesis doc: %w", err)
}
fmt.Println(string(sortedBz))
return nil
},
}
cmd.Flags().String(flagGenesisTime, "", "override genesis_time with this flag")
cmd.Flags().String(flagChainID, "", "override chain_id with this flag")
return cmd
}

40
migrate/doc.go Normal file
View File

@ -0,0 +1,40 @@
/*
Migrate handles translating the state of the blockchain between software versions.
For example, as modules are changed over time the structure of the data they store changes. The data structure must be
migrated to the new structure of the newer versions.
There are two types of migration:
- **genesis migration** a script converts an exported genesis file from the old software to a new genesis file for the new software
- **live upgrade** a handler in the upgrade module converts data in the database itself from the old version to the new
Genesis migration starts a whole new blockchain (with new chain-id) for the new software version.
Live upgrade keeps the blockchain (and chain-id) the same for the new software version.
We only support migrations between mainnet kava releases.
We only support migrations from the previous mainnet kava version to the current. We don't support migrating between two old versions, use the old software version for this.
We only support migrations from old to new versions, not the other way around.
Genesis Migration
The process is:
- unmarshal the current genesis file into the old `GenesisState` type that has been copied into a `legacy` folder (ideally using the old codec version)
- convert that `GenesisState` to the current `GenesisState` type
- marshal it to json (using current codec)
On each release we can delete the previous releases migration and old GenesisState type.
eg kava-3 migrates `auth.GenesisState` from kava-2 to `auth.GenesisState` from kava-3,
but for kava-4 we don't need to keep around kava-2's `auth.GenesisState` type.
This folder contains old types from several sdk modules because they needed custom migrations for kava-3.
The sdk version for kava-2 was a master commit 18de63.
Live Upgrade
The process is:
- submit upgrade proposal on old chain
- old chain halts
- people download new version and restart their validators
- on start the new upgrade handler runs
- use copypasted old keeper and types to read from db, convert to current types and write with current keeper
*/
package migrate

274
migrate/v0_8/migrate.go Normal file
View File

@ -0,0 +1,274 @@
package v0_8
import (
"fmt"
"github.com/cosmos/cosmos-sdk/codec"
tmtypes "github.com/tendermint/tendermint/types"
v038auth "github.com/cosmos/cosmos-sdk/x/auth"
v038authexported "github.com/cosmos/cosmos-sdk/x/auth/exported"
v038vesting "github.com/cosmos/cosmos-sdk/x/auth/vesting/types"
v038dist "github.com/cosmos/cosmos-sdk/x/distribution"
v038evidence "github.com/cosmos/cosmos-sdk/x/evidence"
v038genutil "github.com/cosmos/cosmos-sdk/x/genutil"
v038genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types"
v038slashing "github.com/cosmos/cosmos-sdk/x/slashing"
v038staking "github.com/cosmos/cosmos-sdk/x/staking"
v038supply "github.com/cosmos/cosmos-sdk/x/supply"
v038upgrade "github.com/cosmos/cosmos-sdk/x/upgrade"
"github.com/kava-labs/kava/app"
v18de63auth "github.com/kava-labs/kava/migrate/v0_8/sdk/auth/v18de63"
v038distcustom "github.com/kava-labs/kava/migrate/v0_8/sdk/distribution/v0_38"
v18de63dist "github.com/kava-labs/kava/migrate/v0_8/sdk/distribution/v18de63"
v038evidencecustom "github.com/kava-labs/kava/migrate/v0_8/sdk/evidence/v0_38"
v038slashingcustom "github.com/kava-labs/kava/migrate/v0_8/sdk/slashing/v0_38"
v18de63slashing "github.com/kava-labs/kava/migrate/v0_8/sdk/slashing/v18de63"
v038stakingcustom "github.com/kava-labs/kava/migrate/v0_8/sdk/staking/v0_38"
v18de63staking "github.com/kava-labs/kava/migrate/v0_8/sdk/staking/v18de63"
v18de63supply "github.com/kava-labs/kava/migrate/v0_8/sdk/supply/v18de63"
v032tendermint "github.com/kava-labs/kava/migrate/v0_8/tendermint/v0_32"
v033tendermint "github.com/kava-labs/kava/migrate/v0_8/tendermint/v0_33"
"github.com/kava-labs/kava/x/auction"
"github.com/kava-labs/kava/x/bep3"
"github.com/kava-labs/kava/x/cdp"
"github.com/kava-labs/kava/x/committee"
"github.com/kava-labs/kava/x/incentive"
"github.com/kava-labs/kava/x/kavadist"
"github.com/kava-labs/kava/x/pricefeed"
v0_3validator_vesting "github.com/kava-labs/kava/x/validator-vesting/legacy/v0_3"
v0_8validator_vesting "github.com/kava-labs/kava/x/validator-vesting/types"
)
// Migrate translates a genesis file from kava v0.3.x format to kava v0.8.x format.
func Migrate(v0_3GenDoc v032tendermint.GenesisDoc) tmtypes.GenesisDoc {
// migrate app state
var appStateMap v038genutil.AppMap
if err := v032tendermint.Cdc.UnmarshalJSON(v0_3GenDoc.AppState, &appStateMap); err != nil {
panic(err)
}
newAppState := MigrateAppState(appStateMap)
v0_8Codec := app.MakeCodec()
marshaledNewAppState, err := v0_8Codec.MarshalJSON(newAppState)
if err != nil {
panic(err)
}
// migrate tendermint state
newGenDoc := v033tendermint.Migrate(v0_3GenDoc)
newGenDoc.AppState = marshaledNewAppState
return newGenDoc
}
func MigrateAppState(v0_3AppState v038genutil.AppMap) v038genutil.AppMap {
// run sdk migrations for commit 18de63 to v0.38, ignoring auth (validator vesting needs a custom migration)
v0_8AppState := MigrateSDK(v0_3AppState)
// create codec for current app version
v0_8Codec := app.MakeCodec()
// migrate auth state
// recreate the codec from v0.3 (note: current codec and crypto packages are backwards compatible) (note this is not a compete recreation of v0.3's codec)
v0_3Codec := codec.New()
codec.RegisterCrypto(v0_3Codec)
v18de63auth.RegisterCodec(v0_3Codec)
v18de63auth.RegisterCodecVesting(v0_3Codec)
v18de63supply.RegisterCodec(v0_3Codec)
v0_3validator_vesting.RegisterCodec(v0_3Codec)
if v0_3AppState[v18de63auth.ModuleName] != nil {
var authGenState v18de63auth.GenesisState
v0_3Codec.MustUnmarshalJSON(v0_3AppState[v18de63auth.ModuleName], &authGenState)
delete(v0_3AppState, v18de63auth.ModuleName)
v0_8AppState[v038auth.ModuleName] = v0_8Codec.MustMarshalJSON(MigrateAuth(authGenState))
}
// migrate new modules (by adding new gen states)
v0_8AppState[auction.ModuleName] = v0_8Codec.MustMarshalJSON(auction.DefaultGenesisState())
v0_8AppState[bep3.ModuleName] = v0_8Codec.MustMarshalJSON(bep3.DefaultGenesisState())
v0_8AppState[cdp.ModuleName] = v0_8Codec.MustMarshalJSON(cdp.DefaultGenesisState())
v0_8AppState[committee.ModuleName] = v0_8Codec.MustMarshalJSON(committee.DefaultGenesisState())
v0_8AppState[incentive.ModuleName] = v0_8Codec.MustMarshalJSON(incentive.DefaultGenesisState())
v0_8AppState[kavadist.ModuleName] = v0_8Codec.MustMarshalJSON(kavadist.DefaultGenesisState())
v0_8AppState[pricefeed.ModuleName] = v0_8Codec.MustMarshalJSON(pricefeed.DefaultGenesisState())
return v0_8AppState
}
// migrate the sdk modules from sdk commit 18de63 (v0.37 and half) to v0.38.3, mostly copying v038.Migrate
func MigrateSDK(appState v038genutil.AppMap) v038genutil.AppMap {
v18de63Codec := codec.New() // ideally this would use the exact version of amino from kava v0.3, but the current version is backwards compatible
codec.RegisterCrypto(v18de63Codec)
v18de63auth.RegisterCodec(v18de63Codec)
v038Codec := app.MakeCodec() // using current kava app codec
// for each module, unmarshal old state, run a migrate(genesisStateType) func, marshal returned type into json and set
// migrate distribution state
if appState[v18de63dist.ModuleName] != nil {
var distGenState v18de63dist.GenesisState
v18de63Codec.MustUnmarshalJSON(appState[v18de63dist.ModuleName], &distGenState)
delete(appState, v18de63dist.ModuleName) // delete old key in case the name changed
appState[v038dist.ModuleName] = v038Codec.MustMarshalJSON(v038distcustom.Migrate(distGenState))
}
// migrate slashing and evidence state
if appState[v18de63slashing.ModuleName] != nil {
var slashingGenState v18de63slashing.GenesisState
v18de63Codec.MustUnmarshalJSON(appState[v18de63slashing.ModuleName], &slashingGenState)
delete(appState, v18de63slashing.ModuleName)
// remove param
appState[v038slashing.ModuleName] = v038Codec.MustMarshalJSON(v038slashingcustom.Migrate(slashingGenState))
// add new evidence module genesis (with above param)
appState[v038evidence.ModuleName] = v038Codec.MustMarshalJSON(v038evidencecustom.Migrate(slashingGenState))
}
// migrate staking state
if appState[v18de63staking.ModuleName] != nil {
var stakingGenState v18de63staking.GenesisState
v18de63Codec.MustUnmarshalJSON(appState[v18de63staking.ModuleName], &stakingGenState)
delete(appState, v18de63staking.ModuleName)
appState[v038staking.ModuleName] = v038Codec.MustMarshalJSON(v038stakingcustom.Migrate(stakingGenState))
}
// migrate genutil state
appState[v038genutil.ModuleName] = v038Codec.MustMarshalJSON(v038genutiltypes.DefaultGenesisState())
// add upgrade state
appState[v038upgrade.ModuleName] = []byte(`{}`)
return appState
}
func MigrateAuth(oldGenState v18de63auth.GenesisState) v038auth.GenesisState {
// old and new struct type are identical but with different (un)marshalJSON methods
var newAccounts v038authexported.GenesisAccounts
for _, account := range oldGenState.Accounts {
switch acc := account.(type) {
case *v18de63auth.BaseAccount:
a := v038auth.BaseAccount(*acc)
newAccounts = append(newAccounts, v038authexported.GenesisAccount(&a))
case *v18de63auth.BaseVestingAccount:
ba := v038auth.BaseAccount(*(acc.BaseAccount))
bva := v038vesting.BaseVestingAccount{
BaseAccount: &ba,
OriginalVesting: acc.OriginalVesting,
DelegatedFree: acc.DelegatedFree,
DelegatedVesting: acc.DelegatedVesting,
EndTime: acc.EndTime,
}
newAccounts = append(newAccounts, v038authexported.GenesisAccount(&bva))
case *v18de63auth.ContinuousVestingAccount:
ba := v038auth.BaseAccount(*(acc.BaseVestingAccount.BaseAccount))
bva := v038vesting.BaseVestingAccount{
BaseAccount: &ba,
OriginalVesting: acc.BaseVestingAccount.OriginalVesting,
DelegatedFree: acc.BaseVestingAccount.DelegatedFree,
DelegatedVesting: acc.BaseVestingAccount.DelegatedVesting,
EndTime: acc.BaseVestingAccount.EndTime,
}
cva := v038vesting.ContinuousVestingAccount{
BaseVestingAccount: &bva,
StartTime: acc.StartTime,
}
newAccounts = append(newAccounts, v038authexported.GenesisAccount(&cva))
case *v18de63auth.DelayedVestingAccount:
ba := v038auth.BaseAccount(*(acc.BaseVestingAccount.BaseAccount))
bva := v038vesting.BaseVestingAccount{
BaseAccount: &ba,
OriginalVesting: acc.BaseVestingAccount.OriginalVesting,
DelegatedFree: acc.BaseVestingAccount.DelegatedFree,
DelegatedVesting: acc.BaseVestingAccount.DelegatedVesting,
EndTime: acc.BaseVestingAccount.EndTime,
}
dva := v038vesting.DelayedVestingAccount{
BaseVestingAccount: &bva,
}
newAccounts = append(newAccounts, v038authexported.GenesisAccount(&dva))
case *v18de63auth.PeriodicVestingAccount:
ba := v038auth.BaseAccount(*(acc.BaseVestingAccount.BaseAccount))
bva := v038vesting.BaseVestingAccount{
BaseAccount: &ba,
OriginalVesting: acc.BaseVestingAccount.OriginalVesting,
DelegatedFree: acc.BaseVestingAccount.DelegatedFree,
DelegatedVesting: acc.BaseVestingAccount.DelegatedVesting,
EndTime: acc.BaseVestingAccount.EndTime,
}
var newPeriods v038vesting.Periods
for _, p := range acc.VestingPeriods {
newPeriods = append(newPeriods, v038vesting.Period(p))
}
pva := v038vesting.PeriodicVestingAccount{
BaseVestingAccount: &bva,
StartTime: acc.StartTime,
VestingPeriods: newPeriods,
}
newAccounts = append(newAccounts, v038authexported.GenesisAccount(&pva))
case *v18de63supply.ModuleAccount:
ba := v038auth.BaseAccount(*(acc.BaseAccount))
ma := v038supply.ModuleAccount{
BaseAccount: &ba,
Name: acc.Name,
Permissions: acc.Permissions,
}
newAccounts = append(newAccounts, v038authexported.GenesisAccount(&ma))
case *v0_3validator_vesting.ValidatorVestingAccount:
ba := v038auth.BaseAccount(*(acc.PeriodicVestingAccount.BaseVestingAccount.BaseAccount))
bva := v038vesting.BaseVestingAccount{
BaseAccount: &ba,
OriginalVesting: acc.PeriodicVestingAccount.BaseVestingAccount.OriginalVesting,
DelegatedFree: acc.PeriodicVestingAccount.BaseVestingAccount.DelegatedFree,
DelegatedVesting: acc.PeriodicVestingAccount.BaseVestingAccount.DelegatedVesting,
EndTime: acc.PeriodicVestingAccount.BaseVestingAccount.EndTime,
}
var newPeriods v038vesting.Periods
for _, p := range acc.PeriodicVestingAccount.VestingPeriods {
newPeriods = append(newPeriods, v038vesting.Period(p))
}
pva := v038vesting.PeriodicVestingAccount{
BaseVestingAccount: &bva,
StartTime: acc.PeriodicVestingAccount.StartTime,
VestingPeriods: newPeriods,
}
var newVestingProgress []v0_8validator_vesting.VestingProgress
for _, p := range acc.VestingPeriodProgress {
newVestingProgress = append(newVestingProgress, v0_8validator_vesting.VestingProgress(p))
}
vva := v0_8validator_vesting.ValidatorVestingAccount{
PeriodicVestingAccount: &pva,
ValidatorAddress: acc.ValidatorAddress,
ReturnAddress: acc.ReturnAddress,
SigningThreshold: acc.SigningThreshold,
CurrentPeriodProgress: v0_8validator_vesting.CurrentPeriodProgress(acc.CurrentPeriodProgress),
VestingPeriodProgress: newVestingProgress,
DebtAfterFailedVesting: acc.DebtAfterFailedVesting,
}
newAccounts = append(newAccounts, v038authexported.GenesisAccount(&vva))
default:
panic(fmt.Sprintf("unrecognized account type: %T", acc))
}
}
gs := v038auth.GenesisState{
Params: v038auth.Params(oldGenState.Params),
Accounts: newAccounts,
}
return gs
}

View File

@ -0,0 +1,192 @@
package v0_8
import (
"io/ioutil"
"os"
"path/filepath"
"testing"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/genutil"
v032tendermint "github.com/kava-labs/kava/migrate/v0_8/tendermint/v0_32"
v033tendermint "github.com/kava-labs/kava/migrate/v0_8/tendermint/v0_33"
"github.com/stretchr/testify/require"
tmtypes "github.com/tendermint/tendermint/types"
"github.com/kava-labs/kava/app"
)
func TestMain(m *testing.M) {
config := sdk.GetConfig()
app.SetBech32AddressPrefixes(config)
app.SetBip44CoinType(config)
os.Exit(m.Run())
}
func TestMigrate_Auth_BaseAccount(t *testing.T) {
bz, err := ioutil.ReadFile(filepath.Join("testdata", "auth-base-old.json"))
require.NoError(t, err)
oldAppState := genutil.AppMap{"auth": bz}
newAppState := MigrateAppState(oldAppState)
bz, err = ioutil.ReadFile(filepath.Join("testdata", "auth-base-new.json"))
require.NoError(t, err)
require.JSONEq(t, string(bz), string(newAppState["auth"]))
}
func TestMigrate_Auth_MultiSigAccount(t *testing.T) {
bz, err := ioutil.ReadFile(filepath.Join("testdata", "auth-base-multisig-old.json"))
require.NoError(t, err)
oldAppState := genutil.AppMap{"auth": bz}
newAppState := MigrateAppState(oldAppState)
bz, err = ioutil.ReadFile(filepath.Join("testdata", "auth-base-multisig-new.json"))
require.NoError(t, err)
require.JSONEq(t, string(bz), string(newAppState["auth"]))
}
func TestMigrate_Auth_ValidatorVestingAccount(t *testing.T) {
bz, err := ioutil.ReadFile(filepath.Join("testdata", "auth-valvesting-old.json"))
require.NoError(t, err)
oldAppState := genutil.AppMap{"auth": bz}
newAppState := MigrateAppState(oldAppState)
bz, err = ioutil.ReadFile(filepath.Join("testdata", "auth-valvesting-new.json"))
require.NoError(t, err)
require.JSONEq(t, string(bz), string(newAppState["auth"]))
}
func TestMigrate_Auth_ModuleAccount(t *testing.T) {
bz, err := ioutil.ReadFile(filepath.Join("testdata", "auth-module-old.json"))
require.NoError(t, err)
oldAppState := genutil.AppMap{"auth": bz}
newAppState := MigrateAppState(oldAppState)
bz, err = ioutil.ReadFile(filepath.Join("testdata", "auth-module-new.json"))
require.NoError(t, err)
require.JSONEq(t, string(bz), string(newAppState["auth"]))
}
func TestMigrate_Auth_PeriodicVestingAccount(t *testing.T) {
bz, err := ioutil.ReadFile(filepath.Join("testdata", "auth-periodic-old.json"))
require.NoError(t, err)
oldAppState := genutil.AppMap{"auth": bz}
newAppState := MigrateAppState(oldAppState)
bz, err = ioutil.ReadFile(filepath.Join("testdata", "auth-periodic-new.json"))
require.NoError(t, err)
require.JSONEq(t, string(bz), string(newAppState["auth"]))
}
func TestMigrate_Distribution(t *testing.T) {
bz, err := ioutil.ReadFile(filepath.Join("testdata", "distribution-old.json"))
require.NoError(t, err)
oldAppState := genutil.AppMap{"distribution": bz}
newAppState := MigrateSDK(oldAppState)
bz, err = ioutil.ReadFile(filepath.Join("testdata", "distribution-new.json"))
require.NoError(t, err)
require.JSONEq(t, string(bz), string(newAppState["distribution"]))
}
func TestMigrate_Staking(t *testing.T) {
bz, err := ioutil.ReadFile(filepath.Join("testdata", "staking-old.json"))
require.NoError(t, err)
oldAppState := genutil.AppMap{"staking": bz}
newAppState := MigrateSDK(oldAppState)
bz, err = ioutil.ReadFile(filepath.Join("testdata", "staking-new.json"))
require.NoError(t, err)
require.JSONEq(t, string(bz), string(newAppState["staking"]))
}
func TestMigrate_Slashing(t *testing.T) {
bz, err := ioutil.ReadFile(filepath.Join("testdata", "slashing-old.json"))
require.NoError(t, err)
oldAppState := genutil.AppMap{"slashing": bz}
newAppState := MigrateSDK(oldAppState)
bz, err = ioutil.ReadFile(filepath.Join("testdata", "slashing-new.json"))
require.NoError(t, err)
require.JSONEq(t, string(bz), string(newAppState["slashing"]))
}
func TestMigrate_Evidence(t *testing.T) {
bz, err := ioutil.ReadFile(filepath.Join("testdata", "slashing-old.json"))
require.NoError(t, err)
oldAppState := genutil.AppMap{"slashing": bz}
newAppState := MigrateSDK(oldAppState)
bz, err = ioutil.ReadFile(filepath.Join("testdata", "evidence-new.json"))
require.NoError(t, err)
require.JSONEq(t, string(bz), string(newAppState["evidence"]))
}
func TestMigrate_Tendermint(t *testing.T) {
oldGenDoc, err := v032tendermint.GenesisDocFromFile(filepath.Join("testdata", "tendermint-old.json"))
require.NoError(t, err)
newGenDoc := v033tendermint.Migrate(*oldGenDoc)
expectedGenDoc, err := tmtypes.GenesisDocFromFile(filepath.Join("testdata", "tendermint-new.json"))
require.NoError(t, err)
require.Equal(t, *expectedGenDoc, newGenDoc)
}
func TestMigrate(t *testing.T) {
oldGenDoc, err := v032tendermint.GenesisDocFromFile(filepath.Join("testdata", "all-old.json"))
require.NoError(t, err)
newGenDoc := Migrate(*oldGenDoc)
expectedGenDoc, err := tmtypes.GenesisDocFromFile(filepath.Join("testdata", "all-new.json"))
require.NoError(t, err)
// check each field seperately to aid debugging
require.Equal(t, expectedGenDoc.AppHash, newGenDoc.AppHash)
require.JSONEq(t, string(expectedGenDoc.AppState), string(newGenDoc.AppState))
require.Equal(t, expectedGenDoc.ChainID, newGenDoc.ChainID)
require.Equal(t, expectedGenDoc.ConsensusParams, newGenDoc.ConsensusParams)
require.Equal(t, expectedGenDoc.GenesisTime, newGenDoc.GenesisTime)
require.Equal(t, expectedGenDoc.Validators, newGenDoc.Validators)
var newAppState genutil.AppMap
require.NoError(t,
app.MakeCodec().UnmarshalJSON(newGenDoc.AppState, &newAppState),
)
require.NoError(t,
app.ModuleBasics.ValidateGenesis(newAppState),
)
}
func TestMigrate_Full(t *testing.T) {
// 1) load an exported kava-2 state
oldGenDoc, err := v032tendermint.GenesisDocFromFile(filepath.Join("testdata", "kava-2.json"))
require.NoError(t, err)
tApp := app.NewTestApp() // also sets the bech32 prefix on sdk.Config
cdc := app.MakeCodec()
// 2) migrate
newGenDoc := Migrate(*oldGenDoc)
// 3) check new genesis is valid
var newAppState genutil.AppMap
require.NoError(t,
cdc.UnmarshalJSON(newGenDoc.AppState, &newAppState),
)
require.NoError(t,
app.ModuleBasics.ValidateGenesis(newAppState),
)
require.NotPanics(t, func() {
// this runs both InitGenesis for all modules (which panic on errors) and runs all invariants
tApp.InitializeFromGenesisStates(app.GenesisState(newAppState))
})
}

View File

@ -0,0 +1,15 @@
package v18de63
import (
"github.com/tendermint/tendermint/crypto"
sdk "github.com/cosmos/cosmos-sdk/types"
)
type BaseAccount struct {
Address sdk.AccAddress `json:"address" yaml:"address"`
Coins sdk.Coins `json:"coins" yaml:"coins"`
PubKey crypto.PubKey `json:"public_key" yaml:"public_key"`
AccountNumber uint64 `json:"account_number" yaml:"account_number"`
Sequence uint64 `json:"sequence" yaml:"sequence"`
}

View File

@ -0,0 +1,12 @@
package v18de63
import (
"github.com/cosmos/cosmos-sdk/codec"
)
// RegisterCodec registers concrete types on the codec
func RegisterCodec(cdc *codec.Codec) {
cdc.RegisterInterface((*GenesisAccount)(nil), nil)
cdc.RegisterInterface((*Account)(nil), nil)
cdc.RegisterConcrete(&BaseAccount{}, "cosmos-sdk/Account", nil)
}

View File

@ -0,0 +1,21 @@
package v18de63
// Note: interfaces have had methods removed as they're not needed for unmarshalling genesis.json
// This allows account types to be copy and pasted into this package without all their methods.
// Account is an interface used to store coins at a given address within state.
// It presumes a notion of sequence numbers for replay protection,
// a notion of account numbers for replay protection for previously pruned accounts,
// and a pubkey for authentication purposes.
//
// Many complex conditions can be used in the concrete struct which implements Account.
type Account interface {
}
// GenesisAccounts defines a slice of GenesisAccount objects
type GenesisAccounts []GenesisAccount
// GenesisAccount defines a genesis account that embeds an Account with validation capabilities.
type GenesisAccount interface {
Account
}

View File

@ -0,0 +1,7 @@
package v18de63
// GenesisState - all auth state that must be provided at genesis
type GenesisState struct {
Params Params `json:"params" yaml:"params"`
Accounts GenesisAccounts `json:"accounts" yaml:"accounts"`
}

View File

@ -0,0 +1,3 @@
package v18de63
const ModuleName = "auth"

View File

@ -0,0 +1,10 @@
package v18de63
// Params defines the parameters for the auth module.
type Params struct {
MaxMemoCharacters uint64 `json:"max_memo_characters" yaml:"max_memo_characters"`
TxSigLimit uint64 `json:"tx_sig_limit" yaml:"tx_sig_limit"`
TxSizeCostPerByte uint64 `json:"tx_size_cost_per_byte" yaml:"tx_size_cost_per_byte"`
SigVerifyCostED25519 uint64 `json:"sig_verify_cost_ed25519" yaml:"sig_verify_cost_ed25519"`
SigVerifyCostSecp256k1 uint64 `json:"sig_verify_cost_secp256k1" yaml:"sig_verify_cost_secp256k1"`
}

View File

@ -0,0 +1,14 @@
package v18de63
import (
sdk "github.com/cosmos/cosmos-sdk/types"
)
// Period defines a length of time and amount of coins that will vest
type Period struct {
Length int64 `json:"length" yaml:"length"` // length of the period, in seconds
Amount sdk.Coins `json:"amount" yaml:"amount"` // amount of coins vesting during this period
}
// Periods stores all vesting periods passed as part of a PeriodicVestingAccount
type Periods []Period

View File

@ -0,0 +1,39 @@
package v18de63
import (
sdk "github.com/cosmos/cosmos-sdk/types"
)
// BaseVestingAccount implements the VestingAccount interface. It contains all
// the necessary fields needed for any vesting account implementation.
type BaseVestingAccount struct {
*BaseAccount
OriginalVesting sdk.Coins `json:"original_vesting" yaml:"original_vesting"` // coins in account upon initialization
DelegatedFree sdk.Coins `json:"delegated_free" yaml:"delegated_free"` // coins that are vested and delegated
DelegatedVesting sdk.Coins `json:"delegated_vesting" yaml:"delegated_vesting"` // coins that vesting and delegated
EndTime int64 `json:"end_time" yaml:"end_time"` // when the coins become unlocked
}
// ContinuousVestingAccount implements the VestingAccount interface. It
// continuously vests by unlocking coins linearly with respect to time.
type ContinuousVestingAccount struct {
*BaseVestingAccount
StartTime int64 `json:"start_time" yaml:"start_time"` // when the coins start to vest
}
// PeriodicVestingAccount implements the VestingAccount interface. It
// periodically vests by unlocking coins during each specified period
type PeriodicVestingAccount struct {
*BaseVestingAccount
StartTime int64 `json:"start_time" yaml:"start_time"` // when the coins start to vest
VestingPeriods Periods `json:"vesting_periods" yaml:"vesting_periods"` // the vesting schedule
}
// DelayedVestingAccount implements the VestingAccount interface. It vests all
// coins after a specific time, but non prior. In other words, it keeps them
// locked until a specified time.
type DelayedVestingAccount struct {
*BaseVestingAccount
}

View File

@ -0,0 +1,14 @@
package v18de63
import (
"github.com/cosmos/cosmos-sdk/codec"
)
// RegisterCodec registers concrete types on the codec
func RegisterCodecVesting(cdc *codec.Codec) { // renamed to avoid conflict as packages are combined
cdc.RegisterInterface((*VestingAccount)(nil), nil)
cdc.RegisterConcrete(&BaseVestingAccount{}, "cosmos-sdk/BaseVestingAccount", nil)
cdc.RegisterConcrete(&ContinuousVestingAccount{}, "cosmos-sdk/ContinuousVestingAccount", nil)
cdc.RegisterConcrete(&DelayedVestingAccount{}, "cosmos-sdk/DelayedVestingAccount", nil)
cdc.RegisterConcrete(&PeriodicVestingAccount{}, "cosmos-sdk/PeriodicVestingAccount", nil)
}

View File

@ -0,0 +1,9 @@
package v18de63
// Note: interfaces have had methods removed as they're not needed for unmarshalling genesis.json
// This allows account types to be copy and pasted into this package without all their methods.
// VestingAccount defines an account type that vests coins via a vesting schedule.
type VestingAccount interface {
Account
}

View File

@ -0,0 +1,98 @@
package v038
import (
v038dist "github.com/cosmos/cosmos-sdk/x/distribution"
v18de63dist "github.com/kava-labs/kava/migrate/v0_8/sdk/distribution/v18de63"
)
func Migrate(oldGenState v18de63dist.GenesisState) v038dist.GenesisState {
// Changes: some fields moved into a params struct, some changes in json tags
params := v038dist.Params{
CommunityTax: oldGenState.CommunityTax,
BaseProposerReward: oldGenState.BaseProposerReward,
BonusProposerReward: oldGenState.BonusProposerReward,
WithdrawAddrEnabled: oldGenState.WithdrawAddrEnabled,
}
withdrawInfos := []v038dist.DelegatorWithdrawInfo{}
for _, v := range oldGenState.DelegatorWithdrawInfos {
withdrawInfos = append(withdrawInfos, v038dist.DelegatorWithdrawInfo(v))
}
outstandingRewards := []v038dist.ValidatorOutstandingRewardsRecord{}
for _, v := range oldGenState.OutstandingRewards {
outstandingRewards = append(outstandingRewards, v038dist.ValidatorOutstandingRewardsRecord(v))
}
accumulatedComs := []v038dist.ValidatorAccumulatedCommissionRecord{}
for _, v := range oldGenState.ValidatorAccumulatedCommissions {
accumulatedComs = append(accumulatedComs, v038dist.ValidatorAccumulatedCommissionRecord(v))
}
histRewards := []v038dist.ValidatorHistoricalRewardsRecord{}
for _, v := range oldGenState.ValidatorHistoricalRewards {
histRewards = append(histRewards, v038dist.ValidatorHistoricalRewardsRecord{
ValidatorAddress: v.ValidatorAddress,
Period: v.Period,
Rewards: v038dist.NewValidatorHistoricalRewards(
v.Rewards.CumulativeRewardRatio,
v.Rewards.ReferenceCount,
),
})
}
currRewards := []v038dist.ValidatorCurrentRewardsRecord{}
for _, v := range oldGenState.ValidatorCurrentRewards {
currRewards = append(currRewards, v038dist.ValidatorCurrentRewardsRecord{
ValidatorAddress: v.ValidatorAddress,
Rewards: v038dist.NewValidatorCurrentRewards(
v.Rewards.Rewards,
v.Rewards.Period,
),
})
}
startInfos := []v038dist.DelegatorStartingInfoRecord{}
for _, v := range oldGenState.DelegatorStartingInfos {
startInfos = append(startInfos, v038dist.DelegatorStartingInfoRecord{
DelegatorAddress: v.DelegatorAddress,
ValidatorAddress: v.ValidatorAddress,
StartingInfo: v038dist.NewDelegatorStartingInfo(
v.StartingInfo.PreviousPeriod,
v.StartingInfo.Stake,
v.StartingInfo.Height,
),
})
}
slashEvents := []v038dist.ValidatorSlashEventRecord{}
for _, v := range oldGenState.ValidatorSlashEvents {
slashEvents = append(slashEvents, v038dist.ValidatorSlashEventRecord{
ValidatorAddress: v.ValidatorAddress,
Height: v.Height,
Period: v.Period,
Event: v038dist.NewValidatorSlashEvent(
v.Event.ValidatorPeriod,
v.Event.Fraction,
),
})
}
newGenState := v038dist.NewGenesisState(
params,
v038dist.FeePool(oldGenState.FeePool),
withdrawInfos,
oldGenState.PreviousProposer,
outstandingRewards,
accumulatedComs,
histRewards,
currRewards,
startInfos,
slashEvents,
)
return newGenState
}

View File

@ -0,0 +1,18 @@
package v18de63
import (
sdk "github.com/cosmos/cosmos-sdk/types"
)
// starting info for a delegator reward period
// tracks the previous validator period, the delegation's amount
// of staking token, and the creation height (to check later on
// if any slashes have occurred)
// NOTE that even though validators are slashed to whole staking tokens, the
// delegators within the validator may be left with less than a full token,
// thus sdk.Dec is used
type DelegatorStartingInfo struct {
PreviousPeriod uint64 `json:"previous_period" yaml:"previous_period"` // period at which the delegation should withdraw starting from
Stake sdk.Dec `json:"stake" yaml:"stake"` // amount of staking token delegated
Height uint64 `json:"creation_height" yaml:"creation_height"` // height at which delegation was created
}

View File

@ -0,0 +1,10 @@
package v18de63
import (
sdk "github.com/cosmos/cosmos-sdk/types"
)
// global fee pool for distribution
type FeePool struct {
CommunityPool sdk.DecCoins `json:"community_pool" yaml:"community_pool"` // pool for community funds yet to be spent
}

View File

@ -0,0 +1,69 @@
package v18de63
import (
sdk "github.com/cosmos/cosmos-sdk/types"
)
// the address for where distributions rewards are withdrawn to by default
// this struct is only used at genesis to feed in default withdraw addresses
type DelegatorWithdrawInfo struct {
DelegatorAddress sdk.AccAddress `json:"delegator_address" yaml:"delegator_address"`
WithdrawAddress sdk.AccAddress `json:"withdraw_address" yaml:"withdraw_address"`
}
// used for import/export via genesis json
type ValidatorOutstandingRewardsRecord struct {
ValidatorAddress sdk.ValAddress `json:"validator_address" yaml:"validator_address"`
OutstandingRewards sdk.DecCoins `json:"outstanding_rewards" yaml:"outstanding_rewards"`
}
// used for import / export via genesis json
type ValidatorAccumulatedCommissionRecord struct {
ValidatorAddress sdk.ValAddress `json:"validator_address" yaml:"validator_address"`
Accumulated ValidatorAccumulatedCommission `json:"accumulated" yaml:"accumulated"`
}
// used for import / export via genesis json
type ValidatorHistoricalRewardsRecord struct {
ValidatorAddress sdk.ValAddress `json:"validator_address" yaml:"validator_address"`
Period uint64 `json:"period" yaml:"period"`
Rewards ValidatorHistoricalRewards `json:"rewards" yaml:"rewards"`
}
// used for import / export via genesis json
type ValidatorCurrentRewardsRecord struct {
ValidatorAddress sdk.ValAddress `json:"validator_address" yaml:"validator_address"`
Rewards ValidatorCurrentRewards `json:"rewards" yaml:"rewards"`
}
// used for import / export via genesis json
type DelegatorStartingInfoRecord struct {
DelegatorAddress sdk.AccAddress `json:"delegator_address" yaml:"delegator_address"`
ValidatorAddress sdk.ValAddress `json:"validator_address" yaml:"validator_address"`
StartingInfo DelegatorStartingInfo `json:"starting_info" yaml:"starting_info"`
}
// used for import / export via genesis json
type ValidatorSlashEventRecord struct {
ValidatorAddress sdk.ValAddress `json:"validator_address" yaml:"validator_address"`
Height uint64 `json:"height" yaml:"height"`
Period uint64 `json:"period" yaml:"period"`
Event ValidatorSlashEvent `json:"validator_slash_event" yaml:"validator_slash_event"`
}
// GenesisState - all distribution state that must be provided at genesis
type GenesisState struct {
FeePool FeePool `json:"fee_pool" yaml:"fee_pool"`
CommunityTax sdk.Dec `json:"community_tax" yaml:"community_tax"`
BaseProposerReward sdk.Dec `json:"base_proposer_reward" yaml:"base_proposer_reward"`
BonusProposerReward sdk.Dec `json:"bonus_proposer_reward" yaml:"bonus_proposer_reward"`
WithdrawAddrEnabled bool `json:"withdraw_addr_enabled" yaml:"withdraw_addr_enabled"`
DelegatorWithdrawInfos []DelegatorWithdrawInfo `json:"delegator_withdraw_infos" yaml:"delegator_withdraw_infos"`
PreviousProposer sdk.ConsAddress `json:"previous_proposer" yaml:"previous_proposer"`
OutstandingRewards []ValidatorOutstandingRewardsRecord `json:"outstanding_rewards" yaml:"outstanding_rewards"`
ValidatorAccumulatedCommissions []ValidatorAccumulatedCommissionRecord `json:"validator_accumulated_commissions" yaml:"validator_accumulated_commissions"`
ValidatorHistoricalRewards []ValidatorHistoricalRewardsRecord `json:"validator_historical_rewards" yaml:"validator_historical_rewards"`
ValidatorCurrentRewards []ValidatorCurrentRewardsRecord `json:"validator_current_rewards" yaml:"validator_current_rewards"`
DelegatorStartingInfos []DelegatorStartingInfoRecord `json:"delegator_starting_infos" yaml:"delegator_starting_infos"`
ValidatorSlashEvents []ValidatorSlashEventRecord `json:"validator_slash_events" yaml:"validator_slash_events"`
}

View File

@ -0,0 +1,3 @@
package v18de63
const ModuleName = "distribution"

View File

@ -0,0 +1,49 @@
package v18de63
import (
sdk "github.com/cosmos/cosmos-sdk/types"
)
// historical rewards for a validator
// height is implicit within the store key
// cumulative reward ratio is the sum from the zeroeth period
// until this period of rewards / tokens, per the spec
// The reference count indicates the number of objects
// which might need to reference this historical entry
// at any point.
// ReferenceCount =
// number of outstanding delegations which ended the associated period (and might need to read that record)
// + number of slashes which ended the associated period (and might need to read that record)
// + one per validator for the zeroeth period, set on initialization
type ValidatorHistoricalRewards struct {
CumulativeRewardRatio sdk.DecCoins `json:"cumulative_reward_ratio" yaml:"cumulative_reward_ratio"`
ReferenceCount uint16 `json:"reference_count" yaml:"reference_count"`
}
// current rewards and current period for a validator
// kept as a running counter and incremented each block
// as long as the validator's tokens remain constant
type ValidatorCurrentRewards struct {
Rewards sdk.DecCoins `json:"rewards" yaml:"rewards"` // current rewards
Period uint64 `json:"period" yaml:"period"` // current period
}
// accumulated commission for a validator
// kept as a running counter, can be withdrawn at any time
type ValidatorAccumulatedCommission = sdk.DecCoins
// validator slash event
// height is implicit within the store key
// needed to calculate appropriate amounts of staking token
// for delegations which withdraw after a slash has occurred
type ValidatorSlashEvent struct {
ValidatorPeriod uint64 `json:"validator_period" yaml:"validator_period"` // period when the slash occurred
Fraction sdk.Dec `json:"fraction" yaml:"fraction"` // slash fraction
}
// ValidatorSlashEvents is a collection of ValidatorSlashEvent
type ValidatorSlashEvents []ValidatorSlashEvent
// outstanding (un-withdrawn) rewards for a validator
// inexpensive to track, allows simple sanity checks
type ValidatorOutstandingRewards = sdk.DecCoins

View File

@ -0,0 +1,16 @@
package v038
import (
v038evidence "github.com/cosmos/cosmos-sdk/x/evidence"
v18de63slashing "github.com/kava-labs/kava/migrate/v0_8/sdk/slashing/v18de63"
)
func Migrate(oldSlashingGenState v18de63slashing.GenesisState) v038evidence.GenesisState {
// Need to use DefaultGenesisState as evidence doesn't export Params type (inside internal/ and missing from alias.go)
newGenState := v038evidence.DefaultGenesisState()
newGenState.Params.MaxEvidenceAge = oldSlashingGenState.Params.MaxEvidenceAge
return newGenState
}

View File

@ -0,0 +1,23 @@
package v038
import (
"testing"
"time"
v18de63slashing "github.com/kava-labs/kava/migrate/v0_8/sdk/slashing/v18de63"
"github.com/stretchr/testify/require"
)
func TestMigrate(t *testing.T) {
age := 21 * 24 * time.Hour
oldSlashingState := v18de63slashing.GenesisState{
Params: v18de63slashing.Params{MaxEvidenceAge: age},
}
newEvidenceState := Migrate(oldSlashingState)
// check age param was copied over
require.Equal(t, age, newEvidenceState.Params.MaxEvidenceAge)
// check new genesis state is valid
require.NoError(t, newEvidenceState.Validate())
}

View File

@ -0,0 +1,27 @@
package v038
import (
v038slashing "github.com/cosmos/cosmos-sdk/x/slashing"
"github.com/kava-labs/kava/migrate/v0_8/sdk/slashing/v18de63"
)
func Migrate(oldGenState v18de63.GenesisState) v038slashing.GenesisState {
// old and new types are identical except for the MaxEvidenceAge param
newParams := v038slashing.Params{
// no MaxEvidenceAge
SignedBlocksWindow: oldGenState.Params.SignedBlocksWindow,
MinSignedPerWindow: oldGenState.Params.MinSignedPerWindow,
DowntimeJailDuration: oldGenState.Params.DowntimeJailDuration,
SlashFractionDoubleSign: oldGenState.Params.SlashFractionDoubleSign,
SlashFractionDowntime: oldGenState.Params.SlashFractionDowntime,
}
return v038slashing.GenesisState{
Params: newParams,
SigningInfos: oldGenState.SigningInfos,
MissedBlocks: oldGenState.MissedBlocks,
}
}

View File

@ -0,0 +1,33 @@
package v038
import (
"testing"
"time"
"github.com/stretchr/testify/require"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/slashing"
v18de63slashing "github.com/kava-labs/kava/migrate/v0_8/sdk/slashing/v18de63"
)
func TestMigrate(t *testing.T) {
oldState := v18de63slashing.GenesisState{
Params: v18de63slashing.Params{
DowntimeJailDuration: 10 * time.Minute,
MaxEvidenceAge: 21 * 24 * time.Hour,
MinSignedPerWindow: sdk.MustNewDecFromStr("0.05"),
SignedBlocksWindow: 10000,
SlashFractionDoubleSign: sdk.MustNewDecFromStr("0.05"),
SlashFractionDowntime: sdk.MustNewDecFromStr("0.0001"),
},
SigningInfos: nil,
MissedBlocks: nil,
}
newState := Migrate(oldState)
// check new genesis state is valid
require.NoError(t, slashing.ValidateGenesis(newState))
}

View File

@ -0,0 +1,30 @@
package v18de63
import (
"time"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/slashing"
)
const ModuleName = "slashing"
// The field types (except Params) are the same between v18de63 and v0.38, so the types can be imported rather than copied in
type GenesisState struct {
Params Params `json:"params" yaml:"params"`
SigningInfos map[string]slashing.ValidatorSigningInfo `json:"signing_infos" yaml:"signing_infos"`
MissedBlocks map[string][]slashing.MissedBlock `json:"missed_blocks" yaml:"missed_blocks"`
}
// These sdk types are the same between v18de63 and v0.38
type Params struct {
MaxEvidenceAge time.Duration `json:"max_evidence_age" yaml:"max_evidence_age"`
SignedBlocksWindow int64 `json:"signed_blocks_window" yaml:"signed_blocks_window"`
MinSignedPerWindow sdk.Dec `json:"min_signed_per_window" yaml:"min_signed_per_window"`
DowntimeJailDuration time.Duration `json:"downtime_jail_duration" yaml:"downtime_jail_duration"`
SlashFractionDoubleSign sdk.Dec `json:"slash_fraction_double_sign" yaml:"slash_fraction_double_sign"`
SlashFractionDowntime sdk.Dec `json:"slash_fraction_downtime" yaml:"slash_fraction_downtime"`
}

View File

@ -0,0 +1,31 @@
package v038
import (
v038staking "github.com/cosmos/cosmos-sdk/x/staking/types"
"github.com/kava-labs/kava/migrate/v0_8/sdk/staking/v18de63"
)
func Migrate(oldGenState v18de63.GenesisState) v038staking.GenesisState {
// old and new types are identical except for a new HistoricalEntries field
newParams := v038staking.Params{
UnbondingTime: oldGenState.Params.UnbondingTime,
MaxValidators: oldGenState.Params.MaxValidators,
MaxEntries: oldGenState.Params.MaxEntries,
HistoricalEntries: v038staking.DefaultHistoricalEntries,
BondDenom: oldGenState.Params.BondDenom,
}
return v038staking.GenesisState{
Params: newParams,
LastTotalPower: oldGenState.LastTotalPower,
LastValidatorPowers: oldGenState.LastValidatorPowers,
Validators: oldGenState.Validators,
Delegations: oldGenState.Delegations,
UnbondingDelegations: oldGenState.UnbondingDelegations,
Redelegations: oldGenState.Redelegations,
Exported: oldGenState.Exported,
}
}

View File

@ -0,0 +1,31 @@
package v18de63
import (
"time"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/staking"
)
// All v18de63 types here are identical to current v0.38 types except Params which has a new field HistoricalEntries.
// Since they're identical, the types here import current types rather than copying them in from v18de63.
const ModuleName = staking.ModuleName
type GenesisState struct {
Params Params `json:"params" yaml:"params"`
LastTotalPower sdk.Int `json:"last_total_power" yaml:"last_total_power"`
LastValidatorPowers []staking.LastValidatorPower `json:"last_validator_powers" yaml:"last_validator_powers"`
Validators staking.Validators `json:"validators" yaml:"validators"`
Delegations staking.Delegations `json:"delegations" yaml:"delegations"`
UnbondingDelegations []staking.UnbondingDelegation `json:"unbonding_delegations" yaml:"unbonding_delegations"`
Redelegations []staking.Redelegation `json:"redelegations" yaml:"redelegations"`
Exported bool `json:"exported" yaml:"exported"`
}
type Params struct {
UnbondingTime time.Duration `json:"unbonding_time" yaml:"unbonding_time"` // time duration of unbonding
MaxValidators uint16 `json:"max_validators" yaml:"max_validators"` // maximum number of validators (max uint16 = 65535)
MaxEntries uint16 `json:"max_entries" yaml:"max_entries"` // max entries for either unbonding delegation or redelegation (per pair/trio)
BondDenom string `json:"bond_denom" yaml:"bond_denom"` // bondable coin denomination
}

View File

@ -0,0 +1,12 @@
package v18de63
import (
"github.com/cosmos/cosmos-sdk/codec"
)
// Note some types are unnecessary for unmarshalling genesis.json so have not been registered
// RegisterCodec registers the account types and interface
func RegisterCodec(cdc *codec.Codec) {
cdc.RegisterConcrete(&ModuleAccount{}, "cosmos-sdk/ModuleAccount", nil)
}

View File

@ -0,0 +1,12 @@
package v18de63
import (
authtypes "github.com/kava-labs/kava/migrate/v0_8/sdk/auth/v18de63"
)
// ModuleAccount defines an account for modules that holds coins on a pool
type ModuleAccount struct {
*authtypes.BaseAccount
Name string `json:"name" yaml:"name"` // name of the module
Permissions []string `json:"permissions" yaml:"permissions"` // permissions of module account
}

View File

@ -0,0 +1,22 @@
package v032
import (
"github.com/cosmos/cosmos-sdk/codec"
//amino "github.com/tendermint/go-amino"
cryptoAmino "github.com/tendermint/tendermint/crypto/encoding/amino"
"github.com/tendermint/tendermint/types"
)
// Replace amino codec with sdk codec to avoid an explicit amino import in go.mod.
// This will use a different version of amino from tendermint v0.32, but they are backwards compatible.
var Cdc = codec.New()
func init() {
RegisterBlockAmino(Cdc)
}
func RegisterBlockAmino(cdc *codec.Codec) {
cryptoAmino.RegisterAmino(cdc)
types.RegisterEvidences(cdc) // v0.33 is backwards compatible with v0.32 here
}

View File

@ -0,0 +1,96 @@
package v032
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"time"
//"github.com/pkg/errors" // replaced this pkg with "errors" to avoid adding a dependency
tmbytes "github.com/tendermint/tendermint/libs/bytes"
"github.com/tendermint/tendermint/types"
tmtime "github.com/tendermint/tendermint/types/time"
)
const (
// MaxChainIDLen is a maximum length of the chain ID.
MaxChainIDLen = 50
)
// GenesisDoc defines the initial conditions for a tendermint blockchain, in particular its validator set.
type GenesisDoc struct {
GenesisTime time.Time `json:"genesis_time"`
ChainID string `json:"chain_id"`
ConsensusParams *ConsensusParams `json:"consensus_params,omitempty"`
Validators []types.GenesisValidator `json:"validators,omitempty"` // v0.33 GenesisValidator is backwards compatible with v0.32
AppHash tmbytes.HexBytes `json:"app_hash"` // moved from `common` to `bytes` as they are the same between v0.32 and v0.33
AppState json.RawMessage `json:"app_state,omitempty"`
}
// ValidateAndComplete checks that all necessary fields are present
// and fills in defaults for optional fields left empty
func (genDoc *GenesisDoc) ValidateAndComplete() error {
if genDoc.ChainID == "" {
return errors.New("Genesis doc must include non-empty chain_id")
}
if len(genDoc.ChainID) > MaxChainIDLen {
return fmt.Errorf("chain_id in genesis doc is too long (max: %d)", MaxChainIDLen) // replaced errors with fmt
}
if genDoc.ConsensusParams == nil {
genDoc.ConsensusParams = DefaultConsensusParams()
} /*else if err := genDoc.ConsensusParams.Validate(); err != nil {
return err
}*/ // remove validation to avoid having to copy in more types and methods from v0.32
for i, v := range genDoc.Validators {
if v.Power == 0 {
return fmt.Errorf("The genesis file cannot contain validators with no voting power: %v", v) // replaced errors with fmt
}
if len(v.Address) > 0 && !bytes.Equal(v.PubKey.Address(), v.Address) {
return fmt.Errorf("Incorrect address for validator %v in the genesis file, should be %v", v, v.PubKey.Address()) // replaced errors with fmt
}
if len(v.Address) == 0 {
genDoc.Validators[i].Address = v.PubKey.Address()
}
}
if genDoc.GenesisTime.IsZero() {
genDoc.GenesisTime = tmtime.Now()
}
return nil
}
//------------------------------------------------------------
// Make genesis state from file
// GenesisDocFromJSON unmarshalls JSON data into a GenesisDoc.
func GenesisDocFromJSON(jsonBlob []byte) (*GenesisDoc, error) {
genDoc := GenesisDoc{}
err := Cdc.UnmarshalJSON(jsonBlob, &genDoc)
if err != nil {
return nil, err
}
if err := genDoc.ValidateAndComplete(); err != nil {
return nil, err
}
return &genDoc, err
}
// GenesisDocFromFile reads JSON data from a file and unmarshalls it into a GenesisDoc.
func GenesisDocFromFile(genDocFile string) (*GenesisDoc, error) {
jsonBlob, err := ioutil.ReadFile(genDocFile)
if err != nil {
return nil, fmt.Errorf("Couldn't read GenesisDoc file: %w", err)
}
genDoc, err := GenesisDocFromJSON(jsonBlob)
if err != nil {
return nil, fmt.Errorf("Error reading GenesisDoc at %v: %w", genDocFile, err)
}
return genDoc, nil
}

View File

@ -0,0 +1,61 @@
package v032
// ConsensusParams contains consensus critical parameters that determine the
// validity of blocks.
type ConsensusParams struct {
Block BlockParams `json:"block"`
Evidence EvidenceParams `json:"evidence"`
Validator ValidatorParams `json:"validator"`
}
// BlockParams define limits on the block size and gas plus minimum time
// between blocks.
type BlockParams struct {
MaxBytes int64 `json:"max_bytes"`
MaxGas int64 `json:"max_gas"`
// Minimum time increment between consecutive blocks (in milliseconds)
// Not exposed to the application.
TimeIotaMs int64 `json:"time_iota_ms"`
}
// EvidenceParams determine how we handle evidence of malfeasance.
type EvidenceParams struct {
MaxAge int64 `json:"max_age"` // only accept new evidence more recent than this
}
// ValidatorParams restrict the public key types validators can use.
// NOTE: uses ABCI pubkey naming, not Amino names.
type ValidatorParams struct {
PubKeyTypes []string `json:"pub_key_types"`
}
// // DefaultConsensusParams returns a default ConsensusParams.
func DefaultConsensusParams() *ConsensusParams {
return &ConsensusParams{
DefaultBlockParams(),
DefaultEvidenceParams(),
DefaultValidatorParams(),
}
}
// DefaultBlockParams returns a default BlockParams.
func DefaultBlockParams() BlockParams {
return BlockParams{
MaxBytes: 22020096, // 21MB
MaxGas: -1,
TimeIotaMs: 1000, // 1s
}
}
// DefaultEvidenceParams Params returns a default EvidenceParams.
func DefaultEvidenceParams() EvidenceParams {
return EvidenceParams{
MaxAge: 100000, // 27.8 hrs at 1block/s
}
}
// DefaultValidatorParams returns a default ValidatorParams, which allows
// only ed25519 pubkeys.
func DefaultValidatorParams() ValidatorParams {
return ValidatorParams{[]string{ABCIPubKeyTypeEd25519}}
}

View File

@ -0,0 +1,3 @@
package v032
const ABCIPubKeyTypeEd25519 = "ed25519"

View File

@ -0,0 +1,31 @@
package v033
import (
"time"
v032tendermint "github.com/kava-labs/kava/migrate/v0_8/tendermint/v0_32"
tmtypes "github.com/tendermint/tendermint/types"
)
func Migrate(v032GenDoc v032tendermint.GenesisDoc) tmtypes.GenesisDoc {
// migrate evidence params
newConsensusParams := tmtypes.ConsensusParams{
Block: tmtypes.BlockParams(v032GenDoc.ConsensusParams.Block),
Evidence: tmtypes.EvidenceParams{
MaxAgeNumBlocks: v032GenDoc.ConsensusParams.Evidence.MaxAge,
MaxAgeDuration: time.Duration(int64(time.Second) * 6 * v032GenDoc.ConsensusParams.Evidence.MaxAge), // assume 6 second block times
},
Validator: tmtypes.ValidatorParams(v032GenDoc.ConsensusParams.Validator),
}
return tmtypes.GenesisDoc{
GenesisTime: v032GenDoc.GenesisTime,
ChainID: v032GenDoc.ChainID,
ConsensusParams: &newConsensusParams,
Validators: v032GenDoc.Validators,
AppHash: v032GenDoc.AppHash,
AppState: v032GenDoc.AppState,
}
}

1114
migrate/v0_8/testdata/all-new.json vendored Normal file

File diff suppressed because it is too large Load Diff

1057
migrate/v0_8/testdata/all-old.json vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,26 @@
{
"params": {
"max_memo_characters": "256",
"sig_verify_cost_ed25519": "590",
"sig_verify_cost_secp256k1": "1000",
"tx_sig_limit": "7",
"tx_size_cost_per_byte": "10"
},
"accounts": [
{
"type": "cosmos-sdk/Account",
"value": {
"account_number": 95,
"address": "kava1ceun2qqw65qce5la33j8zv8ltyyaqqfcxftutz",
"coins": [
{
"amount": "9950000",
"denom": "ukava"
}
],
"public_key": "kavapub1ytql0csgqgfzd666axrjzqc4p3rlrz4ryut2v4r7m29hx6gx0h8pr52pvfzmw7r4dnurt9kctgfzd666axrjzqel670atjnfm8al2jjq7y69ttrjnw96uyqe83342g537mwvej67dqfzd666axrjzqkw686lp4ylpv29fv8t6hxxef5ln33a286a7507utmlc03hgyejsqfzd666axrjzqaa8j22fy52lpjgql0864qm9lqftadj3859z4q205d7xedn974suvfzd666axrjzq4ckxdsxywc0gqhfrxk39z058v3f3yuvmljsagdp2ggx89z5hru9gx07cnh",
"sequence": 3
}
}
]
}

View File

@ -0,0 +1,53 @@
{
"params": {
"max_memo_characters": "256",
"sig_verify_cost_ed25519": "590",
"sig_verify_cost_secp256k1": "1000",
"tx_sig_limit": "7",
"tx_size_cost_per_byte": "10"
},
"accounts": [
{
"type": "cosmos-sdk/Account",
"value": {
"account_number": "95",
"address": "kava1ceun2qqw65qce5la33j8zv8ltyyaqqfcxftutz",
"coins": [
{
"amount": "9950000",
"denom": "ukava"
}
],
"public_key": {
"type": "tendermint/PubKeyMultisigThreshold",
"value": {
"pubkeys": [
{
"type": "tendermint/PubKeySecp256k1",
"value": "AxUMR/GKoycWplR+2otzaQZ9zhHRQWJFt3h1bPg1ltha"
},
{
"type": "tendermint/PubKeySecp256k1",
"value": "Az/Xn9XKadn79UpA8TRVrHKbi64QGTxjVSKR9tzMy15o"
},
{
"type": "tendermint/PubKeySecp256k1",
"value": "As7R9fDUnwsUVLDr1cxspp+cY9UfXfUf7i9/w+N0EzKA"
},
{
"type": "tendermint/PubKeySecp256k1",
"value": "A708lKSSivhkgH3n1UGy/AlfWyiehRVAp9G+Nlsy+rDj"
},
{
"type": "tendermint/PubKeySecp256k1",
"value": "ArixmwMR2HoBdIzWiUT6HZFMScZv8odQ0KkIMcoqXHwq"
}
],
"threshold": "2"
}
},
"sequence": "3"
}
}
]
}

View File

@ -0,0 +1,26 @@
{
"params": {
"max_memo_characters": "256",
"sig_verify_cost_ed25519": "590",
"sig_verify_cost_secp256k1": "1000",
"tx_sig_limit": "7",
"tx_size_cost_per_byte": "10"
},
"accounts": [
{
"type": "cosmos-sdk/Account",
"value": {
"account_number": 4589,
"address": "kava1qqfzmtucfc2ky6qm2yysypvehay0jytjp87czf",
"coins": [
{
"amount": "2769",
"denom": "ukava"
}
],
"public_key": "",
"sequence": 0
}
}
]
}

View File

@ -0,0 +1,26 @@
{
"params": {
"max_memo_characters": "256",
"sig_verify_cost_ed25519": "590",
"sig_verify_cost_secp256k1": "1000",
"tx_sig_limit": "7",
"tx_size_cost_per_byte": "10"
},
"accounts": [
{
"type": "cosmos-sdk/Account",
"value": {
"account_number": "4589",
"address": "kava1qqfzmtucfc2ky6qm2yysypvehay0jytjp87czf",
"coins": [
{
"amount": "2769",
"denom": "ukava"
}
],
"public_key": null,
"sequence": "0"
}
}
]
}

View File

@ -0,0 +1,31 @@
{
"params": {
"max_memo_characters": "256",
"sig_verify_cost_ed25519": "590",
"sig_verify_cost_secp256k1": "1000",
"tx_sig_limit": "7",
"tx_size_cost_per_byte": "10"
},
"accounts": [
{
"type": "cosmos-sdk/ModuleAccount",
"value": {
"account_number": 168,
"address": "kava1fl48vsnmsdzcv85q5d2q4z5ajdha8yu3fwaj0s",
"coins": [
{
"amount": "87921781313382",
"denom": "ukava"
}
],
"public_key": "",
"sequence": 0,
"name": "bonded_tokens_pool",
"permissions": [
"burner",
"staking"
]
}
}
]
}

View File

@ -0,0 +1,33 @@
{
"params": {
"max_memo_characters": "256",
"sig_verify_cost_ed25519": "590",
"sig_verify_cost_secp256k1": "1000",
"tx_sig_limit": "7",
"tx_size_cost_per_byte": "10"
},
"accounts": [
{
"type": "cosmos-sdk/ModuleAccount",
"value": {
"BaseAccount": {
"account_number": "168",
"address": "kava1fl48vsnmsdzcv85q5d2q4z5ajdha8yu3fwaj0s",
"coins": [
{
"amount": "87921781313382",
"denom": "ukava"
}
],
"public_key": null,
"sequence": "0"
},
"name": "bonded_tokens_pool",
"permissions": [
"burner",
"staking"
]
}
}
]
}

View File

@ -0,0 +1,119 @@
{
"params": {
"max_memo_characters": "256",
"sig_verify_cost_ed25519": "590",
"sig_verify_cost_secp256k1": "1000",
"tx_sig_limit": "7",
"tx_size_cost_per_byte": "10"
},
"accounts": [
{
"type": "cosmos-sdk/PeriodicVestingAccount",
"value": {
"account_number": 118,
"address": "kava13vt44t6uwht8mnsy0x0nx8873r5tfux7tkh4ah",
"coins": [
{
"amount": "62500000000",
"denom": "ukava"
}
],
"public_key": "",
"sequence": 0,
"delegated_free": [],
"delegated_vesting": [],
"end_time": 1667656800,
"original_vesting": [
{
"amount": "62490000000",
"denom": "ukava"
}
],
"start_time": 1572962400,
"vesting_periods": [
{
"amount": [
{
"amount": "15615000000",
"denom": "ukava"
}
],
"length": 31622400
},
{
"amount": [
{
"amount": "5859375000",
"denom": "ukava"
}
],
"length": 7948800
},
{
"amount": [
{
"amount": "5859375000",
"denom": "ukava"
}
],
"length": 7689600
},
{
"amount": [
{
"amount": "5859375000",
"denom": "ukava"
}
],
"length": 7948800
},
{
"amount": [
{
"amount": "5859375000",
"denom": "ukava"
}
],
"length": 7948800
},
{
"amount": [
{
"amount": "5859375000",
"denom": "ukava"
}
],
"length": 7948800
},
{
"amount": [
{
"amount": "5859375000",
"denom": "ukava"
}
],
"length": 7689600
},
{
"amount": [
{
"amount": "5859375000",
"denom": "ukava"
}
],
"length": 7948800
},
{
"amount": [
{
"amount": "5859375000",
"denom": "ukava"
}
],
"length": 7948800
}
]
}
}
]
}

View File

@ -0,0 +1,123 @@
{
"params": {
"max_memo_characters": "256",
"sig_verify_cost_ed25519": "590",
"sig_verify_cost_secp256k1": "1000",
"tx_sig_limit": "7",
"tx_size_cost_per_byte": "10"
},
"accounts": [
{
"type": "cosmos-sdk/PeriodicVestingAccount",
"value": {
"BaseVestingAccount": {
"BaseAccount": {
"account_number": "118",
"address": "kava13vt44t6uwht8mnsy0x0nx8873r5tfux7tkh4ah",
"coins": [
{
"amount": "62500000000",
"denom": "ukava"
}
],
"public_key": null,
"sequence": "0"
},
"delegated_free": [],
"delegated_vesting": [],
"end_time": "1667656800",
"original_vesting": [
{
"amount": "62490000000",
"denom": "ukava"
}
]
},
"start_time": "1572962400",
"vesting_periods": [
{
"amount": [
{
"amount": "15615000000",
"denom": "ukava"
}
],
"length": "31622400"
},
{
"amount": [
{
"amount": "5859375000",
"denom": "ukava"
}
],
"length": "7948800"
},
{
"amount": [
{
"amount": "5859375000",
"denom": "ukava"
}
],
"length": "7689600"
},
{
"amount": [
{
"amount": "5859375000",
"denom": "ukava"
}
],
"length": "7948800"
},
{
"amount": [
{
"amount": "5859375000",
"denom": "ukava"
}
],
"length": "7948800"
},
{
"amount": [
{
"amount": "5859375000",
"denom": "ukava"
}
],
"length": "7948800"
},
{
"amount": [
{
"amount": "5859375000",
"denom": "ukava"
}
],
"length": "7689600"
},
{
"amount": [
{
"amount": "5859375000",
"denom": "ukava"
}
],
"length": "7948800"
},
{
"amount": [
{
"amount": "5859375000",
"denom": "ukava"
}
],
"length": "7948800"
}
]
}
}
]
}

View File

@ -0,0 +1,144 @@
{
"params": {
"max_memo_characters": "256",
"sig_verify_cost_ed25519": "590",
"sig_verify_cost_secp256k1": "1000",
"tx_sig_limit": "7",
"tx_size_cost_per_byte": "10"
},
"accounts": [
{
"type": "cosmos-sdk/ValidatorVestingAccount",
"value": {
"address": "kava1pjm84k90qnmcexv6704cxe243j52vww572j78u",
"coins": [
{
"amount": "410694803",
"denom": "ukava"
}
],
"public_key": "kavapub1addwnpepqdt5kgxp76qmz6hfdpkfeee5d9ufes34aa4l7yryksch3dc5c3jwgdh2lju",
"account_number": 104,
"sequence": 10,
"delegated_free": [],
"delegated_vesting": [
{
"amount": "699980000000",
"denom": "ukava"
}
],
"end_time": 1636120800,
"original_vesting": [
{
"amount": "699990000000",
"denom": "ukava"
}
],
"start_time": 1572962400,
"vesting_periods": [
{
"amount": [
{
"amount": "349995000000",
"denom": "ukava"
}
],
"length": 15724800
},
{
"amount": [
{
"amount": "58332500000",
"denom": "ukava"
}
],
"length": 7948800
},
{
"amount": [
{
"amount": "58332500000",
"denom": "ukava"
}
],
"length": 7948800
},
{
"amount": [
{
"amount": "58332500000",
"denom": "ukava"
}
],
"length": 7948800
},
{
"amount": [
{
"amount": "58332500000",
"denom": "ukava"
}
],
"length": 7689600
},
{
"amount": [
{
"amount": "58332500000",
"denom": "ukava"
}
],
"length": 7948800
},
{
"amount": [
{
"amount": "58332500000",
"denom": "ukava"
}
],
"length": 7948800
}
],
"current_period_progress": {
"missed_blocks": 9,
"total_blocks": 190565
},
"debt_after_failed_vesting": [],
"return_address": "kava1qvsus5qg8yhre7k2c78xkkw4nvqqgev7ezrja8",
"signing_threshold": 90,
"validator_address": "kavavalcons1rcgcrswwvunnfrx73ksc5ks8t9jtcnpaehf726",
"vesting_period_progress": [
{
"period_complete": true,
"vesting_successful": true
},
{
"period_complete": false,
"vesting_successful": false
},
{
"period_complete": false,
"vesting_successful": false
},
{
"period_complete": false,
"vesting_successful": false
},
{
"period_complete": false,
"vesting_successful": false
},
{
"period_complete": false,
"vesting_successful": false
},
{
"period_complete": false,
"vesting_successful": false
}
]
}
}
]
}

View File

@ -0,0 +1,153 @@
{
"params": {
"max_memo_characters": "256",
"sig_verify_cost_ed25519": "590",
"sig_verify_cost_secp256k1": "1000",
"tx_sig_limit": "7",
"tx_size_cost_per_byte": "10"
},
"accounts": [
{
"type": "cosmos-sdk/ValidatorVestingAccount",
"value": {
"PeriodicVestingAccount": {
"BaseVestingAccount": {
"BaseAccount": {
"account_number": "104",
"address": "kava1pjm84k90qnmcexv6704cxe243j52vww572j78u",
"coins": [
{
"amount": "410694803",
"denom": "ukava"
}
],
"public_key": {
"type": "tendermint/PubKeySecp256k1",
"value": "A1dLIMH2gbFq6WhsnOc0aXicwjXva/8QZLQxeLcUxGTk"
},
"sequence": "10"
},
"delegated_free": [],
"delegated_vesting": [
{
"amount": "699980000000",
"denom": "ukava"
}
],
"end_time": "1636120800",
"original_vesting": [
{
"amount": "699990000000",
"denom": "ukava"
}
]
},
"start_time": "1572962400",
"vesting_periods": [
{
"amount": [
{
"amount": "349995000000",
"denom": "ukava"
}
],
"length": "15724800"
},
{
"amount": [
{
"amount": "58332500000",
"denom": "ukava"
}
],
"length": "7948800"
},
{
"amount": [
{
"amount": "58332500000",
"denom": "ukava"
}
],
"length": "7948800"
},
{
"amount": [
{
"amount": "58332500000",
"denom": "ukava"
}
],
"length": "7948800"
},
{
"amount": [
{
"amount": "58332500000",
"denom": "ukava"
}
],
"length": "7689600"
},
{
"amount": [
{
"amount": "58332500000",
"denom": "ukava"
}
],
"length": "7948800"
},
{
"amount": [
{
"amount": "58332500000",
"denom": "ukava"
}
],
"length": "7948800"
}
]
},
"current_period_progress": {
"missed_blocks": "9",
"total_blocks": "190565"
},
"debt_after_failed_vesting": [],
"return_address": "kava1qvsus5qg8yhre7k2c78xkkw4nvqqgev7ezrja8",
"signing_threshold": "90",
"validator_address": "kavavalcons1rcgcrswwvunnfrx73ksc5ks8t9jtcnpaehf726",
"vesting_period_progress": [
{
"period_complete": true,
"vesting_successful": true
},
{
"period_complete": false,
"vesting_successful": false
},
{
"period_complete": false,
"vesting_successful": false
},
{
"period_complete": false,
"vesting_successful": false
},
{
"period_complete": false,
"vesting_successful": false
},
{
"period_complete": false,
"vesting_successful": false
},
{
"period_complete": false,
"vesting_successful": false
}
]
}
}
]
}

View File

@ -0,0 +1,251 @@
{
"params": {
"base_proposer_reward": "0.010000000000000000",
"bonus_proposer_reward": "0.040000000000000000",
"community_tax": "0.000000000000000000",
"withdraw_addr_enabled": false
},
"delegator_starting_infos": [
{
"delegator_address": "kava1qyc2cfl0nw8r95dsdw534x99wq0xcj9rksmhx4",
"starting_info": {
"creation_height": "252",
"previous_period": "1",
"stake": "3000000000.000000000000000000"
},
"validator_address": "kavavaloper1qyc2cfl0nw8r95dsdw534x99wq0xcj9rmxpl7z"
},
{
"delegator_address": "kava1qvsus5qg8yhre7k2c78xkkw4nvqqgev7ezrja8",
"starting_info": {
"creation_height": "1064509",
"previous_period": "82",
"stake": "20000000000.000000000000000000"
},
"validator_address": "kavavaloper1qyc2cfl0nw8r95dsdw534x99wq0xcj9rmxpl7z"
},
{
"delegator_address": "kava1fhj7pkuvwflr7z7ngp2v9tj7g58aq2tjh2q84j",
"starting_info": {
"creation_height": "2082995",
"previous_period": "87",
"stake": "0.002955339603289120"
},
"validator_address": "kavavaloper1qyc2cfl0nw8r95dsdw534x99wq0xcj9rmxpl7z"
},
{
"delegator_address": "kava12xprvq28w06ylkq45vnwkwpxtmv03fd5t4r70n",
"starting_info": {
"creation_height": "580421",
"previous_period": "3",
"stake": "9000000.000000000000000000"
},
"validator_address": "kavavaloper1qyc2cfl0nw8r95dsdw534x99wq0xcj9rmxpl7z"
}
],
"delegator_withdraw_infos": [],
"fee_pool": {
"community_pool": [
{
"amount": "4273.406019327669990744",
"denom": "ukava"
}
]
},
"outstanding_rewards": [
{
"outstanding_rewards": [
{
"amount": "407746339.697585794084260309",
"denom": "ukava"
}
],
"validator_address": "kavavaloper1qyc2cfl0nw8r95dsdw534x99wq0xcj9rmxpl7z"
},
{
"outstanding_rewards": [
{
"amount": "270577067.008799337336325953",
"denom": "ukava"
}
],
"validator_address": "kavavaloper1qfy0e2w62g6j4jg5djcqd4py3zsaeqexjplj2d"
},
{
"outstanding_rewards": [
{
"amount": "393922320.552371198553884301",
"denom": "ukava"
}
],
"validator_address": "kavavaloper1q3y9qga5hf360dmzta67vp54qz25tmv4hhkk4t"
},
{
"outstanding_rewards": [
{
"amount": "6319216.166548663982974419",
"denom": "ukava"
}
],
"validator_address": "kavavaloper1qk0pta4ga5t8p5vv7me8dz32lvcrv2rp098cas"
}
],
"previous_proposer": "kavavalcons1l78wcdl4lygm38l39jcq5sep2l7ku7z8m9mxwg",
"validator_accumulated_commissions": [
{
"accumulated": [
{
"amount": "191541157.919101533286771494",
"denom": "ukava"
}
],
"validator_address": "kavavaloper1qyc2cfl0nw8r95dsdw534x99wq0xcj9rmxpl7z"
},
{
"accumulated": [
{
"amount": "270577067.008799223260139456",
"denom": "ukava"
}
],
"validator_address": "kavavaloper1qfy0e2w62g6j4jg5djcqd4py3zsaeqexjplj2d"
},
{
"accumulated": [
{
"amount": "76703922.531362561792462166",
"denom": "ukava"
}
],
"validator_address": "kavavaloper1q3y9qga5hf360dmzta67vp54qz25tmv4hhkk4t"
},
{
"accumulated": [
{
"amount": "1846231.214029771840277834",
"denom": "ukava"
}
],
"validator_address": "kavavaloper1qk0pta4ga5t8p5vv7me8dz32lvcrv2rp098cas"
}
],
"validator_current_rewards": [
{
"rewards": {
"period": "88",
"rewards": [
{
"amount": "41505563.459999591766155596",
"denom": "ukava"
}
]
},
"validator_address": "kavavaloper1qyc2cfl0nw8r95dsdw534x99wq0xcj9rmxpl7z"
},
{
"rewards": {
"period": "76",
"rewards": null
},
"validator_address": "kavavaloper1qfy0e2w62g6j4jg5djcqd4py3zsaeqexjplj2d"
},
{
"rewards": {
"period": "22",
"rewards": [
{
"amount": "178497730.995723717812777164",
"denom": "ukava"
}
]
},
"validator_address": "kavavaloper1q3y9qga5hf360dmzta67vp54qz25tmv4hhkk4t"
},
{
"rewards": {
"period": "20",
"rewards": [
{
"amount": "4248603.711022474381844829",
"denom": "ukava"
}
]
},
"validator_address": "kavavaloper1qk0pta4ga5t8p5vv7me8dz32lvcrv2rp098cas"
}
],
"validator_historical_rewards": [
{
"period": "1",
"rewards": {
"cumulative_reward_ratio": null,
"reference_count": 1
},
"validator_address": "kavavaloper1qyc2cfl0nw8r95dsdw534x99wq0xcj9rmxpl7z"
},
{
"period": "82",
"rewards": {
"cumulative_reward_ratio": [
{
"amount": "0.017163087196561731",
"denom": "ukava"
}
],
"reference_count": 1
},
"validator_address": "kavavaloper1qyc2cfl0nw8r95dsdw534x99wq0xcj9rmxpl7z"
},
{
"period": "87",
"rewards": {
"cumulative_reward_ratio": [
{
"amount": "0.022515630092578764",
"denom": "ukava"
}
],
"reference_count": 2
},
"validator_address": "kavavaloper1qyc2cfl0nw8r95dsdw534x99wq0xcj9rmxpl7z"
}
],
"validator_slash_events": [
{
"height": "1415519",
"period": "85",
"validator_address": "kavavaloper1qyc2cfl0nw8r95dsdw534x99wq0xcj9rmxpl7z",
"validator_slash_event": {
"fraction": "0.000099999130782470",
"validator_period": "85"
}
},
{
"height": "1971549",
"period": "86",
"validator_address": "kavavaloper1qyc2cfl0nw8r95dsdw534x99wq0xcj9rmxpl7z",
"validator_slash_event": {
"fraction": "0.000099996092041800",
"validator_period": "86"
}
},
{
"height": "1433843",
"period": "9",
"validator_address": "kavavaloper18cf35l7req0k6ulqapeyv830mrrucn9xj87plr",
"validator_slash_event": {
"fraction": "0.000100000000000000",
"validator_period": "9"
}
},
{
"height": "2200561",
"period": "12",
"validator_address": "kavavaloper1fw7vjc3fphahqxpdjypddlulnltxws8g0mrds7",
"validator_slash_event": {
"fraction": "0.000100000000000000",
"validator_period": "12"
}
}
]
}

View File

@ -0,0 +1,249 @@
{
"base_proposer_reward": "0.010000000000000000",
"bonus_proposer_reward": "0.040000000000000000",
"community_tax": "0.000000000000000000",
"delegator_starting_infos": [
{
"delegator_address": "kava1qyc2cfl0nw8r95dsdw534x99wq0xcj9rksmhx4",
"starting_info": {
"creation_height": "252",
"previous_period": "1",
"stake": "3000000000.000000000000000000"
},
"validator_address": "kavavaloper1qyc2cfl0nw8r95dsdw534x99wq0xcj9rmxpl7z"
},
{
"delegator_address": "kava1qvsus5qg8yhre7k2c78xkkw4nvqqgev7ezrja8",
"starting_info": {
"creation_height": "1064509",
"previous_period": "82",
"stake": "20000000000.000000000000000000"
},
"validator_address": "kavavaloper1qyc2cfl0nw8r95dsdw534x99wq0xcj9rmxpl7z"
},
{
"delegator_address": "kava1fhj7pkuvwflr7z7ngp2v9tj7g58aq2tjh2q84j",
"starting_info": {
"creation_height": "2082995",
"previous_period": "87",
"stake": "0.002955339603289120"
},
"validator_address": "kavavaloper1qyc2cfl0nw8r95dsdw534x99wq0xcj9rmxpl7z"
},
{
"delegator_address": "kava12xprvq28w06ylkq45vnwkwpxtmv03fd5t4r70n",
"starting_info": {
"creation_height": "580421",
"previous_period": "3",
"stake": "9000000.000000000000000000"
},
"validator_address": "kavavaloper1qyc2cfl0nw8r95dsdw534x99wq0xcj9rmxpl7z"
}
],
"delegator_withdraw_infos": [],
"fee_pool": {
"community_pool": [
{
"amount": "4273.406019327669990744",
"denom": "ukava"
}
]
},
"outstanding_rewards": [
{
"outstanding_rewards": [
{
"amount": "407746339.697585794084260309",
"denom": "ukava"
}
],
"validator_address": "kavavaloper1qyc2cfl0nw8r95dsdw534x99wq0xcj9rmxpl7z"
},
{
"outstanding_rewards": [
{
"amount": "270577067.008799337336325953",
"denom": "ukava"
}
],
"validator_address": "kavavaloper1qfy0e2w62g6j4jg5djcqd4py3zsaeqexjplj2d"
},
{
"outstanding_rewards": [
{
"amount": "393922320.552371198553884301",
"denom": "ukava"
}
],
"validator_address": "kavavaloper1q3y9qga5hf360dmzta67vp54qz25tmv4hhkk4t"
},
{
"outstanding_rewards": [
{
"amount": "6319216.166548663982974419",
"denom": "ukava"
}
],
"validator_address": "kavavaloper1qk0pta4ga5t8p5vv7me8dz32lvcrv2rp098cas"
}
],
"previous_proposer": "kavavalcons1l78wcdl4lygm38l39jcq5sep2l7ku7z8m9mxwg",
"validator_accumulated_commissions": [
{
"accumulated": [
{
"amount": "191541157.919101533286771494",
"denom": "ukava"
}
],
"validator_address": "kavavaloper1qyc2cfl0nw8r95dsdw534x99wq0xcj9rmxpl7z"
},
{
"accumulated": [
{
"amount": "270577067.008799223260139456",
"denom": "ukava"
}
],
"validator_address": "kavavaloper1qfy0e2w62g6j4jg5djcqd4py3zsaeqexjplj2d"
},
{
"accumulated": [
{
"amount": "76703922.531362561792462166",
"denom": "ukava"
}
],
"validator_address": "kavavaloper1q3y9qga5hf360dmzta67vp54qz25tmv4hhkk4t"
},
{
"accumulated": [
{
"amount": "1846231.214029771840277834",
"denom": "ukava"
}
],
"validator_address": "kavavaloper1qk0pta4ga5t8p5vv7me8dz32lvcrv2rp098cas"
}
],
"validator_current_rewards": [
{
"rewards": {
"period": "88",
"rewards": [
{
"amount": "41505563.459999591766155596",
"denom": "ukava"
}
]
},
"validator_address": "kavavaloper1qyc2cfl0nw8r95dsdw534x99wq0xcj9rmxpl7z"
},
{
"rewards": {
"period": "76",
"rewards": null
},
"validator_address": "kavavaloper1qfy0e2w62g6j4jg5djcqd4py3zsaeqexjplj2d"
},
{
"rewards": {
"period": "22",
"rewards": [
{
"amount": "178497730.995723717812777164",
"denom": "ukava"
}
]
},
"validator_address": "kavavaloper1q3y9qga5hf360dmzta67vp54qz25tmv4hhkk4t"
},
{
"rewards": {
"period": "20",
"rewards": [
{
"amount": "4248603.711022474381844829",
"denom": "ukava"
}
]
},
"validator_address": "kavavaloper1qk0pta4ga5t8p5vv7me8dz32lvcrv2rp098cas"
}
],
"validator_historical_rewards": [
{
"period": "1",
"rewards": {
"cumulative_reward_ratio": null,
"reference_count": 1
},
"validator_address": "kavavaloper1qyc2cfl0nw8r95dsdw534x99wq0xcj9rmxpl7z"
},
{
"period": "82",
"rewards": {
"cumulative_reward_ratio": [
{
"amount": "0.017163087196561731",
"denom": "ukava"
}
],
"reference_count": 1
},
"validator_address": "kavavaloper1qyc2cfl0nw8r95dsdw534x99wq0xcj9rmxpl7z"
},
{
"period": "87",
"rewards": {
"cumulative_reward_ratio": [
{
"amount": "0.022515630092578764",
"denom": "ukava"
}
],
"reference_count": 2
},
"validator_address": "kavavaloper1qyc2cfl0nw8r95dsdw534x99wq0xcj9rmxpl7z"
}
],
"validator_slash_events": [
{
"height": "1415519",
"period": "85",
"validator_address": "kavavaloper1qyc2cfl0nw8r95dsdw534x99wq0xcj9rmxpl7z",
"validator_slash_event": {
"fraction": "0.000099999130782470",
"validator_period": "85"
}
},
{
"height": "1971549",
"period": "86",
"validator_address": "kavavaloper1qyc2cfl0nw8r95dsdw534x99wq0xcj9rmxpl7z",
"validator_slash_event": {
"fraction": "0.000099996092041800",
"validator_period": "86"
}
},
{
"height": "1433843",
"period": "9",
"validator_address": "kavavaloper18cf35l7req0k6ulqapeyv830mrrucn9xj87plr",
"validator_slash_event": {
"fraction": "0.000100000000000000",
"validator_period": "9"
}
},
{
"height": "2200561",
"period": "12",
"validator_address": "kavavaloper1fw7vjc3fphahqxpdjypddlulnltxws8g0mrds7",
"validator_slash_event": {
"fraction": "0.000100000000000000",
"validator_period": "12"
}
}
],
"withdraw_addr_enabled": false
}

View File

@ -0,0 +1,6 @@
{
"params": {
"max_evidence_age": "1814400000000000"
},
"evidence": []
}

1
migrate/v0_8/testdata/kava-2.json vendored Normal file

File diff suppressed because one or more lines are too long

69
migrate/v0_8/testdata/slashing-new.json vendored Normal file
View File

@ -0,0 +1,69 @@
{
"missed_blocks": {
"kavavalcons1029jhm4lz26q78ftrmazf8hw7lmrt08l2vq3cs": [
{
"index": "66",
"missed": false
},
{
"index": "67",
"missed": false
},
{
"index": "68",
"missed": false
},
{
"index": "76",
"missed": false
},
{
"index": "1241",
"missed": false
}
],
"kavavalcons1030yrl85a6vskx5xn0fyt4446grfk9zy4uxssy": [
{
"index": "0",
"missed": false
},
{
"index": "1",
"missed": false
},
{
"index": "2",
"missed": false
},
{
"index": "4",
"missed": false
}
]
},
"params": {
"downtime_jail_duration": "600000000000",
"min_signed_per_window": "0.050000000000000000",
"signed_blocks_window": "10000",
"slash_fraction_double_sign": "0.050000000000000000",
"slash_fraction_downtime": "0.000100000000000000"
},
"signing_infos": {
"kavavalcons1029jhm4lz26q78ftrmazf8hw7lmrt08l2vq3cs": {
"address": "kavavalcons1029jhm4lz26q78ftrmazf8hw7lmrt08l2vq3cs",
"index_offset": "2345571",
"jailed_until": "1970-01-01T00:00:00Z",
"missed_blocks_counter": "0",
"start_height": "5",
"tombstoned": false
},
"kavavalcons1030yrl85a6vskx5xn0fyt4446grfk9zy4uxssy": {
"address": "kavavalcons1030yrl85a6vskx5xn0fyt4446grfk9zy4uxssy",
"index_offset": "1222230",
"jailed_until": "2020-02-12T19:09:03.214161979Z",
"missed_blocks_counter": "147",
"start_height": "5",
"tombstoned": false
}
}
}

70
migrate/v0_8/testdata/slashing-old.json vendored Normal file
View File

@ -0,0 +1,70 @@
{
"missed_blocks": {
"kavavalcons1029jhm4lz26q78ftrmazf8hw7lmrt08l2vq3cs": [
{
"index": "66",
"missed": false
},
{
"index": "67",
"missed": false
},
{
"index": "68",
"missed": false
},
{
"index": "76",
"missed": false
},
{
"index": "1241",
"missed": false
}
],
"kavavalcons1030yrl85a6vskx5xn0fyt4446grfk9zy4uxssy": [
{
"index": "0",
"missed": false
},
{
"index": "1",
"missed": false
},
{
"index": "2",
"missed": false
},
{
"index": "4",
"missed": false
}
]
},
"params": {
"downtime_jail_duration": "600000000000",
"max_evidence_age": "1814400000000000",
"min_signed_per_window": "0.050000000000000000",
"signed_blocks_window": "10000",
"slash_fraction_double_sign": "0.050000000000000000",
"slash_fraction_downtime": "0.000100000000000000"
},
"signing_infos": {
"kavavalcons1029jhm4lz26q78ftrmazf8hw7lmrt08l2vq3cs": {
"address": "kavavalcons1029jhm4lz26q78ftrmazf8hw7lmrt08l2vq3cs",
"index_offset": "2345571",
"jailed_until": "1970-01-01T00:00:00Z",
"missed_blocks_counter": "0",
"start_height": "5",
"tombstoned": false
},
"kavavalcons1030yrl85a6vskx5xn0fyt4446grfk9zy4uxssy": {
"address": "kavavalcons1030yrl85a6vskx5xn0fyt4446grfk9zy4uxssy",
"index_offset": "1222230",
"jailed_until": "2020-02-12T19:09:03.214161979Z",
"missed_blocks_counter": "147",
"start_height": "5",
"tombstoned": false
}
}
}

210
migrate/v0_8/testdata/staking-new.json vendored Normal file
View File

@ -0,0 +1,210 @@
{
"delegations": [
{
"delegator_address": "kava1qql069rj0vz0x8jdk5h63ecsaurq04mmt875ws",
"shares": "80098000.000000000000000000",
"validator_address": "kavavaloper1ndkn5rdl9n929am6q2zt9ndfhhggcxkhetna90"
},
{
"delegator_address": "kava1qzvq736hxfwdqgxwek3229z7ec4rfmc6s4kdc2",
"shares": "333327700000.000000000000000000",
"validator_address": "kavavaloper12g40q2parn5z9ewh5xpltmayv6y0q3zs6ddmdg"
},
{
"delegator_address": "kava1qyc2cfl0nw8r95dsdw534x99wq0xcj9rksmhx4",
"shares": "3000000000.000000000000000000",
"validator_address": "kavavaloper1qyc2cfl0nw8r95dsdw534x99wq0xcj9rmxpl7z"
},
{
"delegator_address": "kava1q8kk899edzecc86k5wx7q9l3t8rztx5lwccsme",
"shares": "0.004486575456999808",
"validator_address": "kavavaloper15urq2dtp9qce4fyc85m6upwm9xul3049dcs7da"
}
],
"exported": true,
"last_total_power": "87921748",
"last_validator_powers": [
{
"Address": "kavavaloper1xhxzmj8fvkqn76knay9x2chfra826369dhdu2c",
"Power": "933070"
},
{
"Address": "kavavaloper18zksjhrefqew0zahmts894p8asscufxvdfq702",
"Power": "14"
},
{
"Address": "kavavaloper18s9m5d5cjf0humjv7mkq8pm47kchwm0r0369cx",
"Power": "20010"
},
{
"Address": "kavavaloper18cf35l7req0k6ulqapeyv830mrrucn9xj87plr",
"Power": "1171728"
}
],
"params": {
"bond_denom": "ukava",
"max_entries": 7,
"max_validators": 100,
"unbonding_time": "1814400000000000",
"historical_entries": 0
},
"redelegations": [
{
"delegator_address": "kava1q8kk899edzecc86k5wx7q9l3t8rztx5lwccsme",
"entries": [
{
"completion_time": "2020-05-22T23:23:30.992348649Z",
"creation_height": "2110394",
"initial_balance": "315012002",
"shares_dst": "315012002.000000000000000000"
}
],
"validator_dst_address": "kavavaloper140g8fnnl46mlvfhygj3zvjqlku6x0fwu6lgey7",
"validator_src_address": "kavavaloper15urq2dtp9qce4fyc85m6upwm9xul3049dcs7da"
},
{
"delegator_address": "kava1q8kk899edzecc86k5wx7q9l3t8rztx5lwccsme",
"entries": [
{
"completion_time": "2020-05-22T23:20:15.64728237Z",
"creation_height": "2110366",
"initial_balance": "1003230066",
"shares_dst": "1003230066.000000000000000000"
}
],
"validator_dst_address": "kavavaloper1c9ye54e3pzwm3e0zpdlel6pnavrj9qqvh0atdq",
"validator_src_address": "kavavaloper140g8fnnl46mlvfhygj3zvjqlku6x0fwu6lgey7"
},
{
"delegator_address": "kava1qvsus5qg8yhre7k2c78xkkw4nvqqgev7ezrja8",
"entries": [
{
"completion_time": "2020-06-09T14:47:39.423043692Z",
"creation_height": "2327982",
"initial_balance": "1505000000000",
"shares_dst": "1505000000000.000000000000000000"
}
],
"validator_dst_address": "kavavaloper1phd8jz25lumudc7ac7rhmupvcqcv7lg3c8dprc",
"validator_src_address": "kavavaloper1wu8m65vqazssv2rh8rthv532hzggfr3h9azwz9"
}
],
"unbonding_delegations": [
{
"delegator_address": "kava1qs8m8cyw9992tgzqn7pnftf2pndmp8ft34xwvp",
"entries": [
{
"balance": "174823000",
"completion_time": "2020-06-08T16:51:21.788234654Z",
"creation_height": "2316738",
"initial_balance": "174823000"
}
],
"validator_address": "kavavaloper1ptyzewnns2kn37ewtmv6ppsvhdnmeapvl7z9xh"
},
{
"delegator_address": "kava1pjm84k90qnmcexv6704cxe243j52vww572j78u",
"entries": [
{
"balance": "50000000000",
"completion_time": "2020-06-02T03:09:04.133632623Z",
"creation_height": "2235868",
"initial_balance": "50000000000"
}
],
"validator_address": "kavavaloper1jyuv7z9at27elvmnmzh2v39dc06r9kjcy59xkr"
},
{
"delegator_address": "kava1ph5u9mfytwgy25g6k6dyf0dxvuz63qwl7eymuf",
"entries": [
{
"balance": "10000000",
"completion_time": "2020-06-10T09:08:14.122467986Z",
"creation_height": "2337413",
"initial_balance": "10000000"
}
],
"validator_address": "kavavaloper1ptyzewnns2kn37ewtmv6ppsvhdnmeapvl7z9xh"
}
],
"validators": [
{
"commission": {
"commission_rates": {
"max_change_rate": "0.500000000000000000",
"max_rate": "0.500000000000000000",
"rate": "0.500000000000000000"
},
"update_time": "2020-02-05T09:55:51.495267155Z"
},
"consensus_pubkey": "kavavalconspub1zcjduepqyj4j29k7hn58g7n6ert7mm4m7d0kllrx6h5rzzgpvjdt69r80zsq3az2xq",
"delegator_shares": "23009000000.002955930745759376",
"description": {
"details": "\"Trustless Digital Asset Management\", Twitter: @StakeCapital, operated by @bneiluj @leopoldjoy",
"identity": "",
"moniker": "Stake Capital",
"security_contact": "",
"website": ""
},
"jailed": false,
"min_self_delegation": "1",
"operator_address": "kavavaloper1qyc2cfl0nw8r95dsdw534x99wq0xcj9rmxpl7z",
"status": 2,
"tokens": "23004398541",
"unbonding_height": "1971549",
"unbonding_time": "2020-05-11T17:02:08.405902954Z"
},
{
"commission": {
"commission_rates": {
"max_change_rate": "1.000000000000000000",
"max_rate": "1.000000000000000000",
"rate": "1.000000000000000000"
},
"update_time": "2019-11-20T18:38:18.607985797Z"
},
"consensus_pubkey": "kavavalconspub1zcjduepqftv90yrm4g4w4mq47rdx9f384yxegfx7qfpkft89x2nlzafv36pq47wgls",
"delegator_shares": "20069063571.000000000000000000",
"description": {
"details": "Forking the Banks",
"identity": "EA61A46F31742B22",
"moniker": "DragonStake",
"security_contact": "dragonstake@protonmail.com",
"website": "https://dragonstake.io"
},
"jailed": false,
"min_self_delegation": "1",
"operator_address": "kavavaloper1qfy0e2w62g6j4jg5djcqd4py3zsaeqexjplj2d",
"status": 2,
"tokens": "20069063571",
"unbonding_height": "0",
"unbonding_time": "1970-01-01T00:00:00Z"
},
{
"commission": {
"commission_rates": {
"max_change_rate": "0.010000000000000000",
"max_rate": "0.200000000000000000",
"rate": "0.110000000000000000"
},
"update_time": "2019-11-21T00:42:13.651988876Z"
},
"consensus_pubkey": "kavavalconspub1zcjduepquu3m094f3j9jnklursgngn667tt3rz0ahpt4f7406qzqclc42mnqxlrn7e",
"delegator_shares": "20004700000.000000000000000000",
"description": {
"details": "Validating with love in Holland for the world :)",
"identity": "1EBAA06E87B6DD60",
"moniker": "funky",
"security_contact": "",
"website": "https://kava-funkyvalidator.nl"
},
"jailed": false,
"min_self_delegation": "1",
"operator_address": "kavavaloper1q3y9qga5hf360dmzta67vp54qz25tmv4hhkk4t",
"status": 2,
"tokens": "20004700000",
"unbonding_height": "0",
"unbonding_time": "1970-01-01T00:00:00Z"
}
]
}

209
migrate/v0_8/testdata/staking-old.json vendored Normal file
View File

@ -0,0 +1,209 @@
{
"delegations": [
{
"delegator_address": "kava1qql069rj0vz0x8jdk5h63ecsaurq04mmt875ws",
"shares": "80098000.000000000000000000",
"validator_address": "kavavaloper1ndkn5rdl9n929am6q2zt9ndfhhggcxkhetna90"
},
{
"delegator_address": "kava1qzvq736hxfwdqgxwek3229z7ec4rfmc6s4kdc2",
"shares": "333327700000.000000000000000000",
"validator_address": "kavavaloper12g40q2parn5z9ewh5xpltmayv6y0q3zs6ddmdg"
},
{
"delegator_address": "kava1qyc2cfl0nw8r95dsdw534x99wq0xcj9rksmhx4",
"shares": "3000000000.000000000000000000",
"validator_address": "kavavaloper1qyc2cfl0nw8r95dsdw534x99wq0xcj9rmxpl7z"
},
{
"delegator_address": "kava1q8kk899edzecc86k5wx7q9l3t8rztx5lwccsme",
"shares": "0.004486575456999808",
"validator_address": "kavavaloper15urq2dtp9qce4fyc85m6upwm9xul3049dcs7da"
}
],
"exported": true,
"last_total_power": "87921748",
"last_validator_powers": [
{
"Address": "kavavaloper1xhxzmj8fvkqn76knay9x2chfra826369dhdu2c",
"Power": "933070"
},
{
"Address": "kavavaloper18zksjhrefqew0zahmts894p8asscufxvdfq702",
"Power": "14"
},
{
"Address": "kavavaloper18s9m5d5cjf0humjv7mkq8pm47kchwm0r0369cx",
"Power": "20010"
},
{
"Address": "kavavaloper18cf35l7req0k6ulqapeyv830mrrucn9xj87plr",
"Power": "1171728"
}
],
"params": {
"bond_denom": "ukava",
"max_entries": 7,
"max_validators": 100,
"unbonding_time": "1814400000000000"
},
"redelegations": [
{
"delegator_address": "kava1q8kk899edzecc86k5wx7q9l3t8rztx5lwccsme",
"entries": [
{
"completion_time": "2020-05-22T23:23:30.992348649Z",
"creation_height": "2110394",
"initial_balance": "315012002",
"shares_dst": "315012002.000000000000000000"
}
],
"validator_dst_address": "kavavaloper140g8fnnl46mlvfhygj3zvjqlku6x0fwu6lgey7",
"validator_src_address": "kavavaloper15urq2dtp9qce4fyc85m6upwm9xul3049dcs7da"
},
{
"delegator_address": "kava1q8kk899edzecc86k5wx7q9l3t8rztx5lwccsme",
"entries": [
{
"completion_time": "2020-05-22T23:20:15.64728237Z",
"creation_height": "2110366",
"initial_balance": "1003230066",
"shares_dst": "1003230066.000000000000000000"
}
],
"validator_dst_address": "kavavaloper1c9ye54e3pzwm3e0zpdlel6pnavrj9qqvh0atdq",
"validator_src_address": "kavavaloper140g8fnnl46mlvfhygj3zvjqlku6x0fwu6lgey7"
},
{
"delegator_address": "kava1qvsus5qg8yhre7k2c78xkkw4nvqqgev7ezrja8",
"entries": [
{
"completion_time": "2020-06-09T14:47:39.423043692Z",
"creation_height": "2327982",
"initial_balance": "1505000000000",
"shares_dst": "1505000000000.000000000000000000"
}
],
"validator_dst_address": "kavavaloper1phd8jz25lumudc7ac7rhmupvcqcv7lg3c8dprc",
"validator_src_address": "kavavaloper1wu8m65vqazssv2rh8rthv532hzggfr3h9azwz9"
}
],
"unbonding_delegations": [
{
"delegator_address": "kava1qs8m8cyw9992tgzqn7pnftf2pndmp8ft34xwvp",
"entries": [
{
"balance": "174823000",
"completion_time": "2020-06-08T16:51:21.788234654Z",
"creation_height": "2316738",
"initial_balance": "174823000"
}
],
"validator_address": "kavavaloper1ptyzewnns2kn37ewtmv6ppsvhdnmeapvl7z9xh"
},
{
"delegator_address": "kava1pjm84k90qnmcexv6704cxe243j52vww572j78u",
"entries": [
{
"balance": "50000000000",
"completion_time": "2020-06-02T03:09:04.133632623Z",
"creation_height": "2235868",
"initial_balance": "50000000000"
}
],
"validator_address": "kavavaloper1jyuv7z9at27elvmnmzh2v39dc06r9kjcy59xkr"
},
{
"delegator_address": "kava1ph5u9mfytwgy25g6k6dyf0dxvuz63qwl7eymuf",
"entries": [
{
"balance": "10000000",
"completion_time": "2020-06-10T09:08:14.122467986Z",
"creation_height": "2337413",
"initial_balance": "10000000"
}
],
"validator_address": "kavavaloper1ptyzewnns2kn37ewtmv6ppsvhdnmeapvl7z9xh"
}
],
"validators": [
{
"commission": {
"commission_rates": {
"max_change_rate": "0.500000000000000000",
"max_rate": "0.500000000000000000",
"rate": "0.500000000000000000"
},
"update_time": "2020-02-05T09:55:51.495267155Z"
},
"consensus_pubkey": "kavavalconspub1zcjduepqyj4j29k7hn58g7n6ert7mm4m7d0kllrx6h5rzzgpvjdt69r80zsq3az2xq",
"delegator_shares": "23009000000.002955930745759376",
"description": {
"details": "\"Trustless Digital Asset Management\", Twitter: @StakeCapital, operated by @bneiluj @leopoldjoy",
"identity": "",
"moniker": "Stake Capital",
"security_contact": "",
"website": ""
},
"jailed": false,
"min_self_delegation": "1",
"operator_address": "kavavaloper1qyc2cfl0nw8r95dsdw534x99wq0xcj9rmxpl7z",
"status": 2,
"tokens": "23004398541",
"unbonding_height": "1971549",
"unbonding_time": "2020-05-11T17:02:08.405902954Z"
},
{
"commission": {
"commission_rates": {
"max_change_rate": "1.000000000000000000",
"max_rate": "1.000000000000000000",
"rate": "1.000000000000000000"
},
"update_time": "2019-11-20T18:38:18.607985797Z"
},
"consensus_pubkey": "kavavalconspub1zcjduepqftv90yrm4g4w4mq47rdx9f384yxegfx7qfpkft89x2nlzafv36pq47wgls",
"delegator_shares": "20069063571.000000000000000000",
"description": {
"details": "Forking the Banks",
"identity": "EA61A46F31742B22",
"moniker": "DragonStake",
"security_contact": "dragonstake@protonmail.com",
"website": "https://dragonstake.io"
},
"jailed": false,
"min_self_delegation": "1",
"operator_address": "kavavaloper1qfy0e2w62g6j4jg5djcqd4py3zsaeqexjplj2d",
"status": 2,
"tokens": "20069063571",
"unbonding_height": "0",
"unbonding_time": "1970-01-01T00:00:00Z"
},
{
"commission": {
"commission_rates": {
"max_change_rate": "0.010000000000000000",
"max_rate": "0.200000000000000000",
"rate": "0.110000000000000000"
},
"update_time": "2019-11-21T00:42:13.651988876Z"
},
"consensus_pubkey": "kavavalconspub1zcjduepquu3m094f3j9jnklursgngn667tt3rz0ahpt4f7406qzqclc42mnqxlrn7e",
"delegator_shares": "20004700000.000000000000000000",
"description": {
"details": "Validating with love in Holland for the world :)",
"identity": "1EBAA06E87B6DD60",
"moniker": "funky",
"security_contact": "",
"website": "https://kava-funkyvalidator.nl"
},
"jailed": false,
"min_self_delegation": "1",
"operator_address": "kavavaloper1q3y9qga5hf360dmzta67vp54qz25tmv4hhkk4t",
"status": 2,
"tokens": "20004700000",
"unbonding_height": "0",
"unbonding_time": "1970-01-01T00:00:00Z"
}
]
}

View File

@ -0,0 +1,33 @@
{
"app_hash": "",
"app_state": {},
"chain_id": "kava-2",
"consensus_params": {
"block": {
"max_bytes": "200000",
"max_gas": "2000000",
"time_iota_ms": "1000"
},
"evidence": {
"max_age_num_blocks": "1000000",
"max_age_duration": "6000000000000000"
},
"validator": {
"pub_key_types": [
"ed25519"
]
}
},
"genesis_time": "2019-11-15T14:00:00Z",
"validators": [
{
"address": "",
"name": "val",
"power": "100",
"pub_key": {
"type": "tendermint/PubKeyEd25519",
"value": "Dg91loCPZ8RCmp5SL2LEVzTG3Q51HdEdgELRFC51b3M="
}
}
]
}

View File

@ -0,0 +1,32 @@
{
"app_hash": "",
"app_state": {},
"chain_id": "kava-2",
"consensus_params": {
"block": {
"max_bytes": "200000",
"max_gas": "2000000",
"time_iota_ms": "1000"
},
"evidence": {
"max_age": "1000000"
},
"validator": {
"pub_key_types": [
"ed25519"
]
}
},
"genesis_time": "2019-11-15T14:00:00Z",
"validators": [
{
"address": "",
"name": "val",
"power": "100",
"pub_key": {
"type": "tendermint/PubKeyEd25519",
"value": "Dg91loCPZ8RCmp5SL2LEVzTG3Q51HdEdgELRFC51b3M="
}
}
]
}

View File

@ -80,7 +80,10 @@ func InitGenesis(ctx sdk.Context, k Keeper, pk types.PricefeedKeeper, sk types.S
k.SetNextCdpID(ctx, gs.StartingCdpID)
k.SetDebtDenom(ctx, gs.DebtDenom)
k.SetGovDenom(ctx, gs.GovDenom)
// only set the previous block time if it's different than default
if !gs.PreviousDistributionTime.Equal(types.DefaultPreviousDistributionTime) {
k.SetPreviousSavingsDistribution(ctx, gs.PreviousDistributionTime)
}
for _, d := range gs.Deposits {
k.SetDeposit(ctx, d)

View File

@ -69,7 +69,7 @@ func (suite *SavingsTestSuite) TestGetSetPreviousDistributionTime() {
now := tmtime.Now()
_, f := suite.keeper.GetPreviousSavingsDistribution(suite.ctx)
suite.True(f)
suite.Require().False(f) // distr time not set at genesis when the default genesis is used
suite.NotPanics(func() { suite.keeper.SetPreviousSavingsDistribution(suite.ctx, now) })

View File

@ -0,0 +1,10 @@
package v18de63
import (
"github.com/cosmos/cosmos-sdk/codec"
)
// RegisterCodec registers concrete types on the codec
func RegisterCodec(cdc *codec.Codec) {
cdc.RegisterConcrete(&ValidatorVestingAccount{}, "cosmos-sdk/ValidatorVestingAccount", nil)
}

View File

@ -0,0 +1,36 @@
package v18de63
import (
sdk "github.com/cosmos/cosmos-sdk/types"
authvestingtypes "github.com/kava-labs/kava/migrate/v0_8/sdk/auth/v18de63" // combined auth and vesting packages
)
// VestingProgress tracks the status of each vesting period
type VestingProgress struct {
PeriodComplete bool `json:"period_complete" yaml:"period_complete"`
VestingSuccessful bool `json:"vesting_successful" yaml:"vesting_successful"`
}
// CurrentPeriodProgress tracks the progress of the current vesting period
type CurrentPeriodProgress struct {
MissedBlocks int64 `json:"missed_blocks" yaml:"missed_blocks"`
TotalBlocks int64 `json:"total_blocks" yaml:"total_blocks"`
}
// ValidatorVestingAccount implements the VestingAccount interface. It
// conditionally vests by unlocking coins during each specified period, provided
// that the validator address has validated at least **SigningThreshold** blocks during
// the previous vesting period. The signing threshold takes values 0 to 100 are represents the
// percentage of blocks that must be signed each period for the vesting to complete successfully.
// If the validator has not signed at least the threshold percentage of blocks during a period,
// the coins are returned to the return address, or burned if the return address is null.
type ValidatorVestingAccount struct {
*authvestingtypes.PeriodicVestingAccount
ValidatorAddress sdk.ConsAddress `json:"validator_address" yaml:"validator_address"`
ReturnAddress sdk.AccAddress `json:"return_address" yaml:"return_address"`
SigningThreshold int64 `json:"signing_threshold" yaml:"signing_threshold"`
CurrentPeriodProgress CurrentPeriodProgress `json:"current_period_progress" yaml:"current_period_progress"`
VestingPeriodProgress []VestingProgress `json:"vesting_period_progress" yaml:"vesting_period_progress"`
DebtAfterFailedVesting sdk.Coins `json:"debt_after_failed_vesting" yaml:"debt_after_failed_vesting"`
}