Skip to content

Commit

Permalink
Merge pull request #4166 from Agoric/mfig-dont-munge-genesis
Browse files Browse the repository at this point in the history
Fix IBC (`x/capability`) nondeterminism after node restart
  • Loading branch information
mergify[bot] authored Dec 9, 2021
2 parents 71f8101 + 823f4fe commit 4b40da0
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 36 deletions.
50 changes: 18 additions & 32 deletions golang/cosmos/app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"github.com/rakyll/statik/fs"

abci "github.com/tendermint/tendermint/abci/types"
tmjson "github.com/tendermint/tendermint/libs/json"
"github.com/tendermint/tendermint/libs/log"
tmos "github.com/tendermint/tendermint/libs/os"
dbm "github.com/tendermint/tm-db"
Expand Down Expand Up @@ -468,10 +469,23 @@ func NewAgoricApp(
// CanWithdrawInvariant invariant.
// NOTE: staking module is required if HistoricalEntries param > 0
app.mm.SetOrderBeginBlockers(
upgradetypes.ModuleName, minttypes.ModuleName, distrtypes.ModuleName, slashingtypes.ModuleName,
evidencetypes.ModuleName, stakingtypes.ModuleName, ibchost.ModuleName, swingset.ModuleName,
upgradetypes.ModuleName,
capabilitytypes.ModuleName,
minttypes.ModuleName,
distrtypes.ModuleName,
slashingtypes.ModuleName,
evidencetypes.ModuleName,
stakingtypes.ModuleName,
ibchost.ModuleName,
swingset.ModuleName,
)
app.mm.SetOrderEndBlockers(
vbank.ModuleName,
swingset.ModuleName,
crisistypes.ModuleName,
govtypes.ModuleName,
stakingtypes.ModuleName,
)
app.mm.SetOrderEndBlockers(vbank.ModuleName, swingset.ModuleName, crisistypes.ModuleName, govtypes.ModuleName, stakingtypes.ModuleName)

// NOTE: The genutils module must occur after staking so that pools are
// properly initialized with tokens from genesis accounts.
Expand Down Expand Up @@ -610,43 +624,15 @@ func (app *GaiaApp) EndBlocker(ctx sdk.Context, req abci.RequestEndBlock) abci.R
return app.mm.EndBlock(ctx, req)
}

func updateTransferPort(gs GenesisState, reservedPort, newPort string) error {
var transferGenesis ibctransfertypes.GenesisState
if err := json.Unmarshal(gs[ibctransfertypes.ModuleName], &transferGenesis); err != nil {
return err
}
if len(transferGenesis.PortId) > 0 && transferGenesis.PortId != reservedPort {
// Already not the reserved port name.
return nil
}
// Change the listening IBC port to avoid conflict.
transferGenesis.PortId = newPort
transferGenesisBytes, err := json.Marshal(transferGenesis)
if err != nil {
return err
}
gs[ibctransfertypes.ModuleName] = transferGenesisBytes
return nil
}

// InitChainer application update at chain initialization
func (app *GaiaApp) InitChainer(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain {
var genesisState GenesisState
if err := json.Unmarshal(req.AppStateBytes, &genesisState); err != nil {
panic(err)
}
if err := updateTransferPort(genesisState, "transfer", "cosmos-transfer"); err != nil {
if err := tmjson.Unmarshal(req.AppStateBytes, &genesisState); err != nil {
panic(err)
}
app.UpgradeKeeper.SetModuleVersionMap(ctx, app.mm.GetVersionMap())
res := app.mm.InitGenesis(ctx, app.appCodec, genesisState)

// Set Historical infos in InitChain to ignore genesis params
// This is needed for IBC connections not to time out easily
stakingParams := app.StakingKeeper.GetParams(ctx)
stakingParams.HistoricalEntries = 10000
app.StakingKeeper.SetParams(ctx, stakingParams)

// Agoric: report the genesis time explicitly.
genTime := req.GetTime()
if genTime.After(time.Now()) {
Expand Down
16 changes: 16 additions & 0 deletions packages/agoric-cli/src/chain-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@ export const CENTRAL_DENOM = 'urun';
export const MINT_DENOM = 'ubld';
export const STAKING_DENOM = 'ubld';
export const STAKING_MAX_VALIDATORS = 150;
// Required for IBC connections not to time out.
export const STAKING_MIN_HISTORICAL_ENTRIES = 10000;

// We reserve the default `transfer` IBC port for Pegasus (JS-level ERTP
// assets). The `cosmos-transfer` IBC port is used for ibc-go (Cosmos-level
// prefixed string token denominations).
export const COSMOS_TRANSFER_PORT_ID = 'cosmos-transfer';

export const DENOM_METADATA = [
{
Expand Down Expand Up @@ -178,6 +185,15 @@ export function finishCosmosGenesis({ genesisJson, exportedGenesisJson }) {

genesis.app_state.staking.params.bond_denom = STAKING_DENOM;
genesis.app_state.staking.params.max_validators = STAKING_MAX_VALIDATORS;
const {
historical_entries: existingHistoricalEntries = 0,
} = genesis.app_state.staking.params;
genesis.app_state.staking.params.historical_entries = Math.max(
existingHistoricalEntries,
STAKING_MIN_HISTORICAL_ENTRIES,
);

genesis.app_state.transfer.port_id = COSMOS_TRANSFER_PORT_ID;

// We scale this parameter according to our own block cadence, so
// that we tolerate the same downtime as the old genesis.
Expand Down
24 changes: 20 additions & 4 deletions packages/deployment/src/init.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,18 +108,27 @@ const genericAskDatacenter = ({ inquirer }) => async (

const DOCKER_DATACENTER = 'default';

const makeProviders = ({ env, inquirer, wr, setup, fetch }) => ({
const makeProviders = ({ env, inquirer, wr, setup, fetch, needBacktick }) => ({
docker: {
name: 'Docker instances',
value: 'docker',
askDetails: async (_provider, _myDetails) => {
let vspec = '/sys/fs/cgroup:/sys/fs/cgroup';
let vspec = '';

const dockerInfo = await needBacktick(`docker info`);
const cgroupMatch = dockerInfo.match(/^\s*Cgroup\sVersion:\s*(\d+)/im);
if (!cgroupMatch || Number(cgroupMatch[1]) < 2) {
// Older cgroup version, we need to mount `/sys/fs/cgroup` explicitly
// for our Agoric deployment Docker containers' systemd.
vspec += ',/sys/fs/cgroup:/sys/fs/cgroup';
}
if (env.DOCKER_VOLUMES) {
vspec += `,${env.DOCKER_VOLUMES}`;
}
return {
VOLUMES: vspec
.split(',')
.filter(vol => vol.trim())
.map(vol => vol.split(':'))
// eslint-disable-next-line camelcase
.map(([host_path, container_path]) => ({
Expand Down Expand Up @@ -276,8 +285,15 @@ const doInit = ({
fetch,
parseArgs,
}) => async (progname, args) => {
const { needDoRun, cwd, chdir } = running;
const PROVIDERS = makeProviders({ env, inquirer, wr, setup, fetch });
const { needDoRun, needBacktick, cwd, chdir } = running;
const PROVIDERS = makeProviders({
env,
inquirer,
wr,
setup,
fetch,
needBacktick,
});

const { _: parsedArgs, noninteractive } = parseArgs(args.slice(1), {
boolean: ['noninteractive'],
Expand Down

0 comments on commit 4b40da0

Please sign in to comment.