// Merge the proofs under the same rootHash into the tree
Merge the proofs under the same rootHash into the tree
// Merge the proofs under the same rootHash into the tree
func (h *HistoryTree) MergeProof(key uint64, value []byte, proofs ProofChain) error {
	if len(value) != common.HashLength || proofs == nil {
		return errors.New("value or proofs is nil")
	}
	if h.root == nil {
		return errors.New("historytree is nil")
	}
	proofsKey := proofs.BigKey().Uint64()
	if proofsKey != key {
		return fmt.Errorf("key and proofs is not match, KEY:%d but Proofs.Key():%d", key, proofsKey)
	}
	root, err := h.HashValue()
	if err != nil {
		return common.NewDvppError("get history tree root hash error", err)
	}
	proofRoot, err := proofs.Proof(common.BytesToHash(value))
	if err != nil {
		return fmt.Errorf("get proofs(%s) root error: %v", proofs, err)
	}
	if !bytes.Equal(root, proofRoot) {
		return errors.New("proofs is not created from the same tree")
	}
	prefix := heightToPrefix(key)
	tracers := make([]nodeTracer, 0)
	_, _, leafvalue, exist, err := locateNode(h.root, prefix, h.adapter, &tracers)
	if err != nil {
		return fmt.Errorf("locateNode by %d -> (%x) failed: %v", key, prefix, err)
	}
	if exist {
		if bytes.Equal(value, leafvalue) {
			return nil
		}
		return fmt.Errorf("want value(%x), but found a different leaf(%x) in the tree", value[:5],
			common.ForPrint(leafvalue))
	}
	nodes := make([]*TreeNode, HistoryTreeDepth)
	last := HistoryTreeDepth - 1
	nodes[last] = h.root
	for i := 0; i < len(tracers); i++ {
		nodes[last-1-i] = tracers[i].nodeInPos
	}
	for i := 0; i < HistoryTreeDepth; i++ {
		if nodes[i] == nil {
			if i == 0 {
				nodes[i], err = NewNodeByProof(h.adapter, int(prefix[last-i]), value, nil, proofs[i].ChildProofs)
			} else {
				nodes[i], err = NewNodeByProof(h.adapter, int(prefix[last-i]), nil, nodes[i-1], proofs[i].ChildProofs)
			}
			if err != nil {
				return fmt.Errorf("NewNodeByProof(%d) at %d error: %v", int(prefix[last-i]), i, err)
			}
		} else {
			if i == 0 {
				err = nodes[i].MergeProof(h.adapter, int(prefix[last-i]), value, nil, proofs[i].ChildProofs)
			} else {
				err = nodes[i].MergeProof(h.adapter, int(prefix[last-i]), nil, nodes[i-1], proofs[i].ChildProofs)
			}
			if err != nil {
				return fmt.Errorf("MergeProof(%d) at %d error: %v", int(prefix[last-i]), i, err)
			}
		}
	}
	return nil
}
func ( h * HistoryTree ) MergeProof ( key uint64 , value [ ] byte , proofs ProofChain ) error { if len ( value ) != common . HashLength || proofs == nil { return errors . New ( " " ) } if h . root == nil { return errors . New ( " " ) } proofsKey := proofs . BigKey ( ) . Uint64 ( ) if proofsKey != key { return fmt . Errorf ( " " , key , proofsKey ) } root , err := h . HashValue ( ) if err != nil { return common . NewDvppError ( " " , err ) } proofRoot , err := proofs . Proof ( common . BytesToHash ( value ) ) if err != nil { return fmt . Errorf ( " " , proofs , err ) } if ! bytes . Equal ( root , proofRoot ) { return errors . New ( " " ) } prefix := heightToPrefix ( key ) tracers := make ( [ ] nodeTracer , 0 ) _ , _ , leafvalue , exist , err := locateNode ( h . root , prefix , h . adapter , & tracers ) if err != nil { return fmt . Errorf ( " " , key , prefix , err ) } if exist { if bytes . Equal ( value , leafvalue ) { return nil } return fmt . Errorf ( " " , value [ : 5 ] , common . ForPrint ( leafvalue ) ) } nodes := make ( [ ] * TreeNode , HistoryTreeDepth ) last := HistoryTreeDepth - 1 nodes [ last ] = h . root for i := 0 ; i < len ( tracers ) ; i ++ { nodes [ last - 1 - i ] = tracers [ i ] . nodeInPos } for i := 0 ; i < HistoryTreeDepth ; i ++ { if nodes [ i ] == nil { if i == 0 { nodes [ i ] , err = NewNodeByProof ( h . adapter , int ( prefix [ last - i ] ) , value , nil , proofs [ i ] . ChildProofs ) } else { nodes [ i ] , err = NewNodeByProof ( h . adapter , int ( prefix [ last - i ] ) , nil , nodes [ i - 1 ] , proofs [ i ] . ChildProofs ) } if err != nil { return fmt . Errorf ( " " , int ( prefix [ last - i ] ) , i , err ) } } else { if i == 0 { err = nodes [ i ] . MergeProof ( h . adapter , int ( prefix [ last - i ] ) , value , nil , proofs [ i ] . ChildProofs ) } else { err = nodes [ i ] . MergeProof ( h . adapter , int ( prefix [ last - i ] ) , nil , nodes [ i - 1 ] , proofs [ i ] . ChildProofs ) } if err != nil { return fmt . Errorf ( " " , int ( prefix [ last - i ] ) , i , err ) } } } return nil }
Merge the proofs under the same rootHash into the tree
Merge the proofs under the same rootHash into the tree
// proofsKey, _ := proofs.Key() // Check whether it is the content of the same tree // the merging value already exists // target leaf node already exists, and the values are not match // Place root and existing nodes on the path into the nodes list in reverse order // Create missing node or complement information from bottom to top // creating when the node is missing // leaf node // non-leaf node // merge when the node already exists