utils.gno
3.19 Kb ยท 129 lines
1package gns
2
3import (
4 "math"
5 "strconv"
6
7 "gno.land/p/nt/ufmt"
8)
9
10// validBlockTime validates that block time is within acceptable range.
11// Returns error if block time is <= 0 or >= 1e9.
12func validBlockTime(blockTime int64) error {
13 if blockTime <= 0 || blockTime >= 1e9 {
14 return errInvalidAvgBlockTimeInMs
15 }
16
17 return nil
18}
19
20// validYear validates that year is within halving period range (1-12).
21// Returns error if year is outside the valid range.
22func validYear(year int64) error {
23 if year < HALVING_START_YEAR || year > HALVING_END_YEAR {
24 return makeErrorWithDetails(errInvalidYear, ufmt.Sprintf("year: %d", year))
25 }
26
27 return nil
28}
29
30// validEmissionAmount validates that the emission amount does not exceed maximum.
31// Returns error if minting the amount would exceed MAX_EMISSION_AMOUNT.
32func validEmissionAmount(amount int64) error {
33 if amount < 0 {
34 return makeErrorWithDetails(errInvalidEmissionAmount, ufmt.Sprintf("emission amount cannot be negative: %d", amount))
35 }
36
37 if safeAddInt64(amount, MintedEmissionAmount()) > MAX_EMISSION_AMOUNT {
38 return makeErrorWithDetails(errTooManyEmission, ufmt.Sprintf("too many emission amount: %d", amount))
39 }
40
41 return nil
42}
43
44// i64Min returns the smaller of two int64 values.
45func i64Min(x, y int64) int64 {
46 if x < y {
47 return x
48 }
49 return y
50}
51
52// formatUint formats unsigned integer types to string.
53// Supports uint8, uint32, and uint64. Panics for unsupported types.
54func formatUint(v any) string {
55 switch v := v.(type) {
56 case uint8:
57 return strconv.FormatUint(uint64(v), 10)
58 case uint32:
59 return strconv.FormatUint(uint64(v), 10)
60 case uint64:
61 return strconv.FormatUint(v, 10)
62 default:
63 panic(ufmt.Sprintf("invalid type: %T", v))
64 }
65}
66
67// formatInt formats signed integer types to string.
68// Supports int32, int64, and int. Panics for unsupported types.
69func formatInt(v any) string {
70 switch v := v.(type) {
71 case int32:
72 return strconv.FormatInt(int64(v), 10)
73 case int64:
74 return strconv.FormatInt(v, 10)
75 case int:
76 return strconv.Itoa(v)
77 default:
78 panic(ufmt.Sprintf("invalid type: %T", v))
79 }
80}
81
82// safeAddInt64 performs safe addition of int64 values, panicking on overflow or underflow
83func safeAddInt64(a, b int64) int64 {
84 if a > 0 && b > math.MaxInt64-a {
85 panic("int64 addition overflow")
86 }
87 if a < 0 && b < math.MinInt64-a {
88 panic("int64 addition underflow")
89 }
90 return a + b
91}
92
93// safeSubInt64 performs safe subtraction of int64 values, panicking on overflow or underflow
94func safeSubInt64(a, b int64) int64 {
95 if b > 0 && a < math.MinInt64+b {
96 panic("int64 subtraction underflow")
97 }
98 if b < 0 && a > math.MaxInt64+b {
99 panic("int64 subtraction overflow")
100 }
101 return a - b
102}
103
104// safeMulInt64 performs safe multiplication of int64 values, panicking on overflow or underflow
105func safeMulInt64(a, b int64) int64 {
106 if a == 0 || b == 0 {
107 return 0
108 }
109
110 if a > 0 && b > 0 {
111 if a > math.MaxInt64/b {
112 panic("int64 multiplication overflow")
113 }
114 } else if a < 0 && b < 0 {
115 if a < math.MaxInt64/b {
116 panic("int64 multiplication overflow")
117 }
118 } else if a > 0 && b < 0 {
119 if b < math.MinInt64/a {
120 panic("int64 multiplication underflow")
121 }
122 } else { // a < 0 && b > 0
123 if a < math.MinInt64/b {
124 panic("int64 multiplication underflow")
125 }
126 }
127
128 return a * b
129}