upgrade.gno
2.49 Kb · 75 lines
1package position
2
3import (
4 "gno.land/r/gnoswap/access/v1"
5)
6
7// RegisterInitializer registers a new position implementation version.
8// This function is called by each version (v1, v2, etc.) during initialization
9// to register their implementation with the proxy system.
10//
11// The initializer function creates a new instance of the implementation
12// using the provided positionStore interface.
13//
14// Parameters:
15// - cur: current realm context; callers use cross(cur) when crossing into this realm
16// - initializer: callback that receives the implementation realm context and position store, then returns that version's IPosition implementation
17//
18// Security: Only contracts within the domain path can register initializers.
19// Each package path can only register once to prevent duplicate registrations.
20func RegisterInitializer(cur realm, initializer func(_ int, rlm realm, positionStore IPositionStore) IPosition) {
21 initializerFunc := func(_ int, rlm realm, domainStore any) any {
22 access.AssertIsRlmCurrent(0, rlm)
23
24 currentPositionStore, ok := domainStore.(IPositionStore)
25 if !ok {
26 panic("domainStore is not an IPositionStore")
27 }
28
29 return initializer(0, rlm, currentPositionStore)
30 }
31
32 err := versionManager.RegisterInitializer(0, cur, initializerFunc)
33 if err != nil {
34 panic(err)
35 }
36
37 err = updateImplementation()
38 if err != nil {
39 panic(err)
40 }
41}
42
43// UpgradeImpl switches the active position implementation to a different version.
44// This function allows seamless upgrades from one version to another without
45// data migration or downtime.
46//
47// Parameters:
48// - cur: current realm context; callers use cross(cur) when crossing into this realm
49// - packagePath: fully qualified package path of a previously registered replacement implementation
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, packagePath string) {
54 // Ensure only admin or governance can perform upgrades
55 caller := cur.Previous().Address()
56 access.AssertIsAdminOrGovernance(caller)
57
58 err := versionManager.ChangeImplementation(0, cur, packagePath)
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.
70//
71// Returns:
72// - packagePath: package path of the active implementation
73func GetImplementationPackagePath() string {
74 return versionManager.GetCurrentPackagePath()
75}