github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/merkletree2/tree.go (about) 1 package merkletree2 2 3 import ( 4 "bytes" 5 "fmt" 6 "sort" 7 "sync" 8 9 "github.com/keybase/client/go/logger" 10 "github.com/keybase/go-codec/codec" 11 ) 12 13 // Tree is the MerkleTree class; it needs an engine and a configuration 14 // to run 15 type Tree struct { 16 sync.RWMutex 17 18 cfg Config 19 eng StorageEngine 20 21 newRootVersion RootVersion 22 23 // step is an optimization parameter for GetKeyValuePairWithProof that 24 // controls how many path positions at a time the tree requests from the 25 // storage engine. Lower values result in more storage engine requests, but 26 // less of the (somewhat expensive) bit fiddling operations. Values higher 27 // than 63 are not recommended as the bit operations (in the best case) 28 // cannot be done using a single 64 bit word and become more expensive. This 29 // is unnecessary if the tree has random keys (as such a tree should be 30 // approximately balanced and have short-ish paths). 31 step int 32 33 // these two fields are used as buffers during tree building to avoid making 34 // many short lived memory allocations 35 bufKss KeySpecificSecret 36 bufLeaf Node 37 } 38 39 // NewTree makes a new tree 40 func NewTree(c Config, step int, e StorageEngine, v RootVersion) (*Tree, error) { 41 if c.UseBlindedValueHashes { 42 _, ok := e.(StorageEngineWithBlinding) 43 if !ok { 44 return nil, fmt.Errorf("The config requires a StorageEngineWithBlinding implementation as a StorageEngine") 45 } 46 } 47 if step < 1 { 48 return nil, fmt.Errorf("step must be a positive integer") 49 } 50 51 return &Tree{cfg: c, eng: e, step: step, newRootVersion: v}, nil 52 } 53 54 // Hash is a byte-array, used to represent a full collision-resistant hash. 55 type Hash []byte 56 57 // Equal compares two hashes byte by byte 58 func (h Hash) Equal(h2 Hash) bool { 59 return bytes.Equal(h, h2) 60 } 61 62 // Key is a byte-array, and it is the type of the keys in the KeyValuePairs that 63 // the tree can store. 64 type Key []byte 65 66 // Equal compares two keys byte by byte 67 func (k Key) Equal(k2 Key) bool { 68 return bytes.Equal(k, k2) 69 } 70 71 // Cmp compares two keys lexicographically as byte slices 72 func (k Key) Cmp(k2 Key) int { 73 return bytes.Compare(k, k2) 74 } 75 76 // Seqno is an integer used to differentiate different versions of a merkle tree. 77 type Seqno int64 78 79 type SeqnoSortedAsInt []Seqno 80 81 func (d SeqnoSortedAsInt) Len() int { 82 return len(d) 83 } 84 85 func (d SeqnoSortedAsInt) Swap(i, j int) { 86 d[i], d[j] = d[j], d[i] 87 } 88 89 func (d SeqnoSortedAsInt) Less(i, j int) bool { 90 return d[i] < d[j] 91 } 92 93 // ChildIndex specifies one of an iNode's child nodes. 94 type ChildIndex int 95 96 // KeyValuePair is something the merkle tree can store. The key can be something 97 // like a UID or a TLF ID. The Value is a generic interface, so you can store 98 // anything there, as long as it obeys Msgpack-decoding behavior. The Value must 99 // be of the same type returned by ValueConstructor in the TreeConfig, otherwise 100 // the behavior is undefined. 101 type KeyValuePair struct { 102 _struct struct{} `codec:",toarray"` //nolint 103 Key Key `codec:"k"` 104 Value interface{} `codec:"v"` 105 } 106 107 type EncodedValue []byte 108 109 func (e EncodedValue) Equal(e2 EncodedValue) bool { 110 return bytes.Equal(e, e2) 111 } 112 113 // KeyEncodedValuePair is similar to a KeyValuePair, but the values is encoded 114 // as a byte slice. 115 type KeyEncodedValuePair struct { 116 _struct struct{} `codec:",toarray"` //nolint 117 Key Key `codec:"k"` 118 Value EncodedValue `codec:"v"` 119 } 120 121 type KeyHashPair struct { 122 _struct struct{} `codec:",toarray"` //nolint 123 Key Key `codec:"k"` 124 Hash Hash `codec:"h"` 125 } 126 127 // NodeType is used to distinguish serialized internal nodes from leaves in the tree 128 type NodeType uint8 129 130 const ( 131 NodeTypeNone NodeType = 0 132 NodeTypeINode NodeType = 1 133 NodeTypeLeaf NodeType = 2 134 ) 135 136 // A Node is either an internal node or a leaf: INodes and LeafHashes cannot 137 // both have length > 0 (else msgpack encoding will fail). 138 type Node struct { 139 INodes []Hash 140 LeafHashes []KeyHashPair 141 } 142 143 var _ codec.Selfer = &Node{} 144 145 func (n *Node) CodecEncodeSelf(e *codec.Encoder) { 146 if n.INodes != nil && n.LeafHashes != nil && len(n.INodes) > 0 && len(n.LeafHashes) > 0 { 147 panic("Cannot Encode a node with both Inodes and LeafHashes") 148 } 149 150 if n.INodes != nil && len(n.INodes) > 0 { 151 e.MustEncode(NodeTypeINode) 152 e.MustEncode(n.INodes) 153 return 154 } 155 156 // Note: we encode empty nodes (with empty or nil LeafHashes) as leaf nodes. 157 // This is so we can represent a tree with no values as a single (empty) 158 // leaf node. 159 e.MustEncode(NodeTypeLeaf) 160 // encode empty slices and nil slices equally 161 if len(n.LeafHashes) == 0 { 162 e.MustEncode([]KeyHashPair(nil)) 163 } else { 164 e.MustEncode(n.LeafHashes) 165 } 166 } 167 168 func (n *Node) CodecDecodeSelf(d *codec.Decoder) { 169 var nodeType NodeType 170 d.MustDecode(&nodeType) 171 switch nodeType { 172 case NodeTypeINode: 173 d.MustDecode(&n.INodes) 174 case NodeTypeLeaf: 175 d.MustDecode(&n.LeafHashes) 176 default: 177 panic("Unrecognized NodeType") 178 } 179 } 180 181 type PositionHashPair struct { 182 _struct struct{} `codec:",toarray"` //nolint 183 Position Position `codec:"p"` 184 Hash Hash `codec:"h"` 185 } 186 187 type RootVersion uint8 188 189 const ( 190 RootVersionV1 RootVersion = 1 191 CurrentRootVersion RootVersion = RootVersionV1 192 ) 193 194 type RootMetadata struct { 195 _struct struct{} `codec:",toarray"` //nolint 196 RootVersion RootVersion 197 EncodingType EncodingType 198 Seqno Seqno 199 BareRootHash Hash 200 SkipPointersHash Hash 201 202 // AddOnsHash is the (currently empty) hash of a (not yet defined) data 203 // structure which will contain a map[string]Hash (or even 204 // map[string]interface{}) which can contain arbitrary values. This AddOn 205 // struct is not used in verifying proofs, and new elements can be added to 206 // this map without bumping the RootVersion. Clients are expected to ignore 207 // fields in this map which they do not understand. 208 AddOnsHash Hash 209 } 210 211 func (t *Tree) makeNextRootMetadata(ctx logger.ContextInterface, tr Transaction, curr *RootMetadata, newRootHash Hash, addOnsHash Hash) (RootMetadata, error) { 212 root := RootMetadata{ 213 RootVersion: t.newRootVersion, 214 EncodingType: t.cfg.Encoder.GetEncodingType(), 215 BareRootHash: newRootHash, 216 AddOnsHash: addOnsHash, 217 } 218 219 // If there is no previous root, we do not need to include any skips, so 220 // return early. 221 if curr == nil || curr.Seqno == 0 { 222 root.Seqno = 1 223 return root, nil 224 } 225 226 newSeqno := curr.Seqno + 1 227 skipSeqnos := SkipPointersForSeqno(newSeqno) 228 229 skips, err := t.eng.LookupRootHashes(ctx, tr, skipSeqnos) 230 if err != nil { 231 return RootMetadata{}, fmt.Errorf("makeNextRootMetadata: error retrieving previous hashes %+v: %v", skipSeqnos, err) 232 } 233 234 _, skipsHash, err := t.cfg.Encoder.EncodeAndHashGeneric(skips) 235 if err != nil { 236 return RootMetadata{}, fmt.Errorf("makeNextRootMetadata: error encoding %+v, err: %v", skips, err) 237 } 238 239 root.Seqno = curr.Seqno + 1 240 root.SkipPointersHash = skipsHash 241 242 return root, nil 243 } 244 245 func (t *Tree) GenerateAndStoreMasterSecret( 246 ctx logger.ContextInterface, tr Transaction, s Seqno) (ms MasterSecret, err error) { 247 ms, err = t.cfg.Encoder.GenerateMasterSecret(s) 248 if err != nil { 249 return nil, err 250 } 251 err = t.eng.(StorageEngineWithBlinding).StoreMasterSecret(ctx, tr, s, ms) 252 if err != nil { 253 return nil, err 254 } 255 return ms, nil 256 } 257 258 func (t *Tree) encodeKVPairs(sortedKVPairs []KeyValuePair) (kevPairs []KeyEncodedValuePair, err error) { 259 kevPairs = make([]KeyEncodedValuePair, len(sortedKVPairs)) 260 for i, kvp := range sortedKVPairs { 261 v, err := t.cfg.Encoder.Encode(kvp.Value) 262 if err != nil { 263 return nil, err 264 } 265 kevPairs[i].Key = kvp.Key 266 kevPairs[i].Value = EncodedValue(v) 267 } 268 return kevPairs, nil 269 } 270 271 // Build builds a new tree version, taking a batch input. The 272 // sortedKeyValuePairs must be sorted (lexicographically) by Key. 273 // 274 // NOTE: The input to this function should contain at least all the keys which 275 // were inserted in previous versions of the tree, and each key should only 276 // appear once, otherwise this procedure will put the tree into an inconsistent 277 // state. This function does not check the condition is true for efficiency 278 // reasons. 279 func (t *Tree) Build( 280 ctx logger.ContextInterface, tr Transaction, sortedKVPairs []KeyValuePair, addOnsHash Hash) (s Seqno, rootHash Hash, err error) { 281 t.Lock() 282 defer t.Unlock() 283 284 latestSeqNo, rootMetadata, err := t.eng.LookupLatestRoot(ctx, tr) 285 switch err.(type) { 286 case nil: 287 case NoLatestRootFoundError: 288 ctx.Debug("No root found. Starting a new merkle tree.") 289 latestSeqNo = 0 290 rootMetadata = RootMetadata{} 291 default: 292 return 0, nil, err 293 } 294 295 newSeqno := latestSeqNo + 1 296 297 sortedKEVPairs, err := t.encodeKVPairs(sortedKVPairs) 298 if err != nil { 299 return 0, nil, err 300 } 301 302 if len(sortedKEVPairs) > 0 { 303 if err = t.eng.StoreKEVPairs(ctx, tr, newSeqno, sortedKEVPairs); err != nil { 304 return 0, nil, err 305 } 306 } 307 308 var ms MasterSecret 309 if t.cfg.UseBlindedValueHashes { 310 ms, err = t.GenerateAndStoreMasterSecret(ctx, tr, newSeqno) 311 if err != nil { 312 return 0, nil, err 313 } 314 } else { 315 ms = nil 316 } 317 318 var newBareRootHash Hash 319 if newBareRootHash, err = t.hashTreeRecursive(ctx, tr, newSeqno, ms, 320 t.cfg.GetRootPosition(), sortedKEVPairs); err != nil { 321 return 0, nil, err 322 } 323 324 newRootMetadata, err := t.makeNextRootMetadata(ctx, tr, &rootMetadata, newBareRootHash, addOnsHash) 325 if err != nil { 326 return 0, nil, err 327 } 328 329 _, newRootHash, err := t.cfg.Encoder.EncodeAndHashGeneric(newRootMetadata) 330 if err != nil { 331 return 0, nil, err 332 } 333 334 if err = t.eng.StoreRootMetadata(ctx, tr, newRootMetadata, newRootHash); err != nil { 335 return 0, nil, err 336 } 337 338 _, hash, err := t.cfg.Encoder.EncodeAndHashGeneric(newRootMetadata) 339 340 return newSeqno, hash, err 341 } 342 343 func (t *Tree) hashTreeRecursive(ctx logger.ContextInterface, tr Transaction, s Seqno, ms MasterSecret, 344 p *Position, sortedKEVPairs []KeyEncodedValuePair) (ret Hash, err error) { 345 select { 346 case <-ctx.Ctx().Done(): 347 return nil, ctx.Ctx().Err() 348 default: 349 } 350 351 if len(sortedKEVPairs) <= t.cfg.MaxValuesPerLeaf { 352 err = t.makeAndStoreLeaf(ctx, tr, s, ms, p, sortedKEVPairs, &ret) 353 return ret, err 354 } 355 356 node := Node{INodes: make([]Hash, t.cfg.ChildrenPerNode)} 357 358 pairsNotYetSelected := sortedKEVPairs 359 var nextChild *Position 360 for i, child := ChildIndex(0), t.cfg.GetChild(p, ChildIndex(0)); i < ChildIndex(t.cfg.ChildrenPerNode); i++ { 361 var end int 362 if i+1 < ChildIndex(t.cfg.ChildrenPerNode) { 363 nextChild = t.cfg.GetChild(p, i+1) 364 maxKey := t.cfg.getMinKey(nextChild) 365 366 end = sort.Search(len(pairsNotYetSelected), func(n int) bool { 367 return pairsNotYetSelected[n].Key.Cmp(maxKey) >= 0 368 }) 369 } else { 370 end = len(pairsNotYetSelected) 371 } 372 373 if end > 0 { 374 pairsSelected := pairsNotYetSelected[0:end] 375 pairsNotYetSelected = pairsNotYetSelected[end:] 376 node.INodes[i], err = t.hashTreeRecursive(ctx, tr, s, ms, child, pairsSelected) 377 if err != nil { 378 return nil, err 379 } 380 } 381 child = nextChild 382 } 383 if err = t.cfg.Encoder.HashGeneric(node, &ret); err != nil { 384 return nil, err 385 } 386 err = t.eng.StoreNode(ctx, tr, s, p, ret) 387 return ret, err 388 } 389 390 // makeKeyHashPairsFromKeyValuePairs preserves ordering 391 func (t *Tree) makeKeyHashPairsFromKeyValuePairs(ms MasterSecret, unhashed []KeyEncodedValuePair, node *Node) (err error) { 392 if cap(node.LeafHashes) < len(unhashed) { 393 node.LeafHashes = make([]KeyHashPair, len(unhashed)) 394 } 395 node.LeafHashes = node.LeafHashes[:len(unhashed)] 396 397 for i, kevp := range unhashed { 398 t.cfg.Encoder.ComputeKeySpecificSecretTo(ms, kevp.Key, &t.bufKss) 399 err = t.cfg.Encoder.HashKeyEncodedValuePairWithKeySpecificSecretTo(kevp, t.bufKss, &node.LeafHashes[i].Hash) 400 if err != nil { 401 return err 402 } 403 node.LeafHashes[i].Key = kevp.Key 404 } 405 return nil 406 } 407 408 func (t *Tree) makeAndStoreLeaf(ctx logger.ContextInterface, tr Transaction, s Seqno, ms MasterSecret, p *Position, sortedKEVPairs []KeyEncodedValuePair, ret *Hash) (err error) { 409 410 err = t.makeKeyHashPairsFromKeyValuePairs(ms, sortedKEVPairs, &t.bufLeaf) 411 if err != nil { 412 return err 413 } 414 415 if err = t.cfg.Encoder.HashGeneric(t.bufLeaf, ret); err != nil { 416 return err 417 } 418 if err = t.eng.StoreNode(ctx, tr, s, p, *ret); err != nil { 419 return err 420 } 421 return nil 422 } 423 424 // Retrieves a KeyValuePair from the tree. Note that if the root at Seqno s was 425 // not committed yet, there might be no proof for this pair yet (hence it is 426 // unsafe). 427 func (t *Tree) GetKeyValuePairUnsafe(ctx logger.ContextInterface, tr Transaction, s Seqno, k Key) (kvp KeyValuePair, err error) { 428 if s == 0 { 429 return KeyValuePair{}, NewInvalidSeqnoError(0, fmt.Errorf("No keys stored at Seqno 0")) 430 } 431 if len(k) != t.cfg.KeysByteLength { 432 return KeyValuePair{}, NewInvalidKeyError() 433 } 434 val, _, err := t.eng.LookupKEVPair(ctx, tr, s, k) 435 if err != nil { 436 return KeyValuePair{}, err 437 } 438 valContainer := t.cfg.ConstructValueContainer() 439 err = t.cfg.Encoder.Decode(&valContainer, val) 440 if err != nil { 441 return KeyValuePair{}, err 442 } 443 return KeyValuePair{Key: k, Value: valContainer}, nil 444 } 445 446 // Retrieves a KeyValuePair from the tree. Note that if the root at Seqno s was 447 // not committed yet, an InvalidSeqnoError is returned. 448 func (t *Tree) GetKeyValuePair(ctx logger.ContextInterface, tr Transaction, s Seqno, k Key) (KeyValuePair, error) { 449 // Checking the Seqno was committed. 450 _, err := t.eng.LookupRoot(ctx, tr, s) 451 if err != nil { 452 return KeyValuePair{}, err 453 } 454 455 return t.GetKeyValuePairUnsafe(ctx, tr, s, k) 456 } 457 458 // A MerkleInclusionProof proves that a specific key value pair is stored in a 459 // merkle tree, given the RootMetadata hash of such tree. It can also be used to 460 // prove that a specific key is not part of the tree (we call this an exclusion 461 // or absence proof) 462 type MerkleInclusionProof struct { 463 _struct struct{} `codec:",toarray"` //nolint 464 KeySpecificSecret KeySpecificSecret `codec:"k"` 465 // When this struct is used as an exclusion proof, OtherPairsInLeaf is set 466 // to nil if the proof ends at an internal node, and set to a slice of 467 // length 0 or more if the proof ends at a (possibly empty) leaf node. In 468 // particular, a tree with no keys is encoded with the root being the only 469 // (empty leaf) node. 470 OtherPairsInLeaf []KeyHashPair `codec:"l"` 471 // SiblingHashesOnPath are ordered by level from the farthest to the closest 472 // to the root, and lexicographically within each level. 473 SiblingHashesOnPath []Hash `codec:"s"` 474 RootMetadataNoHash RootMetadata `codec:"e"` 475 } 476 477 // A MerkleExtensionProof proves, given the RootMetadata hashes of two merkle 478 // trees and their respective Seqno values, that: - the two merkle trees have 479 // the expected Seqno values, - the most recent merkle tree "points back" to the 480 // least recent one through a chain of SkipPointers that refer to merkle trees 481 // at intermediate Seqnos. 482 type MerkleExtensionProof struct { 483 _struct struct{} `codec:",toarray"` //nolint 484 RootHashes []Hash `codec:"h"` 485 PreviousRootsNoSkips []RootMetadata `codec:"k"` 486 } 487 488 // An MerkleInclusionExtensionProof combines a MerkleInclusionProof and a 489 // MerkleExtensionProof. The redundant fields are deleted so that sending a 490 // combined proof is more efficient than sending both of them individually. 491 type MerkleInclusionExtensionProof struct { 492 _struct struct{} `codec:",toarray"` //nolint 493 MerkleInclusionProof MerkleInclusionProof 494 MerkleExtensionProof MerkleExtensionProof 495 } 496 497 // This type orders positionHashPairs by position, more specificelly first by 498 // level descending (nodes with higher level first) and then within each level 499 // in ascending order. This is the order required by the merkle proof verifier 500 // to easily reconstruct a path. 501 type PosHashPairsInMerkleProofOrder []PositionHashPair 502 503 func (p PosHashPairsInMerkleProofOrder) Len() int { 504 return len(p) 505 } 506 507 func (p PosHashPairsInMerkleProofOrder) Less(i, j int) bool { 508 return p[i].Position.CmpInMerkleProofOrder(&(p[j].Position)) < 0 509 } 510 511 func (p PosHashPairsInMerkleProofOrder) Swap(i, j int) { 512 p[i], p[j] = p[j], p[i] 513 } 514 515 var _ sort.Interface = PosHashPairsInMerkleProofOrder{} 516 517 // If the key is not in the tree at the root with the specified hash, this function returns a nil value, a proof 518 // which certifies that and no error. 519 func (t *Tree) GetEncodedValueWithInclusionOrExclusionProofFromRootHash(ctx logger.ContextInterface, tr Transaction, rootHash Hash, k Key) (val EncodedValue, proof MerkleInclusionProof, err error) { 520 // Lookup the appropriate root. 521 rootMetadata, err := t.eng.LookupRootFromHash(ctx, tr, rootHash) 522 if err != nil { 523 return nil, MerkleInclusionProof{}, err 524 } 525 return t.getEncodedValueWithInclusionProofOrExclusionProof(ctx, tr, rootMetadata, k) 526 } 527 528 // If the key is not in the tree at seqno s, this function returns a KeyNotFoundError and no absence proof. 529 func (t *Tree) GetEncodedValueWithInclusionProof(ctx logger.ContextInterface, tr Transaction, s Seqno, k Key) (val EncodedValue, proof MerkleInclusionProof, err error) { 530 // Lookup the appropriate root. 531 rootMetadata, err := t.eng.LookupRoot(ctx, tr, s) 532 if err != nil { 533 return nil, MerkleInclusionProof{}, err 534 } 535 val, proof, err = t.getEncodedValueWithInclusionProofOrExclusionProof(ctx, tr, rootMetadata, k) 536 if err != nil { 537 return nil, MerkleInclusionProof{}, err 538 } 539 if val == nil { 540 return nil, MerkleInclusionProof{}, NewKeyNotFoundError() 541 } 542 return val, proof, nil 543 } 544 545 // if the key is not in the tree, this function returns a nil value, a proof 546 // which certifies that and no error. 547 func (t *Tree) getEncodedValueWithInclusionProofOrExclusionProof(ctx logger.ContextInterface, tr Transaction, rootMetadata RootMetadata, k Key) (val EncodedValue, proof MerkleInclusionProof, err error) { 548 if len(k) != t.cfg.KeysByteLength { 549 return nil, MerkleInclusionProof{}, fmt.Errorf("The supplied key has the wrong length: exp %v, got %v", t.cfg.KeysByteLength, len(k)) 550 } 551 552 s := rootMetadata.Seqno 553 proof.RootMetadataNoHash = rootMetadata 554 // clear up hash to make the proof smaller. 555 proof.RootMetadataNoHash.BareRootHash = nil 556 557 var siblingPosHashPairs []PositionHashPair 558 needMore := true 559 for curr := 1; needMore && curr <= t.cfg.MaxDepth; curr += t.step + 1 { 560 // The first element is the position at level curr+step on the path from 561 // the root to k (on a complete tree). The next ones are all the 562 // necessary siblings at levels from curr+step to curr (both included) 563 // on such path. 564 deepestAndCurrSiblingPositions := t.cfg.getDeepestPositionAtLevelAndSiblingsOnPathToKey(k, curr+t.step, curr) 565 deepestAndCurrSiblings, err := t.eng.LookupNodes(ctx, tr, s, deepestAndCurrSiblingPositions) 566 if err != nil { 567 return nil, MerkleInclusionProof{}, err 568 } 569 570 sort.Sort(PosHashPairsInMerkleProofOrder(deepestAndCurrSiblings)) 571 572 var currSiblings []PositionHashPair 573 // if we found a PositionHashPair corrisponding to the first element in 574 // deepestAndCurrSiblingPositions, it means the path might be deeper and we 575 // need to fetch more siblings. 576 candidateDeepest := len(deepestAndCurrSiblings) 577 if len(deepestAndCurrSiblings) > 0 { 578 candidateDeepest = sort.Search(len(deepestAndCurrSiblings), func(i int) bool { 579 return deepestAndCurrSiblings[i].Position.CmpInMerkleProofOrder(&deepestAndCurrSiblingPositions[0]) >= 0 580 }) 581 } 582 if candidateDeepest < len(deepestAndCurrSiblings) && deepestAndCurrSiblings[candidateDeepest].Position.Equals(&deepestAndCurrSiblingPositions[0]) { 583 currSiblings = deepestAndCurrSiblings[:candidateDeepest] 584 currSiblings = append(currSiblings, deepestAndCurrSiblings[candidateDeepest+1:]...) 585 } else { 586 currSiblings = deepestAndCurrSiblings 587 needMore = false 588 } 589 siblingPosHashPairs = append(currSiblings, siblingPosHashPairs...) 590 } 591 592 var leafLevel int 593 if len(siblingPosHashPairs) == 0 { 594 // If there are no siblings, the key must be stored on the root 595 leafLevel = 0 596 } else { 597 // The level of the first sibling equals the level of the leaf node for the 598 // key we are producing the proof for. 599 leafLevel = t.cfg.getLevel(&(siblingPosHashPairs[0].Position)) 600 } 601 602 deepestPosition, err := t.cfg.getDeepestPositionForKey(k) 603 if err != nil { 604 return nil, MerkleInclusionProof{}, err 605 } 606 leafPos := t.cfg.getParentAtLevel(deepestPosition, uint(leafLevel)) 607 608 proof.SiblingHashesOnPath = make([]Hash, leafLevel*(t.cfg.ChildrenPerNode-1)) 609 leafChildIndexes := t.cfg.positionToChildIndexPath(leafPos) 610 // Flatten the siblingPosHashPairs Hashes into a []Hash. 611 for _, pos := range siblingPosHashPairs { 612 if t.cfg.getDeepestChildIndex(&pos.Position) < leafChildIndexes[leafLevel-t.cfg.getLevel(&pos.Position)] { 613 proof.SiblingHashesOnPath[(leafLevel-t.cfg.getLevel(&pos.Position))*(t.cfg.ChildrenPerNode-1)+int(t.cfg.getDeepestChildIndex(&pos.Position))] = pos.Hash 614 } else { 615 proof.SiblingHashesOnPath[(leafLevel-t.cfg.getLevel(&pos.Position))*(t.cfg.ChildrenPerNode-1)+int(t.cfg.getDeepestChildIndex(&pos.Position))-1] = pos.Hash 616 } 617 } 618 619 var kevps []KeyEncodedValuePair 620 621 // We have two cases: either the node at leafPos is actually a leaf 622 // (which might or not contain the key which we are trying to look up), 623 // or such node does not exists at all (which happens only if the key we 624 // are looking up is not part of the tree at that seqno). 625 _, err = t.eng.LookupNode(ctx, tr, s, leafPos) 626 if err != nil { 627 // NodeNotFoundError is ignored as the inclusion proof we 628 // produce will prove that the key is not in the tree. 629 if _, nodeNotFound := err.(NodeNotFoundError); !nodeNotFound { 630 return nil, MerkleInclusionProof{}, err 631 } 632 } else { 633 if t.cfg.MaxValuesPerLeaf == 1 { 634 // Try to avoid LookupKEVPairsUnderPosition if possible as it is a range 635 // query and thus more expensive. 636 kevp, _, err := t.eng.LookupKEVPair(ctx, tr, s, k) 637 if err != nil { 638 // KeyNotFoundError is ignored as the inclusion proof we 639 // produce will prove that the key is not in the tree. 640 if _, keyNotFound := err.(KeyNotFoundError); !keyNotFound { 641 return nil, MerkleInclusionProof{}, err 642 } 643 } else { 644 kevps = append(kevps, KeyEncodedValuePair{Key: k, Value: kevp}) 645 } 646 } 647 648 // if len(kevps)>0, then MaxValuesPerLeaf == 1 and we found the key we 649 // are looking for, so there is no need to look for other keys under 650 // leafPos. 651 if len(kevps) == 0 { 652 // Lookup hashes of key value pairs stored at the same leaf. 653 // These pairs are ordered by key. 654 kevps, _, err = t.eng.LookupKEVPairsUnderPosition(ctx, tr, s, leafPos) 655 if err != nil { 656 // KeyNotFoundError is ignored. This would happen when we are 657 // trying to produce an absence proof on an empty tree: there 658 // would be a leaf node containing no keys. 659 if _, keyNotFound := err.(KeyNotFoundError); !keyNotFound { 660 return nil, MerkleInclusionProof{}, err 661 } 662 kevps = make([]KeyEncodedValuePair, 0) 663 } 664 } 665 } 666 667 var ms MasterSecret 668 if t.cfg.UseBlindedValueHashes && len(kevps) > 0 { 669 msMap, err := t.eng.(StorageEngineWithBlinding).LookupMasterSecrets(ctx, tr, []Seqno{s}) 670 if err != nil { 671 return nil, MerkleInclusionProof{}, err 672 } 673 ms = msMap[s] 674 } 675 676 // OtherPairsInLeaf will have length equal to kevps - 1 in an inclusion 677 // proof, and kevps in an absence proof. 678 if kevps != nil { 679 proof.OtherPairsInLeaf = make([]KeyHashPair, 0, len(kevps)) 680 } 681 for _, kevpi := range kevps { 682 if kevpi.Key.Equal(k) { 683 val = kevpi.Value 684 if t.cfg.UseBlindedValueHashes { 685 proof.KeySpecificSecret = t.cfg.Encoder.ComputeKeySpecificSecret(ms, k) 686 } else { 687 proof.KeySpecificSecret = nil 688 } 689 continue 690 } 691 692 var hash Hash 693 hash, err = t.cfg.Encoder.HashKeyEncodedValuePairWithKeySpecificSecret(kevpi, t.cfg.Encoder.ComputeKeySpecificSecret(ms, kevpi.Key)) 694 if err != nil { 695 return nil, MerkleInclusionProof{}, err 696 } 697 proof.OtherPairsInLeaf = append(proof.OtherPairsInLeaf, KeyHashPair{Key: kevpi.Key, Hash: hash}) 698 } 699 700 return val, proof, nil 701 } 702 703 func (t *Tree) GetKeyValuePairWithProof(ctx logger.ContextInterface, tr Transaction, s Seqno, k Key) (kvp KeyValuePair, proof MerkleInclusionProof, err error) { 704 val, proof, err := t.GetEncodedValueWithInclusionProof(ctx, tr, s, k) 705 if err != nil { 706 return KeyValuePair{}, MerkleInclusionProof{}, err 707 } 708 709 valContainer := t.cfg.ConstructValueContainer() 710 err = t.cfg.Encoder.Decode(&valContainer, val) 711 if err != nil { 712 return KeyValuePair{}, MerkleInclusionProof{}, err 713 } 714 kvp = KeyValuePair{Key: k, Value: valContainer} 715 716 return kvp, proof, nil 717 } 718 719 func (t *Tree) getExtensionProof(ctx logger.ContextInterface, tr Transaction, fromSeqno, toSeqno Seqno, isPartOfIncExtProof bool) (proof MerkleExtensionProof, err error) { 720 // Optimization: no proof is required to show something extends itself. 721 if fromSeqno == toSeqno { 722 return MerkleExtensionProof{}, nil 723 } 724 725 seqnos, err := ComputeRootHashSeqnosNeededInExtensionProof(fromSeqno, toSeqno) 726 if err != nil { 727 return MerkleExtensionProof{}, err 728 } 729 hashes, err := t.eng.LookupRootHashes(ctx, tr, seqnos) 730 if err != nil { 731 return MerkleExtensionProof{}, err 732 } 733 734 seqnos, err = ComputeRootMetadataSeqnosNeededInExtensionProof(fromSeqno, toSeqno, isPartOfIncExtProof) 735 if err != nil { 736 return MerkleExtensionProof{}, err 737 } 738 roots, err := t.eng.LookupRoots(ctx, tr, seqnos) 739 if err != nil { 740 return MerkleExtensionProof{}, err 741 } 742 743 proof.RootHashes = hashes 744 proof.PreviousRootsNoSkips = roots 745 746 return proof, nil 747 } 748 749 func (t *Tree) GetExtensionProof(ctx logger.ContextInterface, tr Transaction, fromSeqno, toSeqno Seqno) (proof MerkleExtensionProof, err error) { 750 return t.getExtensionProof(ctx, tr, fromSeqno, toSeqno, false) 751 } 752 753 func (t *Tree) GetEncodedValueWithInclusionExtensionProof(ctx logger.ContextInterface, tr Transaction, haveSeqno, wantSeqno Seqno, k Key) (val EncodedValue, proof MerkleInclusionExtensionProof, err error) { 754 val, incProof, err := t.GetEncodedValueWithInclusionProof(ctx, tr, wantSeqno, k) 755 if err != nil { 756 return nil, MerkleInclusionExtensionProof{}, err 757 } 758 proof.MerkleInclusionProof = incProof 759 760 if haveSeqno != wantSeqno { 761 // clear these fields to save bandwidth, they are redundant when an 762 // inclusion proof is paired with an extension proof. Note that if 763 // haveSeqno == wantSeqno, we don't do this optimization as the 764 // extension proof is skipped. 765 proof.MerkleInclusionProof.RootMetadataNoHash.SkipPointersHash = nil 766 proof.MerkleInclusionProof.RootMetadataNoHash.Seqno = Seqno(0) 767 } 768 769 extProof, err := t.getExtensionProof(ctx, tr, haveSeqno, wantSeqno, true) 770 if err != nil { 771 return nil, MerkleInclusionExtensionProof{}, err 772 } 773 774 // clear these fields to save bandwidth 775 for i := range extProof.PreviousRootsNoSkips { 776 extProof.PreviousRootsNoSkips[i].SkipPointersHash = nil 777 } 778 779 proof.MerkleExtensionProof = extProof 780 return val, proof, err 781 } 782 783 func (t *Tree) GetKeyValuePairWithInclusionExtensionProof(ctx logger.ContextInterface, tr Transaction, haveSeqno, wantSeqno Seqno, k Key) (kvp KeyValuePair, proof MerkleInclusionExtensionProof, err error) { 784 val, proof, err := t.GetEncodedValueWithInclusionExtensionProof(ctx, tr, haveSeqno, wantSeqno, k) 785 if err != nil { 786 return KeyValuePair{}, MerkleInclusionExtensionProof{}, err 787 } 788 789 valContainer := t.cfg.ConstructValueContainer() 790 err = t.cfg.Encoder.Decode(&valContainer, val) 791 if err != nil { 792 return KeyValuePair{}, MerkleInclusionExtensionProof{}, err 793 } 794 kvp = KeyValuePair{Key: k, Value: valContainer} 795 796 return kvp, proof, nil 797 } 798 799 func (t *Tree) ExecTransaction(ctx logger.ContextInterface, txFn func(logger.ContextInterface, Transaction) error) error { 800 return t.eng.ExecTransaction(ctx, txFn) 801 } 802 803 // GetLatestRoot returns the latest RootMetadata which was stored in the 804 // tree (and its Hash and Seqno). If no such record was stored yet, 805 // GetLatestRoot returns 0 as a Seqno and a NoLatestRootFound error. 806 func (t *Tree) GetLatestRoot(ctx logger.ContextInterface, tr Transaction) (s Seqno, root RootMetadata, rootHash Hash, err error) { 807 s, root, err = t.eng.LookupLatestRoot(ctx, tr) 808 if err != nil || s == 0 { 809 return 0, RootMetadata{}, nil, err 810 } 811 _, rootHash, err = t.cfg.Encoder.EncodeAndHashGeneric(root) 812 if err != nil { 813 return 0, RootMetadata{}, nil, err 814 } 815 816 return s, root, rootHash, nil 817 }