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

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}