fix(gnovm): pin the per-file Go version in the consensus type-check#5978
Open
davd-gzl wants to merge 3 commits into
Open
fix(gnovm): pin the per-file Go version in the consensus type-check#5978davd-gzl wants to merge 3 commits into
davd-gzl wants to merge 3 commits into
Conversation
The consensus type-check pins types.Config.GoVersion to go1.18 so the accept/reject verdict for a submitted package is a function of the package alone. The pin only governs files carrying no per-file version: go/types upgrades a file above the Config pin when it has a //go:build go1.N line, and rejects a file whose version exceeds the version the binary was built with. Package bodies are attacker-supplied and reach go/types through go/parser, which populates ast.File.GoVersion from those lines. So a submitter could raise the gate on their own file, and a file tagged above one validator's toolchain was accepted on a newer build and rejected on an older one. Both are state forks across heterogeneous validator builds. Blank ast.File.GoVersion on every parsed .gno file in GoParseMemPackage. Build constraints have no meaning in Gno, so no per-file version can legitimately be set from inside a submitted package, and Config.GoVersion becomes the sole version authority for every file and every import.
…BlockNodes IterMemPackage's only implementation skips prod-less packages before its only channel send, and the Store interface documents that skip, so the receiving nil check can never fire. The guard arrived as a merge artifact: it comes from the un-squashed branch of gnolang#5891, whose squash on master put the skip in store.go instead, and the merge kept both copies.
Collaborator
🛠 PR Checks Summary🔴 Pending initial approval by a review team member, or review from tech-staff Manual Checks (for Reviewers):
Read More🤖 This bot helps streamline PR reviews by verifying automated checks and providing guidance for contributors and reviewers. ✅ Automated Checks (for Contributors):🟢 Maintainers must be able to edit this pull request (more info) ☑️ Contributor Actions:
☑️ Reviewer Actions:
📚 Resources:Debug
|
davd-gzl
marked this pull request as ready for review
July 18, 2026 22:09
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up to #5893.
Whoever uploads a package decides which language rules it gets checked against. The chain should decide.
One comment line gets code accepted that should be rejected.
for range 10needs Go 1.22, which the VM cannot run:The chain sets the language version to Go 1.18 before checking. That setting only applies to files which do not state a version themselves, and
//go:build go1.Nis how a file states one:It also makes the answer depend on the machine. Go's type checker refuses a file asking for a version newer than the Go release used to build the node, so a package marked
go1.26is accepted by a node built with Go 1.26 and rejected by one built with Go 1.25:The fix erases the version a file states, right after parsing:
A new test covers both cases and fails without the fix.
The second commit is unrelated cleanup: a nil check that can never run, left by the #5891 merge.