Skip to content

Instantly share code, notes, and snippets.

@fedekunze
Last active August 5, 2022 09:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fedekunze/427d05538d29d56a6516624daccef9aa to your computer and use it in GitHub Desktop.
Save fedekunze/427d05538d29d56a6516624daccef9aa to your computer and use it in GitHub Desktop.
Guide: Cosmos SDK Hard Forks for Security Vulnerabilities
// BeginBlocker runs the Tendermint ABCI BeginBlock logic. It executes state changes at the beginning
// of the new block for every registered module. If there is a registered fork at the current height,
// BeginBlocker will schedule the upgrade plan and perform the state migration (if any).
func (app *App) BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock) abci.ResponseBeginBlock {
// Perform any scheduled forks before executing the modules logic
app.ScheduleForkUpgrade(ctx)
return app.mm.BeginBlock(ctx, req)
}
const (
// UpgradeName is the shared upgrade plan name for mainnet and testnet
UpgradeName = "v7.0.0"
// MainnetUpgradeHeight defines the Evmos mainnet block height on which the upgrade will take place
MainnetUpgradeHeight = 2_476_000
// UpgradeInfo defines the binaries that will be used for the upgrade
UpgradeInfo = `'{"binaries":{"darwin/arm64":"https://github.com/evmos/evmos/releases/download/v7.0.0/evmos_7.0.0_Darwin_arm64.tar.gz","darwin/x86_64":"https://github.com/evmos/evmos/releases/download/v7.0.0/evmos_7.0.0_Darwin_x86_64.tar.gz","linux/arm64":"https://github.com/evmos/evmos/releases/download/v7.0.0/evmos_7.0.0_Linux_arm64.tar.gz","linux/x86_64":"https://github.com/evmos/evmos/releases/download/v7.0.0/evmos_7.0.0_Linux_x86_64.tar.gz","windows/x86_64":"https://github.com/evmos/evmos/releases/download/v7.0.0/evmos_7.0.0_Windows_x86_64.zip"}}'`
)
// ScheduleForkUpgrade executes any necessary fork logic for based upon the current
// block height and chain ID (mainnet or testnet). It sets an upgrade plan once
// the chain reaches the pre-defined upgrade height.
//
// CONTRACT: for this logic to work properly it is required to:
//
// 1) Release a non-breaking patch version so that the chain can set the scheduled upgrade plan at upgrade-height.
// 2) Release the software defined in the upgrade-info
func (app *App) ScheduleForkUpgrade(ctx sdk.Context) {
// NOTE: there are no testnet forks for the existing versions
if !types.IsMainnet(ctx.ChainID()) {
return
}
upgradePlan := upgradetypes.Plan{
Height: ctx.BlockHeight(),
}
// handle mainnet forks with their corresponding upgrade name and info
switch ctx.BlockHeight() {
case v2.MainnetUpgradeHeight:
upgradePlan.Name = v2.UpgradeName
upgradePlan.Info = v2.UpgradeInfo
case v4.MainnetUpgradeHeight:
upgradePlan.Name = v4.UpgradeName
upgradePlan.Info = v4.UpgradeInfo
case v7.MainnetUpgradeHeight:
upgradePlan.Name = v7.UpgradeName
upgradePlan.Info = v7.UpgradeInfo
default:
// No-op
return
}
// schedule the upgrade plan to the current block hight, effectively performing
// a hard fork that uses the upgrade handler to manage the migration.
if err := app.UpgradeKeeper.ScheduleUpgrade(ctx, upgradePlan); err != nil {
panic(
fmt.Errorf(
"failed to schedule upgrade %s during BeginBlock at height %d: %w",
upgradePlan.Name, ctx.BlockHeight(), err,
),
)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment