Update types to new tree_hash crate

This commit is contained in:
Paul Hauner
2019-04-16 14:14:38 +10:00
parent 3eaa06d758
commit b8c4c3308a
70 changed files with 284 additions and 234 deletions

View File

@@ -12,3 +12,4 @@ serde = "1.0"
serde_derive = "1.0"
serde_hex = { path = "../serde_hex" }
ssz = { path = "../ssz" }
tree_hash = { path = "../tree_hash" }

View File

@@ -166,7 +166,7 @@ impl<'de> Deserialize<'de> for AggregateSignature {
}
impl TreeHash for AggregateSignature {
fn hash_tree_root(&self) -> Vec<u8> {
fn tree_hash_root(&self) -> Vec<u8> {
hash(&self.as_bytes())
}
}

View File

@@ -2,7 +2,8 @@ use super::{fake_signature::FakeSignature, AggregatePublicKey, BLS_AGG_SIG_BYTE_
use serde::de::{Deserialize, Deserializer};
use serde::ser::{Serialize, Serializer};
use serde_hex::{encode as hex_encode, PrefixedHexVisitor};
use ssz::{hash, ssz_encode, Decodable, DecodeError, Encodable, SszStream, TreeHash};
use ssz::{ssz_encode, Decodable, DecodeError, Encodable, SszStream};
use tree_hash::impl_tree_hash_for_ssz_bytes;
/// A BLS aggregate signature.
///
@@ -98,11 +99,7 @@ impl<'de> Deserialize<'de> for FakeAggregateSignature {
}
}
impl TreeHash for FakeAggregateSignature {
fn hash_tree_root(&self) -> Vec<u8> {
hash(&self.bytes)
}
}
impl_tree_hash_for_ssz_bytes!(FakeAggregateSignature);
#[cfg(test)]
mod tests {

View File

@@ -3,7 +3,8 @@ use hex::encode as hex_encode;
use serde::de::{Deserialize, Deserializer};
use serde::ser::{Serialize, Serializer};
use serde_hex::HexVisitor;
use ssz::{hash, ssz_encode, Decodable, DecodeError, Encodable, SszStream, TreeHash};
use ssz::{ssz_encode, Decodable, DecodeError, Encodable, SszStream};
use tree_hash::impl_tree_hash_for_ssz_bytes;
/// A single BLS signature.
///
@@ -73,11 +74,7 @@ impl Decodable for FakeSignature {
}
}
impl TreeHash for FakeSignature {
fn hash_tree_root(&self) -> Vec<u8> {
hash(&self.bytes)
}
}
impl_tree_hash_for_ssz_bytes!(FakeSignature);
impl Serialize for FakeSignature {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>

View File

@@ -3,10 +3,11 @@ use bls_aggregates::PublicKey as RawPublicKey;
use serde::de::{Deserialize, Deserializer};
use serde::ser::{Serialize, Serializer};
use serde_hex::{encode as hex_encode, HexVisitor};
use ssz::{decode, hash, ssz_encode, Decodable, DecodeError, Encodable, SszStream, TreeHash};
use ssz::{decode, ssz_encode, Decodable, DecodeError, Encodable, SszStream};
use std::default;
use std::fmt;
use std::hash::{Hash, Hasher};
use tree_hash::impl_tree_hash_for_ssz_bytes;
/// A single BLS signature.
///
@@ -104,11 +105,7 @@ impl<'de> Deserialize<'de> for PublicKey {
}
}
impl TreeHash for PublicKey {
fn hash_tree_root(&self) -> Vec<u8> {
hash(&self.0.as_bytes())
}
}
impl_tree_hash_for_ssz_bytes!(PublicKey);
impl PartialEq for PublicKey {
fn eq(&self, other: &PublicKey) -> bool {

View File

@@ -4,7 +4,8 @@ use hex::encode as hex_encode;
use serde::de::{Deserialize, Deserializer};
use serde::ser::{Serialize, Serializer};
use serde_hex::HexVisitor;
use ssz::{decode, ssz_encode, Decodable, DecodeError, Encodable, SszStream, TreeHash};
use ssz::{decode, ssz_encode, Decodable, DecodeError, Encodable, SszStream};
use tree_hash::impl_tree_hash_for_ssz_bytes;
/// A single BLS signature.
///
@@ -69,11 +70,7 @@ impl<'de> Deserialize<'de> for SecretKey {
}
}
impl TreeHash for SecretKey {
fn hash_tree_root(&self) -> Vec<u8> {
self.0.as_bytes().clone()
}
}
impl_tree_hash_for_ssz_bytes!(SecretKey);
#[cfg(test)]
mod tests {

View File

@@ -115,7 +115,7 @@ impl Decodable for Signature {
}
impl TreeHash for Signature {
fn hash_tree_root(&self) -> Vec<u8> {
fn tree_hash_root(&self) -> Vec<u8> {
hash(&self.as_bytes())
}
}

View File

@@ -10,3 +10,4 @@ ssz = { path = "../ssz" }
bit-vec = "0.5.0"
serde = "1.0"
serde_derive = "1.0"
tree_hash = { path = "../tree_hash" }

View File

@@ -9,6 +9,7 @@ use serde_hex::{encode, PrefixedHexVisitor};
use ssz::{Decodable, Encodable};
use std::cmp;
use std::default;
use tree_hash::impl_tree_hash_for_ssz_bytes;
/// A BooleanBitfield represents a set of booleans compactly stored as a vector of bits.
/// The BooleanBitfield is given a fixed size during construction. Reads outside of the current size return an out-of-bounds error. Writes outside of the current size expand the size of the set.
@@ -256,11 +257,7 @@ impl<'de> Deserialize<'de> for BooleanBitfield {
}
}
impl ssz::TreeHash for BooleanBitfield {
fn hash_tree_root(&self) -> Vec<u8> {
self.to_bytes().hash_tree_root()
}
}
impl_tree_hash_for_ssz_bytes!(BooleanBitfield);
#[cfg(test)]
mod tests {

View File

@@ -1,94 +0,0 @@
use ssz::{SignedRoot, TreeHash};
use ssz_derive::{SignedRoot, TreeHash};
#[derive(TreeHash, SignedRoot)]
struct CryptoKitties {
best_kitty: u64,
worst_kitty: u8,
kitties: Vec<u32>,
}
impl CryptoKitties {
fn new() -> Self {
CryptoKitties {
best_kitty: 9999,
worst_kitty: 1,
kitties: vec![2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43],
}
}
fn hash(&self) -> Vec<u8> {
let mut list: Vec<Vec<u8>> = Vec::new();
list.push(self.best_kitty.hash_tree_root());
list.push(self.worst_kitty.hash_tree_root());
list.push(self.kitties.hash_tree_root());
ssz::merkle_hash(&mut list)
}
}
#[test]
fn test_cryptokitties_hash() {
let kitties = CryptoKitties::new();
let expected_hash = vec![
201, 9, 139, 14, 24, 247, 21, 55, 132, 211, 51, 125, 183, 186, 177, 33, 147, 210, 42, 108,
174, 162, 221, 227, 157, 179, 15, 7, 97, 239, 82, 220,
];
assert_eq!(kitties.hash(), expected_hash);
}
#[test]
fn test_simple_tree_hash_derive() {
let kitties = CryptoKitties::new();
assert_eq!(kitties.hash_tree_root(), kitties.hash());
}
#[test]
fn test_simple_signed_root_derive() {
let kitties = CryptoKitties::new();
assert_eq!(kitties.signed_root(), kitties.hash());
}
#[derive(TreeHash, SignedRoot)]
struct Casper {
friendly: bool,
#[tree_hash(skip_hashing)]
friends: Vec<u32>,
#[signed_root(skip_hashing)]
dead: bool,
}
impl Casper {
fn new() -> Self {
Casper {
friendly: true,
friends: vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
dead: true,
}
}
fn expected_signed_hash(&self) -> Vec<u8> {
let mut list = Vec::new();
list.push(self.friendly.hash_tree_root());
list.push(self.friends.hash_tree_root());
ssz::merkle_hash(&mut list)
}
fn expected_tree_hash(&self) -> Vec<u8> {
let mut list = Vec::new();
list.push(self.friendly.hash_tree_root());
list.push(self.dead.hash_tree_root());
ssz::merkle_hash(&mut list)
}
}
#[test]
fn test_annotated_tree_hash_derive() {
let casper = Casper::new();
assert_eq!(casper.hash_tree_root(), casper.expected_tree_hash());
}
#[test]
fn test_annotated_signed_root_derive() {
let casper = Casper::new();
assert_eq!(casper.signed_root(), casper.expected_signed_hash());
}

View File

@@ -25,9 +25,14 @@ pub fn efficient_merkleize(bytes: &[u8]) -> Vec<u8> {
let nodes = num_nodes(leaves);
let internal_nodes = nodes - leaves;
let num_bytes = internal_nodes * HASHSIZE + bytes.len();
let num_bytes = std::cmp::max(internal_nodes, 1) * HASHSIZE + bytes.len();
let mut o: Vec<u8> = vec![0; internal_nodes * HASHSIZE];
if o.len() < HASHSIZE {
o.resize(HASHSIZE, 0);
}
o.append(&mut bytes.to_vec());
assert_eq!(o.len(), num_bytes);

View File

@@ -30,6 +30,24 @@ impl_for_bitsize!(u64, 64);
impl_for_bitsize!(usize, 64);
impl_for_bitsize!(bool, 8);
impl TreeHash for [u8; 4] {
fn tree_hash_type() -> TreeHashType {
TreeHashType::List
}
fn tree_hash_packed_encoding(&self) -> Vec<u8> {
panic!("bytesN should never be packed.")
}
fn tree_hash_packing_factor() -> usize {
panic!("bytesN should never be packed.")
}
fn tree_hash_root(&self) -> Vec<u8> {
merkle_root(&ssz::ssz_encode(self))
}
}
impl TreeHash for H256 {
fn tree_hash_type() -> TreeHashType {
TreeHashType::Basic
@@ -95,3 +113,20 @@ where
hash(&root_and_len)
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn bool() {
let mut true_bytes: Vec<u8> = vec![1];
true_bytes.append(&mut vec![0; 31]);
let false_bytes: Vec<u8> = vec![0; 32];
assert_eq!(true.tree_hash_root(), true_bytes);
assert_eq!(false.tree_hash_root(), false_bytes);
}
}

View File

@@ -31,12 +31,10 @@ fn get_hashable_named_field_idents<'a>(struct_data: &'a syn::DataStruct) -> Vec<
///
/// The field attribute is: `#[tree_hash(skip_hashing)]`
fn should_skip_hashing(field: &syn::Field) -> bool {
for attr in &field.attrs {
if attr.tts.to_string() == "( skip_hashing )" {
return true;
}
}
false
field
.attrs
.iter()
.any(|attr| attr.into_token_stream().to_string() == "# [ tree_hash ( skip_hashing ) ]")
}
/// Implements `tree_hash::CachedTreeHashSubTree` for some `struct`.

View File

@@ -98,3 +98,85 @@ fn signed_root() {
assert_eq!(unsigned.tree_hash_root(), signed.signed_root());
}
#[derive(TreeHash, SignedRoot)]
struct CryptoKitties {
best_kitty: u64,
worst_kitty: u8,
kitties: Vec<u32>,
}
impl CryptoKitties {
fn new() -> Self {
CryptoKitties {
best_kitty: 9999,
worst_kitty: 1,
kitties: vec![2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43],
}
}
fn hash(&self) -> Vec<u8> {
let mut leaves = vec![];
leaves.append(&mut self.best_kitty.tree_hash_root());
leaves.append(&mut self.worst_kitty.tree_hash_root());
leaves.append(&mut self.kitties.tree_hash_root());
tree_hash::merkle_root(&leaves)
}
}
#[test]
fn test_simple_tree_hash_derive() {
let kitties = CryptoKitties::new();
assert_eq!(kitties.tree_hash_root(), kitties.hash());
}
#[test]
fn test_simple_signed_root_derive() {
let kitties = CryptoKitties::new();
assert_eq!(kitties.signed_root(), kitties.hash());
}
#[derive(TreeHash, SignedRoot)]
struct Casper {
friendly: bool,
#[tree_hash(skip_hashing)]
friends: Vec<u32>,
#[signed_root(skip_hashing)]
dead: bool,
}
impl Casper {
fn new() -> Self {
Casper {
friendly: true,
friends: vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
dead: true,
}
}
fn expected_signed_hash(&self) -> Vec<u8> {
let mut list = Vec::new();
list.append(&mut self.friendly.tree_hash_root());
list.append(&mut self.friends.tree_hash_root());
tree_hash::merkle_root(&list)
}
fn expected_tree_hash(&self) -> Vec<u8> {
let mut list = Vec::new();
list.append(&mut self.friendly.tree_hash_root());
list.append(&mut self.dead.tree_hash_root());
tree_hash::merkle_root(&list)
}
}
#[test]
fn test_annotated_tree_hash_derive() {
let casper = Casper::new();
assert_eq!(casper.tree_hash_root(), casper.expected_tree_hash());
}
#[test]
fn test_annotated_signed_root_derive() {
let casper = Casper::new();
assert_eq!(casper.signed_root(), casper.expected_signed_hash());
}