Search Apps Documentation Source Content File Folder Download Copy Actions Download

upgrade.gno

2.53 Kb · 72 lines
 1package governance
 2
 3import (
 4	"gno.land/r/gnoswap/access"
 5)
 6
 7// RegisterInitializer registers a version-specific initializer. Each version
 8// (e.g. v1, v2) calls this function from its init body to plug itself into
 9// the proxy.
10//
11// The initializer constructs the version's IGovernance from the supplied
12// IGovernanceStore and GovStakerAccessor. It receives a realm value that
13// resolves to the governance proxy realm — the only address with write
14// permission on the shared KV store — so any per-version store bootstrap
15// performed inside the initializer passes the proxy's authorization check.
16//
17// Security: Only contracts within the domain path can register initializers.
18// Each package path can only register once to prevent duplicate registrations.
19func RegisterInitializer(cur realm, initializer func(_ int, rlm realm, governanceStore IGovernanceStore, stakerAccessor GovStakerAccessor) IGovernance) {
20	// `cur` captured here is the governance crossing frame. The wrapping
21	// closure forwards it to the version initializer so any store writes
22	// the initializer performs run under the proxy's identity rather than
23	// the version package's, which would fail the kvStore ACL.
24	initializerFunc := func(_ int, rlm realm, domainStore any) any {
25		if !rlm.IsCurrent() {
26			panic(ErrSpoofedRealm)
27		}
28
29		currentGovernanceStore, ok := domainStore.(IGovernanceStore)
30		if !ok {
31			panic("domainStore is not an IGovernanceStore")
32		}
33		return initializer(0, rlm, currentGovernanceStore, newGovStakerAccessor())
34	}
35
36	err := versionManager.RegisterInitializer(0, cur, initializerFunc)
37	if err != nil {
38		panic(err)
39	}
40
41	err = updateImplementation()
42	if err != nil {
43		panic(err)
44	}
45}
46
47// UpgradeImpl switches the active governance implementation to a different version.
48// This function allows seamless upgrades from one version to another without
49// data migration or downtime.
50//
51// Security: Only admin or governance can perform upgrades.
52// The new implementation must have been previously registered via RegisterInitializer.
53func UpgradeImpl(cur realm, targetPackagePath string) {
54	// Ensure only admin or governance can perform upgrades
55	prev := cur.Previous()
56	access.AssertIsAdminOrGovernance(prev.Address())
57
58	err := versionManager.ChangeImplementation(0, cur, targetPackagePath)
59	if err != nil {
60		panic(err)
61	}
62
63	err = updateImplementation()
64	if err != nil {
65		panic(err)
66	}
67}
68
69// GetImplementationPackagePath returns the package path of the currently active implementation.
70func GetImplementationPackagePath() string {
71	return versionManager.GetCurrentPackagePath()
72}