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  }