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

upgrade.gno

3.03 Kb · 83 lines
 1package protocol_fee
 2
 3import (
 4	"gno.land/r/gnoswap/access/v1"
 5)
 6
 7// RegisterInitializer registers a new protocol fee 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 protocolFeeStore interface. It receives a realm value
13// that resolves to the protocol_fee proxy realm — the only address with
14// write permission on the shared KV store — so any per-version store
15// bootstrapping performed inside the initializer passes the proxy's
16// authorization check.
17//
18// Security: Only contracts within the domain path can register initializers.
19// Each package path can only register once to prevent duplicate registrations.
20//
21// Parameters:
22//   - cur: Current realm context; callers use cross(cur) when crossing into this realm.
23//   - initializer: callback that receives the proxy realm context and protocol-fee store, initializes version-specific state, and returns the implementation instance
24func RegisterInitializer(cur realm, initializer func(_ int, rlm realm, protocolFeeStore IProtocolFeeStore) IProtocolFee) {
25	// `cur` captured here is the protocol_fee crossing frame. The wrapping
26	// closure forwards it to the v1 initializer so any store writes the
27	// initializer performs run under the proxy's identity rather than the
28	// version package's, which would fail the kvStore ACL.
29	initializerFunc := func(_ int, rlm realm, domainStore any) any {
30		access.AssertIsRlmCurrent(0, rlm)
31
32		currentProtocolFeeStore, ok := domainStore.(IProtocolFeeStore)
33		if !ok {
34			panic("domainStore is not an IProtocolFeeStore")
35		}
36
37		return initializer(0, rlm, currentProtocolFeeStore)
38	}
39
40	err := versionManager.RegisterInitializer(0, cur, initializerFunc)
41	if err != nil {
42		panic(err)
43	}
44
45	err = updateImplementation()
46	if err != nil {
47		panic(err)
48	}
49}
50
51// UpgradeImpl switches the active protocol fee implementation to a different version.
52// This function allows seamless upgrades from one version to another without
53// data migration or downtime.
54//
55// Security: Only admin or governance can perform upgrades.
56// The new implementation must have been previously registered via RegisterInitializer.
57//
58// Parameters:
59//   - cur: Current realm context; callers use cross(cur) when crossing into this realm.
60//   - packagePath: registered implementation package path to activate
61func UpgradeImpl(cur realm, packagePath string) {
62	// Ensure only admin or governance can perform upgrades
63	prev := cur.Previous()
64	access.AssertIsAdminOrGovernance(prev.Address())
65
66	err := versionManager.ChangeImplementation(0, cur, packagePath)
67	if err != nil {
68		panic(err)
69	}
70
71	err = updateImplementation()
72	if err != nil {
73		panic(err)
74	}
75}
76
77// GetImplementationPackagePath returns the package path of the currently active implementation.
78//
79// Returns:
80//   - packagePath: package path of the active implementation
81func GetImplementationPackagePath() string {
82	return versionManager.GetCurrentPackagePath()
83}