Move nonce/pow to end of block header, change post-pow hash (#794)

* move nonce/pow to end of block header, update call to cuckoo-miner
* change header hash to be pow only
* fix genesis block miner and tests
This commit is contained in:
Yeastplume
2018-03-16 19:04:31 +00:00
committed by Ignotus Peverell
parent 1bad7188b7
commit b53b84b0c6
6 changed files with 103 additions and 94 deletions
+49 -31
View File
@@ -22,7 +22,7 @@ use core::{Committed, Input, KernelFeatures, Output, OutputFeatures, Proof, Proo
ShortId, SwitchCommitHash, Transaction, TxKernel};
use consensus;
use consensus::{exceeds_weight, reward, VerifySortOrder, REWARD};
use core::hash::{Hash, Hashed, ZERO_HASH};
use core::hash::{Hash, HashWriter, Hashed, ZERO_HASH};
use core::id::ShortIdentifiable;
use core::target::Difficulty;
use core::transaction;
@@ -105,22 +105,22 @@ pub struct BlockHeader {
pub previous: Hash,
/// Timestamp at which the block was built.
pub timestamp: time::Tm,
/// Total accumulated difficulty since genesis block
pub total_difficulty: Difficulty,
/// Merklish root of all the commitments in the TxHashSet
pub output_root: Hash,
/// Merklish root of all range proofs in the TxHashSet
pub range_proof_root: Hash,
/// Merklish root of all transaction kernels in the TxHashSet
pub kernel_root: Hash,
/// Nonce increment used to mine this block.
pub nonce: u64,
/// Proof of work data.
pub pow: Proof,
/// Total accumulated difficulty since genesis block
pub total_difficulty: Difficulty,
/// Total accumulated sum of kernel offsets since genesis block.
/// We can derive the kernel offset sum for *this* block from
/// the total kernel offset of the previous block header.
pub total_kernel_offset: BlindingFactor,
/// Nonce increment used to mine this block.
pub nonce: u64,
/// Proof of work data.
pub pow: Proof,
}
impl Default for BlockHeader {
@@ -135,9 +135,9 @@ impl Default for BlockHeader {
output_root: ZERO_HASH,
range_proof_root: ZERO_HASH,
kernel_root: ZERO_HASH,
total_kernel_offset: BlindingFactor::zero(),
nonce: 0,
pow: Proof::zero(proof_size),
total_kernel_offset: BlindingFactor::zero(),
}
}
}
@@ -145,23 +145,11 @@ 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_u16, self.version],
[write_u64, self.height],
[write_fixed_bytes, &self.previous],
[write_i64, self.timestamp.to_timespec().sec],
[write_fixed_bytes, &self.output_root],
[write_fixed_bytes, &self.range_proof_root],
[write_fixed_bytes, &self.kernel_root]
);
try!(writer.write_u64(self.nonce));
try!(self.total_difficulty.write(writer));
try!(self.total_kernel_offset.write(writer));
if writer.serialization_mode() != ser::SerializationMode::Hash {
if writer.serialization_mode() == ser::SerializationMode::Hash {
try!(self.pow.write(writer));
} else {
self.write_pre_pow(writer)?;
self.pow.write(writer)?;
}
Ok(())
}
@@ -173,12 +161,12 @@ impl Readable for BlockHeader {
let (version, height) = ser_multiread!(reader, read_u16, read_u64);
let previous = Hash::read(reader)?;
let timestamp = reader.read_i64()?;
let total_difficulty = Difficulty::read(reader)?;
let output_root = Hash::read(reader)?;
let rproof_root = Hash::read(reader)?;
let kernel_root = Hash::read(reader)?;
let nonce = reader.read_u64()?;
let total_difficulty = Difficulty::read(reader)?;
let total_kernel_offset = BlindingFactor::read(reader)?;
let nonce = reader.read_u64()?;
let pow = Proof::read(reader)?;
if timestamp > (1 << 60) {
@@ -193,17 +181,47 @@ impl Readable for BlockHeader {
sec: timestamp,
nsec: 0,
}),
total_difficulty: total_difficulty,
output_root: output_root,
range_proof_root: rproof_root,
kernel_root: kernel_root,
pow: pow,
nonce: nonce,
total_difficulty: total_difficulty,
total_kernel_offset: total_kernel_offset,
nonce: nonce,
pow: pow,
})
}
}
impl BlockHeader {
/// Write the pre-hash portion of the header
pub fn write_pre_pow<W: Writer>(&self, writer: &mut W) -> Result<(), ser::Error> {
ser_multiwrite!(
writer,
[write_u16, self.version],
[write_u64, self.height],
[write_fixed_bytes, &self.previous],
[write_i64, self.timestamp.to_timespec().sec],
[write_u64, self.total_difficulty.into_num()],
[write_fixed_bytes, &self.output_root],
[write_fixed_bytes, &self.range_proof_root],
[write_fixed_bytes, &self.kernel_root],
[write_fixed_bytes, &self.total_kernel_offset],
[write_u64, self.nonce]
);
Ok(())
}
///
/// Returns the pre-pow hash, as the post-pow hash
/// should just be the hash of the POW
pub fn pre_pow_hash(&self) -> Hash {
let mut hasher = HashWriter::default();
self.write_pre_pow(&mut hasher).unwrap();
let mut ret = [0; 32];
hasher.finalize(&mut ret);
Hash(ret)
}
}
/// Compact representation of a full block.
/// Each input/output/kernel is represented as a short_id.
/// A node is reasonably likely to have already seen all tx data (tx broadcast before block)
@@ -566,7 +584,7 @@ impl Block {
}.cut_through())
}
/// Blockhash, computed using only the header
/// Blockhash, computed using only the POW
pub fn hash(&self) -> Hash {
self.header.hash()
}
@@ -1124,7 +1142,7 @@ mod test {
let cb2 = b.as_compact_block();
// random nonce will not affect the hash of the compact block itself
// hash is based on header only
// hash is based on header POW only
assert!(cb1.nonce != cb2.nonce);
assert_eq!(b.hash(), cb1.hash());
assert_eq!(cb1.hash(), cb2.hash());
+17 -1
View File
@@ -24,7 +24,8 @@ pub mod transaction;
// pub mod txoset;
#[allow(dead_code)]
use std::fmt;
use rand::{thread_rng, Rng};
use std::{fmt, iter};
use std::cmp::Ordering;
use std::num::ParseFloatError;
use consensus::GRIN_BASE;
@@ -152,6 +153,21 @@ impl Proof {
}
}
/// Builds a proof with random POW data,
/// needed so that tests that ignore POW
/// don't fail due to duplicate hashes
pub fn random(proof_size: usize) -> Proof {
let mut rng = thread_rng();
let v: Vec<u32> = iter::repeat(())
.map(|()| rng.gen())
.take(proof_size)
.collect();
Proof {
proof_size: proof_size,
nonces: v,
}
}
/// Converts the proof to a vector of u64s
pub fn to_u64s(&self) -> Vec<u64> {
let mut out_nonces = Vec::with_capacity(self.proof_size);