github.com/Finschia/finschia-sdk@v0.48.1/types/utils.go (about)

     1  package types
     2  
     3  import (
     4  	"encoding/binary"
     5  	"encoding/json"
     6  	"fmt"
     7  	"time"
     8  
     9  	dbm "github.com/tendermint/tm-db"
    10  )
    11  
    12  var (
    13  	// DBBackend is set at compile time. Could be cleveldb, defaults is goleveldb.
    14  	DBBackend = ""
    15  	backend   = dbm.GoLevelDBBackend
    16  )
    17  
    18  func init() {
    19  	if len(DBBackend) != 0 {
    20  		backend = dbm.BackendType(DBBackend)
    21  	}
    22  }
    23  
    24  // SortedJSON takes any JSON and returns it sorted by keys. Also, all white-spaces
    25  // are removed.
    26  // This method can be used to canonicalize JSON to be returned by GetSignBytes,
    27  // e.g. for the ledger integration.
    28  // If the passed JSON isn't valid it will return an error.
    29  func SortJSON(toSortJSON []byte) ([]byte, error) {
    30  	var c interface{}
    31  	err := json.Unmarshal(toSortJSON, &c)
    32  	if err != nil {
    33  		return nil, err
    34  	}
    35  	js, err := json.Marshal(c)
    36  	if err != nil {
    37  		return nil, err
    38  	}
    39  	return js, nil
    40  }
    41  
    42  // MustSortJSON is like SortJSON but panic if an error occurs, e.g., if
    43  // the passed JSON isn't valid.
    44  func MustSortJSON(toSortJSON []byte) []byte {
    45  	js, err := SortJSON(toSortJSON)
    46  	if err != nil {
    47  		panic(err)
    48  	}
    49  	return js
    50  }
    51  
    52  // Uint64ToBigEndian - marshals uint64 to a bigendian byte slice so it can be sorted
    53  func Uint64ToBigEndian(i uint64) []byte {
    54  	b := make([]byte, 8)
    55  	binary.BigEndian.PutUint64(b, i)
    56  	return b
    57  }
    58  
    59  // BigEndianToUint64 returns an uint64 from big endian encoded bytes. If encoding
    60  // is empty, zero is returned.
    61  func BigEndianToUint64(bz []byte) uint64 {
    62  	if len(bz) == 0 {
    63  		return 0
    64  	}
    65  
    66  	return binary.BigEndian.Uint64(bz)
    67  }
    68  
    69  // Slight modification of the RFC3339Nano but it right pads all zeros and drops the time zone info
    70  const SortableTimeFormat = "2006-01-02T15:04:05.000000000"
    71  
    72  // Formats a time.Time into a []byte that can be sorted
    73  func FormatTimeBytes(t time.Time) []byte {
    74  	return []byte(t.UTC().Round(0).Format(SortableTimeFormat))
    75  }
    76  
    77  // Parses a []byte encoded using FormatTimeKey back into a time.Time
    78  func ParseTimeBytes(bz []byte) (time.Time, error) {
    79  	str := string(bz)
    80  	t, err := time.Parse(SortableTimeFormat, str)
    81  	if err != nil {
    82  		return t, err
    83  	}
    84  	return t.UTC().Round(0), nil
    85  }
    86  
    87  // NewLevelDB instantiate a new LevelDB instance according to DBBackend.
    88  func NewLevelDB(name, dir string) (db dbm.DB, err error) {
    89  	defer func() {
    90  		if r := recover(); r != nil {
    91  			err = fmt.Errorf("couldn't create db: %v", r)
    92  		}
    93  	}()
    94  
    95  	return dbm.NewDB(name, backend, dir)
    96  }
    97  
    98  // copy bytes
    99  func CopyBytes(bz []byte) (ret []byte) {
   100  	if bz == nil {
   101  		return nil
   102  	}
   103  	ret = make([]byte, len(bz))
   104  	copy(ret, bz)
   105  	return ret
   106  }