From 8782d4c93a23764e62e7d33cd466938f135c479f Mon Sep 17 00:00:00 2001 From: GnaD <89174180+GNaD13@users.noreply.github.com> Date: Tue, 28 Nov 2023 18:16:41 +0700 Subject: [PATCH 1/3] Change to StoreCodeUnchecked in Genesis and snapshotter (#5167) * change to store code unchecked * separate storeWasmCode and importWasmCode * add parameter to storeWasmCode to pass the store function * store code for msg server * fix: typos in godocs * Update modules/light-clients/08-wasm/internal/ibcwasm/expected_interfaces.go Co-authored-by: Damian Nolan * linting business --------- Co-authored-by: Carlos Rodriguez Co-authored-by: DimitrisJim Co-authored-by: Damian Nolan (cherry picked from commit 10bb80b70ac231adcfef79bfb304b40d47179602) # Conflicts: # modules/light-clients/08-wasm/keeper/keeper.go # modules/light-clients/08-wasm/keeper/snapshotter.go --- .../internal/ibcwasm/expected_interfaces.go | 10 ++++++- .../light-clients/08-wasm/keeper/genesis.go | 2 +- .../light-clients/08-wasm/keeper/keeper.go | 8 ++++++ .../08-wasm/keeper/msg_server.go | 2 +- .../08-wasm/keeper/snapshotter.go | 4 +++ .../08-wasm/testing/mock_engine.go | 28 +++++++++++++++---- 6 files changed, 45 insertions(+), 9 deletions(-) diff --git a/modules/light-clients/08-wasm/internal/ibcwasm/expected_interfaces.go b/modules/light-clients/08-wasm/internal/ibcwasm/expected_interfaces.go index 45849de1e0a..5b57a2f0d0b 100644 --- a/modules/light-clients/08-wasm/internal/ibcwasm/expected_interfaces.go +++ b/modules/light-clients/08-wasm/internal/ibcwasm/expected_interfaces.go @@ -11,10 +11,18 @@ type WasmEngine interface { // StoreCode will compile the wasm code, and store the resulting pre-compile // as well as the original code. Both can be referenced later via checksum // This must be done one time for given code, after which it can be - // instatitated many times, and each instance called many times. + // instantiated many times, and each instance called many times. // It does the same as StoreCodeUnchecked plus the static checks. StoreCode(code wasmvm.WasmCode) (wasmvm.Checksum, error) + // StoreCodeUnchecked will compile the wasm code, and store the resulting pre-compile + // as well as the original code. Both can be referenced later via checksum + // This must be done one time for given code, after which it can be + // instantiated many times, and each instance called many times. + // It does the same as StoreCode but without the static checks. + // This allows restoring previous contract code in genesis and state-sync that may have been initially stored under different configuration constraints. + StoreCodeUnchecked(code wasmvm.WasmCode) (wasmvm.Checksum, error) + // Instantiate will create a new contract based on the given checksum. // We can set the initMsg (contract "genesis") here, and it then receives // an account and address and can be invoked (Execute) many times. diff --git a/modules/light-clients/08-wasm/keeper/genesis.go b/modules/light-clients/08-wasm/keeper/genesis.go index de88b457cb2..143099e8cfa 100644 --- a/modules/light-clients/08-wasm/keeper/genesis.go +++ b/modules/light-clients/08-wasm/keeper/genesis.go @@ -12,7 +12,7 @@ import ( // state. func (k Keeper) InitGenesis(ctx sdk.Context, gs types.GenesisState) error { for _, contract := range gs.Contracts { - _, err := k.storeWasmCode(ctx, contract.CodeBytes) + _, err := k.storeWasmCode(ctx, contract.CodeBytes, ibcwasm.GetVM().StoreCodeUnchecked) if err != nil { return err } diff --git a/modules/light-clients/08-wasm/keeper/keeper.go b/modules/light-clients/08-wasm/keeper/keeper.go index 3fb6bec81a6..a1315fd3451 100644 --- a/modules/light-clients/08-wasm/keeper/keeper.go +++ b/modules/light-clients/08-wasm/keeper/keeper.go @@ -94,12 +94,16 @@ func (k Keeper) GetAuthority() string { return k.authority } +<<<<<<< HEAD func generateWasmChecksum(code []byte) []byte { hash := sha256.Sum256(code) return hash[:] } func (k Keeper) storeWasmCode(ctx sdk.Context, code []byte) ([]byte, error) { +======= +func (Keeper) storeWasmCode(ctx sdk.Context, code []byte, storeFn func(code wasmvm.WasmCode) (wasmvm.Checksum, error)) ([]byte, error) { +>>>>>>> 10bb80b7 (Change to StoreCodeUnchecked in Genesis and snapshotter (#5167)) var err error if types.IsGzip(code) { ctx.GasMeter().ConsumeGas(types.VMGasRegister.UncompressCosts(len(code)), "Uncompress gzip bytecode") @@ -122,7 +126,11 @@ func (k Keeper) storeWasmCode(ctx sdk.Context, code []byte) ([]byte, error) { // create the code in the vm ctx.GasMeter().ConsumeGas(types.VMGasRegister.CompileCosts(len(code)), "Compiling wasm bytecode") +<<<<<<< HEAD vmChecksum, err := k.wasmVM.StoreCode(code) +======= + vmChecksum, err := storeFn(code) +>>>>>>> 10bb80b7 (Change to StoreCodeUnchecked in Genesis and snapshotter (#5167)) if err != nil { return nil, errorsmod.Wrap(err, "failed to store contract") } diff --git a/modules/light-clients/08-wasm/keeper/msg_server.go b/modules/light-clients/08-wasm/keeper/msg_server.go index d63d5ded4bb..cf37610cdf6 100644 --- a/modules/light-clients/08-wasm/keeper/msg_server.go +++ b/modules/light-clients/08-wasm/keeper/msg_server.go @@ -22,7 +22,7 @@ func (k Keeper) StoreCode(goCtx context.Context, msg *types.MsgStoreCode) (*type } ctx := sdk.UnwrapSDKContext(goCtx) - checksum, err := k.storeWasmCode(ctx, msg.WasmByteCode) + checksum, err := k.storeWasmCode(ctx, msg.WasmByteCode, ibcwasm.GetVM().StoreCode) if err != nil { return nil, errorsmod.Wrap(err, "failed to store wasm bytecode") } diff --git a/modules/light-clients/08-wasm/keeper/snapshotter.go b/modules/light-clients/08-wasm/keeper/snapshotter.go index 91540d27aad..dcdb41908c4 100644 --- a/modules/light-clients/08-wasm/keeper/snapshotter.go +++ b/modules/light-clients/08-wasm/keeper/snapshotter.go @@ -113,7 +113,11 @@ func restoreV1(ctx sdk.Context, k *Keeper, compressedCode []byte) error { return errorsmod.Wrap(err, "failed to uncompress wasm code") } +<<<<<<< HEAD checksum, err := k.wasmVM.StoreCode(wasmCode) +======= + checksum, err := ibcwasm.GetVM().StoreCodeUnchecked(wasmCode) +>>>>>>> 10bb80b7 (Change to StoreCodeUnchecked in Genesis and snapshotter (#5167)) if err != nil { return errorsmod.Wrap(err, "failed to store wasm code") } diff --git a/modules/light-clients/08-wasm/testing/mock_engine.go b/modules/light-clients/08-wasm/testing/mock_engine.go index 202bb901ff0..fea2cad8dfd 100644 --- a/modules/light-clients/08-wasm/testing/mock_engine.go +++ b/modules/light-clients/08-wasm/testing/mock_engine.go @@ -65,6 +65,13 @@ func NewMockWasmEngine() *MockWasmEngine { return checkSum, nil } + m.StoreCodeUncheckedFn = func(code wasmvm.WasmCode) (wasmvm.Checksum, error) { + checkSum, _ := types.CreateChecksum(code) + + m.storedContracts[binary.LittleEndian.Uint32(checkSum)] = code + return checkSum, nil + } + m.PinFn = func(checksum wasmvm.Checksum) error { return nil } @@ -106,12 +113,13 @@ func (m *MockWasmEngine) RegisterSudoCallback(sudoMessage any, fn sudoFn) { // Without a stub function a panic is thrown. // ref: https://github.com/CosmWasm/wasmd/blob/v0.42.0/x/wasm/keeper/wasmtesting/mock_engine.go#L19 type MockWasmEngine struct { - StoreCodeFn func(code wasmvm.WasmCode) (wasmvm.Checksum, error) - InstantiateFn func(checksum wasmvm.Checksum, env wasmvmtypes.Env, info wasmvmtypes.MessageInfo, initMsg []byte, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.Response, uint64, error) - MigrateFn func(checksum wasmvm.Checksum, env wasmvmtypes.Env, migrateMsg []byte, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.Response, uint64, error) - GetCodeFn func(checksum wasmvm.Checksum) (wasmvm.WasmCode, error) - PinFn func(checksum wasmvm.Checksum) error - UnpinFn func(checksum wasmvm.Checksum) error + StoreCodeFn func(code wasmvm.WasmCode) (wasmvm.Checksum, error) + StoreCodeUncheckedFn func(code wasmvm.WasmCode) (wasmvm.Checksum, error) + InstantiateFn func(checksum wasmvm.Checksum, env wasmvmtypes.Env, info wasmvmtypes.MessageInfo, initMsg []byte, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.Response, uint64, error) + MigrateFn func(checksum wasmvm.Checksum, env wasmvmtypes.Env, migrateMsg []byte, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.Response, uint64, error) + GetCodeFn func(checksum wasmvm.Checksum) (wasmvm.WasmCode, error) + PinFn func(checksum wasmvm.Checksum) error + UnpinFn func(checksum wasmvm.Checksum) error // queryCallbacks contains a mapping of queryMsg field type name to callback function. queryCallbacks map[string]queryFn @@ -129,6 +137,14 @@ func (m *MockWasmEngine) StoreCode(code wasmvm.WasmCode) (wasmvm.Checksum, error return m.StoreCodeFn(code) } +// StoreCode implements the WasmEngine interface. +func (m *MockWasmEngine) StoreCodeUnchecked(code wasmvm.WasmCode) (wasmvm.Checksum, error) { + if m.StoreCodeUncheckedFn == nil { + panic(errors.New("mock engine is not properly initialized: StoreCodeUncheckedFn is nil")) + } + return m.StoreCodeUncheckedFn(code) +} + // Instantiate implements the WasmEngine interface. func (m *MockWasmEngine) Instantiate(checksum wasmvm.Checksum, env wasmvmtypes.Env, info wasmvmtypes.MessageInfo, initMsg []byte, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.Response, uint64, error) { if m.InstantiateFn == nil { From 235a88dbd16db095ff89f6945c42d499961f7a1f Mon Sep 17 00:00:00 2001 From: Carlos Rodriguez Date: Wed, 29 Nov 2023 21:58:23 +0100 Subject: [PATCH 2/3] fix some conflicts --- modules/light-clients/08-wasm/keeper/keeper.go | 14 -------------- .../light-clients/08-wasm/keeper/snapshotter.go | 5 +---- 2 files changed, 1 insertion(+), 18 deletions(-) diff --git a/modules/light-clients/08-wasm/keeper/keeper.go b/modules/light-clients/08-wasm/keeper/keeper.go index a1315fd3451..8e6f0d48bf6 100644 --- a/modules/light-clients/08-wasm/keeper/keeper.go +++ b/modules/light-clients/08-wasm/keeper/keeper.go @@ -2,7 +2,6 @@ package keeper import ( "bytes" - "crypto/sha256" "encoding/hex" "errors" "fmt" @@ -94,16 +93,7 @@ func (k Keeper) GetAuthority() string { return k.authority } -<<<<<<< HEAD -func generateWasmChecksum(code []byte) []byte { - hash := sha256.Sum256(code) - return hash[:] -} - -func (k Keeper) storeWasmCode(ctx sdk.Context, code []byte) ([]byte, error) { -======= func (Keeper) storeWasmCode(ctx sdk.Context, code []byte, storeFn func(code wasmvm.WasmCode) (wasmvm.Checksum, error)) ([]byte, error) { ->>>>>>> 10bb80b7 (Change to StoreCodeUnchecked in Genesis and snapshotter (#5167)) var err error if types.IsGzip(code) { ctx.GasMeter().ConsumeGas(types.VMGasRegister.UncompressCosts(len(code)), "Uncompress gzip bytecode") @@ -126,11 +116,7 @@ func (Keeper) storeWasmCode(ctx sdk.Context, code []byte, storeFn func(code wasm // create the code in the vm ctx.GasMeter().ConsumeGas(types.VMGasRegister.CompileCosts(len(code)), "Compiling wasm bytecode") -<<<<<<< HEAD - vmChecksum, err := k.wasmVM.StoreCode(code) -======= vmChecksum, err := storeFn(code) ->>>>>>> 10bb80b7 (Change to StoreCodeUnchecked in Genesis and snapshotter (#5167)) if err != nil { return nil, errorsmod.Wrap(err, "failed to store contract") } diff --git a/modules/light-clients/08-wasm/keeper/snapshotter.go b/modules/light-clients/08-wasm/keeper/snapshotter.go index dcdb41908c4..decf98c873d 100644 --- a/modules/light-clients/08-wasm/keeper/snapshotter.go +++ b/modules/light-clients/08-wasm/keeper/snapshotter.go @@ -14,6 +14,7 @@ import ( tmproto "github.com/cometbft/cometbft/proto/tendermint/types" + "github.com/cosmos/ibc-go/modules/light-clients/08-wasm/internal/ibcwasm" "github.com/cosmos/ibc-go/modules/light-clients/08-wasm/types" ) @@ -113,11 +114,7 @@ func restoreV1(ctx sdk.Context, k *Keeper, compressedCode []byte) error { return errorsmod.Wrap(err, "failed to uncompress wasm code") } -<<<<<<< HEAD - checksum, err := k.wasmVM.StoreCode(wasmCode) -======= checksum, err := ibcwasm.GetVM().StoreCodeUnchecked(wasmCode) ->>>>>>> 10bb80b7 (Change to StoreCodeUnchecked in Genesis and snapshotter (#5167)) if err != nil { return errorsmod.Wrap(err, "failed to store wasm code") } From f4f9be95c269008cec7c14750b58bf3642cba106 Mon Sep 17 00:00:00 2001 From: Carlos Rodriguez Date: Thu, 30 Nov 2023 09:59:38 +0100 Subject: [PATCH 3/3] use storeFn --- modules/light-clients/08-wasm/keeper/keeper.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/light-clients/08-wasm/keeper/keeper.go b/modules/light-clients/08-wasm/keeper/keeper.go index d86dcc7c353..65a813149c5 100644 --- a/modules/light-clients/08-wasm/keeper/keeper.go +++ b/modules/light-clients/08-wasm/keeper/keeper.go @@ -118,7 +118,7 @@ func (Keeper) storeWasmCode(ctx sdk.Context, code []byte, storeFn func(code wasm // create the code in the vm ctx.GasMeter().ConsumeGas(types.VMGasRegister.CompileCosts(len(code)), "Compiling wasm bytecode") - vmChecksum, err := ibcwasm.GetVM().StoreCode(code) + vmChecksum, err := storeFn(code) if err != nil { return nil, errorsmod.Wrap(err, "failed to store contract") }