Search Apps Documentation Source Content File Folder Download Copy Actions Download

util.gno

3.94 Kb ยท 169 lines
  1package v1
  2
  3import (
  4	b64 "encoding/base64"
  5	"math"
  6	"strconv"
  7
  8	u256 "gno.land/p/gnoswap/uint256"
  9	"gno.land/p/nt/avl"
 10	"gno.land/p/nt/ufmt"
 11	"gno.land/p/onbloc/json"
 12)
 13
 14// marshal data to json string
 15func marshal(data *json.Node) string {
 16	b, err := json.Marshal(data)
 17	if err != nil {
 18		panic(err.Error())
 19	}
 20
 21	return string(b)
 22}
 23
 24// b64Encode encodes data to base64 string
 25func b64Encode(data string) string {
 26	return string(b64.StdEncoding.EncodeToString([]byte(data)))
 27}
 28
 29// formatUint formats a uint64 to a string
 30func formatUint(v uint64) string {
 31	return strconv.FormatUint(v, 10)
 32}
 33
 34// formatInt formats an int64 to a string
 35func formatInt(v int64) string {
 36	return strconv.FormatInt(v, 10)
 37}
 38
 39// getUint64FromTree returns the uint64 value from the tree
 40func getUint64FromTree(tree *avl.Tree, key string) uint64 {
 41	value, exists := tree.Get(key)
 42	if !exists {
 43		return 0
 44	}
 45
 46	v, ok := value.(uint64)
 47	if !ok {
 48		panic(ufmt.Sprintf("failed to cast value to uint64: %T", value))
 49	}
 50
 51	return v
 52}
 53
 54// updateUint64InTree updates the uint64 value in the tree
 55func updateUint64InTree(tree *avl.Tree, key string, delta uint64, add bool) uint64 {
 56	current := getUint64FromTree(tree, key)
 57	var newValue uint64
 58	if add {
 59		newValue = safeAddUint64(current, delta)
 60	} else {
 61		if current < delta {
 62			panic(makeErrorWithDetails(
 63				errNotEnoughBalance,
 64				ufmt.Sprintf("not enough balance: current(%d) < requested(%d)", current, delta),
 65			))
 66		}
 67		newValue = safeSubUint64(current, delta)
 68	}
 69
 70	tree.Set(key, newValue)
 71
 72	return newValue
 73}
 74
 75// getOrCreateInnerTree returns the inner tree for the given key
 76func getOrCreateInnerTree(tree *avl.Tree, key string) *avl.Tree {
 77	value, exists := tree.Get(key)
 78	if !exists {
 79		innerTree := avl.NewTree()
 80		tree.Set(key, innerTree)
 81		return innerTree
 82	}
 83
 84	v, ok := value.(*avl.Tree)
 85	if !ok {
 86		panic(ufmt.Sprintf("failed to cast value to *avl.Tree: %T", value))
 87	}
 88
 89	return v
 90}
 91
 92// milliToSec converts milliseconds to seconds
 93func milliToSec(ms int64) int64 {
 94	var msPerSec int64 = 1000
 95	return ms / msPerSec
 96}
 97
 98// safeConvertToInt64 safely converts a *u256.Uint value to an int64, ensuring no overflow.
 99//
100// This function attempts to convert the given *u256.Uint value to an int64. If the value exceeds
101// the maximum allowable range for int64 (`2^63 - 1`), it triggers a panic with a descriptive error message.
102//
103// Parameters:
104// - value (*u256.Uint): The unsigned 256-bit integer to be converted.
105//
106// Returns:
107// - int64: The converted value if it falls within the int64 range.
108//
109// Panics:
110//   - If the `value` exceeds the range of int64, the function will panic with an error indicating
111//     the overflow and the original value.
112func safeConvertToInt64(value *u256.Uint) int64 {
113	const INT64_MAX = 9223372036854775807
114	const MAX_INT64 = "9223372036854775807"
115
116	res, overflow := value.Uint64WithOverflow()
117	if overflow || res > uint64(INT64_MAX) {
118		panic(ufmt.Sprintf(
119			"amount(%s) overflows int64 range (max %s)",
120			value.ToString(),
121			MAX_INT64,
122		))
123	}
124	return int64(res)
125}
126
127// safeAddInt64 performs safe addition of int64 values, panicking on overflow or underflow
128func safeAddInt64(a, b int64) int64 {
129	if a > 0 && b > math.MaxInt64-a {
130		panic("int64 addition overflow")
131	}
132
133	if a < 0 && b < math.MinInt64-a {
134		panic("int64 addition underflow")
135	}
136
137	return a + b
138}
139
140// safeSubInt64 performs safe subtraction of int64 values, panicking on overflow or underflow
141func safeSubInt64(a, b int64) int64 {
142	if b > 0 && a < math.MinInt64+b {
143		panic("int64 subtraction underflow")
144	}
145
146	if b < 0 && a > math.MaxInt64+b {
147		panic("int64 subtraction overflow")
148	}
149
150	return a - b
151}
152
153// safeAddUint64 performs safe addition of uint64 values, panicking on overflow
154func safeAddUint64(a, b uint64) uint64 {
155	if a > math.MaxUint64-b {
156		panic("uint64 addition overflow")
157	}
158
159	return a + b
160}
161
162// safeSubUint64 performs safe subtraction of uint64 values, panicking on underflow
163func safeSubUint64(a, b uint64) uint64 {
164	if a < b {
165		panic("uint64 subtraction underflow")
166	}
167
168	return a - b
169}