diff --git a/core/src/core/block.rs b/core/src/core/block.rs index 5f223e08c..af324c7ac 100644 --- a/core/src/core/block.rs +++ b/core/src/core/block.rs @@ -64,8 +64,7 @@ impl Default for BlockHeader { } } -// Only Writeable implementation is required for hashing, which is part of -// core. Readable is in the ser package. +/// Serialization of a block header impl Writeable for BlockHeader { fn write(&self, writer: &mut Writer) -> Result<(), ser::Error> { ser_multiwrite!(writer, @@ -88,6 +87,37 @@ impl Writeable for BlockHeader { } } +/// Deserialization of a block header +impl Readable for BlockHeader { + fn read(reader: &mut Reader) -> Result { + let (height, previous, timestamp, cuckoo_len) = + ser_multiread!(reader, read_u64, read_32_bytes, read_i64, read_u8); + let target = try!(Target::read(reader)); + let (utxo_merkle, tx_merkle, nonce) = + ser_multiread!(reader, read_32_bytes, read_32_bytes, read_u64); + + // cuckoo cycle of 42 nodes + let mut pow = [0; PROOFSIZE]; + for n in 0..PROOFSIZE { + pow[n] = try!(reader.read_u32()); + } + Ok(BlockHeader { + height: height, + previous: Hash::from_vec(previous), + timestamp: time::at_utc(time::Timespec { + sec: timestamp, + nsec: 0, + }), + cuckoo_len: cuckoo_len, + target: target, + utxo_merkle: Hash::from_vec(utxo_merkle), + tx_merkle: Hash::from_vec(tx_merkle), + pow: Proof(pow), + nonce: nonce, + }) + } +} + /// A block as expressed in the MimbleWimble protocol. The reward is /// non-explicit, assumed to be deductible from block height (similar to /// bitcoin's schedule) and expressed as a global transaction fee (added v.H), @@ -127,24 +157,14 @@ impl Writeable for Block { /// from a binary stream. impl Readable for Block { fn read(reader: &mut Reader) -> Result { - let (height, previous, timestamp, cuckoo_len) = - ser_multiread!(reader, read_u64, read_32_bytes, read_i64, read_u8); - let target = try!(Target::read(reader)); - let (utxo_merkle, tx_merkle, nonce) = - ser_multiread!(reader, read_32_bytes, read_32_bytes, read_u64); + let header = try!(BlockHeader::read(reader)); - // cuckoo cycle of 42 nodes - let mut pow = [0; PROOFSIZE]; - for n in 0..PROOFSIZE { - pow[n] = try!(reader.read_u32()); - } - - let (td, input_len, output_len, proof_len) = - ser_multiread!(reader, read_u64, read_u64, read_u64, read_u64); + let (input_len, output_len, proof_len) = + ser_multiread!(reader, read_u64, read_u64, read_u64); if input_len > MAX_IN_OUT_LEN || output_len > MAX_IN_OUT_LEN || proof_len > MAX_IN_OUT_LEN { - return Err(ser::Error::TooLargeReadErr("Too many inputs, outputs or proofs." - .to_string())); + return Err(ser::Error::TooLargeReadErr( + "Too many inputs, outputs or proofs.".to_string())); } let inputs = try!((0..input_len).map(|_| Input::read(reader)).collect()); @@ -152,20 +172,7 @@ impl Readable for Block { let proofs = try!((0..proof_len).map(|_| TxProof::read(reader)).collect()); Ok(Block { - header: BlockHeader { - height: height, - previous: Hash::from_vec(previous), - timestamp: time::at_utc(time::Timespec { - sec: timestamp, - nsec: 0, - }), - cuckoo_len: cuckoo_len, - target: target, - utxo_merkle: Hash::from_vec(utxo_merkle), - tx_merkle: Hash::from_vec(tx_merkle), - pow: Proof(pow), - nonce: nonce, - }, + header: header, inputs: inputs, outputs: outputs, proofs: proofs, diff --git a/core/src/pow/mod.rs b/core/src/pow/mod.rs index fdefd8615..08255760e 100644 --- a/core/src/pow/mod.rs +++ b/core/src/pow/mod.rs @@ -88,21 +88,21 @@ impl PowHeader { } /// Validates the proof of work of a given header. -pub fn verify(b: &Block, target: Target) -> bool { - verify_size(b, target, b.header.cuckoo_len as u32) +pub fn verify(b: &Block) -> bool { + verify_size(b, b.header.cuckoo_len as u32) } /// Same as default verify function but uses the much easier Cuckoo20 (mostly /// for tests). -pub fn verify20(b: &Block, target: Target) -> bool { - verify_size(b, target, 20) +pub fn verify20(b: &Block) -> bool { + verify_size(b, 20) } -pub fn verify_size(b: &Block, target: Target, sizeshift: u32) -> bool { +pub fn verify_size(b: &Block, sizeshift: u32) -> bool { let hash = PowHeader::from_block(b).hash(); // make sure the hash is smaller than our target before going into more // expensive validation - if target < b.header.pow.to_target() { + if b.header.target < b.header.pow.to_target() { return false; } Cuckoo::new(hash.to_slice(), sizeshift).verify(b.header.pow, EASINESS as u64) @@ -165,6 +165,6 @@ mod test { assert!(proof.to_target() < MAX_TARGET); b.header.pow = proof; b.header.nonce = nonce; - assert!(verify20(&b, MAX_TARGET)); + assert!(verify20(&b)); } }