mirror of
https://github.com/mimblewimble/grin.git
synced 2025-01-21 03:21:08 +03:00
Build block header from pre pow data and proof (#3178)
* Implement validation and generation of block header by proof and pre pow * Optimize * handle missed ser result errors and test invalid pre_pow * switch to specific error mapping * clean import
This commit is contained in:
parent
4449c91c04
commit
4152d9fc0c
2 changed files with 56 additions and 1 deletions
|
@ -25,7 +25,10 @@ use crate::core::{
|
||||||
};
|
};
|
||||||
use crate::global;
|
use crate::global;
|
||||||
use crate::pow::{verify_size, Difficulty, Proof, ProofOfWork};
|
use crate::pow::{verify_size, Difficulty, Proof, ProofOfWork};
|
||||||
use crate::ser::{self, FixedLength, PMMRable, Readable, Reader, Writeable, Writer};
|
use crate::ser::{
|
||||||
|
self, deserialize_default, serialize_default, FixedLength, PMMRable, Readable, Reader,
|
||||||
|
Writeable, Writer,
|
||||||
|
};
|
||||||
use chrono::naive::{MAX_DATE, MIN_DATE};
|
use chrono::naive::{MAX_DATE, MIN_DATE};
|
||||||
use chrono::prelude::{DateTime, NaiveDateTime, Utc};
|
use chrono::prelude::{DateTime, NaiveDateTime, Utc};
|
||||||
use chrono::Duration;
|
use chrono::Duration;
|
||||||
|
@ -34,6 +37,7 @@ use std::collections::HashSet;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::iter::FromIterator;
|
use std::iter::FromIterator;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
use util::from_hex;
|
||||||
use util::RwLock;
|
use util::RwLock;
|
||||||
use util::{secp, static_secp_instance};
|
use util::{secp, static_secp_instance};
|
||||||
|
|
||||||
|
@ -350,6 +354,23 @@ impl BlockHeader {
|
||||||
header_buf
|
header_buf
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Constructs a header given pre_pow string, nonce, and proof
|
||||||
|
pub fn from_pre_pow_and_proof(
|
||||||
|
pre_pow: String,
|
||||||
|
nonce: u64,
|
||||||
|
proof: Proof,
|
||||||
|
) -> Result<Self, Error> {
|
||||||
|
// Convert hex pre pow string
|
||||||
|
let mut header_bytes = from_hex(pre_pow)
|
||||||
|
.map_err(|e| Error::Serialization(ser::Error::HexError(e.to_string())))?;
|
||||||
|
// Serialize and append serialized nonce and proof
|
||||||
|
serialize_default(&mut header_bytes, &nonce)?;
|
||||||
|
serialize_default(&mut header_bytes, &proof)?;
|
||||||
|
|
||||||
|
// Deserialize header from constructed bytes
|
||||||
|
Ok(deserialize_default(&mut &header_bytes[..])?)
|
||||||
|
}
|
||||||
|
|
||||||
/// Total difficulty accumulated by the proof of work on this header
|
/// Total difficulty accumulated by the proof of work on this header
|
||||||
pub fn total_difficulty(&self) -> Difficulty {
|
pub fn total_difficulty(&self) -> Difficulty {
|
||||||
self.pow.total_difficulty
|
self.pow.total_difficulty
|
||||||
|
|
|
@ -26,6 +26,7 @@ use crate::core::core::{
|
||||||
};
|
};
|
||||||
use crate::core::libtx::build::{self, input, output};
|
use crate::core::libtx::build::{self, input, output};
|
||||||
use crate::core::libtx::ProofBuilder;
|
use crate::core::libtx::ProofBuilder;
|
||||||
|
use crate::core::pow::Proof;
|
||||||
use crate::core::{global, ser};
|
use crate::core::{global, ser};
|
||||||
use chrono::Duration;
|
use chrono::Duration;
|
||||||
use grin_core as core;
|
use grin_core as core;
|
||||||
|
@ -569,3 +570,36 @@ fn wrong_amount_range_proof() {
|
||||||
_ => panic!("Bad range proof should be invalid"),
|
_ => panic!("Bad range proof should be invalid"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn validate_header_proof() {
|
||||||
|
let keychain = ExtKeychain::from_random_seed(false).unwrap();
|
||||||
|
let builder = ProofBuilder::new(&keychain);
|
||||||
|
let prev = BlockHeader::default();
|
||||||
|
let key_id = ExtKeychain::derive_key_id(1, 1, 0, 0, 0);
|
||||||
|
let b = new_block(vec![], &keychain, &builder, &prev, &key_id);
|
||||||
|
|
||||||
|
let mut header_buf = vec![];
|
||||||
|
{
|
||||||
|
let mut writer = ser::BinWriter::default(&mut header_buf);
|
||||||
|
b.header.write_pre_pow(&mut writer).unwrap();
|
||||||
|
b.header.pow.write_pre_pow(&mut writer).unwrap();
|
||||||
|
}
|
||||||
|
let pre_pow = util::to_hex(header_buf);
|
||||||
|
|
||||||
|
let reconstructed = BlockHeader::from_pre_pow_and_proof(
|
||||||
|
pre_pow,
|
||||||
|
b.header.pow.nonce,
|
||||||
|
b.header.pow.proof.clone(),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
assert_eq!(reconstructed, b.header);
|
||||||
|
|
||||||
|
// assert invalid pre_pow returns error
|
||||||
|
assert!(BlockHeader::from_pre_pow_and_proof(
|
||||||
|
"0xaf1678".to_string(),
|
||||||
|
b.header.pow.nonce,
|
||||||
|
b.header.pow.proof.clone(),
|
||||||
|
)
|
||||||
|
.is_err());
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue