diff --git a/.github/workflows/golangci.yml b/.github/workflows/golangci.yml new file mode 100644 index 000000000..a51dd836b --- /dev/null +++ b/.github/workflows/golangci.yml @@ -0,0 +1,27 @@ +name: golangci-lint +on: + push: + tags: + - v* + branches: + - master + - main + pull_request: +permissions: + contents: read + # Optional: allow read access to pull request. Use with `only-new-issues` option. + # pull-requests: read +jobs: + golangci: + name: lint + runs-on: ubuntu-latest + steps: + - uses: actions/setup-go@v3 + with: + go-version: 1.23 # check with 1.19 because it matches dev envs. Does not need to affect go.mod. + - uses: actions/checkout@v3 + - name: golangci-lint + uses: golangci/golangci-lint-action@v3 + with: + # Optional: version of golangci-lint to use in form of v1.2 or v1.2.3 or `latest` to use the latest version + version: latest diff --git a/.golangci.yml b/.golangci.yml index 3af894222..e6381dbc2 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,10 +1,59 @@ +run: + tests: true + # timeout for analysis, e.g. 30s, 5m, default is 1m + timeout: 5m + linters: - # Enable specific linter - # https://golangci-lint.run/usage/linters/#enabled-by-default + disable-all: true enable: + - copyloopvar + - dogsled + - errcheck + - gci + - goconst + - gocritic - gofumpt - - goimports + - gosec + - gosimple + - govet + - ineffassign + - maintidx + - misspell + - nakedret + - nolintlint + # - revive + - staticcheck + # - stylecheck + - typecheck + - unconvert + - unparam + - unused + +# TODO: fix the sdkerrors.Wrap deprecation warning and re-enable staticcheck +# TODO: fix the use of deprecated gov style + +issues: + max-issues-per-linter: 10000 + max-same-issues: 10000 linters-settings: - goimports: - local-prefixes: github.com/CosmWasm/wasmvm + revive: + rules: + - name: var-naming + severity: warning + disabled: false + exclude: [""] + arguments: + - ["ID"] # AllowList + - ["VM"] # DenyList + - - upperCaseConst: true # Extra parameter (upperCaseConst|skipPackageNameChecks) + dogsled: + max-blank-identifiers: 3 + maligned: + # print struct with more effective memory layout or not, false by default + suggest-new: true + nolintlint: + allow-unused: false + allow-leading-space: true + require-explanation: false + require-specific: false diff --git a/go.mod b/go.mod index b8a003356..16083455d 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/CosmWasm/wasmvm/v2 -go 1.21 +go 1.23 require ( github.com/google/btree v1.0.0 diff --git a/ibc_test.go b/ibc_test.go index 2da754d14..c6b542c21 100644 --- a/ibc_test.go +++ b/ibc_test.go @@ -7,19 +7,18 @@ import ( "os" "testing" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "github.com/CosmWasm/wasmvm/v2/internal/api" "github.com/CosmWasm/wasmvm/v2/types" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) -const IBC_TEST_CONTRACT = "./testdata/ibc_reflect.wasm" +const IBCTestContract = "./testdata/ibc_reflect.wasm" func TestIBC(t *testing.T) { vm := withVM(t) - wasm, err := os.ReadFile(IBC_TEST_CONTRACT) + wasm, err := os.ReadFile(IBCTestContract) require.NoError(t, err) checksum, _, err := vm.StoreCode(wasm, TESTING_GAS_LIMIT) @@ -81,31 +80,31 @@ func toBytes(t *testing.T, v interface{}) []byte { return bz } -const IBC_VERSION = "ibc-reflect-v1" +const IBCVersion = "ibc-reflect-v1" func TestIBCHandshake(t *testing.T) { // code id of the reflect contract - const REFLECT_ID uint64 = 101 + const ReflectID uint64 = 101 // channel id for handshake - const CHANNEL_ID = "channel-432" + const ChannelID = "channel-432" vm := withVM(t) - checksum := createTestContract(t, vm, IBC_TEST_CONTRACT) + checksum := createTestContract(t, vm, IBCTestContract) gasMeter1 := api.NewMockGasMeter(TESTING_GAS_LIMIT) deserCost := types.UFraction{Numerator: 1, Denominator: 1} // instantiate it with this store store := api.NewLookup(gasMeter1) goapi := api.NewMockAPI() balance := types.Array[types.Coin]{} - querier := api.DefaultQuerier(api.MOCK_CONTRACT_ADDR, balance) + querier := api.DefaultQuerier(api.MockContractAddr, balance) // instantiate env := api.MockEnv() info := api.MockInfo("creator", nil) - init_msg := IBCInstantiateMsg{ - ReflectCodeID: REFLECT_ID, + initMsg := IBCInstantiateMsg{ + ReflectCodeID: ReflectID, } - i, _, err := vm.Instantiate(checksum, env, info, toBytes(t, init_msg), store, *goapi, querier, gasMeter1, TESTING_GAS_LIMIT, deserCost) + i, _, err := vm.Instantiate(checksum, env, info, toBytes(t, initMsg), store, *goapi, querier, gasMeter1, TESTING_GAS_LIMIT, deserCost) require.NoError(t, err) assert.NotNil(t, i.Ok) iResponse := i.Ok @@ -115,7 +114,7 @@ func TestIBCHandshake(t *testing.T) { gasMeter2 := api.NewMockGasMeter(TESTING_GAS_LIMIT) store.SetGasMeter(gasMeter2) env = api.MockEnv() - openMsg := api.MockIBCChannelOpenInit(CHANNEL_ID, types.Ordered, IBC_VERSION) + openMsg := api.MockIBCChannelOpenInit(ChannelID, types.Ordered, IBCVersion) o, _, err := vm.IBCChannelOpen(checksum, env, openMsg, store, *goapi, querier, gasMeter2, TESTING_GAS_LIMIT, deserCost) require.NoError(t, err) require.NotNil(t, o.Ok) @@ -127,7 +126,7 @@ func TestIBCHandshake(t *testing.T) { store.SetGasMeter(gasMeter3) env = api.MockEnv() // completes and dispatches message to create reflect contract - connectMsg := api.MockIBCChannelConnectAck(CHANNEL_ID, types.Ordered, IBC_VERSION) + connectMsg := api.MockIBCChannelConnectAck(ChannelID, types.Ordered, IBCVersion) conn, _, err := vm.IBCChannelConnect(checksum, env, connectMsg, store, *goapi, querier, gasMeter2, TESTING_GAS_LIMIT, deserCost) require.NoError(t, err) require.NotNil(t, conn.Ok) @@ -135,48 +134,48 @@ func TestIBCHandshake(t *testing.T) { require.Equal(t, 1, len(connResponse.Messages)) // check for the expected custom event - expected_events := []types.Event{{ + expectedEvents := []types.Event{{ Type: "ibc", Attributes: []types.EventAttribute{{ Key: "channel", Value: "connect", }}, }} - require.Equal(t, expected_events, connResponse.Events) + require.Equal(t, expectedEvents, connResponse.Events) // make sure it read the balance properly and we got 250 atoms dispatch := connResponse.Messages[0].Msg require.NotNil(t, dispatch.Wasm, "%#v", dispatch) require.NotNil(t, dispatch.Wasm.Instantiate, "%#v", dispatch) init := dispatch.Wasm.Instantiate - assert.Equal(t, REFLECT_ID, init.CodeID) + assert.Equal(t, ReflectID, init.CodeID) assert.Empty(t, init.Funds) } func TestIBCPacketDispatch(t *testing.T) { // code id of the reflect contract - const REFLECT_ID uint64 = 77 + const ReflectID uint64 = 77 // address of first reflect contract instance that we created - const REFLECT_ADDR = "reflect-acct-1" + const ReflectAddress = "reflect-acct-1" // channel id for handshake - const CHANNEL_ID = "channel-234" + const ChannelID = "channel-234" // setup vm := withVM(t) - checksum := createTestContract(t, vm, IBC_TEST_CONTRACT) + checksum := createTestContract(t, vm, IBCTestContract) gasMeter1 := api.NewMockGasMeter(TESTING_GAS_LIMIT) deserCost := types.UFraction{Numerator: 1, Denominator: 1} // instantiate it with this store store := api.NewLookup(gasMeter1) goapi := api.NewMockAPI() balance := types.Array[types.Coin]{} - querier := api.DefaultQuerier(api.MOCK_CONTRACT_ADDR, balance) + querier := api.DefaultQuerier(api.MockContractAddr, balance) // instantiate env := api.MockEnv() info := api.MockInfo("creator", nil) initMsg := IBCInstantiateMsg{ - ReflectCodeID: REFLECT_ID, + ReflectCodeID: ReflectID, } _, _, err := vm.Instantiate(checksum, env, info, toBytes(t, initMsg), store, *goapi, querier, gasMeter1, TESTING_GAS_LIMIT, deserCost) require.NoError(t, err) @@ -184,7 +183,7 @@ func TestIBCPacketDispatch(t *testing.T) { // channel open gasMeter2 := api.NewMockGasMeter(TESTING_GAS_LIMIT) store.SetGasMeter(gasMeter2) - openMsg := api.MockIBCChannelOpenInit(CHANNEL_ID, types.Ordered, IBC_VERSION) + openMsg := api.MockIBCChannelOpenInit(ChannelID, types.Ordered, IBCVersion) o, _, err := vm.IBCChannelOpen(checksum, env, openMsg, store, *goapi, querier, gasMeter2, TESTING_GAS_LIMIT, deserCost) require.NoError(t, err) require.NotNil(t, o.Ok) @@ -195,7 +194,7 @@ func TestIBCPacketDispatch(t *testing.T) { gasMeter3 := api.NewMockGasMeter(TESTING_GAS_LIMIT) store.SetGasMeter(gasMeter3) // completes and dispatches message to create reflect contract - connectMsg := api.MockIBCChannelConnectAck(CHANNEL_ID, types.Ordered, IBC_VERSION) + connectMsg := api.MockIBCChannelConnectAck(ChannelID, types.Ordered, IBCVersion) conn, _, err := vm.IBCChannelConnect(checksum, env, connectMsg, store, *goapi, querier, gasMeter3, TESTING_GAS_LIMIT, deserCost) require.NoError(t, err) require.NotNil(t, conn.Ok) @@ -215,7 +214,7 @@ func TestIBCPacketDispatch(t *testing.T) { Attributes: types.Array[types.EventAttribute]{ { Key: "_contract_address", - Value: REFLECT_ADDR, + Value: ReflectAddress, }, }, }}, @@ -238,8 +237,8 @@ func TestIBCPacketDispatch(t *testing.T) { err = json.Unmarshal(qResponse, &accounts) require.NoError(t, err) require.Equal(t, 1, len(accounts.Accounts)) - require.Equal(t, CHANNEL_ID, accounts.Accounts[0].ChannelID) - require.Equal(t, REFLECT_ADDR, accounts.Accounts[0].Account) + require.Equal(t, ChannelID, accounts.Accounts[0].ChannelID) + require.Equal(t, ReflectAddress, accounts.Accounts[0].Account) // process message received on this channel gasMeter5 := api.NewMockGasMeter(TESTING_GAS_LIMIT) @@ -254,7 +253,7 @@ func TestIBCPacketDispatch(t *testing.T) { }}, }, } - msg := api.MockIBCPacketReceive(CHANNEL_ID, toBytes(t, ibcMsg)) + msg := api.MockIBCPacketReceive(ChannelID, toBytes(t, ibcMsg)) pr, _, err := vm.IBCPacketReceive(checksum, env, msg, store, *goapi, querier, gasMeter5, TESTING_GAS_LIMIT, deserCost) require.NoError(t, err) assert.NotNil(t, pr.Ok) @@ -279,14 +278,14 @@ func TestIBCPacketDispatch(t *testing.T) { require.Equal(t, "invalid packet: cosmwasm_std::addresses::Addr not found", ack2.Err) // check for the expected custom event - expected_events := []types.Event{{ + expectedEvents := []types.Event{{ Type: "ibc", Attributes: []types.EventAttribute{{ Key: "packet", Value: "receive", }}, }} - require.Equal(t, expected_events, prResponse2.Events) + require.Equal(t, expectedEvents, prResponse2.Events) } func TestAnalyzeCode(t *testing.T) { @@ -305,7 +304,7 @@ func TestAnalyzeCode(t *testing.T) { require.Equal(t, uint64(42), *report.ContractMigrateVersion) // Store IBC contract - wasm2, err := os.ReadFile(IBC_TEST_CONTRACT) + wasm2, err := os.ReadFile(IBCTestContract) require.NoError(t, err) checksum2, _, err := vm.StoreCode(wasm2, TESTING_GAS_LIMIT) require.NoError(t, err) @@ -318,42 +317,42 @@ func TestAnalyzeCode(t *testing.T) { } func TestIBCMsgGetChannel(t *testing.T) { - const CHANNEL_ID = "channel-432" + const ChannelID = "channel-432" - msg1 := api.MockIBCChannelOpenInit(CHANNEL_ID, types.Ordered, "random-garbage") - msg2 := api.MockIBCChannelOpenTry(CHANNEL_ID, types.Ordered, "random-garbage") - msg3 := api.MockIBCChannelConnectAck(CHANNEL_ID, types.Ordered, "random-garbage") - msg4 := api.MockIBCChannelConnectConfirm(CHANNEL_ID, types.Ordered, "random-garbage") - msg5 := api.MockIBCChannelCloseInit(CHANNEL_ID, types.Ordered, "random-garbage") - msg6 := api.MockIBCChannelCloseConfirm(CHANNEL_ID, types.Ordered, "random-garbage") + msg1 := api.MockIBCChannelOpenInit(ChannelID, types.Ordered, "random-garbage") + msg2 := api.MockIBCChannelOpenTry(ChannelID, types.Ordered, "random-garbage") + msg3 := api.MockIBCChannelConnectAck(ChannelID, types.Ordered, "random-garbage") + msg4 := api.MockIBCChannelConnectConfirm(ChannelID, types.Ordered, "random-garbage") + msg5 := api.MockIBCChannelCloseInit(ChannelID, types.Ordered, "random-garbage") + msg6 := api.MockIBCChannelCloseConfirm(ChannelID, types.Ordered, "random-garbage") require.Equal(t, msg1.GetChannel(), msg2.GetChannel()) require.Equal(t, msg1.GetChannel(), msg3.GetChannel()) require.Equal(t, msg1.GetChannel(), msg4.GetChannel()) require.Equal(t, msg1.GetChannel(), msg5.GetChannel()) require.Equal(t, msg1.GetChannel(), msg6.GetChannel()) - require.Equal(t, msg1.GetChannel().Endpoint.ChannelID, CHANNEL_ID) + require.Equal(t, msg1.GetChannel().Endpoint.ChannelID, ChannelID) } func TestIBCMsgGetCounterVersion(t *testing.T) { - const CHANNEL_ID = "channel-432" + const ChannelID = "channel-432" const VERSION = "random-garbage" - msg1 := api.MockIBCChannelOpenInit(CHANNEL_ID, types.Ordered, VERSION) + msg1 := api.MockIBCChannelOpenInit(ChannelID, types.Ordered, VERSION) _, ok := msg1.GetCounterVersion() require.False(t, ok) - msg2 := api.MockIBCChannelOpenTry(CHANNEL_ID, types.Ordered, VERSION) + msg2 := api.MockIBCChannelOpenTry(ChannelID, types.Ordered, VERSION) v, ok := msg2.GetCounterVersion() require.True(t, ok) require.Equal(t, VERSION, v) - msg3 := api.MockIBCChannelConnectAck(CHANNEL_ID, types.Ordered, VERSION) + msg3 := api.MockIBCChannelConnectAck(ChannelID, types.Ordered, VERSION) v, ok = msg3.GetCounterVersion() require.True(t, ok) require.Equal(t, VERSION, v) - msg4 := api.MockIBCChannelConnectConfirm(CHANNEL_ID, types.Ordered, VERSION) + msg4 := api.MockIBCChannelConnectConfirm(ChannelID, types.Ordered, VERSION) _, ok = msg4.GetCounterVersion() require.False(t, ok) } diff --git a/internal/api/api_test.go b/internal/api/api_test.go index 1d8109857..ff1d95f64 100644 --- a/internal/api/api_test.go +++ b/internal/api/api_test.go @@ -5,9 +5,8 @@ import ( "os" "testing" - "github.com/stretchr/testify/require" - "github.com/CosmWasm/wasmvm/v2/types" + "github.com/stretchr/testify/require" ) func TestValidateAddressFailure(t *testing.T) { @@ -24,7 +23,7 @@ func TestValidateAddressFailure(t *testing.T) { // instantiate it with this store store := NewLookup(gasMeter) api := NewMockAPI() - querier := DefaultQuerier(MOCK_CONTRACT_ADDR, types.Array[types.Coin]{types.NewCoin(100, "ATOM")}) + querier := DefaultQuerier(MockContractAddr, types.Array[types.Coin]{types.NewCoin(100, "ATOM")}) env := MockEnvBin(t) info := MockInfoBin(t, "creator") diff --git a/internal/api/callbacks.go b/internal/api/callbacks.go index 702c8faf7..1fe276547 100644 --- a/internal/api/callbacks.go +++ b/internal/api/callbacks.go @@ -108,6 +108,7 @@ type DBState struct { // state := buildDBState(kv, callID) // db := buildDB(&state, &gasMeter) // // then pass db into some FFI function + func buildDBState(kv types.KVStore, callID uint64) DBState { return DBState{ Store: kv, @@ -231,7 +232,7 @@ func cScan(ptr *C.db_t, gasMeter *C.gas_meter_t, usedGas *cu64, start C.U8SliceV // we received an invalid pointer return C.GoError_BadArgument } - if !(*errOut).is_none { + if !errOut.is_none { panic("Got a non-none UnmanagedVector we're about to override. This is a bug because someone has to drop the old one.") } @@ -384,7 +385,7 @@ func cHumanizeAddress(ptr *C.api_t, src C.U8SliceView, dest *C.UnmanagedVector, if dest == nil || errOut == nil { return C.GoError_BadArgument } - if !(*dest).is_none || !(*errOut).is_none { + if !dest.is_none || !errOut.is_none { panic("Got a non-none UnmanagedVector we're about to override. This is a bug because someone has to drop the old one.") } @@ -412,7 +413,7 @@ func cCanonicalizeAddress(ptr *C.api_t, src C.U8SliceView, dest *C.UnmanagedVect if dest == nil || errOut == nil { return C.GoError_BadArgument } - if !(*dest).is_none || !(*errOut).is_none { + if !dest.is_none || !errOut.is_none { panic("Got a non-none UnmanagedVector we're about to override. This is a bug because someone has to drop the old one.") } @@ -439,7 +440,7 @@ func cValidateAddress(ptr *C.api_t, src C.U8SliceView, errOut *C.UnmanagedVector if errOut == nil { return C.GoError_BadArgument } - if !(*errOut).is_none { + if !errOut.is_none { panic("Got a non-none UnmanagedVector we're about to override. This is a bug because someone has to drop the old one.") } @@ -479,7 +480,7 @@ func cQueryExternal(ptr *C.querier_t, gasLimit cu64, usedGas *cu64, request C.U8 // we received an invalid pointer return C.GoError_BadArgument } - if !(*result).is_none || !(*errOut).is_none { + if !result.is_none || !errOut.is_none { panic("Got a non-none UnmanagedVector we're about to override. This is a bug because someone has to drop the old one.") } diff --git a/internal/api/iterator.go b/internal/api/iterator.go index c9a768b40..4ba47e792 100644 --- a/internal/api/iterator.go +++ b/internal/api/iterator.go @@ -28,7 +28,7 @@ var ( func startCall() uint64 { latestCallIDMutex.Lock() defer latestCallIDMutex.Unlock() - latestCallID += 1 + latestCallID++ return latestCallID } @@ -65,7 +65,7 @@ func storeIterator(callID uint64, it types.Iterator, frameLenLimit int) (uint64, new_index := len(iteratorFrames[callID]) if new_index >= frameLenLimit { - return 0, fmt.Errorf("Reached iterator limit (%d)", frameLenLimit) + return 0, fmt.Errorf("reached iterator limit (%d)", frameLenLimit) } // store at array position `new_index` diff --git a/internal/api/iterator_test.go b/internal/api/iterator_test.go index 0c81db775..53e254317 100644 --- a/internal/api/iterator_test.go +++ b/internal/api/iterator_test.go @@ -6,11 +6,10 @@ import ( "sync" "testing" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "github.com/CosmWasm/wasmvm/v2/internal/api/testdb" "github.com/CosmWasm/wasmvm/v2/types" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) type queueData struct { @@ -31,7 +30,7 @@ func setupQueueContractWithData(t *testing.T, cache Cache, values ...int) queueD // instantiate it with this store store := NewLookup(gasMeter1) api := NewMockAPI() - querier := DefaultQuerier(MOCK_CONTRACT_ADDR, types.Array[types.Coin]{types.NewCoin(100, "ATOM")}) + querier := DefaultQuerier(MockContractAddr, types.Array[types.Coin]{types.NewCoin(100, "ATOM")}) env := MockEnvBin(t) info := MockInfoBin(t, "creator") msg := []byte(`{}`) @@ -116,7 +115,7 @@ func TestStoreIteratorHitsLimit(t *testing.T) { iter, _ = store.Iterator(nil, nil) _, err = storeIterator(callID, iter, limit) - require.ErrorContains(t, err, "Reached iterator limit (2)") + require.ErrorContains(t, err, "reached iterator limit (2)") endCall(callID) } @@ -217,6 +216,9 @@ func TestQueueIteratorRaces(t *testing.T) { env := MockEnvBin(t) reduceQuery := func(t *testing.T, setup queueData, expected string) { + callID := startCall() + defer endCall(callID) + checksum, querier, api := setup.checksum, setup.querier, setup.api gasMeter := NewMockGasMeter(TESTING_GAS_LIMIT) igasMeter := types.GasMeter(gasMeter) @@ -292,5 +294,5 @@ func TestQueueIteratorLimit(t *testing.T) { query = []byte(`{"open_iterators":{"count":35000}}`) env = MockEnvBin(t) _, _, err = Query(cache, checksum, env, query, &igasMeter, store, api, &querier, gasLimit, TESTING_PRINT_DEBUG) - require.ErrorContains(t, err, "Reached iterator limit (32768)") + require.ErrorContains(t, err, "reached iterator limit (32768)") } diff --git a/internal/api/lib.go b/internal/api/lib.go index 2b71adc1c..a454af2f8 100644 --- a/internal/api/lib.go +++ b/internal/api/lib.go @@ -13,9 +13,8 @@ import ( "strings" "syscall" - "golang.org/x/sys/unix" - "github.com/CosmWasm/wasmvm/v2/types" + "golang.org/x/sys/unix" ) // Value types @@ -32,9 +31,7 @@ type ( ) // Pointers -type ( - cu8_ptr = *C.uint8_t -) +type cu8_ptr = *C.uint8_t //nolint:revive type Cache struct { ptr *C.cache_t @@ -47,26 +44,26 @@ func InitCache(config types.VMConfig) (Cache, error) { // libwasmvm would create this directory too but we need it earlier for the lockfile err := os.MkdirAll(config.Cache.BaseDir, 0o755) if err != nil { - return Cache{}, fmt.Errorf("Could not create base directory") + return Cache{}, fmt.Errorf("could not create base directory") } lockfile, err := os.OpenFile(filepath.Join(config.Cache.BaseDir, "exclusive.lock"), os.O_WRONLY|os.O_CREATE, 0o666) if err != nil { - return Cache{}, fmt.Errorf("Could not open exclusive.lock") + return Cache{}, fmt.Errorf("could not open exclusive.lock") } _, err = lockfile.WriteString("This is a lockfile that prevent two VM instances to operate on the same directory in parallel.\nSee codebase at github.com/CosmWasm/wasmvm for more information.\nSafety first – brought to you by Confio ❤️\n") if err != nil { - return Cache{}, fmt.Errorf("Error writing to exclusive.lock") + return Cache{}, fmt.Errorf("error writing to exclusive.lock") } err = unix.Flock(int(lockfile.Fd()), unix.LOCK_EX|unix.LOCK_NB) if err != nil { - return Cache{}, fmt.Errorf("Could not lock exclusive.lock. Is a different VM running in the same directory already?") + return Cache{}, fmt.Errorf("could not lock exclusive.lock. is a different VM running in the same directory already?") } configBytes, err := json.Marshal(config) if err != nil { - return Cache{}, fmt.Errorf("Could not serialize config") + return Cache{}, fmt.Errorf("could not serialize config") } configView := makeView(configBytes) defer runtime.KeepAlive(configBytes) diff --git a/internal/api/lib_test.go b/internal/api/lib_test.go index 90c55a8c2..62fabbc74 100644 --- a/internal/api/lib_test.go +++ b/internal/api/lib_test.go @@ -6,6 +6,7 @@ import ( "encoding/hex" "encoding/json" "fmt" + "math" "os" "path/filepath" "strings" @@ -13,10 +14,9 @@ import ( "testing" "time" + "github.com/CosmWasm/wasmvm/v2/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - - "github.com/CosmWasm/wasmvm/v2/types" ) const ( @@ -81,7 +81,7 @@ func TestInitCacheErrorsForBrokenDir(t *testing.T) { }, } _, err := InitCache(config) - require.ErrorContains(t, err, "Could not create base directory") + require.ErrorContains(t, err, "could not create base directory") } func TestInitLockingPreventsConcurrentAccess(t *testing.T) { @@ -109,7 +109,7 @@ func TestInitLockingPreventsConcurrentAccess(t *testing.T) { }, } _, err2 := InitCache(config2) - require.ErrorContains(t, err2, "Could not lock exclusive.lock") + require.ErrorContains(t, err2, "could not lock exclusive.lock") ReleaseCache(cache1) @@ -381,7 +381,7 @@ func TestGetMetrics(t *testing.T) { igasMeter := types.GasMeter(gasMeter) store := NewLookup(gasMeter) api := NewMockAPI() - querier := DefaultQuerier(MOCK_CONTRACT_ADDR, types.Array[types.Coin]{types.NewCoin(100, "ATOM")}) + querier := DefaultQuerier(MockContractAddr, types.Array[types.Coin]{types.NewCoin(100, "ATOM")}) env := MockEnvBin(t) info := MockInfoBin(t, "creator") msg1 := []byte(`{"verifier": "fred", "beneficiary": "bob"}`) @@ -501,9 +501,9 @@ func TestGetPinnedMetrics(t *testing.T) { findMetrics := func(list []types.PerModuleEntry, checksum types.Checksum) *types.PerModuleMetrics { found := (*types.PerModuleMetrics)(nil) - for _, structure := range list { - if bytes.Equal(structure.Checksum, checksum) { - found = &structure.Metrics + for i := range list { + if bytes.Equal(list[i].Checksum, checksum) { + found = &list[i].Metrics break } } @@ -529,7 +529,7 @@ func TestGetPinnedMetrics(t *testing.T) { igasMeter := types.GasMeter(gasMeter) store := NewLookup(gasMeter) api := NewMockAPI() - querier := DefaultQuerier(MOCK_CONTRACT_ADDR, types.Array[types.Coin]{types.NewCoin(100, "ATOM")}) + querier := DefaultQuerier(MockContractAddr, types.Array[types.Coin]{types.NewCoin(100, "ATOM")}) env := MockEnvBin(t) info := MockInfoBin(t, "creator") msg1 := []byte(`{"verifier": "fred", "beneficiary": "bob"}`) @@ -565,7 +565,7 @@ func TestInstantiate(t *testing.T) { // instantiate it with this store store := NewLookup(gasMeter) api := NewMockAPI() - querier := DefaultQuerier(MOCK_CONTRACT_ADDR, types.Array[types.Coin]{types.NewCoin(100, "ATOM")}) + querier := DefaultQuerier(MockContractAddr, types.Array[types.Coin]{types.NewCoin(100, "ATOM")}) env := MockEnvBin(t) info := MockInfoBin(t, "creator") msg := []byte(`{"verifier": "fred", "beneficiary": "bob"}`) @@ -593,7 +593,7 @@ func TestExecute(t *testing.T) { store := NewLookup(gasMeter1) api := NewMockAPI() balance := types.Array[types.Coin]{types.NewCoin(250, "ATOM")} - querier := DefaultQuerier(MOCK_CONTRACT_ADDR, balance) + querier := DefaultQuerier(MockContractAddr, balance) env := MockEnvBin(t) info := MockInfoBin(t, "creator") @@ -658,7 +658,7 @@ func TestExecutePanic(t *testing.T) { store := NewLookup(gasMeter1) api := NewMockAPI() balance := types.Array[types.Coin]{types.NewCoin(250, "ATOM")} - querier := DefaultQuerier(MOCK_CONTRACT_ADDR, balance) + querier := DefaultQuerier(MockContractAddr, balance) env := MockEnvBin(t) info := MockInfoBin(t, "creator") @@ -687,7 +687,7 @@ func TestExecuteUnreachable(t *testing.T) { store := NewLookup(gasMeter1) api := NewMockAPI() balance := types.Array[types.Coin]{types.NewCoin(250, "ATOM")} - querier := DefaultQuerier(MOCK_CONTRACT_ADDR, balance) + querier := DefaultQuerier(MockContractAddr, balance) env := MockEnvBin(t) info := MockInfoBin(t, "creator") @@ -714,7 +714,7 @@ func TestExecuteCpuLoop(t *testing.T) { // instantiate it with this store store := NewLookup(gasMeter1) api := NewMockAPI() - querier := DefaultQuerier(MOCK_CONTRACT_ADDR, nil) + querier := DefaultQuerier(MockContractAddr, nil) env := MockEnvBin(t) info := MockInfoBin(t, "creator") @@ -752,7 +752,7 @@ func TestExecuteStorageLoop(t *testing.T) { // instantiate it with this store store := NewLookup(gasMeter1) api := NewMockAPI() - querier := DefaultQuerier(MOCK_CONTRACT_ADDR, nil) + querier := DefaultQuerier(MockContractAddr, nil) env := MockEnvBin(t) info := MockInfoBin(t, "creator") @@ -778,6 +778,9 @@ func TestExecuteStorageLoop(t *testing.T) { // the "sdk gas" * GasMultiplier + the wasm cost should equal the maxGas (or be very close) totalCost := gasReport.UsedInternally + gasMeter2.GasConsumed() + if totalCost > math.MaxInt64 { + t.Fatal("gas cost overflow") + } require.Equal(t, int64(maxGas), int64(totalCost)) } @@ -792,7 +795,7 @@ func BenchmarkContractCall(b *testing.B) { // instantiate it with this store store := NewLookup(gasMeter1) api := NewMockAPI() - querier := DefaultQuerier(MOCK_CONTRACT_ADDR, nil) + querier := DefaultQuerier(MockContractAddr, nil) env := MockEnvBin(b) info := MockInfoBin(b, "creator") @@ -826,7 +829,7 @@ func Benchmark100ConcurrentContractCalls(b *testing.B) { // instantiate it with this store store := NewLookup(gasMeter1) api := NewMockAPI() - querier := DefaultQuerier(MOCK_CONTRACT_ADDR, nil) + querier := DefaultQuerier(MockContractAddr, nil) env := MockEnvBin(b) info := MockInfoBin(b, "creator") @@ -871,13 +874,13 @@ func TestExecuteUserErrorsInApiCalls(t *testing.T) { // instantiate it with this store store := NewLookup(gasMeter1) balance := types.Array[types.Coin]{types.NewCoin(250, "ATOM")} - querier := DefaultQuerier(MOCK_CONTRACT_ADDR, balance) + querier := DefaultQuerier(MockContractAddr, balance) env := MockEnvBin(t) info := MockInfoBin(t, "creator") - defaultApi := NewMockAPI() + defaultAPI := NewMockAPI() msg := []byte(`{"verifier": "fred", "beneficiary": "bob"}`) - res, _, err := Instantiate(cache, checksum, env, info, msg, &igasMeter1, store, defaultApi, &querier, maxGas, TESTING_PRINT_DEBUG) + res, _, err := Instantiate(cache, checksum, env, info, msg, &igasMeter1, store, defaultAPI, &querier, maxGas, TESTING_PRINT_DEBUG) require.NoError(t, err) requireOkResponse(t, res, 0) @@ -885,8 +888,8 @@ func TestExecuteUserErrorsInApiCalls(t *testing.T) { igasMeter2 := types.GasMeter(gasMeter2) store.SetGasMeter(gasMeter2) info = MockInfoBin(t, "fred") - failingApi := NewMockFailureAPI() - res, _, err = Execute(cache, checksum, env, info, []byte(`{"user_errors_in_api_calls":{}}`), &igasMeter2, store, failingApi, &querier, maxGas, TESTING_PRINT_DEBUG) + failingAPI := NewMockFailureAPI() + res, _, err = Execute(cache, checksum, env, info, []byte(`{"user_errors_in_api_calls":{}}`), &igasMeter2, store, failingAPI, &querier, maxGas, TESTING_PRINT_DEBUG) require.NoError(t, err) requireOkResponse(t, res, 0) } @@ -902,7 +905,7 @@ func TestMigrate(t *testing.T) { store := NewLookup(gasMeter) api := NewMockAPI() balance := types.Array[types.Coin]{types.NewCoin(250, "ATOM")} - querier := DefaultQuerier(MOCK_CONTRACT_ADDR, balance) + querier := DefaultQuerier(MockContractAddr, balance) env := MockEnvBin(t) info := MockInfoBin(t, "creator") msg := []byte(`{"verifier": "fred", "beneficiary": "bob"}`) @@ -946,7 +949,7 @@ func TestMultipleInstances(t *testing.T) { igasMeter1 := types.GasMeter(gasMeter1) store1 := NewLookup(gasMeter1) api := NewMockAPI() - querier := DefaultQuerier(MOCK_CONTRACT_ADDR, types.Array[types.Coin]{types.NewCoin(100, "ATOM")}) + querier := DefaultQuerier(MockContractAddr, types.Array[types.Coin]{types.NewCoin(100, "ATOM")}) env := MockEnvBin(t) info := MockInfoBin(t, "regen") msg := []byte(`{"verifier": "fred", "beneficiary": "bob"}`) @@ -1001,7 +1004,7 @@ func TestSudo(t *testing.T) { store := NewLookup(gasMeter1) api := NewMockAPI() balance := types.Array[types.Coin]{types.NewCoin(250, "ATOM")} - querier := DefaultQuerier(MOCK_CONTRACT_ADDR, balance) + querier := DefaultQuerier(MockContractAddr, balance) env := MockEnvBin(t) info := MockInfoBin(t, "creator") @@ -1044,7 +1047,7 @@ func TestDispatchSubmessage(t *testing.T) { // instantiate it with this store store := NewLookup(gasMeter1) api := NewMockAPI() - querier := DefaultQuerier(MOCK_CONTRACT_ADDR, nil) + querier := DefaultQuerier(MockContractAddr, nil) env := MockEnvBin(t) info := MockInfoBin(t, "creator") @@ -1097,7 +1100,7 @@ func TestReplyAndQuery(t *testing.T) { // instantiate it with this store store := NewLookup(gasMeter1) api := NewMockAPI() - querier := DefaultQuerier(MOCK_CONTRACT_ADDR, nil) + querier := DefaultQuerier(MockContractAddr, nil) env := MockEnvBin(t) info := MockInfoBin(t, "creator") @@ -1156,7 +1159,7 @@ func TestReplyAndQuery(t *testing.T) { require.Equal(t, events, val.Events) } -func requireOkResponse(t testing.TB, res []byte, expectedMsgs int) { +func requireOkResponse(t testing.TB, res []byte, expectedMsgs int) { //nolint:unparam // expectedMsgs always receives 0 but that could change var result types.ContractResult err := json.Unmarshal(res, &result) require.NoError(t, err) @@ -1235,7 +1238,7 @@ func TestQuery(t *testing.T) { igasMeter1 := types.GasMeter(gasMeter1) store := NewLookup(gasMeter1) api := NewMockAPI() - querier := DefaultQuerier(MOCK_CONTRACT_ADDR, types.Array[types.Coin]{types.NewCoin(100, "ATOM")}) + querier := DefaultQuerier(MockContractAddr, types.Array[types.Coin]{types.NewCoin(100, "ATOM")}) env := MockEnvBin(t) info := MockInfoBin(t, "creator") msg := []byte(`{"verifier": "fred", "beneficiary": "bob"}`) @@ -1322,7 +1325,7 @@ func TestCustomReflectQuerier(t *testing.T) { store := NewLookup(gasMeter) api := NewMockAPI() initBalance := types.Array[types.Coin]{types.NewCoin(1234, "ATOM")} - querier := DefaultQuerier(MOCK_CONTRACT_ADDR, initBalance) + querier := DefaultQuerier(MockContractAddr, initBalance) // we need this to handle the custom requests from the reflect contract innerQuerier := querier.(*MockQuerier) innerQuerier.Custom = ReflectCustom{} @@ -1361,17 +1364,17 @@ func TestFloats(t *testing.T) { // helper to print the value in the same format as Rust's Debug trait debugStr := func(value Value) string { - if value.U32 != nil { + switch { + case value.U32 != nil: return fmt.Sprintf("U32(%d)", *value.U32) - } else if value.U64 != nil { + case value.U64 != nil: return fmt.Sprintf("U64(%d)", *value.U64) - } else if value.F32 != nil { + case value.F32 != nil: return fmt.Sprintf("F32(%d)", *value.F32) - } else if value.F64 != nil { + case value.F64 != nil: return fmt.Sprintf("F64(%d)", *value.F64) - } else { - t.FailNow() - return "" + default: + return "None" } } @@ -1384,7 +1387,7 @@ func TestFloats(t *testing.T) { // instantiate it with this store store := NewLookup(gasMeter) api := NewMockAPI() - querier := DefaultQuerier(MOCK_CONTRACT_ADDR, nil) + querier := DefaultQuerier(MockContractAddr, nil) env := MockEnvBin(t) // query instructions diff --git a/internal/api/memory.go b/internal/api/memory.go index f2fb06d73..b64ff5ea6 100644 --- a/internal/api/memory.go +++ b/internal/api/memory.go @@ -30,9 +30,9 @@ func makeView(s []byte) C.ByteSliceView { } // Creates a C.UnmanagedVector, which cannot be done in test files directly -func constructUnmanagedVector(is_none cbool, ptr cu8_ptr, len cusize, cap cusize) C.UnmanagedVector { +func constructUnmanagedVector(isNone cbool, ptr cu8_ptr, len cusize, cap cusize) C.UnmanagedVector { return C.UnmanagedVector{ - is_none: is_none, + is_none: isNone, ptr: ptr, len: len, cap: cap, @@ -46,7 +46,7 @@ func uninitializedUnmanagedVector() C.UnmanagedVector { } func newUnmanagedVector(data []byte) C.UnmanagedVector { - if data == nil { + if data == nil { //nolint:gocritic return C.new_unmanaged_vector(cbool(true), cu8_ptr(nil), cusize(0)) } else if len(data) == 0 { // in Go, accessing the 0-th element of an empty array triggers a panic. That is why in the case @@ -62,7 +62,7 @@ func newUnmanagedVector(data []byte) C.UnmanagedVector { func copyAndDestroyUnmanagedVector(v C.UnmanagedVector) []byte { var out []byte - if v.is_none { + if v.is_none { //nolint:gocritic out = nil } else if v.cap == cusize(0) { // There is no allocation we can copy diff --git a/internal/api/memory_test.go b/internal/api/memory_test.go index 397faf50c..892a6f37e 100644 --- a/internal/api/memory_test.go +++ b/internal/api/memory_test.go @@ -1,6 +1,7 @@ package api import ( + "math" "testing" "unsafe" @@ -11,7 +12,9 @@ func TestMakeView(t *testing.T) { data := []byte{0xaa, 0xbb, 0x64} dataView := makeView(data) require.Equal(t, cbool(false), dataView.is_nil) - require.Equal(t, cusize(3), dataView.len) + length := int(dataView.len) + require.Less(t, length, math.MaxInt) + require.Equal(t, 3, length) empty := []byte{} emptyView := makeView(empty) @@ -28,8 +31,12 @@ func TestCreateAndDestroyUnmanagedVector(t *testing.T) { original := []byte{0xaa, 0xbb, 0x64} unmanaged := newUnmanagedVector(original) require.Equal(t, cbool(false), unmanaged.is_none) - require.Equal(t, 3, int(unmanaged.len)) - require.GreaterOrEqual(t, 3, int(unmanaged.cap)) // Rust implementation decides this + length := int(unmanaged.len) + require.Less(t, length, math.MaxInt) + require.Equal(t, 3, length) + cap := int(unmanaged.cap) + require.Less(t, cap, math.MaxInt) + require.GreaterOrEqual(t, cap, 3) // Rust implementation decides this copy := copyAndDestroyUnmanagedVector(unmanaged) require.Equal(t, original, copy) } @@ -39,8 +46,12 @@ func TestCreateAndDestroyUnmanagedVector(t *testing.T) { original := []byte{} unmanaged := newUnmanagedVector(original) require.Equal(t, cbool(false), unmanaged.is_none) - require.Equal(t, 0, int(unmanaged.len)) - require.GreaterOrEqual(t, 0, int(unmanaged.cap)) // Rust implementation decides this + length := int(unmanaged.len) + require.Less(t, length, math.MaxInt) + require.Equal(t, 0, length) + cap := int(unmanaged.cap) + require.Less(t, cap, math.MaxInt) + require.GreaterOrEqual(t, cap, 0) // Rust implementation decides this copy := copyAndDestroyUnmanagedVector(unmanaged) require.Equal(t, original, copy) } @@ -63,15 +74,15 @@ func TestCreateAndDestroyUnmanagedVector(t *testing.T) { func TestCopyDestroyUnmanagedVector(t *testing.T) { { // ptr, cap and len broken. Do not access those values when is_none is true - invalid_ptr := unsafe.Pointer(uintptr(42)) - uv := constructUnmanagedVector(cbool(true), cu8_ptr(invalid_ptr), cusize(0xBB), cusize(0xAA)) + invalidPtr := unsafe.Pointer(uintptr(42)) + uv := constructUnmanagedVector(cbool(true), cu8_ptr(invalidPtr), cusize(0xBB), cusize(0xAA)) copy := copyAndDestroyUnmanagedVector(uv) require.Nil(t, copy) } { // Capacity is 0, so no allocation happened. Do not access the pointer. - invalid_ptr := unsafe.Pointer(uintptr(42)) - uv := constructUnmanagedVector(cbool(false), cu8_ptr(invalid_ptr), cusize(0), cusize(0)) + invalidPtr := unsafe.Pointer(uintptr(42)) + uv := constructUnmanagedVector(cbool(false), cu8_ptr(invalidPtr), cusize(0), cusize(0)) copy := copyAndDestroyUnmanagedVector(uv) require.Equal(t, []byte{}, copy) } diff --git a/internal/api/mocks.go b/internal/api/mocks.go index ac8500dd8..01ce06be2 100644 --- a/internal/api/mocks.go +++ b/internal/api/mocks.go @@ -8,16 +8,18 @@ import ( "strings" "testing" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "github.com/CosmWasm/wasmvm/v2/internal/api/testdb" "github.com/CosmWasm/wasmvm/v2/types" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) /** helper constructors **/ -const MOCK_CONTRACT_ADDR = "contract" +const ( + MockContractAddr = "contract" + Foobar = "foobar" +) func MockEnv() types.Env { return types.Env{ @@ -30,7 +32,7 @@ func MockEnv() types.Env { Index: 4, }, Contract: types.ContractInfo{ - Address: MOCK_CONTRACT_ADDR, + Address: MockContractAddr, }, } } @@ -247,6 +249,8 @@ func (g *mockGasMeter) ConsumeGas(amount types.Gas, descriptor string) { // // We making simple values and non-clear multiples so it is easy to see their impact in test output // Also note we do not charge for each read on an iterator (out of simplicity and not needed for tests) +// + const ( GetPrice uint64 = 99000 SetPrice uint64 = 187000 @@ -387,8 +391,8 @@ func NewMockAPI() *types.GoAPI { } } -func TestMockApi(t *testing.T) { - human := "foobar" +func TestMockAPI(t *testing.T) { + human := "Foobar" canon, cost, err := MockCanonicalizeAddress(human) require.NoError(t, err) assert.Equal(t, CanonicalLength, len(canon)) @@ -402,7 +406,7 @@ func TestMockApi(t *testing.T) { /**** MockQuerier ****/ -const DEFAULT_QUERIER_GAS_LIMIT = 1_000_000 +const DefaultQuerierGasLimit = 1_000_000 type MockQuerier struct { Bank BankQuerier @@ -423,7 +427,9 @@ func DefaultQuerier(contractAddr string, coins types.Array[types.Coin]) types.Qu } } -func (q *MockQuerier) Query(request types.QueryRequest, _gasLimit uint64) ([]byte, error) { +// Query is a mock implementation of the Querier interface. It takes a request and a gas limit. +// It returns the marshaled request and an error if the request is not supported. +func (q *MockQuerier) Query(request types.QueryRequest, _ uint64) ([]byte, error) { marshaled, err := json.Marshal(request) if err != nil { return nil, err @@ -526,17 +532,17 @@ func (q ReflectCustom) Query(request json.RawMessage) ([]byte, error) { return nil, err } var resp CustomResponse - if query.Ping != nil { + if query.Ping != nil { //nolint:gocritic resp.Msg = "PONG" } else if query.Capitalized != nil { resp.Msg = strings.ToUpper(query.Capitalized.Text) } else { - return nil, errors.New("Unsupported query") + return nil, errors.New("unsupported query") } return json.Marshal(resp) } -//************ test code for mocks *************************// +// ************ test code for mocks *************************// func TestBankQuerierAllBalances(t *testing.T) { addr := "foobar" @@ -551,7 +557,7 @@ func TestBankQuerierAllBalances(t *testing.T) { }, }, } - res, err := q.Query(req, DEFAULT_QUERIER_GAS_LIMIT) + res, err := q.Query(req, DefaultQuerierGasLimit) require.NoError(t, err) var resp types.AllBalancesResponse err = json.Unmarshal(res, &resp) @@ -566,7 +572,7 @@ func TestBankQuerierAllBalances(t *testing.T) { }, }, } - res, err = q.Query(req2, DEFAULT_QUERIER_GAS_LIMIT) + res, err = q.Query(req2, DefaultQuerierGasLimit) require.NoError(t, err) var resp2 types.AllBalancesResponse err = json.Unmarshal(res, &resp2) @@ -588,7 +594,7 @@ func TestBankQuerierBalance(t *testing.T) { }, }, } - res, err := q.Query(req, DEFAULT_QUERIER_GAS_LIMIT) + res, err := q.Query(req, DefaultQuerierGasLimit) require.NoError(t, err) var resp types.BalanceResponse err = json.Unmarshal(res, &resp) @@ -604,7 +610,7 @@ func TestBankQuerierBalance(t *testing.T) { }, }, } - res, err = q.Query(req2, DEFAULT_QUERIER_GAS_LIMIT) + res, err = q.Query(req2, DefaultQuerierGasLimit) require.NoError(t, err) var resp2 types.BalanceResponse err = json.Unmarshal(res, &resp2) @@ -620,7 +626,7 @@ func TestBankQuerierBalance(t *testing.T) { }, }, } - res, err = q.Query(req3, DEFAULT_QUERIER_GAS_LIMIT) + res, err = q.Query(req3, DefaultQuerierGasLimit) require.NoError(t, err) var resp3 types.BalanceResponse err = json.Unmarshal(res, &resp3) diff --git a/internal/api/version.go b/internal/api/version.go index 43a13f0b9..63a48095a 100644 --- a/internal/api/version.go +++ b/internal/api/version.go @@ -6,12 +6,12 @@ package api import "C" func LibwasmvmVersion() (string, error) { - version_ptr, err := C.version_str() + versionPtr, err := C.version_str() if err != nil { return "", err } // For C.GoString documentation see https://pkg.go.dev/cmd/cgo and // https://gist.github.com/helinwang/2c7bd2867ea5110f70e6431a7c80cd9b - version_copy := C.GoString(version_ptr) - return version_copy, nil + versionCopy := C.GoString(versionPtr) + return versionCopy, nil } diff --git a/lib.go b/lib.go index 458af0740..cb18a4c61 100644 --- a/lib.go +++ b/lib.go @@ -44,15 +44,15 @@ func LibwasmvmVersion() (string, error) { // to avoid accidental misusage. func CreateChecksum(wasm []byte) (Checksum, error) { if len(wasm) == 0 { - return Checksum{}, fmt.Errorf("Wasm bytes nil or empty") + return Checksum{}, fmt.Errorf("wasm bytes nil or empty") } if len(wasm) < 4 { - return Checksum{}, fmt.Errorf("Wasm bytes shorter than 4 bytes") + return Checksum{}, fmt.Errorf("wasm bytes shorter than 4 bytes") } // magic number for Wasm is "\0asm" // See https://webassembly.github.io/spec/core/binary/modules.html#binary-module if !bytes.Equal(wasm[:4], []byte("\x00\x61\x73\x6D")) { - return Checksum{}, fmt.Errorf("Wasm bytes do not start with Wasm magic number") + return Checksum{}, fmt.Errorf("wasm bytes do not start with wasm magic number") } hash := sha256.Sum256(wasm) return Checksum(hash[:]), nil diff --git a/lib_libwasmvm.go b/lib_libwasmvm.go index 3f66b71ea..66a687500 100644 --- a/lib_libwasmvm.go +++ b/lib_libwasmvm.go @@ -703,7 +703,7 @@ var ( func DeserializeResponse(gasLimit uint64, deserCost types.UFraction, gasReport *types.GasReport, data []byte, response any) error { gasForDeserialization := deserCost.Mul(uint64(len(data))).Floor() if gasLimit < gasForDeserialization+gasReport.UsedInternally { - return fmt.Errorf("Insufficient gas left to deserialize contract execution result (%d bytes)", len(data)) + return fmt.Errorf("insufficient gas left to deserialize contract execution result (%d bytes)", len(data)) } gasReport.UsedInternally += gasForDeserialization gasReport.Remaining -= gasForDeserialization diff --git a/lib_libwasmvm_test.go b/lib_libwasmvm_test.go index 4c25f69a0..83be94e10 100644 --- a/lib_libwasmvm_test.go +++ b/lib_libwasmvm_test.go @@ -9,11 +9,10 @@ import ( "os" "testing" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "github.com/CosmWasm/wasmvm/v2/internal/api" "github.com/CosmWasm/wasmvm/v2/types" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) const ( @@ -77,21 +76,21 @@ func TestStoreCode(t *testing.T) { wasm := []byte{0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00} _, _, err := vm.StoreCode(wasm, TESTING_GAS_LIMIT) - require.ErrorContains(t, err, "Error during static Wasm validation: Wasm contract must contain exactly one memory") + require.ErrorContains(t, err, "Error calling the VM: Error during static Wasm validation: Wasm contract must contain exactly one memory") } // No Wasm { wasm := []byte("foobar") _, _, err := vm.StoreCode(wasm, TESTING_GAS_LIMIT) - require.ErrorContains(t, err, "Wasm bytecode could not be deserialized") + require.ErrorContains(t, err, "bytecode could not be deserialized") } // Empty { wasm := []byte("") _, _, err := vm.StoreCode(wasm, TESTING_GAS_LIMIT) - require.ErrorContains(t, err, "Wasm bytecode could not be deserialized") + require.ErrorContains(t, err, "bytecode could not be deserialized") } // Nil @@ -177,7 +176,7 @@ func TestHappyPath(t *testing.T) { store := api.NewLookup(gasMeter1) goapi := api.NewMockAPI() balance := types.Array[types.Coin]{types.NewCoin(250, "ATOM")} - querier := api.DefaultQuerier(api.MOCK_CONTRACT_ADDR, balance) + querier := api.DefaultQuerier(api.MockContractAddr, balance) // instantiate env := api.MockEnv() @@ -222,7 +221,7 @@ func TestEnv(t *testing.T) { store := api.NewLookup(gasMeter1) goapi := api.NewMockAPI() balance := types.Array[types.Coin]{types.NewCoin(250, "ATOM")} - querier := api.DefaultQuerier(api.MOCK_CONTRACT_ADDR, balance) + querier := api.DefaultQuerier(api.MockContractAddr, balance) // instantiate env := api.MockEnv() @@ -302,7 +301,7 @@ func TestGetMetrics(t *testing.T) { store := api.NewLookup(gasMeter1) goapi := api.NewMockAPI() balance := types.Array[types.Coin]{types.NewCoin(250, "ATOM")} - querier := api.DefaultQuerier(api.MOCK_CONTRACT_ADDR, balance) + querier := api.DefaultQuerier(api.MockContractAddr, balance) env := api.MockEnv() info := api.MockInfo("creator", nil) diff --git a/lib_test.go b/lib_test.go index 35094e7df..c2d40c8e8 100644 --- a/lib_test.go +++ b/lib_test.go @@ -3,9 +3,8 @@ package cosmwasm import ( "testing" - "github.com/stretchr/testify/require" - "github.com/CosmWasm/wasmvm/v2/types" + "github.com/stretchr/testify/require" ) func TestCreateChecksum(t *testing.T) { @@ -29,5 +28,5 @@ func TestCreateChecksum(t *testing.T) { // Text file fails _, err = CreateChecksum([]byte("Hello world")) - require.ErrorContains(t, err, "do not start with Wasm magic number") + require.ErrorContains(t, err, "do not start with wasm magic number") } diff --git a/types/msg.go b/types/msg.go index 60a6e8751..4998c4590 100644 --- a/types/msg.go +++ b/types/msg.go @@ -139,7 +139,7 @@ type GovMsg struct { type voteOption int type VoteMsg struct { - ProposalId uint64 `json:"proposal_id"` + ProposalID uint64 `json:"proposal_id"` // Option is the vote option. // // This used to be called "vote", but was changed for consistency with Cosmos SDK. @@ -150,7 +150,7 @@ type VoteMsg struct { func (m *VoteMsg) UnmarshalJSON(data []byte) error { // We need a custom unmarshaler to parse both the "stargate" and "any" variants type InternalVoteMsg struct { - ProposalId uint64 `json:"proposal_id"` + ProposalID uint64 `json:"proposal_id"` Option *voteOption `json:"option"` Vote *voteOption `json:"vote"` // old version } @@ -168,14 +168,14 @@ func (m *VoteMsg) UnmarshalJSON(data []byte) error { } *m = VoteMsg{ - ProposalId: tmp.ProposalId, + ProposalID: tmp.ProposalID, Option: *tmp.Option, } return nil } type VoteWeightedMsg struct { - ProposalId uint64 `json:"proposal_id"` + ProposalID uint64 `json:"proposal_id"` Options []WeightedVoteOption `json:"options"` } @@ -215,7 +215,7 @@ func (v voteOption) MarshalJSON() ([]byte, error) { return json.Marshal(v.String()) } -func (s *voteOption) UnmarshalJSON(b []byte) error { +func (s *voteOption) UnmarshalJSON(b []byte) error { //nolint:revive var j string err := json.Unmarshal(b, &j) if err != nil { diff --git a/types/msg_test.go b/types/msg_test.go index f56915928..d26d63c3d 100644 --- a/types/msg_test.go +++ b/types/msg_test.go @@ -123,7 +123,7 @@ func TestGovMsgVoteSerialization(t *testing.T) { require.Nil(t, msg.VoteWeighted) require.NotNil(t, msg.Vote) - require.Equal(t, uint64(4), msg.Vote.ProposalId) + require.Equal(t, uint64(4), msg.Vote.ProposalID) require.Equal(t, NoWithVeto, msg.Vote.Option) newDocument := []byte(`{"vote":{"proposal_id":4,"option":"no_with_veto"}}`) @@ -144,7 +144,7 @@ func TestGovMsgVoteWeightedSerialization(t *testing.T) { require.Nil(t, msg.Vote) require.NotNil(t, msg.VoteWeighted) - require.Equal(t, uint64(25), msg.VoteWeighted.ProposalId) + require.Equal(t, uint64(25), msg.VoteWeighted.ProposalID) require.Equal(t, []WeightedVoteOption{ {Yes, "0.25"}, {No, "0.25"}, diff --git a/types/submessages.go b/types/submessages.go index b0cb81747..d7d58c075 100644 --- a/types/submessages.go +++ b/types/submessages.go @@ -29,15 +29,15 @@ var toReplyOn = map[string]replyOn{ "never": ReplyNever, } -func (r replyOn) String() string { - return fromReplyOn[r] +func (s replyOn) String() string { + return fromReplyOn[s] } -func (s replyOn) MarshalJSON() ([]byte, error) { +func (s replyOn) MarshalJSON() ([]byte, error) { //nolint:revive return json.Marshal(s.String()) } -func (s *replyOn) UnmarshalJSON(b []byte) error { +func (s *replyOn) UnmarshalJSON(b []byte) error { //nolint:revive var j string err := json.Unmarshal(b, &j) if err != nil {