[][src]Trait exonum_merkledb::ObjectHash

pub trait ObjectHash {
    fn object_hash(&self) -> Hash;
}

A common trait for the ability to compute a unique hash.

The hash value returned by the object_hash() method isn't always irreversible. This hash is used, for example, in the storage as a key, as uniqueness is important in this case.

Required methods

fn object_hash(&self) -> Hash

Returns a hash of the value.

Hash must be unique, but not necessary cryptographic.

Loading content...

Implementations on Foreign Types

impl ObjectHash for Hash[src]

Just returns the original hash.

impl ObjectHash for str[src]

impl ObjectHash for [u8][src]

impl ObjectHash for ()[src]

impl ObjectHash for bool[src]

impl ObjectHash for Vec<u8>[src]

impl ObjectHash for String[src]

impl ObjectHash for PublicKey[src]

impl ObjectHash for DateTime<Utc>[src]

impl ObjectHash for Uuid[src]

impl ObjectHash for Decimal[src]

impl ObjectHash for u8[src]

impl ObjectHash for u16[src]

impl ObjectHash for u32[src]

impl ObjectHash for u64[src]

impl ObjectHash for u128[src]

impl ObjectHash for i8[src]

impl ObjectHash for i16[src]

impl ObjectHash for i32[src]

impl ObjectHash for i64[src]

impl ObjectHash for i128[src]

Loading content...

Implementors

impl<T, K: ?Sized, V, KeyMode> ObjectHash for ProofMapIndex<T, K, V, KeyMode> where
    T: RawAccess,
    K: BinaryKey,
    V: BinaryValue,
    KeyMode: ToProofPath<K>, 
[src]

object_hash() of a proof map is uniquely determined by its contents (i.e., keys and corresponding values). It does not depend on the order of key insertion.

Specification

The object_hash is defined as

h = sha256( HashTag::MapNode || root_hash )

where root_hash is computed according to one of the three cases as follows.

Empty map

root_hash = Hash::zero().

Map with a single entry

root_hash = sha256( HashTag::MapBranchNode || path || child_hash ).

Here, the map contains a single path, and child_hash is the hash of the object under this key. path is serialized as

LEB128(bit_length) || bytes,

where

  • LEB128 is a compact serialization format for unsigned integers
  • bit_length is the number of bits in the path
  • bytes is the path serialized as the minimum necessary number of bytes, with zero padding at the end if necessary.

Map with multiple entries

root_hash = sha256(
    HashTag::MapBranchNode
    || left_path || right_path
    || left_hash || right_hash
).

Here, the root node in the Merkle Patricia tree corresponding to the map has left_path / right_path as child paths, and left_hash / right_hash are hashes of child nodes. These hashes are defined according to the same formula for branch nodes, and for leaves as

leaf_hash = sha256( HashTag::Blob || serialized_value ).

ProofPaths are serialized in the same way as in the previous case.

Examples

let db = TemporaryDB::new();
let fork = db.fork();
let mut index = fork.get_proof_map("name");

let default_hash = index.object_hash();
assert_eq!(HashTag::empty_map_hash(), default_hash);

index.put(&default_hash, 100);
let hash = index.object_hash();
assert_ne!(hash, default_hash);

impl<T, V> ObjectHash for ProofListIndex<T, V> where
    T: RawAccess,
    V: BinaryValue
[src]

object_hash for a list depends on all list items. It explicitly commits to the list length in order to be able to more easily prove absence of elements and to prevent second pre-image attacks.

Specification

The object_hash is calculated as follows:

h = sha256( HashTag::ListNode || u64_LE(len) || root_hash )

Here, u64_LE is the 8-byte little-endian serialization of an integer. In particular, for an empty list

h = sha256( HashTag::ListNode || 0 || Hash::zero() )

root_hash is defined recursively based on the binary Merkle tree corresponding to the list. The tree is built so that left children at each level are filled up first, and the depth of each leaf node is the same. For example, here's the structure of a tree with 6 leaves:

      root (0..6)
     /        \
   0..4      4..6
  /    \       |
0..2  2..4   4..6
/  \  /  \   /  \
0  1  2  3   4  5

For branch nodes of the tree,

node_hash = sha256( HashTag::ListBranchNode || left_hash || right_hash? )

where left_hash is the hash of the left child and right_hash is the optional hash of the right child, which may be absent if the tree is not balanced.

For leaves, the hash is

leaf_hash = sha256( HashTag::Blob || serialized_value ).

Examples

let db = TemporaryDB::new();
let fork = db.fork();
let mut index = fork.get_proof_list("name");

let default_hash = index.object_hash();
assert_eq!(HashTag::empty_list_hash(), default_hash);
index.push(1);
let hash = index.object_hash();
assert_ne!(hash, default_hash);

impl<T, V> ObjectHash for ProofEntry<T, V> where
    T: RawAccess,
    V: BinaryValue + ObjectHash
[src]

object_hash is computed as SHA-256 of the entry serialization, or Hash::zero() if the entry is not set.

Examples

let db = TemporaryDB::new();
let fork = db.fork();
let mut index = fork.get_proof_entry("name");
assert_eq!(Hash::default(), index.object_hash());

let value = 10;
index.set(value);
assert_eq!(exonum_crypto::hash(&[value]), index.object_hash());
Loading content...