diff --git a/x/wasm/client/cli/gov_tx_test.go b/x/wasm/client/cli/gov_tx_test.go index bc498f0fb..f63af3ad5 100644 --- a/x/wasm/client/cli/gov_tx_test.go +++ b/x/wasm/client/cli/gov_tx_test.go @@ -104,7 +104,7 @@ func TestParseCodeInfoFlags(t *testing.T) { wasmBin, err := os.ReadFile("../../keeper/testdata/hackatom.wasm.gzip") require.NoError(t, err) - checksumStr := "beb3de5e9b93b52e514c74ce87ccddb594b9bcd33b7f1af1bb6da63fc883917b" + checksumStr := "5ca46abb8e9b1b754a5c906f9c0f4eec9121ee09e3cee55ea0faba54763706e2" specs := map[string]struct { args []string diff --git a/x/wasm/client/cli/tx_test.go b/x/wasm/client/cli/tx_test.go index 8d6dfcf84..1be235b4d 100644 --- a/x/wasm/client/cli/tx_test.go +++ b/x/wasm/client/cli/tx_test.go @@ -75,22 +75,22 @@ func TestParseVerificationFlags(t *testing.T) { "gov store zipped": { srcPath: "../../keeper/testdata/hackatom.wasm.gzip", args: []string{ - "--instantiate-everybody=true", "--code-hash=beb3de5e9b93b52e514c74ce87ccddb594b9bcd33b7f1af1bb6da63fc883917b", + "--instantiate-everybody=true", "--code-hash=5ca46abb8e9b1b754a5c906f9c0f4eec9121ee09e3cee55ea0faba54763706e2", "--code-source-url=https://example.com", "--builder=cosmwasm/workspace-optimizer:0.12.11", }, expBuilder: "cosmwasm/workspace-optimizer:0.12.11", expSource: "https://example.com", - expCodeHash: "beb3de5e9b93b52e514c74ce87ccddb594b9bcd33b7f1af1bb6da63fc883917b", + expCodeHash: "5ca46abb8e9b1b754a5c906f9c0f4eec9121ee09e3cee55ea0faba54763706e2", }, "gov store raw": { srcPath: "../../keeper/testdata/hackatom.wasm", args: []string{ - "--instantiate-everybody=true", "--code-hash=beb3de5e9b93b52e514c74ce87ccddb594b9bcd33b7f1af1bb6da63fc883917b", + "--instantiate-everybody=true", "--code-hash=5ca46abb8e9b1b754a5c906f9c0f4eec9121ee09e3cee55ea0faba54763706e2", "--code-source-url=https://example.com", "--builder=cosmwasm/workspace-optimizer:0.12.11", }, expBuilder: "cosmwasm/workspace-optimizer:0.12.11", expSource: "https://example.com", - expCodeHash: "beb3de5e9b93b52e514c74ce87ccddb594b9bcd33b7f1af1bb6da63fc883917b", + expCodeHash: "5ca46abb8e9b1b754a5c906f9c0f4eec9121ee09e3cee55ea0faba54763706e2", }, "gov store checksum mismatch": { srcPath: "../../keeper/testdata/hackatom.wasm", diff --git a/x/wasm/keeper/keeper.go b/x/wasm/keeper/keeper.go index 0699c3352..24583f7db 100644 --- a/x/wasm/keeper/keeper.go +++ b/x/wasm/keeper/keeper.go @@ -191,12 +191,12 @@ func (k Keeper) storeCodeInfo(ctx sdk.Context, codeID uint64, codeInfo types.Cod func (k Keeper) importCode(ctx sdk.Context, codeID uint64, codeInfo types.CodeInfo, wasmCode []byte) error { if ioutils.IsGzip(wasmCode) { var err error - wasmCode, err = ioutils.Uncompress(wasmCode, int64(types.MaxWasmSize)) + wasmCode, err = ioutils.Uncompress(wasmCode, math.MaxInt64) if err != nil { return errorsmod.Wrap(types.ErrCreateFailed, err.Error()) } } - newCodeHash, err := k.wasmVM.Create(wasmCode) + newCodeHash, err := k.wasmVM.StoreCodeUnchecked(wasmCode) if err != nil { return errorsmod.Wrap(types.ErrCreateFailed, err.Error()) } @@ -977,7 +977,7 @@ func (k Keeper) runtimeGasForContract(ctx sdk.Context) uint64 { if meter.IsOutOfGas() { return 0 } - if meter.Limit() == math.MaxUint64 { // infinite gas meter with limit=math.MaxUint64 and not out of gas + if meter.Limit() == math.MaxUint64 { // infinite gas meter with limit=0 and not out of gas return math.MaxUint64 } diff --git a/x/wasm/keeper/keeper_test.go b/x/wasm/keeper/keeper_test.go index 30b322b9a..82aecb470 100644 --- a/x/wasm/keeper/keeper_test.go +++ b/x/wasm/keeper/keeper_test.go @@ -66,7 +66,7 @@ func TestCreateSuccess(t *testing.T) { require.NoError(t, err) require.Equal(t, hackatomWasm, storedCode) // and events emitted - codeHash := strings.ToLower("beb3de5e9b93b52e514c74ce87ccddb594b9bcd33b7f1af1bb6da63fc883917b") + codeHash := strings.ToLower("5ca46abb8e9b1b754a5c906f9c0f4eec9121ee09e3cee55ea0faba54763706e2") exp := sdk.Events{sdk.NewEvent("store_code", sdk.NewAttribute("code_checksum", codeHash), sdk.NewAttribute("code_id", "1"))} assert.Equal(t, exp, em.Events()) } @@ -416,7 +416,7 @@ func TestInstantiate(t *testing.T) { gasAfter := ctx.GasMeter().GasConsumed() if types.EnableGasVerification { - require.Equal(t, uint64(0x1b5bc), gasAfter-gasBefore) + require.Equal(t, uint64(0x1b5bd), gasAfter-gasBefore) } // ensure it is stored properly diff --git a/x/wasm/keeper/proposal_integration_test.go b/x/wasm/keeper/proposal_integration_test.go index a72d3e068..ecc2e927f 100644 --- a/x/wasm/keeper/proposal_integration_test.go +++ b/x/wasm/keeper/proposal_integration_test.go @@ -34,7 +34,7 @@ func TestStoreCodeProposal(t *testing.T) { require.NoError(t, err) gzippedWasmCode, err := os.ReadFile("./testdata/hackatom.wasm.gzip") require.NoError(t, err) - checksum, err := hex.DecodeString("beb3de5e9b93b52e514c74ce87ccddb594b9bcd33b7f1af1bb6da63fc883917b") + checksum, err := hex.DecodeString("5ca46abb8e9b1b754a5c906f9c0f4eec9121ee09e3cee55ea0faba54763706e2") require.NoError(t, err) specs := map[string]struct { @@ -319,7 +319,7 @@ func TestStoreAndInstantiateContractProposal(t *testing.T) { wasmCode, err := os.ReadFile("./testdata/hackatom.wasm") require.NoError(t, err) - checksum, err := hex.DecodeString("beb3de5e9b93b52e514c74ce87ccddb594b9bcd33b7f1af1bb6da63fc883917b") + checksum, err := hex.DecodeString("5ca46abb8e9b1b754a5c906f9c0f4eec9121ee09e3cee55ea0faba54763706e2") require.NoError(t, err) var ( diff --git a/x/wasm/keeper/recurse_test.go b/x/wasm/keeper/recurse_test.go index d6f73cfa4..cab895b14 100644 --- a/x/wasm/keeper/recurse_test.go +++ b/x/wasm/keeper/recurse_test.go @@ -57,8 +57,8 @@ func TestGasCostOnQuery(t *testing.T) { // Note: about 100 SDK gas (10k wasmer gas) for each round of sha256 GasWork50 uint64 = 64_218 // this is a little shy of 50k gas - to keep an eye on the limit - GasReturnUnhashed uint64 = 32 - GasReturnHashed uint64 = 27 + GasReturnUnhashed uint64 = 29 + GasReturnHashed uint64 = 24 ) cases := map[string]struct { @@ -208,9 +208,9 @@ func TestLimitRecursiveQueryGas(t *testing.T) { const ( // Note: about 100 SDK gas (10k wasmer gas) for each round of sha256 - GasWork2k uint64 = 77_206 // = NewContractInstanceCosts + x // we have 6x gas used in cpu than in the instance + GasWork2k uint64 = 77_161 // = NewContractInstanceCosts + x // we have 6x gas used in cpu than in the instance // This is overhead for calling into a sub-contract - GasReturnHashed uint64 = 27 + GasReturnHashed uint64 = 25 ) cases := map[string]struct { @@ -261,7 +261,7 @@ func TestLimitRecursiveQueryGas(t *testing.T) { expectQueriesFromContract: 10, expectOutOfGas: false, expectError: "query wasm contract failed", // Error we get from the contract instance doing the failing query, not wasmd - expectedGas: 10*(GasWork2k+GasReturnHashed) - 247, + expectedGas: 10*(GasWork2k+GasReturnHashed) - 229, }, } diff --git a/x/wasm/keeper/relay.go b/x/wasm/keeper/relay.go index 1e4e215bd..5209e9b7b 100644 --- a/x/wasm/keeper/relay.go +++ b/x/wasm/keeper/relay.go @@ -137,6 +137,7 @@ func (k Keeper) OnRecvPacket( } // note submessage reply results can overwrite the `Acknowledgement` data return k.handleContractResponse(ctx, contractAddr, contractInfo.IBCPortID, res.Ok.Messages, res.Ok.Attributes, res.Ok.Acknowledgement, res.Ok.Events) + } // OnAckPacket calls the contract to handle the "acknowledgement" data which can contain success or failure of a packet diff --git a/x/wasm/keeper/test_common.go b/x/wasm/keeper/test_common.go index 23f7e0125..4eaec3281 100644 --- a/x/wasm/keeper/test_common.go +++ b/x/wasm/keeper/test_common.go @@ -658,6 +658,7 @@ func InstantiateHackatomExampleContract(t testing.TB, ctx sdk.Context, keepers T adminAddr := contract.CreatorAddr label := "demo contract to query" contractAddr, _, err := keepers.ContractKeeper.Instantiate(ctx, contract.CodeID, contract.CreatorAddr, adminAddr, initMsgBz, label, initialAmount) + fmt.Println(err) require.NoError(t, err) return HackatomExampleInstance{ ExampleContract: contract, diff --git a/x/wasm/keeper/testdata/cyberpunk.wasm b/x/wasm/keeper/testdata/cyberpunk.wasm index 355804ad1..7f81df52e 100644 Binary files a/x/wasm/keeper/testdata/cyberpunk.wasm and b/x/wasm/keeper/testdata/cyberpunk.wasm differ diff --git a/x/wasm/keeper/testdata/hackatom.wasm b/x/wasm/keeper/testdata/hackatom.wasm index baa03a853..d7ae04051 100644 Binary files a/x/wasm/keeper/testdata/hackatom.wasm and b/x/wasm/keeper/testdata/hackatom.wasm differ diff --git a/x/wasm/keeper/testdata/hackatom.wasm.gzip b/x/wasm/keeper/testdata/hackatom.wasm.gzip index 3c95e9b1d..58da39db0 100644 Binary files a/x/wasm/keeper/testdata/hackatom.wasm.gzip and b/x/wasm/keeper/testdata/hackatom.wasm.gzip differ diff --git a/x/wasm/keeper/testdata/ibc_reflect.wasm b/x/wasm/keeper/testdata/ibc_reflect.wasm index ec737104c..c51a0ba47 100644 Binary files a/x/wasm/keeper/testdata/ibc_reflect.wasm and b/x/wasm/keeper/testdata/ibc_reflect.wasm differ diff --git a/x/wasm/keeper/testdata/ibc_reflect_send.wasm b/x/wasm/keeper/testdata/ibc_reflect_send.wasm index 0f7d7e459..a6a2b7ff4 100644 Binary files a/x/wasm/keeper/testdata/ibc_reflect_send.wasm and b/x/wasm/keeper/testdata/ibc_reflect_send.wasm differ diff --git a/x/wasm/keeper/testdata/reflect.wasm b/x/wasm/keeper/testdata/reflect.wasm index 31735645d..23fcff553 100644 Binary files a/x/wasm/keeper/testdata/reflect.wasm and b/x/wasm/keeper/testdata/reflect.wasm differ diff --git a/x/wasm/keeper/testdata/staking.wasm b/x/wasm/keeper/testdata/staking.wasm index 015ae00ed..635b04ec1 100644 Binary files a/x/wasm/keeper/testdata/staking.wasm and b/x/wasm/keeper/testdata/staking.wasm differ diff --git a/x/wasm/keeper/testdata/version.txt b/x/wasm/keeper/testdata/version.txt index 31899b963..f5ca6914e 100644 --- a/x/wasm/keeper/testdata/version.txt +++ b/x/wasm/keeper/testdata/version.txt @@ -1,3 +1,3 @@ v1.3.0 burner.wasm: v1.2.0 -ibc-reflect.wasm: custom build, see: https://github.com/CosmWasm/cosmwasm/pull/1690 \ No newline at end of file +ibc-reflect.wasm: custom build, see: https://github.com/CosmWasm/cosmwasm/pull/1690 diff --git a/x/wasm/keeper/wasmtesting/mock_engine.go b/x/wasm/keeper/wasmtesting/mock_engine.go index df13b3376..1ec7800d2 100644 --- a/x/wasm/keeper/wasmtesting/mock_engine.go +++ b/x/wasm/keeper/wasmtesting/mock_engine.go @@ -197,6 +197,10 @@ func SelfCallingInstMockWasmer(executeCalled *bool) *MockWasmer { anyCodeID := bytes.Repeat([]byte{0x1}, 32) return anyCodeID, nil }, + StoreCodeFn: func(code wasmvm.WasmCode) (wasmvm.Checksum, error) { + anyCodeID := bytes.Repeat([]byte{0x1}, 32) + return anyCodeID, nil + }, InstantiateFn: func(codeID 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) { return &wasmvmtypes.Response{ Messages: []wasmvmtypes.SubMsg{ diff --git a/x/wasm/types/events.go b/x/wasm/types/events.go index 442c3ed36..a456519bf 100644 --- a/x/wasm/types/events.go +++ b/x/wasm/types/events.go @@ -1,5 +1,11 @@ package types +import ( + "fmt" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/ibc-go/v6/modules/core/exported" +) + const ( // WasmModuleEventType is stored with any contract TX that returns non empty EventAttributes WasmModuleEventType = "wasm" @@ -17,8 +23,31 @@ const ( EventTypeGovContractResult = "gov_contract_result" EventTypeUpdateContractAdmin = "update_contract_admin" EventTypeUpdateCodeAccessConfig = "update_code_access_config" + EventTypePacketRecv = "ibc_packet_received" ) +// EmitAcknowledgementEvent emits an event signalling a successful or failed acknowledgement and including the error +// details if any. +func EmitAcknowledgementEvent(ctx sdk.Context, contractAddr sdk.AccAddress, ack exported.Acknowledgement, err error) { + success := err == nil && (ack == nil || ack.Success()) + attributes := []sdk.Attribute{ + sdk.NewAttribute(sdk.AttributeKeyModule, ModuleName), + sdk.NewAttribute(AttributeKeyContractAddr, contractAddr.String()), + sdk.NewAttribute(AttributeKeyAckSuccess, fmt.Sprintf("%t", success)), + } + + if err != nil { + attributes = append(attributes, sdk.NewAttribute(AttributeKeyAckError, err.Error())) + } + + ctx.EventManager().EmitEvent( + sdk.NewEvent( + EventTypePacketRecv, + attributes..., + ), + ) +} + // event attributes returned from contract execution const ( AttributeReservedPrefix = "_" @@ -31,4 +60,6 @@ const ( AttributeKeyNewAdmin = "new_admin_address" AttributeKeyCodePermission = "code_permission" AttributeKeyAuthorizedAddresses = "authorized_addresses" + AttributeKeyAckSuccess = "success" + AttributeKeyAckError = "error" )