From 90e2e33326aa70b98d25eaba9fb7476036f14615 Mon Sep 17 00:00:00 2001 From: Tyler <48813565+technicallyty@users.noreply.github.com> Date: Wed, 22 Jan 2025 14:02:08 -0800 Subject: [PATCH] migrate lots of contexts --- .../08-wasm/keeper/contract_keeper.go | 82 ++++++++++--------- .../light-clients/08-wasm/keeper/events.go | 46 +++++------ .../08-wasm/keeper/grpc_query.go | 5 +- .../light-clients/08-wasm/keeper/keeper.go | 29 +++---- .../08-wasm/keeper/migrations.go | 2 +- .../08-wasm/keeper/msg_server.go | 17 ++-- .../light-clients/08-wasm/keeper/querier.go | 42 +++++----- .../08-wasm/light_client_module.go | 35 +++----- .../08-wasm/types/gas_register_custom.go | 31 ++++--- 9 files changed, 140 insertions(+), 149 deletions(-) diff --git a/modules/light-clients/08-wasm/keeper/contract_keeper.go b/modules/light-clients/08-wasm/keeper/contract_keeper.go index e812f2570e4..b17473f9bad 100644 --- a/modules/light-clients/08-wasm/keeper/contract_keeper.go +++ b/modules/light-clients/08-wasm/keeper/contract_keeper.go @@ -2,6 +2,7 @@ package keeper import ( "bytes" + "context" "encoding/hex" "encoding/json" "errors" @@ -9,12 +10,11 @@ import ( 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" @@ -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") @@ -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") @@ -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()) @@ -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") @@ -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 ")) } diff --git a/modules/light-clients/08-wasm/keeper/events.go b/modules/light-clients/08-wasm/keeper/events.go index 8e9801b9e45..2262f4c4ee1 100644 --- a/modules/light-clients/08-wasm/keeper/events.go +++ b/modules/light-clients/08-wasm/keeper/events.go @@ -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), + ) } diff --git a/modules/light-clients/08-wasm/keeper/grpc_query.go b/modules/light-clients/08-wasm/keeper/grpc_query.go index 21b2a558894..a2907499561 100644 --- a/modules/light-clients/08-wasm/keeper/grpc_query.go +++ b/modules/light-clients/08-wasm/keeper/grpc_query.go @@ -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" @@ -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") } @@ -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()) } diff --git a/modules/light-clients/08-wasm/keeper/keeper.go b/modules/light-clients/08-wasm/keeper/keeper.go index e070689c5e4..ec3dc4e01ce 100644 --- a/modules/light-clients/08-wasm/keeper/keeper.go +++ b/modules/light-clients/08-wasm/keeper/keeper.go @@ -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 @@ -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. @@ -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 @@ -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") } @@ -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") } @@ -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 { @@ -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 } diff --git a/modules/light-clients/08-wasm/keeper/migrations.go b/modules/light-clients/08-wasm/keeper/migrations.go index 9626103d31c..c80c1b4a68e 100644 --- a/modules/light-clients/08-wasm/keeper/migrations.go +++ b/modules/light-clients/08-wasm/keeper/migrations.go @@ -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 } diff --git a/modules/light-clients/08-wasm/keeper/msg_server.go b/modules/light-clients/08-wasm/keeper/msg_server.go index d08063d6630..49b9eb6f33a 100644 --- a/modules/light-clients/08-wasm/keeper/msg_server.go +++ b/modules/light-clients/08-wasm/keeper/msg_server.go @@ -6,8 +6,6 @@ import ( errorsmod "cosmossdk.io/errors" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/ibc-go/modules/light-clients/08-wasm/types" ibcerrors "github.com/cosmos/ibc-go/v9/modules/core/errors" ) @@ -15,18 +13,17 @@ import ( var _ types.MsgServer = (*Keeper)(nil) // StoreCode defines a rpc handler method for MsgStoreCode -func (k Keeper) StoreCode(goCtx context.Context, msg *types.MsgStoreCode) (*types.MsgStoreCodeResponse, error) { +func (k Keeper) StoreCode(ctx context.Context, msg *types.MsgStoreCode) (*types.MsgStoreCodeResponse, error) { if k.GetAuthority() != msg.Signer { return nil, errorsmod.Wrapf(ibcerrors.ErrUnauthorized, "expected %s, got %s", k.GetAuthority(), msg.Signer) } - ctx := sdk.UnwrapSDKContext(goCtx) checksum, err := k.storeWasmCode(ctx, msg.WasmByteCode, k.GetVM().StoreCode) if err != nil { return nil, errorsmod.Wrap(err, "failed to store wasm bytecode") } - emitStoreWasmCodeEvent(ctx, checksum) + emitStoreWasmCodeEvent(k.EventService.EventManager(ctx), checksum) return &types.MsgStoreCodeResponse{ Checksum: checksum, @@ -34,16 +31,16 @@ func (k Keeper) StoreCode(goCtx context.Context, msg *types.MsgStoreCode) (*type } // RemoveChecksum defines a rpc handler method for MsgRemoveChecksum -func (k Keeper) RemoveChecksum(goCtx context.Context, msg *types.MsgRemoveChecksum) (*types.MsgRemoveChecksumResponse, error) { +func (k Keeper) RemoveChecksum(ctx context.Context, msg *types.MsgRemoveChecksum) (*types.MsgRemoveChecksumResponse, error) { if k.GetAuthority() != msg.Signer { return nil, errorsmod.Wrapf(ibcerrors.ErrUnauthorized, "expected %s, got %s", k.GetAuthority(), msg.Signer) } - if !k.HasChecksum(goCtx, msg.Checksum) { + if !k.HasChecksum(ctx, msg.Checksum) { return nil, types.ErrWasmChecksumNotFound } - err := k.GetChecksums().Remove(goCtx, msg.Checksum) + err := k.GetChecksums().Remove(ctx, msg.Checksum) if err != nil { return nil, errorsmod.Wrap(err, "failed to remove checksum") } @@ -57,13 +54,11 @@ func (k Keeper) RemoveChecksum(goCtx context.Context, msg *types.MsgRemoveChecks } // MigrateContract defines a rpc handler method for MsgMigrateContract -func (k Keeper) MigrateContract(goCtx context.Context, msg *types.MsgMigrateContract) (*types.MsgMigrateContractResponse, error) { +func (k Keeper) MigrateContract(ctx context.Context, msg *types.MsgMigrateContract) (*types.MsgMigrateContractResponse, error) { if k.GetAuthority() != msg.Signer { return nil, errorsmod.Wrapf(ibcerrors.ErrUnauthorized, "expected %s, got %s", k.GetAuthority(), msg.Signer) } - ctx := sdk.UnwrapSDKContext(goCtx) - err := k.migrateContractCode(ctx, msg.ClientId, msg.Checksum, msg.Msg) if err != nil { return nil, errorsmod.Wrap(err, "failed to migrate contract") diff --git a/modules/light-clients/08-wasm/keeper/querier.go b/modules/light-clients/08-wasm/keeper/querier.go index 20fa56b6ca0..3ed4db4f086 100644 --- a/modules/light-clients/08-wasm/keeper/querier.go +++ b/modules/light-clients/08-wasm/keeper/querier.go @@ -1,12 +1,16 @@ package keeper import ( + "context" "encoding/json" "fmt" "slices" wasmvmtypes "github.com/CosmWasm/wasmvm/v2/types" + "cosmossdk.io/core/appmodule" + "cosmossdk.io/core/gas" + "cosmossdk.io/core/log" errorsmod "cosmossdk.io/errors" storetypes "cosmossdk.io/store/types" @@ -39,44 +43,44 @@ var defaultAcceptList = []string{ // queryHandler is a wrapper around the sdk.Context and the CallerID that calls // into the query plugins. type queryHandler struct { - Ctx sdk.Context + appmodule.Environment + Ctx context.Context Plugins QueryPlugins CallerID string } // newQueryHandler returns a default querier that can be used in the contract. -func newQueryHandler(ctx sdk.Context, plugins QueryPlugins, callerID string) *queryHandler { +func newQueryHandler(ctx context.Context, env appmodule.Environment, plugins QueryPlugins, callerID string) *queryHandler { return &queryHandler{ - Ctx: ctx, - Plugins: plugins, - CallerID: callerID, + Environment: env, + Ctx: ctx, + Plugins: plugins, + CallerID: callerID, } } // GasConsumed implements the wasmvmtypes.Querier interface. func (q *queryHandler) GasConsumed() uint64 { - return VMGasRegister.ToWasmVMGas(q.Ctx.GasMeter().GasConsumed()) + return VMGasRegister.ToWasmVMGas(q.GasService.GasMeter(q.Ctx).Consumed()) } // Query implements the wasmvmtypes.Querier interface. func (q *queryHandler) Query(request wasmvmtypes.QueryRequest, gasLimit uint64) ([]byte, error) { sdkGas := VMGasRegister.FromWasmVMGas(gasLimit) + var res []byte // discard all changes/events in subCtx by not committing the cached context - subCtx, _ := q.Ctx.WithGasMeter(storetypes.NewGasMeter(sdkGas)).CacheContext() - - // make sure we charge the higher level context even on panic - defer func() { - q.Ctx.GasMeter().ConsumeGas(subCtx.GasMeter().GasConsumed(), "contract sub-query") - }() - - res, err := q.Plugins.HandleQuery(subCtx, q.CallerID, request) - if err == nil { - return res, nil - } + _, err := q.BranchService.ExecuteWithGasLimit(q.Ctx, sdkGas, func(ctx context.Context) error { + var err error + res, err = q.Plugins.HandleQuery(ctx, q.CallerID, request) + if err == nil { + return nil + } - moduleLogger(q.Ctx).Debug("Redacting query error", "cause", err) - return nil, redactError(err) + q.Logger.Debug("Redacting query error", "cause", err) + return redactError(err) + }) + return res, err } type ( diff --git a/modules/light-clients/08-wasm/light_client_module.go b/modules/light-clients/08-wasm/light_client_module.go index cd88887418e..5b0680e3b49 100644 --- a/modules/light-clients/08-wasm/light_client_module.go +++ b/modules/light-clients/08-wasm/light_client_module.go @@ -9,8 +9,6 @@ import ( errorsmod "cosmossdk.io/errors" - sdk "github.com/cosmos/cosmos-sdk/types" - internaltypes "github.com/cosmos/ibc-go/modules/light-clients/08-wasm/internal/types" wasmkeeper "github.com/cosmos/ibc-go/modules/light-clients/08-wasm/keeper" "github.com/cosmos/ibc-go/modules/light-clients/08-wasm/types" @@ -71,8 +69,7 @@ func (l LightClientModule) Initialize(ctx context.Context, clientID string, clie Checksum: clientState.Checksum, } - sdkCtx := sdk.UnwrapSDKContext(ctx) // TODO: https://github.com/cosmos/ibc-go/issues/5917 - return l.keeper.WasmInstantiate(sdkCtx, clientID, clientStore, &clientState, payload) + return l.keeper.WasmInstantiate(ctx, clientID, clientStore, &clientState, payload) } // VerifyClientMessage obtains the client state associated with the client identifier, it then must verify the ClientMessage. @@ -97,8 +94,7 @@ func (l LightClientModule) VerifyClientMessage(ctx context.Context, clientID str payload := types.QueryMsg{ VerifyClientMessage: &types.VerifyClientMessageMsg{ClientMessage: clientMessage.Data}, } - sdkCtx := sdk.UnwrapSDKContext(ctx) // TODO: https://github.com/cosmos/ibc-go/issues/5917 - _, err := l.keeper.WasmQuery(sdkCtx, clientID, clientStore, clientState, payload) + _, err := l.keeper.WasmQuery(ctx, clientID, clientStore, clientState, payload) return err } @@ -122,8 +118,7 @@ func (l LightClientModule) CheckForMisbehaviour(ctx context.Context, clientID st CheckForMisbehaviour: &types.CheckForMisbehaviourMsg{ClientMessage: clientMessage.Data}, } - sdkCtx := sdk.UnwrapSDKContext(ctx) // TODO: https://github.com/cosmos/ibc-go/issues/5917 - res, err := l.keeper.WasmQuery(sdkCtx, clientID, clientStore, clientState, payload) + res, err := l.keeper.WasmQuery(ctx, clientID, clientStore, clientState, payload) if err != nil { return false } @@ -157,8 +152,7 @@ func (l LightClientModule) UpdateStateOnMisbehaviour(ctx context.Context, client UpdateStateOnMisbehaviour: &types.UpdateStateOnMisbehaviourMsg{ClientMessage: clientMessage.Data}, } - sdkCtx := sdk.UnwrapSDKContext(ctx) // TODO: https://github.com/cosmos/ibc-go/issues/5917 - _, err := l.keeper.WasmSudo(sdkCtx, clientID, clientStore, clientState, payload) + _, err := l.keeper.WasmSudo(ctx, clientID, clientStore, clientState, payload) if err != nil { panic(err) } @@ -184,8 +178,7 @@ func (l LightClientModule) UpdateState(ctx context.Context, clientID string, cli UpdateState: &types.UpdateStateMsg{ClientMessage: clientMessage.Data}, } - sdkCtx := sdk.UnwrapSDKContext(ctx) // TODO: https://github.com/cosmos/ibc-go/issues/5917 - res, err := l.keeper.WasmSudo(sdkCtx, clientID, clientStore, clientState, payload) + res, err := l.keeper.WasmSudo(ctx, clientID, clientStore, clientState, payload) if err != nil { panic(err) } @@ -253,8 +246,7 @@ func (l LightClientModule) VerifyMembership( }, } - sdkCtx := sdk.UnwrapSDKContext(ctx) // TODO: https://github.com/cosmos/ibc-go/issues/5917 - _, err := l.keeper.WasmSudo(sdkCtx, clientID, clientStore, clientState, payload) + _, err := l.keeper.WasmSudo(ctx, clientID, clientStore, clientState, payload) return err } @@ -306,8 +298,7 @@ func (l LightClientModule) VerifyNonMembership( }, } - sdkCtx := sdk.UnwrapSDKContext(ctx) // TODO: https://github.com/cosmos/ibc-go/issues/5917 - _, err := l.keeper.WasmSudo(sdkCtx, clientID, clientStore, clientState, payload) + _, err := l.keeper.WasmSudo(ctx, clientID, clientStore, clientState, payload) return err } @@ -336,8 +327,7 @@ func (l LightClientModule) Status(ctx context.Context, clientID string) exported } payload := types.QueryMsg{Status: &types.StatusMsg{}} - sdkCtx := sdk.UnwrapSDKContext(ctx) // TODO: https://github.com/cosmos/ibc-go/issues/5917 - res, err := l.keeper.WasmQuery(sdkCtx, clientID, clientStore, clientState, payload) + res, err := l.keeper.WasmQuery(ctx, clientID, clientStore, clientState, payload) if err != nil { return exported.Unknown } @@ -386,8 +376,7 @@ func (l LightClientModule) TimestampAtHeight(ctx context.Context, clientID strin }, } - sdkCtx := sdk.UnwrapSDKContext(ctx) // TODO: https://github.com/cosmos/ibc-go/issues/5917 - res, err := l.keeper.WasmQuery(sdkCtx, clientID, clientStore, clientState, payload) + res, err := l.keeper.WasmQuery(ctx, clientID, clientStore, clientState, payload) if err != nil { return 0, errorsmod.Wrapf(err, "height (%s)", height) } @@ -440,8 +429,7 @@ func (l LightClientModule) RecoverClient(ctx context.Context, clientID, substitu MigrateClientStore: &types.MigrateClientStoreMsg{}, } - sdkCtx := sdk.UnwrapSDKContext(ctx) // TODO: https://github.com/cosmos/ibc-go/issues/5917 - _, err = l.keeper.WasmSudo(sdkCtx, clientID, store, subjectClientState, payload) + _, err = l.keeper.WasmSudo(ctx, clientID, store, subjectClientState, payload) return err } @@ -489,7 +477,6 @@ func (l LightClientModule) VerifyUpgradeAndUpdateState( }, } - sdkCtx := sdk.UnwrapSDKContext(ctx) // TODO: https://github.com/cosmos/ibc-go/issues/5917 - _, err := l.keeper.WasmSudo(sdkCtx, clientID, clientStore, clientState, payload) + _, err := l.keeper.WasmSudo(ctx, clientID, clientStore, clientState, payload) return err } diff --git a/modules/light-clients/08-wasm/types/gas_register_custom.go b/modules/light-clients/08-wasm/types/gas_register_custom.go index 991d8779c43..1453b5a1d22 100644 --- a/modules/light-clients/08-wasm/types/gas_register_custom.go +++ b/modules/light-clients/08-wasm/types/gas_register_custom.go @@ -6,9 +6,8 @@ import ( wasmvm "github.com/CosmWasm/wasmvm/v2" wasmvmtypes "github.com/CosmWasm/wasmvm/v2/types" + "cosmossdk.io/core/gas" storetypes "cosmossdk.io/store/types" - - sdk "github.com/cosmos/cosmos-sdk/types" ) // While gas_register.go is a direct copy of https://github.com/CosmWasm/wasmd/blob/main/x/wasm/types/gas_register.go @@ -24,39 +23,47 @@ var CostJSONDeserialization = wasmvmtypes.UFraction{ Denominator: 1, } -func (g WasmGasRegister) RuntimeGasForContract(ctx sdk.Context) uint64 { - meter := ctx.GasMeter() - if meter.IsOutOfGas() { +func (g WasmGasRegister) RuntimeGasForContract(meter gas.Meter) uint64 { + if meter.Remaining() >= meter.Limit() { return 0 } + // infinite gas meter with limit=0 or MaxUint64 if meter.Limit() == 0 || meter.Limit() == math.MaxUint64 { return math.MaxUint64 } - return g.ToWasmVMGas(meter.Limit() - meter.GasConsumedToLimit()) + + var consumedToLimit gas.Gas + if meter.Remaining() <= meter.Limit() { + consumedToLimit = meter.Limit() + } else { + consumedToLimit = meter.Consumed() + } + + return g.ToWasmVMGas(meter.Limit() - consumedToLimit) } -func (g WasmGasRegister) ConsumeRuntimeGas(ctx sdk.Context, gas uint64) { +func (g WasmGasRegister) ConsumeRuntimeGas(meter gas.Meter, gas uint64) { consumed := g.FromWasmVMGas(gas) - ctx.GasMeter().ConsumeGas(consumed, "wasm contract") + meter.Consume(consumed, "wasm contract") // throw OutOfGas error if we ran out (got exactly to zero due to better limit enforcing) - if ctx.GasMeter().IsOutOfGas() { + if meter.Remaining() >= meter.Limit() { panic(storetypes.ErrorOutOfGas{Descriptor: "Wasmer function execution"}) } } // MultipliedGasMeter wraps the GasMeter from context and multiplies all reads by out defined multiplier type MultipliedGasMeter struct { - originalMeter storetypes.GasMeter + originalMeter gas.Meter GasRegister GasRegister } -func NewMultipliedGasMeter(originalMeter storetypes.GasMeter, gr GasRegister) MultipliedGasMeter { +func NewMultipliedGasMeter(originalMeter gas.Meter, gr GasRegister) MultipliedGasMeter { return MultipliedGasMeter{originalMeter: originalMeter, GasRegister: gr} } var _ wasmvm.GasMeter = MultipliedGasMeter{} func (m MultipliedGasMeter) GasConsumed() storetypes.Gas { - return m.GasRegister.ToWasmVMGas(m.originalMeter.GasConsumed()) + return m.GasRegister.ToWasmVMGas(m.originalMeter.Consumed()) }