github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/x/common/util.go (about) 1 package common 2 3 import ( 4 "bytes" 5 "encoding/binary" 6 "fmt" 7 "math/big" 8 "math/rand" 9 "net/http" 10 "os" 11 "runtime" 12 "strconv" 13 "strings" 14 "testing" 15 "time" 16 17 "github.com/fibonacci-chain/fbc/x/params/subspace" 18 19 sdkerrors "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types/errors" 20 21 apptypes "github.com/fibonacci-chain/fbc/app/types" 22 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/client/context" 23 sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types" 24 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types/rest" 25 ) 26 27 const ( 28 letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" 29 ) 30 31 func InitConfig() { 32 config := sdk.GetConfig() 33 if config.GetBech32ConsensusAddrPrefix() == apptypes.Bech32PrefixConsAddr { 34 return 35 } 36 apptypes.SetBech32Prefixes(config) 37 apptypes.SetBip44CoinType(config) 38 config.Seal() 39 } 40 41 // Int64ToBytes converts int64 to bytes 42 func Int64ToBytes(i int64) []byte { 43 var buf = make([]byte, 8) 44 binary.BigEndian.PutUint64(buf, uint64(i)) 45 return buf 46 } 47 48 // BytesToInt64 converts bytes to int64 49 func BytesToInt64(buf []byte) int64 { 50 return int64(binary.BigEndian.Uint64(buf)) 51 } 52 53 // Paginate converts page params for a paginated query, 54 func Paginate(pageStr, perPageStr string) (page int, perPage int, err error) { 55 if pageStr != "" { 56 page, err = strconv.Atoi(pageStr) 57 if err != nil { 58 return 59 } 60 } 61 if perPageStr != "" { 62 perPage, err = strconv.Atoi(perPageStr) 63 if err != nil { 64 return 65 } 66 } 67 if page < 0 || perPage < 0 { 68 err = fmt.Errorf("negative page %d or per_page %d is invalid", page, perPage) 69 return 70 } 71 return 72 } 73 74 // GetPage returns the offset and limit for data query 75 func GetPage(page, perPage int) (offset, limit int) { 76 if page <= 0 || perPage <= 0 { 77 return 78 } 79 offset = (page - 1) * perPage 80 limit = perPage 81 return 82 } 83 84 // HandleErrorMsg handles the error msg 85 func HandleErrorMsg(w http.ResponseWriter, cliCtx context.CLIContext, code uint32, msg string) { 86 response := GetErrorResponseJSON(code, msg, msg) 87 rest.PostProcessResponse(w, cliCtx, response) 88 } 89 90 // HasSufficientCoins checks whether the account has sufficient coins 91 func HasSufficientCoins(addr sdk.AccAddress, availableCoins, amt sdk.Coins) (err error) { 92 //availableCoins := availCoins[:] 93 if !amt.IsValid() { 94 return sdkerrors.Wrap(sdkerrors.ErrInvalidCoins, amt.String()) 95 } 96 if !availableCoins.IsValid() { 97 return sdkerrors.Wrap(sdkerrors.ErrInvalidCoins, amt.String()) 98 } 99 100 _, hasNeg := availableCoins.SafeSub(amt) 101 if hasNeg { 102 return sdkerrors.Wrap(sdkerrors.ErrInsufficientFunds, 103 fmt.Sprintf("insufficient account funds;address: %s, availableCoin: %s, needCoin: %s", 104 addr.String(), availableCoins, amt), 105 ) 106 } 107 return nil 108 } 109 110 // SkipSysTestChecker is supported to used in System Unit Test 111 // (described in http://gitlab.okcoin-inc.com/dex/fbexchain/issues/472) 112 // if System environment variables "SYS_TEST_ALL" is set to 1, all of the system test will be enable. \n 113 // if System environment variables "ORM_MYSQL_SYS_TEST" is set to 1, 114 // 115 // all of the system test in orm_mysql_sys_test.go will be enble. 116 func SkipSysTestChecker(t *testing.T) { 117 _, fname, _, ok := runtime.Caller(0) 118 enable := ok 119 if enable { 120 enableAllEnv := "SYS_TEST_ALL" 121 122 sysTestName := strings.Split(fname, ".go")[0] 123 enableCurrent := strings.ToUpper(sysTestName) 124 125 enable = os.Getenv(enableAllEnv) == "1" || 126 (strings.HasSuffix(sysTestName, "sys_test") && os.Getenv(enableCurrent) == "1") 127 } 128 129 if !enable { 130 t.SkipNow() 131 } 132 } 133 134 // mulAndQuo returns a * b / c 135 func MulAndQuo(a, b, c sdk.Dec) sdk.Dec { 136 // 10^8 137 auxiliaryDec := sdk.NewDecFromBigInt(new(big.Int).Exp(big.NewInt(10), big.NewInt(sdk.Precision), nil)) 138 a = a.MulTruncate(auxiliaryDec) 139 return a.MulTruncate(b).QuoTruncate(c).QuoTruncate(auxiliaryDec) 140 } 141 142 // BlackHoleAddress returns the black hole address 143 func BlackHoleAddress() sdk.AccAddress { 144 addr, _ := sdk.AccAddressFromHex(blackHoleHex) 145 return addr 146 } 147 148 func GetFixedLengthRandomString(n int) string { 149 b := make([]byte, n) 150 for i := range b { 151 b[i] = letterBytes[rand.Intn(len(letterBytes))] 152 } 153 return string(b) 154 } 155 156 func PanicTrace(kb int) { 157 s := []byte("/src/runtime/panic.go") 158 e := []byte("\ngoroutine ") 159 line := []byte("\n") 160 stack := make([]byte, kb<<10) //4KB 161 length := runtime.Stack(stack, true) 162 start := bytes.Index(stack, s) 163 stack = stack[start:length] 164 start = bytes.Index(stack, line) + 1 165 stack = stack[start:] 166 end := bytes.LastIndex(stack, line) 167 if end != -1 { 168 stack = stack[:end] 169 } 170 end = bytes.Index(stack, e) 171 if end != -1 { 172 stack = stack[:end] 173 } 174 stack = bytes.TrimRight(stack, "\n") 175 fmt.Print(string(stack)) 176 } 177 178 func SanityCheckHandler(res *sdk.Result, err error) { 179 if res == nil && err == nil { 180 panic("Invalid handler") 181 } 182 if res != nil && err != nil { 183 panic("Invalid handler") 184 } 185 } 186 187 func ValidateSysCoin(param string) subspace.ValueValidatorFn { 188 return func(i interface{}) error { 189 v, ok := i.(sdk.SysCoin) 190 if !ok { 191 return fmt.Errorf("invalid parameter type: %T", i) 192 } 193 194 if !v.IsValid() { 195 return fmt.Errorf("invalid %s: %s", param, v) 196 } 197 198 return nil 199 } 200 } 201 202 func ValidateSysCoins(param string) subspace.ValueValidatorFn { 203 return func(i interface{}) error { 204 v, ok := i.(sdk.SysCoins) 205 if !ok { 206 return fmt.Errorf("invalid parameter type: %T", i) 207 } 208 209 if !v.IsValid() { 210 return fmt.Errorf("invalid %s: %s", param, v) 211 } 212 213 return nil 214 } 215 } 216 217 func ValidateDurationPositive(param string) subspace.ValueValidatorFn { 218 return func(i interface{}) error { 219 v, ok := i.(time.Duration) 220 if !ok { 221 return fmt.Errorf("invalid parameter type: %T", i) 222 } 223 224 if v <= 0 { 225 return fmt.Errorf("%s must be positive: %d", param, v) 226 } 227 228 return nil 229 } 230 } 231 232 func ValidateBool(param string) subspace.ValueValidatorFn { 233 return func(i interface{}) error { 234 _, ok := i.(bool) 235 if !ok { 236 return fmt.Errorf("invalid parameter type: %T", i) 237 } 238 239 return nil 240 } 241 } 242 243 func ValidateInt64Positive(param string) subspace.ValueValidatorFn { 244 return func(i interface{}) error { 245 v, ok := i.(int64) 246 if !ok { 247 return fmt.Errorf("invalid parameter type: %T", i) 248 } 249 250 if v <= 0 { 251 return fmt.Errorf("%s must be positive: %d", param, v) 252 } 253 254 return nil 255 } 256 } 257 258 func ValidateUint64Positive(param string) subspace.ValueValidatorFn { 259 return func(i interface{}) error { 260 v, ok := i.(uint64) 261 if !ok { 262 return fmt.Errorf("invalid parameter type: %T", i) 263 } 264 265 if v == 0 { 266 return fmt.Errorf("%s must be positive: %d", param, v) 267 } 268 269 return nil 270 } 271 } 272 273 func ValidateRateNotNeg(param string) subspace.ValueValidatorFn { 274 return func(i interface{}) error { 275 v, ok := i.(sdk.Dec) 276 if !ok { 277 return fmt.Errorf("invalid parameter type: %T", i) 278 } 279 if v.IsNegative() { 280 return fmt.Errorf("%s cannot be negative: %s", param, v) 281 } 282 if v.GT(sdk.OneDec()) { 283 return fmt.Errorf("%s is too large: %s", param, v) 284 } 285 return nil 286 } 287 } 288 289 func ValidateDecPositive(param string) subspace.ValueValidatorFn { 290 return func(i interface{}) error { 291 v, ok := i.(sdk.Dec) 292 if !ok { 293 return fmt.Errorf("invalid parameter type: %T", i) 294 } 295 if !v.IsPositive() { 296 return fmt.Errorf("%s must be positive: %s", param, v) 297 } 298 return nil 299 } 300 } 301 302 func ValidateDenom(param string) subspace.ValueValidatorFn { 303 return func(i interface{}) error { 304 v, ok := i.(string) 305 if !ok { 306 return fmt.Errorf("invalid parameter type: %T", i) 307 } 308 309 if sdk.ValidateDenom(v) != nil { 310 return fmt.Errorf("invalid %s", param) 311 } 312 313 return nil 314 } 315 } 316 317 func ValidateUint16Positive(param string) subspace.ValueValidatorFn { 318 return func(i interface{}) error { 319 v, ok := i.(uint16) 320 if !ok { 321 return fmt.Errorf("invalid parameter type: %T", i) 322 } 323 324 if v == 0 { 325 return fmt.Errorf("%s must be positive: %d", param, v) 326 } 327 328 return nil 329 } 330 } 331 332 // CheckSignerAddress delegators must be the same as to the signers and amount only one 333 func CheckSignerAddress(signers, delegators []sdk.AccAddress) bool { 334 if len(signers) == 1 && len(delegators) == 1 { 335 return signers[0].Equals(delegators[0]) 336 } 337 return false 338 }