Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

R4R: Fix state export/import, add to CI #2690

Merged
merged 34 commits into from
Nov 9, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
766c3b0
Update PENDING.md
cwgoes Nov 5, 2018
f20e961
Update slashing import/export
cwgoes Nov 5, 2018
85a6d88
More slashing.WriteGenesis
cwgoes Nov 5, 2018
7c88bb6
Add test import/export to CI
cwgoes Nov 5, 2018
0545e18
Efficacious import/export
cwgoes Nov 5, 2018
40fa0fd
Store equality comparision in progress
cwgoes Nov 5, 2018
ca6c0fc
Account stores match
cwgoes Nov 5, 2018
5ac2359
Onto debugging x/stake store
cwgoes Nov 5, 2018
145435f
'make format'
cwgoes Nov 5, 2018
54b9129
Fix validator bond intra-tx counter
cwgoes Nov 6, 2018
41088c4
Set timeslices for unbonding validators
cwgoes Nov 6, 2018
84e5514
Fix missed blocks
cwgoes Nov 6, 2018
c7c21ad
Fix distribution import/export
cwgoes Nov 6, 2018
ed6866a
x/gov fixes in progress
cwgoes Nov 6, 2018
4eaffaf
Fee collection keeper import/export
cwgoes Nov 6, 2018
76cb763
Switch seed to realize more discrepancies
cwgoes Nov 6, 2018
0ecc430
x/stake import/export contd...
cwgoes Nov 6, 2018
80601a6
Linter fix
cwgoes Nov 6, 2018
699f813
Fix dependancy issue
jackzampolin Nov 7, 2018
b354738
Update lockfile
jackzampolin Nov 7, 2018
dcaa533
Merge branch 'develop' into cwgoes/state-export-import-fixes
cwgoes Nov 7, 2018
f508536
Peek, don't update proposal ID
cwgoes Nov 7, 2018
0dcce00
Failing case (works on seeds 12, 13 now)
cwgoes Nov 7, 2018
5365ba1
WriteGenesis => ExportGenesis
cwgoes Nov 7, 2018
257ace9
Address remaining @jaekwon comments
cwgoes Nov 7, 2018
252d961
Works but still need to debug stake, test gov
cwgoes Nov 7, 2018
ba21c55
Delete validators from unbonding queue when re-bonded
cwgoes Nov 7, 2018
6e0948e
Failing again
cwgoes Nov 7, 2018
9a4bde0
Hook for validator deletion, fix staking genesis tests
cwgoes Nov 7, 2018
9c7cfe7
Swap to use hooks for add/remove pubkey
cwgoes Nov 8, 2018
306a6bd
Cleanup, fails again
cwgoes Nov 8, 2018
2b18c7f
More testing seeds
cwgoes Nov 8, 2018
1814284
Bug fixes!
cwgoes Nov 8, 2018
1567057
Fixup hooks
cwgoes Nov 8, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,24 @@ jobs:
export PATH="$GOBIN:$PATH"
make test_sim_gaia_fast

test_sim_gaia_import_export:
<<: *defaults
parallelism: 1
steps:
- attach_workspace:
at: /tmp/workspace
- checkout
- run:
name: dependencies
command: |
export PATH="$GOBIN:$PATH"
make get_vendor_deps
- run:
name: Test Gaia import/export simulation
command: |
export PATH="$GOBIN:$PATH"
make test_sim_gaia_import_export

test_sim_gaia_multi_seed:
<<: *defaults
parallelism: 1
Expand Down Expand Up @@ -259,6 +277,9 @@ workflows:
- test_sim_gaia_fast:
requires:
- setup_dependencies
- test_sim_gaia_import_export:
requires:
- setup_dependencies
- test_sim_gaia_multi_seed:
requires:
- setup_dependencies
Expand Down
12 changes: 11 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,15 @@ test_sim_gaia_fast:
@echo "Running quick Gaia simulation. This may take several minutes..."
@go test ./cmd/gaia/app -run TestFullGaiaSimulation -SimulationEnabled=true -SimulationNumBlocks=500 -SimulationBlockSize=200 -SimulationCommit=true -SimulationSeed=10 -v -timeout 24h

test_sim_gaia_import_export:
@echo "Running Gaia import/export simulation. This may take several minutes..."
@go test ./cmd/gaia/app -run TestGaiaImportExport -SimulationEnabled=true -SimulationNumBlocks=50 -SimulationBlockSize=200 -SimulationCommit=true -SimulationSeed=4 -v -timeout 24h
cwgoes marked this conversation as resolved.
Show resolved Hide resolved
@go test ./cmd/gaia/app -run TestGaiaImportExport -SimulationEnabled=true -SimulationNumBlocks=50 -SimulationBlockSize=200 -SimulationCommit=true -SimulationSeed=11 -v -timeout 24h
@go test ./cmd/gaia/app -run TestGaiaImportExport -SimulationEnabled=true -SimulationNumBlocks=50 -SimulationBlockSize=200 -SimulationCommit=true -SimulationSeed=12 -v -timeout 24h
@go test ./cmd/gaia/app -run TestGaiaImportExport -SimulationEnabled=true -SimulationNumBlocks=50 -SimulationBlockSize=200 -SimulationCommit=true -SimulationSeed=13 -v -timeout 24h
@go test ./cmd/gaia/app -run TestGaiaImportExport -SimulationEnabled=true -SimulationNumBlocks=50 -SimulationBlockSize=200 -SimulationCommit=true -SimulationSeed=414 -v -timeout 24h
@go test ./cmd/gaia/app -run TestGaiaImportExport -SimulationEnabled=true -SimulationNumBlocks=50 -SimulationBlockSize=200 -SimulationCommit=true -SimulationSeed=4142 -v -timeout 24h

test_sim_gaia_multi_seed:
@echo "Running multi-seed Gaia simulation. This may take awhile!"
@bash scripts/multisim.sh 25
Expand Down Expand Up @@ -250,4 +259,5 @@ localnet-stop:
check_tools check_dev_tools get_tools get_dev_tools get_vendor_deps draw_deps test test_cli test_unit \
test_cover test_lint benchmark devdoc_init devdoc devdoc_save devdoc_update \
build-linux build-docker-gaiadnode localnet-start localnet-stop \
format check-ledger test_sim_gaia_nondeterminism test_sim_modules test_sim_gaia_fast test_sim_gaia_multi_seed update_tools update_dev_tools
format check-ledger test_sim_gaia_nondeterminism test_sim_modules test_sim_gaia_fast \
cwgoes marked this conversation as resolved.
Show resolved Hide resolved
test_sim_gaia_multi_seed test_sim_gaia_import_export update_tools update_dev_tools
5 changes: 3 additions & 2 deletions PENDING.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ FEATURES
* Gaia

* SDK
* (#1336) Mechanism for SDK Users to configure their own Bech32 prefixes instead of using the default cosmos prefixes.
- \#1336 Mechanism for SDK Users to configure their own Bech32 prefixes instead of using the default cosmos prefixes.

* Tendermint

Expand Down Expand Up @@ -65,7 +65,8 @@ BUG FIXES
* Gaia CLI (`gaiacli`)

* Gaia
- \#2670 [x/stake] fixed incorrect `IterateBondedValidators` and split into two functions: `IterateBondedValidators` and `IterateLastBlockConsValidators`
- \#2670 [x/stake] fixed incorrent `IterateBondedValidators` and split into two functions: `IterateBondedValidators` and `IterateLastBlockConsValidators`
- \#2648 [gaiad] Fix `gaiad export` / `gaiad import` consistency, test in CI
- \#2691 Fix local testnet creation by using a single canonical genesis time

* SDK
Expand Down
32 changes: 20 additions & 12 deletions cmd/gaia/app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -210,9 +210,6 @@ func (app *GaiaApp) EndBlocker(ctx sdk.Context, req abci.RequestEndBlock) abci.R
tags := gov.EndBlocker(ctx, app.govKeeper)
validatorUpdates := stake.EndBlocker(ctx, app.stakeKeeper)

// Add these new validators to the addr -> pubkey map.
app.slashingKeeper.AddValidators(ctx, validatorUpdates)

return abci.ResponseEndBlock{
ValidatorUpdates: validatorUpdates,
Tags: tags,
Expand All @@ -231,6 +228,10 @@ func (app *GaiaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci
// return sdk.ErrGenesisParse("").TraceCause(err, "")
}

// sort by account number to maintain consistency
sort.Slice(genesisState.Accounts, func(i, j int) bool {
return genesisState.Accounts[i].AccountNumber < genesisState.Accounts[j].AccountNumber
})
// load the accounts
for _, gacc := range genesisState.Accounts {
acc := gacc.ToAccount()
Expand All @@ -244,7 +245,8 @@ func (app *GaiaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci
panic(err) // TODO find a way to do this w/o panics
}

// load the address to pubkey map
// initialize module-specific stores
auth.InitGenesis(ctx, app.feeCollectionKeeper, genesisState.AuthData)
slashing.InitGenesis(ctx, app.slashingKeeper, genesisState.SlashingData, genesisState.StakeData)
gov.InitGenesis(ctx, app.govKeeper, genesisState.GovData)
mint.InitGenesis(ctx, app.mintKeeper, genesisState.MintData)
Expand All @@ -270,7 +272,6 @@ func (app *GaiaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci

validators = app.stakeKeeper.ApplyAndReturnValidatorSetUpdates(ctx)
}
app.slashingKeeper.AddValidators(ctx, validators)

// sanity check
if len(req.Validators) > 0 {
Expand Down Expand Up @@ -306,11 +307,12 @@ func (app *GaiaApp) ExportAppStateAndValidators() (appState json.RawMessage, val
app.accountKeeper.IterateAccounts(ctx, appendAccount)
genState := NewGenesisState(
accounts,
stake.WriteGenesis(ctx, app.stakeKeeper),
mint.WriteGenesis(ctx, app.mintKeeper),
distr.WriteGenesis(ctx, app.distrKeeper),
gov.WriteGenesis(ctx, app.govKeeper),
slashing.GenesisState{}, // TODO create write methods
auth.ExportGenesis(ctx, app.feeCollectionKeeper),
stake.ExportGenesis(ctx, app.stakeKeeper),
mint.ExportGenesis(ctx, app.mintKeeper),
distr.ExportGenesis(ctx, app.distrKeeper),
gov.ExportGenesis(ctx, app.govKeeper),
slashing.ExportGenesis(ctx, app.slashingKeeper),
)
appState, err = codec.MarshalJSONIndent(app.cdc, genState)
if err != nil {
Expand All @@ -337,12 +339,15 @@ var _ sdk.StakingHooks = Hooks{}
// nolint
func (h Hooks) OnValidatorCreated(ctx sdk.Context, valAddr sdk.ValAddress) {
h.dh.OnValidatorCreated(ctx, valAddr)
h.sh.OnValidatorCreated(ctx, valAddr)
}
func (h Hooks) OnValidatorModified(ctx sdk.Context, valAddr sdk.ValAddress) {
h.dh.OnValidatorModified(ctx, valAddr)
h.sh.OnValidatorModified(ctx, valAddr)
}
func (h Hooks) OnValidatorRemoved(ctx sdk.Context, valAddr sdk.ValAddress) {
h.dh.OnValidatorRemoved(ctx, valAddr)
func (h Hooks) OnValidatorRemoved(ctx sdk.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) {
h.dh.OnValidatorRemoved(ctx, consAddr, valAddr)
h.sh.OnValidatorRemoved(ctx, consAddr, valAddr)
}
func (h Hooks) OnValidatorBonded(ctx sdk.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) {
h.dh.OnValidatorBonded(ctx, consAddr, valAddr)
Expand All @@ -358,10 +363,13 @@ func (h Hooks) OnValidatorBeginUnbonding(ctx sdk.Context, consAddr sdk.ConsAddre
}
func (h Hooks) OnDelegationCreated(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) {
h.dh.OnDelegationCreated(ctx, delAddr, valAddr)
h.sh.OnDelegationCreated(ctx, delAddr, valAddr)
}
func (h Hooks) OnDelegationSharesModified(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) {
h.dh.OnDelegationSharesModified(ctx, delAddr, valAddr)
h.sh.OnDelegationSharesModified(ctx, delAddr, valAddr)
}
func (h Hooks) OnDelegationRemoved(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) {
h.dh.OnDelegationRemoved(ctx, delAddr, valAddr)
h.sh.OnDelegationRemoved(ctx, delAddr, valAddr)
}
30 changes: 20 additions & 10 deletions cmd/gaia/app/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ var (
// State to Unmarshal
type GenesisState struct {
Accounts []GenesisAccount `json:"accounts"`
AuthData auth.GenesisState `json:"auth"`
StakeData stake.GenesisState `json:"stake"`
MintData mint.GenesisState `json:"mint"`
DistrData distr.GenesisState `json:"distr"`
Expand All @@ -40,11 +41,12 @@ type GenesisState struct {
GenTxs []json.RawMessage `json:"gentxs"`
}

func NewGenesisState(accounts []GenesisAccount, stakeData stake.GenesisState, mintData mint.GenesisState,
func NewGenesisState(accounts []GenesisAccount, authData auth.GenesisState, stakeData stake.GenesisState, mintData mint.GenesisState,
distrData distr.GenesisState, govData gov.GenesisState, slashingData slashing.GenesisState) GenesisState {

return GenesisState{
Accounts: accounts,
AuthData: authData,
StakeData: stakeData,
MintData: mintData,
DistrData: distrData,
Expand All @@ -53,31 +55,39 @@ func NewGenesisState(accounts []GenesisAccount, stakeData stake.GenesisState, mi
}
}

// GenesisAccount doesn't need pubkey or sequence
// nolint
type GenesisAccount struct {
Address sdk.AccAddress `json:"address"`
Coins sdk.Coins `json:"coins"`
Address sdk.AccAddress `json:"address"`
Coins sdk.Coins `json:"coins"`
Sequence int64 `json:"sequence_number"`
AccountNumber int64 `json:"account_number"`
}

func NewGenesisAccount(acc *auth.BaseAccount) GenesisAccount {
return GenesisAccount{
Address: acc.Address,
Coins: acc.Coins,
Address: acc.Address,
Coins: acc.Coins,
AccountNumber: acc.AccountNumber,
Sequence: acc.Sequence,
}
}

func NewGenesisAccountI(acc auth.Account) GenesisAccount {
return GenesisAccount{
Address: acc.GetAddress(),
Coins: acc.GetCoins(),
Address: acc.GetAddress(),
Coins: acc.GetCoins(),
AccountNumber: acc.GetAccountNumber(),
Sequence: acc.GetSequence(),
}
}

// convert GenesisAccount to auth.BaseAccount
func (ga *GenesisAccount) ToAccount() (acc *auth.BaseAccount) {
return &auth.BaseAccount{
Address: ga.Address,
Coins: ga.Coins.Sort(),
Address: ga.Address,
Coins: ga.Coins.Sort(),
AccountNumber: ga.AccountNumber,
Sequence: ga.Sequence,
}
}

Expand Down
98 changes: 98 additions & 0 deletions cmd/gaia/app/sim_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (

"github.com/stretchr/testify/require"

abci "github.com/tendermint/tendermint/abci/types"
dbm "github.com/tendermint/tendermint/libs/db"
"github.com/tendermint/tendermint/libs/log"

Expand Down Expand Up @@ -266,6 +267,103 @@ func TestFullGaiaSimulation(t *testing.T) {
require.Nil(t, err)
}

func TestGaiaImportExport(t *testing.T) {
if !enabled {
t.Skip("Skipping Gaia import/export simulation")
}

// Setup Gaia application
var logger log.Logger
if verbose {
logger = log.TestingLogger()
} else {
logger = log.NewNopLogger()
}
var db dbm.DB
dir, _ := ioutil.TempDir("", "goleveldb-gaia-sim")
db, _ = dbm.NewGoLevelDB("Simulation", dir)
defer func() {
db.Close()
os.RemoveAll(dir)
}()
app := NewGaiaApp(logger, db, nil)
require.Equal(t, "GaiaApp", app.Name())

// Run randomized simulation
err := simulation.SimulateFromSeed(
t, app.BaseApp, appStateFn, seed,
testAndRunTxs(app),
[]simulation.RandSetup{},
invariants(app),
numBlocks,
blockSize,
commit,
)
if commit {
// for memdb:
// fmt.Println("Database Size", db.Stats()["database.size"])
fmt.Println("GoLevelDB Stats")
fmt.Println(db.Stats()["leveldb.stats"])
fmt.Println("GoLevelDB cached block size", db.Stats()["leveldb.cachedblock"])
}
require.Nil(t, err)

fmt.Printf("Exporting genesis...\n")

appState, _, err := app.ExportAppStateAndValidators()
if err != nil {
panic(err)
}

fmt.Printf("Importing genesis...\n")

newDir, _ := ioutil.TempDir("", "goleveldb-gaia-sim-2")
newDB, _ := dbm.NewGoLevelDB("Simulation-2", dir)
defer func() {
newDB.Close()
os.RemoveAll(newDir)
}()
newApp := NewGaiaApp(log.NewNopLogger(), newDB, nil)
require.Equal(t, "GaiaApp", newApp.Name())
request := abci.RequestInitChain{
AppStateBytes: appState,
}
newApp.InitChain(request)
newApp.Commit()

fmt.Printf("Comparing stores...\n")
ctxA := app.NewContext(true, abci.Header{})
ctxB := newApp.NewContext(true, abci.Header{})
type StoreKeysPrefixes struct {
A sdk.StoreKey
B sdk.StoreKey
Prefixes [][]byte
}
storeKeysPrefixes := []StoreKeysPrefixes{
{app.keyMain, newApp.keyMain, [][]byte{}},
{app.keyAccount, newApp.keyAccount, [][]byte{}},
{app.keyStake, newApp.keyStake, [][]byte{stake.UnbondingQueueKey, stake.RedelegationQueueKey, stake.ValidatorQueueKey}}, // ordering may change but it doesn't matter
{app.keySlashing, newApp.keySlashing, [][]byte{}},
{app.keyMint, newApp.keyMint, [][]byte{}},
{app.keyDistr, newApp.keyDistr, [][]byte{}},
{app.keyFeeCollection, newApp.keyFeeCollection, [][]byte{}},
{app.keyParams, newApp.keyParams, [][]byte{}},
{app.keyGov, newApp.keyGov, [][]byte{}},
}
for _, storeKeysPrefix := range storeKeysPrefixes {
storeKeyA := storeKeysPrefix.A
storeKeyB := storeKeysPrefix.B
prefixes := storeKeysPrefix.Prefixes
storeA := ctxA.KVStore(storeKeyA)
storeB := ctxB.KVStore(storeKeyB)
kvA, kvB, count, equal := sdk.DiffKVStores(storeA, storeB, prefixes)
fmt.Printf("Compared %d key/value pairs between %s and %s\n", count, storeKeyA, storeKeyB)
require.True(t, equal, "unequal stores: %s / %s:\nstore A %s (%X) => %s (%X)\nstore B %s (%X) => %s (%X)",
storeKeyA, storeKeyB, kvA.Key, kvA.Key, kvA.Value, kvA.Value, kvB.Key, kvB.Key, kvB.Value, kvB.Value)
}

}

// TODO: Make another test for the fuzzer itself, which just has noOp txs
// and doesn't depend on gaia
func TestAppStateDeterminism(t *testing.T) {
Expand Down
2 changes: 1 addition & 1 deletion cmd/gaia/init/collect.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,6 @@ func genAppStateFromConfig(
return
}

err = WriteGenesisFile(genFile, initCfg.ChainID, nil, appState)
err = ExportGenesisFile(genFile, initCfg.ChainID, nil, appState)
return
}
2 changes: 1 addition & 1 deletion cmd/gaia/init/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ func InitCmd(ctx *server.Context, cdc *codec.Codec, appInit server.AppInit) *cob
viper.GetBool(flagOverwrite)); err != nil {
return err
}
if err = WriteGenesisFile(genFile, chainID, nil, appState); err != nil {
if err = ExportGenesisFile(genFile, chainID, nil, appState); err != nil {
return err
}

Expand Down
2 changes: 1 addition & 1 deletion cmd/gaia/init/testnet.go
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ func collectGenFiles(
genFile := config.GenesisFile()

// overwrite each validator's genesis file to have a canonical genesis time
err = WriteGenesisFileWithTime(genFile, chainID, nil, appState, genTime)
err = ExportGenesisFileWithTime(genFile, chainID, nil, appState, genTime)
if err != nil {
return err
}
Expand Down
8 changes: 4 additions & 4 deletions cmd/gaia/init/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ import (
"github.com/tendermint/tendermint/types"
)

// WriteGenesisFile creates and writes the genesis configuration to disk. An
// ExportGenesisFile creates and writes the genesis configuration to disk. An
// error is returned if building or writing the configuration to file fails.
func WriteGenesisFile(
func ExportGenesisFile(
genFile, chainID string, validators []types.GenesisValidator, appState json.RawMessage,
) error {

Expand All @@ -36,9 +36,9 @@ func WriteGenesisFile(
return genDoc.SaveAs(genFile)
}

// WriteGenesisFileWithTime creates and writes the genesis configuration to disk.
// ExportGenesisFileWithTime creates and writes the genesis configuration to disk.
// An error is returned if building or writing the configuration to file fails.
func WriteGenesisFileWithTime(
func ExportGenesisFileWithTime(
genFile, chainID string, validators []types.GenesisValidator,
appState json.RawMessage, genTime time.Time,
) error {
Expand Down
Loading