admin_test.gno
4.98 Kb · 112 lines
1package valopers
2
3import (
4 "testing"
5
6 "gno.land/p/nt/uassert/v0"
7)
8
9// TestAuthDescribesGovDAOGate pins init.gno's configuration, including the
10// proposer half — which is the load-bearing half.
11//
12// Deliberately does NOT reassign `auth`: an earlier version of this test
13// built its own ContractAuthority and then claimed to "mirror init.gno",
14// which meant changing the contract path in init.gno left it green.
15//
16// Before ContractAuthority.String() rendered the proposer, this assertion
17// was blind to the drift that matters: swapping init.gno for
18// NewRestrictedContractAuthority(path, handler, NewAutoAcceptAuthority())
19// — i.e. reopening the hole for this realm — left the rendered string
20// byte-identical and the whole valopers suite green.
21//
22// It is also blind no longer to a proposer that merely CLAIMS to be the
23// contract-identity default: authz renders any non-canonical Authority
24// wrapped as custom_authority[...], so a spoofing impl cannot reproduce
25// these bytes. See authz's TestSpoofedProposerCannotImpersonateContractIdentity.
26func TestAuthDescribesGovDAOGate(cur realm, t *testing.T) {
27 uassert.Equal(t,
28 "contract_authority[contract=gno.land/r/gov/dao,proposer=contract-identity]",
29 Auth())
30}
31
32// TestUpdateInstructionsRejectsNonGovDAO is the negative pin for the
33// repointed authority, and it is the one that would have caught the
34// regression class this realm fears.
35//
36// The authority is a ContractAuthority for gno.land/r/gov/dao driven by
37// DoByPrevious, so the principal is whoever crossed into valopers. Here
38// that is the test's own frame, not GovDAO's executor — so the privileged
39// write must be refused and `instructions` must not move.
40//
41// Note what this test could NOT assert before the repoint: under the
42// previous ContractAuthority(ownPath) + DoByCurrent pairing, rlm.Address()
43// inside any valopers crossing frame is unconditionally valopers' own
44// address, so this exact call SUCCEEDED and the old version of this test
45// asserted NotPanics. That is why it never pinned anything: the gate it was
46// exercising could not reject.
47//
48// The positive half — that GovDAO can still perform the write — lives in
49// proposal/filetests/z_governed_instructions_filetest.gno, which runs
50// propose -> vote -> execute end to end.
51func TestUpdateInstructionsRejectsNonGovDAO(cur realm, t *testing.T) {
52 before := instructions
53
54 // An ERROR, not a panic: the refusal has to travel back to
55 // impl.ExecuteProposal as a value so a passed-but-refused proposal can
56 // be marked Denied instead of aborting the execute transaction. See
57 // updateInstructions.
58 err := updateInstructions(0, cur, "SHOULD-NOT-LAND")
59
60 uassert.ErrorContains(t, err, "unauthorized",
61 "a non-GovDAO principal must be refused")
62 uassert.Equal(t, before, instructions,
63 "instructions must not move when the gate refuses")
64}
65
66// The instructions proposal's on-chain title is rendered to GovDAO voters
67// and is what off-chain tooling matches on, so it is pinned rather than
68// left to drift silently. It changed in this realm's history from
69// "/p/gnops/valopers: ..." (wrong — valopers is an /r/ realm) when
70// proposal construction moved out of r/gnops/valopers/proposal.
71func TestInstructionsProposalTitleIsPinned(cur realm, t *testing.T) {
72 uassert.Equal(t, "/r/gnops/valopers: Update instructions", instructionsProposalTitle)
73
74 req := NewInstructionsProposalRequest(cross(cur), "whatever")
75 uassert.Equal(t, instructionsProposalTitle, req.Title())
76}
77
78// The authority must be rotatable by GovDAO, or a principal that stops
79// being presentable freezes `instructions` with no on-chain recovery (and
80// redeploying is expensive: r/sys/validators/v0/cache.gno hardcodes
81// valopersRealmPath). This pins that the rotation path exists, is sealed
82// the same way the instructions write is, and that a non-GovDAO principal
83// cannot drive it.
84func TestRotateAuthorityRejectsNonGovDAO(cur realm, t *testing.T) {
85 before := Auth()
86
87 err := rotateAuthority(0, cur, "gno.land/r/gov/dao/v4")
88
89 uassert.ErrorContains(t, err, "unauthorized",
90 "a non-GovDAO principal must not be able to rotate the authority")
91 uassert.Equal(t, before, Auth(), "the authority must be unchanged")
92}
93
94// The rotation request is built here and returned sealed: dao.ProposalRequest
95// exposes only Title/Description/Filter, so a holder cannot reach the
96// executor. Anyone may build one; only GovDAO can adopt and run it.
97func TestRotationProposalRequestIsSealed(cur realm, t *testing.T) {
98 req := NewAuthorityRotationProposalRequest(cross(cur), "gno.land/r/gov/dao/v4")
99
100 uassert.Equal(t, "/r/gnops/valopers: Rotate governance authority", req.Title())
101 uassert.NotEqual(t, "", req.Description())
102
103 // Building the request must not itself perform the rotation.
104 uassert.Equal(t,
105 "contract_authority[contract=gno.land/r/gov/dao,proposer=contract-identity]",
106 Auth())
107}
108
109// TestUpdateMinFee was removed: register_fee now lives in sysparams
110// (node:valoper:register_fee), governed via the generic
111// NewSysParamUint64PropRequest factory. See proposal.gno for the
112// replacement flow.