mirror of
https://github.com/mimblewimble/grin.git
synced 2025-01-20 19:11: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::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::prelude::{DateTime, NaiveDateTime, Utc};
|
||||
use chrono::Duration;
|
||||
|
@ -34,6 +37,7 @@ use std::collections::HashSet;
|
|||
use std::fmt;
|
||||
use std::iter::FromIterator;
|
||||
use std::sync::Arc;
|
||||
use util::from_hex;
|
||||
use util::RwLock;
|
||||
use util::{secp, static_secp_instance};
|
||||
|
||||
|
@ -350,6 +354,23 @@ impl BlockHeader {
|
|||
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
|
||||
pub fn total_difficulty(&self) -> 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::ProofBuilder;
|
||||
use crate::core::pow::Proof;
|
||||
use crate::core::{global, ser};
|
||||
use chrono::Duration;
|
||||
use grin_core as core;
|
||||
|
@ -569,3 +570,36 @@ fn wrong_amount_range_proof() {
|
|||
_ => 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