Skip to content

smaller PR #659

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 31 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
fdaf809
enable additional linters
faddat Dec 22, 2024
016154b
Merge branch 'faddat/testifylint' into faddat/bump-go
faddat Dec 22, 2024
71b2d1e
adjust golang version in circleci
faddat Dec 22, 2024
f371399
bump go...
faddat Dec 22, 2024
cbde717
remove dupl
faddat Dec 22, 2024
08ea4c4
lint main.go
faddat Jan 2, 2025
7a812f5
lints...
faddat Jan 2, 2025
65039a5
complete
faddat Jan 2, 2025
ada59f4
Merge branch 'main' into faddat/bump-go
faddat Jan 16, 2025
a06cd0d
remove mutext lock in lib_test.go
faddat Jan 17, 2025
1118f26
remove unused variable
faddat Jan 17, 2025
d6c14e6
restore comments
faddat Jan 17, 2025
d943802
fix lint in .golangci.yml
faddat Jan 17, 2025
f9e29a6
Merge branch 'faddat/errcheck' into faddat/bump-go
faddat Feb 1, 2025
ce052d6
lint
faddat Feb 1, 2025
59fa5a4
Refactor test helper function for creating message binary
faddat Feb 14, 2025
20aaea0
revert unnecessary change
faddat Feb 18, 2025
19d75a5
resolve merge conflict and reduce required go version
faddat Feb 19, 2025
f74e259
adjust loop to go 1.21
faddat Feb 19, 2025
1aa9993
Merge remote-tracking branch 'origin/main' into before-revive
faddat Apr 25, 2025
66ff709
all linters excecpt revive
faddat Apr 25, 2025
e7e28b8
gocritic
faddat Apr 25, 2025
703cc45
disable gocritic temporarily
faddat Apr 25, 2025
2e9424b
update linter for v2
faddat Apr 25, 2025
71448a8
really get it working for v2
faddat Apr 25, 2025
6838413
Update internal/api/lib_test.go
faddat Apr 27, 2025
a574461
bring back useful comments
faddat Apr 27, 2025
0e58174
Merge remote-tracking branch 'origin/main' into faddat/smaller-pr
faddat Apr 29, 2025
c0d7ea2
use C.ErrnoVALUE_Success
faddat Apr 29, 2025
ff1c56d
I cannot argue about this :)
faddat Apr 29, 2025
c9bc165
eliminate double declaration of CapitalizedResponse
faddat Apr 30, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ version: "2"

run:
tests: true
timeout: 5m

linters:
# Enable specific linters
Expand All @@ -10,6 +11,38 @@ linters:
- misspell
- testifylint
- thelper
- copyloopvar # Detect copy loops
- errcheck # Detect unchecked errors
- govet # Reports suspicious constructs
- ineffassign # Detect unused assignments
- staticcheck # Go static analysis
- unused # Detect unused constants, variables, functions and types

# Additional recommended linters
- gosec # Security checker
- misspell # Find commonly misspelled words
- bodyclose # Check HTTP response bodies are closed
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one seems a bit out of place. We don't handle HTTP requests here. Let's remove it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

eh, let's keep it in case we ever do. Its there to prevent mistakes sir. Now we know we pass that linter. There are many more to pass.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sir, this is glue code between a blockchain sdk and a VM. It will never do any HTTP requests.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pass the linter anyhow. The idea is to have e'm all (well realistically the right ones) working right. So I can remove it, but there's no reason to it eats like .1s or something and provides a layer of protection in the future.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove. If I accept useless changes like this, the repo will bloat in no time.

- goconst # Find repeated strings that could be constants
- gocognit # Check cognitive complexity
- whitespace # Check trailing whitespace
- thelper # Detect test helpers not using t.Helper()
- tparallel # Detect incorrect usage of t.Parallel()

# enable lager because changes are huge
# - revive
# - gocritic # A more opinionated linter


settings:
gocritic:
enable-all: true
disabled-checks:
- dupSubExpr
- dupImport
- paramTypeCombine



exclusions:
generated: lax
presets:
Expand Down
66 changes: 52 additions & 14 deletions cmd/demo/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,53 +4,91 @@ import (
"fmt"
"math"
"os"
"path/filepath"
"strings"

wasmvm "github.com/CosmWasm/wasmvm/v3"
)

// PrintDebug enables debug printing when true.
const (
PRINT_DEBUG = true
MEMORY_LIMIT = 32 // MiB
CACHE_SIZE = 100 // MiB
PrintDebug = true
// MemoryLimit defines the memory limit in MiB.
MemoryLimit = 32
// CacheSize defines the cache size in MiB.
CacheSize = 100
)

var SUPPORTED_CAPABILITIES = []string{"staking"}
// SupportedCapabilities defines the list of supported staking capabilities.
var SupportedCapabilities = []string{"staking"}

// This is just a demo to ensure we can compile a static go binary
// exitCode tracks the code that the program will exit with.
var exitCode = 0

// main is the entry point for the demo application that tests wasmvm functionality.
func main() {
defer func() {
os.Exit(exitCode)
}()

if len(os.Args) < 2 {
fmt.Println("Usage: demo <file|version>")
exitCode = 1
return
}

file := os.Args[1]

if file == "version" {
libwasmvmVersion, err := wasmvm.LibwasmvmVersion()
if err != nil {
panic(err)
fmt.Printf("Error getting libwasmvm version: %v\n", err)
exitCode = 1
return
}
fmt.Printf("libwasmvm: %s\n", libwasmvmVersion)
return
}

fmt.Printf("Running %s...\n", file)
bz, err := os.ReadFile(file)

// Validate file path
cleanPath := filepath.Clean(file)
if filepath.IsAbs(cleanPath) || strings.Contains(cleanPath, "..") {
fmt.Println("Error: invalid file path")
exitCode = 1
return
}
Comment on lines +57 to +61
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why go out of our way to reject absolute paths and paths in the parent directory?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

slavishly satisfying the linter's high standards

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this a "high standard"? Are there possible problems with accepting absolute paths or paths inside the parent directory? Otherwise, this is needlessly restrictive.
Which linter causes this? Are there any explanations for this lint?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's gosec. And the reasoning is validating file paths a bit insanely. They have a numbered system. I'll dig it up.

Copy link
Contributor Author

@faddat faddat Apr 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, it's a security thing, suggest we keep it. It's basically keeping us vigilant here, I think that's okay

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove and mark as nolint. A lint like this makes sense in a webserver environment where you want people to only access relative paths inside a directory. This is a cli application where the path is supplied by the person who executes it.


bz, err := os.ReadFile(cleanPath)
if err != nil {
panic(err)
fmt.Printf("Error reading file: %v\n", err)
exitCode = 1
return
}
fmt.Println("Loaded!")

err = os.MkdirAll("tmp", 0o755)
err = os.MkdirAll("tmp", 0o750)
if err != nil {
panic(err)
fmt.Printf("Error creating tmp directory: %v\n", err)
exitCode = 1
return
}
vm, err := wasmvm.NewVM("tmp", SUPPORTED_CAPABILITIES, MEMORY_LIMIT, PRINT_DEBUG, CACHE_SIZE)
vm, err := wasmvm.NewVM("tmp", SupportedCapabilities, MemoryLimit, PrintDebug, CacheSize)
if err != nil {
panic(err)
fmt.Printf("Error creating VM: %v\n", err)
exitCode = 1
return
}
defer vm.Cleanup()

checksum, _, err := vm.StoreCode(bz, math.MaxUint64)
if err != nil {
panic(err)
fmt.Printf("Error storing code: %v\n", err)
exitCode = 1
return
}
fmt.Printf("Stored code with checksum: %X\n", checksum)

vm.Cleanup()
fmt.Println("finished")
}
2 changes: 1 addition & 1 deletion ibc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ type AccountInfo struct {
ChannelID string `json:"channel_id"`
}

// We just check if an error is returned or not
// We just check if an error is returned or not.
type AcknowledgeDispatch struct {
Err string `json:"error"`
}
Expand Down
21 changes: 10 additions & 11 deletions internal/api/callbacks.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ func cGet(ptr *C.db_t, gasMeter *C.gas_meter_t, usedGas *cu64, key C.U8SliceView
return C.GoError_BadArgument
}
// errOut is unused and we don't check `is_none` because of https://github.com/CosmWasm/wasmvm/issues/536
if !(*val).is_none {
if !val.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.")
}

Expand Down Expand Up @@ -231,7 +231,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.")
}

Expand Down Expand Up @@ -277,14 +277,13 @@ func cNext(ref C.IteratorReference, gasMeter *C.gas_meter_t, usedGas *cu64, key
// k, v := itr.Key(); itr.Value()
// ...
// }

defer recoverPanic(&ret)
if ref.call_id == 0 || gasMeter == nil || usedGas == nil || key == nil || val == nil || errOut == nil {
// we received an invalid pointer
return C.GoError_BadArgument
}
// errOut is unused and we don't check `is_none` because of https://github.com/CosmWasm/wasmvm/issues/536
if !(*key).is_none || !(*val).is_none {
if !key.is_none || !val.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.")
}

Expand Down Expand Up @@ -336,7 +335,7 @@ func nextPart(ref C.IteratorReference, gasMeter *C.gas_meter_t, usedGas *cu64, o
return C.GoError_BadArgument
}
// errOut is unused and we don't check `is_none` because of https://github.com/CosmWasm/wasmvm/issues/536
if !(*output).is_none {
if !output.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.")
}

Expand All @@ -356,7 +355,7 @@ func nextPart(ref C.IteratorReference, gasMeter *C.gas_meter_t, usedGas *cu64, o
// check iter.Error() ????
iter.Next()
gasAfter := gm.GasConsumed()
*usedGas = (cu64)(gasAfter - gasBefore)
*usedGas = (cu64(gasAfter - gasBefore))

*output = newUnmanagedVector(out)
return C.GoError_None
Expand Down Expand Up @@ -384,7 +383,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.")
}

Expand All @@ -398,7 +397,7 @@ func cHumanizeAddress(ptr *C.api_t, src C.U8SliceView, dest *C.UnmanagedVector,
*errOut = newUnmanagedVector([]byte(err.Error()))
return C.GoError_User
}
if len(h) == 0 {
if h == "" {
panic(fmt.Sprintf("`api.HumanizeAddress()` returned an empty string for %q", s))
}
*dest = newUnmanagedVector([]byte(h))
Expand All @@ -412,7 +411,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.")
}

Expand All @@ -439,7 +438,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.")
}

Expand Down Expand Up @@ -479,7 +478,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.")
}

Expand Down
13 changes: 9 additions & 4 deletions internal/api/iterator.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@ package api
import (
"fmt"
"math"
"os"
"sync"

"github.com/CosmWasm/wasmvm/v3/types"
)

// frame stores all Iterators for one contract call
// frame stores all Iterators for one contract call.
type frame []types.Iterator

// iteratorFrames contains one frame for each contract call, indexed by contract call ID.
Expand All @@ -17,7 +18,7 @@ var (
iteratorFramesMutex sync.Mutex
)

// this is a global counter for creating call IDs
// this is a global counter for creating call IDs.
var (
latestCallID uint64
latestCallIDMutex sync.Mutex
Expand All @@ -44,13 +45,17 @@ func removeFrame(callID uint64) frame {
return remove
}

// endCall is called at the end of a contract call to remove one item the iteratorFrames
// endCall is called at the end of a contract call to remove one item the iteratorFrames.
func endCall(callID uint64) {
// we pull removeFrame in another function so we don't hold the mutex while cleaning up the removed frame
remove := removeFrame(callID)
// free all iterators in the frame when we release it
for _, iter := range remove {
iter.Close()
if err := iter.Close(); err != nil {
// In this cleanup code, we can't do much with the error
// Log it to stderr since that's better than silently ignoring it
fmt.Fprintf(os.Stderr, "failed to close iterator: %v\n", err)
}
}
}

Expand Down
7 changes: 5 additions & 2 deletions internal/api/lib.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ type Cache struct {
type Querier = types.Querier

func InitCache(config types.VMConfig) (Cache, error) {
// libwasmvm would create this directory too but we need it earlier for the lockfile
// 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")
Expand Down Expand Up @@ -83,7 +83,10 @@ func InitCache(config types.VMConfig) (Cache, error) {
func ReleaseCache(cache Cache) {
C.release_cache(cache.ptr)

cache.lockfile.Close() // Also releases the file lock
if err := cache.lockfile.Close(); err != nil {
// Just log the error since this is cleanup code
fmt.Printf("failed to close lockfile: %v\n", err)
} // Also releases the file lock.
}

func StoreCode(cache Cache, wasm []byte, persist bool) ([]byte, error) {
Expand Down
Loading