Skip to content

feat(vm): add vm/qlatestversion query and soft version warnings for gnokey addpkg#5380

Open
davd-gzl wants to merge 8 commits intognolang:masterfrom
davd-gzl:feat/soft-version-warnings
Open

feat(vm): add vm/qlatestversion query and soft version warnings for gnokey addpkg#5380
davd-gzl wants to merge 8 commits intognolang:masterfrom
davd-gzl:feat/soft-version-warnings

Conversation

@davd-gzl
Copy link
Copy Markdown
Member

@davd-gzl davd-gzl commented Mar 27, 2026

Description

Adds soft version warnings for non-sequential package versioning, as discussed in #5365.
On-chain enforcement is not possible because IBC package synchronization delivers packages in arbitrary order. This PR adds tooling-level warnings instead.

Changes

  • ParseVersionSuffix() helper in gnovm/pkg/gnolang/mempackage.go — extracts version number from paths like gno.land/p/demo/avl/v2
  • vm/qlatestversion ABCI query — returns latest deployed version, first missing version, and missing count for a given base path
  • gnokey maketx addpkg --force — warns on stderr when previous version is missing; blocks when gap > 5 unless --force is passed
  • Docs — added vm/qlatestversion to the gnokey query reference

Follow-ups

  • gnoweb warning banner

Test script

demo_version_warnings.sh:

#!/bin/bash
# demo_version_warnings.sh
#
# Demonstrates the soft version warning feature for Gno package versioning.
#
# This script:
#   1. Starts a local gnodev node
#   2. Deploys versioned packages with gaps (v0, v1, v3 — skipping v2)
#   3. Shows the CLI warning when deploying with a gap
#   4. Shows the ABCI query response for vm/qlatestversion
#   5. Shows that a large gap (v10) is blocked without --force
#   6. Shows that --force overrides the block
#
# Prerequisites:
#   Build gnodev and gnokey from the current tree
#
# Usage:
#   bash misc/demo_version_warnings.sh

set -euo pipefail

CHAIN_ID="dev"
REMOTE="127.0.0.1:26657"
KEY="devtest"
PASSWORD=""
GAS_FEE="1000000ugnot"
GAS_WANTED="100000000"
BASE_PKG="gno.land/p/demo/versiontest"

WORK=$(mktemp -d)
trap 'rm -rf "$WORK"; [ -n "${GNODEV_PID:-}" ] && kill "$GNODEV_PID" 2>/dev/null; wait "$GNODEV_PID" 2>/dev/null || true' EXIT

echo "=== Soft Version Warnings Demo ==="
echo ""

# --- Step 0: Check binaries ---
if ! command -v gnodev &>/dev/null || ! command -v gnokey &>/dev/null; then
    echo "ERROR: gnodev and gnokey must be installed. Run 'make install' first."
    exit 1
fi

# --- Step 1: Start gnodev ---
echo "Starting gnodev..."
gnodev -no-watch &>/dev/null &
GNODEV_PID=$!

# Wait for node to be ready (up to ~2 minutes)
MAX_RETRIES=40
RETRY_COUNT=0
echo "Waiting for node to be ready..."
while [ $RETRY_COUNT -lt $MAX_RETRIES ]; do
    if gnokey query bank/balances/g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5 -remote="$REMOTE" &>/dev/null; then
        echo "Node is ready!"
        break
    fi
    sleep 3
    RETRY_COUNT=$((RETRY_COUNT + 1))
done

if [ $RETRY_COUNT -eq $MAX_RETRIES ]; then
    echo "ERROR: Failed to connect to node after $MAX_RETRIES attempts"
    exit 1
fi

echo "gnodev is running (PID $GNODEV_PID, RPC at $REMOTE)"
echo ""

# Helper: run gnokey maketx addpkg with password piping
deploy_pkg() {
    local pkgpath=$1
    local pkgdir=$2
    shift 2
    echo "$PASSWORD" | gnokey maketx addpkg \
        -pkgpath "$pkgpath" \
        -pkgdir "$pkgdir" \
        -gas-fee "$GAS_FEE" \
        -gas-wanted "$GAS_WANTED" \
        -broadcast \
        -chainid "$CHAIN_ID" \
        -remote "$REMOTE" \
        -insecure-password-stdin=true \
        "$@" \
        "$KEY"
}

# --- Step 2: Create package files ---
create_pkg() {
    local version=$1
    local dir="$WORK/v${version}"
    mkdir -p "$dir"
    cat > "$dir"/gnomod.toml <<EOF
module = "${BASE_PKG}/v${version}"
gno = "0.9"
EOF
    cat > "$dir"/hello.gno <<EOF
package versiontest

func Hello() string {
    return "Hello from v${version}!"
}
EOF
    echo "$dir"
}

# --- Step 3: Deploy v0 (no warning expected) ---
echo "--- Deploying v0 (first version, no warning expected) ---"
DIR=$(create_pkg 0)
deploy_pkg "${BASE_PKG}/v0" "$DIR" 2>&1
echo "v0 deployed successfully."
echo ""

# --- Step 4: Deploy v1 (sequential, no warning expected) ---
echo "--- Deploying v1 (sequential, no warning expected) ---"
DIR=$(create_pkg 1)
deploy_pkg "${BASE_PKG}/v1" "$DIR" 2>&1
echo "v1 deployed successfully."
echo ""

# --- Step 5: Deploy v3, skipping v2 (warning expected) ---
echo "--- Deploying v3, skipping v2 (soft warning expected) ---"
DIR=$(create_pkg 3)
deploy_pkg "${BASE_PKG}/v3" "$DIR" 2>&1
echo ""
echo "v3 deployed (with warning about missing v2)."
echo ""

# --- Step 6: Query vm/qlatestversion ---
echo "--- Querying vm/qlatestversion ---"
echo "gnokey query vm/qlatestversion --data \"${BASE_PKG}\" -remote $REMOTE"
gnokey query vm/qlatestversion --data "${BASE_PKG}" -remote "$REMOTE" 2>&1 || true
echo ""

# --- Step 7: Try deploying v10 without --force (should be blocked) ---
echo "--- Deploying v10, large gap from v3 (should be BLOCKED without --force) ---"
DIR=$(create_pkg 10)
deploy_pkg "${BASE_PKG}/v10" "$DIR" 2>&1 || echo "(Blocked as expected — gap too large)"
echo ""

# --- Step 8: Deploy v10 WITH --force (should succeed) ---
echo "--- Deploying v10 with --force (should succeed) ---"
deploy_pkg "${BASE_PKG}/v10" "$DIR" -force 2>&1
echo ""
echo "v10 deployed with --force."
echo ""

# --- Step 9: Query again to see updated state ---
echo "--- Querying vm/qlatestversion (after v10 deployment) ---"
gnokey query vm/qlatestversion --data "${BASE_PKG}" -remote "$REMOTE" 2>&1 || true
echo ""

# --- Done ---
echo "=== Demo Complete ==="
echo ""
echo "Summary:"
echo "  - v0, v1, v3, v10 deployed to ${BASE_PKG}"
echo "  - v2, v4-v9 are missing"
echo "  - v3 deployment showed a soft warning (missing v2)"
echo "  - v10 deployment was blocked without --force, succeeded with --force"
echo ""
echo "gnodev is still running (PID $GNODEV_PID, RPC at $REMOTE)."
echo "To see the gnoweb warning banner, start gnoweb and visit:"
echo "  http://127.0.0.1:8888/p/demo/versiontest/v10"
echo ""
echo "Press Ctrl+C to stop gnodev."
wait "$GNODEV_PID" 2>/dev/null || true

@github-actions github-actions bot added 📖 documentation Improvements or additions to documentation 📦 🤖 gnovm Issues or PRs gnovm related 📦 ⛰️ gno.land Issues or PRs gno.land package related labels Mar 27, 2026
@Gno2D2 Gno2D2 added the review/triage-pending PRs opened by external contributors that are waiting for the 1st review label Mar 27, 2026
@Gno2D2
Copy link
Copy Markdown
Collaborator

Gno2D2 commented Mar 27, 2026

🛠 PR Checks Summary

🔴 Pending initial approval by a review team member, or review from tech-staff

Manual Checks (for Reviewers):
  • IGNORE the bot requirements for this PR (force green CI check)
  • The pull request description provides enough details
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)
🔴 Pending initial approval by a review team member, or review from tech-staff

☑️ Contributor Actions:
  1. Fix any issues flagged by automated checks.
  2. Follow the Contributor Checklist to ensure your PR is ready for review.
    • Add new tests, or document why they are unnecessary.
    • Provide clear examples/screenshots, if necessary.
    • Update documentation, if required.
    • Ensure no breaking changes, or include BREAKING CHANGE notes.
    • Link related issues/PRs, where applicable.
☑️ Reviewer Actions:
  1. Complete manual checks for the PR, including the guidelines and additional checks if applicable.
📚 Resources:
Debug
Automated Checks
Maintainers must be able to edit this pull request (more info)

If

🟢 Condition met
└── 🟢 And
    ├── 🟢 The base branch matches this pattern: ^master$
    └── 🟢 The pull request was created from a fork (head branch repo: davd-gzl/gno)

Then

🟢 Requirement satisfied
└── 🟢 Maintainer can modify this pull request

Pending initial approval by a review team member, or review from tech-staff

If

🟢 Condition met
└── 🟢 And
    ├── 🟢 The base branch matches this pattern: ^master$
    └── 🟢 Not (🔴 Pull request author is a member of the team: tech-staff)

Then

🔴 Requirement not satisfied
└── 🔴 If
    ├── 🔴 Condition
    │   └── 🔴 Or
    │       ├── 🔴 At least one of these user(s) reviewed the pull request: [davd-gzl jefft0 notJoon omarsy MikaelVallenet] (with state "APPROVED")
    │       ├── 🔴 At least 1 user(s) of the team tech-staff reviewed pull request
    │       └── 🔴 This pull request is a draft
    └── 🔴 Else
        └── 🔴 And
            ├── 🟢 This label is applied to pull request: review/triage-pending
            └── 🔴 On no pull request

Manual Checks
**IGNORE** the bot requirements for this PR (force green CI check)

If

🟢 Condition met
└── 🟢 On every pull request

Can be checked by

  • Any user with comment edit permission
The pull request description provides enough details

If

🟢 Condition met
└── 🟢 And
    ├── 🟢 Not (🔴 Pull request author is a member of the team: core-contributors)
    └── 🟢 Not (🔴 Pull request author is user: dependabot[bot])

Can be checked by

  • team core-contributors

@codecov
Copy link
Copy Markdown

codecov bot commented Mar 27, 2026

Codecov Report

❌ Patch coverage is 79.27928% with 23 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
gno.land/pkg/keyscli/addpkg.go 67.79% 17 Missing and 2 partials ⚠️
gno.land/pkg/sdk/vm/handler.go 84.61% 1 Missing and 1 partial ⚠️
gno.land/pkg/sdk/vm/keeper.go 91.66% 1 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

📖 documentation Improvements or additions to documentation 📦 ⛰️ gno.land Issues or PRs gno.land package related 📦 🤖 gnovm Issues or PRs gnovm related review/triage-pending PRs opened by external contributors that are waiting for the 1st review

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

2 participants