Skip to content Search Apps Documentation Source Content File Folder Download Copy Actions State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

Community realm. Read the code first. Community realm, deployed by its author. Read the code before you interact or send coins.

security_test.gno

3.99 Kb · 106 lines
  1package gns
  2
  3import (
  4	"testing"
  5)
  6
  7// This file targets the "critical invariants" list from the spec that are best
  8// expressed as focused checks against the internal helpers.
  9
 10func TestInvariantAdminCannotConfiscate(cur realm, t *testing.T) {
 11	reset()
 12	doRegister(cur, "alice", alice, 100000)
 13	n := getRaw("alice")
 14
 15	// invariant 18: admin has no routine power over an active user name.
 16	errIs(t, authorize(admin, n, PermTransfer), errUnauthorized, "admin no transfer")
 17	errIs(t, authorize(admin, n, PermManageRecords), errUnauthorized, "admin no records")
 18
 19	// invariant 14/17 via ReserveName: an actively-owned name cannot be reserved
 20	// (confiscated). We assert the precondition the crossing path enforces.
 21	isFalse(t, available("alice"), "active name unavailable to others")
 22	isTrue(t, isActive(n) && n.Owner.IsValid(), "name active and owned")
 23}
 24
 25func TestInvariantGraceNotRegisterable(cur realm, t *testing.T) {
 26	reset()
 27	doRegister(cur, "alice", alice, 1000)
 28	testing.SkipHeights(210) // into grace
 29	eqStr(t, string(StatusGrace), string(Status("alice")), "in grace")
 30	// invariant 3: a grace-period name cannot be registered by another user.
 31	isFalse(t, available("alice"), "grace name not available")
 32}
 33
 34func TestInvariantSingleEffectiveOwner(cur realm, t *testing.T) {
 35	reset()
 36	doRegister(cur, "alice", alice, 100000)
 37	// invariant 1: exactly one owner.
 38	o1, ok := OwnerOf("alice")
 39	isTrue(t, ok, "owned")
 40	testing.SetRealm(testing.NewUserRealm(alice))
 41	Transfer(cross(cur), "alice", bob, true, false)
 42	o2, _ := OwnerOf("alice")
 43	isFalse(t, o1 == o2, "owner changed to exactly one new owner")
 44	eqStr(t, bob.String(), o2, "single new owner")
 45}
 46
 47func TestInvariantPermanentOnlyRestrictive(t *testing.T) {
 48	reset()
 49	// invariant 5, exhaustive over all flags.
 50	all := ControlPolicy{
 51		OwnerCanTransfer: true, OwnerCanCreateSubnames: true, RecordsMutable: true,
 52		ParentCanReclaim: true, ParentCanTransfer: true, ParentCanDelete: true,
 53		ParentCanChangePolicy: true, Permanent: true,
 54	}
 55	// try to relax everything
 56	got := mergeRestrictive(all, all) // identity keeps all true
 57	isTrue(t, got.OwnerCanTransfer && got.RecordsMutable && got.ParentCanReclaim, "identity keeps flags")
 58
 59	none := ControlPolicy{Permanent: true}
 60	restricted := mergeRestrictive(all, none)
 61	isFalse(t, restricted.OwnerCanTransfer, "all restricted off")
 62	isFalse(t, restricted.ParentCanReclaim, "reclaim off")
 63	isTrue(t, restricted.Permanent, "permanent stays on")
 64
 65	// cannot turn any back on
 66	reenable := mergeRestrictive(restricted, all)
 67	isFalse(t, reenable.OwnerCanTransfer, "cannot re-enable transfer")
 68	isFalse(t, reenable.RecordsMutable, "cannot re-enable records")
 69}
 70
 71func TestInvariantPriceOverflowSafe(t *testing.T) {
 72	reset()
 73	config.BasePricePerSecond = 1 << 40
 74	// invariant 10: overflow returns an error, never a wrapped value.
 75	_, err := priceFor("a", 1<<40) // *100 multiplier -> overflow
 76	isErr(t, err, "overflow detected")
 77}
 78
 79func TestInvariantCommitmentTiming(cur realm, t *testing.T) {
 80	reset()
 81	commit, _ := MakeCommitment("alice", alice, 1000, "s", "", config.PolicyRevision)
 82	testing.SetRealm(testing.NewUserRealm(alice))
 83	Commit(cross(cur), commit)
 84
 85	cs := CommitmentStatus(commit)
 86	// invariant 8: ready/expiry window is enforced by MinCommitAge/MaxCommitAge.
 87	eqInt(t, cs.CreatedAt+config.MinCommitAge, cs.ReadyAt, "ready at min age")
 88	eqInt(t, cs.CreatedAt+config.MaxCommitAge, cs.ExpiresAt, "expires at max age")
 89}
 90
 91func TestPauseGatePure(t *testing.T) {
 92	reset()
 93	// paused reads still work; the mutation gate is requireNotPaused.
 94	config.Paused = true
 95	// Status is a read; must still function while paused.
 96	eqStr(t, string(StatusAvailable), string(Status("nobody")), "reads work while paused")
 97	config.Paused = false
 98}
 99
100func TestRecordLimitsConfigured(t *testing.T) {
101	reset()
102	// invariant 13: per-name storage bounds are configured and enforced.
103	isTrue(t, config.MaxRecordsPerName > 0, "record count bound configured")
104	isTrue(t, config.MaxTextValueBytes > 0, "text size bound configured")
105	isTrue(t, config.MaxOperatorsPerName > 0, "operator bound configured")
106}