forked from bandprotocol/bandchain
-
Notifications
You must be signed in to change notification settings - Fork 0
/
util.go
128 lines (114 loc) · 2.99 KB
/
util.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package proof
import (
"encoding/base64"
"encoding/binary"
"encoding/hex"
"reflect"
"strconv"
"time"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/tendermint/tendermint/crypto/tmhash"
)
// Copied from https://github.com/tendermint/tendermint/blob/master/types/utils.go
func cdcEncode(cdc *codec.Codec, item interface{}) []byte {
if item != nil && !isTypedNil(item) && !isEmpty(item) {
return cdc.MustMarshalBinaryBare(item)
}
return nil
}
// Go lacks a simple and safe way to see if something is a typed nil.
// See:
// - https://dave.cheney.net/2017/08/09/typed-nils-in-go-2
// - https://groups.google.com/forum/#!topic/golang-nuts/wnH302gBa4I/discussion
// - https://github.com/golang/go/issues/21538
func isTypedNil(o interface{}) bool {
rv := reflect.ValueOf(o)
switch rv.Kind() {
case reflect.Chan, reflect.Func, reflect.Map, reflect.Ptr, reflect.Slice:
return rv.IsNil()
default:
return false
}
}
// Returns true if it has zero length.
func isEmpty(o interface{}) bool {
rv := reflect.ValueOf(o)
switch rv.Kind() {
case reflect.Array, reflect.Chan, reflect.Map, reflect.Slice, reflect.String:
return rv.Len() == 0
default:
return false
}
}
func base64ToBytes(s string) []byte {
decodedString, err := base64.StdEncoding.DecodeString(s)
if err != nil {
panic(err)
}
return decodedString
}
func encodeStoreMerkleHash(key string, value []byte) []byte {
bytesKey := []byte(key)
keyBytes := append([]byte{uint8(len(bytesKey))}, bytesKey...)
valueBytes := append([]byte{32}, tmhash.Sum(tmhash.Sum(value))...)
return append(keyBytes, valueBytes...)
}
func encodeVarint(value int64) []byte {
buf := make([]byte, binary.MaxVarintLen64)
n := binary.PutVarint(buf, value)
return buf[:n]
}
func encodeUvarint(value uint64) []byte {
buf := make([]byte, binary.MaxVarintLen64)
n := binary.PutUvarint(buf, value)
return buf[:n]
}
func mustParseInt64(b []byte) int64 {
i64, err := strconv.ParseInt(string(b), 10, 64)
if err != nil {
panic(err)
}
return i64
}
func mustParseUint64(b []byte) uint64 {
u64, err := strconv.ParseUint(string(b), 10, 64)
if err != nil {
panic(err)
}
return u64
}
func mustDecodeString(hexstr string) []byte {
b, err := hex.DecodeString(hexstr)
if err != nil {
panic(err)
}
return b
}
func parseTime(str string) time.Time {
layout := "2006-01-02T15:04:05.000000000Z"
t, err := time.Parse(layout, str)
if err != nil {
panic(err)
}
return t
}
func encodeTime(t time.Time) []byte {
bz := []byte{}
s := t.Unix()
// skip if default/zero value:
if s != 0 {
bz = append(bz, encodeFieldNumberAndTyp3(1, 0)...)
bz = append(bz, encodeUvarint(uint64(s))...)
}
ns := int32(t.Nanosecond()) // this int64 -> int32 cast is safe (nanos are in [0, 999999999])
// skip if default/zero value:
if ns != 0 {
bz = append(bz, encodeFieldNumberAndTyp3(2, 0)...)
bz = append(bz, encodeUvarint(uint64(ns))...)
}
return bz
}
// Write field key.
func encodeFieldNumberAndTyp3(num uint32, typ uint8) []byte {
return encodeUvarint((uint64(num) << 3) | uint64(typ))
}