github.com/lbryio/lbcd@v0.22.119/claimtrie/merkletrie/merkletrie.go (about) 1 package merkletrie 2 3 import ( 4 "bytes" 5 "fmt" 6 "runtime" 7 "sort" 8 "sync" 9 10 "github.com/pkg/errors" 11 12 "github.com/lbryio/lbcd/chaincfg/chainhash" 13 "github.com/lbryio/lbcd/claimtrie/node" 14 ) 15 16 var ( 17 // EmptyTrieHash represents the Merkle Hash of an empty PersistentTrie. 18 // "0000000000000000000000000000000000000000000000000000000000000001" 19 EmptyTrieHash = &chainhash.Hash{1} 20 NoChildrenHash = &chainhash.Hash{2} 21 NoClaimsHash = &chainhash.Hash{3} 22 ) 23 24 // PersistentTrie implements a 256-way prefix tree. 25 type PersistentTrie struct { 26 repo Repo 27 28 root *vertex 29 bufs *sync.Pool 30 } 31 32 // NewPersistentTrie returns a PersistentTrie. 33 func NewPersistentTrie(repo Repo) *PersistentTrie { 34 35 tr := &PersistentTrie{ 36 repo: repo, 37 bufs: &sync.Pool{ 38 New: func() interface{} { 39 return new(bytes.Buffer) 40 }, 41 }, 42 root: newVertex(EmptyTrieHash), 43 } 44 45 return tr 46 } 47 48 // SetRoot drops all resolved nodes in the PersistentTrie, and set the Root with specified hash. 49 func (t *PersistentTrie) SetRoot(h *chainhash.Hash) error { 50 t.root = newVertex(h) 51 runtime.GC() 52 return nil 53 } 54 55 // Update updates the nodes along the path to the key. 56 // Each node is resolved or created with their Hash cleared. 57 func (t *PersistentTrie) Update(name []byte, hash *chainhash.Hash, restoreChildren bool) { 58 59 n := t.root 60 for i, ch := range name { 61 if restoreChildren && len(n.childLinks) == 0 { 62 t.resolveChildLinks(n, name[:i]) 63 } 64 if n.childLinks[ch] == nil { 65 n.childLinks[ch] = newVertex(nil) 66 } 67 n.merkleHash = nil 68 n = n.childLinks[ch] 69 } 70 71 if restoreChildren && len(n.childLinks) == 0 { 72 t.resolveChildLinks(n, name) 73 } 74 n.merkleHash = nil 75 n.claimsHash = hash 76 } 77 78 // resolveChildLinks updates the links on n 79 func (t *PersistentTrie) resolveChildLinks(n *vertex, key []byte) { 80 81 if n.merkleHash == nil { 82 return 83 } 84 85 b := t.bufs.Get().(*bytes.Buffer) 86 defer t.bufs.Put(b) 87 b.Reset() 88 b.Write(key) 89 b.Write(n.merkleHash[:]) 90 91 result, closer, err := t.repo.Get(b.Bytes()) 92 if result == nil { 93 return 94 } else if err != nil { 95 panic(err) 96 } 97 defer closer.Close() 98 99 nb := nbuf(result) 100 _, n.claimsHash = nb.hasValue() 101 for i := 0; i < nb.entries(); i++ { 102 p, h := nb.entry(i) 103 n.childLinks[p] = newVertex(h) 104 } 105 } 106 107 // MerkleHash returns the Merkle Hash of the PersistentTrie. 108 // All nodes must have been resolved before calling this function. 109 func (t *PersistentTrie) MerkleHash() *chainhash.Hash { 110 buf := make([]byte, 0, 256) 111 if h := t.merkle(buf, t.root); h == nil { 112 return EmptyTrieHash 113 } 114 return t.root.merkleHash 115 } 116 117 // merkle recursively resolves the hashes of the node. 118 // All nodes must have been resolved before calling this function. 119 func (t *PersistentTrie) merkle(prefix []byte, v *vertex) *chainhash.Hash { 120 if v.merkleHash != nil { 121 return v.merkleHash 122 } 123 124 b := t.bufs.Get().(*bytes.Buffer) 125 defer t.bufs.Put(b) 126 b.Reset() 127 128 keys := keysInOrder(v) 129 130 for _, ch := range keys { 131 child := v.childLinks[ch] 132 if child == nil { 133 continue 134 } 135 p := append(prefix, ch) 136 h := t.merkle(p, child) 137 if h != nil { 138 b.WriteByte(ch) // nolint : errchk 139 b.Write(h[:]) // nolint : errchk 140 } 141 if h == nil || len(prefix) > 4 { // TODO: determine the right number here 142 delete(v.childLinks, ch) // keep the RAM down (they get recreated on Update) 143 } 144 } 145 146 if v.claimsHash != nil { 147 b.Write(v.claimsHash[:]) 148 } 149 150 if b.Len() > 0 { 151 h := chainhash.DoubleHashH(b.Bytes()) 152 v.merkleHash = &h 153 t.repo.Set(append(prefix, h[:]...), b.Bytes()) 154 } 155 156 return v.merkleHash 157 } 158 159 func keysInOrder(v *vertex) []byte { 160 keys := make([]byte, 0, len(v.childLinks)) 161 for key := range v.childLinks { 162 keys = append(keys, key) 163 } 164 sort.Slice(keys, func(i, j int) bool { return keys[i] < keys[j] }) 165 return keys 166 } 167 168 func (t *PersistentTrie) MerkleHashAllClaims() *chainhash.Hash { 169 buf := make([]byte, 0, 256) 170 if h := t.merkleAllClaims(buf, t.root); h == nil { 171 return EmptyTrieHash 172 } 173 return t.root.merkleHash 174 } 175 176 func (t *PersistentTrie) merkleAllClaims(prefix []byte, v *vertex) *chainhash.Hash { 177 if v.merkleHash != nil { 178 return v.merkleHash 179 } 180 b := t.bufs.Get().(*bytes.Buffer) 181 defer t.bufs.Put(b) 182 b.Reset() 183 184 keys := keysInOrder(v) 185 childHashes := make([]*chainhash.Hash, 0, len(keys)) 186 for _, ch := range keys { 187 n := v.childLinks[ch] 188 if n == nil { 189 continue 190 } 191 p := append(prefix, ch) 192 h := t.merkleAllClaims(p, n) 193 if h != nil { 194 childHashes = append(childHashes, h) 195 b.WriteByte(ch) // nolint : errchk 196 b.Write(h[:]) // nolint : errchk 197 } 198 if h == nil || len(prefix) > 4 { // TODO: determine the right number here 199 delete(v.childLinks, ch) // keep the RAM down (they get recreated on Update) 200 } 201 } 202 203 if len(childHashes) > 1 || v.claimsHash != nil { // yeah, about that 1 there -- old code used the condensed trie 204 left := NoChildrenHash 205 if len(childHashes) > 0 { 206 left = node.ComputeMerkleRoot(childHashes) 207 } 208 right := NoClaimsHash 209 if v.claimsHash != nil { 210 b.Write(v.claimsHash[:]) // for Has Value, nolint : errchk 211 right = v.claimsHash 212 } 213 214 h := node.HashMerkleBranches(left, right) 215 v.merkleHash = h 216 t.repo.Set(append(prefix, h[:]...), b.Bytes()) 217 } else if len(childHashes) == 1 { 218 v.merkleHash = childHashes[0] // pass it up the tree 219 t.repo.Set(append(prefix, v.merkleHash[:]...), b.Bytes()) 220 } 221 222 return v.merkleHash 223 } 224 225 func (t *PersistentTrie) Close() error { 226 return errors.WithStack(t.repo.Close()) 227 } 228 229 func (t *PersistentTrie) Dump(s string) { 230 // TODO: this function is in the wrong spot; either it goes with its caller or it needs to be a generic iterator 231 // we don't want fmt used in here either way 232 233 v := t.root 234 235 for i := 0; i < len(s); i++ { 236 t.resolveChildLinks(v, []byte(s[:i])) 237 ch := s[i] 238 v = v.childLinks[ch] 239 if v == nil { 240 fmt.Printf("Missing child at %s\n", s[:i+1]) 241 return 242 } 243 } 244 t.resolveChildLinks(v, []byte(s)) 245 246 fmt.Printf("Node hash: %s, has value: %t\n", v.merkleHash.String(), v.claimsHash != nil) 247 248 for key, value := range v.childLinks { 249 fmt.Printf(" Child %s hash: %s\n", string(key), value.merkleHash.String()) 250 } 251 } 252 253 func (t *PersistentTrie) Flush() error { 254 return t.repo.Flush() 255 }