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

WIP: Merge PRs from Cosmos-SDK 0.27 #797

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
9 changes: 9 additions & 0 deletions Gopkg.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -120,19 +120,19 @@ test_sim_modules:

test_sim_benchmark:
@echo "Running benchmark test..."
@go test ./app -run=none -bench=BenchmarkFullIrisSimulation -v -SimulationCommit=true -SimulationNumBlocks=100 -timeout 24h
@go test ./app -run=none -bench=BenchmarkFullIrisSimulation -v -SimulationCommit=true -SimulationNumBlocks=100 -SimulationCommit=true -timeout 24h

test_sim_iris_nondeterminism:
@echo "Running nondeterminism test..."
@go test ./app -run TestAppStateDeterminism -v -SimulationEnabled=true -timeout 10m

test_sim_iris_fast:
@echo "Running quick Iris simulation. This may take several minutes..."
@go test ./app -run TestFullIrisSimulation -v -SimulationEnabled=true -SimulationNumBlocks=100 -timeout 24h
@go test ./app -run TestFullIrisSimulation -v -SimulationEnabled=true -SimulationNumBlocks=100 -SimulationBlockSize=200 -SimulationCommit=true -SimulationSeed=99 -timeout 24h

test_sim_iris_slow:
@echo "Running full Iris simulation. This may take awhile!"
@go test ./app -run TestFullIrisSimulation -v -SimulationEnabled=true -SimulationNumBlocks=1000 -SimulationVerbose=true -timeout 24h
@go test ./app -run TestFullIrisSimulation -v -SimulationEnabled=true -SimulationNumBlocks=1000 -SimulationBlockSize=200 -SimulationCommit=true -SimulationSeed=99 -timeout 24h

testnet_init:
@echo "Work well only when Bech32PrefixAccAddr equal faa"
Expand Down
59 changes: 10 additions & 49 deletions app/app.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package app

import (
"encoding/json"
"fmt"
"io"
"os"
Expand Down Expand Up @@ -32,14 +31,14 @@ import (
cmn "github.com/tendermint/tendermint/libs/common"
dbm "github.com/tendermint/tendermint/libs/db"
"github.com/tendermint/tendermint/libs/log"
tmtypes "github.com/tendermint/tendermint/types"
"time"
"github.com/irisnet/irishub/modules/guardian"
)

const (
appName = "IrisApp"
FlagReplay = "replay"
FlagReplayHeight = "replay_height"
)

// default home directories for expected binaries
Expand Down Expand Up @@ -247,6 +246,11 @@ func (app *IrisApp) mountStoreAndSetupBaseApp(lastHeight int64) {
var err error
if viper.GetBool(FlagReplay) {
err = app.LoadVersion(lastHeight, app.keyMain, true)
} else if viper.GetInt64(FlagReplayHeight) > 0 {
replayHeight := viper.GetInt64(FlagReplayHeight)
loadHeight := bam.ReplayToHeight(replayHeight, app.Logger)
app.Logger.Info(fmt.Sprintf("Load store at %d, start to replay to %d", loadHeight, replayHeight))
err = app.LoadVersion(loadHeight, app.keyMain, true)
} else {
err = app.LoadLatestVersion(app.keyMain)
}
Expand Down Expand Up @@ -320,6 +324,10 @@ func (app *IrisApp) EndBlocker(ctx sdk.Context, req abci.RequestEndBlock) abci.R
validatorUpdates := stake.EndBlocker(ctx, app.stakeKeeper)
tags = tags.AppendTags(upgrade.EndBlocker(ctx, app.upgradeKeeper))
tags = tags.AppendTags(service.EndBlocker(ctx, app.serviceKeeper))
height := ctx.BlockHeight()
_=height
app.assertRuntimeInvariants()

return abci.ResponseEndBlock{
ValidatorUpdates: validatorUpdates,
Tags: tags,
Expand Down Expand Up @@ -413,53 +421,6 @@ func (app *IrisApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci
}
}

// export the state of iris for a genesis file
func (app *IrisApp) ExportAppStateAndValidators() (appState json.RawMessage, validators []tmtypes.GenesisValidator, err error) {
ctx := app.NewContext(true, abci.Header{})

// iterate to get the accounts
accounts := []GenesisAccount{}
appendAccount := func(acc auth.Account) (stop bool) {
account := NewGenesisAccountI(acc)
accounts = append(accounts, account)
return false
}
app.accountMapper.IterateAccounts(ctx, appendAccount)
fileAccounts := []GenesisFileAccount{}
for _, acc := range accounts {
var coinsString []string
for _, coin := range acc.Coins {
coinsString = append(coinsString, coin.String())
}
fileAccounts = append(fileAccounts,
GenesisFileAccount{
Address: acc.Address,
Coins: coinsString,
Sequence: acc.Sequence,
AccountNumber: acc.AccountNumber,
})
}
genState := NewGenesisFileState(
fileAccounts,
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),
upgrade.WriteGenesis(ctx),
service.ExportGenesis(ctx, app.serviceKeeper),
arbitration.ExportGenesis(ctx),
guardian.ExportGenesis(ctx, app.guardianKeeper),
slashing.ExportGenesis(ctx, app.slashingKeeper),
)
appState, err = codec.MarshalJSONIndent(app.cdc, genState)
if err != nil {
return nil, nil, err
}
validators = stake.WriteValidators(ctx, app.stakeKeeper)
return appState, validators, nil
}

// Iterates through msgs and executes them
func (app *IrisApp) runMsgs(ctx sdk.Context, msgs []sdk.Msg, mode bam.RunTxMode) (result sdk.Result) {
// accumulate results
Expand Down
166 changes: 166 additions & 0 deletions app/export.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
package app

import (
"encoding/json"
"fmt"

"github.com/irisnet/irishub/codec"
sdk "github.com/irisnet/irishub/types"
"github.com/irisnet/irishub/modules/auth"
distr "github.com/irisnet/irishub/modules/distribution"
"github.com/irisnet/irishub/modules/gov"
"github.com/irisnet/irishub/modules/mint"
"github.com/irisnet/irishub/modules/slashing"
stake "github.com/irisnet/irishub/modules/stake"
abci "github.com/tendermint/tendermint/abci/types"
tmtypes "github.com/tendermint/tendermint/types"
"github.com/irisnet/irishub/modules/upgrade"
"github.com/irisnet/irishub/modules/service"
"github.com/irisnet/irishub/modules/arbitration"
"github.com/irisnet/irishub/modules/guardian"
)

// export the state of gaia for a genesis file
func (app *IrisApp) ExportAppStateAndValidators(forZeroHeight bool) (
appState json.RawMessage, validators []tmtypes.GenesisValidator, err error) {

// as if they could withdraw from the start of the next block
ctx := app.NewContext(true, abci.Header{Height: app.LastBlockHeight()})

if forZeroHeight {
app.prepForZeroHeightGenesis(ctx)
}

// iterate to get the accounts
accounts := []GenesisAccount{}
appendAccount := func(acc auth.Account) (stop bool) {
account := NewGenesisAccountI(acc)
accounts = append(accounts, account)
return false
}
app.accountMapper.IterateAccounts(ctx, appendAccount)
fileAccounts := []GenesisFileAccount{}
for _, acc := range accounts {
var coinsString []string
for _, coin := range acc.Coins {
coinsString = append(coinsString, coin.String())
}
fileAccounts = append(fileAccounts,
GenesisFileAccount{
Address: acc.Address,
Coins: coinsString,
Sequence: acc.Sequence,
AccountNumber: acc.AccountNumber,
})
}

genState := NewGenesisFileState(
fileAccounts,
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),
upgrade.WriteGenesis(ctx),
service.ExportGenesis(ctx, app.serviceKeeper),
arbitration.ExportGenesis(ctx),
guardian.ExportGenesis(ctx, app.guardianKeeper),
slashing.ExportGenesis(ctx, app.slashingKeeper),
)
appState, err = codec.MarshalJSONIndent(app.cdc, genState)
if err != nil {
return nil, nil, err
}
validators = stake.WriteValidators(ctx, app.stakeKeeper)
return appState, validators, nil
}

// prepare for fresh start at zero height
func (app *IrisApp) prepForZeroHeightGenesis(ctx sdk.Context) {

/* Just to be safe, assert the invariants on current state. */
app.assertRuntimeInvariantsOnContext(ctx)

/* Handle fee distribution state. */

// withdraw all delegator & validator rewards
vdiIter := func(_ int64, valInfo distr.ValidatorDistInfo) (stop bool) {
_, _, err := app.distrKeeper.WithdrawValidatorRewardsAll(ctx, valInfo.OperatorAddr)
if err != nil {
panic(err)
}
return false
}
app.distrKeeper.IterateValidatorDistInfos(ctx, vdiIter)

ddiIter := func(_ int64, distInfo distr.DelegationDistInfo) (stop bool) {
_, err := app.distrKeeper.WithdrawDelegationReward(
ctx, distInfo.DelegatorAddr, distInfo.ValOperatorAddr)
if err != nil {
panic(err)
}
return false
}
app.distrKeeper.IterateDelegationDistInfos(ctx, ddiIter)

app.assertRuntimeInvariantsOnContext(ctx)

// set distribution info withdrawal heights to 0
app.distrKeeper.IterateDelegationDistInfos(ctx, func(_ int64, delInfo distr.DelegationDistInfo) (stop bool) {
delInfo.DelPoolWithdrawalHeight = 0
app.distrKeeper.SetDelegationDistInfo(ctx, delInfo)
return false
})
app.distrKeeper.IterateValidatorDistInfos(ctx, func(_ int64, valInfo distr.ValidatorDistInfo) (stop bool) {
valInfo.FeePoolWithdrawalHeight = 0
app.distrKeeper.SetValidatorDistInfo(ctx, valInfo)
return false
})

// assert that the fee pool is empty
feePool := app.distrKeeper.GetFeePool(ctx)
if !feePool.TotalValAccum.Accum.IsZero() {
panic("unexpected leftover validator accum")
}
bondDenom := app.stakeKeeper.GetParams(ctx).BondDenom
if !feePool.ValPool.AmountOf(bondDenom).IsZero() {
panic(fmt.Sprintf("unexpected leftover validator pool coins: %v",
feePool.ValPool.AmountOf(bondDenom).String()))
}

// reset fee pool height, save fee pool
feePool.TotalValAccum = distr.NewTotalAccum(0)
app.distrKeeper.SetFeePool(ctx, feePool)

/* Handle stake state. */

// iterate through validators by power descending, reset bond height, update bond intra-tx counter
store := ctx.KVStore(app.keyStake)
iter := sdk.KVStoreReversePrefixIterator(store, stake.ValidatorsByPowerIndexKey)
counter := int16(0)
for ; iter.Valid(); iter.Next() {
addr := sdk.ValAddress(iter.Value())
validator, found := app.stakeKeeper.GetValidator(ctx, addr)
if !found {
panic("expected validator, not found")
}
validator.BondHeight = 0
validator.BondIntraTxCounter = counter
validator.UnbondingHeight = 0
app.stakeKeeper.SetValidator(ctx, validator)
counter++
}
iter.Close()

/* Handle slashing state. */

// we have to clear the slashing periods, since they reference heights
app.slashingKeeper.DeleteValidatorSlashingPeriods(ctx)

// reset start height on signing infos
app.slashingKeeper.IterateValidatorSigningInfos(ctx, func(addr sdk.ConsAddress, info slashing.ValidatorSigningInfo) (stop bool) {
info.StartHeight = 0
app.slashingKeeper.SetValidatorSigningInfo(ctx, addr, info)
return false
})
}
41 changes: 41 additions & 0 deletions app/invariants.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package app

import (
"fmt"
"time"

sdk "github.com/irisnet/irishub/types"
banksim "github.com/irisnet/irishub/modules/bank/simulation"
distrsim "github.com/irisnet/irishub/modules/distribution/simulation"
"github.com/irisnet/irishub/modules/mock/simulation"
stakesim "github.com/irisnet/irishub/modules/stake/simulation"
abci "github.com/tendermint/tendermint/abci/types"
)

func (app *IrisApp) runtimeInvariants() []simulation.Invariant {
return []simulation.Invariant{
banksim.NonnegativeBalanceInvariant(app.accountMapper),
distrsim.ValAccumInvariants(app.distrKeeper, app.stakeKeeper),
stakesim.SupplyInvariants(app.bankKeeper, app.stakeKeeper,
app.feeCollectionKeeper, app.distrKeeper, app.serviceKeeper, app.accountMapper),
stakesim.PositivePowerInvariant(app.stakeKeeper),
}
}

func (app *IrisApp) assertRuntimeInvariants() {
ctx := app.NewContext(false, abci.Header{Height: app.LastBlockHeight() + 1})
app.assertRuntimeInvariantsOnContext(ctx)
}

func (app *IrisApp) assertRuntimeInvariantsOnContext(ctx sdk.Context) {
start := time.Now()
invariants := app.runtimeInvariants()
for _, inv := range invariants {
if err := inv(ctx); err != nil {
panic(fmt.Errorf("invariant broken: %s", err))
}
}
end := time.Now()
diff := end.Sub(start)
app.BaseApp.Logger.With("module", "invariants").Info("Asserted all invariants", "duration", diff)
}
Loading