upgrade.gno
1.71 Kb · 63 lines
1package ucs03_zkgm
2
3import (
4 "strings"
5
6 "gno.land/r/onbloc/ibc/union/access"
7)
8
9func ProxyPkgPath() string {
10 return proxyPkgPath
11}
12
13func ProxyAddress() address {
14 return proxyAddress
15}
16
17// RegisterImpl records an impl constructor under the calling realm's package
18// path. It is called from the impl realm's init, so the path is permanent once
19// installed: re-registration is rejected. The caller must be a sub-realm of this
20// proxy (its path must be prefixed by the proxy path), matching core's host
21// registration rule.
22func RegisterImpl(cur realm, constructor func(store IStore) IApp) {
23 currentPath := cur.PkgPath()
24 previousPath := cur.Previous().PkgPath()
25
26 prefix := currentPath + "/"
27
28 if !strings.HasPrefix(previousPath, prefix) {
29 panic("previous impl path is not a prefix of the current impl path")
30 }
31
32 if _, ok := implConstructors[previousPath]; ok {
33 panic("impl already registered")
34 }
35
36 implConstructors[previousPath] = constructor
37}
38
39// UpdateImpl installs or re-points the implementation following the bootstrap and
40// steady-state tiers of the trust model. It is admin-gated and injects the
41// proxy-owned store into the registered constructor for path.
42func UpdateImpl(cur realm, path string) {
43 access.AssertCanCall(0, cur, SelectorUpdateImpl)
44
45 constructor, ok := implConstructors[path]
46 if !ok {
47 panic("impl constructor not found")
48 }
49
50 oldImplPath := currentImplPath
51 currentImplPath = path
52 currentImpl = constructor(store)
53 emitZkgmImplUpdatedEvent(cur.Previous().PkgPath(), oldImplPath, path, []string{path})
54}
55
56// mustGetImpl returns the installed impl, panicking until the first UpdateImpl.
57func mustGetImpl() IApp {
58 if currentImpl == nil {
59 panic("implementation not installed")
60 }
61
62 return currentImpl
63}