Formatting.
This commit is contained in:
+21
-20
@@ -46,7 +46,7 @@ pub struct BlockHeader {
|
||||
pub timestamp: time::Tm,
|
||||
/// Length of the cuckoo cycle used to mine this block.
|
||||
pub cuckoo_len: u8,
|
||||
/// Merkle root of the UTXO set
|
||||
/// Merkle root of the UTXO set
|
||||
pub utxo_merkle: Hash,
|
||||
/// Merkle tree of hashes for all inputs, outputs and kernels in the block
|
||||
pub tx_merkle: Hash,
|
||||
@@ -90,7 +90,7 @@ impl Writeable for BlockHeader {
|
||||
[write_u8, self.cuckoo_len],
|
||||
[write_fixed_bytes, &self.utxo_merkle],
|
||||
[write_fixed_bytes, &self.tx_merkle],
|
||||
[write_u8, self.features.bits()]);
|
||||
[write_u8, self.features.bits()]);
|
||||
|
||||
try!(writer.write_u64(self.nonce));
|
||||
try!(self.difficulty.write(writer));
|
||||
@@ -141,13 +141,13 @@ impl Readable for BlockHeader {
|
||||
/// additive to the total of fees ever collected.
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct Block {
|
||||
/// The header with metadata and commitments to the rest of the data
|
||||
/// The header with metadata and commitments to the rest of the data
|
||||
pub header: BlockHeader,
|
||||
/// List of transaction inputs
|
||||
/// List of transaction inputs
|
||||
pub inputs: Vec<Input>,
|
||||
/// List of transaction outputs
|
||||
/// List of transaction outputs
|
||||
pub outputs: Vec<Output>,
|
||||
/// List of transaction kernels and associated proofs
|
||||
/// List of transaction kernels and associated proofs
|
||||
pub kernels: Vec<TxKernel>,
|
||||
}
|
||||
|
||||
@@ -228,7 +228,6 @@ impl Default for Block {
|
||||
}
|
||||
|
||||
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.
|
||||
@@ -240,17 +239,17 @@ impl Block {
|
||||
let secp = Secp256k1::with_caps(secp::ContextFlag::Commit);
|
||||
let (reward_out, reward_proof) = try!(Block::reward_output(reward_key, &secp));
|
||||
|
||||
Block::with_reward(prev, txs, reward_out, reward_proof)
|
||||
Block::with_reward(prev, txs, reward_out, reward_proof)
|
||||
}
|
||||
|
||||
/// Builds a new block ready to mine from the header of the previous block,
|
||||
/// a vector of transactions and the reward information. Checks
|
||||
/// 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<&mut Transaction>,
|
||||
reward_out: Output,
|
||||
reward_kern: TxKernel)
|
||||
-> Result<Block, secp::Error> {
|
||||
txs: Vec<&mut 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);
|
||||
@@ -295,15 +294,15 @@ impl Block {
|
||||
kernels: kernels,
|
||||
}
|
||||
.compact())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Blockhash, computed using only the header
|
||||
/// Blockhash, computed using only the header
|
||||
pub fn hash(&self) -> Hash {
|
||||
self.header.hash()
|
||||
}
|
||||
|
||||
/// Sum of all fees (inputs less outputs) in the block
|
||||
/// Sum of all fees (inputs less outputs) in the block
|
||||
pub fn total_fees(&self) -> u64 {
|
||||
self.kernels.iter().map(|p| p.fee).sum()
|
||||
}
|
||||
@@ -350,7 +349,8 @@ impl Block {
|
||||
}
|
||||
}
|
||||
|
||||
/// Merges the 2 blocks, essentially appending the inputs, outputs and kernels.
|
||||
/// Merges the 2 blocks, essentially appending the inputs, outputs and
|
||||
/// kernels.
|
||||
/// Also performs a compaction on the result.
|
||||
pub fn merge(&self, other: Block) -> Block {
|
||||
let mut all_inputs = self.inputs.clone();
|
||||
@@ -448,10 +448,11 @@ impl Block {
|
||||
.verify_kernels(secp)
|
||||
}
|
||||
|
||||
/// Builds the blinded output and related signature proof for the block reward.
|
||||
/// 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> {
|
||||
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();
|
||||
|
||||
@@ -205,9 +205,8 @@ mod test {
|
||||
#[test]
|
||||
fn blind_simpler_tx() {
|
||||
let secp = Secp256k1::with_caps(secp::ContextFlag::Commit);
|
||||
let (tx, _) =
|
||||
transaction(vec![input_rand(6), output(2, key::ONE_KEY), with_fee(4)])
|
||||
.unwrap();
|
||||
let (tx, _) = transaction(vec![input_rand(6), output(2, key::ONE_KEY), with_fee(4)])
|
||||
.unwrap();
|
||||
tx.verify_sig(&secp).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
+41
-39
@@ -48,15 +48,15 @@ impl fmt::Display for Hash {
|
||||
}
|
||||
|
||||
impl Hash {
|
||||
/// Builds a Hash from a byte vector. If the vector is too short, it will be
|
||||
/// completed by zeroes. If it's too long, it will be truncated.
|
||||
pub fn from_vec(v: Vec<u8>) -> Hash {
|
||||
let mut h = [0; 32];
|
||||
for i in 0..min(v.len(), 32) {
|
||||
h[i] = v[i];
|
||||
}
|
||||
Hash(h)
|
||||
}
|
||||
/// Builds a Hash from a byte vector. If the vector is too short, it will be
|
||||
/// completed by zeroes. If it's too long, it will be truncated.
|
||||
pub fn from_vec(v: Vec<u8>) -> Hash {
|
||||
let mut h = [0; 32];
|
||||
for i in 0..min(v.len(), 32) {
|
||||
h[i] = v[i];
|
||||
}
|
||||
Hash(h)
|
||||
}
|
||||
|
||||
/// Converts the hash to a byte vector
|
||||
pub fn to_vec(&self) -> Vec<u8> {
|
||||
@@ -65,49 +65,49 @@ impl Hash {
|
||||
}
|
||||
|
||||
impl ops::Index<usize> for Hash {
|
||||
type Output = u8;
|
||||
type Output = u8;
|
||||
|
||||
fn index(&self, idx: usize) -> &u8 {
|
||||
&self.0[idx]
|
||||
}
|
||||
fn index(&self, idx: usize) -> &u8 {
|
||||
&self.0[idx]
|
||||
}
|
||||
}
|
||||
|
||||
impl ops::Index<ops::Range<usize>> for Hash {
|
||||
type Output = [u8];
|
||||
type Output = [u8];
|
||||
|
||||
fn index(&self, idx: ops::Range<usize>) -> &[u8] {
|
||||
&self.0[idx]
|
||||
}
|
||||
fn index(&self, idx: ops::Range<usize>) -> &[u8] {
|
||||
&self.0[idx]
|
||||
}
|
||||
}
|
||||
|
||||
impl ops::Index<ops::RangeTo<usize>> for Hash {
|
||||
type Output = [u8];
|
||||
type Output = [u8];
|
||||
|
||||
fn index(&self, idx: ops::RangeTo<usize>) -> &[u8] {
|
||||
&self.0[idx]
|
||||
}
|
||||
fn index(&self, idx: ops::RangeTo<usize>) -> &[u8] {
|
||||
&self.0[idx]
|
||||
}
|
||||
}
|
||||
|
||||
impl ops::Index<ops::RangeFrom<usize>> for Hash {
|
||||
type Output = [u8];
|
||||
type Output = [u8];
|
||||
|
||||
fn index(&self, idx: ops::RangeFrom<usize>) -> &[u8] {
|
||||
&self.0[idx]
|
||||
}
|
||||
fn index(&self, idx: ops::RangeFrom<usize>) -> &[u8] {
|
||||
&self.0[idx]
|
||||
}
|
||||
}
|
||||
|
||||
impl ops::Index<ops::RangeFull> for Hash {
|
||||
type Output = [u8];
|
||||
type Output = [u8];
|
||||
|
||||
fn index(&self, idx: ops::RangeFull) -> &[u8] {
|
||||
&self.0[idx]
|
||||
}
|
||||
fn index(&self, idx: ops::RangeFull) -> &[u8] {
|
||||
&self.0[idx]
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<[u8]> for Hash {
|
||||
fn as_ref(&self) -> &[u8] {
|
||||
&self.0
|
||||
}
|
||||
fn as_ref(&self) -> &[u8] {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl Readable for Hash {
|
||||
@@ -133,17 +133,19 @@ pub struct HashWriter {
|
||||
}
|
||||
|
||||
impl HashWriter {
|
||||
/// Consume the `HashWriter`, outputting its current hash into a 32-byte array
|
||||
/// Consume the `HashWriter`, outputting its current hash into a 32-byte
|
||||
/// array
|
||||
pub fn finalize(self, output: &mut [u8]) {
|
||||
self.state.finalize(output);
|
||||
}
|
||||
|
||||
/// Consume the `HashWriter`, outputting a `Hash` corresponding to its current state
|
||||
pub fn into_hash(self) -> Hash {
|
||||
let mut new_hash = ZERO_HASH;
|
||||
/// Consume the `HashWriter`, outputting a `Hash` corresponding to its
|
||||
/// current state
|
||||
pub fn into_hash(self) -> Hash {
|
||||
let mut new_hash = ZERO_HASH;
|
||||
self.state.finalize(&mut new_hash.0[..]);
|
||||
new_hash
|
||||
}
|
||||
new_hash
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for HashWriter {
|
||||
@@ -165,7 +167,7 @@ impl ser::Writer for HashWriter {
|
||||
|
||||
/// A trait for types that have a canonical hash
|
||||
pub trait Hashed {
|
||||
/// Obtain the hash of the object
|
||||
/// Obtain the hash of the object
|
||||
fn hash(&self) -> Hash;
|
||||
}
|
||||
|
||||
|
||||
+12
-12
@@ -33,7 +33,7 @@ pub const MAX_TARGET: [u8; 32] = [0xf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
/// The difficulty is defined as the maximum target divided by the block hash.
|
||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord)]
|
||||
pub struct Difficulty {
|
||||
num: BigUint
|
||||
num: BigUint,
|
||||
}
|
||||
|
||||
impl Difficulty {
|
||||
@@ -44,15 +44,15 @@ impl Difficulty {
|
||||
Difficulty { num: BigUint::new(vec![1]) }
|
||||
}
|
||||
|
||||
/// Convert a `u32` into a `Difficulty`
|
||||
/// Convert a `u32` into a `Difficulty`
|
||||
pub fn from_num(num: u32) -> Difficulty {
|
||||
Difficulty { num: BigUint::new(vec![num]) }
|
||||
}
|
||||
|
||||
/// Convert a `BigUint` into a `Difficulty`
|
||||
pub fn from_biguint(num: BigUint) -> Difficulty {
|
||||
Difficulty { num: num }
|
||||
}
|
||||
/// Convert a `BigUint` into a `Difficulty`
|
||||
pub fn from_biguint(num: BigUint) -> Difficulty {
|
||||
Difficulty { num: num }
|
||||
}
|
||||
|
||||
/// Computes the difficulty from a hash. Divides the maximum target by the
|
||||
/// provided hash.
|
||||
@@ -62,16 +62,16 @@ impl Difficulty {
|
||||
Difficulty { num: max_target / h_num }
|
||||
}
|
||||
|
||||
/// Converts the difficulty into a bignum
|
||||
pub fn into_biguint(self) -> BigUint {
|
||||
self.num
|
||||
}
|
||||
/// Converts the difficulty into a bignum
|
||||
pub fn into_biguint(self) -> BigUint {
|
||||
self.num
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Difficulty {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}", self.num)
|
||||
}
|
||||
write!(f, "{}", self.num)
|
||||
}
|
||||
}
|
||||
|
||||
impl Add<Difficulty> for Difficulty {
|
||||
|
||||
@@ -55,10 +55,10 @@ 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]);
|
||||
[write_u8, self.features.bits()],
|
||||
[write_fixed_bytes, &self.excess],
|
||||
[write_bytes, &self.excess_sig],
|
||||
[write_u64, self.fee]);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -261,7 +261,7 @@ impl Readable for Input {
|
||||
/// The input for a transaction, which spends a pre-existing output. The input
|
||||
/// commitment is a reproduction of the commitment of the output it's spending.
|
||||
impl Input {
|
||||
/// Extracts the referenced commitment from a transaction output
|
||||
/// Extracts the referenced commitment from a transaction output
|
||||
pub fn commitment(&self) -> Commitment {
|
||||
self.0
|
||||
}
|
||||
@@ -286,9 +286,9 @@ bitflags! {
|
||||
pub struct Output {
|
||||
/// Options for an output's structure or use
|
||||
pub features: OutputFeatures,
|
||||
/// The homomorphic commitment representing the output's amount
|
||||
/// The homomorphic commitment representing the output's amount
|
||||
pub commit: Commitment,
|
||||
/// A proof that the commitment is in the right range
|
||||
/// A proof that the commitment is in the right range
|
||||
pub proof: RangeProof,
|
||||
}
|
||||
|
||||
@@ -296,7 +296,9 @@ 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)?
|
||||
|
||||
@@ -32,9 +32,9 @@ const MAXPATHLEN: usize = 8192;
|
||||
/// A cuckoo-cycle related error
|
||||
#[derive(Debug)]
|
||||
pub enum Error {
|
||||
/// Unable to find a short enough path
|
||||
/// Unable to find a short enough path
|
||||
Path,
|
||||
/// Unable to find a solution
|
||||
/// Unable to find a solution
|
||||
NoSolution,
|
||||
}
|
||||
|
||||
@@ -168,7 +168,7 @@ enum CycleSol {
|
||||
}
|
||||
|
||||
impl Miner {
|
||||
/// Creates a new miner
|
||||
/// Creates a new miner
|
||||
pub fn new(header: &[u8], ease: u32, sizeshift: u32) -> Miner {
|
||||
let cuckoo = Cuckoo::new(header, sizeshift);
|
||||
let size = 1 << sizeshift;
|
||||
@@ -181,7 +181,7 @@ impl Miner {
|
||||
}
|
||||
}
|
||||
|
||||
/// Searches for a solution
|
||||
/// Searches for a solution
|
||||
pub fn mine(&mut self) -> Result<Proof, Error> {
|
||||
let mut us = [0; MAXPATHLEN];
|
||||
let mut vs = [0; MAXPATHLEN];
|
||||
|
||||
+23
-22
@@ -34,9 +34,9 @@ pub enum Error {
|
||||
IOErr(io::Error),
|
||||
/// Expected a given value that wasn't found
|
||||
UnexpectedData {
|
||||
/// What we wanted
|
||||
/// What we wanted
|
||||
expected: Vec<u8>,
|
||||
/// What we got
|
||||
/// What we got
|
||||
received: Vec<u8>,
|
||||
},
|
||||
/// Data wasn't in a consumable format
|
||||
@@ -179,7 +179,9 @@ pub trait Writeable {
|
||||
/// Trait that every type that can be deserialized from binary must implement.
|
||||
/// Reads directly to a Reader, a utility type thinly wrapping an
|
||||
/// underlying Read implementation.
|
||||
pub trait Readable where Self: Sized {
|
||||
pub trait Readable
|
||||
where Self: Sized
|
||||
{
|
||||
/// Reads the data necessary to this Readable from the provided reader
|
||||
fn read(reader: &mut Reader) -> Result<Self, Error>;
|
||||
}
|
||||
@@ -326,36 +328,35 @@ impl_int!(u64, write_u64, read_u64);
|
||||
impl_int!(i64, write_i64, read_i64);
|
||||
|
||||
impl<A: Writeable, B: Writeable> Writeable for (A, B) {
|
||||
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), Error> {
|
||||
try!(Writeable::write(&self.0, writer));
|
||||
Writeable::write(&self.1, writer)
|
||||
}
|
||||
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), Error> {
|
||||
try!(Writeable::write(&self.0, writer));
|
||||
Writeable::write(&self.1, writer)
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: Readable, B: Readable> Readable for (A, B) {
|
||||
fn read(reader: &mut Reader) -> Result<(A, B), Error> {
|
||||
Ok((try!(Readable::read(reader)),
|
||||
try!(Readable::read(reader))))
|
||||
}
|
||||
fn read(reader: &mut Reader) -> Result<(A, B), Error> {
|
||||
Ok((try!(Readable::read(reader)), try!(Readable::read(reader))))
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: Writeable, B: Writeable, C: Writeable> Writeable for (A, B, C) {
|
||||
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), Error> {
|
||||
try!(Writeable::write(&self.0, writer));
|
||||
try!(Writeable::write(&self.1, writer));
|
||||
Writeable::write(&self.2, writer)
|
||||
}
|
||||
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), Error> {
|
||||
try!(Writeable::write(&self.0, writer));
|
||||
try!(Writeable::write(&self.1, writer));
|
||||
Writeable::write(&self.2, writer)
|
||||
}
|
||||
}
|
||||
|
||||
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))))
|
||||
}
|
||||
fn read(reader: &mut Reader) -> Result<(A, B, C), Error> {
|
||||
Ok((try!(Readable::read(reader)),
|
||||
try!(Readable::read(reader)),
|
||||
try!(Readable::read(reader))))
|
||||
}
|
||||
}
|
||||
|
||||
/// Useful marker trait on types that can be sized byte slices
|
||||
/// Useful marker trait on types that can be sized byte slices
|
||||
pub trait AsFixedBytes: Sized + AsRef<[u8]> {}
|
||||
|
||||
impl<'a> AsFixedBytes for &'a [u8] {}
|
||||
|
||||
Reference in New Issue
Block a user