diff --git a/src/blockdata/block.rs b/src/blockdata/block.rs index 2a7bded..f574caf 100644 --- a/src/blockdata/block.rs +++ b/src/blockdata/block.rs @@ -20,8 +20,6 @@ //! these blocks and the blockchain. //! -use num::{FromPrimitive, Zero}; - use util; use util::Error::{SpvBadTarget, SpvBadProofOfWork}; use util::hash::Sha256dHash; @@ -90,9 +88,9 @@ impl BlockHeader { // The mantissa is signed but may not be negative if mant > 0x7FFFFF { - Zero::zero() + Default::default() } else { - ::from_u64(mant as u64).unwrap() << (expt as usize) + Uint256::from_u64(mant as u64).unwrap() << (expt as usize) } } diff --git a/src/blockdata/blockchain.rs b/src/blockdata/blockchain.rs index 3b5b740..385da01 100644 --- a/src/blockdata/blockchain.rs +++ b/src/blockdata/blockchain.rs @@ -18,7 +18,6 @@ //! blockchain. //! -use num::{FromPrimitive, Zero}; use std::{marker, ptr}; use blockdata::block::{Block, BlockHeader}; @@ -348,7 +347,7 @@ impl Blockchain { let genesis = genesis_block(network); let genhash = genesis.header.bitcoin_hash(); let new_node = Box::new(BlockchainNode { - total_work: Zero::zero(), + total_work: Default::default(), required_difficulty: genesis.header.target(), block: genesis, height: 0, @@ -444,7 +443,7 @@ impl Blockchain { // Compute new target let mut target = unsafe { (*prev).block.header.target() }; target = target.mul_u32(timespan); - target = target / FromPrimitive::from_u64(DIFFCHANGE_TIMESPAN as u64).unwrap(); + target = target / Uint256::from_u64(DIFFCHANGE_TIMESPAN as u64).unwrap(); // Clamp below MAX_TARGET (difficulty 1) let max = max_target(self.network); if target > max { target = max }; diff --git a/src/blockdata/constants.rs b/src/blockdata/constants.rs index 6621fdc..5e6cfef 100644 --- a/src/blockdata/constants.rs +++ b/src/blockdata/constants.rs @@ -20,7 +20,6 @@ //! use std::default::Default; -use num::FromPrimitive; use blockdata::opcodes; use blockdata::script; @@ -44,7 +43,7 @@ pub static DIFFCHANGE_TIMESPAN: u32 = 14 * 24 * 3600; /// In Bitcoind this is insanely described as ~((u256)0 >> 32) pub fn max_target(_: Network) -> Uint256 { - ::from_u64(0xFFFF).unwrap() << 208 + Uint256::from_u64(0xFFFF).unwrap() << 208 } /// The maximum value allowed in an output (useful for sanity checking, diff --git a/src/lib.rs b/src/lib.rs index 42d47a5..952a922 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -44,7 +44,6 @@ extern crate byteorder; extern crate crypto; #[macro_use] extern crate jsonrpc; -extern crate num; extern crate rand; extern crate rustc_serialize as serialize; extern crate secp256k1; diff --git a/src/util/hash.rs b/src/util/hash.rs index 39783d7..24bd638 100644 --- a/src/util/hash.rs +++ b/src/util/hash.rs @@ -429,11 +429,11 @@ impl MerkleRoot for Vec { #[cfg(test)] mod tests { - use num::FromPrimitive; use strason; use network::encodable::VarInt; use network::serialize::{serialize, deserialize}; + use util::uint::{Uint128, Uint256}; use super::*; #[test] @@ -515,8 +515,8 @@ mod tests { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); - assert_eq!(Some(one.into_le()), FromPrimitive::from_u64(1)); - assert_eq!(Some(one.into_le().low_128()), FromPrimitive::from_u64(1)); + assert_eq!(Some(one.into_le()), Uint256::from_u64(1)); + assert_eq!(Some(one.into_le().low_128()), Uint128::from_u64(1)); } } diff --git a/src/util/mod.rs b/src/util/mod.rs index 4fef29c..6fb1d55 100644 --- a/src/util/mod.rs +++ b/src/util/mod.rs @@ -43,6 +43,12 @@ pub trait BitArray { /// Trailing zeros fn trailing_zeros(&self) -> usize; + + /// Create all-zeros value + fn zero() -> Self; + + /// Create value represeting one + fn one() -> Self; } /// A general error code diff --git a/src/util/patricia_tree.rs b/src/util/patricia_tree.rs index 6fb35c1..7d397eb 100644 --- a/src/util/patricia_tree.rs +++ b/src/util/patricia_tree.rs @@ -23,7 +23,6 @@ use std::fmt::Debug; use std::marker; use std::{cmp, fmt, ops, ptr}; -use num::{Zero, One}; use network::encodable::{ConsensusDecodable, ConsensusEncodable}; use network::serialize::{SimpleDecoder, SimpleEncoder}; @@ -39,7 +38,7 @@ pub struct PatriciaTree { } impl PatriciaTree - where K: Copy + BitArray + cmp::Eq + Zero + One + + where K: Copy + BitArray + cmp::Eq + ops::BitXor + ops::Add + ops::Shr + @@ -51,7 +50,7 @@ impl PatriciaTree data: None, child_l: None, child_r: None, - skip_prefix: Zero::zero(), + skip_prefix: BitArray::zero(), skip_len: 0 } } @@ -221,7 +220,7 @@ impl PatriciaTree /// Return value is (deletable, actual return value), where `deletable` is true /// is true when the entire node can be deleted (i.e. it has no children) fn recurse(tree: &mut PatriciaTree, key: &K, key_len: usize) -> (bool, Option) - where K: Copy + BitArray + cmp::Eq + Zero + One + + where K: Copy + BitArray + cmp::Eq + ops::Add + ops::Shr + ops::Shl @@ -255,9 +254,9 @@ impl PatriciaTree tree.data = data; tree.child_l = child_l; tree.child_r = child_r; - let new_bit = if bit { let ret: K = One::one(); + let new_bit = if bit { let ret: K = BitArray::one(); ret << (tree.skip_len as usize) } - else { Zero::zero() }; + else { BitArray::zero() }; tree.skip_prefix = tree.skip_prefix + new_bit + (skip_prefix << (1 + tree.skip_len as usize)); @@ -314,9 +313,9 @@ impl PatriciaTree tree.data = data; tree.child_l = child_l; tree.child_r = child_r; - let new_bit = if bit { let ret: K = One::one(); + let new_bit = if bit { let ret: K = BitArray::one(); ret << (tree.skip_len as usize) } - else { Zero::zero() }; + else { BitArray::zero() }; tree.skip_prefix = tree.skip_prefix + new_bit + (skip_prefix << (1 + tree.skip_len as usize)); @@ -545,18 +544,16 @@ impl<'a, K: Copy, V> Iterator for MutItems<'a, K, V> { #[cfg(test)] mod tests { - use num::Zero; - use num::FromPrimitive; - use network::serialize::{deserialize, serialize}; use util::hash::Sha256dHash; use util::uint::Uint128; use util::uint::Uint256; use util::patricia_tree::PatriciaTree; + use util::BitArray; #[test] fn patricia_single_insert_lookup_delete_test() { - let mut key: Uint256 = FromPrimitive::from_u64(0xDEADBEEFDEADBEEF).unwrap(); + let mut key = Uint256::from_u64(0xDEADBEEFDEADBEEF).unwrap(); key = key + (key << 64); let mut tree = PatriciaTree::new(); @@ -622,14 +619,14 @@ mod tests { // Do the actual test -- note that we also test insertion and deletion // at the root here. for i in 0u32..10 { - tree.insert(&Zero::zero(), i as usize, i); + tree.insert(&BitArray::zero(), i as usize, i); } for i in 0u32..10 { - let m = tree.lookup(&Zero::zero(), i as usize); + let m = tree.lookup(&BitArray::zero(), i as usize); assert_eq!(m, Some(&i)); } for i in 0u32..10 { - let m = tree.delete(&Zero::zero(), i as usize); + let m = tree.delete(&BitArray::zero(), i as usize); assert_eq!(m, Some(i)); } // Check that the chunder was unharmed diff --git a/src/util/uint.rs b/src/util/uint.rs index 4481b43..5b7c0a4 100644 --- a/src/util/uint.rs +++ b/src/util/uint.rs @@ -19,7 +19,6 @@ //! use std::fmt; -use num::{FromPrimitive, Zero, One}; use util::BitArray; @@ -71,31 +70,18 @@ macro_rules! construct_uint { } $name(ret) + $name(carry) } - } - impl FromPrimitive for $name { - #[inline] - fn from_u64(init: u64) -> Option<$name> { + /// Create an object from a given unsigned 64-bit integer + pub fn from_u64(init: u64) -> Option<$name> { let mut ret = [0; $n_words]; ret[0] = init; Some($name(ret)) } - #[inline] - fn from_i64(init: i64) -> Option<$name> { + /// Create an object from a given signed 64-bit integer + pub fn from_i64(init: i64) -> Option<$name> { assert!(init >= 0); - FromPrimitive::from_u64(init as u64) - } - } - - impl Zero for $name { - fn zero() -> $name { $name([0; $n_words]) } - fn is_zero(&self) -> bool { self.0.iter().all(|&n| n == 0) } - } - - impl One for $name { - fn one() -> $name { - $name({ let mut ret = [0; $n_words]; ret[0] = 1; ret }) + $name::from_u64(init as u64) } } @@ -124,7 +110,7 @@ macro_rules! construct_uint { #[inline] fn sub(self, other: $name) -> $name { - self + !other + One::one() + self + !other + BitArray::one() } } @@ -212,6 +198,17 @@ macro_rules! construct_uint { } (0x40 * ($n_words - 1)) + arr[$n_words - 1].trailing_zeros() as usize } + + fn zero() -> $name { $name([0; $n_words]) } + fn one() -> $name { + $name({ let mut ret = [0; $n_words]; ret[0] = 1; ret }) + } + } + + impl ::std::default::Default for $name { + fn default() -> $name { + BitArray::zero() + } } impl ::std::ops::BitAnd<$name> for $name { @@ -375,22 +372,20 @@ impl Uint256 { #[cfg(test)] mod tests { - use num::FromPrimitive; - use network::serialize::{deserialize, serialize}; use util::uint::Uint256; use util::BitArray; #[test] pub fn uint256_bits_test() { - assert_eq!(::from_u64(255).unwrap().bits(), 8); - assert_eq!(::from_u64(256).unwrap().bits(), 9); - assert_eq!(::from_u64(300).unwrap().bits(), 9); - assert_eq!(::from_u64(60000).unwrap().bits(), 16); - assert_eq!(::from_u64(70000).unwrap().bits(), 17); + assert_eq!(Uint256::from_u64(255).unwrap().bits(), 8); + assert_eq!(Uint256::from_u64(256).unwrap().bits(), 9); + assert_eq!(Uint256::from_u64(300).unwrap().bits(), 9); + assert_eq!(Uint256::from_u64(60000).unwrap().bits(), 16); + assert_eq!(Uint256::from_u64(70000).unwrap().bits(), 17); // Try to read the following lines out loud quickly - let mut shl = ::from_u64(70000).unwrap(); + let mut shl = Uint256::from_u64(70000).unwrap(); shl = shl << 100; assert_eq!(shl.bits(), 117); shl = shl << 100; @@ -399,11 +394,11 @@ mod tests { assert_eq!(shl.bits(), 0); // Bit set check - assert!(!::from_u64(10).unwrap().bit(0)); - assert!(::from_u64(10).unwrap().bit(1)); - assert!(!::from_u64(10).unwrap().bit(2)); - assert!(::from_u64(10).unwrap().bit(3)); - assert!(!::from_u64(10).unwrap().bit(4)); + assert!(!Uint256::from_u64(10).unwrap().bit(0)); + assert!(Uint256::from_u64(10).unwrap().bit(1)); + assert!(!Uint256::from_u64(10).unwrap().bit(2)); + assert!(Uint256::from_u64(10).unwrap().bit(3)); + assert!(!Uint256::from_u64(10).unwrap().bit(4)); } #[test] @@ -425,7 +420,7 @@ mod tests { #[test] pub fn uint256_arithmetic_test() { - let init = ::from_u64(0xDEADBEEFDEADBEEF).unwrap(); + let init = Uint256::from_u64(0xDEADBEEFDEADBEEF).unwrap(); let copy = init; let add = init + copy; @@ -446,17 +441,17 @@ mod tests { let mult = sub.mul_u32(300); assert_eq!(mult, Uint256([0x8C8C3EE70C644118u64, 0x0209E7378231E632, 0, 0])); // Division - assert_eq!(::from_u64(105).unwrap() / - ::from_u64(5).unwrap(), - ::from_u64(21).unwrap()); - let div = mult / ::from_u64(300).unwrap(); + assert_eq!(Uint256::from_u64(105).unwrap() / + Uint256::from_u64(5).unwrap(), + Uint256::from_u64(21).unwrap()); + let div = mult / Uint256::from_u64(300).unwrap(); assert_eq!(div, Uint256([0x9F30411021524112u64, 0x0001BD5B7DDFBD5A, 0, 0])); // TODO: bit inversion } #[test] pub fn uint256_bitslice_test() { - let init = ::from_u64(0xDEADBEEFDEADBEEF).unwrap(); + let init = Uint256::from_u64(0xDEADBEEFDEADBEEF).unwrap(); let add = init + (init << 64); assert_eq!(add.bit_slice(64, 128), init); assert_eq!(add.mask(64), init); @@ -466,7 +461,7 @@ mod tests { pub fn uint256_extreme_bitshift_test() { // Shifting a u64 by 64 bits gives an undefined value, so make sure that // we're doing the Right Thing here - let init = ::from_u64(0xDEADBEEFDEADBEEF).unwrap(); + let init = Uint256::from_u64(0xDEADBEEFDEADBEEF).unwrap(); assert_eq!(init << 64, Uint256([0, 0xDEADBEEFDEADBEEF, 0, 0])); let add = (init << 64) + init;