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}