upgrade.gno
2.12 Kb · 68 lines
1package staker
2
3import (
4 "errors"
5
6 "gno.land/r/gnoswap/access"
7)
8
9// RegisterInitializer registers a new staker implementation version.
10// This function is called by each version (v1, v2, etc.) during initialization
11// to register their implementation with the proxy system.
12//
13// The initializer function creates a new instance of the implementation
14// using the provided stakerStore interface.
15//
16// Security: Only contracts within the domain path can register initializers.
17// Each package path can only register once to prevent duplicate registrations.
18func RegisterInitializer(cur realm, initializer func(_ int, rlm realm, stakerStore IStakerStore, poolAccessor PoolAccessor, emissionAccessor EmissionAccessor, nftAccessor NFTAccessor) IStaker) {
19 initializerFunc := func(_ int, rlm realm, domainStore any) any {
20 if !rlm.IsCurrent() {
21 panic(errors.New(ErrSpoofedRealm))
22 }
23
24 currentStakerStore, ok := domainStore.(IStakerStore)
25 if !ok {
26 panic("domainStore is not an IStakerStore")
27 }
28
29 return initializer(0, rlm, currentStakerStore, newPoolAccessor(), newEmissionAccessor(), newNFTAccessor())
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 staker implementation to a different version.
44// This function allows seamless upgrades from one version to another without
45// data migration or downtime.
46//
47// Security: Only admin or governance can perform upgrades.
48// The new implementation must have been previously registered via RegisterInitializer.
49func UpgradeImpl(cur realm, packagePath string) {
50 // Ensure only admin or governance can perform upgrades
51 caller := cur.Previous().Address()
52 access.AssertIsAdminOrGovernance(caller)
53
54 err := versionManager.ChangeImplementation(0, cur, packagePath)
55 if err != nil {
56 panic(err)
57 }
58
59 err = updateImplementation()
60 if err != nil {
61 panic(err)
62 }
63}
64
65// GetImplementationPackagePath returns the package path of the currently active implementation.
66func GetImplementationPackagePath() string {
67 return versionManager.GetCurrentPackagePath()
68}