github.com/quantosnetwork/Quantos@v0.0.0-20220306172517-e20b28c5a29a/merkle/trie.go (about) 1 package merkle 2 3 import ( 4 "encoding/hex" 5 "encoding/json" 6 "fmt" 7 "github.com/davecgh/go-spew/spew" 8 "github.com/zeebo/blake3" 9 "go.uber.org/atomic" 10 "log" 11 "strings" 12 "sync" 13 "time" 14 ) 15 16 /* 17 18 @dev Info about the merkle trie structure 19 20 Blake3 Merkle tree (sum512) 21 Leaf size: 128 [64]bytes 22 Root size: 128 [64]bytes 23 MergeLeaf size: 256 [128]bytes 24 25 ML = MergeLeaf (Node hash) 26 C = count 27 L = Leaf 28 mr merkle root 29 H = Blake3 hasher sum 512 30 ++ = all of that type 31 32 f(mr) = H SUM(ML++) 33 ML = (LH[1] + LH[2]) 34 LH = H(L) 35 36 */ 37 38 type Hash [64]byte 39 40 type MerkleTrie interface { 41 Get(key []byte) ([]byte, bool) 42 Put(key []byte, value []byte) 43 Del(key []byte, value []byte) bool 44 } 45 46 type treeBuilder struct { 47 treeContents []TreeContent 48 size int 49 height int 50 leavesTotal int 51 state TreeStates 52 } 53 54 type TreeContent [][]byte 55 56 type Tree struct { 57 MerkleRoot []byte 58 TrunkRoots [][]byte 59 TreeHash []byte 60 Branches map[int]*branch 61 Hashable 62 } 63 64 type branch struct { 65 // a branch can have multiple branches attached to it before there are leaves 66 hasChildren bool 67 hasParent bool 68 multipleBranches []*branch 69 childCount atomic.Bool 70 leftLeaf *TreeLeaf 71 rightLeaf *TreeLeaf 72 // in real life that would be the length of the branch 73 byteLen int 74 Hashable 75 } 76 77 type TreeLeaf struct { 78 parentBranch *branch 79 80 content TreeContent 81 context string 82 Hashable 83 } 84 85 func (tc TreeContent) hash() Hash { 86 b := tc.Bytes() 87 return hashFn(b) 88 } 89 90 func (tc TreeContent) Bytes() []byte { 91 b, _ := json.Marshal(tc) 92 return b 93 } 94 95 type Hashable interface { 96 hash() Hash 97 } 98 99 type EmptyLeaf struct { 100 } 101 102 func (e EmptyLeaf) hash() Hash { 103 return hashFn(nil) 104 } 105 106 func (b *branch) hash() Hash { 107 var l, r [64]byte 108 l = b.leftLeaf.hash() 109 r = b.rightLeaf.hash() 110 return hashFn(append(l[:], r[:]...)) 111 } 112 113 func (l *TreeLeaf) hash() Hash { 114 return hashFn(l.content.Bytes()) 115 } 116 117 func hashFn(data []byte) Hash { 118 return blake3.Sum512(data) 119 } 120 121 func (h Hash) String() string { 122 return hex.EncodeToString(h[:]) 123 } 124 125 func NewTree(contents []TreeContent) { 126 127 tree := &Tree{} 128 c := make([]TreeContent, len(contents)) 129 copy(c, contents) 130 131 tree.Branches = map[int]*branch{} 132 b := tree.newBuilder(c) 133 b._prepare(tree) 134 if b.state == DONE { 135 fmt.Printf("merkle trie done: %v", tree) 136 } 137 hashes := tree.Walk() 138 mr := tree.hashMerkleRoot(hashes) 139 log.Printf("tree merkle root: %v", hex.EncodeToString(mr)) 140 141 } 142 143 func (m *Tree) newBuilder(contents []TreeContent) *treeBuilder { 144 builder := &treeBuilder{} 145 builder.height = 0 146 builder.state = 0 147 builder.size = 0 148 builder.leavesTotal = 0 149 builder.treeContents = contents 150 return builder 151 } 152 153 func (m *Tree) Build(contents []Hashable) { 154 155 } 156 157 func (m *Tree) Put(key []byte, value []byte) {} 158 func (m *Tree) Get(key []byte) ([]byte, bool) { 159 return nil, false 160 } 161 func (m *Tree) Del(key []byte, value []byte) bool { 162 return false 163 } 164 165 type TreeStates int 166 167 const ( 168 NONE TreeStates = iota 169 WORKING 170 DONE 171 ERRORED 172 IDLE 173 VERIFIED 174 ARCHIVED 175 ARCHIVING 176 SNAPSHOT 177 WALKING 178 HASHING 179 ) 180 181 func (tb *treeBuilder) _prepare(m *Tree) { 182 183 tb.state = IDLE 184 // contentLen := len(tb.treeContents) 185 for i := range tb.treeContents { 186 tb.state = WORKING 187 tb._addSingleBranch(m) 188 // now we get the height to add the leaves 189 height := tb.height - 1 190 if height < len(tb.treeContents)-1 { 191 tb._addLeaves(m, height, tb.treeContents[i], tb.treeContents[i+1]) 192 } else { 193 tb._addLeaves(m, height, tb.treeContents[i], tb.treeContents[i-1]) 194 } 195 } 196 tb.state = DONE 197 } 198 199 func (tb *treeBuilder) _addSingleBranch(m *Tree) { 200 branch := &branch{} 201 branch.hasChildren = false 202 branch.hasParent = false 203 branch.leftLeaf = new(TreeLeaf) 204 branch.rightLeaf = new(TreeLeaf) 205 206 m.Branches[tb.height] = branch 207 tb.height++ 208 } 209 210 func (tb *treeBuilder) _addLeaves(m *Tree, height int, left, right Hashable) { 211 m.Branches[height].leftLeaf = new(TreeLeaf) 212 m.Branches[height].leftLeaf.content = left.(TreeContent) 213 m.Branches[height].rightLeaf = new(TreeLeaf) 214 m.Branches[height].rightLeaf.content = right.(TreeContent) 215 216 } 217 218 func (t *Tree) Print() { 219 220 merkleRoot := t.hash() 221 fmt.Println(merkleRoot) 222 223 } 224 225 func (t *Tree) hash() Hash { 226 return Hash{} 227 } 228 229 type treeWalkFunction = func(b *branch, h func([]byte)) 230 231 var TreeReceipt []byte 232 233 func (t *Tree) Walk() []map[int][]string { 234 branches := t.Branches 235 state := IDLE 236 //height := 0 237 var hashes []map[int][]string 238 hashes = make([]map[int][]string, len(branches)) 239 for i := 0; i < len(branches); i++ { 240 state = WALKING 241 //height = i 242 branch := branches[i] 243 244 state = HASHING 245 left := branch.leftLeaf.hash() 246 right := branch.rightLeaf.hash() 247 248 leaves := map[int][]string{} 249 leaves[0] = []string{left.String(), right.String()} 250 hashes = append(hashes, leaves) 251 /*hashes[height][0] = left.String() 252 hashes[height][1] = right.String()*/ 253 254 } 255 256 state = DONE 257 258 if state == DONE { 259 return hashes 260 } 261 return t.Walk() 262 //return nil 263 } 264 265 func (t *Tree) hashMerkleRoot(hashes []map[int][]string) []byte { 266 267 var mu sync.Mutex 268 269 root := &struct { 270 height int 271 timestamp int64 272 hash []byte 273 String string 274 }{} 275 276 hasher := blake3.New() 277 // hasher.Reset() 278 279 root.height = 0 280 root.timestamp = time.Now().UnixNano() 281 hs := make([][]byte, len(hashes)) 282 mu.Lock() 283 defer mu.Unlock() 284 for i := 0; i < len(hashes)-1; i++ { 285 286 toJoin := hashes[i][0] 287 hsj := strings.Join(toJoin, "") 288 289 if hsj != "" { 290 spew.Dump(hsj) 291 hs[i] = []byte(hsj) 292 hasher.Write(hs[i]) 293 root.height += i 294 } 295 } 296 rhash := blake3.Sum512(hasher.Sum(nil)) 297 root.hash = rhash[:] 298 root.String = hex.EncodeToString(root.hash) 299 300 t.MerkleRoot = root.hash 301 return t.MerkleRoot 302 }