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

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