Cargo fmt all the things

This commit is contained in:
Ignotus Peverell
2017-09-29 18:44:25 +00:00
parent 3b51180359
commit 8504efb796
57 changed files with 3678 additions and 2600 deletions
+68 -39
View File
@@ -27,7 +27,8 @@ use core::target::Difficulty;
pub const REWARD: u64 = 1_000_000_000;
/// Number of blocks before a coinbase matures and can be spent
/// TODO - reduced this for testing - need to investigate if we can lower this in test env
/// TODO - reduced this for testing - need to investigate if we can lower this
/// in test env
// pub const COINBASE_MATURITY: u64 = 1_000;
pub const COINBASE_MATURITY: u64 = 3;
@@ -99,7 +100,8 @@ impl fmt::Display for TargetError {
/// difference between the median timestamps at the beginning and the end
/// of the window.
pub fn next_difficulty<T>(cursor: T) -> Result<Difficulty, TargetError>
where T: IntoIterator<Item = Result<(u64, Difficulty), TargetError>>
where
T: IntoIterator<Item = Result<(u64, Difficulty), TargetError>>,
{
// Block times at the begining and end of the adjustment window, used to
@@ -155,8 +157,9 @@ pub fn next_difficulty<T>(cursor: T) -> Result<Difficulty, TargetError>
ts_damp
};
Ok(diff_avg * Difficulty::from_num(BLOCK_TIME_WINDOW) /
Difficulty::from_num(adj_ts))
Ok(
diff_avg * Difficulty::from_num(BLOCK_TIME_WINDOW) / Difficulty::from_num(adj_ts),
)
}
#[cfg(test)]
@@ -171,24 +174,25 @@ mod test {
// Builds an iterator for next difficulty calculation with the provided
// constant time interval, difficulty and total length.
fn repeat(interval: u64, diff: u64, len: u64) -> Vec<Result<(u64, Difficulty), TargetError>> {
//watch overflow here, length shouldn't be ridiculous anyhow
// watch overflow here, length shouldn't be ridiculous anyhow
assert!(len < std::usize::MAX as u64);
let diffs = vec![Difficulty::from_num(diff); len as usize];
let times = (0..(len as usize)).map(|n| n * interval as usize).rev();
let pairs = times.zip(diffs.iter());
pairs.map(|(t, d)| Ok((t as u64, d.clone()))).collect::<Vec<_>>()
pairs
.map(|(t, d)| Ok((t as u64, d.clone())))
.collect::<Vec<_>>()
}
fn repeat_offs(from: u64,
interval: u64,
diff: u64,
len: u64)
-> Vec<Result<(u64, Difficulty), TargetError>> {
map_vec!(repeat(interval, diff, len), |e| {
match e.clone() {
Err(e) => Err(e),
Ok((t, d)) => Ok((t + from, d)),
}
fn repeat_offs(
from: u64,
interval: u64,
diff: u64,
len: u64,
) -> Vec<Result<(u64, Difficulty), TargetError>> {
map_vec!(repeat(interval, diff, len), |e| match e.clone() {
Err(e) => Err(e),
Ok((t, d)) => Ok((t + from, d)),
})
}
@@ -196,19 +200,28 @@ mod test {
#[test]
fn next_target_adjustment() {
// not enough data
assert_eq!(next_difficulty(vec![]).unwrap(), Difficulty::from_num(MINIMUM_DIFFICULTY));
assert_eq!(
next_difficulty(vec![]).unwrap(),
Difficulty::from_num(MINIMUM_DIFFICULTY)
);
assert_eq!(next_difficulty(vec![Ok((60, Difficulty::one()))]).unwrap(),
Difficulty::from_num(MINIMUM_DIFFICULTY));
assert_eq!(
next_difficulty(vec![Ok((60, Difficulty::one()))]).unwrap(),
Difficulty::from_num(MINIMUM_DIFFICULTY)
);
assert_eq!(next_difficulty(repeat(60, 10, DIFFICULTY_ADJUST_WINDOW)).unwrap(),
Difficulty::from_num(MINIMUM_DIFFICULTY));
assert_eq!(
next_difficulty(repeat(60, 10, DIFFICULTY_ADJUST_WINDOW)).unwrap(),
Difficulty::from_num(MINIMUM_DIFFICULTY)
);
// just enough data, right interval, should stay constant
let just_enough = DIFFICULTY_ADJUST_WINDOW + MEDIAN_TIME_WINDOW;
assert_eq!(next_difficulty(repeat(60, 1000, just_enough)).unwrap(),
Difficulty::from_num(1000));
assert_eq!(
next_difficulty(repeat(60, 1000, just_enough)).unwrap(),
Difficulty::from_num(1000)
);
// checking averaging works, window length is odd so need to compensate a little
let sec = DIFFICULTY_ADJUST_WINDOW / 2 + 1 + MEDIAN_TIME_WINDOW;
@@ -218,28 +231,44 @@ mod test {
assert_eq!(next_difficulty(s2).unwrap(), Difficulty::from_num(999));
// too slow, diff goes down
assert_eq!(next_difficulty(repeat(90, 1000, just_enough)).unwrap(),
Difficulty::from_num(889));
assert_eq!(next_difficulty(repeat(120, 1000, just_enough)).unwrap(),
Difficulty::from_num(800));
assert_eq!(
next_difficulty(repeat(90, 1000, just_enough)).unwrap(),
Difficulty::from_num(889)
);
assert_eq!(
next_difficulty(repeat(120, 1000, just_enough)).unwrap(),
Difficulty::from_num(800)
);
// too fast, diff goes up
assert_eq!(next_difficulty(repeat(55, 1000, just_enough)).unwrap(),
Difficulty::from_num(1021));
assert_eq!(next_difficulty(repeat(45, 1000, just_enough)).unwrap(),
Difficulty::from_num(1067));
assert_eq!(
next_difficulty(repeat(55, 1000, just_enough)).unwrap(),
Difficulty::from_num(1021)
);
assert_eq!(
next_difficulty(repeat(45, 1000, just_enough)).unwrap(),
Difficulty::from_num(1067)
);
// hitting lower time bound, should always get the same result below
assert_eq!(next_difficulty(repeat(20, 1000, just_enough)).unwrap(),
Difficulty::from_num(1200));
assert_eq!(next_difficulty(repeat(10, 1000, just_enough)).unwrap(),
Difficulty::from_num(1200));
assert_eq!(
next_difficulty(repeat(20, 1000, just_enough)).unwrap(),
Difficulty::from_num(1200)
);
assert_eq!(
next_difficulty(repeat(10, 1000, just_enough)).unwrap(),
Difficulty::from_num(1200)
);
// hitting higher time bound, should always get the same result above
assert_eq!(next_difficulty(repeat(160, 1000, just_enough)).unwrap(),
Difficulty::from_num(750));
assert_eq!(next_difficulty(repeat(200, 1000, just_enough)).unwrap(),
Difficulty::from_num(750));
assert_eq!(
next_difficulty(repeat(160, 1000, just_enough)).unwrap(),
Difficulty::from_num(750)
);
assert_eq!(
next_difficulty(repeat(200, 1000, just_enough)).unwrap(),
Difficulty::from_num(750)
);
}
}
+161 -142
View File
@@ -85,14 +85,16 @@ impl Default for BlockHeader {
/// Serialization of a block header
impl Writeable for BlockHeader {
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), ser::Error> {
ser_multiwrite!(writer,
[write_u64, self.height],
[write_fixed_bytes, &self.previous],
[write_i64, self.timestamp.to_timespec().sec],
[write_fixed_bytes, &self.utxo_root],
[write_fixed_bytes, &self.range_proof_root],
[write_fixed_bytes, &self.kernel_root],
[write_u8, self.features.bits()]);
ser_multiwrite!(
writer,
[write_u64, self.height],
[write_fixed_bytes, &self.previous],
[write_i64, self.timestamp.to_timespec().sec],
[write_fixed_bytes, &self.utxo_root],
[write_fixed_bytes, &self.range_proof_root],
[write_fixed_bytes, &self.kernel_root],
[write_u8, self.features.bits()]
);
try!(writer.write_u64(self.nonce));
try!(self.difficulty.write(writer));
@@ -129,7 +131,9 @@ impl Readable for BlockHeader {
utxo_root: utxo_root,
range_proof_root: rproof_root,
kernel_root: kernel_root,
features: BlockFeatures::from_bits(features).ok_or(ser::Error::CorruptedData)?,
features: BlockFeatures::from_bits(features).ok_or(
ser::Error::CorruptedData,
)?,
pow: pow,
nonce: nonce,
difficulty: difficulty,
@@ -162,10 +166,12 @@ impl Writeable for Block {
try!(self.header.write(writer));
if writer.serialization_mode() != ser::SerializationMode::Hash {
ser_multiwrite!(writer,
[write_u64, self.inputs.len() as u64],
[write_u64, self.outputs.len() as u64],
[write_u64, self.kernels.len() as u64]);
ser_multiwrite!(
writer,
[write_u64, self.inputs.len() as u64],
[write_u64, self.outputs.len() as u64],
[write_u64, self.kernels.len() as u64]
);
for inp in &self.inputs {
try!(inp.write(writer));
@@ -234,10 +240,11 @@ impl Block {
/// Builds a new block from the header of the previous block, a vector of
/// transactions and the private key that will receive the reward. Checks
/// that all transactions are valid and calculates the Merkle tree.
pub fn new(prev: &BlockHeader,
txs: Vec<&Transaction>,
reward_key: SecretKey)
-> Result<Block, secp::Error> {
pub fn new(
prev: &BlockHeader,
txs: Vec<&Transaction>,
reward_key: SecretKey,
) -> Result<Block, secp::Error> {
let secp = Secp256k1::with_caps(secp::ContextFlag::Commit);
let (reward_out, reward_proof) = try!(Block::reward_output(reward_key, &secp));
@@ -248,11 +255,12 @@ impl Block {
/// Builds a new block ready to mine from the header of the previous block,
/// a vector of transactions and the reward information. Checks
/// that all transactions are valid and calculates the Merkle tree.
pub fn with_reward(prev: &BlockHeader,
txs: Vec<&Transaction>,
reward_out: Output,
reward_kern: TxKernel)
-> Result<Block, secp::Error> {
pub fn with_reward(
prev: &BlockHeader,
txs: Vec<&Transaction>,
reward_out: Output,
reward_kern: TxKernel,
) -> Result<Block, secp::Error> {
// note: the following reads easily but may not be the most efficient due to
// repeated iterations, revisit if a problem
let secp = Secp256k1::with_caps(secp::ContextFlag::Commit);
@@ -264,18 +272,16 @@ impl Block {
// build vectors with all inputs and all outputs, ordering them by hash
// needs to be a fold so we don't end up with a vector of vectors and we
// want to fully own the refs (not just a pointer like flat_map).
let mut inputs = txs.iter()
.fold(vec![], |mut acc, ref tx| {
let mut inputs = tx.inputs.clone();
acc.append(&mut inputs);
acc
});
let mut outputs = txs.iter()
.fold(vec![], |mut acc, ref tx| {
let mut outputs = tx.outputs.clone();
acc.append(&mut outputs);
acc
});
let mut inputs = txs.iter().fold(vec![], |mut acc, ref tx| {
let mut inputs = tx.inputs.clone();
acc.append(&mut inputs);
acc
});
let mut outputs = txs.iter().fold(vec![], |mut acc, ref tx| {
let mut outputs = tx.outputs.clone();
acc.append(&mut outputs);
acc
});
outputs.push(reward_out);
inputs.sort_by_key(|inp| inp.hash());
@@ -283,19 +289,24 @@ impl Block {
// calculate the overall Merkle tree and fees
Ok(Block {
Ok(
Block {
header: BlockHeader {
height: prev.height + 1,
timestamp: time::Tm { tm_nsec: 0, ..time::now_utc() },
timestamp: time::Tm {
tm_nsec: 0,
..time::now_utc()
},
previous: prev.hash(),
total_difficulty: prev.pow.clone().to_difficulty() + prev.total_difficulty.clone(),
total_difficulty: prev.pow.clone().to_difficulty() +
prev.total_difficulty.clone(),
..Default::default()
},
inputs: inputs,
outputs: outputs,
kernels: kernels,
}
.compact())
}.compact(),
)
}
@@ -312,37 +323,37 @@ impl Block {
/// Matches any output with a potential spending input, eliminating them
/// from the block. Provides a simple way to compact the block. The
/// elimination is stable with respect to inputs and outputs order.
///
/// NOTE: exclude coinbase from compaction process
/// if a block contains a new coinbase output and
/// is a transaction spending a previous coinbase
/// we do not want to compact these away
///
///
/// NOTE: exclude coinbase from compaction process
/// if a block contains a new coinbase output and
/// is a transaction spending a previous coinbase
/// we do not want to compact these away
///
pub fn compact(&self) -> Block {
let in_set = self.inputs
.iter()
.map(|inp| inp.commitment())
.collect::<HashSet<_>>();
let in_set = self.inputs
.iter()
.map(|inp| inp.commitment())
.collect::<HashSet<_>>();
let out_set = self.outputs
.iter()
.filter(|out| !out.features.contains(COINBASE_OUTPUT))
.map(|out| out.commitment())
.collect::<HashSet<_>>();
let out_set = self.outputs
.iter()
.filter(|out| !out.features.contains(COINBASE_OUTPUT))
.map(|out| out.commitment())
.collect::<HashSet<_>>();
let commitments_to_compact = in_set.intersection(&out_set).collect::<HashSet<_>>();
let commitments_to_compact = in_set.intersection(&out_set).collect::<HashSet<_>>();
let new_inputs = self.inputs
.iter()
.filter(|inp| !commitments_to_compact.contains(&inp.commitment()))
.map(|&inp| inp)
.collect::<Vec<_>>();
let new_inputs = self.inputs
.iter()
.filter(|inp| !commitments_to_compact.contains(&inp.commitment()))
.map(|&inp| inp)
.collect::<Vec<_>>();
let new_outputs = self.outputs
.iter()
.filter(|out| !commitments_to_compact.contains(&out.commitment()))
.map(|&out| out)
.collect::<Vec<_>>();
let new_outputs = self.outputs
.iter()
.filter(|out| !commitments_to_compact.contains(&out.commitment()))
.map(|&out| out)
.collect::<Vec<_>>();
Block {
header: BlockHeader {
@@ -374,18 +385,17 @@ impl Block {
all_outputs.sort_by_key(|out| out.hash());
Block {
// compact will fix the merkle tree
header: BlockHeader {
pow: self.header.pow.clone(),
difficulty: self.header.difficulty.clone(),
total_difficulty: self.header.total_difficulty.clone(),
..self.header
},
inputs: all_inputs,
outputs: all_outputs,
kernels: all_kernels,
}
.compact()
// compact will fix the merkle tree
header: BlockHeader {
pow: self.header.pow.clone(),
difficulty: self.header.difficulty.clone(),
total_difficulty: self.header.total_difficulty.clone(),
..self.header
},
inputs: all_inputs,
outputs: all_outputs,
kernels: all_kernels,
}.compact()
}
/// Validates all the elements in a block that can be checked without
@@ -394,7 +404,7 @@ impl Block {
pub fn validate(&self, secp: &Secp256k1) -> Result<(), secp::Error> {
self.verify_coinbase(secp)?;
self.verify_kernels(secp)?;
Ok(())
Ok(())
}
/// Validate the sum of input/output commitments match the sum in kernels
@@ -441,23 +451,25 @@ impl Block {
// verifying the kernels on a block composed of just the coinbase outputs
// and kernels checks all we need
Block {
header: BlockHeader::default(),
inputs: vec![],
outputs: cb_outs,
kernels: cb_kerns,
}
.verify_kernels(secp)
header: BlockHeader::default(),
inputs: vec![],
outputs: cb_outs,
kernels: cb_kerns,
}.verify_kernels(secp)
}
/// Builds the blinded output and related signature proof for the block
/// reward.
pub fn reward_output(skey: secp::key::SecretKey,
secp: &Secp256k1)
-> Result<(Output, TxKernel), secp::Error> {
let msg = try!(secp::Message::from_slice(&[0; secp::constants::MESSAGE_SIZE]));
pub fn reward_output(
skey: secp::key::SecretKey,
secp: &Secp256k1,
) -> Result<(Output, TxKernel), secp::Error> {
let msg = try!(secp::Message::from_slice(
&[0; secp::constants::MESSAGE_SIZE],
));
let sig = try!(secp.sign(&msg, &skey));
let commit = secp.commit(REWARD, skey).unwrap();
//let switch_commit = secp.switch_commit(skey).unwrap();
// let switch_commit = secp.switch_commit(skey).unwrap();
let nonce = secp.nonce();
let rproof = secp.range_proof(0, REWARD, skey, commit, nonce);
@@ -560,78 +572,85 @@ mod test {
assert_eq!(b3.outputs.len(), 4);
}
#[test]
fn empty_block_with_coinbase_is_valid() {
let ref secp = new_secp();
let b = new_block(vec![], secp);
#[test]
fn empty_block_with_coinbase_is_valid() {
let ref secp = new_secp();
let b = new_block(vec![], secp);
assert_eq!(b.inputs.len(), 0);
assert_eq!(b.outputs.len(), 1);
assert_eq!(b.kernels.len(), 1);
assert_eq!(b.inputs.len(), 0);
assert_eq!(b.outputs.len(), 1);
assert_eq!(b.kernels.len(), 1);
let coinbase_outputs = b.outputs
let coinbase_outputs = b.outputs
.iter()
.filter(|out| out.features.contains(COINBASE_OUTPUT))
.map(|o| o.clone())
.map(|o| o.clone())
.collect::<Vec<_>>();
assert_eq!(coinbase_outputs.len(), 1);
assert_eq!(coinbase_outputs.len(), 1);
let coinbase_kernels = b.kernels
let coinbase_kernels = b.kernels
.iter()
.filter(|out| out.features.contains(COINBASE_KERNEL))
.map(|o| o.clone())
.map(|o| o.clone())
.collect::<Vec<_>>();
assert_eq!(coinbase_kernels.len(), 1);
assert_eq!(coinbase_kernels.len(), 1);
// the block should be valid here (single coinbase output with corresponding txn kernel)
assert_eq!(b.validate(&secp), Ok(()));
}
// the block should be valid here (single coinbase output with corresponding
// txn kernel)
assert_eq!(b.validate(&secp), Ok(()));
}
#[test]
// test that flipping the COINBASE_OUTPUT flag on the output features
// invalidates the block and specifically it causes verify_coinbase to fail
// additionally verifying the merkle_inputs_outputs also fails
fn remove_coinbase_output_flag() {
let ref secp = new_secp();
let mut b = new_block(vec![], secp);
#[test]
// test that flipping the COINBASE_OUTPUT flag on the output features
// invalidates the block and specifically it causes verify_coinbase to fail
// additionally verifying the merkle_inputs_outputs also fails
fn remove_coinbase_output_flag() {
let ref secp = new_secp();
let mut b = new_block(vec![], secp);
assert!(b.outputs[0].features.contains(COINBASE_OUTPUT));
b.outputs[0].features.remove(COINBASE_OUTPUT);
assert!(b.outputs[0].features.contains(COINBASE_OUTPUT));
b.outputs[0].features.remove(COINBASE_OUTPUT);
assert_eq!(b.verify_coinbase(&secp), Err(secp::Error::IncorrectCommitSum));
assert_eq!(b.verify_kernels(&secp), Ok(()));
assert_eq!(
b.verify_coinbase(&secp),
Err(secp::Error::IncorrectCommitSum)
);
assert_eq!(b.verify_kernels(&secp), Ok(()));
assert_eq!(b.validate(&secp), Err(secp::Error::IncorrectCommitSum));
}
assert_eq!(b.validate(&secp), Err(secp::Error::IncorrectCommitSum));
}
#[test]
// test that flipping the COINBASE_KERNEL flag on the kernel features
// invalidates the block and specifically it causes verify_coinbase to fail
fn remove_coinbase_kernel_flag() {
let ref secp = new_secp();
let mut b = new_block(vec![], secp);
#[test]
// test that flipping the COINBASE_KERNEL flag on the kernel features
// invalidates the block and specifically it causes verify_coinbase to fail
fn remove_coinbase_kernel_flag() {
let ref secp = new_secp();
let mut b = new_block(vec![], secp);
assert!(b.kernels[0].features.contains(COINBASE_KERNEL));
b.kernels[0].features.remove(COINBASE_KERNEL);
assert!(b.kernels[0].features.contains(COINBASE_KERNEL));
b.kernels[0].features.remove(COINBASE_KERNEL);
assert_eq!(b.verify_coinbase(&secp), Err(secp::Error::IncorrectCommitSum));
assert_eq!(b.verify_kernels(&secp), Ok(()));
assert_eq!(
b.verify_coinbase(&secp),
Err(secp::Error::IncorrectCommitSum)
);
assert_eq!(b.verify_kernels(&secp), Ok(()));
assert_eq!(b.validate(&secp), Err(secp::Error::IncorrectCommitSum));
}
assert_eq!(b.validate(&secp), Err(secp::Error::IncorrectCommitSum));
}
#[test]
fn serialize_deserialize_block() {
let ref secp = new_secp();
let b = new_block(vec![], secp);
#[test]
fn serialize_deserialize_block() {
let ref secp = new_secp();
let b = new_block(vec![], secp);
let mut vec = Vec::new();
ser::serialize(&mut vec, &b).expect("serialization failed");
let b2: Block = ser::deserialize(&mut &vec[..]).unwrap();
let mut vec = Vec::new();
ser::serialize(&mut vec, &b).expect("serialization failed");
let b2: Block = ser::deserialize(&mut &vec[..]).unwrap();
assert_eq!(b.inputs, b2.inputs);
assert_eq!(b.outputs, b2.outputs);
assert_eq!(b.kernels, b2.kernels);
assert_eq!(b.header, b2.header);
}
assert_eq!(b.inputs, b2.inputs);
assert_eq!(b.outputs, b2.outputs);
assert_eq!(b.kernels, b2.kernels);
assert_eq!(b.header, b2.header);
}
}
+35 -20
View File
@@ -112,12 +112,14 @@ pub fn output(value: u64, blinding: SecretKey) -> Box<Append> {
let commit = build.secp.commit(value, blinding).unwrap();
let nonce = build.secp.nonce();
let rproof = build.secp.range_proof(0, value, blinding, commit, nonce);
(tx.with_output(Output {
features: DEFAULT_OUTPUT,
commit: commit,
proof: rproof,
}),
sum.add(blinding))
(
tx.with_output(Output {
features: DEFAULT_OUTPUT,
commit: commit,
proof: rproof,
}),
sum.add(blinding),
)
})
}
@@ -130,30 +132,38 @@ pub fn output_rand(value: u64) -> Box<Append> {
let commit = build.secp.commit(value, blinding).unwrap();
let nonce = build.secp.nonce();
let rproof = build.secp.range_proof(0, value, blinding, commit, nonce);
(tx.with_output(Output {
features: DEFAULT_OUTPUT,
commit: commit,
proof: rproof,
}),
sum.add(blinding))
(
tx.with_output(Output {
features: DEFAULT_OUTPUT,
commit: commit,
proof: rproof,
}),
sum.add(blinding),
)
})
}
/// Sets the fee on the transaction being built.
pub fn with_fee(fee: u64) -> Box<Append> {
Box::new(move |_build, (tx, sum)| -> (Transaction, BlindSum) { (tx.with_fee(fee), sum) })
Box::new(move |_build, (tx, sum)| -> (Transaction, BlindSum) {
(tx.with_fee(fee), sum)
})
}
/// Sets a known excess value on the transaction being built. Usually used in
/// combination with the initial_tx function when a new transaction is built
/// by adding to a pre-existing one.
pub fn with_excess(excess: SecretKey) -> Box<Append> {
Box::new(move |_build, (tx, sum)| -> (Transaction, BlindSum) { (tx, sum.add(excess)) })
Box::new(move |_build, (tx, sum)| -> (Transaction, BlindSum) {
(tx, sum.add(excess))
})
}
/// Sets an initial transaction to add to when building a new transaction.
pub fn initial_tx(tx: Transaction) -> Box<Append> {
Box::new(move |_build, (_, sum)| -> (Transaction, BlindSum) { (tx.clone(), sum) })
Box::new(move |_build, (_, sum)| -> (Transaction, BlindSum) {
(tx.clone(), sum)
})
}
/// Builds a new transaction by combining all the combinators provided in a
@@ -171,8 +181,10 @@ pub fn transaction(elems: Vec<Box<Append>>) -> Result<(Transaction, SecretKey),
secp: Secp256k1::with_caps(secp::ContextFlag::Commit),
rng: OsRng::new().unwrap(),
};
let (mut tx, sum) = elems.iter().fold((Transaction::empty(), BlindSum::new()),
|acc, elem| elem(&mut ctx, acc));
let (mut tx, sum) = elems.iter().fold(
(Transaction::empty(), BlindSum::new()),
|acc, elem| elem(&mut ctx, acc),
);
let blind_sum = sum.sum(&ctx.secp)?;
let msg = secp::Message::from_slice(&u64_to_32bytes(tx.fee))?;
@@ -199,9 +211,12 @@ mod test {
#[test]
fn blind_simple_tx() {
let secp = Secp256k1::with_caps(secp::ContextFlag::Commit);
let (tx, _) =
transaction(vec![input_rand(10), input_rand(11), output_rand(20), with_fee(1)])
.unwrap();
let (tx, _) = transaction(vec![
input_rand(10),
input_rand(11),
output_rand(20),
with_fee(1),
]).unwrap();
tx.verify_sig(&secp).unwrap();
}
#[test]
+2 -2
View File
@@ -143,9 +143,9 @@ impl HashWriter {
/// Consume the `HashWriter`, outputting a `Hash` corresponding to its
/// current state
pub fn into_hash(self) -> Hash {
let mut res = [0; 32];
let mut res = [0; 32];
(&mut res).copy_from_slice(self.state.finalize().as_bytes());
Hash(res)
Hash(res)
}
}
+22 -14
View File
@@ -20,7 +20,7 @@ pub mod hash;
pub mod pmmr;
pub mod target;
pub mod transaction;
//pub mod txoset;
// pub mod txoset;
#[allow(dead_code)]
use std::fmt;
@@ -82,7 +82,7 @@ pub trait Committed {
/// Proof of work
pub struct Proof {
/// The nonces
pub nonces:Vec<u32>,
pub nonces: Vec<u32>,
/// The proof size
pub proof_size: usize,
@@ -125,9 +125,8 @@ impl Clone for Proof {
}
impl Proof {
/// Builds a proof with all bytes zeroed out
pub fn new(in_nonces:Vec<u32>) -> Proof {
pub fn new(in_nonces: Vec<u32>) -> Proof {
Proof {
proof_size: in_nonces.len(),
nonces: in_nonces,
@@ -135,10 +134,10 @@ impl Proof {
}
/// Builds a proof with all bytes zeroed out
pub fn zero(proof_size:usize) -> Proof {
pub fn zero(proof_size: usize) -> Proof {
Proof {
proof_size: proof_size,
nonces: vec![0;proof_size],
nonces: vec![0; proof_size],
}
}
@@ -251,9 +250,12 @@ mod test {
#[test]
fn hash_output() {
let (tx, _) =
build::transaction(vec![input_rand(75), output_rand(42), output_rand(32), with_fee(1)])
.unwrap();
let (tx, _) = build::transaction(vec![
input_rand(75),
output_rand(42),
output_rand(32),
with_fee(1),
]).unwrap();
let h = tx.outputs[0].hash();
assert!(h != ZERO_HASH);
let h2 = tx.outputs[1].hash();
@@ -309,9 +311,11 @@ mod test {
// From now on, Bob only has the obscured transaction and the sum of
// blinding factors. He adds his output, finalizes the transaction so it's
// ready for broadcast.
let (tx_final, _) =
build::transaction(vec![initial_tx(tx_alice), with_excess(blind_sum), output_rand(5)])
.unwrap();
let (tx_final, _) = build::transaction(vec![
initial_tx(tx_alice),
with_excess(blind_sum),
output_rand(5),
]).unwrap();
tx_final.validate(&secp).unwrap();
}
@@ -357,8 +361,12 @@ mod test {
// utility producing a transaction with 2 inputs and a single outputs
pub fn tx2i1o() -> Transaction {
build::transaction(vec![input_rand(10), input_rand(11), output_rand(20), with_fee(1)])
.map(|(tx, _)| tx)
build::transaction(vec![
input_rand(10),
input_rand(11),
output_rand(20),
with_fee(1),
]).map(|(tx, _)| tx)
.unwrap()
}
+97 -40
View File
@@ -15,7 +15,11 @@
//! Persistent and prunable Merkle Mountain Range implementation. For a high
//! level description of MMRs, see:
//!
//! https://github.com/opentimestamps/opentimestamps-server/blob/master/doc/merkle-mountain-range.md
//! https://github.
//! com/opentimestamps/opentimestamps-server/blob/master/doc/merkle-mountain-range.
//!
//!
//! md
//!
//! This implementation is built in two major parts:
//!
@@ -91,7 +95,10 @@ impl<T> Summable for NoSum<T> {
return 0;
}
}
impl<T> Writeable for NoSum<T> where T: Writeable {
impl<T> Writeable for NoSum<T>
where
T: Writeable,
{
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), ser::Error> {
self.0.write(writer)
}
@@ -100,14 +107,20 @@ impl<T> Writeable for NoSum<T> where T: Writeable {
/// A utility type to handle (Hash, Sum) pairs more conveniently. The addition
/// of two HashSums is the (Hash(h1|h2), h1 + h2) HashSum.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct HashSum<T> where T: Summable {
pub struct HashSum<T>
where
T: Summable,
{
/// The hash
pub hash: Hash,
/// The sum
pub sum: T::Sum,
}
impl<T> HashSum<T> where T: Summable + Hashed {
impl<T> HashSum<T>
where
T: Summable + Hashed,
{
/// Create a hash sum from a summable
pub fn from_summable(idx: u64, elmt: &T) -> HashSum<T> {
let hash = elmt.hash();
@@ -120,7 +133,10 @@ impl<T> HashSum<T> where T: Summable + Hashed {
}
}
impl<T> Readable for HashSum<T> where T: Summable {
impl<T> Readable for HashSum<T>
where
T: Summable,
{
fn read(r: &mut Reader) -> Result<HashSum<T>, ser::Error> {
Ok(HashSum {
hash: Hash::read(r)?,
@@ -129,14 +145,20 @@ impl<T> Readable for HashSum<T> where T: Summable {
}
}
impl<T> Writeable for HashSum<T> where T: Summable {
impl<T> Writeable for HashSum<T>
where
T: Summable,
{
fn write<W: Writer>(&self, w: &mut W) -> Result<(), ser::Error> {
self.hash.write(w)?;
self.sum.write(w)
}
}
impl<T> ops::Add for HashSum<T> where T: Summable {
impl<T> ops::Add for HashSum<T>
where
T: Summable,
{
type Output = HashSum<T>;
fn add(self, other: HashSum<T>) -> HashSum<T> {
HashSum {
@@ -150,8 +172,10 @@ impl<T> ops::Add for HashSum<T> where T: Summable {
/// The PMMR itself does not need the Backend to be accurate on the existence
/// of an element (i.e. remove could be a no-op) but layers above can
/// depend on an accurate Backend to check existence.
pub trait Backend<T> where T: Summable {
pub trait Backend<T>
where
T: Summable,
{
/// Append the provided HashSums to the backend storage. The position of the
/// first element of the Vec in the MMR is provided to help the
/// implementation.
@@ -176,15 +200,22 @@ pub trait Backend<T> where T: Summable {
/// Heavily relies on navigation operations within a binary tree. In particular,
/// all the implementation needs to keep track of the MMR structure is how far
/// we are in the sequence of nodes making up the MMR.
pub struct PMMR<'a, T, B> where T: Summable, B: 'a + Backend<T> {
pub struct PMMR<'a, T, B>
where
T: Summable,
B: 'a + Backend<T>,
{
last_pos: u64,
backend: &'a mut B,
// only needed for parameterizing Backend
summable: PhantomData<T>,
}
impl<'a, T, B> PMMR<'a, T, B> where T: Summable + Hashed + Clone, B: 'a + Backend<T> {
impl<'a, T, B> PMMR<'a, T, B>
where
T: Summable + Hashed + Clone,
B: 'a + Backend<T>,
{
/// Build a new prunable Merkle Mountain Range using the provided backend.
pub fn new(backend: &'a mut B) -> PMMR<T, B> {
PMMR {
@@ -194,7 +225,8 @@ impl<'a, T, B> PMMR<'a, T, B> where T: Summable + Hashed + Clone, B: 'a + Backen
}
}
/// Build a new prunable Merkle Mountain Range pre-initlialized until last_pos
/// Build a new prunable Merkle Mountain Range pre-initlialized until
/// last_pos
/// with the provided backend.
pub fn at(backend: &'a mut B, last_pos: u64) -> PMMR<T, B> {
PMMR {
@@ -215,7 +247,7 @@ impl<'a, T, B> PMMR<'a, T, B> where T: Summable + Hashed + Clone, B: 'a + Backen
ret = match (ret, peak) {
(None, x) => x,
(Some(hsum), None) => Some(hsum),
(Some(lhsum), Some(rhsum)) => Some(lhsum + rhsum)
(Some(lhsum), Some(rhsum)) => Some(lhsum + rhsum),
}
}
ret.expect("no root, invalid tree")
@@ -234,10 +266,11 @@ impl<'a, T, B> PMMR<'a, T, B> where T: Summable + Hashed + Clone, B: 'a + Backen
// height it means we have to build a higher peak by summing with a previous
// sibling. we do it iteratively in case the new peak itself allows the
// creation of another parent.
while bintree_postorder_height(pos+1) > height {
while bintree_postorder_height(pos + 1) > height {
let left_sibling = bintree_jump_left_sibling(pos);
let left_hashsum = self.backend.get(left_sibling)
.expect("missing left sibling in tree, should not have been pruned");
let left_hashsum = self.backend.get(left_sibling).expect(
"missing left sibling in tree, should not have been pruned",
);
current_hashsum = left_hashsum + current_hashsum;
to_append.push(current_hashsum.clone());
@@ -259,7 +292,7 @@ impl<'a, T, B> PMMR<'a, T, B> where T: Summable + Hashed + Clone, B: 'a + Backen
// position is a leaf, which may had some parent that needs to exist
// afterward for the MMR to be valid
let mut pos = position;
while bintree_postorder_height(pos+1) > 0 {
while bintree_postorder_height(pos + 1) > 0 {
pos += 1;
}
@@ -268,13 +301,14 @@ impl<'a, T, B> PMMR<'a, T, B> where T: Summable + Hashed + Clone, B: 'a + Backen
Ok(())
}
/// Prune an element from the tree given its position. Note that to be able to
/// Prune an element from the tree given its position. Note that to be able
/// to
/// provide that position and prune, consumers of this API are expected to
/// keep an index of elements to positions in the tree. Prunes parent
/// nodes as well when they become childless.
pub fn prune(&mut self, position: u64, index: u32) -> Result<bool, String> {
if let None = self.backend.get(position) {
return Ok(false)
return Ok(false);
}
let prunable_height = bintree_postorder_height(position);
if prunable_height > 0 {
@@ -286,7 +320,7 @@ impl<'a, T, B> PMMR<'a, T, B> where T: Summable + Hashed + Clone, B: 'a + Backen
// the tree.
let mut to_prune = vec![];
let mut current = position;
while current+1 < self.last_pos {
while current + 1 < self.last_pos {
let (parent, sibling) = family(current);
if parent > self.last_pos {
// can't prune when our parent isn't here yet
@@ -330,7 +364,7 @@ impl<'a, T, B> PMMR<'a, T, B> where T: Summable + Hashed + Clone, B: 'a + Backen
print!("{:>8} ", n + 1);
}
println!("");
for n in 1..(sz+1) {
for n in 1..(sz + 1) {
let ohs = self.get(n);
match ohs {
Some(hs) => print!("{} ", hs.hash),
@@ -345,36 +379,45 @@ impl<'a, T, B> PMMR<'a, T, B> where T: Summable + Hashed + Clone, B: 'a + Backen
/// compact the Vector itself but still frees the reference to the
/// underlying HashSum.
#[derive(Clone)]
pub struct VecBackend<T> where T: Summable + Clone {
pub struct VecBackend<T>
where
T: Summable + Clone,
{
pub elems: Vec<Option<HashSum<T>>>,
}
impl<T> Backend<T> for VecBackend<T> where T: Summable + Clone {
impl<T> Backend<T> for VecBackend<T>
where
T: Summable + Clone,
{
#[allow(unused_variables)]
fn append(&mut self, position: u64, data: Vec<HashSum<T>>) -> Result<(), String> {
self.elems.append(&mut map_vec!(data, |d| Some(d.clone())));
Ok(())
}
fn get(&self, position: u64) -> Option<HashSum<T>> {
self.elems[(position-1) as usize].clone()
self.elems[(position - 1) as usize].clone()
}
fn remove(&mut self, positions: Vec<u64>, index: u32) -> Result<(), String> {
for n in positions {
self.elems[(n-1) as usize] = None
self.elems[(n - 1) as usize] = None
}
Ok(())
}
#[allow(unused_variables)]
fn rewind(&mut self, position: u64, index: u32) -> Result<(), String> {
self.elems = self.elems[0..(position as usize)+1].to_vec();
self.elems = self.elems[0..(position as usize) + 1].to_vec();
Ok(())
}
}
impl<T> VecBackend<T> where T: Summable + Clone {
impl<T> VecBackend<T>
where
T: Summable + Clone,
{
/// Instantiates a new VecBackend<T>
pub fn new() -> VecBackend<T> {
VecBackend{elems: vec![]}
VecBackend { elems: vec![] }
}
/// Current number of HashSum elements in the underlying Vec.
@@ -418,7 +461,7 @@ pub struct PruneList {
impl PruneList {
/// Instantiate a new empty prune list
pub fn new() -> PruneList {
PruneList{pruned_nodes: vec![]}
PruneList { pruned_nodes: vec![] }
}
/// Computes by how many positions a node at pos should be shifted given the
@@ -501,7 +544,7 @@ fn peaks(num: u64) -> Vec<u64> {
// detecting an invalid mountain range, when siblings exist but no parent
// exists
if bintree_postorder_height(num+1) > bintree_postorder_height(num) {
if bintree_postorder_height(num + 1) > bintree_postorder_height(num) {
return vec![];
}
@@ -616,7 +659,7 @@ pub fn family(pos: u64) -> (u64, u64) {
let parent: u64;
let pos_height = bintree_postorder_height(pos);
let next_height = bintree_postorder_height(pos+1);
let next_height = bintree_postorder_height(pos + 1);
if next_height > pos_height {
sibling = bintree_jump_left_sibling(pos);
parent = pos + 1;
@@ -710,15 +753,19 @@ mod test {
#[test]
#[allow(unused_variables)]
fn first_50_mmr_heights() {
let first_100_str =
"0 0 1 0 0 1 2 0 0 1 0 0 1 2 3 0 0 1 0 0 1 2 0 0 1 0 0 1 2 3 4 \
let first_100_str = "0 0 1 0 0 1 2 0 0 1 0 0 1 2 3 0 0 1 0 0 1 2 0 0 1 0 0 1 2 3 4 \
0 0 1 0 0 1 2 0 0 1 0 0 1 2 3 0 0 1 0 0 1 2 0 0 1 0 0 1 2 3 4 5 \
0 0 1 0 0 1 2 0 0 1 0 0 1 2 3 0 0 1 0 0 1 2 0 0 1 0 0 1 2 3 4 0 0 1 0 0";
let first_100 = first_100_str.split(' ').map(|n| n.parse::<u64>().unwrap());
let mut count = 1;
for n in first_100 {
assert_eq!(n, bintree_postorder_height(count), "expected {}, got {}",
n, bintree_postorder_height(count));
assert_eq!(
n,
bintree_postorder_height(count),
"expected {}, got {}",
n,
bintree_postorder_height(count)
);
count += 1;
}
}
@@ -785,7 +832,13 @@ mod test {
let hash = Hashed::hash(&elems[0]);
let sum = elems[0].sum();
let node_hash = (1 as u64, &sum, hash).hash();
assert_eq!(pmmr.root(), HashSum{hash: node_hash, sum: sum});
assert_eq!(
pmmr.root(),
HashSum {
hash: node_hash,
sum: sum,
}
);
assert_eq!(pmmr.unpruned_size(), 1);
// two elements
@@ -802,7 +855,8 @@ mod test {
// four elements
pmmr.push(elems[3]).unwrap();
let sum4 = sum2 + (HashSum::from_summable(4, &elems[2]) + HashSum::from_summable(5, &elems[3]));
let sum4 = sum2 +
(HashSum::from_summable(4, &elems[2]) + HashSum::from_summable(5, &elems[3]));
assert_eq!(pmmr.root(), sum4);
assert_eq!(pmmr.unpruned_size(), 7);
@@ -814,7 +868,8 @@ mod test {
// six elements
pmmr.push(elems[5]).unwrap();
let sum6 = sum4.clone() + (HashSum::from_summable(8, &elems[4]) + HashSum::from_summable(9, &elems[5]));
let sum6 = sum4.clone() +
(HashSum::from_summable(8, &elems[4]) + HashSum::from_summable(9, &elems[5]));
assert_eq!(pmmr.root(), sum6.clone());
assert_eq!(pmmr.unpruned_size(), 10);
@@ -826,7 +881,9 @@ mod test {
// eight elements
pmmr.push(elems[7]).unwrap();
let sum8 = sum4 + ((HashSum::from_summable(8, &elems[4]) + HashSum::from_summable(9, &elems[5])) + (HashSum::from_summable(11, &elems[6]) + HashSum::from_summable(12, &elems[7])));
let sum8 = sum4 +
((HashSum::from_summable(8, &elems[4]) + HashSum::from_summable(9, &elems[5])) +
(HashSum::from_summable(11, &elems[6]) + HashSum::from_summable(12, &elems[7])));
assert_eq!(pmmr.root(), sum8);
assert_eq!(pmmr.unpruned_size(), 15);
+14 -8
View File
@@ -59,8 +59,8 @@ impl Difficulty {
/// provided hash.
pub fn from_hash(h: &Hash) -> Difficulty {
let max_target = BigEndian::read_u64(&MAX_TARGET);
//Use the first 64 bits of the given hash
let mut in_vec=h.to_vec();
// Use the first 64 bits of the given hash
let mut in_vec = h.to_vec();
in_vec.truncate(8);
let num = BigEndian::read_u64(&in_vec);
Difficulty { num: max_target / num }
@@ -121,7 +121,8 @@ impl Readable for Difficulty {
impl Serialize for Difficulty {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer
where
S: Serializer,
{
serializer.serialize_u64(self.num)
}
@@ -129,7 +130,8 @@ impl Serialize for Difficulty {
impl<'de> Deserialize<'de> for Difficulty {
fn deserialize<D>(deserializer: D) -> Result<Difficulty, D::Error>
where D: Deserializer<'de>
where
D: Deserializer<'de>,
{
deserializer.deserialize_u64(DiffVisitor)
}
@@ -145,12 +147,16 @@ impl<'de> de::Visitor<'de> for DiffVisitor {
}
fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
where E: de::Error
where
E: de::Error,
{
let num_in = s.parse::<u64>();
if let Err(_)=num_in {
return Err(de::Error::invalid_value(de::Unexpected::Str(s), &"a value number"));
};
if let Err(_) = num_in {
return Err(de::Error::invalid_value(
de::Unexpected::Str(s),
&"a value number",
));
};
Ok(Difficulty { num: num_in.unwrap() })
}
}
+37 -22
View File
@@ -54,11 +54,13 @@ pub struct TxKernel {
impl Writeable for TxKernel {
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), ser::Error> {
ser_multiwrite!(writer,
[write_u8, self.features.bits()],
[write_fixed_bytes, &self.excess],
[write_bytes, &self.excess_sig],
[write_u64, self.fee]);
ser_multiwrite!(
writer,
[write_u8, self.features.bits()],
[write_fixed_bytes, &self.excess],
[write_bytes, &self.excess_sig],
[write_u64, self.fee]
);
Ok(())
}
}
@@ -66,8 +68,9 @@ impl Writeable for TxKernel {
impl Readable for TxKernel {
fn read(reader: &mut Reader) -> Result<TxKernel, ser::Error> {
Ok(TxKernel {
features:
KernelFeatures::from_bits(reader.read_u8()?).ok_or(ser::Error::CorruptedData)?,
features: KernelFeatures::from_bits(reader.read_u8()?).ok_or(
ser::Error::CorruptedData,
)?,
excess: Commitment::read(reader)?,
excess_sig: reader.read_vec()?,
fee: reader.read_u64()?,
@@ -104,11 +107,13 @@ pub struct Transaction {
/// write the transaction as binary.
impl Writeable for Transaction {
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), ser::Error> {
ser_multiwrite!(writer,
[write_u64, self.fee],
[write_bytes, &self.excess_sig],
[write_u64, self.inputs.len() as u64],
[write_u64, self.outputs.len() as u64]);
ser_multiwrite!(
writer,
[write_u64, self.fee],
[write_bytes, &self.excess_sig],
[write_u64, self.inputs.len() as u64],
[write_u64, self.outputs.len() as u64]
);
for inp in &self.inputs {
try!(inp.write(writer));
}
@@ -185,7 +190,10 @@ impl Transaction {
pub fn with_input(self, input: Input) -> Transaction {
let mut new_ins = self.inputs;
new_ins.push(input);
Transaction { inputs: new_ins, ..self }
Transaction {
inputs: new_ins,
..self
}
}
/// Builds a new transaction with the provided output added. Existing
@@ -193,7 +201,10 @@ impl Transaction {
pub fn with_output(self, output: Output) -> Transaction {
let mut new_outs = self.outputs;
new_outs.push(output);
Transaction { outputs: new_outs, ..self }
Transaction {
outputs: new_outs,
..self
}
}
/// Builds a new transaction with the provided fee.
@@ -304,9 +315,11 @@ pub struct Output {
/// an Output as binary.
impl Writeable for Output {
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), ser::Error> {
ser_multiwrite!(writer,
[write_u8, self.features.bits()],
[write_fixed_bytes, &self.commit]);
ser_multiwrite!(
writer,
[write_u8, self.features.bits()],
[write_fixed_bytes, &self.commit]
);
// The hash of an output doesn't include the range proof
if writer.serialization_mode() == ser::SerializationMode::Full {
writer.write_bytes(&self.proof)?
@@ -320,8 +333,9 @@ impl Writeable for Output {
impl Readable for Output {
fn read(reader: &mut Reader) -> Result<Output, ser::Error> {
Ok(Output {
features:
OutputFeatures::from_bits(reader.read_u8()?).ok_or(ser::Error::CorruptedData)?,
features: OutputFeatures::from_bits(reader.read_u8()?).ok_or(
ser::Error::CorruptedData,
)?,
commit: Commitment::read(reader)?,
proof: RangeProof::read(reader)?,
})
@@ -341,8 +355,6 @@ impl Output {
/// Validates the range proof using the commitment
pub fn verify_proof(&self, secp: &Secp256k1) -> Result<(), secp::Error> {
/// secp.verify_range_proof returns range if and only if both min_value and max_value less than 2^64
/// since group order is much larger (~2^256) we can be sure overflow is not the case
secp.verify_range_proof(self.commit, self.proof).map(|_| ())
}
}
@@ -392,7 +404,10 @@ impl ops::Add for SumCommit {
type Output = SumCommit;
fn add(self, other: SumCommit) -> SumCommit {
let sum = match self.secp.commit_sum(vec![self.commit.clone(), other.commit.clone()], vec![]) {
let sum = match self.secp.commit_sum(
vec![self.commit.clone(), other.commit.clone()],
vec![],
) {
Ok(s) => s,
Err(_) => Commitment::from_vec(vec![1; 33]),
};
+74 -31
View File
@@ -21,7 +21,7 @@
/// different sets of parameters for different purposes,
/// e.g. CI, User testing, production values
use std::sync::{RwLock};
use std::sync::RwLock;
use consensus::PROOFSIZE;
use consensus::DEFAULT_SIZESHIFT;
@@ -29,16 +29,16 @@ use consensus::DEFAULT_SIZESHIFT;
/// by users
/// Automated testing sizeshift
pub const AUTOMATED_TESTING_SIZESHIFT:u8 = 10;
pub const AUTOMATED_TESTING_SIZESHIFT: u8 = 10;
/// Automated testing proof size
pub const AUTOMATED_TESTING_PROOF_SIZE:usize = 4;
pub const AUTOMATED_TESTING_PROOF_SIZE: usize = 4;
/// User testing sizeshift
pub const USER_TESTING_SIZESHIFT:u8 = 16;
pub const USER_TESTING_SIZESHIFT: u8 = 16;
/// User testing proof size
pub const USER_TESTING_PROOF_SIZE:usize = 42;
pub const USER_TESTING_PROOF_SIZE: usize = 42;
/// Mining parameter modes
#[derive(Debug, Clone, Serialize, Deserialize)]
@@ -55,18 +55,19 @@ pub enum MiningParameterMode {
lazy_static!{
/// The mining parameter mode
pub static ref MINING_PARAMETER_MODE: RwLock<MiningParameterMode> = RwLock::new(MiningParameterMode::Production);
pub static ref MINING_PARAMETER_MODE: RwLock<MiningParameterMode> =
RwLock::new(MiningParameterMode::Production);
}
/// Set the mining mode
pub fn set_mining_mode(mode:MiningParameterMode){
let mut param_ref=MINING_PARAMETER_MODE.write().unwrap();
*param_ref=mode;
pub fn set_mining_mode(mode: MiningParameterMode) {
let mut param_ref = MINING_PARAMETER_MODE.write().unwrap();
*param_ref = mode;
}
/// The sizeshift
pub fn sizeshift() -> u8 {
let param_ref=MINING_PARAMETER_MODE.read().unwrap();
let param_ref = MINING_PARAMETER_MODE.read().unwrap();
match *param_ref {
MiningParameterMode::AutomatedTesting => AUTOMATED_TESTING_SIZESHIFT,
MiningParameterMode::UserTesting => USER_TESTING_SIZESHIFT,
@@ -76,7 +77,7 @@ pub fn sizeshift() -> u8 {
/// The proofsize
pub fn proofsize() -> usize {
let param_ref=MINING_PARAMETER_MODE.read().unwrap();
let param_ref = MINING_PARAMETER_MODE.read().unwrap();
match *param_ref {
MiningParameterMode::AutomatedTesting => AUTOMATED_TESTING_PROOF_SIZE,
MiningParameterMode::UserTesting => USER_TESTING_PROOF_SIZE,
@@ -86,8 +87,8 @@ pub fn proofsize() -> usize {
/// Are we in automated testing mode?
pub fn is_automated_testing_mode() -> bool {
let param_ref=MINING_PARAMETER_MODE.read().unwrap();
if let MiningParameterMode::AutomatedTesting=*param_ref {
let param_ref = MINING_PARAMETER_MODE.read().unwrap();
if let MiningParameterMode::AutomatedTesting = *param_ref {
return true;
} else {
return false;
@@ -96,8 +97,8 @@ pub fn is_automated_testing_mode() -> bool {
/// Are we in production mode?
pub fn is_production_mode() -> bool {
let param_ref=MINING_PARAMETER_MODE.read().unwrap();
if let MiningParameterMode::Production=*param_ref {
let param_ref = MINING_PARAMETER_MODE.read().unwrap();
if let MiningParameterMode::Production = *param_ref {
return true;
} else {
return false;
@@ -105,30 +106,72 @@ pub fn is_production_mode() -> bool {
}
/// Helper function to get a nonce known to create a valid POW on
/// Helper function to get a nonce known to create a valid POW on
/// the genesis block, to prevent it taking ages. Should be fine for now
/// as the genesis block POW solution turns out to be the same for every new block chain
/// as the genesis block POW solution turns out to be the same for every new
/// block chain
/// at the moment
pub fn get_genesis_nonce() -> u64 {
let param_ref=MINING_PARAMETER_MODE.read().unwrap();
let param_ref = MINING_PARAMETER_MODE.read().unwrap();
match *param_ref {
MiningParameterMode::AutomatedTesting => 0, //won't make a difference
MiningParameterMode::UserTesting => 22141, //Magic nonce for current genesis block at cuckoo16
MiningParameterMode::Production => 1429942738856787200, //Magic nonce for current genesis at cuckoo30
// won't make a difference
MiningParameterMode::AutomatedTesting => 0,
// Magic nonce for current genesis block at cuckoo16
MiningParameterMode::UserTesting => 22141,
// Magic nonce for current genesis at cuckoo30
MiningParameterMode::Production => 1429942738856787200,
}
}
/// Returns the genesis POW for production, because it takes far too long to mine at production values
/// Returns the genesis POW for production, because it takes far too long to
/// mine at production values
/// using the internal miner
pub fn get_genesis_pow() -> [u32;42]{
//TODO: This is diff 26, probably just want a 10: mine one
[7444824, 11926557, 28520390, 30594072, 50854023, 52797085, 57882033,
59816511, 61404804, 84947619, 87779345, 115270337, 162618676,
166860710, 178656003, 178971372, 200454733, 209197630, 221231015,
228598741, 241012783, 245401183, 279080304, 295848517, 327300943,
329741709, 366394532, 382493153, 389329248, 404353381, 406012911,
418813499, 426573907, 452566575, 456930760, 463021458, 474340589,
476248039, 478197093, 487576917, 495653489, 501862896]
pub fn get_genesis_pow() -> [u32; 42] {
// TODO: This is diff 26, probably just want a 10: mine one
[
7444824,
11926557,
28520390,
30594072,
50854023,
52797085,
57882033,
59816511,
61404804,
84947619,
87779345,
115270337,
162618676,
166860710,
178656003,
178971372,
200454733,
209197630,
221231015,
228598741,
241012783,
245401183,
279080304,
295848517,
327300943,
329741709,
366394532,
382493153,
389329248,
404353381,
406012911,
418813499,
426573907,
452566575,
456930760,
463021458,
474340589,
476248039,
478197093,
487576917,
495653489,
501862896,
]
}
+35 -16
View File
@@ -55,9 +55,10 @@ impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Error::IOErr(ref e) => write!(f, "{}", e),
Error::UnexpectedData { expected: ref e, received: ref r } => {
write!(f, "expected {:?}, got {:?}", e, r)
}
Error::UnexpectedData {
expected: ref e,
received: ref r,
} => write!(f, "expected {:?}, got {:?}", e, r),
Error::CorruptedData => f.write_str("corrupted data"),
Error::TooLargeReadErr => f.write_str("too large read"),
}
@@ -75,7 +76,10 @@ impl error::Error for Error {
fn description(&self) -> &str {
match *self {
Error::IOErr(ref e) => error::Error::description(e),
Error::UnexpectedData { expected: _, received: _ } => "unexpected data",
Error::UnexpectedData {
expected: _,
received: _,
} => "unexpected data",
Error::CorruptedData => "corrupted data",
Error::TooLargeReadErr => "too large read",
}
@@ -180,7 +184,8 @@ pub trait Writeable {
/// Reads directly to a Reader, a utility type thinly wrapping an
/// underlying Read implementation.
pub trait Readable
where Self: Sized
where
Self: Sized,
{
/// Reads the data necessary to this Readable from the provided reader
fn read(reader: &mut Reader) -> Result<Self, Error>;
@@ -245,7 +250,9 @@ impl<'a> Reader for BinReader<'a> {
return Err(Error::TooLargeReadErr);
}
let mut buf = vec![0; length];
self.source.read_exact(&mut buf).map(move |_| buf).map_err(Error::IOErr)
self.source.read_exact(&mut buf).map(move |_| buf).map_err(
Error::IOErr,
)
}
fn expect_u8(&mut self, val: u8) -> Result<u8, Error> {
@@ -338,14 +345,19 @@ impl_int!(u32, write_u32, read_u32);
impl_int!(u64, write_u64, read_u64);
impl_int!(i64, write_i64, read_i64);
impl<T> Readable for Vec<T> where T: Readable {
impl<T> Readable for Vec<T>
where
T: Readable,
{
fn read(reader: &mut Reader) -> Result<Vec<T>, Error> {
let mut buf = Vec::new();
loop {
let elem = T::read(reader);
match elem {
Ok(e) => buf.push(e),
Err(Error::IOErr(ref ioerr)) if ioerr.kind() == io::ErrorKind::UnexpectedEof => break,
Err(Error::IOErr(ref ioerr)) if ioerr.kind() == io::ErrorKind::UnexpectedEof => {
break
}
Err(e) => return Err(e),
}
}
@@ -353,7 +365,10 @@ impl<T> Readable for Vec<T> where T: Readable {
}
}
impl<T> Writeable for Vec<T> where T: Writeable {
impl<T> Writeable for Vec<T>
where
T: Writeable,
{
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), Error> {
for elmt in self {
elmt.write(writer)?;
@@ -400,18 +415,22 @@ impl<A: Writeable, B: Writeable, C: Writeable, D: Writeable> Writeable for (A, B
impl<A: Readable, B: Readable, C: Readable> Readable for (A, B, C) {
fn read(reader: &mut Reader) -> Result<(A, B, C), Error> {
Ok((try!(Readable::read(reader)),
try!(Readable::read(reader)),
try!(Readable::read(reader))))
Ok((
try!(Readable::read(reader)),
try!(Readable::read(reader)),
try!(Readable::read(reader)),
))
}
}
impl<A: Readable, B: Readable, C: Readable, D: Readable> Readable for (A, B, C, D) {
fn read(reader: &mut Reader) -> Result<(A, B, C, D), Error> {
Ok((try!(Readable::read(reader)),
try!(Readable::read(reader)),
try!(Readable::read(reader)),
try!(Readable::read(reader))))
Ok((
try!(Readable::read(reader)),
try!(Readable::read(reader)),
try!(Readable::read(reader)),
try!(Readable::read(reader)),
))
}
}