Merge branch 'master' of github.com:ethcore/parity into chain_generator
This commit is contained in:
commit
38d74bf78c
3
.gitignore
vendored
3
.gitignore
vendored
@ -27,3 +27,6 @@
|
||||
# jetbrains ide stuff
|
||||
.idea
|
||||
*.iml
|
||||
|
||||
# Build artifacts
|
||||
out/
|
||||
|
@ -19,7 +19,7 @@ First (if you don't already have it) get multirust:
|
||||
|
||||
- Linux:
|
||||
```bash
|
||||
curl -sf https://raw.githubusercontent.com/brson/multirust/master/blastoff.sh | sudo sh -s -- --yes
|
||||
curl -sf https://raw.githubusercontent.com/brson/multirust/master/quick-install.sh | sudo sh -s -- --yes
|
||||
```
|
||||
|
||||
- OSX with Homebrew:
|
||||
|
@ -1,9 +1,9 @@
|
||||
{
|
||||
"name": "Frontier",
|
||||
"name": "Frontier/Homestead",
|
||||
"engineName": "Ethash",
|
||||
"params": {
|
||||
"accountStartNonce": "0x00",
|
||||
"frontierCompatibilityModeLimit": "0x10c8e0",
|
||||
"frontierCompatibilityModeLimit": "0x118c30",
|
||||
"maximumExtraDataSize": "0x20",
|
||||
"tieBreakingGas": false,
|
||||
"minGasLimit": "0x1388",
|
||||
|
@ -3,7 +3,7 @@
|
||||
"engineName": "Ethash",
|
||||
"params": {
|
||||
"accountStartNonce": "0x00",
|
||||
"frontierCompatibilityModeLimit": "0x10c8e0",
|
||||
"frontierCompatibilityModeLimit": "0x118c30",
|
||||
"maximumExtraDataSize": "0x20",
|
||||
"tieBreakingGas": false,
|
||||
"minGasLimit": "0x1388",
|
||||
|
@ -115,7 +115,7 @@ declare_test!{StateTests_stSolidityTest, "StateTests/stSolidityTest"}
|
||||
declare_test!{StateTests_stSpecialTest, "StateTests/stSpecialTest"}
|
||||
declare_test!{StateTests_stSystemOperationsTest, "StateTests/stSystemOperationsTest"}
|
||||
declare_test!{StateTests_stTransactionTest, "StateTests/stTransactionTest"}
|
||||
declare_test!{StateTests_stTransitionTest, "StateTests/stTransitionTest"}
|
||||
//declare_test!{StateTests_stTransitionTest, "StateTests/stTransitionTest"}
|
||||
declare_test!{StateTests_stWalletTest, "StateTests/stWalletTest"}
|
||||
|
||||
|
||||
|
@ -245,8 +245,8 @@ impl ChainSync {
|
||||
start_block_number: self.starting_block,
|
||||
last_imported_block_number: self.last_imported_block,
|
||||
highest_block_number: self.highest_block,
|
||||
blocks_received: match self.last_imported_block { None => 0, Some(x) => x - self.starting_block },
|
||||
blocks_total: match self.highest_block { None => 0, Some(x) => x - self.starting_block },
|
||||
blocks_received: match self.last_imported_block { Some(x) if x > self.starting_block => x - self.starting_block, _ => 0 },
|
||||
blocks_total: match self.highest_block { Some(x) if x > self.starting_block => x - self.starting_block, _ => 0 },
|
||||
num_peers: self.peers.len(),
|
||||
num_active_peers: self.peers.values().filter(|p| p.asking != PeerAsking::Nothing).count(),
|
||||
mem_used:
|
||||
|
@ -117,7 +117,7 @@ impl BlockChainClient for TestBlockChainClient {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn logs(&self, filter: Filter) -> Vec<LocalizedLogEntry> {
|
||||
fn logs(&self, _filter: Filter) -> Vec<LocalizedLogEntry> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
|
@ -74,6 +74,19 @@ fn u256_mul(b: &mut Bencher) {
|
||||
}
|
||||
|
||||
|
||||
#[bench]
|
||||
fn u256_full_mul(b: &mut Bencher) {
|
||||
b.iter(|| {
|
||||
let n = black_box(10000);
|
||||
(0..n).fold(U256([rand::random::<u64>(), rand::random::<u64>(), rand::random::<u64>(), rand::random::<u64>()]),
|
||||
|old, new| {
|
||||
let U512(ref u512words) = old.full_mul(U256([rand::random::<u64>(), rand::random::<u64>(), rand::random::<u64>(), rand::random::<u64>()]));
|
||||
U256([u512words[0], u512words[2], u512words[2], u512words[3]])
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
#[bench]
|
||||
fn u128_mul(b: &mut Bencher) {
|
||||
b.iter(|| {
|
||||
|
@ -46,14 +46,14 @@ pub fn enumerate_geth_keys(path: &Path) -> Result<Vec<(Address, String)>, io::Er
|
||||
#[derive(Debug)]
|
||||
pub enum ImportError {
|
||||
/// Io error reading geth file
|
||||
IoError(io::Error),
|
||||
Io(io::Error),
|
||||
/// format error
|
||||
FormatError,
|
||||
Format,
|
||||
}
|
||||
|
||||
impl From<io::Error> for ImportError {
|
||||
fn from (err: io::Error) -> ImportError {
|
||||
ImportError::IoError(err)
|
||||
ImportError::Io(err)
|
||||
}
|
||||
}
|
||||
|
||||
@ -65,15 +65,15 @@ pub fn import_geth_key(secret_store: &mut SecretStore, geth_keyfile_path: &Path)
|
||||
|
||||
let mut json_result = Json::from_str(&buf);
|
||||
let mut json = match json_result {
|
||||
Ok(ref mut parsed_json) => try!(parsed_json.as_object_mut().ok_or(ImportError::FormatError)),
|
||||
Err(_) => { return Err(ImportError::FormatError); }
|
||||
Ok(ref mut parsed_json) => try!(parsed_json.as_object_mut().ok_or(ImportError::Format)),
|
||||
Err(_) => { return Err(ImportError::Format); }
|
||||
};
|
||||
let crypto_object = try!(json.get("Crypto").and_then(|crypto| crypto.as_object()).ok_or(ImportError::FormatError)).clone();
|
||||
let crypto_object = try!(json.get("Crypto").and_then(|crypto| crypto.as_object()).ok_or(ImportError::Format)).clone();
|
||||
json.insert("crypto".to_owned(), Json::Object(crypto_object));
|
||||
json.remove("Crypto");
|
||||
match KeyFileContent::load(&Json::Object(json.clone())) {
|
||||
Ok(key_file) => try!(secret_store.import_key(key_file)),
|
||||
Err(_) => { return Err(ImportError::FormatError); }
|
||||
Err(_) => { return Err(ImportError::Format); }
|
||||
};
|
||||
Ok(())
|
||||
}
|
||||
@ -82,7 +82,7 @@ pub fn import_geth_key(secret_store: &mut SecretStore, geth_keyfile_path: &Path)
|
||||
pub fn import_geth_keys(secret_store: &mut SecretStore, geth_keyfiles_directory: &Path) -> Result<(), ImportError> {
|
||||
use std::path::PathBuf;
|
||||
let geth_files = try!(enumerate_geth_keys(geth_keyfiles_directory));
|
||||
for &(ref address, ref file_path) in geth_files.iter() {
|
||||
for &(ref address, ref file_path) in &geth_files {
|
||||
let mut path = PathBuf::new();
|
||||
path.push(geth_keyfiles_directory);
|
||||
path.push(file_path);
|
||||
|
@ -144,6 +144,7 @@ pub mod network;
|
||||
pub mod log;
|
||||
pub mod panics;
|
||||
pub mod keys;
|
||||
pub mod table;
|
||||
|
||||
pub use common::*;
|
||||
pub use misc::*;
|
||||
|
@ -376,7 +376,7 @@ impl<Message> Host<Message> where Message: Send + Sync + Clone {
|
||||
let entry = NodeEntry { endpoint: n.endpoint.clone(), id: n.id.clone() };
|
||||
self.pinned_nodes.push(n.id.clone());
|
||||
self.nodes.write().unwrap().add_node(n);
|
||||
if let &mut Some(ref mut discovery) = self.discovery.lock().unwrap().deref_mut() {
|
||||
if let Some(ref mut discovery) = *self.discovery.lock().unwrap().deref_mut() {
|
||||
discovery.add_node(entry);
|
||||
}
|
||||
}
|
||||
@ -418,7 +418,7 @@ impl<Message> Host<Message> where Message: Send + Sync + Clone {
|
||||
}
|
||||
Some(addr) => NodeEndpoint { address: addr, udp_port: udp_port }
|
||||
};
|
||||
|
||||
|
||||
// Setup the server socket
|
||||
*tcp_listener = Some(TcpListener::bind(&listen_address).unwrap());
|
||||
self.info.write().unwrap().public_endpoint = public_endpoint.clone();
|
||||
@ -697,7 +697,7 @@ impl<Message> Host<Message> where Message: Send + Sync + Clone {
|
||||
let entry = NodeEntry { id: session.id().clone(), endpoint: NodeEndpoint { address: address, udp_port: address.port() } };
|
||||
self.nodes.write().unwrap().add_node(Node::new(entry.id.clone(), entry.endpoint.clone()));
|
||||
let mut discovery = self.discovery.lock().unwrap();
|
||||
if let &mut Some(ref mut discovery) = discovery.deref_mut() {
|
||||
if let Some(ref mut discovery) = *discovery.deref_mut() {
|
||||
discovery.add_node(entry);
|
||||
}
|
||||
}
|
||||
|
254
util/src/table.rs
Normal file
254
util/src/table.rs
Normal file
@ -0,0 +1,254 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//! A collection associating pair of keys (row and column) with a single value.
|
||||
|
||||
use std::hash::Hash;
|
||||
use std::collections::HashMap;
|
||||
|
||||
/// Structure to hold double-indexed values
|
||||
///
|
||||
/// You can obviously use `HashMap<(Row,Col), Val>`, but this structure gives
|
||||
/// you better access to all `Columns` in Specific `Row`. Namely you can get sub-hashmap
|
||||
/// `HashMap<Col, Val>` for specific `Row`
|
||||
pub struct Table<Row, Col, Val>
|
||||
where Row: Eq + Hash + Clone,
|
||||
Col: Eq + Hash {
|
||||
map: HashMap<Row, HashMap<Col, Val>>,
|
||||
}
|
||||
|
||||
impl<Row, Col, Val> Table<Row, Col, Val>
|
||||
where Row: Eq + Hash + Clone,
|
||||
Col: Eq + Hash {
|
||||
/// Creates new Table
|
||||
pub fn new() -> Table<Row, Col, Val> {
|
||||
Table {
|
||||
map: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Removes all elements from this Table
|
||||
pub fn clear(&mut self) {
|
||||
self.map.clear();
|
||||
}
|
||||
|
||||
/// Returns length of the Table (number of (row, col, val) tuples)
|
||||
pub fn len(&self) -> usize {
|
||||
self.map.values().fold(0, |acc, v| acc + v.len())
|
||||
}
|
||||
|
||||
/// Check if there is any element in this Table
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.map.is_empty() || self.map.values().all(|v| v.is_empty())
|
||||
}
|
||||
|
||||
/// Get mutable reference for single Table row.
|
||||
pub fn row_mut(&mut self, row: &Row) -> Option<&mut HashMap<Col, Val>> {
|
||||
self.map.get_mut(row)
|
||||
}
|
||||
|
||||
/// Checks if row is defined for that table (note that even if defined it might be empty)
|
||||
pub fn has_row(&self, row: &Row) -> bool {
|
||||
self.map.contains_key(row)
|
||||
}
|
||||
|
||||
/// Get immutable reference for single row in this Table
|
||||
pub fn row(&self, row: &Row) -> Option<&HashMap<Col, Val>> {
|
||||
self.map.get(row)
|
||||
}
|
||||
|
||||
/// Get element in cell described by `(row, col)`
|
||||
pub fn get(&self, row: &Row, col: &Col) -> Option<&Val> {
|
||||
self.map.get(row).and_then(|r| r.get(col))
|
||||
}
|
||||
|
||||
/// Remove value from specific cell
|
||||
///
|
||||
/// It will remove the row if it's the last value in it
|
||||
pub fn remove(&mut self, row: &Row, col: &Col) -> Option<Val> {
|
||||
let (val, is_empty) = {
|
||||
let row_map = self.map.get_mut(row);
|
||||
if let None = row_map {
|
||||
return None;
|
||||
}
|
||||
let mut row_map = row_map.unwrap();
|
||||
let val = row_map.remove(col);
|
||||
(val, row_map.is_empty())
|
||||
};
|
||||
// Clean row
|
||||
if is_empty {
|
||||
self.map.remove(row);
|
||||
}
|
||||
val
|
||||
}
|
||||
|
||||
/// Remove given row from Table if there are no values defined in it
|
||||
///
|
||||
/// When using `#row_mut` it may happen that all values from some row are drained.
|
||||
/// Table however will not be aware that row is empty.
|
||||
/// You can use this method to explicitly remove row entry from the Table.
|
||||
pub fn clear_if_empty(&mut self, row: &Row) {
|
||||
let is_empty = self.map.get(row).map_or(false, |m| m.is_empty());
|
||||
if is_empty {
|
||||
self.map.remove(row);
|
||||
}
|
||||
}
|
||||
|
||||
/// Inserts new value to specified cell
|
||||
///
|
||||
/// Returns previous value (if any)
|
||||
pub fn insert(&mut self, row: Row, col: Col, val: Val) -> Option<Val> {
|
||||
self.map.entry(row).or_insert_with(|| HashMap::new()).insert(col, val)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn should_create_empty_table() {
|
||||
// when
|
||||
let table : Table<usize, usize, bool> = Table::new();
|
||||
|
||||
// then
|
||||
assert!(table.is_empty());
|
||||
assert_eq!(table.len(), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_insert_elements_and_return_previous_if_any() {
|
||||
// given
|
||||
let mut table = Table::new();
|
||||
|
||||
// when
|
||||
let r1 = table.insert(5, 4, true);
|
||||
let r2 = table.insert(10, 4, true);
|
||||
let r3 = table.insert(10, 10, true);
|
||||
let r4 = table.insert(10, 10, false);
|
||||
|
||||
// then
|
||||
assert!(r1.is_none());
|
||||
assert!(r2.is_none());
|
||||
assert!(r3.is_none());
|
||||
assert!(r4.is_some());
|
||||
assert!(!table.is_empty());
|
||||
assert_eq!(r4.unwrap(), true);
|
||||
assert_eq!(table.len(), 3);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_remove_element() {
|
||||
// given
|
||||
let mut table = Table::new();
|
||||
table.insert(5, 4, true);
|
||||
assert!(!table.is_empty());
|
||||
assert_eq!(table.len(), 1);
|
||||
|
||||
// when
|
||||
let r = table.remove(&5, &4);
|
||||
|
||||
// then
|
||||
assert!(table.is_empty());
|
||||
assert_eq!(table.len() ,0);
|
||||
assert_eq!(r.unwrap(), true);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_return_none_if_trying_to_remove_non_existing_element() {
|
||||
// given
|
||||
let mut table : Table<usize, usize, usize> = Table::new();
|
||||
assert!(table.is_empty());
|
||||
|
||||
// when
|
||||
let r = table.remove(&5, &4);
|
||||
|
||||
// then
|
||||
assert!(r.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_clear_row_if_removing_last_element() {
|
||||
// given
|
||||
let mut table = Table::new();
|
||||
table.insert(5, 4, true);
|
||||
assert!(table.has_row(&5));
|
||||
|
||||
// when
|
||||
let r = table.remove(&5, &4);
|
||||
|
||||
// then
|
||||
assert!(r.is_some());
|
||||
assert!(!table.has_row(&5));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_return_element_given_row_and_col() {
|
||||
// given
|
||||
let mut table = Table::new();
|
||||
table.insert(1551, 1234, 123);
|
||||
|
||||
// when
|
||||
let r1 = table.get(&1551, &1234);
|
||||
let r2 = table.get(&5, &4);
|
||||
|
||||
// then
|
||||
assert!(r1.is_some());
|
||||
assert!(r2.is_none());
|
||||
assert_eq!(r1.unwrap(), &123);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_clear_table() {
|
||||
// given
|
||||
let mut table = Table::new();
|
||||
table.insert(1, 1, true);
|
||||
table.insert(1, 2, false);
|
||||
table.insert(2, 2, false);
|
||||
assert_eq!(table.len(), 3);
|
||||
|
||||
// when
|
||||
table.clear();
|
||||
|
||||
// then
|
||||
assert!(table.is_empty());
|
||||
assert_eq!(table.len(), 0);
|
||||
assert_eq!(table.has_row(&1), false);
|
||||
assert_eq!(table.has_row(&2), false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_return_mutable_row() {
|
||||
// given
|
||||
let mut table = Table::new();
|
||||
table.insert(1, 1, true);
|
||||
table.insert(1, 2, false);
|
||||
table.insert(2, 2, false);
|
||||
|
||||
// when
|
||||
{
|
||||
let mut row = table.row_mut(&1).unwrap();
|
||||
row.remove(&1);
|
||||
row.remove(&2);
|
||||
}
|
||||
assert!(table.has_row(&1));
|
||||
table.clear_if_empty(&1);
|
||||
|
||||
// then
|
||||
assert!(!table.has_row(&1));
|
||||
assert_eq!(table.len(), 1);
|
||||
}
|
||||
}
|
257
util/src/uint.rs
257
util/src/uint.rs
@ -1097,6 +1097,157 @@ construct_uint!(U512, 8);
|
||||
construct_uint!(U256, 4);
|
||||
construct_uint!(U128, 2);
|
||||
|
||||
impl U256 {
|
||||
/// Multiplies two 256-bit integers to produce full 512-bit integer
|
||||
/// No overflow possible
|
||||
#[cfg(all(x64asm, target_arch="x86_64"))]
|
||||
pub fn full_mul(self, other: U256) -> U512 {
|
||||
let self_t: &[u64; 4] = unsafe { &mem::transmute(self) };
|
||||
let other_t: &[u64; 4] = unsafe { &mem::transmute(other) };
|
||||
let mut result: [u64; 8] = unsafe { mem::uninitialized() };
|
||||
unsafe {
|
||||
asm!("
|
||||
mov $8, %rax
|
||||
mulq $12
|
||||
mov %rax, $0
|
||||
mov %rdx, $1
|
||||
|
||||
mov $8, %rax
|
||||
mulq $13
|
||||
add %rax, $1
|
||||
adc $$0, %rdx
|
||||
mov %rdx, $2
|
||||
|
||||
mov $8, %rax
|
||||
mulq $14
|
||||
add %rax, $2
|
||||
adc $$0, %rdx
|
||||
mov %rdx, $3
|
||||
|
||||
mov $8, %rax
|
||||
mulq $15
|
||||
add %rax, $3
|
||||
adc $$0, %rdx
|
||||
mov %rdx, $4
|
||||
|
||||
mov $9, %rax
|
||||
mulq $12
|
||||
add %rax, $1
|
||||
adc %rdx, $2
|
||||
adc $$0, $3
|
||||
adc $$0, $4
|
||||
xor $5, $5
|
||||
adc $$0, $5
|
||||
xor $6, $6
|
||||
adc $$0, $6
|
||||
xor $7, $7
|
||||
adc $$0, $7
|
||||
|
||||
mov $9, %rax
|
||||
mulq $13
|
||||
add %rax, $2
|
||||
adc %rdx, $3
|
||||
adc $$0, $4
|
||||
adc $$0, $5
|
||||
adc $$0, $6
|
||||
adc $$0, $7
|
||||
|
||||
mov $9, %rax
|
||||
mulq $14
|
||||
add %rax, $3
|
||||
adc %rdx, $4
|
||||
adc $$0, $5
|
||||
adc $$0, $6
|
||||
adc $$0, $7
|
||||
|
||||
mov $9, %rax
|
||||
mulq $15
|
||||
add %rax, $4
|
||||
adc %rdx, $5
|
||||
adc $$0, $6
|
||||
adc $$0, $7
|
||||
|
||||
mov $10, %rax
|
||||
mulq $12
|
||||
add %rax, $2
|
||||
adc %rdx, $3
|
||||
adc $$0, $4
|
||||
adc $$0, $5
|
||||
adc $$0, $6
|
||||
adc $$0, $7
|
||||
|
||||
mov $10, %rax
|
||||
mulq $13
|
||||
add %rax, $3
|
||||
adc %rdx, $4
|
||||
adc $$0, $5
|
||||
adc $$0, $6
|
||||
adc $$0, $7
|
||||
|
||||
mov $10, %rax
|
||||
mulq $14
|
||||
add %rax, $4
|
||||
adc %rdx, $5
|
||||
adc $$0, $6
|
||||
adc $$0, $7
|
||||
|
||||
mov $10, %rax
|
||||
mulq $15
|
||||
add %rax, $5
|
||||
adc %rdx, $6
|
||||
adc $$0, $7
|
||||
|
||||
mov $11, %rax
|
||||
mulq $12
|
||||
add %rax, $3
|
||||
adc %rdx, $4
|
||||
adc $$0, $5
|
||||
adc $$0, $6
|
||||
adc $$0, $7
|
||||
|
||||
mov $11, %rax
|
||||
mulq $13
|
||||
add %rax, $4
|
||||
adc %rdx, $5
|
||||
adc $$0, $6
|
||||
adc $$0, $7
|
||||
|
||||
mov $11, %rax
|
||||
mulq $14
|
||||
add %rax, $5
|
||||
adc %rdx, $6
|
||||
adc $$0, $7
|
||||
|
||||
mov $11, %rax
|
||||
mulq $15
|
||||
add %rax, $6
|
||||
adc %rdx, $7
|
||||
"
|
||||
: /* $0 */ "={r8}"(result[0]), /* $1 */ "={r9}"(result[1]), /* $2 */ "={r10}"(result[2]),
|
||||
/* $3 */ "={r11}"(result[3]), /* $4 */ "={r12}"(result[4]), /* $5 */ "={r13}"(result[5]),
|
||||
/* $6 */ "={r14}"(result[6]), /* $7 */ "={r15}"(result[7])
|
||||
|
||||
: /* $8 */ "m"(self_t[0]), /* $9 */ "m"(self_t[1]), /* $10 */ "m"(self_t[2]),
|
||||
/* $11 */ "m"(self_t[3]), /* $12 */ "m"(other_t[0]), /* $13 */ "m"(other_t[1]),
|
||||
/* $14 */ "m"(other_t[2]), /* $15 */ "m"(other_t[3])
|
||||
: "rax", "rdx"
|
||||
:
|
||||
);
|
||||
}
|
||||
U512(result)
|
||||
}
|
||||
|
||||
/// Multiplies two 256-bit integers to produce full 512-bit integer
|
||||
/// No overflow possible
|
||||
#[cfg(not(all(x64asm, target_arch="x86_64")))]
|
||||
pub fn full_mul(self, other: U256) -> U512 {
|
||||
let self_512 = U512::from(self);
|
||||
let other_512 = U512::from(other);
|
||||
let (result, _) = self_512.overflowing_mul(other_512);
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
impl From<U256> for U512 {
|
||||
fn from(value: U256) -> U512 {
|
||||
let U256(ref arr) = value;
|
||||
@ -1828,5 +1979,111 @@ mod tests {
|
||||
let (_, overflow) = U256([0, 0, 8, 0]).overflowing_mul(U256([0, 0, 7, 0]));
|
||||
assert!(overflow);
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn u256_multi_full_mul() {
|
||||
let result = U256([0, 0, 0, 0]).full_mul(U256([0, 0, 0, 0]));
|
||||
assert_eq!(U512([0, 0, 0, 0, 0, 0, 0, 0]), result);
|
||||
|
||||
let result = U256([1, 0, 0, 0]).full_mul(U256([1, 0, 0, 0]));
|
||||
assert_eq!(U512([1, 0, 0, 0, 0, 0, 0, 0]), result);
|
||||
|
||||
let result = U256([5, 0, 0, 0]).full_mul(U256([5, 0, 0, 0]));
|
||||
assert_eq!(U512([25, 0, 0, 0, 0, 0, 0, 0]), result);
|
||||
|
||||
let result = U256([0, 5, 0, 0]).full_mul(U256([0, 5, 0, 0]));
|
||||
assert_eq!(U512([0, 0, 25, 0, 0, 0, 0, 0]), result);
|
||||
|
||||
let result = U256([0, 0, 0, 4]).full_mul(U256([4, 0, 0, 0]));
|
||||
assert_eq!(U512([0, 0, 0, 16, 0, 0, 0, 0]), result);
|
||||
|
||||
let result = U256([0, 0, 0, 5]).full_mul(U256([2, 0, 0, 0]));
|
||||
assert_eq!(U512([0, 0, 0, 10, 0, 0, 0, 0]), result);
|
||||
|
||||
let result = U256([0, 0, 2, 0]).full_mul(U256([0, 5, 0, 0]));
|
||||
assert_eq!(U512([0, 0, 0, 10, 0, 0, 0, 0]), result);
|
||||
|
||||
let result = U256([0, 3, 0, 0]).full_mul(U256([0, 0, 3, 0]));
|
||||
assert_eq!(U512([0, 0, 0, 9, 0, 0, 0, 0]), result);
|
||||
|
||||
let result = U256([0, 0, 8, 0]).full_mul(U256([0, 0, 6, 0]));
|
||||
assert_eq!(U512([0, 0, 0, 0, 48, 0, 0, 0]), result);
|
||||
|
||||
let result = U256([9, 0, 0, 0]).full_mul(U256([0, 3, 0, 0]));
|
||||
assert_eq!(U512([0, 27, 0, 0, 0, 0, 0, 0]), result);
|
||||
|
||||
let result = U256([::std::u64::MAX, 0, 0, 0]).full_mul(U256([::std::u64::MAX, 0, 0, 0]));
|
||||
assert_eq!(U512([1, ::std::u64::MAX-1, 0, 0, 0, 0, 0, 0]), result);
|
||||
|
||||
let result = U256([0, ::std::u64::MAX, 0, 0]).full_mul(U256([::std::u64::MAX, 0, 0, 0]));
|
||||
assert_eq!(U512([0, 1, ::std::u64::MAX-1, 0, 0, 0, 0, 0]), result);
|
||||
|
||||
let result = U256([::std::u64::MAX, ::std::u64::MAX, 0, 0]).full_mul(U256([::std::u64::MAX, 0, 0, 0]));
|
||||
assert_eq!(U512([1, ::std::u64::MAX, ::std::u64::MAX-1, 0, 0, 0, 0, 0]), result);
|
||||
|
||||
let result = U256([::std::u64::MAX, 0, 0, 0]).full_mul(U256([::std::u64::MAX, ::std::u64::MAX, 0, 0]));
|
||||
assert_eq!(U512([1, ::std::u64::MAX, ::std::u64::MAX-1, 0, 0, 0, 0, 0]), result);
|
||||
|
||||
let result = U256([::std::u64::MAX, ::std::u64::MAX, 0, 0]).full_mul(U256([::std::u64::MAX, ::std::u64::MAX, 0, 0]));
|
||||
assert_eq!(U512([1, 0, ::std::u64::MAX-1, ::std::u64::MAX, 0, 0, 0, 0]), result);
|
||||
|
||||
let result = U256([::std::u64::MAX, 0, 0, 0]).full_mul(U256([::std::u64::MAX, ::std::u64::MAX, ::std::u64::MAX, 0]));
|
||||
assert_eq!(U512([1, ::std::u64::MAX, ::std::u64::MAX, ::std::u64::MAX-1, 0, 0, 0, 0]), result);
|
||||
|
||||
let result = U256([::std::u64::MAX, ::std::u64::MAX, ::std::u64::MAX, 0]).full_mul(U256([::std::u64::MAX, 0, 0, 0]));
|
||||
assert_eq!(U512([1, ::std::u64::MAX, ::std::u64::MAX, ::std::u64::MAX-1, 0, 0, 0, 0]), result);
|
||||
|
||||
let result = U256([::std::u64::MAX, 0, 0, 0]).full_mul(U256([::std::u64::MAX, ::std::u64::MAX, ::std::u64::MAX, ::std::u64::MAX]));
|
||||
assert_eq!(U512([1, ::std::u64::MAX, ::std::u64::MAX, ::std::u64::MAX, ::std::u64::MAX-1, 0, 0, 0]), result);
|
||||
|
||||
let result = U256([::std::u64::MAX, ::std::u64::MAX, ::std::u64::MAX, ::std::u64::MAX]).full_mul(U256([::std::u64::MAX, 0, 0, 0]));
|
||||
assert_eq!(U512([1, ::std::u64::MAX, ::std::u64::MAX, ::std::u64::MAX, ::std::u64::MAX-1, 0, 0, 0]), result);
|
||||
|
||||
let result = U256([::std::u64::MAX, ::std::u64::MAX, ::std::u64::MAX, 0]).full_mul(U256([::std::u64::MAX, ::std::u64::MAX, 0, 0]));
|
||||
assert_eq!(U512([1, 0, ::std::u64::MAX, ::std::u64::MAX-1, ::std::u64::MAX, 0, 0, 0]), result);
|
||||
|
||||
let result = U256([::std::u64::MAX, ::std::u64::MAX, 0, 0]).full_mul(U256([::std::u64::MAX, ::std::u64::MAX, ::std::u64::MAX, 0]));
|
||||
assert_eq!(U512([1, 0, ::std::u64::MAX, ::std::u64::MAX-1, ::std::u64::MAX, 0, 0, 0]), result);
|
||||
|
||||
let result = U256([::std::u64::MAX, ::std::u64::MAX, ::std::u64::MAX, ::std::u64::MAX]).full_mul(U256([::std::u64::MAX, ::std::u64::MAX, 0, 0]));
|
||||
assert_eq!(U512([1, 0, ::std::u64::MAX, ::std::u64::MAX, ::std::u64::MAX-1, ::std::u64::MAX, 0, 0]), result);
|
||||
|
||||
let result = U256([::std::u64::MAX, ::std::u64::MAX, 0, 0]).full_mul(U256([::std::u64::MAX, ::std::u64::MAX, ::std::u64::MAX, ::std::u64::MAX]));
|
||||
assert_eq!(U512([1, 0, ::std::u64::MAX, ::std::u64::MAX, ::std::u64::MAX-1, ::std::u64::MAX, 0, 0]), result);
|
||||
|
||||
let result = U256([::std::u64::MAX, ::std::u64::MAX, ::std::u64::MAX, 0]).full_mul(U256([::std::u64::MAX, ::std::u64::MAX, ::std::u64::MAX, 0]));
|
||||
assert_eq!(U512([1, 0, 0, ::std::u64::MAX-1, ::std::u64::MAX, ::std::u64::MAX, 0, 0]), result);
|
||||
|
||||
let result = U256([::std::u64::MAX, ::std::u64::MAX, ::std::u64::MAX, 0]).full_mul(U256([::std::u64::MAX, ::std::u64::MAX, ::std::u64::MAX, ::std::u64::MAX]));
|
||||
assert_eq!(U512([1, 0, 0, ::std::u64::MAX, ::std::u64::MAX-1, ::std::u64::MAX, ::std::u64::MAX, 0]), result);
|
||||
|
||||
let result = U256([::std::u64::MAX, ::std::u64::MAX, ::std::u64::MAX, ::std::u64::MAX]).full_mul(U256([::std::u64::MAX, ::std::u64::MAX, ::std::u64::MAX, 0]));
|
||||
assert_eq!(U512([1, 0, 0, ::std::u64::MAX, ::std::u64::MAX-1, ::std::u64::MAX, ::std::u64::MAX, 0]), result);
|
||||
|
||||
let result = U256([::std::u64::MAX, ::std::u64::MAX, ::std::u64::MAX, ::std::u64::MAX]).full_mul(U256([::std::u64::MAX, ::std::u64::MAX, ::std::u64::MAX, ::std::u64::MAX]));
|
||||
assert_eq!(U512([1, 0, 0, 0, ::std::u64::MAX-1, ::std::u64::MAX, ::std::u64::MAX, ::std::u64::MAX]), result);
|
||||
|
||||
let result = U256([0, 0, 0, ::std::u64::MAX]).full_mul(U256([0, 0, 0, ::std::u64::MAX]));
|
||||
assert_eq!(U512([0, 0, 0, 0, 0, 0, 1, ::std::u64::MAX-1]), result);
|
||||
|
||||
let result = U256([1, 0, 0, 0]).full_mul(U256([0, 0, 0, ::std::u64::MAX]));
|
||||
assert_eq!(U512([0, 0, 0, ::std::u64::MAX, 0, 0, 0, 0]), result);
|
||||
|
||||
let result = U256([1, 2, 3, 4]).full_mul(U256([5, 0, 0, 0]));
|
||||
assert_eq!(U512([5, 10, 15, 20, 0, 0, 0, 0]), result);
|
||||
|
||||
let result = U256([1, 2, 3, 4]).full_mul(U256([0, 6, 0, 0]));
|
||||
assert_eq!(U512([0, 6, 12, 18, 24, 0, 0, 0]), result);
|
||||
|
||||
let result = U256([1, 2, 3, 4]).full_mul(U256([0, 0, 7, 0]));
|
||||
assert_eq!(U512([0, 0, 7, 14, 21, 28, 0, 0]), result);
|
||||
|
||||
let result = U256([1, 2, 3, 4]).full_mul(U256([0, 0, 0, 8]));
|
||||
assert_eq!(U512([0, 0, 0, 8, 16, 24, 32, 0]), result);
|
||||
|
||||
let result = U256([1, 2, 3, 4]).full_mul(U256([5, 6, 7, 8]));
|
||||
assert_eq!(U512([5, 16, 34, 60, 61, 52, 32, 0]), result);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user