diff --git a/Dockerfile b/Dockerfile index e96b6f638b..2feb3b3285 100644 --- a/Dockerfile +++ b/Dockerfile @@ -15,10 +15,10 @@ RUN apk add git WORKDIR /code COPY . /code/ # See https://github.com/CosmWasm/wasmvm/releases -ADD https://github.com/CosmWasm/wasmvm/releases/download/v1.2.4/libwasmvm_muslc.aarch64.a /lib/libwasmvm_muslc.aarch64.a -ADD https://github.com/CosmWasm/wasmvm/releases/download/v1.2.4/libwasmvm_muslc.x86_64.a /lib/libwasmvm_muslc.x86_64.a -RUN sha256sum /lib/libwasmvm_muslc.aarch64.a | grep 682a54082e131eaff9beec80ba3e5908113916fcb8ddf7c668cb2d97cb94c13c -RUN sha256sum /lib/libwasmvm_muslc.x86_64.a | grep ce3d892377d2523cf563e01120cb1436f9343f80be952c93f66aa94f5737b661 +ADD https://github.com/CosmWasm/wasmvm/releases/download/v1.3.0-rc.0/libwasmvm_muslc.aarch64.a /lib/libwasmvm_muslc.aarch64.a +ADD https://github.com/CosmWasm/wasmvm/releases/download/v1.3.0-rc.0/libwasmvm_muslc.x86_64.a /lib/libwasmvm_muslc.x86_64.a +RUN sha256sum /lib/libwasmvm_muslc.aarch64.a | grep f1d5d58e1699dd63bc81c8ee6950a6092729572ccedebdf122c2bbe838cf74ee +RUN sha256sum /lib/libwasmvm_muslc.x86_64.a | grep 829d6063c64feb05b11e39290de0c52402385226e11f8a19a03deca03c996f63 # Copy the library you want to the final location that will be found by the linker flag `-lwasmvm_muslc` RUN cp /lib/libwasmvm_muslc.${arch}.a /lib/libwasmvm_muslc.a diff --git a/README.md b/README.md index 4c95cbb83d..43c1593452 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,7 @@ compatibility list: | wasmd | wasmvm | cosmwasm-vm | cosmwasm-std | |-------|--------------|-------------|--------------| +| 0.33 | v1.3.0 | | 1.0-1.3 | | 0.32 | v1.2.3 | | 1.0-1.2 | | 0.31 | v1.2.0 | | 1.0-1.2 | | 0.30 | v1.1.0 | | 1.0-1.1 | diff --git a/go.mod b/go.mod index 66ca5ff59b..4aee30bc1b 100644 --- a/go.mod +++ b/go.mod @@ -3,9 +3,9 @@ module github.com/CosmWasm/wasmd go 1.19 require ( - github.com/CosmWasm/wasmvm v1.2.4 + github.com/CosmWasm/wasmvm v1.3.0-rc.0 github.com/cosmos/cosmos-proto v1.0.0-beta.2 - github.com/cosmos/cosmos-sdk v0.45.15 + github.com/cosmos/cosmos-sdk v0.45.16 github.com/cosmos/gogoproto v1.4.6 github.com/cosmos/iavl v0.19.5 github.com/cosmos/ibc-go/v4 v4.3.0 @@ -111,6 +111,7 @@ require ( github.com/minio/highwayhash v1.0.2 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mtibben/percent v0.2.1 // indirect + github.com/onsi/ginkgo v1.16.4 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/pelletier/go-toml v1.9.5 // indirect github.com/pelletier/go-toml/v2 v2.0.5 // indirect diff --git a/go.sum b/go.sum index c232189616..ca2d0d9a02 100644 --- a/go.sum +++ b/go.sum @@ -64,8 +64,8 @@ github.com/CloudyKit/fastprinter v0.0.0-20170127035650-74b38d55f37a/go.mod h1:EF github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno= github.com/CloudyKit/jet v2.1.3-0.20180809161101-62edd43e4f88+incompatible/go.mod h1:HPYO+50pSWkPoj9Q/eq0aRGByCL6ScRlUmiEX5Zgm+w= github.com/CloudyKit/jet/v3 v3.0.0/go.mod h1:HKQPgSJmdK8hdoAbKUUWajkHyHo4RaU5rMdUywE7VMo= -github.com/CosmWasm/wasmvm v1.2.4 h1:6OfeZuEcEH/9iqwrg2pkeVtDCkMoj9U6PpKtcrCyVrQ= -github.com/CosmWasm/wasmvm v1.2.4/go.mod h1:vW/E3h8j9xBQs9bCoijDuawKo9kCtxOaS8N8J7KFtkc= +github.com/CosmWasm/wasmvm v1.3.0-rc.0 h1:mHSFWM6i5HX/ZVzaFT0CmO0N4nnePJZX/DM4RNCP6uo= +github.com/CosmWasm/wasmvm v1.3.0-rc.0/go.mod h1:vW/E3h8j9xBQs9bCoijDuawKo9kCtxOaS8N8J7KFtkc= github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= @@ -226,8 +226,8 @@ github.com/cosmos/cosmos-db v0.0.0-20221226095112-f3c38ecb5e32 h1:zlCp9n3uwQieEL github.com/cosmos/cosmos-db v0.0.0-20221226095112-f3c38ecb5e32/go.mod h1:kwMlEC4wWvB48zAShGKVqboJL6w4zCLesaNQ3YLU2BQ= github.com/cosmos/cosmos-proto v1.0.0-beta.2 h1:X3OKvWgK9Gsejo0F1qs5l8Qn6xJV/AzgIWR2wZ8Nua8= github.com/cosmos/cosmos-proto v1.0.0-beta.2/go.mod h1:+XRCLJ14pr5HFEHIUcn51IKXD1Fy3rkEQqt4WqmN4V0= -github.com/cosmos/cosmos-sdk v0.45.15 h1:yyLZ9PylnR1DADf9FYGxnn8t3+Y5K2mMUXNUN38MI5A= -github.com/cosmos/cosmos-sdk v0.45.15/go.mod h1:bScuNwWAP0TZJpUf+SHXRU3xGoUPp+X9nAzfeIXts40= +github.com/cosmos/cosmos-sdk v0.45.16 h1:5ba/Bh5/LE55IwHQuCU4fiG4eXeDKtSWzehXRpaKDcw= +github.com/cosmos/cosmos-sdk v0.45.16/go.mod h1:bScuNwWAP0TZJpUf+SHXRU3xGoUPp+X9nAzfeIXts40= github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d/go.mod h1:tSxLoYXyBmiFeKpvmq4dzayMdCjCnu8uqmCysIGBT2Y= github.com/cosmos/go-bip39 v1.0.0 h1:pcomnQdrdH22njcAatO0yWojsUnCO3y2tNoV1cb6hHY= github.com/cosmos/go-bip39 v1.0.0/go.mod h1:RNJv0H/pOIVgxw6KS7QeX2a0Uo0aKUlfhZ4xuwvCdJw= @@ -378,6 +378,7 @@ github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5Nq github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8= @@ -757,8 +758,9 @@ github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxzi github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/neilotoole/errgroup v0.1.6/go.mod h1:Q2nLGf+594h0CLBs/Mbg6qOr7GtqDK7C2S41udRnToE= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= @@ -769,8 +771,9 @@ github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.13.0/go.mod h1:+REjRxOmWfHCjfv9TTWB1jD1Frx4XydAD3zm1lskyM0= -github.com/onsi/ginkgo v1.14.0 h1:2mOpI4JVVPBN+WQRa0WKH2eXR+Ey+uK4n7Zj0aYpIQA= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= +github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= +github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= @@ -1246,6 +1249,7 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1346,6 +1350,7 @@ golang.org/x/tools v0.0.0-20201022035929-9cf592e881e9/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= diff --git a/x/wasm/client/cli/gov_tx.go b/x/wasm/client/cli/gov_tx.go index c516be2932..f5a0a64a4d 100644 --- a/x/wasm/client/cli/gov_tx.go +++ b/x/wasm/client/cli/gov_tx.go @@ -2,27 +2,25 @@ package cli import ( "bytes" - "crypto/sha256" "encoding/hex" "fmt" "net/url" "strconv" "strings" - "github.com/CosmWasm/wasmd/x/wasm/ioutils" - - "github.com/docker/distribution/reference" - + wasmvm "github.com/CosmWasm/wasmvm" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/tx" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/version" "github.com/cosmos/cosmos-sdk/x/gov/client/cli" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + "github.com/docker/distribution/reference" "github.com/pkg/errors" "github.com/spf13/cobra" flag "github.com/spf13/pflag" + "github.com/CosmWasm/wasmd/x/wasm/ioutils" "github.com/CosmWasm/wasmd/x/wasm/types" ) @@ -135,7 +133,10 @@ func parseVerificationFlags(gzippedWasm []byte, flags *flag.FlagSet) (string, st if err != nil { return "", "", nil, fmt.Errorf("invalid zip: %w", err) } - checksum := sha256.Sum256(raw) + checksum, err := wasmvm.CreateChecksum(raw) + if err != nil { + return "", "", nil, fmt.Errorf("checksum: %s", err) + } if !bytes.Equal(checksum[:], codeHash) { return "", "", nil, fmt.Errorf("code-hash mismatch: %X, checksum: %X", codeHash, checksum) } diff --git a/x/wasm/keeper/genesis_test.go b/x/wasm/keeper/genesis_test.go index ddf89f8a29..b778d75561 100644 --- a/x/wasm/keeper/genesis_test.go +++ b/x/wasm/keeper/genesis_test.go @@ -9,6 +9,7 @@ import ( "testing" "time" + wasmvm "github.com/CosmWasm/wasmvm" "github.com/cosmos/cosmos-sdk/store" sdk "github.com/cosmos/cosmos-sdk/types" authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" @@ -539,7 +540,8 @@ func TestImportContractWithCodeHistoryPreserved(t *testing.T) { wasmCode, err := os.ReadFile("./testdata/hackatom.wasm") require.NoError(t, err) - wasmCodeHash := sha256.Sum256(wasmCode) + wasmCodeHash, err := wasmvm.CreateChecksum(wasmCode) + require.NoError(t, err) enc64 := base64.StdEncoding.EncodeToString genesisStr := fmt.Sprintf(genesisTemplate, enc64(wasmCodeHash[:]), enc64(wasmCode)) diff --git a/x/wasm/keeper/keeper.go b/x/wasm/keeper/keeper.go index 508a04d6fa..f1e87366e2 100644 --- a/x/wasm/keeper/keeper.go +++ b/x/wasm/keeper/keeper.go @@ -154,7 +154,7 @@ func (k Keeper) create(ctx sdk.Context, creator sdk.AccAddress, wasmCode []byte, } ctx.GasMeter().ConsumeGas(k.gasRegister.CompileCosts(len(wasmCode)), "Compiling wasm bytecode") - checksum, err = k.wasmVM.Create(wasmCode) + checksum, err = k.wasmVM.StoreCode(wasmCode) if err != nil { return 0, checksum, sdkerrors.Wrap(types.ErrCreateFailed, err.Error()) } @@ -194,7 +194,7 @@ func (k Keeper) importCode(ctx sdk.Context, codeID uint64, codeInfo types.CodeIn return types.ErrCreateFailed.Wrap(sdkerrors.Wrap(err, "uncompress wasm archive").Error()) } } - newCodeHash, err := k.wasmVM.Create(wasmCode) + newCodeHash, err := k.wasmVM.StoreCodeUnchecked(wasmCode) if err != nil { return sdkerrors.Wrap(types.ErrCreateFailed, err.Error()) } diff --git a/x/wasm/keeper/keeper_test.go b/x/wasm/keeper/keeper_test.go index bf25c52284..c673a16fe8 100644 --- a/x/wasm/keeper/keeper_test.go +++ b/x/wasm/keeper/keeper_test.go @@ -711,7 +711,7 @@ func TestInstantiateWithContractDataResponse(t *testing.T) { return &wasmvmtypes.Response{Data: []byte("my-response-data")}, 0, nil }, AnalyzeCodeFn: wasmtesting.WithoutIBCAnalyzeFn, - CreateFn: wasmtesting.NoOpCreateFn, + StoreCodeFn: wasmtesting.NoOpStoreCodeFn, } example := StoreRandomContract(t, ctx, keepers, wasmerMock) @@ -742,7 +742,7 @@ func TestInstantiateWithContractFactoryChildQueriesParent(t *testing.T) { return do(codeID, env, info, initMsg, store, goapi, querier, gasMeter, gasLimit, deserCost) }, AnalyzeCodeFn: wasmtesting.WithoutIBCAnalyzeFn, - CreateFn: wasmtesting.NoOpCreateFn, + StoreCodeFn: wasmtesting.NoOpStoreCodeFn, } // overwrite wasmvm in router diff --git a/x/wasm/keeper/msg_server_integration_test.go b/x/wasm/keeper/msg_server_integration_test.go index dde8ae7744..ba76d8088b 100644 --- a/x/wasm/keeper/msg_server_integration_test.go +++ b/x/wasm/keeper/msg_server_integration_test.go @@ -1,10 +1,11 @@ package keeper_test import ( - "crypto/sha256" _ "embed" "testing" + wasmvm "github.com/CosmWasm/wasmvm" + wasmvmtypes "github.com/CosmWasm/wasmvm/types" "github.com/cosmos/cosmos-sdk/testutil/testdata" "github.com/stretchr/testify/assert" @@ -35,12 +36,14 @@ func TestStoreCode(t *testing.T) { var result types.MsgStoreCodeResponse require.NoError(t, wasmApp.AppCodec().Unmarshal(rsp.Data, &result)) assert.Equal(t, uint64(1), result.CodeID) - expHash := sha256.Sum256(wasmContract) - assert.Equal(t, expHash[:], result.Checksum) + + expHash, err := wasmvm.CreateChecksum(wasmContract) + require.NoError(t, err) + assert.Equal(t, expHash[:], wasmvmtypes.Checksum(result.Checksum)) // and info := wasmApp.WasmKeeper.GetCodeInfo(ctx, 1) assert.NotNil(t, info) - assert.Equal(t, expHash[:], info.CodeHash) + assert.Equal(t, expHash[:], wasmvmtypes.Checksum(info.CodeHash)) assert.Equal(t, sender.String(), info.Creator) assert.Equal(t, types.DefaultParams().InstantiateDefaultPermission.With(sender), info.InstantiateConfig) } diff --git a/x/wasm/keeper/proposal_integration_test.go b/x/wasm/keeper/proposal_integration_test.go index 9f7e49deef..221051da97 100644 --- a/x/wasm/keeper/proposal_integration_test.go +++ b/x/wasm/keeper/proposal_integration_test.go @@ -746,7 +746,7 @@ func TestPinCodesProposal(t *testing.T) { govKeeper, wasmKeeper := keepers.GovKeeper, keepers.WasmKeeper mock := wasmtesting.MockWasmer{ - CreateFn: wasmtesting.NoOpCreateFn, + StoreCodeFn: wasmtesting.NoOpStoreCodeFn, AnalyzeCodeFn: wasmtesting.WithoutIBCAnalyzeFn, } var ( @@ -834,7 +834,7 @@ func TestUnpinCodesProposal(t *testing.T) { govKeeper, wasmKeeper := keepers.GovKeeper, keepers.WasmKeeper mock := wasmtesting.MockWasmer{ - CreateFn: wasmtesting.NoOpCreateFn, + StoreCodeFn: wasmtesting.NoOpStoreCodeFn, AnalyzeCodeFn: wasmtesting.WithoutIBCAnalyzeFn, } var ( @@ -922,7 +922,7 @@ func TestUpdateInstantiateConfigProposal(t *testing.T) { govKeeper, wasmKeeper := keepers.GovKeeper, keepers.WasmKeeper mock := wasmtesting.MockWasmer{ - CreateFn: wasmtesting.NoOpCreateFn, + StoreCodeFn: wasmtesting.NoOpStoreCodeFn, AnalyzeCodeFn: wasmtesting.WithoutIBCAnalyzeFn, } anyAddress, err := sdk.AccAddressFromBech32("cosmos100dejzacpanrldpjjwksjm62shqhyss44jf5xz") diff --git a/x/wasm/keeper/snapshotter.go b/x/wasm/keeper/snapshotter.go index fcece63714..ea8a87ffd3 100644 --- a/x/wasm/keeper/snapshotter.go +++ b/x/wasm/keeper/snapshotter.go @@ -108,7 +108,7 @@ func restoreV1(ctx sdk.Context, k *Keeper, compressedCode []byte) error { } // FIXME: check which codeIDs the checksum matches?? - _, err = k.wasmVM.Create(wasmCode) + _, err = k.wasmVM.StoreCodeUnchecked(wasmCode) if err != nil { return sdkerrors.Wrap(types.ErrCreateFailed, err.Error()) } diff --git a/x/wasm/keeper/snapshotter_integration_test.go b/x/wasm/keeper/snapshotter_integration_test.go index 432d56c79d..a2c32e57c2 100644 --- a/x/wasm/keeper/snapshotter_integration_test.go +++ b/x/wasm/keeper/snapshotter_integration_test.go @@ -1,26 +1,25 @@ package keeper_test import ( - "crypto/sha256" "os" "testing" "time" - "github.com/CosmWasm/wasmd/x/wasm/types" - - "github.com/stretchr/testify/assert" - + wasmvm "github.com/CosmWasm/wasmvm" + wasmvmtypes "github.com/CosmWasm/wasmvm/types" cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" sdk "github.com/cosmos/cosmos-sdk/types" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" tmtypes "github.com/tendermint/tendermint/types" "github.com/CosmWasm/wasmd/app" "github.com/CosmWasm/wasmd/x/wasm/keeper" + "github.com/CosmWasm/wasmd/x/wasm/types" ) func TestSnapshotter(t *testing.T) { @@ -92,9 +91,11 @@ func TestSnapshotter(t *testing.T) { wasmKeeper.IterateCodeInfos(ctx, func(id uint64, info types.CodeInfo) bool { bz, err := wasmKeeper.GetByteCode(ctx, id) require.NoError(t, err) - hash := sha256.Sum256(bz) + + hash, err := wasmvm.CreateChecksum(bz) + require.NoError(t, err) destCodeIDToChecksum[id] = hash[:] - assert.Equal(t, hash[:], info.CodeHash) + assert.Equal(t, hash[:], wasmvmtypes.Checksum(info.CodeHash)) return false }) assert.Equal(t, srcCodeIDToChecksum, destCodeIDToChecksum) diff --git a/x/wasm/keeper/wasmtesting/mock_engine.go b/x/wasm/keeper/wasmtesting/mock_engine.go index 10c7fdfed2..84cbd6aa10 100644 --- a/x/wasm/keeper/wasmtesting/mock_engine.go +++ b/x/wasm/keeper/wasmtesting/mock_engine.go @@ -2,7 +2,6 @@ package wasmtesting import ( "bytes" - "crypto/sha256" wasmvm "github.com/CosmWasm/wasmvm" wasmvmtypes "github.com/CosmWasm/wasmvm/types" @@ -17,25 +16,26 @@ var _ types.WasmerEngine = &MockWasmer{} // MockWasmer implements types.WasmerEngine for testing purpose. One or multiple messages can be stubbed. // Without a stub function a panic is thrown. type MockWasmer struct { - CreateFn func(codeID wasmvm.WasmCode) (wasmvm.Checksum, error) - AnalyzeCodeFn func(codeID wasmvm.Checksum) (*wasmvmtypes.AnalysisReport, error) - 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) - ExecuteFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, info wasmvmtypes.MessageInfo, executeMsg []byte, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.Response, uint64, error) - QueryFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, queryMsg []byte, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) ([]byte, uint64, error) - MigrateFn func(codeID 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) - SudoFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, sudoMsg []byte, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.Response, uint64, error) - ReplyFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, reply wasmvmtypes.Reply, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.Response, uint64, error) - GetCodeFn func(codeID wasmvm.Checksum) (wasmvm.WasmCode, error) - CleanupFn func() - IBCChannelOpenFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, msg wasmvmtypes.IBCChannelOpenMsg, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBC3ChannelOpenResponse, uint64, error) - IBCChannelConnectFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, msg wasmvmtypes.IBCChannelConnectMsg, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCBasicResponse, uint64, error) - IBCChannelCloseFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, msg wasmvmtypes.IBCChannelCloseMsg, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCBasicResponse, uint64, error) - IBCPacketReceiveFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, msg wasmvmtypes.IBCPacketReceiveMsg, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCReceiveResult, uint64, error) - IBCPacketAckFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, msg wasmvmtypes.IBCPacketAckMsg, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCBasicResponse, uint64, error) - IBCPacketTimeoutFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, msg wasmvmtypes.IBCPacketTimeoutMsg, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCBasicResponse, uint64, error) - PinFn func(checksum wasmvm.Checksum) error - UnpinFn func(checksum wasmvm.Checksum) error - GetMetricsFn func() (*wasmvmtypes.Metrics, error) + StoreCodeFn func(codeID wasmvm.WasmCode) (wasmvm.Checksum, error) + StoreCodeUncheckedFn func(codeID wasmvm.WasmCode) (wasmvm.Checksum, error) + AnalyzeCodeFn func(codeID wasmvm.Checksum) (*wasmvmtypes.AnalysisReport, error) + 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) + ExecuteFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, info wasmvmtypes.MessageInfo, executeMsg []byte, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.Response, uint64, error) + QueryFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, queryMsg []byte, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) ([]byte, uint64, error) + MigrateFn func(codeID 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) + SudoFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, sudoMsg []byte, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.Response, uint64, error) + ReplyFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, reply wasmvmtypes.Reply, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.Response, uint64, error) + GetCodeFn func(codeID wasmvm.Checksum) (wasmvm.WasmCode, error) + CleanupFn func() + IBCChannelOpenFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, msg wasmvmtypes.IBCChannelOpenMsg, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBC3ChannelOpenResponse, uint64, error) + IBCChannelConnectFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, msg wasmvmtypes.IBCChannelConnectMsg, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCBasicResponse, uint64, error) + IBCChannelCloseFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, msg wasmvmtypes.IBCChannelCloseMsg, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCBasicResponse, uint64, error) + IBCPacketReceiveFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, msg wasmvmtypes.IBCPacketReceiveMsg, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCReceiveResult, uint64, error) + IBCPacketAckFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, msg wasmvmtypes.IBCPacketAckMsg, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCBasicResponse, uint64, error) + IBCPacketTimeoutFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, msg wasmvmtypes.IBCPacketTimeoutMsg, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCBasicResponse, uint64, error) + PinFn func(checksum wasmvm.Checksum) error + UnpinFn func(checksum wasmvm.Checksum) error + GetMetricsFn func() (*wasmvmtypes.Metrics, error) } func (m *MockWasmer) IBCChannelOpen(codeID wasmvm.Checksum, env wasmvmtypes.Env, msg wasmvmtypes.IBCChannelOpenMsg, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBC3ChannelOpenResponse, uint64, error) { @@ -80,11 +80,23 @@ func (m *MockWasmer) IBCPacketTimeout(codeID wasmvm.Checksum, env wasmvmtypes.En return m.IBCPacketTimeoutFn(codeID, env, msg, store, goapi, querier, gasMeter, gasLimit, deserCost) } +// Deprecated: use StoreCode instead. func (m *MockWasmer) Create(codeID wasmvm.WasmCode) (wasmvm.Checksum, error) { - if m.CreateFn == nil { + panic("Deprecated: use StoreCode instead") +} + +func (m *MockWasmer) StoreCode(codeID wasmvm.WasmCode) (wasmvm.Checksum, error) { + if m.StoreCodeFn == nil { + panic("not supposed to be called!") + } + return m.StoreCodeFn(codeID) +} + +func (m *MockWasmer) StoreCodeUnchecked(codeID wasmvm.WasmCode) (wasmvm.Checksum, error) { + if m.StoreCodeUncheckedFn == nil { panic("not supposed to be called!") } - return m.CreateFn(codeID) + return m.StoreCodeUncheckedFn(codeID) } func (m *MockWasmer) AnalyzeCode(codeID wasmvm.Checksum) (*wasmvmtypes.AnalysisReport, error) { @@ -176,7 +188,7 @@ var AlwaysPanicMockWasmer = &MockWasmer{} // SelfCallingInstMockWasmer prepares a Wasmer mock that calls itself on instantiation. func SelfCallingInstMockWasmer(executeCalled *bool) *MockWasmer { return &MockWasmer{ - CreateFn: func(code wasmvm.WasmCode) (wasmvm.Checksum, error) { + StoreCodeFn: func(code wasmvm.WasmCode) (wasmvm.Checksum, error) { anyCodeID := bytes.Repeat([]byte{0x1}, 32) return anyCodeID, nil }, @@ -290,7 +302,7 @@ type contractExecutable interface { // MakeInstantiable adds some noop functions to not fail when contract is used for instantiation func MakeInstantiable(m *MockWasmer) { - m.CreateFn = HashOnlyCreateFn + m.StoreCodeFn = HashOnlyStoreCodeFn m.InstantiateFn = NoOpInstantiateFn m.AnalyzeCodeFn = WithoutIBCAnalyzeFn } @@ -321,19 +333,18 @@ func NewIBCContractMockWasmer(c IBCContractCallbacks) *MockWasmer { return m } -func HashOnlyCreateFn(code wasmvm.WasmCode) (wasmvm.Checksum, error) { +func HashOnlyStoreCodeFn(code wasmvm.WasmCode) (wasmvm.Checksum, error) { if code == nil { return nil, sdkerrors.Wrap(types.ErrInvalid, "wasm code must not be nil") } - hash := sha256.Sum256(code) - return hash[:], nil + return wasmvm.CreateChecksum(code) } func NoOpInstantiateFn(wasmvm.Checksum, wasmvmtypes.Env, wasmvmtypes.MessageInfo, []byte, wasmvm.KVStore, wasmvm.GoAPI, wasmvm.Querier, wasmvm.GasMeter, uint64, wasmvmtypes.UFraction) (*wasmvmtypes.Response, uint64, error) { return &wasmvmtypes.Response{}, 0, nil } -func NoOpCreateFn(_ wasmvm.WasmCode) (wasmvm.Checksum, error) { +func NoOpStoreCodeFn(_ wasmvm.WasmCode) (wasmvm.Checksum, error) { return rand.Bytes(32), nil } diff --git a/x/wasm/types/proposal.go b/x/wasm/types/proposal.go index c717f35493..de69b6be13 100644 --- a/x/wasm/types/proposal.go +++ b/x/wasm/types/proposal.go @@ -997,6 +997,7 @@ func (c AccessConfigUpdate) String() string { AccessConfig: %v `, c.CodeID, c.InstantiatePermission) } + func validateCodeIDs(codeIDs []uint64) error { if len(codeIDs) == 0 { return sdkerrors.Wrap(ErrEmpty, "code ids") @@ -1004,7 +1005,6 @@ func validateCodeIDs(codeIDs []uint64) error { for i, num1 := range codeIDs { if num1 == 0 { return ErrInvalid.Wrap("0 is not accepted") - } for j, num2 := range codeIDs { if i != j && num1 == num2 { diff --git a/x/wasm/types/proposal_test.go b/x/wasm/types/proposal_test.go index 55184eb2c0..304d40cb79 100644 --- a/x/wasm/types/proposal_test.go +++ b/x/wasm/types/proposal_test.go @@ -1145,7 +1145,6 @@ func TestProposalCodeIDs(t *testing.T) { src govtypes.Content expErr bool }{ - "Pin empty code id list": { src: &PinCodesProposal{ Title: "Foo", diff --git a/x/wasm/types/test_fixtures.go b/x/wasm/types/test_fixtures.go index e84b61fd7d..1c431dcfc5 100644 --- a/x/wasm/types/test_fixtures.go +++ b/x/wasm/types/test_fixtures.go @@ -2,14 +2,18 @@ package types import ( "bytes" - "crypto/sha256" + _ "embed" "encoding/hex" "encoding/json" "math/rand" + wasmvm "github.com/CosmWasm/wasmvm" sdk "github.com/cosmos/cosmos-sdk/types" ) +//go:embed testdata/reflect.wasm +var reflectWasmCode []byte + func GenesisFixture(mutators ...func(*GenesisState)) GenesisState { const ( numCodes = 2 @@ -50,12 +54,10 @@ func randBytes(n int) []byte { } func CodeFixture(mutators ...func(*Code)) Code { - wasmCode := randBytes(100) - fixture := Code{ CodeID: 1, - CodeInfo: CodeInfoFixture(WithSHA256CodeHash(wasmCode)), - CodeBytes: wasmCode, + CodeInfo: CodeInfoFixture(WithSHA256CodeHash(reflectWasmCode)), + CodeBytes: reflectWasmCode, } for _, m := range mutators { @@ -65,8 +67,10 @@ func CodeFixture(mutators ...func(*Code)) Code { } func CodeInfoFixture(mutators ...func(*CodeInfo)) CodeInfo { - wasmCode := bytes.Repeat([]byte{0x1}, 10) - codeHash := sha256.Sum256(wasmCode) + codeHash, err := wasmvm.CreateChecksum(reflectWasmCode) + if err != nil { + panic(err) + } const anyAddress = "cosmos1qyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqs2m6sx4" fixture := CodeInfo{ CodeHash: codeHash[:], @@ -137,7 +141,10 @@ func ContractCodeHistoryEntryFixture(mutators ...func(*ContractCodeHistoryEntry) func WithSHA256CodeHash(wasmCode []byte) func(info *CodeInfo) { return func(info *CodeInfo) { - codeHash := sha256.Sum256(wasmCode) + codeHash, err := wasmvm.CreateChecksum(wasmCode) + if err != nil { + panic(err) + } info.CodeHash = codeHash[:] } } diff --git a/x/wasm/types/testdata/reflect.wasm b/x/wasm/types/testdata/reflect.wasm new file mode 100644 index 0000000000..31735645df Binary files /dev/null and b/x/wasm/types/testdata/reflect.wasm differ diff --git a/x/wasm/types/wasmer_engine.go b/x/wasm/types/wasmer_engine.go index 9b2efdef50..18d4060a40 100644 --- a/x/wasm/types/wasmer_engine.go +++ b/x/wasm/types/wasmer_engine.go @@ -19,8 +19,24 @@ type WasmerEngine interface { // For example, the code for all ERC-20 contracts should be the same. // This function stores the code for that contract only once, but it can // be instantiated with custom inputs in the future. + // + // Deprecated: use StoreCode instead. Create(code wasmvm.WasmCode) (wasmvm.Checksum, error) + // Create 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. + // It does the same as StoreCodeUnchecked plus the static checks. + StoreCode(code wasmvm.WasmCode) (wasmvm.Checksum, error) + + // Create 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. + // It does the same as StoreCode but without the static checks. + StoreCodeUnchecked(code wasmvm.WasmCode) (wasmvm.Checksum, error) + // AnalyzeCode will statically analyze the code. // Currently just reports if it exposes all IBC entry points. AnalyzeCode(checksum wasmvm.Checksum) (*wasmvmtypes.AnalysisReport, error)