1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
// Copyright 2019 Stichting Organism
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Copyright (c) 2019 The Decred developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.

use crate::hash::H256;

// fast_merkle_root treats the provided slice of hashes as leaves of a merkle tree
// and returns the resulting merkle root.
//
// A merkle tree is a tree in which every non-leaf node is the hash of its
// children nodes.  A diagram depicting how this works for Organism transactions
// where h(x) is a blake256 hash follows:
//
//	         root = h1234 = h(h12 + h34)
//	        /                           \
//	  h12 = h(h1 + h2)            h34 = h(h3 + h4)
//	   /            \              /            \
//	h1 = h(tx1)  h2 = h(tx2)    h3 = h(tx3)  h4 = h(tx4)
//
// The number of inputs is not always a power of two which results in a
// balanced tree structure as above.  In that case, parent nodes with no
// children are also zero and parent nodes with only a single left node
// are calculated by concatenating the left node with itself before hashing.
pub fn fast_merkle_root(mut leaves: Vec<H256>) -> H256 {
    // All zero.
    if leaves.len() == 0 {
        return H256::zero();
    }

    if leaves.len() < 2 {
        return leaves[0];
    }
    // The following algorithm works by replacing the leftmost entries in the
    // slice with the concatenations of each subsequent set of 2 hashes and
    // shrinking the slice by half to account for the fact that each level of
    // the tree is half the size of the previous one.  In the case a level is
    // unbalanced (there is no final right child), the final node is duplicated
    // so it ultimately is concatenated with itself.
    //
    // For example, the following illustrates calculating a tree with 5 leaves:
    //
    // [0 1 2 3 4]                              (5 entries)
    // 1st iteration: [h(0||1) h(2||3) h(4||4)] (3 entries)
    // 2nd iteration: [h(h01||h23) h(h44||h44)] (2 entries)
    // 3rd iteration: [h(h0123||h4444)]         (1 entry)
    while leaves.len() > 1 {
        // When there is no right child, the parent is generated by hashing the
        // concatenation of the left child with itself.
        if leaves.len() & 1 != 0 {
            leaves.push(leaves[leaves.len() - 1]);
        }

        // Set the parent node to the hash of the concatenation of the left and
        // right children.
        let mut i = 0;
        while i < leaves.len() / 2 {
            let left = leaves[i * 2].hash_with(leaves[i * 2 + 1]);
            leaves[i] = left;
            i += 1;
        }
        let drain_start = leaves.len() / 2;
        leaves.split_off(drain_start);
    }

    leaves[0]
}

#[test]
fn test_to_merkle_fast_short() {
    let _inputs = vec![
        H256::from_hex("5e574591d900f7f9abb8f8eb31cc9330247d27ba293ad79c348d602ece717b8b").unwrap(),
        H256::from_hex("b3b70fe08c2da744c9559d533e8db35b3bfefba1b0f1c7b31e7d9d523c00a426").unwrap(),
        H256::from_hex("dd3058a7fc691ff4dee0a8cd6030f404ffda7e7aee88aff3985f7b2bbe4792f7").unwrap(),
        H256::from_hex("5e574591d900f7f9abb8f8eb31cc9330247d27ba293ad79c348d602ece717b8b").unwrap(),
        H256::from_hex("b3b70fe08c2da744c9559d533e8db35b3bfefba1b0f1c7b31e7d9d523c00a426").unwrap(),
        H256::from_hex("dd3058a7fc691ff4dee0a8cd6030f404ffda7e7aee88aff3985f7b2bbe4792f7").unwrap(),
        H256::from_hex("5e574591d900f7f9abb8f8eb31cc9330247d27ba293ad79c348d602ece717b8b").unwrap(),
        H256::from_hex("b3b70fe08c2da744c9559d533e8db35b3bfefba1b0f1c7b31e7d9d523c00a426").unwrap(),
        H256::from_hex("dd3058a7fc691ff4dee0a8cd6030f404ffda7e7aee88aff3985f7b2bbe4792f7").unwrap(),
    ];

    //assert_eq!(fast_merkle_root(&mut inputs),  H256::from_hex("a144c719391569aa20bf612bf5588bce71cd397574cb6c060e0bac100f6e5805").unwrap());
}

#[test]
fn test_to_merkle_fast_zero() {
    assert_eq!(fast_merkle_root(vec![H256::zero()]), H256::zero());
}