Really unclear Error while creating merkle tree

use hex;

use sha2::{Digest, Sha256};

use std::{fs::File, io};

fn filehash(path: &str) -> String {

    let mut file = File::open(path).unwrap();

    let mut hasher = Sha256::new();

    io::copy(&mut file, &mut hasher);

    hex::encode(hasher.finalize())

}

#[derive(Clone)]

struct MerkleTree {

    hashvalue: String,

    left: Option<Box<MerkleTree>>,

    right: Option<Box<MerkleTree>>,

}

impl MerkleTree {

    fn createmerkle(paths: &Vec<String>) -> Box<MerkleTree> {

        let length = paths.len();

        let mut leaves: Vec<MerkleTree> = Vec::with_capacity(length);

        for i in 0..length {

            leaves[i] = MerkleTree{hashvalue : filehash(&paths[i][..]),left : None,right : None};

        }

        MerkleTree::buildmerkle(leaves)

    }

    fn buildmerkle(mut nodes: Vec<MerkleTree>) -> Box<MerkleTree> {

        let mut length = nodes.len();

        let mut is_even = false;

        if length % 2 == 0 {

            is_even = true;

        }

        length = (length + 1) / 2;

        if length != 1 {

            let mut upperlayer: Vec<MerkleTree> = Vec::with_capacity(length);

            if is_even {

                for i in (length - 1)..=0 {

                    upperlayer[i].right = Some(Box::new(nodes[2*i +1].clone()));

                    upperlayer[i].left = Some(Box::new(nodes[2*i].clone()));

                    MerkleTree::combinehash(&mut upperlayer[i]);

                }

            } else {

                nodes.push(nodes.last().unwrap().clone());

                for i in (length - 1)..=0 {

                    upperlayer[i].right = Some(Box::new(nodes[2*i +1].clone()));

                    upperlayer[i].left = Some(Box::new(nodes[2*i].clone()));

                    MerkleTree::combinehash(&mut upperlayer[i]);

            }

        }

            drop(nodes);

            MerkleTree::buildmerkle(upperlayer)

        } else {

            Box::new(nodes[0].clone())

        }

    }

    fn combinehash(node: & mut MerkleTree) {

        let mut hasher = Sha256::new();

        hasher.update(node.left.as_ref().unwrap().hashvalue.clone());

        hasher.update(node.right.as_ref().unwrap().hashvalue.clone());

        node.hashvalue = hex::encode(hasher.finalize());

    }

    fn display(root : Box<MerkleTree>) 

    {   

        match root.left

        {

            Some(left) => {

                MerkleTree::display(left);  

                println!("{}",root.hashvalue);

            },

            

            None => ()

        }

        match root.right

        {

            Some(right) => {

                MerkleTree::display(right); 

                println!("{}",root.hashvalue);

            },

            

            None => ()

        }

    }

}

fn main() {

    let mut paths : Vec<String> = Vec::with_capacity(8);

    let mut path =  String::with_capacity(16);

    println!("Enter X to complete file upload");

    loop{

        println!("enter the path for the file");

        path = String::from("");

        io::stdin().read_line(&mut path).expect("sorry input failed");

        path = path.trim().to_string();

        match &path[..]

        {

            "X" | "x" => {

                break;

            }

            _ => {

                paths.push(path);

            }

        }

    }

    let merkleroot = MerkleTree::createmerkle(&paths);

    MerkleTree::display(merkleroot);

}
thread 'main' panicked at 'index out of bounds: the len is 0 but the index is 0', src\main.rs:28:13
stack backtrace:
   0: std::panicking::begin_panic_handler
             at /rustc/c8dfcfe046a7680554bf4eb612bad840e7631c4b\/library\std\src\panicking.rs:515
   1: core::panicking::panic_fmt
             at /rustc/c8dfcfe046a7680554bf4eb612bad840e7631c4b\/library\core\src\panicking.rs:92
   2: core::panicking::panic_bounds_check
             at /rustc/c8dfcfe046a7680554bf4eb612bad840e7631c4b\/library\core\src\panicking.rs:69
   3: core::slice::index::impl$2::index_mut<play::MerkleTree>
             at /rustc/c8dfcfe046a7680554bf4eb612bad840e7631c4b\library\core\src\slice\index.rs:190
   4: core::slice::index::impl$1::index_mut<play::MerkleTree,usize>
             at /rustc/c8dfcfe046a7680554bf4eb612bad840e7631c4b\library\core\src\slice\index.rs:26
   5: alloc::vec::impl$15::index_mut<play::MerkleTree,usize,alloc::alloc::Global>
             at /rustc/c8dfcfe046a7680554bf4eb612bad840e7631c4b\library\alloc\src\vec\mod.rs:2444
   6: play::MerkleTree::createmerkle
             at .\src\main.rs:28
   7: play::main
             at .\src\main.rs:126
   8: core::ops::function::FnOnce::call_once<void (*)(),tuple$<> >
             at /rustc/c8dfcfe046a7680554bf4eb612bad840e7631c4b\library\core\src\ops\function.rs:227
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
error: process didn't exit successfully: `target\debug\play.exe` (exit code: 101)

I'm trying to create a Merkle Tree but i'm not understanding why is this throwing error

You can't initialise a Vec like this. with_capacity will allocate enough space for length items, but it will still be empty and all indexing operations on it will fail. Try using leaves.push instead. A similar issue happens with upperlayer but the fix for that isn't as clear since it should hold Merkletrees but the code doesn't create any in that section.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.