-
Notifications
You must be signed in to change notification settings - Fork 389
/
Copy pathnative.go
144 lines (124 loc) · 3.4 KB
/
native.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
package std
import (
gno "github.com/gnolang/gno/gnovm/pkg/gnolang"
"github.com/gnolang/gno/tm2/pkg/bech32"
"github.com/gnolang/gno/tm2/pkg/crypto"
"github.com/gnolang/gno/tm2/pkg/std"
)
func AssertOriginCall(m *gno.Machine) {
if !IsOriginCall(m) {
m.Panic(typedString("invalid non-origin call"))
}
}
func IsOriginCall(m *gno.Machine) bool {
return len(m.Frames) == 2
}
func CurrentRealmPath(m *gno.Machine) string {
if m.Realm != nil {
return m.Realm.Path
}
return ""
}
func GetChainID(m *gno.Machine) string {
return m.Context.(ExecContext).ChainID
}
func GetHeight(m *gno.Machine) int64 {
return m.Context.(ExecContext).Height
}
func X_origSend(m *gno.Machine) (denoms []string, amounts []int64) {
os := m.Context.(ExecContext).OrigSend
return ExpandCoins(os)
}
func X_origCaller(m *gno.Machine) string {
return string(m.Context.(ExecContext).OrigCaller)
}
func X_origPkgAddr(m *gno.Machine) string {
return string(m.Context.(ExecContext).OrigPkgAddr)
}
func X_callerAt(m *gno.Machine, n int) string {
if n <= 0 {
m.Panic(typedString("GetCallerAt requires positive arg"))
return ""
}
// Add 1 to n to account for the GetCallerAt (gno fn) frame.
n++
if n > m.NumFrames() {
// NOTE: the last frame's LastPackage
// is set to the original non-frame
// package, so need this check.
m.Panic(typedString("frame not found"))
return ""
}
if n == m.NumFrames() {
// This makes it consistent with GetOrigCaller.
ctx := m.Context.(ExecContext)
return string(ctx.OrigCaller)
}
return string(m.MustLastCallFrame(n).LastPackage.GetPkgAddr().Bech32())
}
func X_getRealm(m *gno.Machine, height int) (address string, pkgPath string) {
var (
ctx = m.Context.(ExecContext)
currentCaller crypto.Bech32Address
// Keeps track of the number of times currentCaller
// has changed.
changes int
)
for i := m.NumFrames() - 1; i > 0; i-- {
fr := m.Frames[i]
if fr.LastPackage == nil || !fr.LastPackage.IsRealm() {
continue
}
// LastPackage is a realm. Get caller and pkgPath, and compare against
// current* values.
caller := fr.LastPackage.GetPkgAddr().Bech32()
pkgPath := fr.LastPackage.PkgPath
if caller != currentCaller {
if changes == height {
return string(caller), pkgPath
}
currentCaller = caller
changes++
}
}
// Fallback case: return OrigCaller.
return string(ctx.OrigCaller), ""
}
func X_derivePkgAddr(pkgPath string) string {
return string(gno.DerivePkgAddr(pkgPath).Bech32())
}
func X_encodeBech32(prefix string, bytes [20]byte) string {
b32, err := bech32.ConvertAndEncode(prefix, bytes[:])
if err != nil {
panic(err) // should not happen
}
return b32
}
func X_decodeBech32(addr string) (prefix string, bytes [20]byte, ok bool) {
prefix, bz, err := bech32.Decode(addr)
if err != nil || len(bz) != 20 {
return "", [20]byte{}, false
}
return prefix, [20]byte(bz), true
}
func typedString(s string) gno.TypedValue {
tv := gno.TypedValue{T: gno.StringType}
tv.SetString(gno.StringValue(s))
return tv
}
func ExpandCoins(c std.Coins) (denoms []string, amounts []int64) {
denoms = make([]string, len(c))
amounts = make([]int64, len(c))
for i, coin := range c {
denoms[i] = coin.Denom
amounts[i] = coin.Amount
}
return denoms, amounts
}
func CompactCoins(denoms []string, amounts []int64) std.Coins {
coins := make(std.Coins, len(denoms))
for i := range coins {
coins[i] = std.Coin{Denom: denoms[i], Amount: amounts[i]}
}
return coins
}