seed.gno
5.66 Kb · 138 lines
1package zones
2
3import (
4 "chain/runtime"
5
6 "gno.land/p/moul/zones/v0"
7)
8
9// seedReason is the review every seeded zone and endpoint carries, so a reader
10// can tell a deploy-time entry from one a curator reviewed later, and knows how
11// old the check is.
12const seedReason = "seeded at deploy; probed 2026-10-01"
13
14// seedZone is one zone the realm starts with, approved, plus the endpoints it
15// starts with. Every seeded endpoint carries the probe's verdict, which is per
16// zone: verified with seedReason when the zone's endpoints answered, flagged
17// with failed, the observed failure, when they did not. Flagged rather than left unverified, because "probed and down"
18// and "nobody looked" are different facts and only a review can say which.
19type seedZone struct {
20 slug string
21 info zones.Info
22 failed string // empty when every endpoint answered the probe
23 endpoints [][3]string // kind, address, label
24}
25
26// seeds are the four zones this registry opens with. Every address below was
27// probed on 2026-10-01: each RPC's /status answered with the chain id given
28// here, except staging, whose RPC answered "temporarily unavailable" and whose
29// gnoweb answered 503, which is why its endpoints are seeded flagged with that. The
30// peers are the persistent_peers each network's VALIDATOR.md publishes in the
31// gnolang/gno monorepo, under misc/deployments.
32//
33// A function, not a package-level var: a realm's package variables are its
34// database, so a var here would keep every seed stored a second time, forever,
35// beside the registry copy seed() makes of it.
36func seeds() []seedZone {
37 return []seedZone{
38 {
39 slug: "mainnet",
40 info: zones.Info{
41 ChainID: "gnoland-1",
42 Title: "gno.land mainnet",
43 Description: "The gno.land mainnet, launched 2026-09-12.",
44 Kind: zones.Mainnet,
45 GnowebURL: "https://gno.land",
46 RPCURL: "https://rpc.gno.land",
47 GenesisURL: "https://github.com/gnolang/gno/releases/download/chain/mainnet/genesis.json",
48 },
49 endpoints: [][3]string{
50 {"rpc", "https://rpc.gno.land", "gno core"},
51 {"gnoweb", "https://gno.land", "gno core"},
52 {"peer", "[email protected]:26656", "seed-1, gno core"},
53 {"peer", "[email protected]:26656", "seed-2, gno core"},
54 {"indexer", "https://indexer.gno.land/graphql/query", "gno core tx-indexer"},
55 {"explorer", "https://gnoscope.com/?network=mainnet", "gnoscope"},
56 },
57 },
58 {
59 slug: "onyx",
60 info: zones.Info{
61 ChainID: "onyx-1",
62 Title: "Onyx testnet",
63 Description: "The gno.land testnet, launched 2026-09-28: mainnet's code, upgraded whenever mainnet is.",
64 Kind: zones.Testnet,
65 GnowebURL: "https://onyx.testnets.gno.land",
66 RPCURL: "https://rpc.onyx.testnets.gno.land",
67 GenesisURL: "https://github.com/gnolang/gno/releases/download/chain/onyx/genesis.json",
68 },
69 endpoints: [][3]string{
70 {"rpc", "https://rpc.onyx.testnets.gno.land", "gno core"},
71 {"gnoweb", "https://onyx.testnets.gno.land", "gno core"},
72 {"peer", "g1x5mlj5ava0dw9vkf4j6admjlzswm6f06p44krn@seed-1.onyx.testnets.gno.land:26656", "seed-1, gno core"},
73 {"peer", "g1grq5zswt0dlwwe7clr4359w70k2ewgse0gcwck@seed-2.onyx.testnets.gno.land:26656", "seed-2, gno core"},
74 {"indexer", "https://indexer.onyx.testnets.gno.land/graphql/query", "gno core tx-indexer"},
75 {"faucet", "https://onyx.testnets.gno.land/faucet", "gno core"},
76 {"explorer", "https://gnoscope.com/?network=onyx", "gnoscope"},
77 },
78 },
79 {
80 slug: "staging",
81 info: zones.Info{
82 ChainID: "staging",
83 Title: "gno.land staging",
84 Description: "gno core's staging network.",
85 Kind: zones.Devnet,
86 GnowebURL: "https://staging.gno.land",
87 RPCURL: "https://rpc.staging.gno.land",
88 },
89 failed: "did not answer when probed 2026-10-01: the RPC said temporarily unavailable, gnoweb 503",
90 endpoints: [][3]string{
91 {"rpc", "https://rpc.staging.gno.land", "gno core"},
92 {"gnoweb", "https://staging.gno.land", "gno core"},
93 },
94 },
95 {
96 slug: "moul-staging",
97 info: zones.Info{
98 ChainID: "moulstaging-1",
99 Title: "moul's gnodev staging",
100 Description: "One gnodev node in staging mode, run by moul: a single validator, no consensus, worthless GNOT. Good for trying a deploy.",
101 Kind: zones.Devnet,
102 GnowebURL: "https://gno-staging.moul.p2p.team",
103 RPCURL: "https://rpc.gno-staging.moul.p2p.team",
104 },
105 endpoints: [][3]string{
106 {"rpc", "https://rpc.gno-staging.moul.p2p.team", "moul"},
107 {"gnoweb", "https://gno-staging.moul.p2p.team", "moul"},
108 {"faucet", "https://gno-staging.moul.p2p.team/faucet", "moul"},
109 },
110 },
111 }
112}
113
114// seed files every seed through the same Registry methods a caller's
115// transaction goes through (the gated ones, so a seeded endpoint is not
116// Exempt; each is ruled on at once, so none is clearable), so a seed that
117// would fail validation fails the deploy instead of shipping a zone no later
118// edit could reproduce.
119func seed() {
120 at := runtime.ChainHeight()
121 for _, s := range seeds() {
122 must(reg.Propose(Admin, at, s.slug, s.info))
123 must(reg.ReviewZone(s.slug, zones.Approved, mustZone(s.slug).Revision, Admin, at, seedReason))
124 for _, e := range s.endpoints {
125 k, err := zones.ParseEndpointKind(e[0])
126 must(err)
127 id, err := reg.Register(Admin, at, s.slug, k, e[1], e[2])
128 must(err)
129 ep, _ := reg.Endpoint(id)
130 zrev := mustZone(s.slug).Revision // the approval moved it
131 if s.failed == "" {
132 must(reg.ReviewEndpoint(id, zones.Verified, zrev, ep.Revision, Admin, at, seedReason))
133 } else {
134 must(reg.ReviewEndpoint(id, zones.Flagged, zrev, ep.Revision, Admin, at, s.failed))
135 }
136 }
137 }
138}