Skip to content Search Apps Documentation Source Content File Folder Download Copy Actions 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}