Merge branch 'master' of github.com:gavofyork/ethcore-util into network
This commit is contained in:
		
						commit
						223e946268
					
				@ -15,7 +15,7 @@ mio = "0.5.0"
 | 
			
		||||
rand = "0.3.12"
 | 
			
		||||
time = "0.1.34"
 | 
			
		||||
tiny-keccak = "1.0"
 | 
			
		||||
rocksdb = "0.2"
 | 
			
		||||
rocksdb = "0.3"
 | 
			
		||||
lazy_static = "0.1"
 | 
			
		||||
eth-secp256k1 = { git = "https://github.com/arkpar/rust-secp256k1.git" }
 | 
			
		||||
rust-crypto = "0.2.34"
 | 
			
		||||
 | 
			
		||||
@ -195,7 +195,6 @@ macro_rules! impl_hash {
 | 
			
		||||
			fn from_json(json: &Json) -> Self {
 | 
			
		||||
				match json {
 | 
			
		||||
					&Json::String(ref s) => {
 | 
			
		||||
						println!("s: {}", s);
 | 
			
		||||
						match s.len() % 2 {
 | 
			
		||||
							0 => FromStr::from_str(clean_0x(s)).unwrap(),
 | 
			
		||||
							_ => FromStr::from_str(&("0".to_string() + &(clean_0x(s).to_string()))[..]).unwrap()
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,6 @@
 | 
			
		||||
#![feature(op_assign_traits)]
 | 
			
		||||
#![feature(associated_consts)]
 | 
			
		||||
#![feature(wrapping)]
 | 
			
		||||
//! Ethcore-util library
 | 
			
		||||
//!
 | 
			
		||||
//! ### Rust version:
 | 
			
		||||
 | 
			
		||||
@ -2,6 +2,7 @@
 | 
			
		||||
 | 
			
		||||
use hash::*;
 | 
			
		||||
use bytes::*;
 | 
			
		||||
use rlp::*;
 | 
			
		||||
use sha3::*;
 | 
			
		||||
use hashdb::*;
 | 
			
		||||
use std::mem;
 | 
			
		||||
@ -53,13 +54,15 @@ use std::collections::HashMap;
 | 
			
		||||
/// ```
 | 
			
		||||
pub struct MemoryDB {
 | 
			
		||||
	data: HashMap<H256, (Bytes, i32)>,
 | 
			
		||||
	static_null_rlp: (Bytes, i32),
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl MemoryDB {
 | 
			
		||||
	/// Create a new instance of the memory DB.
 | 
			
		||||
	pub fn new() -> MemoryDB {
 | 
			
		||||
		MemoryDB {
 | 
			
		||||
			data: HashMap::new()
 | 
			
		||||
			data: HashMap::new(),
 | 
			
		||||
 			static_null_rlp: (vec![0x80u8; 1], 1),
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -98,6 +101,9 @@ impl MemoryDB {
 | 
			
		||||
	/// Even when Some is returned, the data is only guaranteed to be useful
 | 
			
		||||
	/// when the refs > 0.
 | 
			
		||||
	pub fn raw(&self, key: &H256) -> Option<&(Bytes, i32)> {
 | 
			
		||||
		if key == &SHA3_NULL_RLP {
 | 
			
		||||
			return Some(&self.static_null_rlp);
 | 
			
		||||
		}
 | 
			
		||||
		self.data.get(key)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -108,18 +114,23 @@ impl MemoryDB {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	pub fn denote(&self, key: &H256, value: Bytes) -> &(Bytes, i32) {
 | 
			
		||||
		if self.data.get(&key) == None {
 | 
			
		||||
		if self.raw(key) == None {
 | 
			
		||||
			unsafe {
 | 
			
		||||
				let p = &self.data as *const HashMap<H256, (Bytes, i32)> as *mut HashMap<H256, (Bytes, i32)>;
 | 
			
		||||
				(*p).insert(key.clone(), (value, 0));
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		self.data.get(key).unwrap()
 | 
			
		||||
		self.raw(key).unwrap()
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static NULL_RLP_STATIC: [u8; 1] = [0x80; 1];
 | 
			
		||||
 | 
			
		||||
impl HashDB for MemoryDB {
 | 
			
		||||
	fn lookup(&self, key: &H256) -> Option<&[u8]> {
 | 
			
		||||
		if key == &SHA3_NULL_RLP {
 | 
			
		||||
			return Some(&NULL_RLP_STATIC);
 | 
			
		||||
		}
 | 
			
		||||
		match self.data.get(key) {
 | 
			
		||||
			Some(&(ref d, rc)) if rc > 0 => Some(d),
 | 
			
		||||
			_ => None
 | 
			
		||||
@ -127,10 +138,13 @@ impl HashDB for MemoryDB {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	fn keys(&self) -> HashMap<H256, i32> {
 | 
			
		||||
		self.data.iter().filter_map(|(k, v)| if v.1 != 0 {Some((k.clone(), v.1))} else {None}).collect::<HashMap<H256, i32>>()
 | 
			
		||||
		self.data.iter().filter_map(|(k, v)| if v.1 != 0 {Some((k.clone(), v.1))} else {None}).collect()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	fn exists(&self, key: &H256) -> bool {
 | 
			
		||||
		if key == &SHA3_NULL_RLP {
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
		match self.data.get(key) {
 | 
			
		||||
			Some(&(_, x)) if x > 0 => true,
 | 
			
		||||
			_ => false
 | 
			
		||||
@ -138,6 +152,9 @@ impl HashDB for MemoryDB {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	fn insert(&mut self, value: &[u8]) -> H256 {
 | 
			
		||||
		if value == &NULL_RLP {
 | 
			
		||||
			return SHA3_NULL_RLP.clone();
 | 
			
		||||
		}
 | 
			
		||||
		let key = value.sha3();
 | 
			
		||||
		if match self.data.get_mut(&key) {
 | 
			
		||||
			Some(&mut (ref mut old_value, ref mut rc @ -0x80000000i32 ... 0)) => {
 | 
			
		||||
@ -154,6 +171,9 @@ impl HashDB for MemoryDB {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	fn emplace(&mut self, key: H256, value: Bytes) {
 | 
			
		||||
		if value == &NULL_RLP {
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		match self.data.get_mut(&key) {
 | 
			
		||||
			Some(&mut (ref mut old_value, ref mut rc @ -0x80000000i32 ... 0)) => {
 | 
			
		||||
				*old_value = value;
 | 
			
		||||
@ -168,6 +188,9 @@ impl HashDB for MemoryDB {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	fn kill(&mut self, key: &H256) {
 | 
			
		||||
		if key == &SHA3_NULL_RLP {
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		if match self.data.get_mut(key) {
 | 
			
		||||
			Some(&mut (_, ref mut x)) => { *x -= 1; false }
 | 
			
		||||
			None => true
 | 
			
		||||
 | 
			
		||||
@ -10,7 +10,7 @@ use std::ops::*;
 | 
			
		||||
use std::sync::*;
 | 
			
		||||
use std::env;
 | 
			
		||||
use std::collections::HashMap;
 | 
			
		||||
use rocksdb::{DB, Writable};
 | 
			
		||||
use rocksdb::{DB, Writable, IteratorMode};
 | 
			
		||||
 | 
			
		||||
#[derive(Clone)]
 | 
			
		||||
/// Implementation of the HashDB trait for a disk-backed database with a memory overlay.
 | 
			
		||||
@ -138,7 +138,7 @@ impl OverlayDB {
 | 
			
		||||
impl HashDB for OverlayDB {
 | 
			
		||||
	fn keys(&self) -> HashMap<H256, i32> {
 | 
			
		||||
		let mut ret: HashMap<H256, i32> = HashMap::new();
 | 
			
		||||
		for (key, _) in self.backing.iterator().from_start() {
 | 
			
		||||
		for (key, _) in self.backing.iterator(IteratorMode::Start) {
 | 
			
		||||
			let h = H256::from_slice(key.deref());
 | 
			
		||||
			let r = self.payload(&h).unwrap().1;
 | 
			
		||||
			ret.insert(h, r as i32);
 | 
			
		||||
 | 
			
		||||
@ -81,7 +81,7 @@ impl<'db> TrieDB<'db> {
 | 
			
		||||
		let mut ret = self.db.keys();
 | 
			
		||||
		for (k, v) in Self::to_map(self.keys()).into_iter() {
 | 
			
		||||
			let keycount = *ret.get(&k).unwrap_or(&0);
 | 
			
		||||
			match keycount == v as i32 {
 | 
			
		||||
			match keycount <= v as i32 {
 | 
			
		||||
				true => ret.remove(&k),
 | 
			
		||||
				_ => ret.insert(k, keycount - v as i32),
 | 
			
		||||
			};
 | 
			
		||||
 | 
			
		||||
@ -64,16 +64,13 @@ impl<'db> TrieDBMut<'db> {
 | 
			
		||||
		}; 
 | 
			
		||||
 | 
			
		||||
		// set root rlp
 | 
			
		||||
		*r.root = r.db.insert(&NULL_RLP); 
 | 
			
		||||
		*r.root = SHA3_NULL_RLP.clone(); 
 | 
			
		||||
		r 
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/// Create a new trie with the backing database `db` and `root`
 | 
			
		||||
	/// Panics, if `root` does not exist
 | 
			
		||||
	pub fn from_existing(db: &'db mut HashDB, root: &'db mut H256) -> Self {
 | 
			
		||||
		if !db.exists(root) && root == &SHA3_NULL_RLP {
 | 
			
		||||
			*root = db.insert(&NULL_RLP); 
 | 
			
		||||
		}
 | 
			
		||||
		assert!(db.exists(root));
 | 
			
		||||
		TrieDBMut { 
 | 
			
		||||
			db: db, 
 | 
			
		||||
@ -111,7 +108,7 @@ impl<'db> TrieDBMut<'db> {
 | 
			
		||||
		let mut ret = self.db.keys();
 | 
			
		||||
		for (k, v) in Self::to_map(self.keys()).into_iter() {
 | 
			
		||||
			let keycount = *ret.get(&k).unwrap_or(&0);
 | 
			
		||||
			match keycount == v as i32 {
 | 
			
		||||
			match keycount <= v as i32 {
 | 
			
		||||
				true => ret.remove(&k),
 | 
			
		||||
				_ => ret.insert(k, keycount - v as i32),
 | 
			
		||||
			};
 | 
			
		||||
@ -771,8 +768,9 @@ mod tests {
 | 
			
		||||
			assert!(memtrie.db_items_remaining().is_empty());
 | 
			
		||||
			unpopulate_trie(&mut memtrie, &x);
 | 
			
		||||
			if *memtrie.root() != SHA3_NULL_RLP || !memtrie.db_items_remaining().is_empty() {
 | 
			
		||||
				println!("TRIE MISMATCH");
 | 
			
		||||
				println!("- TRIE MISMATCH");
 | 
			
		||||
				println!("");
 | 
			
		||||
				println!("remaining: {:?}", memtrie.db_items_remaining());
 | 
			
		||||
				println!("{:?} vs {:?}", memtrie.root(), real);
 | 
			
		||||
				for i in x.iter() {
 | 
			
		||||
					println!("{:?} -> {:?}", i.0.pretty(), i.1.pretty());
 | 
			
		||||
@ -811,7 +809,7 @@ mod tests {
 | 
			
		||||
		let mut t1 = TrieDBMut::new(&mut memdb, &mut root);
 | 
			
		||||
		t1.insert(&[0x01, 0x23], &big_value.to_vec());
 | 
			
		||||
		t1.insert(&[0x01, 0x34], &big_value.to_vec());
 | 
			
		||||
		trace!("keys remaining {:?}", t1.db_items_remaining());
 | 
			
		||||
		println!("********************** keys remaining {:?}", t1.db_items_remaining());
 | 
			
		||||
		assert!(t1.db_items_remaining().is_empty());
 | 
			
		||||
		let mut memdb2 = MemoryDB::new();
 | 
			
		||||
		let mut root2 = H256::new();
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										279
									
								
								src/uint.rs
									
									
									
									
									
								
							
							
						
						
									
										279
									
								
								src/uint.rs
									
									
									
									
									
								
							@ -23,6 +23,7 @@
 | 
			
		||||
 | 
			
		||||
use standard::*;
 | 
			
		||||
use from_json::*;
 | 
			
		||||
use std::num::wrapping::OverflowingOps;
 | 
			
		||||
 | 
			
		||||
macro_rules! impl_map_from {
 | 
			
		||||
	($thing:ident, $from:ty, $to:ty) => {
 | 
			
		||||
@ -34,6 +35,13 @@ macro_rules! impl_map_from {
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
macro_rules! panic_on_overflow {
 | 
			
		||||
	($name:expr) => {
 | 
			
		||||
		if $name {
 | 
			
		||||
			panic!("arithmetic operation overflow")
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
pub trait Uint: Sized + Default + FromStr + From<u64> + FromJson + fmt::Debug + fmt::Display + PartialOrd + Ord + PartialEq + Eq + Hash {
 | 
			
		||||
 | 
			
		||||
	/// Size of this type.
 | 
			
		||||
@ -183,13 +191,43 @@ macro_rules! construct_uint {
 | 
			
		||||
				for i in 0..$n_words {
 | 
			
		||||
					let upper = other as u64 * (arr[i] >> 32);
 | 
			
		||||
					let lower = other as u64 * (arr[i] & 0xFFFFFFFF);
 | 
			
		||||
					if i < 3 {
 | 
			
		||||
						carry[i + 1] += upper >> 32;
 | 
			
		||||
 | 
			
		||||
					ret[i] = lower.wrapping_add(upper << 32);
 | 
			
		||||
 | 
			
		||||
					if i < $n_words - 1 {
 | 
			
		||||
						carry[i + 1] = upper >> 32;
 | 
			
		||||
						if ret[i] < lower {
 | 
			
		||||
							carry[i + 1] += 1;
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
					ret[i] = lower + (upper << 32);
 | 
			
		||||
				}
 | 
			
		||||
				$name(ret) + $name(carry)
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			/// Overflowing multiplication by u32
 | 
			
		||||
			fn overflowing_mul_u32(self, other: u32) -> ($name, bool) {
 | 
			
		||||
				let $name(ref arr) = self;
 | 
			
		||||
				let mut carry = [0u64; $n_words];
 | 
			
		||||
				let mut ret = [0u64; $n_words];
 | 
			
		||||
				let mut overflow = false;
 | 
			
		||||
				for i in 0..$n_words {
 | 
			
		||||
					let upper = other as u64 * (arr[i] >> 32);
 | 
			
		||||
					let lower = other as u64 * (arr[i] & 0xFFFFFFFF);
 | 
			
		||||
 | 
			
		||||
					ret[i] = lower.wrapping_add(upper << 32);
 | 
			
		||||
 | 
			
		||||
					if i < $n_words - 1 {
 | 
			
		||||
						carry[i + 1] = upper >> 32;
 | 
			
		||||
						if ret[i] < lower {
 | 
			
		||||
							carry[i + 1] += 1;
 | 
			
		||||
						}
 | 
			
		||||
					} else if (upper >> 32) > 0 || ret[i] < lower {
 | 
			
		||||
						overflow = true
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				let (result, add_overflow) = $name(ret).overflowing_add($name(carry));
 | 
			
		||||
				(result, add_overflow || overflow)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		impl Default for $name {
 | 
			
		||||
@ -270,6 +308,77 @@ macro_rules! construct_uint {
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		impl OverflowingOps for $name {
 | 
			
		||||
			fn overflowing_add(self, other: $name) -> ($name, bool) {
 | 
			
		||||
				let $name(ref me) = self;
 | 
			
		||||
				let $name(ref you) = other;
 | 
			
		||||
				let mut ret = [0u64; $n_words];
 | 
			
		||||
				let mut carry = [0u64; $n_words];
 | 
			
		||||
				let mut b_carry = false;
 | 
			
		||||
				let mut overflow = false;
 | 
			
		||||
 | 
			
		||||
				for i in 0..$n_words {
 | 
			
		||||
					ret[i] = me[i].wrapping_add(you[i]);
 | 
			
		||||
 | 
			
		||||
					if ret[i] < me[i] {
 | 
			
		||||
						if i < $n_words - 1 {
 | 
			
		||||
							carry[i + 1] = 1;
 | 
			
		||||
							b_carry = true;
 | 
			
		||||
						} else {
 | 
			
		||||
							overflow = true
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				if b_carry { 
 | 
			
		||||
					let (ret, add_overflow) = $name(ret).overflowing_add($name(carry));
 | 
			
		||||
					(ret, add_overflow || overflow)
 | 
			
		||||
				} else { 
 | 
			
		||||
					($name(ret), overflow)
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			fn overflowing_sub(self, other: $name) -> ($name, bool) {
 | 
			
		||||
				let (res, _overflow) = (!other).overflowing_add(From::from(1u64));
 | 
			
		||||
				let (res, _overflow) = self.overflowing_add(res);
 | 
			
		||||
				(res, self < other)
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			fn overflowing_mul(self, other: $name) -> ($name, bool) {
 | 
			
		||||
				let mut res = $name::from(0u64);
 | 
			
		||||
				let mut overflow = false;
 | 
			
		||||
				// TODO: be more efficient about this
 | 
			
		||||
				for i in 0..(2 * $n_words) {
 | 
			
		||||
					let (v, mul_overflow) = self.overflowing_mul_u32((other >> (32 * i)).low_u32());
 | 
			
		||||
					let (new_res, add_overflow) = res.overflowing_add(v << (32 * i));
 | 
			
		||||
					res = new_res;
 | 
			
		||||
					overflow = overflow || mul_overflow || add_overflow;
 | 
			
		||||
				}
 | 
			
		||||
				(res, overflow)
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			fn overflowing_div(self, other: $name) -> ($name, bool) {
 | 
			
		||||
				(self / other, false)
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			fn overflowing_rem(self, other: $name) -> ($name, bool) {
 | 
			
		||||
				(self % other, false)
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			fn overflowing_neg(self) -> ($name, bool) {
 | 
			
		||||
				(!self, true)
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			fn overflowing_shl(self, _shift32: u32) -> ($name, bool) {
 | 
			
		||||
				// TODO [todr] not used for now
 | 
			
		||||
				unimplemented!();
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			fn overflowing_shr(self, _shift32: u32) -> ($name, bool) {
 | 
			
		||||
				// TODO [todr] not used for now
 | 
			
		||||
				unimplemented!();
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		impl Add<$name> for $name {
 | 
			
		||||
			type Output = $name;
 | 
			
		||||
 | 
			
		||||
@ -280,10 +389,14 @@ macro_rules! construct_uint {
 | 
			
		||||
				let mut carry = [0u64; $n_words];
 | 
			
		||||
				let mut b_carry = false;
 | 
			
		||||
				for i in 0..$n_words {
 | 
			
		||||
					ret[i] = me[i].wrapping_add(you[i]);
 | 
			
		||||
					if i < $n_words - 1 && ret[i] < me[i] {
 | 
			
		||||
						carry[i + 1] = 1;
 | 
			
		||||
						b_carry = true;
 | 
			
		||||
					if i < $n_words - 1 {
 | 
			
		||||
						ret[i] = me[i].wrapping_add(you[i]);
 | 
			
		||||
						if ret[i] < me[i] {
 | 
			
		||||
							carry[i + 1] = 1;
 | 
			
		||||
							b_carry = true;
 | 
			
		||||
						}
 | 
			
		||||
					} else {
 | 
			
		||||
						ret[i] = me[i] + you[i];
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				if b_carry { $name(ret) + $name(carry) } else { $name(ret) }
 | 
			
		||||
@ -295,7 +408,10 @@ macro_rules! construct_uint {
 | 
			
		||||
 | 
			
		||||
			#[inline]
 | 
			
		||||
			fn sub(self, other: $name) -> $name {
 | 
			
		||||
				self + !other + From::from(1u64)
 | 
			
		||||
				panic_on_overflow!(self < other);
 | 
			
		||||
				let (res, _overflow) = (!other).overflowing_add(From::from(1u64));
 | 
			
		||||
				let (res, _overflow) = self.overflowing_add(res);
 | 
			
		||||
				res
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
@ -337,7 +453,8 @@ macro_rules! construct_uint {
 | 
			
		||||
				loop {
 | 
			
		||||
					if sub_copy >= shift_copy {
 | 
			
		||||
						ret[shift / 64] |= 1 << (shift % 64);
 | 
			
		||||
						sub_copy = sub_copy - shift_copy;
 | 
			
		||||
						let (copy, _overflow) = sub_copy.overflowing_sub(shift_copy);
 | 
			
		||||
						sub_copy = copy
 | 
			
		||||
					}
 | 
			
		||||
					shift_copy = shift_copy >> 1;
 | 
			
		||||
					if shift == 0 { break; }
 | 
			
		||||
@ -426,7 +543,7 @@ macro_rules! construct_uint {
 | 
			
		||||
				let bit_shift = shift % 64;
 | 
			
		||||
				for i in 0..$n_words {
 | 
			
		||||
					// Shift
 | 
			
		||||
					if bit_shift < 64 && i + word_shift < $n_words {
 | 
			
		||||
					if i + word_shift < $n_words {
 | 
			
		||||
						ret[i + word_shift] += original[i] << bit_shift;
 | 
			
		||||
					}
 | 
			
		||||
					// Carry
 | 
			
		||||
@ -602,8 +719,9 @@ pub const BAD_U256: U256 = U256([0xffffffffffffffffu64; 4]);
 | 
			
		||||
 | 
			
		||||
#[cfg(test)]
 | 
			
		||||
mod tests {
 | 
			
		||||
	use uint::{Uint, U256};
 | 
			
		||||
	use uint::{Uint, U128, U256, U512};
 | 
			
		||||
	use std::str::FromStr;
 | 
			
		||||
	use std::num::wrapping::OverflowingOps;
 | 
			
		||||
 | 
			
		||||
	#[test]
 | 
			
		||||
	pub fn uint256_from() {
 | 
			
		||||
@ -729,7 +847,7 @@ mod tests {
 | 
			
		||||
		let incr = shr + U256::from(1u64);
 | 
			
		||||
		assert_eq!(incr, U256([0x7DDE000000000001u64, 0x0001BD5B7DDFBD5B, 0, 0]));
 | 
			
		||||
		// Subtraction
 | 
			
		||||
		let sub = incr - init;
 | 
			
		||||
		let (sub, _of) = incr.overflowing_sub(init);
 | 
			
		||||
		assert_eq!(sub, U256([0x9F30411021524112u64, 0x0001BD5B7DDFBD5A, 0, 0]));
 | 
			
		||||
		// Multiplication
 | 
			
		||||
		let mult = sub.mul_u32(300);
 | 
			
		||||
@ -777,10 +895,145 @@ mod tests {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	#[test]
 | 
			
		||||
	pub fn uint256_mul() {
 | 
			
		||||
	pub fn uint256_mul1() {
 | 
			
		||||
		assert_eq!(U256::from(1u64) * U256::from(10u64), U256::from(10u64));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	#[test]
 | 
			
		||||
	pub fn uint128_add() {
 | 
			
		||||
		assert_eq!(
 | 
			
		||||
			U128::from_str("fffffffffffffffff").unwrap() + U128::from_str("fffffffffffffffff").unwrap(),
 | 
			
		||||
			U128::from_str("1ffffffffffffffffe").unwrap()
 | 
			
		||||
		);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	#[test]
 | 
			
		||||
	pub fn uint128_add_overflow() {
 | 
			
		||||
		assert_eq!(
 | 
			
		||||
			U128::from_str("ffffffffffffffffffffffffffffffff").unwrap()
 | 
			
		||||
			.overflowing_add(
 | 
			
		||||
				U128::from_str("ffffffffffffffffffffffffffffffff").unwrap()
 | 
			
		||||
			),
 | 
			
		||||
			(U128::from_str("fffffffffffffffffffffffffffffffe").unwrap(), true)
 | 
			
		||||
		);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	#[test]
 | 
			
		||||
	#[should_panic]
 | 
			
		||||
	pub fn uint128_add_overflow_panic() {
 | 
			
		||||
		U128::from_str("ffffffffffffffffffffffffffffffff").unwrap()
 | 
			
		||||
		+
 | 
			
		||||
		U128::from_str("ffffffffffffffffffffffffffffffff").unwrap();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	#[test]
 | 
			
		||||
	pub fn uint128_mul() {
 | 
			
		||||
		assert_eq!(
 | 
			
		||||
			U128::from_str("fffffffff").unwrap() * U128::from_str("fffffffff").unwrap(),
 | 
			
		||||
			U128::from_str("ffffffffe000000001").unwrap());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	#[test]
 | 
			
		||||
	pub fn uint512_mul() {
 | 
			
		||||
		assert_eq!(
 | 
			
		||||
			U512::from_str("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap()
 | 
			
		||||
			*
 | 
			
		||||
			U512::from_str("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap(),
 | 
			
		||||
			U512::from_str("3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000001").unwrap()
 | 
			
		||||
		);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	#[test]
 | 
			
		||||
	pub fn uint256_mul_overflow() {
 | 
			
		||||
		assert_eq!(
 | 
			
		||||
			U256::from_str("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap()
 | 
			
		||||
			.overflowing_mul(
 | 
			
		||||
				U256::from_str("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap()
 | 
			
		||||
			),
 | 
			
		||||
			(U256::from_str("1").unwrap(), true)
 | 
			
		||||
			);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	#[test]
 | 
			
		||||
	#[should_panic]
 | 
			
		||||
	pub fn uint256_mul_overflow_panic() {
 | 
			
		||||
		U256::from_str("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap()
 | 
			
		||||
		*
 | 
			
		||||
		U256::from_str("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	#[test]
 | 
			
		||||
	pub fn uint256_sub_overflow() {
 | 
			
		||||
		assert_eq!(
 | 
			
		||||
			U256::from_str("0").unwrap()
 | 
			
		||||
			.overflowing_sub(
 | 
			
		||||
				U256::from_str("1").unwrap()
 | 
			
		||||
			),
 | 
			
		||||
			(U256::from_str("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap(), true)
 | 
			
		||||
			);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	#[test]
 | 
			
		||||
	#[should_panic]
 | 
			
		||||
	pub fn uint256_sub_overflow_panic() {
 | 
			
		||||
		U256::from_str("0").unwrap()
 | 
			
		||||
		-
 | 
			
		||||
		U256::from_str("1").unwrap();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	#[ignore]
 | 
			
		||||
	#[test]
 | 
			
		||||
	pub fn uint256_shl_overflow() {
 | 
			
		||||
		assert_eq!(
 | 
			
		||||
			U256::from_str("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap()
 | 
			
		||||
			.overflowing_shl(4),
 | 
			
		||||
			(U256::from_str("fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0").unwrap(), true)
 | 
			
		||||
		);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	#[ignore]
 | 
			
		||||
	#[test]
 | 
			
		||||
	#[should_panic]
 | 
			
		||||
	pub fn uint256_shl_overflow2() {
 | 
			
		||||
		assert_eq!(
 | 
			
		||||
			U256::from_str("0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap()
 | 
			
		||||
			.overflowing_shl(4),
 | 
			
		||||
			(U256::from_str("fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0").unwrap(), false)
 | 
			
		||||
		);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	#[ignore]
 | 
			
		||||
	#[test]
 | 
			
		||||
	pub fn uint256_shr_overflow() {
 | 
			
		||||
		assert_eq!(
 | 
			
		||||
			U256::from_str("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap()
 | 
			
		||||
			.overflowing_shr(4),
 | 
			
		||||
			(U256::from_str("0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap(), true)
 | 
			
		||||
		);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	#[ignore]
 | 
			
		||||
	#[test]
 | 
			
		||||
	pub fn uint256_shr_overflow2() {
 | 
			
		||||
		assert_eq!(
 | 
			
		||||
			U256::from_str("fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0").unwrap()
 | 
			
		||||
			.overflowing_shr(4),
 | 
			
		||||
			(U256::from_str("0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap(), false)
 | 
			
		||||
		);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	#[test]
 | 
			
		||||
	pub fn uint256_mul() {
 | 
			
		||||
		assert_eq!(
 | 
			
		||||
			U256::from_str("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap()
 | 
			
		||||
			*
 | 
			
		||||
			U256::from_str("2").unwrap(),
 | 
			
		||||
			U256::from_str("fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe").unwrap()
 | 
			
		||||
			);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	#[test]
 | 
			
		||||
	fn uint256_div() {
 | 
			
		||||
		assert_eq!(U256::from(10u64) /  U256::from(1u64), U256::from(10u64));
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user