Skip to content

Commit

Permalink
chore: cleanup post v4.1.0-rc.1 release (backport #276) (#279)
Browse files Browse the repository at this point in the history
Co-authored-by: John Letey <john@nobleassets.xyz>
  • Loading branch information
mergify[bot] and johnletey authored Nov 20, 2023
1 parent 25acf2d commit 0dae09c
Show file tree
Hide file tree
Showing 4 changed files with 160 additions and 46 deletions.
4 changes: 4 additions & 0 deletions interchaintest/genesis_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -628,3 +628,7 @@ func modifyGenesisTariff(
}
return nil
}

func modifyGenesisDowntimeWindow(bz map[string]interface{}) error {
return dyno.Set(bz, "5", "app_state", "slashing", "params", "signed_blocks_window")
}
56 changes: 49 additions & 7 deletions interchaintest/upgrade_grand-1_test.go
Original file line number Diff line number Diff line change
@@ -1,21 +1,27 @@
package interchaintest_test

import (
"context"
"encoding/json"
"testing"
"time"

"github.com/strangelove-ventures/interchaintest/v4/chain/cosmos"
"github.com/strangelove-ventures/interchaintest/v4/ibc"
"github.com/strangelove-ventures/interchaintest/v4/testutil"
"github.com/stretchr/testify/require"
)

// run `make local-image`to rebuild updated binary before running test
func TestGrand1ChainUpgrade(t *testing.T) {

const (
grand1ChainID = "grand-1"
numVals = 4
numValidators = 4
numFullNodes = 0
)

var grand1Genesis = ghcrImage("v0.3.0")
genesis := ghcrImage("v0.3.0")

var grand1Upgrades = []chainUpgrade{
upgrades := []chainUpgrade{
{
// The upgrade was registered on-chain with name "v0.4.1" accidentally,
// when "neon" was the upgrade name in the v0.4.1 code.
Expand Down Expand Up @@ -66,9 +72,45 @@ func TestGrand1ChainUpgrade(t *testing.T) {
},
{
upgradeName: "v4.1.0-rc.0",
image: nobleImageInfo[0],
image: ghcrImage("v4.1.0-rc.0"),
},
{
// v4.1.0-rc.1 is a patch release to fix a consensus failure caused by a validator going offline.
// The preUpgrade logic replicates this failure by bringing one validator offline.
// The postUpgrade logic verifies that after applying the emergency upgrade, the offline validator is jailed.
emergency: true,
image: ghcrImage("v4.1.0-rc.1"),
preUpgrade: func(t *testing.T, ctx context.Context, noble *cosmos.CosmosChain, paramAuthority ibc.Wallet) {
// Select one validator to go offline.
validator := noble.Validators[numValidators-1]

// Take the selected validator offline.
require.NoError(t, validator.StopContainer(ctx))

// Wait 5 blocks (+1) to exceed the downtime window.
timeoutCtx, timeoutCtxCancel := context.WithTimeout(ctx, 42*time.Second)
defer timeoutCtxCancel()

_ = testutil.WaitForBlocks(timeoutCtx, 6, noble)
},
postUpgrade: func(t *testing.T, ctx context.Context, noble *cosmos.CosmosChain, paramAuthority ibc.Wallet) {
raw, _, err := noble.Validators[0].ExecQuery(ctx, "staking", "validators")
require.NoError(t, err)

var res QueryValidatorsResponse
require.NoError(t, json.Unmarshal(raw, &res))

numJailed := 0
for _, validator := range res.Validators {
if validator.Jailed {
numJailed += 1
}
}

require.Equal(t, numJailed, 1)
},
},
}

testNobleChainUpgrade(t, grand1ChainID, grand1Genesis, denomMetadataUsdc, numVals, numFullNodes, grand1Upgrades)
testNobleChainUpgrade(t, "grand-1", genesis, denomMetadataUsdc, numValidators, numFullNodes, upgrades)
}
61 changes: 55 additions & 6 deletions interchaintest/upgrade_noble-1_test.go
Original file line number Diff line number Diff line change
@@ -1,21 +1,34 @@
package interchaintest_test

import (
"context"
"encoding/json"
"testing"
"time"

"github.com/strangelove-ventures/interchaintest/v4/chain/cosmos"
"github.com/strangelove-ventures/interchaintest/v4/ibc"
"github.com/strangelove-ventures/interchaintest/v4/testutil"
"github.com/stretchr/testify/require"
)

type QueryValidatorsResponse struct {
Validators []Validator `json:"validators"`
}
type Validator struct {
Jailed bool `json:"jailed"`
}

// run `make local-image`to rebuild updated binary before running test
func TestNoble1ChainUpgrade(t *testing.T) {

const (
noble1ChainID = "noble-1"
numVals = 4
numValidators = 4
numFullNodes = 0
)

var noble1Genesis = ghcrImage("v1.0.0")
genesis := ghcrImage("v1.0.0")

var noble1Upgrades = []chainUpgrade{
upgrades := []chainUpgrade{
{
upgradeName: "neon",
// this is a mock image that gives us control of the
Expand Down Expand Up @@ -46,7 +59,43 @@ func TestNoble1ChainUpgrade(t *testing.T) {
image: ghcrImage("mock-v4.0.0"),
postUpgrade: testPostArgonUpgrade,
},
{
// v4.0.1 is a patch release to fix a consensus failure caused by a validator going offline.
// The preUpgrade logic replicates this failure by bringing one validator offline.
// The postUpgrade logic verifies that after applying the emergency upgrade, the offline validator is jailed.
emergency: true,
image: ghcrImage("v4.0.1"),
preUpgrade: func(t *testing.T, ctx context.Context, noble *cosmos.CosmosChain, paramAuthority ibc.Wallet) {
// Select one validator to go offline.
validator := noble.Validators[numValidators-1]

// Take the selected validator offline.
require.NoError(t, validator.StopContainer(ctx))

// Wait 5 blocks (+1) to exceed the downtime window.
timeoutCtx, timeoutCtxCancel := context.WithTimeout(ctx, 42*time.Second)
defer timeoutCtxCancel()

_ = testutil.WaitForBlocks(timeoutCtx, 6, noble)
},
postUpgrade: func(t *testing.T, ctx context.Context, noble *cosmos.CosmosChain, paramAuthority ibc.Wallet) {
raw, _, err := noble.Validators[0].ExecQuery(ctx, "staking", "validators")
require.NoError(t, err)

var res QueryValidatorsResponse
require.NoError(t, json.Unmarshal(raw, &res))

numJailed := 0
for _, validator := range res.Validators {
if validator.Jailed {
numJailed += 1
}
}

require.Equal(t, numJailed, 1)
},
},
}

testNobleChainUpgrade(t, noble1ChainID, noble1Genesis, denomMetadataFrienzies, numVals, numFullNodes, noble1Upgrades)
testNobleChainUpgrade(t, "noble-1", genesis, denomMetadataFrienzies, numValidators, numFullNodes, upgrades)
}
85 changes: 52 additions & 33 deletions interchaintest/upgrade_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ type ParamsQueryResponse struct {
type chainUpgrade struct {
image ibc.DockerImage
upgradeName string // if upgradeName is empty, assumes patch/rolling update
emergency bool
preUpgrade func(t *testing.T, ctx context.Context, noble *cosmos.CosmosChain, paramAuthority ibc.Wallet)
postUpgrade func(t *testing.T, ctx context.Context, noble *cosmos.CosmosChain, paramAuthority ibc.Wallet)
}
Expand Down Expand Up @@ -97,6 +98,9 @@ func testNobleChainUpgrade(
if err := modifyGenesisParamAuthority(g, gw.paramAuthority.FormattedAddress()); err != nil {
return nil, err
}
if err := modifyGenesisDowntimeWindow(g); err != nil {
return nil, err
}
out, err := json.Marshal(&g)
if err != nil {
return nil, fmt.Errorf("failed to marshal genesis bytes to json: %w", err)
Expand Down Expand Up @@ -141,51 +145,66 @@ func testNobleChainUpgrade(

if upgrade.upgradeName == "" {
// patch/rolling upgrade
if upgrade.emergency {
err = noble.StopAllNodes(ctx)
require.NoError(t, err, "could not stop nodes for emergency upgrade")

// stage new version
for _, n := range noble.Nodes() {
n.Image = upgrade.image
}
noble.UpgradeVersion(ctx, client, upgrade.image.Repository, upgrade.image.Version)

// do rolling update on half the vals
for i, n := range noble.Validators {
if i%2 == 0 {
continue
}
// shutdown
require.NoError(t, n.StopContainer(ctx))
require.NoError(t, n.RemoveContainer(ctx))
noble.UpgradeVersion(ctx, client, upgrade.image.Repository, upgrade.image.Version)

// startup
require.NoError(t, n.CreateNodeContainer(ctx))
require.NoError(t, n.StartContainer(ctx))
err = noble.StartAllNodes(ctx)
require.NoError(t, err, "could not start nodes for emergency upgrade")

timeoutCtx, timeoutCtxCancel := context.WithTimeout(ctx, time.Second*45)
defer timeoutCtxCancel()

require.NoError(t, testutil.WaitForBlocks(timeoutCtx, int(blocksAfterUpgrade), noble))
}
err = testutil.WaitForBlocks(timeoutCtx, int(blocksAfterUpgrade), noble)
require.NoError(t, err, "chain did not produce blocks after emergency upgrade")
} else {
// stage new version
for _, n := range noble.Nodes() {
n.Image = upgrade.image
}
noble.UpgradeVersion(ctx, client, upgrade.image.Repository, upgrade.image.Version)

// blocks should still be produced after rolling update
timeoutCtx, timeoutCtxCancel := context.WithTimeout(ctx, time.Second*45)
defer timeoutCtxCancel()
// do rolling update on half the vals
for i, n := range noble.Validators {
if i%2 == 0 {
continue
}
// shutdown
require.NoError(t, n.StopContainer(ctx))
require.NoError(t, n.RemoveContainer(ctx))

err = testutil.WaitForBlocks(timeoutCtx, int(blocksAfterUpgrade), noble)
require.NoError(t, err, "chain did not produce blocks after upgrade")
// startup
require.NoError(t, n.CreateNodeContainer(ctx))
require.NoError(t, n.StartContainer(ctx))

// stop all nodes to bring rest of vals up to date
err = noble.StopAllNodes(ctx)
require.NoError(t, err, "error stopping node(s)")
timeoutCtx, timeoutCtxCancel := context.WithTimeout(ctx, time.Second*45)
defer timeoutCtxCancel()

err = noble.StartAllNodes(ctx)
require.NoError(t, err, "error starting upgraded node(s)")
require.NoError(t, testutil.WaitForBlocks(timeoutCtx, int(blocksAfterUpgrade), noble))
}

timeoutCtx, timeoutCtxCancel = context.WithTimeout(ctx, time.Second*45)
defer timeoutCtxCancel()
// blocks should still be produced after rolling update
timeoutCtx, timeoutCtxCancel := context.WithTimeout(ctx, time.Second*45)
defer timeoutCtxCancel()

err = testutil.WaitForBlocks(timeoutCtx, int(blocksAfterUpgrade), noble)
require.NoError(t, err, "chain did not produce blocks after upgrade")
err = testutil.WaitForBlocks(timeoutCtx, int(blocksAfterUpgrade), noble)
require.NoError(t, err, "chain did not produce blocks after upgrade")

// stop all nodes to bring rest of vals up to date
err = noble.StopAllNodes(ctx)
require.NoError(t, err, "error stopping node(s)")

err = noble.StartAllNodes(ctx)
require.NoError(t, err, "error starting upgraded node(s)")

timeoutCtx, timeoutCtxCancel = context.WithTimeout(ctx, time.Second*45)
defer timeoutCtxCancel()

err = testutil.WaitForBlocks(timeoutCtx, int(blocksAfterUpgrade), noble)
require.NoError(t, err, "chain did not produce blocks after upgrade")
}
} else {
// halt upgrade
height, err := noble.Height(ctx)
Expand Down

0 comments on commit 0dae09c

Please sign in to comment.