remove `num` crate dependency

This commit is contained in:
Andrew Poelstra 2018-02-18 15:21:05 +00:00
parent e034ae6065
commit 047c0c149d
8 changed files with 61 additions and 68 deletions

View File

@ -20,8 +20,6 @@
//! these blocks and the blockchain. //! these blocks and the blockchain.
//! //!
use num::{FromPrimitive, Zero};
use util; use util;
use util::Error::{SpvBadTarget, SpvBadProofOfWork}; use util::Error::{SpvBadTarget, SpvBadProofOfWork};
use util::hash::Sha256dHash; use util::hash::Sha256dHash;
@ -90,9 +88,9 @@ impl BlockHeader {
// The mantissa is signed but may not be negative // The mantissa is signed but may not be negative
if mant > 0x7FFFFF { if mant > 0x7FFFFF {
Zero::zero() Default::default()
} else { } else {
<Uint256 as FromPrimitive>::from_u64(mant as u64).unwrap() << (expt as usize) Uint256::from_u64(mant as u64).unwrap() << (expt as usize)
} }
} }

View File

@ -18,7 +18,6 @@
//! blockchain. //! blockchain.
//! //!
use num::{FromPrimitive, Zero};
use std::{marker, ptr}; use std::{marker, ptr};
use blockdata::block::{Block, BlockHeader}; use blockdata::block::{Block, BlockHeader};
@ -348,7 +347,7 @@ impl Blockchain {
let genesis = genesis_block(network); let genesis = genesis_block(network);
let genhash = genesis.header.bitcoin_hash(); let genhash = genesis.header.bitcoin_hash();
let new_node = Box::new(BlockchainNode { let new_node = Box::new(BlockchainNode {
total_work: Zero::zero(), total_work: Default::default(),
required_difficulty: genesis.header.target(), required_difficulty: genesis.header.target(),
block: genesis, block: genesis,
height: 0, height: 0,
@ -444,7 +443,7 @@ impl Blockchain {
// Compute new target // Compute new target
let mut target = unsafe { (*prev).block.header.target() }; let mut target = unsafe { (*prev).block.header.target() };
target = target.mul_u32(timespan); 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) // Clamp below MAX_TARGET (difficulty 1)
let max = max_target(self.network); let max = max_target(self.network);
if target > max { target = max }; if target > max { target = max };

View File

@ -20,7 +20,6 @@
//! //!
use std::default::Default; use std::default::Default;
use num::FromPrimitive;
use blockdata::opcodes; use blockdata::opcodes;
use blockdata::script; 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) /// In Bitcoind this is insanely described as ~((u256)0 >> 32)
pub fn max_target(_: Network) -> Uint256 { pub fn max_target(_: Network) -> Uint256 {
<Uint256 as FromPrimitive>::from_u64(0xFFFF).unwrap() << 208 Uint256::from_u64(0xFFFF).unwrap() << 208
} }
/// The maximum value allowed in an output (useful for sanity checking, /// The maximum value allowed in an output (useful for sanity checking,

View File

@ -44,7 +44,6 @@
extern crate byteorder; extern crate byteorder;
extern crate crypto; extern crate crypto;
#[macro_use] extern crate jsonrpc; #[macro_use] extern crate jsonrpc;
extern crate num;
extern crate rand; extern crate rand;
extern crate rustc_serialize as serialize; extern crate rustc_serialize as serialize;
extern crate secp256k1; extern crate secp256k1;

View File

@ -429,11 +429,11 @@ impl <T: BitcoinHash> MerkleRoot for Vec<T> {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use num::FromPrimitive;
use strason; use strason;
use network::encodable::VarInt; use network::encodable::VarInt;
use network::serialize::{serialize, deserialize}; use network::serialize::{serialize, deserialize};
use util::uint::{Uint128, Uint256};
use super::*; use super::*;
#[test] #[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, 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()), Uint256::from_u64(1));
assert_eq!(Some(one.into_le().low_128()), FromPrimitive::from_u64(1)); assert_eq!(Some(one.into_le().low_128()), Uint128::from_u64(1));
} }
} }

View File

@ -43,6 +43,12 @@ pub trait BitArray {
/// Trailing zeros /// Trailing zeros
fn trailing_zeros(&self) -> usize; fn trailing_zeros(&self) -> usize;
/// Create all-zeros value
fn zero() -> Self;
/// Create value represeting one
fn one() -> Self;
} }
/// A general error code /// A general error code

View File

@ -23,7 +23,6 @@
use std::fmt::Debug; use std::fmt::Debug;
use std::marker; use std::marker;
use std::{cmp, fmt, ops, ptr}; use std::{cmp, fmt, ops, ptr};
use num::{Zero, One};
use network::encodable::{ConsensusDecodable, ConsensusEncodable}; use network::encodable::{ConsensusDecodable, ConsensusEncodable};
use network::serialize::{SimpleDecoder, SimpleEncoder}; use network::serialize::{SimpleDecoder, SimpleEncoder};
@ -39,7 +38,7 @@ pub struct PatriciaTree<K: Copy, V> {
} }
impl<K, V> PatriciaTree<K, V> impl<K, V> PatriciaTree<K, V>
where K: Copy + BitArray + cmp::Eq + Zero + One + where K: Copy + BitArray + cmp::Eq +
ops::BitXor<K, Output=K> + ops::BitXor<K, Output=K> +
ops::Add<K, Output=K> + ops::Add<K, Output=K> +
ops::Shr<usize, Output=K> + ops::Shr<usize, Output=K> +
@ -51,7 +50,7 @@ impl<K, V> PatriciaTree<K, V>
data: None, data: None,
child_l: None, child_l: None,
child_r: None, child_r: None,
skip_prefix: Zero::zero(), skip_prefix: BitArray::zero(),
skip_len: 0 skip_len: 0
} }
} }
@ -221,7 +220,7 @@ impl<K, V> PatriciaTree<K, V>
/// Return value is (deletable, actual return value), where `deletable` is true /// 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) /// is true when the entire node can be deleted (i.e. it has no children)
fn recurse<K, V>(tree: &mut PatriciaTree<K, V>, key: &K, key_len: usize) -> (bool, Option<V>) fn recurse<K, V>(tree: &mut PatriciaTree<K, V>, key: &K, key_len: usize) -> (bool, Option<V>)
where K: Copy + BitArray + cmp::Eq + Zero + One + where K: Copy + BitArray + cmp::Eq +
ops::Add<K, Output=K> + ops::Add<K, Output=K> +
ops::Shr<usize, Output=K> + ops::Shr<usize, Output=K> +
ops::Shl<usize, Output=K> ops::Shl<usize, Output=K>
@ -255,9 +254,9 @@ impl<K, V> PatriciaTree<K, V>
tree.data = data; tree.data = data;
tree.child_l = child_l; tree.child_l = child_l;
tree.child_r = child_r; 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) } ret << (tree.skip_len as usize) }
else { Zero::zero() }; else { BitArray::zero() };
tree.skip_prefix = tree.skip_prefix + tree.skip_prefix = tree.skip_prefix +
new_bit + new_bit +
(skip_prefix << (1 + tree.skip_len as usize)); (skip_prefix << (1 + tree.skip_len as usize));
@ -314,9 +313,9 @@ impl<K, V> PatriciaTree<K, V>
tree.data = data; tree.data = data;
tree.child_l = child_l; tree.child_l = child_l;
tree.child_r = child_r; 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) } ret << (tree.skip_len as usize) }
else { Zero::zero() }; else { BitArray::zero() };
tree.skip_prefix = tree.skip_prefix + tree.skip_prefix = tree.skip_prefix +
new_bit + new_bit +
(skip_prefix << (1 + tree.skip_len as usize)); (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)] #[cfg(test)]
mod tests { mod tests {
use num::Zero;
use num::FromPrimitive;
use network::serialize::{deserialize, serialize}; use network::serialize::{deserialize, serialize};
use util::hash::Sha256dHash; use util::hash::Sha256dHash;
use util::uint::Uint128; use util::uint::Uint128;
use util::uint::Uint256; use util::uint::Uint256;
use util::patricia_tree::PatriciaTree; use util::patricia_tree::PatriciaTree;
use util::BitArray;
#[test] #[test]
fn patricia_single_insert_lookup_delete_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); key = key + (key << 64);
let mut tree = PatriciaTree::new(); let mut tree = PatriciaTree::new();
@ -622,14 +619,14 @@ mod tests {
// Do the actual test -- note that we also test insertion and deletion // Do the actual test -- note that we also test insertion and deletion
// at the root here. // at the root here.
for i in 0u32..10 { 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 { 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)); assert_eq!(m, Some(&i));
} }
for i in 0u32..10 { 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)); assert_eq!(m, Some(i));
} }
// Check that the chunder was unharmed // Check that the chunder was unharmed

View File

@ -19,7 +19,6 @@
//! //!
use std::fmt; use std::fmt;
use num::{FromPrimitive, Zero, One};
use util::BitArray; use util::BitArray;
@ -71,31 +70,18 @@ macro_rules! construct_uint {
} }
$name(ret) + $name(carry) $name(ret) + $name(carry)
} }
}
impl FromPrimitive for $name { /// Create an object from a given unsigned 64-bit integer
#[inline] pub fn from_u64(init: u64) -> Option<$name> {
fn from_u64(init: u64) -> Option<$name> {
let mut ret = [0; $n_words]; let mut ret = [0; $n_words];
ret[0] = init; ret[0] = init;
Some($name(ret)) Some($name(ret))
} }
#[inline] /// Create an object from a given signed 64-bit integer
fn from_i64(init: i64) -> Option<$name> { pub fn from_i64(init: i64) -> Option<$name> {
assert!(init >= 0); assert!(init >= 0);
FromPrimitive::from_u64(init as u64) $name::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 })
} }
} }
@ -124,7 +110,7 @@ macro_rules! construct_uint {
#[inline] #[inline]
fn sub(self, other: $name) -> $name { 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 (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 { impl ::std::ops::BitAnd<$name> for $name {
@ -375,22 +372,20 @@ impl Uint256 {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use num::FromPrimitive;
use network::serialize::{deserialize, serialize}; use network::serialize::{deserialize, serialize};
use util::uint::Uint256; use util::uint::Uint256;
use util::BitArray; use util::BitArray;
#[test] #[test]
pub fn uint256_bits_test() { pub fn uint256_bits_test() {
assert_eq!(<Uint256 as FromPrimitive>::from_u64(255).unwrap().bits(), 8); assert_eq!(Uint256::from_u64(255).unwrap().bits(), 8);
assert_eq!(<Uint256 as FromPrimitive>::from_u64(256).unwrap().bits(), 9); assert_eq!(Uint256::from_u64(256).unwrap().bits(), 9);
assert_eq!(<Uint256 as FromPrimitive>::from_u64(300).unwrap().bits(), 9); assert_eq!(Uint256::from_u64(300).unwrap().bits(), 9);
assert_eq!(<Uint256 as FromPrimitive>::from_u64(60000).unwrap().bits(), 16); assert_eq!(Uint256::from_u64(60000).unwrap().bits(), 16);
assert_eq!(<Uint256 as FromPrimitive>::from_u64(70000).unwrap().bits(), 17); assert_eq!(Uint256::from_u64(70000).unwrap().bits(), 17);
// Try to read the following lines out loud quickly // Try to read the following lines out loud quickly
let mut shl = <Uint256 as FromPrimitive>::from_u64(70000).unwrap(); let mut shl = Uint256::from_u64(70000).unwrap();
shl = shl << 100; shl = shl << 100;
assert_eq!(shl.bits(), 117); assert_eq!(shl.bits(), 117);
shl = shl << 100; shl = shl << 100;
@ -399,11 +394,11 @@ mod tests {
assert_eq!(shl.bits(), 0); assert_eq!(shl.bits(), 0);
// Bit set check // Bit set check
assert!(!<Uint256 as FromPrimitive>::from_u64(10).unwrap().bit(0)); assert!(!Uint256::from_u64(10).unwrap().bit(0));
assert!(<Uint256 as FromPrimitive>::from_u64(10).unwrap().bit(1)); assert!(Uint256::from_u64(10).unwrap().bit(1));
assert!(!<Uint256 as FromPrimitive>::from_u64(10).unwrap().bit(2)); assert!(!Uint256::from_u64(10).unwrap().bit(2));
assert!(<Uint256 as FromPrimitive>::from_u64(10).unwrap().bit(3)); assert!(Uint256::from_u64(10).unwrap().bit(3));
assert!(!<Uint256 as FromPrimitive>::from_u64(10).unwrap().bit(4)); assert!(!Uint256::from_u64(10).unwrap().bit(4));
} }
#[test] #[test]
@ -425,7 +420,7 @@ mod tests {
#[test] #[test]
pub fn uint256_arithmetic_test() { pub fn uint256_arithmetic_test() {
let init = <Uint256 as FromPrimitive>::from_u64(0xDEADBEEFDEADBEEF).unwrap(); let init = Uint256::from_u64(0xDEADBEEFDEADBEEF).unwrap();
let copy = init; let copy = init;
let add = init + copy; let add = init + copy;
@ -446,17 +441,17 @@ mod tests {
let mult = sub.mul_u32(300); let mult = sub.mul_u32(300);
assert_eq!(mult, Uint256([0x8C8C3EE70C644118u64, 0x0209E7378231E632, 0, 0])); assert_eq!(mult, Uint256([0x8C8C3EE70C644118u64, 0x0209E7378231E632, 0, 0]));
// Division // Division
assert_eq!(<Uint256 as FromPrimitive>::from_u64(105).unwrap() / assert_eq!(Uint256::from_u64(105).unwrap() /
<Uint256 as FromPrimitive>::from_u64(5).unwrap(), Uint256::from_u64(5).unwrap(),
<Uint256 as FromPrimitive>::from_u64(21).unwrap()); Uint256::from_u64(21).unwrap());
let div = mult / <Uint256 as FromPrimitive>::from_u64(300).unwrap(); let div = mult / Uint256::from_u64(300).unwrap();
assert_eq!(div, Uint256([0x9F30411021524112u64, 0x0001BD5B7DDFBD5A, 0, 0])); assert_eq!(div, Uint256([0x9F30411021524112u64, 0x0001BD5B7DDFBD5A, 0, 0]));
// TODO: bit inversion // TODO: bit inversion
} }
#[test] #[test]
pub fn uint256_bitslice_test() { pub fn uint256_bitslice_test() {
let init = <Uint256 as FromPrimitive>::from_u64(0xDEADBEEFDEADBEEF).unwrap(); let init = Uint256::from_u64(0xDEADBEEFDEADBEEF).unwrap();
let add = init + (init << 64); let add = init + (init << 64);
assert_eq!(add.bit_slice(64, 128), init); assert_eq!(add.bit_slice(64, 128), init);
assert_eq!(add.mask(64), init); assert_eq!(add.mask(64), init);
@ -466,7 +461,7 @@ mod tests {
pub fn uint256_extreme_bitshift_test() { pub fn uint256_extreme_bitshift_test() {
// Shifting a u64 by 64 bits gives an undefined value, so make sure that // Shifting a u64 by 64 bits gives an undefined value, so make sure that
// we're doing the Right Thing here // we're doing the Right Thing here
let init = <Uint256 as FromPrimitive>::from_u64(0xDEADBEEFDEADBEEF).unwrap(); let init = Uint256::from_u64(0xDEADBEEFDEADBEEF).unwrap();
assert_eq!(init << 64, Uint256([0, 0xDEADBEEFDEADBEEF, 0, 0])); assert_eq!(init << 64, Uint256([0, 0xDEADBEEFDEADBEEF, 0, 0]));
let add = (init << 64) + init; let add = (init << 64) + init;