Skip to content

Commit

Permalink
e2e network upgrades
Browse files Browse the repository at this point in the history
  • Loading branch information
corverroos committed Feb 11, 2025
1 parent dbbccc1 commit 50b9b91
Show file tree
Hide file tree
Showing 12 changed files with 128 additions and 62 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/clicommand.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ jobs:
uses: ./.github/actions/goreleaser-snapshot

- name: Build halovisor image
run: scripts/halovisor/build.sh "${GITHUB_SHA::7}"
run: scripts/halovisor/build.sh

- name: Install CLI from Source
run: go install ./cli/cmd/omni
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/pr-e2etest.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
uses: ./.github/actions/goreleaser-snapshot

- name: Build halovisor image
run: scripts/halovisor/build.sh "${GITHUB_SHA::7}"
run: scripts/halovisor/build.sh

- name: Run devnet1 e2e test
run: |
Expand Down
60 changes: 41 additions & 19 deletions e2e/app/admin/planupgrade.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import (
"github.com/omni-network/omni/contracts/bindings"
"github.com/omni-network/omni/e2e/app"
"github.com/omni-network/omni/e2e/app/eoa"
uluwatu1 "github.com/omni-network/omni/halo/app/upgrades/uluwatu"
"github.com/omni-network/omni/halo/genutil/evm/predeploys"
"github.com/omni-network/omni/lib/cchain/provider"
"github.com/omni-network/omni/lib/errors"
"github.com/omni-network/omni/lib/log"
"github.com/omni-network/omni/lib/netconf"
Expand All @@ -16,40 +16,62 @@ import (
)

var upgradePlans = map[netconf.ID]bindings.UpgradePlan{
netconf.Staging: {
Name: uluwatu1.UpgradeName,
Height: 0, // Dynamically calculated for ephemeral networks
},
netconf.Omega: {
Name: uluwatu1.UpgradeName,
Height: 3_073_000, // Mon 14 Oct 9am EST
// Name: uluwatu1.UpgradeName,
// Height: 3_073_000, // Mon 14 Oct 9am EST
},
}

// PlanUpgrade plans the above configured network upgrade.
func PlanUpgrade(ctx context.Context, def app.Definition, cfg Config) error {
network := def.Manifest.Network
plan, ok := upgradePlans[network]
if !ok {
return errors.New("no network upgrade configured for network", "network", network)
}

backend, err := def.Backends().Backend(network.Static().OmniExecutionChainID)
if err != nil {
return err
}

// Override height with latest+5 for ephemeral networks.
if network.IsEphemeral() {
latest, err := backend.BlockNumber(ctx)
if err != nil {
return err
}
client, err := def.Testnet.BroadcastNode().Client()
if err != nil {
return errors.Wrap(err, "broadcast client")
}
cprov := provider.NewABCI(client, network)

const delay = 100 // Upgrades must be planned in the future, add a buffer of few minutes
plan.Height = latest + delay
next, ok, err := app.NextUpgrade(ctx, cprov)
if err != nil {
return err
} else if !ok {
return errors.New("network fully upgraded")
}

latest, err := backend.BlockNumber(ctx)
if err != nil {
return err
}

const delay = 100 // Upgrades must be planned in the future, add a buffer of few minutes
plan := bindings.UpgradePlan{
Name: next,
Height: latest + delay,
}

if network.IsProtected() {
plan, ok = upgradePlans[network]
if !ok || plan.Height == 0 || plan.Name == "" {
return errors.New("no network upgrade configured for protected network", "network", network)
} else if plan.Name != next {
return errors.New("configured and next upgrade mismatch", "network", network, "conf", plan.Name, "next", next)
} else if latest+delay > plan.Height {
return errors.New("configured height not far in future", "network", network, "conf", plan.Height, "latest", latest)
}
}

log.Debug(ctx, "Planning network upgrade",
"network", network,
"upgrade", plan.Name,
"height", plan.Height,
)

contract, err := bindings.NewUpgrade(common.HexToAddress(predeploys.Upgrade), backend)
if err != nil {
return errors.Wrap(err, "new upgrade contract")
Expand Down
88 changes: 59 additions & 29 deletions e2e/app/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import (
"github.com/omni-network/omni/e2e/xbridge"
haloapp "github.com/omni-network/omni/halo/app"
"github.com/omni-network/omni/halo/genutil/evm/predeploys"
"github.com/omni-network/omni/lib/cchain"
"github.com/omni-network/omni/lib/cchain/provider"
"github.com/omni-network/omni/lib/contracts"
"github.com/omni-network/omni/lib/errors"
"github.com/omni-network/omni/lib/k1util"
Expand Down Expand Up @@ -114,7 +116,7 @@ func Deploy(ctx context.Context, def Definition, cfg DeployConfig) (*pingpong.XD
eg2.Go(func() error { return allowStagingValidators(ctx, def) })
eg2.Go(func() error { return DeployEphemeralGasApp(ctx, def) })
eg2.Go(func() error { return DeployBridge(ctx, def) })
eg2.Go(func() error { return maybeSubmitNetworkUpgrade(ctx, def) })
eg2.Go(func() error { return maybeSubmitNetworkUpgrades(ctx, def) })
eg2.Go(func() error { return FundValidatorsForTesting(ctx, def) })
eg2.Go(func() error { return xbridge.Deploy(ctx, NetworkFromDef(def), def.Backends()) })
if err := eg2.Wait(); err != nil {
Expand Down Expand Up @@ -369,14 +371,20 @@ func checkSupportedChains(ctx context.Context, n netman.Manager) (bool, error) {
return true, nil
}

// maybeSubmitNetworkUpgrade submits a network upgrade if required.
func maybeSubmitNetworkUpgrade(ctx context.Context, def Definition) error {
if def.Manifest.NetworkUpgradeHeight <= 0 {
// maybeSubmitNetworkUpgrades submits multiple network upgrade up to latest (if required).
func maybeSubmitNetworkUpgrades(ctx context.Context, def Definition) error {
if def.Manifest.NetworkUpgradeHeight < 0 {
log.Debug(ctx, "Not submitting network upgrade admin tx")

return nil // No explicit network upgrade required.
}

client, err := def.Testnet.BroadcastNode().Client()
if err != nil {
return errors.Wrap(err, "broadcast client")
}
cprov := provider.NewABCI(client, def.Testnet.Network)

network := def.Testnet.Network

backend, err := def.Backends().Backend(network.Static().OmniExecutionChainID)
Expand All @@ -394,36 +402,58 @@ func maybeSubmitNetworkUpgrade(ctx context.Context, def Definition) error {
return err
}

height, err := backend.BlockNumber(ctx)
if err != nil {
return err
}
for i := 0; ; i++ {
upgrade, ok, err := NextUpgrade(ctx, cprov)
if err != nil {
return err
} else if !ok {
return nil // No next upgrade to plan
}

const minDelay = 5 // Upgrades fail if processed too late (mempool is non-deterministic, so we need a buffer).
height += minDelay
height, err := backend.BlockNumber(ctx)
if err != nil {
return err
}

// If requested height is later, use that as is.
if uint64(def.Manifest.NetworkUpgradeHeight) > height {
height = uint64(def.Manifest.NetworkUpgradeHeight)
}
const minDelay = 5 // Upgrades fail if processed too late (mempool is non-deterministic, so we need a buffer).
height += minDelay

upgrade, err := haloapp.NextUpgrade(def.Manifest.EphemeralGenesisBinary)
if err != nil {
return err
}
log.Info(ctx, "Planning upgrade", "height", height, "name", upgrade)
// If requested height is later, use that as is for first upgrade.
if i == 0 && uint64(def.Manifest.NetworkUpgradeHeight) > height {
height = uint64(def.Manifest.NetworkUpgradeHeight)
}

tx, err := contract.PlanUpgrade(txOpts, bindings.UpgradePlan{
Name: upgrade,
Height: height,
Info: "e2e triggered upgrade",
})
if err != nil {
return errors.Wrap(err, "plan upgrade")
log.Info(ctx, "Planning upgrade", "height", height, "name", upgrade)

tx, err := contract.PlanUpgrade(txOpts, bindings.UpgradePlan{
Name: upgrade,
Height: height,
Info: "e2e triggered upgrade",
})
if err != nil {
return errors.Wrap(err, "plan upgrade")
}
if _, err := backend.WaitMined(ctx, tx); err != nil {
return errors.Wrap(err, "wait mined")
}
}
if _, err := backend.WaitMined(ctx, tx); err != nil {
return errors.Wrap(err, "wait mined")
}

func NextUpgrade(ctx context.Context, cprov cchain.Provider) (string, bool, error) {
for _, upgrade := range haloapp.AllUpgrades() {
plan, ok, err := cprov.AppliedPlan(ctx, upgrade)
if err != nil {
return "", false, errors.Wrap(err, "fetching applied plan")
} else if !ok {
continue
} else if upgrade != plan.Name {
return "", false, errors.New("unexpected upgrade plan name", "expected", upgrade, "actual", plan.Name)
}

return haloapp.NextUpgrade(upgrade)
}

return nil
// No applied upgrades, so return first upgrade.

return haloapp.NextUpgrade("")
}
2 changes: 1 addition & 1 deletion e2e/app/setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ func Setup(ctx context.Context, def Definition, depCfg DeployConfig) error {
// Network upgrade to include in genesis (applied at height=1)
var upgrade string
if def.Manifest.NetworkUpgradeHeight == 0 {
upgrade, err = haloapp.NextUpgrade(def.Manifest.EphemeralGenesisBinary)
upgrade, _, err = haloapp.NextUpgrade(def.Manifest.EphemeralGenesisBinary)
if err != nil {
return err
}
Expand Down
1 change: 1 addition & 0 deletions e2e/manifests/devnet0.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

network = "devnet"
anvil_chains = ["mock_op", "mock_arb"]
ephemeral_genesis_binary = "1_uluwatu"

[node.validator01]

Expand Down
1 change: 1 addition & 0 deletions e2e/manifests/devnet1.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ anvil_chains = ["mock_l1", "mock_l2"]
multi_omni_evms = true
prometheus = true
deploy_solve = true
ephemeral_genesis_binary = "1_uluwatu"

[node.validator01]
[node.validator02]
Expand Down
3 changes: 2 additions & 1 deletion e2e/manifests/devnet2.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ anvil_chains = ["mock_l1", "mock_l2"]
multi_omni_evms = true
prometheus = true
deploy_solve = true
ephemeral_genesis_binary = "1_uluwatu"

feature_flags = ["evm-staking-module", "simple-evm-events", "proto-evm-payload"]
feature_flags = []

[node.validator01]
[node.validator02]
Expand Down
1 change: 1 addition & 0 deletions e2e/manifests/staging.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ public_chains = ["op_sepolia","base_sepolia","arb_sepolia","holesky"]
multi_omni_evms = true
prometheus = true
deploy_solve = true
network_upgrade_height = -1 # Manual upgrades for now

feature_flags = ["evm-staking-module","simple-evm-events","proto-evm-payload"]

Expand Down
3 changes: 1 addition & 2 deletions halo/app/app_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,6 @@ var (
{Account: distrtypes.ModuleName, Permissions: []string{authtypes.Burner}},
{Account: stakingtypes.BondedPoolName, Permissions: []string{authtypes.Burner, stakingtypes.ModuleName}},
{Account: stakingtypes.NotBondedPoolName, Permissions: []string{authtypes.Burner, stakingtypes.ModuleName}},
// TODO(christian): rename package, the rest can stay because names are the same
{Account: evmstakingtypes.ModuleName, Permissions: []string{authtypes.Burner, authtypes.Minter}},
{Account: minttypes.ModuleName, Permissions: []string{authtypes.Minter}},
}
Expand Down Expand Up @@ -155,7 +154,7 @@ var (
{
Name: authtypes.ModuleName,
Config: appconfig.WrapAny(&authmodulev1.Module{
ModuleAccountPermissions: moduleAccPerms(ctx),
ModuleAccountPermissions: moduleAccPerms,
Bech32Prefix: sdk.Bech32HRP,
}),
},
Expand Down
20 changes: 12 additions & 8 deletions halo/app/upgrades.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,23 +54,27 @@ func AllUpgrades() []string {
return resp
}

// NextUpgrade returns the next upgrade name after the provided previous upgrade..
func NextUpgrade(prev string) (string, error) {
// NextUpgrade returns the next upgrade name after the provided previous upgrade,
// or false if this the latest upgrade (no next), or an error if the name is not a
// valid upgrade.
func NextUpgrade(prev string) (string, bool, error) {
if prev == "" { // Return the first upgrade
return upgrades[0].Name, nil
return upgrades[0].Name, true, nil
}

for i, u := range upgrades {
if i == len(upgrades)-1 {
break
if u.Name != prev {
continue
}

if u.Name == prev {
return upgrades[i+1].Name, nil
if i == len(upgrades)-1 {
return "", false, nil // No next upgrade
}

return upgrades[i+1].Name, true, nil
}

return "", errors.New("prev upgrade not found [BUG]")
return "", false, errors.New("prev upgrade not found [BUG]")
}

func (a App) setUpgradeHandlers(ctx context.Context) error {
Expand Down
7 changes: 7 additions & 0 deletions halo/genutil/genutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"time"

haloapp "github.com/omni-network/omni/halo/app"
uluwatu1 "github.com/omni-network/omni/halo/app/upgrades/uluwatu"
"github.com/omni-network/omni/halo/evmupgrade"
vtypes "github.com/omni-network/omni/halo/valsync/types"
"github.com/omni-network/omni/lib/buildinfo"
Expand Down Expand Up @@ -53,6 +54,12 @@ func MakeGenesis(
upgradeName string,
valPubkeys ...crypto.PubKey,
) (*gtypes.AppGenesis, error) {
if upgradeName != "" && upgradeName != uluwatu1.UpgradeName {
// TODO(corver): Add support for chain genesis (block 0) directly from subsequent upgrades,
// ie, no actual network upgrade required since block 0 is already upgraded.
return nil, errors.New("genesis only supports 0_genesis and 1_uluwatu network upgrades")
}

encConf, err := haloapp.ClientEncodingConfig(ctx, network)
if err != nil {
return nil, errors.Wrap(err, "marshal app state")
Expand Down

0 comments on commit 50b9b91

Please sign in to comment.