fn reconstruct_tree(&mut self, starting_digest: &ADDigest) -> Result<()> {
        ensure!(self.base.tree.key_length > 0);
        ensure!(starting_digest.len() == DIGEST_LENGTH + 1);
        self.base.tree.height = (starting_digest.last().unwrap() & 0xffu8) as usize;

        let max_nodes = if self.max_num_operations.is_some() {
            // compute the maximum number of nodes the proof can contain according to
            // https://eprint.iacr.org/2016/994 Appendix B last paragraph

            // First compute log (number of operations), rounded up
            let mut log_num_ops = 0;
            let mut temp = 1;
            let real_num_operations = self.max_num_operations.unwrap_or(0);
            while temp < real_num_operations {
                temp = temp * 2;
                log_num_ops += 1
            }

            // compute maximum height that the tree can be before an operation
            temp = 1 + std::cmp::max(self.base.tree.height, log_num_ops);
            let hnew = temp + temp / 2; // this will replace 1.4405 from the paper with 1.5 and will round down, which is safe, because hnew is an integer
            let real_max_deletes = self.max_deletes.unwrap_or(real_num_operations);
            // Note: this is quite likely a lot more than there will really be nodes
            (real_num_operations + real_max_deletes) * (2 * self.base.tree.height + 1)
                + real_max_deletes * hnew
                + 1 // +1 needed in case numOperations == 0
        } else {
            0
        };

        // Now reconstruct the tree from the proof, which has the post order traversal
        // of the tree
        let mut num_nodes = 0;
        let mut i: usize = 0;
        let mut previous_leaf: Option<NodeId> = None;
        let mut stack: Vec<NodeId> = Vec::new();
        let key_length = self.base.tree.key_length;
        while self.proof[i] != END_OF_TREE_IN_PACKAGED_PROOF {
            let n = self.proof[i];
            i += 1;
            num_nodes += 1;
            ensure!(self.max_num_operations.is_none() || num_nodes <= max_nodes);
            match n {
                LABEL_IN_PACKAGED_PROOF => {
                    let mut label: Digest32 = Default::default();
                    label.copy_from_slice(&self.proof[i..i + DIGEST_LENGTH]);
                    i += DIGEST_LENGTH;
                    stack.push(Node::new_label(&label));
                    previous_leaf = None;
                }
                LEAF_IN_PACKAGED_PROOF => {
                    let key = if let Some(prev) = previous_leaf {
                        Bytes::copy_from_slice(&self.base.tree.next_node_key(&prev))
                    } else {
                        let start = i;
                        i += self.base.tree.key_length;
                        Bytes::copy_from_slice(&self.proof[start..i])
                    };
                    let next_leaf_key = Bytes::copy_from_slice(&self.proof[i..i + key_length]);
                    i += key_length;
                    let value_length = self.base.tree.value_length.unwrap_or_else(|| {
                        let vl = BigEndian::read_u32(&self.proof[i..i + 4]) as usize;
                        i += 4;
                        vl
                    });
                    let value = Bytes::copy_from_slice(&self.proof[i..i + value_length]);
                    i += value_length;
                    let leaf = LeafNode::new(&key, &value, &next_leaf_key);
                    stack.push(leaf.clone());
                    previous_leaf = Some(leaf);
                }
                _ => {
                    let right = stack.pop().unwrap();
                    let left = stack.pop().unwrap();
                    stack.push(InternalNode::new(None, &left, &right, n as Balance));
                }
            }
        }

        ensure!(stack.len() == 1);
        let root = stack.pop().unwrap();
        ensure!(starting_digest.starts_with(&self.base.tree.label(&root)));
        self.base.tree.root = Some(root);
        self.directions_index = (i + 1) * 8; // Directions start right after the packed tree, which we just finished
        Ok(())
    }
// Will be None if the proof is not correct and thus a tree cannot be reconstructed
Will be None if the proof is not correct and thus a tree cannot be reconstructed
Will be None if the proof is not correct and thus a tree cannot be reconstructed
fn reconstruct_tree(&mut self, starting_digest: &ADDigest) -> Result<()> {
        ensure!(self.base.tree.key_length > 0);
        ensure!(starting_digest.len() == DIGEST_LENGTH + 1);
        self.base.tree.height = (starting_digest.last().unwrap() & 0xffu8) as usize;
        let max_nodes = if self.max_num_operations.is_some() {
            // compute the maximum number of nodes the proof can contain according to
            // https://eprint.iacr.org/2016/994 Appendix B last paragraph
            // First compute log (number of operations), rounded up
            let mut log_num_ops = 0;
            let mut temp = 1;
            let real_num_operations = self.max_num_operations.unwrap_or(0);
            while temp < real_num_operations {
                temp = temp * 2;
                log_num_ops += 1
            }
            // compute maximum height that the tree can be before an operation
            temp = 1 + std::cmp::max(self.base.tree.height, log_num_ops);
            let hnew = temp + temp / 2; // this will replace 1.4405 from the paper with 1.5 and will round down, which is safe, because hnew is an integer
            let real_max_deletes = self.max_deletes.unwrap_or(real_num_operations);
            // Note: this is quite likely a lot more than there will really be nodes
            (real_num_operations + real_max_deletes) * (2 * self.base.tree.height + 1)
                + real_max_deletes * hnew
                + 1 // +1 needed in case numOperations == 0
        } else {
            0
        };
        // Now reconstruct the tree from the proof, which has the post order traversal
        // of the tree
        let mut num_nodes = 0;
        let mut i: usize = 0;
        let mut previous_leaf: Option<NodeId> = None;
        let mut stack: Vec<NodeId> = Vec::new();
        let key_length = self.base.tree.key_length;
        while self.proof[i] != END_OF_TREE_IN_PACKAGED_PROOF {
            let n = self.proof[i];
            i += 1;
            num_nodes += 1;
            ensure!(self.max_num_operations.is_none() || num_nodes <= max_nodes);
            match n {
                LABEL_IN_PACKAGED_PROOF => {
                    let mut label: Digest32 = Default::default();
                    label.copy_from_slice(&self.proof[i..i + DIGEST_LENGTH]);
                    i += DIGEST_LENGTH;
                    stack.push(Node::new_label(&label));
                    previous_leaf = None;
                }
                LEAF_IN_PACKAGED_PROOF => {
                    let key = if let Some(prev) = previous_leaf {
                        Bytes::copy_from_slice(&self.base.tree.next_node_key(&prev))
                    } else {
                        let start = i;
                        i += self.base.tree.key_length;
                        Bytes::copy_from_slice(&self.proof[start..i])
                    };
                    let next_leaf_key = Bytes::copy_from_slice(&self.proof[i..i + key_length]);
                    i += key_length;
                    let value_length = self.base.tree.value_length.unwrap_or_else(|| {
                        let vl = BigEndian::read_u32(&self.proof[i..i + 4]) as usize;
                        i += 4;
                        vl
                    });
                    let value = Bytes::copy_from_slice(&self.proof[i..i + value_length]);
                    i += value_length;
                    let leaf = LeafNode::new(&key, &value, &next_leaf_key);
                    stack.push(leaf.clone());
                    previous_leaf = Some(leaf);
                }
                _ => {
                    let right = stack.pop().unwrap();
                    let left = stack.pop().unwrap();
                    stack.push(InternalNode::new(None, &left, &right, n as Balance));
                }
            }
        }
        ensure!(stack.len() == 1);
        let root = stack.pop().unwrap();
        ensure!(starting_digest.starts_with(&self.base.tree.label(&root)));
        self.base.tree.root = Some(root);
        self.directions_index = (i + 1) * 8; // Directions start right after the packed tree, which we just finished
        Ok(())
    }
fn reconstruct_tree ( & mut self , starting_digest : & ADDigest ) -> Result < ( ) > { ensure ! ( self base tree key_length 0 ) ; ensure ! ( starting_digest len ( ) DIGEST_LENGTH 1 ) ; self . base . tree . height = ( starting_digest . last ( ) . unwrap ( ) & 0xffu8 ) as usize ; let max_nodes = if self . max_num_operations . is_some ( ) { // compute the maximum number of nodes the proof can contain according to // https://eprint.iacr.org/2016/994 Appendix B last paragraph // First compute log (number of operations), rounded up let mut log_num_ops = 0 ; let mut temp = 1 ; let real_num_operations = self . max_num_operations . unwrap_or ( 0 ) ; while temp < real_num_operations { temp = temp * 2 ; log_num_ops += 1 } // compute maximum height that the tree can be before an operation temp = 1 + std :: cmp :: max ( self . base . tree . height , log_num_ops ) ; let hnew = temp + temp / 2 ; // this will replace 1.4405 from the paper with 1.5 and will round down, which is safe, because hnew is an integer let real_max_deletes = self . max_deletes . unwrap_or ( real_num_operations ) ; // Note: this is quite likely a lot more than there will really be nodes ( real_num_operations + real_max_deletes ) * ( 2 * self . base . tree . height + 1 ) + real_max_deletes * hnew + 1 // +1 needed in case numOperations == 0 } else { 0 } ; // Now reconstruct the tree from the proof, which has the post order traversal // of the tree let mut num_nodes = 0 ; let mut i : usize = 0 ; let mut previous_leaf : Option < NodeId > = None ; let mut stack : Vec < NodeId > = Vec :: new ( ) ; let key_length = self . base . tree . key_length ; while self . proof [ i ] != END_OF_TREE_IN_PACKAGED_PROOF { let n = self . proof [ i ] ; i += 1 ; num_nodes += 1 ; ensure ! ( self max_num_operations is_none ( ) num_nodes max_nodes ) ; match n { LABEL_IN_PACKAGED_PROOF => { let mut label : Digest32 = Default :: default ( ) ; label . copy_from_slice ( & self . proof [ i .. i + DIGEST_LENGTH ] ) ; i += DIGEST_LENGTH ; stack . push ( Node :: new_label ( & label ) ) ; previous_leaf = None ; } LEAF_IN_PACKAGED_PROOF => { let key = if let Some ( prev ) = previous_leaf { Bytes :: copy_from_slice ( & self . base . tree . next_node_key ( & prev ) ) } else { let start = i ; i += self . base . tree . key_length ; Bytes :: copy_from_slice ( & self . proof [ start .. i ] ) } ; let next_leaf_key = Bytes :: copy_from_slice ( & self . proof [ i .. i + key_length ] ) ; i += key_length ; let value_length = self . base . tree . value_length . unwrap_or_else ( | | { let vl = BigEndian :: read_u32 ( & self . proof [ i .. i + 4 ] ) as usize ; i += 4 ; vl } ) ; let value = Bytes :: copy_from_slice ( & self . proof [ i .. i + value_length ] ) ; i += value_length ; let leaf = LeafNode :: new ( & key , & value , & next_leaf_key ) ; stack . push ( leaf . clone ( ) ) ; previous_leaf = Some ( leaf ) ; } _ => { let right = stack . pop ( ) . unwrap ( ) ; let left = stack . pop ( ) . unwrap ( ) ; stack . push ( InternalNode :: new ( None , & left , & right , n as Balance ) ) ; } } } ensure ! ( stack len ( ) 1 ) ; let root = stack . pop ( ) . unwrap ( ) ; ensure ! ( starting_digest starts_with ( self base tree label ( root ) ) ) ; self . base . tree . root = Some ( root ) ; self . directions_index = ( i + 1 ) * 8 ; // Directions start right after the packed tree, which we just finished Ok ( ( ) ) }
Will be None if the proof is not correct and thus a tree cannot be reconstructed
Will be None if the proof is not correct and thus a tree cannot be reconstructed
&mut self
starting_digest
&ADDigest
&mut self
starting_digest
&ADDigest