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:
committed by
Ignotus Peverell
parent
1bad7188b7
commit
b53b84b0c6
+49
-31
@@ -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
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user