forked from aergoio/aergo
-
Notifications
You must be signed in to change notification settings - Fork 0
/
state.go
178 lines (150 loc) · 3.78 KB
/
state.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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
package types
import (
"bytes"
"fmt"
"math/big"
"reflect"
"github.com/aergoio/aergo/internal/common"
"github.com/aergoio/aergo/internal/enc"
)
const (
HashIDLength = 32
)
// HashID is a fixed size bytes
type HashID [HashIDLength]byte
// BlockID is a HashID to identify a block
type BlockID HashID
// AccountID is a HashID to identify an account
type AccountID HashID
// TxID is a HashID to identify a transaction
type TxID HashID
// ImplHashID is a object has HashID
type ImplHashID interface {
HashID() HashID
}
// ImplHashBytes is a object supports Hash
type ImplHashBytes interface {
Hash() []byte
}
// ImplMarshal is a object has marshal interface
type ImplMarshal interface {
Marshal() ([]byte, error)
}
var (
emptyHashID = HashID{}
)
// GetHashID make a HashID from hash of bytes
func GetHashID(bytes ...[]byte) HashID {
hash := common.Hasher(bytes...)
return ToHashID(hash)
}
// ToHashID make a HashID from bytes
func ToHashID(hash []byte) HashID {
buf := HashID{}
copy(buf[:], hash)
return HashID(buf)
}
func (id HashID) String() string {
return enc.ToString(id[:])
}
// Bytes make a byte slice from id
func (id HashID) Bytes() []byte {
if id == emptyHashID {
return nil
}
return id[:]
}
// Compare returns an integer comparing two HashIDs as byte slices.
func (id HashID) Compare(alt HashID) int {
return bytes.Compare(id.Bytes(), alt.Bytes())
}
// Equal returns a boolean comparing two HashIDs as byte slices.
func (id HashID) Equal(alt HashID) bool {
return bytes.Equal(id.Bytes(), alt.Bytes())
}
// ParseToTxID parse BlockID from bytes. it return error if length of parameter is not fit.
func ParseToBlockID(blockHash []byte) (BlockID, error) {
var hash BlockID
if len(blockHash) != HashIDLength {
return hash, fmt.Errorf("parse error: invalid length")
}
copy(hash[:], blockHash)
return hash, nil
}
// MustParseBlockID parse, it panics if parsing is failed.
func MustParseBlockID(blockHash []byte) BlockID {
hash, err := ParseToBlockID(blockHash)
if err != nil {
panic(err)
}
return hash
}
// ToBlockID make a BlockID from bytes
func ToBlockID(blockHash []byte) BlockID {
return BlockID(ToHashID(blockHash))
}
func (id BlockID) String() string {
return HashID(id).String()
}
// ParseToTxID parse TxID from bytes. it return error if length of parameter is not fit.
func ParseToTxID(txHash []byte) (TxID, error) {
var hash TxID
if len(txHash) != HashIDLength {
return hash, fmt.Errorf("parse error: invalid length")
}
return ToTxID(txHash), nil
}
// ToTxID make a TxID from bytes
func ToTxID(txHash []byte) TxID {
return TxID(ToHashID(txHash))
}
func (id TxID) String() string {
return HashID(id).String()
}
// ToAccountID make a AccountHash from bytes
func ToAccountID(account []byte) AccountID {
return AccountID(GetHashID(account))
}
func (id AccountID) String() string {
return HashID(id).String()
}
// NewState returns an instance of account state
func NewState() *State {
return &State{
Nonce: 0,
Balance: []byte{0},
SqlRecoveryPoint: uint64(1),
}
}
// func (st *State) IsEmpty() bool {
// return st.Nonce == 0 && st.Balance == 0
// }
// func (st *State) GetHash() []byte {
// digest := sha256.New()
// binary.Write(digest, binary.LittleEndian, st.Nonce)
// binary.Write(digest, binary.LittleEndian, st.Balance)
// return digest.Sum(nil)
// }
// func (st *State) Clone() *State {
// if st == nil {
// return nil
// }
// return &State{
// Nonce: st.Nonce,
// Balance: st.Balance,
// CodeHash: st.CodeHash,
// StorageRoot: st.StorageRoot,
// }
// }
func Clone(i interface{}) interface{} {
if i == nil {
return nil
}
return reflect.Indirect(reflect.ValueOf(i)).Interface()
}
func (st *State) GetBalanceBigInt() *big.Int {
if st == nil {
return new(big.Int).SetUint64(0)
}
return new(big.Int).SetBytes(st.Balance)
}