This repository has been archived by the owner on Aug 27, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 27
/
merkle.go
292 lines (256 loc) · 9.57 KB
/
merkle.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
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
// Copyright (c) 2017-2018 The qitmeer developers
package merkle
import (
"fmt"
"github.com/Qitmeer/qitmeer/common/hash"
"github.com/Qitmeer/qitmeer/core/types"
"math"
)
//TODO refactoing the merkle root calculation to support abstract merkle node
func CalcMerkleRoot(txns []*types.Transaction) *hash.Hash {
root := calcMerkleRoot(txns)
return &root
}
// buildMerkleTreeStore creates a merkle tree from a slice of transactions,
// stores it using a linear array, and returns a slice of the backing array. A
// linear array was chosen as opposed to an actual tree structure since it uses
// about half as much memory. The following describes a merkle tree and how it
// is stored in a linear array.
//
// A merkle tree is a tree in which every non-leaf node is the hash of its
// children nodes. A diagram depicting how this works for transactions
// where h(x) is a blake256 hash follows:
//
// root = h1234 = h(h12 + h34)
// / \
// h12 = h(h1 + h2) h34 = h(h3 + h4)
// / \ / \
// h1 = h(tx1) h2 = h(tx2) h3 = h(tx3) h4 = h(tx4)
//
// The above stored as a linear array is as follows:
//
// [h1 h2 h3 h4 h12 h34 root]
//
// As the above shows, the merkle root is always the last element in the array.
//
// The number of inputs is not always a power of two which results in a
// balanced tree structure as above. In that case, parent nodes with no
// children are also zero and parent nodes with only a single left node
// are calculated by concatenating the left node with itself before hashing.
// Since this function uses nodes that are pointers to the hashes, empty nodes
// will be nil.
func BuildMerkleTreeStore(transactions []*types.Tx, witness bool) []*hash.Hash {
// If there's an empty stake tree, return totally zeroed out merkle tree root
// only.
if len(transactions) == 0 {
merkles := make([]*hash.Hash, 1)
merkles[0] = &hash.Hash{}
return merkles
}
// Calculate how many entries are required to hold the binary merkle
// tree as a linear array and create an array of that size.
nextPoT := nextPowerOfTwo(len(transactions))
arraySize := nextPoT*2 - 1
merkles := make([]*hash.Hash, arraySize)
// Create the base transaction hashes and populate the array with them.
for i, tx := range transactions {
switch {
case witness && i == 0:
merkles[i] = &hash.ZeroHash
case witness:
wSha := tx.Tx.TxHashFull()
merkles[i] = &wSha
default:
txH := tx.Tx.TxHash()
merkles[i] = &txH
}
}
// Start the array offset after the last transaction and adjusted to the
// next power of two.
offset := nextPoT
for i := 0; i < arraySize-1; i += 2 {
switch {
// When there is no left child node, the parent is nil too.
case merkles[i] == nil:
merkles[offset] = nil
// When there is no right child, the parent is generated by
// hashing the concatenation of the left child with itself.
case merkles[i+1] == nil:
newHash := HashMerkleBranches(merkles[i], merkles[i])
merkles[offset] = newHash
// The normal case sets the parent node to the hash of the
// concatentation of the left and right children.
default:
newHash := HashMerkleBranches(merkles[i], merkles[i+1])
merkles[offset] = newHash
}
offset++
}
return merkles
}
// calcMerkleRoot creates a merkle tree from the slice of transactions and
// returns the root of the tree.
func calcMerkleRoot(txns []*types.Transaction) hash.Hash {
utilTxns := make([]*types.Tx, 0, len(txns))
for _, tx := range txns {
utilTxns = append(utilTxns, types.NewTx(tx))
}
merkles := BuildMerkleTreeStore(utilTxns, false)
return *merkles[len(merkles)-1]
}
// HashMerkleBranches takes two hashes, treated as the left and right tree
// nodes, and returns the hash of their concatenation. This is a helper
// function used to aid in the generation of a merkle tree.
func HashMerkleBranches(left *hash.Hash, right *hash.Hash) *hash.Hash {
// Concatenate the left and right nodes.
var h [hash.HashSize * 2]byte
copy(h[:hash.HashSize], left[:])
copy(h[hash.HashSize:], right[:])
// TODO, add an abstract layer of hash func
// TODO, double sha256 or other crypto hash
newHash := hash.DoubleHashH(h[:])
return &newHash
}
// nextPowerOfTwo returns the next highest power of two from a given number if
// it is not already a power of two. This is a helper function used during the
// calculation of a merkle tree.
func nextPowerOfTwo(n int) int {
// Return the number if it's already a power of 2.
if n&(n-1) == 0 {
return n
}
// Figure out and return the next power of two.
exponent := uint(math.Log2(float64(n))) + 1
return 1 << exponent // 2^exponent
}
// BuildParentsMerkleTreeStore creates a merkle tree from a slice of block parents,
// stores it using a linear array, and returns a slice of the backing array. A
// linear array was chosen as opposed to an actual tree structure since it uses
// about half as much memory. The following describes a merkle tree and how it
// is stored in a linear array.
//
// A merkle tree is a tree in which every non-leaf node is the hash of its
// children nodes. A diagram depicting how this works for block parents
// where h(x) is a blake256 hash follows:
//
// root = h1234 = h(h12 + h34)
// / \
// h12 = h(h1 + h2) h34 = h(h3 + h4)
// / \ / \
// h1 = h(tx1) h2 = h(tx2) h3 = h(tx3) h4 = h(tx4)
//
// The above stored as a linear array is as follows:
//
// [h1 h2 h3 h4 h12 h34 root]
//
// As the above shows, the merkle root is always the last element in the array.
//
// The number of inputs is not always a power of two which results in a
// balanced tree structure as above. In that case, parent nodes with no
// children are also zero and parent nodes with only a single left node
// are calculated by concatenating the left node with itself before hashing.
// Since this function uses nodes that are pointers to the hashes, empty nodes
// will be nil.
func BuildParentsMerkleTreeStore(parents []*hash.Hash) []*hash.Hash {
// If there's an empty stake tree, return totally zeroed out merkle tree root
// only.
if len(parents) == 0 {
merkles := make([]*hash.Hash, 1)
merkles[0] = &hash.Hash{}
return merkles
}
// Calculate how many entries are required to hold the binary merkle
// tree as a linear array and create an array of that size.
nextPoT := nextPowerOfTwo(len(parents))
arraySize := nextPoT*2 - 1
merkles := make([]*hash.Hash, arraySize)
// Populate the array with hashs.
copy(merkles, parents)
// Start the array offset after the last parent and adjusted to the
// next power of two.
offset := nextPoT
for i := 0; i < arraySize-1; i += 2 {
switch {
// When there is no left child node, the parent is nil too.
case merkles[i] == nil:
merkles[offset] = nil
// When there is no right child, the parent is generated by
// hashing the concatenation of the left child with itself.
case merkles[i+1] == nil:
newHash := HashMerkleBranches(merkles[i], merkles[i])
merkles[offset] = newHash
// The normal case sets the parent node to the hash of the
// concatentation of the left and right children.
default:
newHash := HashMerkleBranches(merkles[i], merkles[i+1])
merkles[offset] = newHash
}
offset++
}
return merkles
}
func ValidateWitnessCommitment(blk *types.SerializedBlock) error {
if len(blk.Transactions()) == 0 {
str := "cannot validate witness commitment of block without " +
"transactions"
return fmt.Errorf(str)
}
coinbaseTx := blk.Transactions()[0]
if len(coinbaseTx.Tx.TxIn) == 0 {
return fmt.Errorf("transaction has no inputs")
}
witnessCommitment := coinbaseTx.Tx.TxIn[0].PreviousOut.Hash
if witnessCommitment.IsEqual(&hash.ZeroHash) {
return fmt.Errorf("Coinbase inputs has no witness commitment")
}
coinbase := coinbaseTx.Tx.TxIn[0].SignScript
witnessMerkleTree := BuildMerkleTreeStore(blk.Transactions(), true)
witnessMerkleRoot := witnessMerkleTree[len(witnessMerkleTree)-1]
witnessPreimage := append(witnessMerkleRoot.Bytes(), coinbase...)
computedCommitment := hash.DoubleHashH(witnessPreimage[:])
if !computedCommitment.IsEqual(&witnessCommitment) {
str := fmt.Sprintf("witness commitment does not match: "+
"computed %s, coinbase includes %s", computedCommitment,
witnessCommitment)
return fmt.Errorf(str)
}
return nil
}
func BuildTokenBalanceMerkleTreeStore(balance []*hash.Hash) []*hash.Hash {
// If there's an empty stake tree, return totally zeroed out merkle tree root
// only.
if len(balance) == 0 {
merkles := make([]*hash.Hash, 1)
merkles[0] = &hash.Hash{}
return merkles
}
// Calculate how many entries are required to hold the binary merkle
// tree as a linear array and create an array of that size.
nextPoT := nextPowerOfTwo(len(balance))
arraySize := nextPoT*2 - 1
merkles := make([]*hash.Hash, arraySize)
// Populate the array with hashs.
copy(merkles, balance)
// Start the array offset after the last parent and adjusted to the
// next power of two.
offset := nextPoT
for i := 0; i < arraySize-1; i += 2 {
switch {
// When there is no left child node, the parent is nil too.
case merkles[i] == nil:
merkles[offset] = nil
// When there is no right child, the parent is generated by
// hashing the concatenation of the left child with itself.
case merkles[i+1] == nil:
newHash := HashMerkleBranches(merkles[i], merkles[i])
merkles[offset] = newHash
// The normal case sets the parent node to the hash of the
// concatentation of the left and right children.
default:
newHash := HashMerkleBranches(merkles[i], merkles[i+1])
merkles[offset] = newHash
}
offset++
}
return merkles
}