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/forge/v0

Package
Open in gnoweb ↗

Overview

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

Files (14)

  • README.mdmarkdown
  • gnomod.tomltoml
  • change.gnogno
  • errors.gnogno
  • forge.gnogno
  • issue.gnogno
  • ref.gnogno
  • validate.gnogno
  • change_test.gnogno
  • forge_test.gnogno
  • helpers_test.gnogno
  • issue_test.gnogno
  • ref_test.gnogno
  • validate_test.gnogno
  • ref_test.gnogno
    1package forge23import (4	"testing"56	"gno.land/p/nt/uassert/v0"7	"gno.land/p/nt/urequire/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
    10func TestSetRefCompareAndSwap(t *testing.T) {
    11 _, r := newRepo(t)
    12
    13 // Create: the expectation is "this ref does not exist".
    14 e, err := r.SetRef(carol, 101, "refs/heads/main", "", oid("a"), "initial import")
    15 urequire.NoError(t, err)
    16 uassert.Equal(t, KindCreate, e.Kind)
    17 uassert.Equal(t, int64(0), e.Seq)
    18 uassert.Equal(t, "", e.OldOID)
    19 uassert.Equal(t, oid("a"), r.Ref("refs/heads/main").OID)
    20 uassert.Equal(t, carol.String(), r.Ref("refs/heads/main").UpdatedBy.String())
    21
    22 // Creating twice is a mistake, not an overwrite.
    23 _, err = r.SetRef(carol, 102, "refs/heads/main", "", oid("b"), "")
    24 uassert.ErrorIs(t, err, ErrRefExists)
    25
    26 // A stale expectation is exactly the lost-push case --force-with-lease
    27 // exists to catch, and here the lease is held by consensus.
    28 _, err = r.SetRef(carol, 102, "refs/heads/main", oid("9"), oid("b"), "")
    29 uassert.ErrorIs(t, err, ErrStaleRef)
    30
    31 // A fresh expectation succeeds and chains onto the previous entry.
    32 e2, err := r.SetRef(carol, 103, "refs/heads/main", oid("a"), oid("b"), "fix the thing")
    33 urequire.NoError(t, err)
    34 uassert.Equal(t, KindUpdate, e2.Kind)
    35 uassert.Equal(t, oid("a"), e2.OldOID)
    36 uassert.Equal(t, EntryDigest(e.Digest, e2), e2.Digest, "digest commits to its predecessor")
    37 uassert.Equal(t, e2.Digest, r.LogHead())
    38
    39 // No-op writes are rejected: they would cost a deposit and record nothing.
    40 _, err = r.SetRef(carol, 104, "refs/heads/main", oid("b"), oid("b"), "")
    41 uassert.ErrorIs(t, err, ErrSameOID)
    42
    43 // Updating a ref that does not exist is not a create.
    44 _, err = r.SetRef(carol, 104, "refs/heads/other", oid("a"), oid("b"), "")
    45 uassert.ErrorIs(t, err, ErrRefNotFound)
    46}
    47
    48func TestSetRefAuthorizationAndValidation(t *testing.T) {
    49 _, r := newRepo(t)
    50
    51 _, err := r.SetRef(eve, 101, "refs/heads/main", "", oid("a"), "")
    52 uassert.ErrorIs(t, err, ErrUnauthorized, "a stranger cannot move a ref")
    53 _, err = r.SetRef(dave, 101, "refs/heads/main", "", oid("a"), "")
    54 uassert.ErrorIs(t, err, ErrUnauthorized, "a reader cannot move a ref")
    55
    56 _, err = r.SetRef(carol, 101, "main", "", oid("a"), "")
    57 uassert.ErrorIs(t, err, ErrInvalidRefName)
    58 _, err = r.SetRef(carol, 101, "refs/heads/main", "", "deadbeef", "")
    59 uassert.ErrorIs(t, err, ErrInvalidOID)
    60 _, err = r.SetRef(carol, 101, "refs/heads/main", "", oid("a"), "two\nlines")
    61 uassert.ErrorIs(t, err, ErrInvalidText, "a note is one line: it is a digest field")
    62}
    63
    64func TestForceAndDelete(t *testing.T) {
    65 _, r := newRepo(t)
    66 _, err := r.SetRef(carol, 101, "refs/heads/main", "", oid("a"), "initial")
    67 urequire.NoError(t, err)
    68 _, err = r.SetRef(carol, 102, "refs/heads/wip", "", oid("c"), "wip")
    69 urequire.NoError(t, err)
    70
    71 // A writer cannot force. A maintainer can, and it is on the record forever.
    72 _, err = r.ForceSetRef(carol, 103, "refs/heads/main", oid("d"), "rewrite")
    73 uassert.ErrorIs(t, err, ErrUnauthorized)
    74 e, err := r.ForceSetRef(bob, 103, "refs/heads/main", oid("d"), "drop the bad commit")
    75 urequire.NoError(t, err)
    76 uassert.Equal(t, KindForce, e.Kind)
    77 uassert.Equal(t, oid("a"), e.OldOID, "the abandoned tip stays in the log")
    78
    79 // Delete is compare-and-swap too, and the default branch is not deletable.
    80 _, err = r.DeleteRef(bob, 104, "refs/heads/main", oid("d"), "")
    81 uassert.ErrorIs(t, err, ErrUnauthorized)
    82 _, err = r.DeleteRef(bob, 104, "refs/heads/wip", oid("9"), "")
    83 uassert.ErrorIs(t, err, ErrStaleRef)
    84 _, err = r.DeleteRef(carol, 104, "refs/heads/wip", oid("c"), "")
    85 uassert.ErrorIs(t, err, ErrUnauthorized)
    86 de, err := r.DeleteRef(bob, 104, "refs/heads/wip", oid("c"), "merged")
    87 urequire.NoError(t, err)
    88 uassert.Equal(t, KindDelete, de.Kind)
    89 uassert.Equal(t, "", de.NewOID)
    90 uassert.Equal(t, 1, r.RefCount(), "the ref is gone")
    91 uassert.Equal(t, 4, r.LogSize(), "the history of it is not")
    92
    93 _, err = r.DeleteRef(bob, 105, "refs/heads/wip", "", "")
    94 uassert.ErrorIs(t, err, ErrRefNotFound)
    95}
    96
    97func TestLogChainVerifies(t *testing.T) {
    98 _, r := newRepo(t)
    99 urequire.Equal(t, "", r.LogHead())
    100
    101 for i, o := range []string{"a", "b", "c", "d"} {
    102 expected := ""
    103 if i > 0 {
    104 expected = r.Ref("refs/heads/main").OID
    105 }
    106 _, err := r.SetRef(carol, int64(100+i), "refs/heads/main", expected, oid(o), "step")
    107 urequire.NoError(t, err)
    108 }
    109 uassert.Equal(t, 4, r.LogSize())
    110
    111 ok, bad := r.VerifyLog()
    112 uassert.True(t, ok, "an untouched log verifies")
    113 uassert.Equal(t, int64(-1), bad)
    114
    115 // Rewrite history the only way it can be rewritten here: reaching into the
    116 // package's own memory, and the chain detects it at the doctored entry.
    117 r.LogEntryAt(1).NewOID = oid("f")
    118 ok, bad = r.VerifyLog()
    119 uassert.False(t, ok, "a doctored entry breaks the chain")
    120 uassert.Equal(t, int64(1), bad)
    121}
    122
    123func TestLogIteration(t *testing.T) {
    124 _, r := newRepo(t)
    125 for i, o := range []string{"a", "b", "c"} {
    126 expected := ""
    127 if i > 0 {
    128 expected = r.Ref("refs/heads/main").OID
    129 }
    130 _, err := r.SetRef(carol, int64(100+i), "refs/heads/main", expected, oid(o), "")
    131 urequire.NoError(t, err)
    132 }
    133
    134 var fwd []string
    135 r.IterateLog(0, 0, func(e *LogEntry) bool {
    136 fwd = append(fwd, e.NewOID[:1])
    137 return false
    138 })
    139 uassert.Equal(t, "a,b,c", join(fwd))
    140
    141 var rev []string
    142 r.IterateLogReverse(0, 2, func(e *LogEntry) bool {
    143 rev = append(rev, e.NewOID[:1])
    144 return false
    145 })
    146 uassert.Equal(t, "c,b", join(rev), "newest-first, paginated")
    147
    148 var names []string
    149 r.IterateRefs(func(ref *Ref) bool {
    150 names = append(names, ref.Name)
    151 return false
    152 })
    153 uassert.Equal(t, "refs/heads/main", join(names))
    154 uassert.True(t, r.LogEntryAt(99) == nil)
    155}
    156