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

fix!: Add upgrade handler #3610

Merged
merged 7 commits into from
Mar 7, 2025
Merged
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
2 changes: 1 addition & 1 deletion app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ var (
// DefaultNodeHome default home directories for the application daemon
DefaultNodeHome string

Upgrades = []upgrades.Upgrade{v23.Upgrade}
Upgrades = []upgrades.Upgrade{v23.Upgrade, v23.RCUpgrade}
)

var (
Expand Down
3 changes: 3 additions & 0 deletions app/keepers/keepers.go
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,9 @@ func NewAppKeeper(
appKeepers.AccountKeeper,
)

// We need to set the bank keeper here otherwise risk a NPE in certain message handlers
appKeepers.AuthzKeeper = appKeepers.AuthzKeeper.SetBankKeeper(appKeepers.BankKeeper)

appKeepers.FeeGrantKeeper = feegrantkeeper.NewKeeper(
appCodec,
runtime.NewKVStoreService(appKeepers.keys[feegrant.StoreKey]),
Expand Down
25 changes: 16 additions & 9 deletions app/upgrades/v23/constants.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package v23

import (
_ "embed"

ibcwasmtypes "github.com/cosmos/ibc-go/modules/light-clients/08-wasm/v10/types"

"cosmossdk.io/store/types"
Expand All @@ -12,15 +10,14 @@ import (

const (
// UpgradeName defines the on-chain upgrade name.
UpgradeName = "v23"
IbcFeeStoreKey = "feeibc"

ExpectedEthLightClientChecksum = "f82549f5bc8adaef18e5ce4f5b68269947343742c938dac322faf1583319172c"
UpgradeName = "v23"
// RCUpgradeName defines the on-chain upgrade name specifically for the testnet RC upgrade.
RCUpgradeName = "23.0.0-rc3"
IbcFeeStoreKey = "feeibc"
ClientUploaderAddress = "cosmos1raa4kyx5ypz75qqk3566c6slx2mw3qzs5ps5du"
IBCWasmStoreCodeTypeURL = "/ibc.lightclients.wasm.v1.MsgStoreCode"
)

//go:embed cw_ics08_wasm_eth.wasm.gz
var ethWasmLightClient []byte

var Upgrade = upgrades.Upgrade{
UpgradeName: UpgradeName,
CreateUpgradeHandler: CreateUpgradeHandler,
Expand All @@ -34,3 +31,13 @@ var Upgrade = upgrades.Upgrade{
},
},
}

var RCUpgrade = upgrades.Upgrade{
UpgradeName: RCUpgradeName,
CreateUpgradeHandler: CreateRCUpgradeHandler,
StoreUpgrades: types.StoreUpgrades{
Added: nil,
Renamed: nil,
Deleted: nil,
},
}
Binary file removed app/upgrades/v23/cw_ics08_wasm_eth.wasm.gz
Binary file not shown.
63 changes: 45 additions & 18 deletions app/upgrades/v23/upgrades.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,7 @@ package v23

import (
"context"
"encoding/hex"
"fmt"

ibcwasmkeeper "github.com/cosmos/ibc-go/modules/light-clients/08-wasm/v10/keeper"
ibcwasmtypes "github.com/cosmos/ibc-go/modules/light-clients/08-wasm/v10/types"
ibctmtypes "github.com/cosmos/ibc-go/v10/modules/light-clients/07-tendermint"

Expand All @@ -14,10 +11,34 @@ import (

sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/module"
"github.com/cosmos/cosmos-sdk/x/authz"
authzkeeper "github.com/cosmos/cosmos-sdk/x/authz/keeper"
govkeeper "github.com/cosmos/cosmos-sdk/x/gov/keeper"

"github.com/cosmos/gaia/v23/app/keepers"
)

// CreateRCUpgradeHandler returns an upgrade handler for Gaia v23.0.0-rc3.
// This should only be executed on networks which have already run a previous v23 upgrade handler.
func CreateRCUpgradeHandler(
mm *module.Manager,
configurator module.Configurator,
keepers *keepers.AppKeepers,
) upgradetypes.UpgradeHandler {
return func(c context.Context, plan upgradetypes.Plan, vm module.VersionMap) (module.VersionMap, error) {
ctx := sdk.UnwrapSDKContext(c)
ctx.Logger().Info("Starting custom migration...")

if err := AuthzGrantWasmLightClient(c, keepers.AuthzKeeper, *keepers.GovKeeper); err != nil {
ctx.Logger().Error("Error running authz grant for ibc wasm client", "message", err.Error())
return vm, err
}

ctx.Logger().Info("Upgrade v23.0.0-rc3 complete")
return vm, nil
}
}

// CreateUpgradeHandler returns an upgrade handler for Gaia v23.
func CreateUpgradeHandler(
mm *module.Manager,
Expand All @@ -39,10 +60,9 @@ func CreateUpgradeHandler(
params.AllowedClients = []string{ibctmtypes.ModuleName, ibcwasmtypes.ModuleName}
keepers.IBCKeeper.ClientKeeper.SetParams(ctx, params)

// Add Eth Light Wasm Light Client
ctx.Logger().Info("Adding Eth Light Wasm Light Client")
if err := AddEthLightWasmLightClient(ctx, keepers.WasmClientKeeper); err != nil {
ctx.Logger().Error("Error adding Eth Light Wasm Light Client", "message", err.Error())
ctx.Logger().Info("Running authz ibc wasm client grant")
if err := AuthzGrantWasmLightClient(ctx, keepers.AuthzKeeper, *keepers.GovKeeper); err != nil {
ctx.Logger().Error("Error running authz grant for ibc wasm client", "message", err.Error())
return nil, err
}

Expand All @@ -51,20 +71,27 @@ func CreateUpgradeHandler(
}
}

func AddEthLightWasmLightClient(ctx context.Context, wasmKeeper ibcwasmkeeper.Keeper) error {
resp, err := wasmKeeper.StoreCode(ctx, &ibcwasmtypes.MsgStoreCode{
Signer: wasmKeeper.GetAuthority(),
WasmByteCode: ethWasmLightClient,
func AuthzGrantWasmLightClient(ctx context.Context, authzKeeper authzkeeper.Keeper, govKeeper govkeeper.Keeper) error {
sdkCtx := sdk.UnwrapSDKContext(ctx)
grant, err := authz.NewGrant(
sdkCtx.BlockTime(),
authz.NewGenericAuthorization(IBCWasmStoreCodeTypeURL),
nil,
)
if err != nil {
return err
}
sdkCtx.Logger().Info("Granting IBC Wasm Store Code", "granter", govKeeper.GetAuthority(), "grantee", ClientUploaderAddress)
resp, err := authzKeeper.Grant(ctx, &authz.MsgGrant{
Granter: govKeeper.GetAuthority(),
Grantee: ClientUploaderAddress,
Grant: grant,
})
if err != nil {
return errorsmod.Wrap(err, "failed to store eth wasm light client during upgrade")
return err
}

actualChecksum := hex.EncodeToString(resp.Checksum)

if hex.EncodeToString(resp.Checksum) != ExpectedEthLightClientChecksum {
return fmt.Errorf("checksum mismatch: expected %s, got %s", ExpectedEthLightClientChecksum, actualChecksum)
if resp != nil {
sdkCtx.Logger().Info("Authz Keeper Grant", "response", resp.String())
}

return nil
}
43 changes: 10 additions & 33 deletions app/upgrades/v23/upgrades_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,52 +8,29 @@ import (

tmproto "github.com/cometbft/cometbft/proto/tendermint/types"

ibcwasmtypes "github.com/cosmos/ibc-go/modules/light-clients/08-wasm/v10/types"
clienttypes "github.com/cosmos/ibc-go/v10/modules/core/02-client/types"
ibcexported "github.com/cosmos/ibc-go/v10/modules/core/exported"
sdk "github.com/cosmos/cosmos-sdk/types"

"github.com/cosmos/gaia/v23/app/helpers"
v23 "github.com/cosmos/gaia/v23/app/upgrades/v23"
)

const (
clientStateJSON = `{"@type":"/ibc.lightclients.wasm.v1.ClientState","data":"eyJjaGFpbl9pZCI6MzE1MTkwOCwiZXBvY2hzX3Blcl9zeW5jX2NvbW1pdHRlZV9wZXJpb2QiOjgsImZvcmtfcGFyYW1ldGVycyI6eyJhbHRhaXIiOnsiZXBvY2giOjAsInZlcnNpb24iOiIyMDAwMDAzOCJ9LCJiZWxsYXRyaXgiOnsiZXBvY2giOjAsInZlcnNpb24iOiIzMDAwMDAzOCJ9LCJjYXBlbGxhIjp7ImVwb2NoIjowLCJ2ZXJzaW9uIjoiNDAwMDAwMzgifSwiZGVuZWIiOnsiZXBvY2giOjAsInZlcnNpb24iOiI1MDAwMDAzOCJ9LCJnZW5lc2lzX2ZvcmtfdmVyc2lvbiI6IjEwMDAwMDM4IiwiZ2VuZXNpc19zbG90IjowfSwiZ2VuZXNpc190aW1lIjoxNzQwODI3NDA3LCJnZW5lc2lzX3ZhbGlkYXRvcnNfcm9vdCI6ImQ2MWVhNDg0ZmViYWNmYWU1Mjk4ZDUyYTJiNTgxZjNlMzA1YTUxZjMxMTJhOTI0MWI5NjhkY2NmMDE5ZjdiMTEiLCJpYmNfY29tbWl0bWVudF9zbG90IjoiMHgxMjYwOTQ0NDg5MjcyOTg4ZDlkZjI4NTE0OWI1YWExYjBmNDhmMjEzNmQ2ZjQxNjE1OWY4NDBhM2UwNzQ3NjAwIiwiaWJjX2NvbnRyYWN0X2FkZHJlc3MiOiIweDI5M2MxOGUwOWU1NTA0ZWJjZTE3ZGFhN2YzZDY2MmM4YjliZjZkNzUiLCJpc19mcm96ZW4iOmZhbHNlLCJsYXRlc3Rfc2xvdCI6MzIsIm1pbl9zeW5jX2NvbW1pdHRlZV9wYXJ0aWNpcGFudHMiOjMyLCJzZWNvbmRzX3Blcl9zbG90Ijo2LCJzbG90c19wZXJfZXBvY2giOjh9","checksum":"+CVJ9byK2u8Y5c5PW2gmmUc0N0LJONrDIvrxWDMZFyw=","latest_height":{"revision_number":"0","revision_height":"32"}}`
consensusStateJSON = `{"@type":"/ibc.lightclients.wasm.v1.ConsensusState","data":"eyJjdXJyZW50X3N5bmNfY29tbWl0dGVlIjoiMHg4MTQ1ZjkyZDEzMTcxNTNlNmJiODFhOTAzZGI2ZjBiMTBjNTBhOTM2ODNmNGMyYWFiMzVlOWE4YTRiYjI4MzMyMzQyNWZiNTZhNDdkOGIzMGE5ZWZkNTA5YzhhZjE0ZTEiLCJuZXh0X3N5bmNfY29tbWl0dGVlIjoiMHg4MTQ1ZjkyZDEzMTcxNTNlNmJiODFhOTAzZGI2ZjBiMTBjNTBhOTM2ODNmNGMyYWFiMzVlOWE4YTRiYjI4MzMyMzQyNWZiNTZhNDdkOGIzMGE5ZWZkNTA5YzhhZjE0ZTEiLCJzbG90IjozMiwic3RhdGVfcm9vdCI6IjB4MjI4NTQzYWVlYzk0NjA5YjQwOGUyNzI0NjIzZjgyMGExNjFhYmY5OWRkODMyNzQ4MWQ1NGNmYmUyNzAyOTE1ZCIsInN0b3JhZ2Vfcm9vdCI6IjB4MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMCIsInRpbWVzdGFtcCI6MTc0MDgyNzU5OX0="}`
)

func TestAddEthLightWasmLightClient(t *testing.T) {
func TestGrantIBCWasmAuth(t *testing.T) {
gaiaApp := helpers.Setup(t)
ctx := gaiaApp.NewUncachedContext(true, tmproto.Header{
Time: time.Unix(1740829624, 0),
})

err := v23.AddEthLightWasmLightClient(ctx, gaiaApp.WasmClientKeeper)
require.NoError(t, err)

// check that the checksum is as expected
queryChecksumsResp, err := gaiaApp.WasmClientKeeper.Checksums(ctx, &ibcwasmtypes.QueryChecksumsRequest{})
require.NoError(t, err)
require.Len(t, queryChecksumsResp.Checksums, 1)
require.Equal(t, v23.ExpectedEthLightClientChecksum, queryChecksumsResp.Checksums[0])

var clientState ibcexported.ClientState
err = gaiaApp.AppCodec().UnmarshalInterfaceJSON([]byte(clientStateJSON), &clientState)
err := v23.AuthzGrantWasmLightClient(ctx, gaiaApp.AuthzKeeper, *gaiaApp.GovKeeper)
require.NoError(t, err)

var consensusState ibcexported.ConsensusState
err = gaiaApp.AppCodec().UnmarshalInterfaceJSON([]byte(consensusStateJSON), &consensusState)
granteeAddr, err := sdk.AccAddressFromBech32(v23.ClientUploaderAddress)
require.NoError(t, err)

createMsg, err := clienttypes.NewMsgCreateClient(clientState, consensusState, "")
granterAddr, err := sdk.AccAddressFromBech32(gaiaApp.GovKeeper.GetAuthority())
require.NoError(t, err)

// create a light client
createClientResp, err := gaiaApp.IBCKeeper.CreateClient(ctx, createMsg)
require.NoError(t, err)
require.Equal(t, "08-wasm-0", createClientResp.ClientId)

// Make a call into the actual light client to verify we can call the light client contract
timestamp, err := gaiaApp.IBCKeeper.ClientKeeper.GetClientTimestampAtHeight(ctx, "08-wasm-0", clienttypes.NewHeight(0, 32))
require.NoError(t, err)
require.Equal(t, uint64(1740827599000000000), timestamp)
auth, _ := gaiaApp.AuthzKeeper.GetAuthorization(
ctx, granteeAddr,
granterAddr,
v23.IBCWasmStoreCodeTypeURL)
require.NotNil(t, auth)
}
Loading