PathrockNetwork Gno Explorer
HomeBlocksTransactionsTokensRealmsPackagesValidatorsAnalytics

PathrockNetwork Gno Explorer — an independent explorer for Gno.land Mainnet (gnoland-1), operated by PathrockNetwork. Not an official Gno.land service.

gnowebarchive RPC

gno.land/p/moul/x/vm/riscv/v0

Package
Open in gnoweb ↗

Overview

Kind
Pure package
Name
v0
Namespace
moul / x / vm / riscv
Files
17 (README)(gnomod.toml)
Exported functions
n/a — not supported for pure packages by the node (vm/qfuncs)
Module
gno.land/p/moul/x/vm/riscv/v0
gno
0.9

Files (17)

  • README.mdmarkdown
  • gnomod.tomltoml
  • decode.gnogno
  • ecall.gnogno
  • exec.gnogno
  • guests.gnogno
  • mem.gnogno
  • predecode.gnogno
  • snapshot.gnogno
  • bench_test.gnogno
  • clang_test.gnogno
  • conformance_test.gnogno
  • decode_test.gnogno
  • predecode_test.gnogno
  • riscv_test.gnogno
  • rust_test.gnogno
  • switchcost_test.gnogno
  • rust_test.gnogno
    1package riscv23import (4	"testing"56	"gno.land/p/moul/x/vm/vmkit/v0"7	"gno.land/p/nt/uassert/v0"8

    Functions

    not supported for pure packages by the node (vm/qfuncs)

    Signatures reconstructed verbatim from vm/qfuncs — interface params keep their inline definitions.

    )
    9
    10// The demo the design issue actually asked for: Rust code, compiled by rustc,
    11// running on gno.land, moving a balance from one account to another.
    12//
    13// The image is guests.gno's, built from tools/riscv-guests/ledger. It is worth
    14// more than the C guest for one reason: it links Rust's real core and
    15// compiler_builtins, so this exercises the standard library's own software
    16// arithmetic rather than only what the compiler emitted for my source.
    17
    18func runLedger(t *testing.T, in string) (string, vmkit.Status, *Machine) {
    19 t.Helper()
    20 m, err := NewMachine(GuestLedger(), entry)
    21 uassert.NoError(t, err)
    22 if m == nil {
    23 return "", vmkit.Trapped, nil
    24 }
    25 h := vmkit.NewTestHost().WithInput([]byte(in))
    26 _, status := m.Step(h, 5000000)
    27 return string(h.Out()), status, m
    28}
    29
    30func TestRustLedgerTransfers(t *testing.T) {
    31 out, status, _ := runLedger(t,
    32 "mint alice 100\nmint bob 50\nsend alice bob 30\n")
    33 uassert.Equal(t, "halted", status.String())
    34 uassert.Equal(t, "alice 70\nbob 80\n", out)
    35}
    36
    37func TestRustLedgerMintBurnAndBlankLines(t *testing.T) {
    38 out, status, _ := runLedger(t, "mint a 5\n\n \nburn a 2\n")
    39 uassert.Equal(t, "halted", status.String())
    40 uassert.Equal(t, "a 3\n", out)
    41
    42 out, status, _ = runLedger(t, "")
    43 uassert.Equal(t, "halted", status.String())
    44 uassert.Equal(t, "", out)
    45}
    46
    47// A refusal is halted, not trapped, and it names the line. This is the
    48// semantic the whole VM is built around: the program said no, the machine did
    49// not break, and a chain has to be able to tell a user which one happened.
    50func TestRustLedgerRefusalsAreHaltsNotTraps(t *testing.T) {
    51 cases := []struct{ in, want string }{
    52 {"mint a 1\nsend a b 9\n", "line 2: insufficient balance\n"},
    53 {"send nobody b 1\n", "line 1: unknown sender\n"},
    54 {"burn ghost 1\n", "line 1: unknown account\n"},
    55 {"frobnicate\n", "line 1: unknown command\n"},
    56 {"mint a x\n", "line 1: bad amount\n"},
    57 }
    58 for _, c := range cases {
    59 out, status, m := runLedger(t, c.in)
    60 uassert.Equal(t, "halted", status.String(), c.in+": "+m.Trap())
    61 uassert.Equal(t, c.want, out)
    62 uassert.Equal(t, uint64(1), uint64(m.Registers()[10]), "a refusal exits 1")
    63 }
    64}
    65
    66// 64-bit arithmetic on a 32-bit machine goes through compiler_builtins, and
    67// printing a balance above 2^32 is the path that proves __udivdi3 ran.
    68func TestRustLedgerDoes64BitArithmetic(t *testing.T) {
    69 // Nine-digit mints, accumulated past what 32 bits holds.
    70 in := ""
    71 for i := 0; i < 6; i++ {
    72 in += "mint whale 999999999\n"
    73 }
    74 out, status, _ := runLedger(t, in)
    75 uassert.Equal(t, "halted", status.String())
    76 uassert.Equal(t, "whale 5999999994\n", out)
    77}
    78
    79// Compiled Rust pauses and resumes like anything else, including in the middle
    80// of a library routine it never asked to call.
    81func TestRustLedgerSurvivesSlicing(t *testing.T) {
    82 image := GuestLedger()
    83 h := vmkit.NewTestHost().WithInput([]byte("mint alice 100\nsend alice bob 30\n"))
    84
    85 sliced, err := NewMachine(image, entry)
    86 uassert.NoError(t, err)
    87 status := vmkit.Running
    88 slices := 0
    89 for i := 0; i < 4000 && status == vmkit.Running; i++ {
    90 var fresh Machine
    91 uassert.NoError(t, fresh.Restore(sliced.Snapshot()))
    92 _, status = fresh.Step(h, 17)
    93 sliced = &fresh
    94 slices++
    95 }
    96 uassert.Equal(t, "halted", status.String())
    97 uassert.True(t, slices > 20, "a sliced run must actually have been sliced")
    98 uassert.Equal(t, "alice 70\nbob 30\n", string(h.Out()))
    99}
    100