Skip to content

Commit

Permalink
migrate lots of contexts
Browse files Browse the repository at this point in the history
  • Loading branch information
technicallyty committed Jan 22, 2025
1 parent e2860db commit 90e2e33
Show file tree
Hide file tree
Showing 9 changed files with 140 additions and 149 deletions.
82 changes: 45 additions & 37 deletions modules/light-clients/08-wasm/keeper/contract_keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,19 @@ package keeper

import (
"bytes"
"context"
"encoding/hex"
"encoding/json"
"errors"

wasmvm "github.com/CosmWasm/wasmvm/v2"
wasmvmtypes "github.com/CosmWasm/wasmvm/v2/types"

"cosmossdk.io/core/header"
errorsmod "cosmossdk.io/errors"
storetypes "cosmossdk.io/store/types"

"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"

internaltypes "github.com/cosmos/ibc-go/modules/light-clients/08-wasm/internal/types"
"github.com/cosmos/ibc-go/modules/light-clients/08-wasm/types"
clienttypes "github.com/cosmos/ibc-go/v9/modules/core/02-client/types"
Expand All @@ -34,70 +34,78 @@ var (
)

// instantiateContract calls vm.Instantiate with appropriate arguments.
func (k Keeper) instantiateContract(ctx sdk.Context, clientID string, clientStore storetypes.KVStore, checksum types.Checksum, msg []byte) (*wasmvmtypes.ContractResult, error) {
sdkGasMeter := ctx.GasMeter()
multipliedGasMeter := types.NewMultipliedGasMeter(sdkGasMeter, types.VMGasRegister)
gasLimit := VMGasRegister.RuntimeGasForContract(ctx)
func (k Keeper) instantiateContract(ctx context.Context, clientID string, clientStore storetypes.KVStore, checksum types.Checksum, msg []byte) (*wasmvmtypes.ContractResult, error) {
meter := k.GasService.GasMeter(ctx)
multipliedGasMeter := types.NewMultipliedGasMeter(meter, types.VMGasRegister)
gasLimit := VMGasRegister.RuntimeGasForContract(meter)

env := getEnv(ctx, clientID)
env := getEnv(k.HeaderService.HeaderInfo(ctx), clientID)

msgInfo := wasmvmtypes.MessageInfo{
Sender: "",
Funds: nil,
}

ctx.GasMeter().ConsumeGas(types.VMGasRegister.SetupContractCost(true, len(msg)), "Loading CosmWasm module: instantiate")
if err := meter.Consume(types.VMGasRegister.SetupContractCost(true, len(msg)), "Loading CosmWasm module: instantiate"); err != nil {
return nil, err
}
resp, gasUsed, err := k.GetVM().Instantiate(checksum, env, msgInfo, msg, internaltypes.NewStoreAdapter(clientStore), wasmvmAPI, k.newQueryHandler(ctx, clientID), multipliedGasMeter, gasLimit, types.CostJSONDeserialization)
types.VMGasRegister.ConsumeRuntimeGas(ctx, gasUsed)
types.VMGasRegister.ConsumeRuntimeGas(meter, gasUsed)
return resp, err
}

// callContract calls vm.Sudo with internally constructed gas meter and environment.
func (k Keeper) callContract(ctx sdk.Context, clientID string, clientStore storetypes.KVStore, checksum types.Checksum, msg []byte) (*wasmvmtypes.ContractResult, error) {
sdkGasMeter := ctx.GasMeter()
func (k Keeper) callContract(ctx context.Context, clientID string, clientStore storetypes.KVStore, checksum types.Checksum, msg []byte) (*wasmvmtypes.ContractResult, error) {
sdkGasMeter := k.GasService.GasMeter(ctx)
multipliedGasMeter := types.NewMultipliedGasMeter(sdkGasMeter, VMGasRegister)
gasLimit := VMGasRegister.RuntimeGasForContract(ctx)
gasLimit := VMGasRegister.RuntimeGasForContract(sdkGasMeter)

env := getEnv(ctx, clientID)
env := getEnv(k.HeaderService.HeaderInfo(ctx), clientID)

ctx.GasMeter().ConsumeGas(VMGasRegister.SetupContractCost(true, len(msg)), "Loading CosmWasm module: sudo")
if err := k.GasService.GasMeter(ctx).Consume(VMGasRegister.SetupContractCost(true, len(msg)), "Loading CosmWasm module: sudo"); err != nil {
return nil, err
}
resp, gasUsed, err := k.GetVM().Sudo(checksum, env, msg, internaltypes.NewStoreAdapter(clientStore), wasmvmAPI, k.newQueryHandler(ctx, clientID), multipliedGasMeter, gasLimit, types.CostJSONDeserialization)
VMGasRegister.ConsumeRuntimeGas(ctx, gasUsed)
VMGasRegister.ConsumeRuntimeGas(sdkGasMeter, gasUsed)
return resp, err
}

// queryContract calls vm.Query.
func (k Keeper) queryContract(ctx sdk.Context, clientID string, clientStore storetypes.KVStore, checksum types.Checksum, msg []byte) (*wasmvmtypes.QueryResult, error) {
sdkGasMeter := ctx.GasMeter()
multipliedGasMeter := types.NewMultipliedGasMeter(sdkGasMeter, VMGasRegister)
gasLimit := VMGasRegister.RuntimeGasForContract(ctx)
func (k Keeper) queryContract(ctx context.Context, clientID string, clientStore storetypes.KVStore, checksum types.Checksum, msg []byte) (*wasmvmtypes.QueryResult, error) {
gasMeter := k.GasService.GasMeter(ctx)
multipliedGasMeter := types.NewMultipliedGasMeter(gasMeter, VMGasRegister)
gasLimit := VMGasRegister.RuntimeGasForContract(gasMeter)

env := getEnv(ctx, clientID)
env := getEnv(k.HeaderService.HeaderInfo(ctx), clientID)

ctx.GasMeter().ConsumeGas(VMGasRegister.SetupContractCost(true, len(msg)), "Loading CosmWasm module: query")
if err := gasMeter.Consume(VMGasRegister.SetupContractCost(true, len(msg)), "Loading CosmWasm module: query"); err != nil {
return nil, err
}
resp, gasUsed, err := k.GetVM().Query(checksum, env, msg, internaltypes.NewStoreAdapter(clientStore), wasmvmAPI, k.newQueryHandler(ctx, clientID), multipliedGasMeter, gasLimit, types.CostJSONDeserialization)
VMGasRegister.ConsumeRuntimeGas(ctx, gasUsed)
VMGasRegister.ConsumeRuntimeGas(gasMeter, gasUsed)

return resp, err
}

// migrateContract calls vm.Migrate with internally constructed gas meter and environment.
func (k Keeper) migrateContract(ctx sdk.Context, clientID string, clientStore storetypes.KVStore, checksum types.Checksum, msg []byte) (*wasmvmtypes.ContractResult, error) {
sdkGasMeter := ctx.GasMeter()
multipliedGasMeter := types.NewMultipliedGasMeter(sdkGasMeter, VMGasRegister)
gasLimit := VMGasRegister.RuntimeGasForContract(ctx)
func (k Keeper) migrateContract(ctx context.Context, clientID string, clientStore storetypes.KVStore, checksum types.Checksum, msg []byte) (*wasmvmtypes.ContractResult, error) {
gasMeter := k.GasService.GasMeter(ctx)
multipliedGasMeter := types.NewMultipliedGasMeter(gasMeter, VMGasRegister)
gasLimit := VMGasRegister.RuntimeGasForContract(gasMeter)

env := getEnv(ctx, clientID)
env := getEnv(k.HeaderService.HeaderInfo(ctx), clientID)

ctx.GasMeter().ConsumeGas(VMGasRegister.SetupContractCost(true, len(msg)), "Loading CosmWasm module: migrate")
if err := gasMeter.Consume(VMGasRegister.SetupContractCost(true, len(msg)), "Loading CosmWasm module: migrate"); err != nil {
return nil, err
}
resp, gasUsed, err := k.GetVM().Migrate(checksum, env, msg, internaltypes.NewStoreAdapter(clientStore), wasmvmAPI, k.newQueryHandler(ctx, clientID), multipliedGasMeter, gasLimit, types.CostJSONDeserialization)
VMGasRegister.ConsumeRuntimeGas(ctx, gasUsed)
VMGasRegister.ConsumeRuntimeGas(gasMeter, gasUsed)

return resp, err
}

// WasmInstantiate accepts a message to instantiate a wasm contract, JSON encodes it and calls instantiateContract.
func (k Keeper) WasmInstantiate(ctx sdk.Context, clientID string, clientStore storetypes.KVStore, cs *types.ClientState, payload types.InstantiateMessage) error {
func (k Keeper) WasmInstantiate(ctx context.Context, clientID string, clientStore storetypes.KVStore, cs *types.ClientState, payload types.InstantiateMessage) error {
encodedData, err := json.Marshal(payload)
if err != nil {
return errorsmod.Wrap(err, "failed to marshal payload for wasm contract instantiation")
Expand Down Expand Up @@ -136,7 +144,7 @@ func (k Keeper) WasmInstantiate(ctx sdk.Context, clientID string, clientStore st
// - the response of the contract call contains non-empty events
// - the response of the contract call contains non-empty attributes
// - the data bytes of the response cannot be unmarshaled into the result type
func (k Keeper) WasmSudo(ctx sdk.Context, clientID string, clientStore storetypes.KVStore, cs *types.ClientState, payload types.SudoMsg) ([]byte, error) {
func (k Keeper) WasmSudo(ctx context.Context, clientID string, clientStore storetypes.KVStore, cs *types.ClientState, payload types.SudoMsg) ([]byte, error) {
encodedData, err := json.Marshal(payload)
if err != nil {
return nil, errorsmod.Wrap(err, "failed to marshal payload for wasm execution")
Expand Down Expand Up @@ -171,7 +179,7 @@ func (k Keeper) WasmSudo(ctx sdk.Context, clientID string, clientStore storetype
// WasmMigrate migrate calls the migrate entry point of the contract with the given payload and returns the result.
// WasmMigrate returns an error if:
// - the contract migration returns an error
func (k Keeper) WasmMigrate(ctx sdk.Context, clientStore storetypes.KVStore, cs *types.ClientState, clientID string, payload []byte) error {
func (k Keeper) WasmMigrate(ctx context.Context, clientStore storetypes.KVStore, cs *types.ClientState, clientID string, payload []byte) error {
res, err := k.migrateContract(ctx, clientID, clientStore, cs.Checksum, payload)
if err != nil {
return errorsmod.Wrap(types.ErrVMError, err.Error())
Expand All @@ -192,7 +200,7 @@ func (k Keeper) WasmMigrate(ctx sdk.Context, clientStore storetypes.KVStore, cs
// WasmQuery returns an error if:
// - the contract query returns an error
// - the data bytes of the response cannot be unmarshal into the result type
func (k Keeper) WasmQuery(ctx sdk.Context, clientID string, clientStore storetypes.KVStore, cs *types.ClientState, payload types.QueryMsg) ([]byte, error) {
func (k Keeper) WasmQuery(ctx context.Context, clientID string, clientStore storetypes.KVStore, cs *types.ClientState, payload types.QueryMsg) ([]byte, error) {
encodedData, err := json.Marshal(payload)
if err != nil {
return nil, errorsmod.Wrap(err, "failed to marshal payload for wasm query")
Expand Down Expand Up @@ -250,15 +258,15 @@ func unmarshalClientState(cdc codec.BinaryCodec, bz []byte) (exported.ClientStat
}

// getEnv returns the state of the blockchain environment the contract is running on
func getEnv(ctx sdk.Context, contractAddr string) wasmvmtypes.Env {
chainID := ctx.BlockHeader().ChainID
height := ctx.BlockHeader().Height
func getEnv(header header.Info, contractAddr string) wasmvmtypes.Env {
chainID := header.ChainID
height := header.Height

// safety checks before casting below
if height < 0 {
panic(errors.New("block height must never be negative"))
}
nsec := ctx.BlockTime().UnixNano()
nsec := header.Time.UnixNano()
if nsec < 0 {
panic(errors.New("block (unix) time must never be negative "))
}
Expand Down
46 changes: 22 additions & 24 deletions modules/light-clients/08-wasm/keeper/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,34 +6,32 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"

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

"cosmossdk.io/core/event"
)

// emitStoreWasmCodeEvent emits a store wasm code event
func emitStoreWasmCodeEvent(ctx sdk.Context, checksum types.Checksum) {
ctx.EventManager().EmitEvents(sdk.Events{
sdk.NewEvent(
types.EventTypeStoreWasmCode,
sdk.NewAttribute(types.AttributeKeyWasmChecksum, hex.EncodeToString(checksum)),
),
sdk.NewEvent(
sdk.EventTypeMessage,
sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
),
})
func emitStoreWasmCodeEvent(em event.Manager, checksum types.Checksum) {
em.EmitKV(
types.EventTypeStoreWasmCode,
event.NewAttribute(types.AttributeKeyWasmChecksum, hex.EncodeToString(checksum)),
)
em.EmitKV(
sdk.EventTypeMessage,
event.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
)
}

// emitMigrateContractEvent emits a migrate contract event
func emitMigrateContractEvent(ctx sdk.Context, clientID string, checksum, newChecksum types.Checksum) {
ctx.EventManager().EmitEvents(sdk.Events{
sdk.NewEvent(
types.EventTypeMigrateContract,
sdk.NewAttribute(types.AttributeKeyClientID, clientID),
sdk.NewAttribute(types.AttributeKeyWasmChecksum, hex.EncodeToString(checksum)),
sdk.NewAttribute(types.AttributeKeyNewChecksum, hex.EncodeToString(newChecksum)),
),
sdk.NewEvent(
sdk.EventTypeMessage,
sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
),
})
func emitMigrateContractEvent(em event.Manager, clientID string, checksum, newChecksum types.Checksum) {
em.EmitKV(
types.EventTypeMigrateContract,
event.NewAttribute(types.AttributeKeyClientID, clientID),
event.NewAttribute(types.AttributeKeyWasmChecksum, hex.EncodeToString(checksum)),
event.NewAttribute(types.AttributeKeyNewChecksum, hex.EncodeToString(newChecksum)),
)
em.EmitKV(
sdk.EventTypeMessage,
event.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
)
}
5 changes: 2 additions & 3 deletions modules/light-clients/08-wasm/keeper/grpc_query.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (
"cosmossdk.io/collections"
errorsmod "cosmossdk.io/errors"

sdk "github.com/cosmos/cosmos-sdk/types"
sdkquery "github.com/cosmos/cosmos-sdk/types/query"

"github.com/cosmos/ibc-go/modules/light-clients/08-wasm/types"
Expand All @@ -19,7 +18,7 @@ import (
var _ types.QueryServer = (*Keeper)(nil)

// Code implements the Query/Code gRPC method
func (k Keeper) Code(goCtx context.Context, req *types.QueryCodeRequest) (*types.QueryCodeResponse, error) {
func (k Keeper) Code(ctx context.Context, req *types.QueryCodeRequest) (*types.QueryCodeResponse, error) {
if req == nil {
return nil, status.Error(codes.InvalidArgument, "empty request")
}
Expand All @@ -30,7 +29,7 @@ func (k Keeper) Code(goCtx context.Context, req *types.QueryCodeRequest) (*types
}

// Only return checksums we previously stored, not arbitrary checksums that might be stored via e.g Wasmd.
if !k.HasChecksum(sdk.UnwrapSDKContext(goCtx), checksum) {
if !k.HasChecksum(ctx, checksum) {
return nil, status.Error(codes.NotFound, errorsmod.Wrap(types.ErrWasmChecksumNotFound, req.Checksum).Error())
}

Expand Down
29 changes: 11 additions & 18 deletions modules/light-clients/08-wasm/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,12 @@ import (

"cosmossdk.io/collections"
"cosmossdk.io/core/appmodule"
"cosmossdk.io/core/log"
errorsmod "cosmossdk.io/errors"
"cosmossdk.io/log"

"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"

"github.com/cosmos/ibc-go/modules/light-clients/08-wasm/types"
clienttypes "github.com/cosmos/ibc-go/v9/modules/core/02-client/types"
"github.com/cosmos/ibc-go/v9/modules/core/exported"
)

// Keeper defines the 08-wasm keeper
Expand Down Expand Up @@ -48,12 +45,8 @@ func (k Keeper) GetAuthority() string {
}

// Logger returns a module-specific logger.
func (Keeper) Logger(ctx sdk.Context) log.Logger {
return moduleLogger(ctx)
}

func moduleLogger(ctx sdk.Context) log.Logger {
return ctx.Logger().With("module", "x/"+exported.ModuleName+"-"+types.ModuleName)
func (k Keeper) Logger() log.Logger {
return k.Environment.Logger
}

// GetVM returns the keeper's vm engine.
Expand All @@ -76,8 +69,8 @@ func (k *Keeper) setQueryPlugins(plugins QueryPlugins) {
k.queryPlugins = plugins
}

func (k Keeper) newQueryHandler(ctx sdk.Context, callerID string) *queryHandler {
return newQueryHandler(ctx, k.getQueryPlugins(), callerID)
func (k Keeper) newQueryHandler(ctx context.Context, callerID string) *queryHandler {
return newQueryHandler(ctx, k.Environment, k.getQueryPlugins(), callerID)
}

// storeWasmCode stores the contract to the VM, pins the checksum in the VM's in memory cache and stores the checksum
Expand All @@ -87,8 +80,9 @@ func (k Keeper) newQueryHandler(ctx sdk.Context, callerID string) *queryHandler
// - The contract must not have already been stored in store.
func (k Keeper) storeWasmCode(ctx context.Context, code []byte, storeFn func(code wasmvm.WasmCode, gasLimit uint64) (wasmvm.Checksum, uint64, error)) ([]byte, error) {
var err error
gasMeter := k.GasService.GasMeter(ctx)
if types.IsGzip(code) {
if err := k.GasService.GasMeter(ctx).Consume(types.VMGasRegister.UncompressCosts(len(code)), "Uncompress gzip bytecode"); err != nil {
if err := gasMeter.Consume(types.VMGasRegister.UncompressCosts(len(code)), "Uncompress gzip bytecode"); err != nil {
return nil, errorsmod.Wrap(err, "failed to consume gas for decompression")
}

Expand All @@ -114,10 +108,9 @@ func (k Keeper) storeWasmCode(ctx context.Context, code []byte, storeFn func(cod
}

// create the code in the vm
sdkCtx := sdk.UnwrapSDKContext(ctx)
gasLeft := types.VMGasRegister.RuntimeGasForContract(sdkCtx)
gasLeft := types.VMGasRegister.RuntimeGasForContract(gasMeter)
vmChecksum, gasUsed, err := storeFn(code, gasLeft)
types.VMGasRegister.ConsumeRuntimeGas(sdkCtx, gasUsed)
types.VMGasRegister.ConsumeRuntimeGas(gasMeter, gasUsed)
if err != nil {
return nil, errorsmod.Wrap(err, "failed to store contract")
}
Expand All @@ -143,7 +136,7 @@ func (k Keeper) storeWasmCode(ctx context.Context, code []byte, storeFn func(cod

// migrateContractCode migrates the contract for a given light client to one denoted by the given new checksum. The checksum we
// are migrating to must first be stored using storeWasmCode and must not match the checksum currently stored for this light client.
func (k Keeper) migrateContractCode(ctx sdk.Context, clientID string, newChecksum, migrateMsg []byte) error {
func (k Keeper) migrateContractCode(ctx context.Context, clientID string, newChecksum, migrateMsg []byte) error {
clientStore := k.clientKeeper.ClientStore(ctx, clientID)
wasmClientState, found := types.GetClientState(clientStore, k.cdc)
if !found {
Expand Down Expand Up @@ -182,7 +175,7 @@ func (k Keeper) migrateContractCode(ctx sdk.Context, clientID string, newChecksu

k.clientKeeper.SetClientState(ctx, clientID, wasmClientState)

emitMigrateContractEvent(ctx, clientID, oldChecksum, newChecksum)
emitMigrateContractEvent(k.Environment.EventService.EventManager(ctx), clientID, oldChecksum, newChecksum)

return nil
}
Expand Down
2 changes: 1 addition & 1 deletion modules/light-clients/08-wasm/keeper/migrations.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func (m Migrator) MigrateChecksums(ctx sdk.Context) error {
return err
}

m.keeper.Logger(ctx).Info("successfully migrated Checksums to collections")
m.keeper.Logger().Info("successfully migrated Checksums to collections")
return nil
}

Expand Down
Loading

0 comments on commit 90e2e33

Please sign in to comment.