feat: Add Byron header hashing (#45)
This commit is contained in:
parent
af314a60c4
commit
769e044bad
4 changed files with 141 additions and 73 deletions
47
pallas-primitives/src/byron/crypto.rs
Normal file
47
pallas-primitives/src/byron/crypto.rs
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
use super::{Block, BlockHead, EbbHead};
|
||||||
|
use pallas_crypto::hash::{Hash, Hasher};
|
||||||
|
|
||||||
|
pub fn hash_boundary_block_header(header: &EbbHead) -> Hash<32> {
|
||||||
|
// hash expects to have a prefix for the type of block
|
||||||
|
Hasher::<256>::hash_cbor(&(0, header))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn hash_main_block_header(header: &BlockHead) -> Hash<32> {
|
||||||
|
// hash expects to have a prefix for the type of block
|
||||||
|
Hasher::<256>::hash_cbor(&(1, header))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn hash_block_header(block: &Block) -> Hash<32> {
|
||||||
|
match block {
|
||||||
|
Block::EbBlock(x) => hash_boundary_block_header(&x.header),
|
||||||
|
Block::MainBlock(x) => hash_main_block_header(&x.header),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//pub fn hash_transaction(data: &TransactionBody) -> Hash<32> {
|
||||||
|
// Hasher::<256>::hash_cbor(data)
|
||||||
|
//}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use crate::byron::Block;
|
||||||
|
use crate::Fragment;
|
||||||
|
|
||||||
|
const KNOWN_HASH: &'static str =
|
||||||
|
"5c196e7394ace0449ba5a51c919369699b13896e97432894b4f0354dce8670b6";
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn transaction_hash_works() {
|
||||||
|
// TODO: expand this test to include more test blocks
|
||||||
|
let block_idx = 1;
|
||||||
|
let block_str = include_str!("test_data/test1.block");
|
||||||
|
|
||||||
|
let block_bytes = hex::decode(block_str).expect(&format!("bad block file {}", block_idx));
|
||||||
|
let block_model = Block::decode_fragment(&block_bytes[..])
|
||||||
|
.expect(&format!("error decoding cbor for file {}", block_idx));
|
||||||
|
|
||||||
|
let computed_hash = super::hash_block_header(&block_model);
|
||||||
|
|
||||||
|
assert_eq!(hex::encode(computed_hash), KNOWN_HASH)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -4,4 +4,4 @@ mod model;
|
||||||
|
|
||||||
pub use model::*;
|
pub use model::*;
|
||||||
|
|
||||||
// pub mod crypto;
|
pub mod crypto;
|
||||||
|
|
|
||||||
|
|
@ -29,10 +29,10 @@ pub type EpochId = u64;
|
||||||
#[derive(Encode, Decode, Debug)]
|
#[derive(Encode, Decode, Debug)]
|
||||||
pub struct SlotId {
|
pub struct SlotId {
|
||||||
#[n(0)]
|
#[n(0)]
|
||||||
epoch: EpochId,
|
pub epoch: EpochId,
|
||||||
|
|
||||||
#[n(1)]
|
#[n(1)]
|
||||||
slot: u64,
|
pub slot: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type PubKey = ByteVec;
|
pub type PubKey = ByteVec;
|
||||||
|
|
@ -489,16 +489,16 @@ impl minicbor::Encode for SscProof {
|
||||||
#[derive(Debug, Encode, Decode)]
|
#[derive(Debug, Encode, Decode)]
|
||||||
pub struct Dlg {
|
pub struct Dlg {
|
||||||
#[n(0)]
|
#[n(0)]
|
||||||
epoch: EpochId,
|
pub epoch: EpochId,
|
||||||
|
|
||||||
#[n(1)]
|
#[n(1)]
|
||||||
issuer: PubKey,
|
pub issuer: PubKey,
|
||||||
|
|
||||||
#[n(2)]
|
#[n(2)]
|
||||||
delegate: PubKey,
|
pub delegate: PubKey,
|
||||||
|
|
||||||
#[n(3)]
|
#[n(3)]
|
||||||
certificate: Signature,
|
pub certificate: Signature,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type DlgSig = (Dlg, Signature);
|
pub type DlgSig = (Dlg, Signature);
|
||||||
|
|
@ -506,16 +506,16 @@ pub type DlgSig = (Dlg, Signature);
|
||||||
#[derive(Debug, Encode, Decode)]
|
#[derive(Debug, Encode, Decode)]
|
||||||
pub struct Lwdlg {
|
pub struct Lwdlg {
|
||||||
#[n(0)]
|
#[n(0)]
|
||||||
epoch_range: (EpochId, EpochId),
|
pub epoch_range: (EpochId, EpochId),
|
||||||
|
|
||||||
#[n(1)]
|
#[n(1)]
|
||||||
issuer: PubKey,
|
pub issuer: PubKey,
|
||||||
|
|
||||||
#[n(2)]
|
#[n(2)]
|
||||||
delegate: PubKey,
|
pub delegate: PubKey,
|
||||||
|
|
||||||
#[n(3)]
|
#[n(3)]
|
||||||
certificate: Signature,
|
pub certificate: Signature,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type LwdlgSig = (Lwdlg, Signature);
|
pub type LwdlgSig = (Lwdlg, Signature);
|
||||||
|
|
@ -573,46 +573,46 @@ impl minicbor::Encode for TxFeePol {
|
||||||
#[derive(Debug, Encode, Decode)]
|
#[derive(Debug, Encode, Decode)]
|
||||||
pub struct BVerMod {
|
pub struct BVerMod {
|
||||||
#[n(0)]
|
#[n(0)]
|
||||||
script_version: (Option<u16>,),
|
pub script_version: (Option<u16>,),
|
||||||
|
|
||||||
#[n(1)]
|
#[n(1)]
|
||||||
slot_duration: (Option<u64>,),
|
pub slot_duration: (Option<u64>,),
|
||||||
|
|
||||||
#[n(2)]
|
#[n(2)]
|
||||||
max_block_size: (Option<u64>,),
|
pub max_block_size: (Option<u64>,),
|
||||||
|
|
||||||
#[n(3)]
|
#[n(3)]
|
||||||
max_header_size: (Option<u64>,),
|
pub max_header_size: (Option<u64>,),
|
||||||
|
|
||||||
#[n(4)]
|
#[n(4)]
|
||||||
max_tx_size: (Option<u64>,),
|
pub max_tx_size: (Option<u64>,),
|
||||||
|
|
||||||
#[n(5)]
|
#[n(5)]
|
||||||
max_proposal_size: (Option<u64>,),
|
pub max_proposal_size: (Option<u64>,),
|
||||||
|
|
||||||
#[n(6)]
|
#[n(6)]
|
||||||
mpc_thd: (Option<u64>,),
|
pub mpc_thd: (Option<u64>,),
|
||||||
|
|
||||||
#[n(7)]
|
#[n(7)]
|
||||||
heavy_del_thd: (Option<u64>,),
|
pub heavy_del_thd: (Option<u64>,),
|
||||||
|
|
||||||
#[n(8)]
|
#[n(8)]
|
||||||
update_vote_thd: (Option<u64>,),
|
pub update_vote_thd: (Option<u64>,),
|
||||||
|
|
||||||
#[n(9)]
|
#[n(9)]
|
||||||
update_proposal_thd: (Option<u64>,),
|
pub update_proposal_thd: (Option<u64>,),
|
||||||
|
|
||||||
#[n(10)]
|
#[n(10)]
|
||||||
update_implicit: (Option<u64>,),
|
pub update_implicit: (Option<u64>,),
|
||||||
|
|
||||||
#[n(11)]
|
#[n(11)]
|
||||||
soft_fork_rule: (Option<(u64, u64, u64)>,),
|
pub soft_fork_rule: (Option<(u64, u64, u64)>,),
|
||||||
|
|
||||||
#[n(12)]
|
#[n(12)]
|
||||||
tx_fee_policy: (Option<TxFeePol>,),
|
pub tx_fee_policy: (Option<TxFeePol>,),
|
||||||
|
|
||||||
#[n(13)]
|
#[n(13)]
|
||||||
unlock_stake_epoch: (Option<EpochId>,),
|
pub unlock_stake_epoch: (Option<EpochId>,),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type UpData = (ByronHash, ByronHash, ByronHash, ByronHash);
|
pub type UpData = (ByronHash, ByronHash, ByronHash, ByronHash);
|
||||||
|
|
@ -620,49 +620,49 @@ pub type UpData = (ByronHash, ByronHash, ByronHash, ByronHash);
|
||||||
#[derive(Debug, Encode, Decode)]
|
#[derive(Debug, Encode, Decode)]
|
||||||
pub struct UpProp {
|
pub struct UpProp {
|
||||||
#[n(0)]
|
#[n(0)]
|
||||||
block_version: Option<BVer>,
|
pub block_version: Option<BVer>,
|
||||||
|
|
||||||
#[n(1)]
|
#[n(1)]
|
||||||
block_version_mod: Option<BVerMod>,
|
pub block_version_mod: Option<BVerMod>,
|
||||||
|
|
||||||
#[n(2)]
|
#[n(2)]
|
||||||
software_version: Option<(String, u32)>,
|
pub software_version: Option<(String, u32)>,
|
||||||
|
|
||||||
#[n(3)]
|
#[n(3)]
|
||||||
data: Option<TagWrap<(String, UpData), 258>>,
|
pub data: Option<TagWrap<(String, UpData), 258>>,
|
||||||
|
|
||||||
#[n(4)]
|
#[n(4)]
|
||||||
attributes: Option<Attributes>,
|
pub attributes: Option<Attributes>,
|
||||||
|
|
||||||
#[n(5)]
|
#[n(5)]
|
||||||
from: Option<PubKey>,
|
pub from: Option<PubKey>,
|
||||||
|
|
||||||
#[n(6)]
|
#[n(6)]
|
||||||
signature: Option<Signature>,
|
pub signature: Option<Signature>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Encode, Decode)]
|
#[derive(Debug, Encode, Decode)]
|
||||||
pub struct UpVote {
|
pub struct UpVote {
|
||||||
#[n(0)]
|
#[n(0)]
|
||||||
voter: PubKey,
|
pub voter: PubKey,
|
||||||
|
|
||||||
#[n(1)]
|
#[n(1)]
|
||||||
proposal_id: UpdId,
|
pub proposal_id: UpdId,
|
||||||
|
|
||||||
#[n(2)]
|
#[n(2)]
|
||||||
vote: bool,
|
pub vote: bool,
|
||||||
|
|
||||||
#[n(3)]
|
#[n(3)]
|
||||||
signature: Signature,
|
pub signature: Signature,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Encode, Decode)]
|
#[derive(Debug, Encode, Decode)]
|
||||||
pub struct Up {
|
pub struct Up {
|
||||||
#[n(0)]
|
#[n(0)]
|
||||||
proposal: Option<UpProp>,
|
pub proposal: Option<UpProp>,
|
||||||
|
|
||||||
#[n(1)]
|
#[n(1)]
|
||||||
votes: MaybeIndefArray<UpVote>,
|
pub votes: MaybeIndefArray<UpVote>,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Blocks
|
// Blocks
|
||||||
|
|
@ -726,58 +726,58 @@ impl minicbor::Encode for BlockSig {
|
||||||
|
|
||||||
#[derive(Encode, Decode, Debug)]
|
#[derive(Encode, Decode, Debug)]
|
||||||
pub struct BlockCons(
|
pub struct BlockCons(
|
||||||
#[n(0)] SlotId,
|
#[n(0)] pub SlotId,
|
||||||
#[n(1)] PubKey,
|
#[n(1)] pub PubKey,
|
||||||
#[n(2)] Difficulty,
|
#[n(2)] pub Difficulty,
|
||||||
#[n(3)] BlockSig,
|
#[n(3)] pub BlockSig,
|
||||||
);
|
);
|
||||||
|
|
||||||
#[derive(Encode, Decode, Debug)]
|
#[derive(Encode, Decode, Debug)]
|
||||||
pub struct BlockHeadEx {
|
pub struct BlockHeadEx {
|
||||||
#[n(0)]
|
#[n(0)]
|
||||||
block_version: BVer,
|
pub block_version: BVer,
|
||||||
|
|
||||||
#[n(1)]
|
#[n(1)]
|
||||||
software_version: (String, u32),
|
pub software_version: (String, u32),
|
||||||
|
|
||||||
#[n(2)]
|
#[n(2)]
|
||||||
attributes: Option<Attributes>,
|
pub attributes: Option<Attributes>,
|
||||||
|
|
||||||
#[n(3)]
|
#[n(3)]
|
||||||
extra_proof: ByronHash,
|
pub extra_proof: ByronHash,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Encode, Decode, Debug)]
|
#[derive(Encode, Decode, Debug)]
|
||||||
pub struct BlockProof {
|
pub struct BlockProof {
|
||||||
#[n(0)]
|
#[n(0)]
|
||||||
tx_proof: TxProof,
|
pub tx_proof: TxProof,
|
||||||
|
|
||||||
#[n(1)]
|
#[n(1)]
|
||||||
ssc_proof: SscProof,
|
pub ssc_proof: SscProof,
|
||||||
|
|
||||||
#[n(2)]
|
#[n(2)]
|
||||||
dlg_proof: ByronHash,
|
pub dlg_proof: ByronHash,
|
||||||
|
|
||||||
#[n(3)]
|
#[n(3)]
|
||||||
upd_proof: ByronHash,
|
pub upd_proof: ByronHash,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Encode, Decode, Debug)]
|
#[derive(Encode, Decode, Debug)]
|
||||||
pub struct BlockHead {
|
pub struct BlockHead {
|
||||||
#[n(0)]
|
#[n(0)]
|
||||||
protocol_magic: u32,
|
pub protocol_magic: u32,
|
||||||
|
|
||||||
#[n(1)]
|
#[n(1)]
|
||||||
prev_block: BlockId,
|
pub prev_block: BlockId,
|
||||||
|
|
||||||
#[n(2)]
|
#[n(2)]
|
||||||
body_proof: BlockProof,
|
pub body_proof: BlockProof,
|
||||||
|
|
||||||
#[n(3)]
|
#[n(3)]
|
||||||
consensus_data: BlockCons,
|
pub consensus_data: BlockCons,
|
||||||
|
|
||||||
#[n(4)]
|
#[n(4)]
|
||||||
extra_data: BlockHeadEx,
|
pub extra_data: BlockHeadEx,
|
||||||
}
|
}
|
||||||
|
|
||||||
// [tx, [* twit]]
|
// [tx, [* twit]]
|
||||||
|
|
@ -786,16 +786,16 @@ pub type TxPayload = (Tx, Vec<Twit>);
|
||||||
#[derive(Encode, Decode, Debug)]
|
#[derive(Encode, Decode, Debug)]
|
||||||
pub struct BlockBody {
|
pub struct BlockBody {
|
||||||
#[n(0)]
|
#[n(0)]
|
||||||
tx_payload: MaybeIndefArray<TxPayload>,
|
pub tx_payload: MaybeIndefArray<TxPayload>,
|
||||||
|
|
||||||
#[n(1)]
|
#[n(1)]
|
||||||
ssc_payload: Ssc,
|
pub ssc_payload: Ssc,
|
||||||
|
|
||||||
#[n(2)]
|
#[n(2)]
|
||||||
dlg_payload: MaybeIndefArray<Dlg>,
|
pub dlg_payload: MaybeIndefArray<Dlg>,
|
||||||
|
|
||||||
#[n(3)]
|
#[n(3)]
|
||||||
upd_payload: Up,
|
pub upd_payload: Up,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Epoch Boundary Blocks
|
// Epoch Boundary Blocks
|
||||||
|
|
@ -803,52 +803,52 @@ pub struct BlockBody {
|
||||||
#[derive(Encode, Decode, Debug)]
|
#[derive(Encode, Decode, Debug)]
|
||||||
pub struct EbbCons {
|
pub struct EbbCons {
|
||||||
#[n(0)]
|
#[n(0)]
|
||||||
epoch_id: EpochId,
|
pub epoch_id: EpochId,
|
||||||
|
|
||||||
#[n(1)]
|
#[n(1)]
|
||||||
difficulty: Difficulty,
|
pub difficulty: Difficulty,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Encode, Decode, Debug)]
|
#[derive(Encode, Decode, Debug)]
|
||||||
pub struct EbbHead {
|
pub struct EbbHead {
|
||||||
#[n(0)]
|
#[n(0)]
|
||||||
protocol_magic: u32,
|
pub protocol_magic: u32,
|
||||||
|
|
||||||
#[n(1)]
|
#[n(1)]
|
||||||
prev_block: BlockId,
|
pub prev_block: BlockId,
|
||||||
|
|
||||||
#[n(2)]
|
#[n(2)]
|
||||||
body_proof: ByronHash,
|
pub body_proof: ByronHash,
|
||||||
|
|
||||||
#[n(3)]
|
#[n(3)]
|
||||||
consensus_data: EbbCons,
|
pub consensus_data: EbbCons,
|
||||||
|
|
||||||
#[n(4)]
|
#[n(4)]
|
||||||
extra_data: (Attributes,),
|
pub extra_data: (Attributes,),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Encode, Decode, Debug)]
|
#[derive(Encode, Decode, Debug)]
|
||||||
pub struct MainBlock {
|
pub struct MainBlock {
|
||||||
#[n(0)]
|
#[n(0)]
|
||||||
header: BlockHead,
|
pub header: BlockHead,
|
||||||
|
|
||||||
#[n(1)]
|
#[n(1)]
|
||||||
body: BlockBody,
|
pub body: BlockBody,
|
||||||
|
|
||||||
#[n(2)]
|
#[n(2)]
|
||||||
extra: MaybeIndefArray<Attributes>,
|
pub extra: MaybeIndefArray<Attributes>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Encode, Decode, Debug)]
|
#[derive(Encode, Decode, Debug)]
|
||||||
pub struct EbBlock {
|
pub struct EbBlock {
|
||||||
#[n(0)]
|
#[n(0)]
|
||||||
header: EbbHead,
|
pub header: EbbHead,
|
||||||
|
|
||||||
#[n(1)]
|
#[n(1)]
|
||||||
body: MaybeIndefArray<StakeholderId>,
|
pub body: MaybeIndefArray<StakeholderId>,
|
||||||
|
|
||||||
#[n(2)]
|
#[n(2)]
|
||||||
extra: Option<Attributes>,
|
pub extra: Option<Attributes>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::large_enum_variant)]
|
#[allow(clippy::large_enum_variant)]
|
||||||
|
|
@ -900,7 +900,7 @@ impl minicbor::Encode for Block {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::byron::Block;
|
use crate::byron::{Block, BlockHead};
|
||||||
use crate::Fragment;
|
use crate::Fragment;
|
||||||
|
|
||||||
use minicbor::{self, to_vec};
|
use minicbor::{self, to_vec};
|
||||||
|
|
@ -928,4 +928,24 @@ mod tests {
|
||||||
// assert_eq!(bytes, bytes2);
|
// assert_eq!(bytes, bytes2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn header_isomorphic_decoding_encoding() {
|
||||||
|
let subjects = vec![include_str!("test_data/test1.header")];
|
||||||
|
|
||||||
|
for (idx, str) in subjects.iter().enumerate() {
|
||||||
|
println!("decoding test header {}", idx + 1);
|
||||||
|
let bytes = hex::decode(str).expect(&format!("bad header file {}", idx));
|
||||||
|
|
||||||
|
let block = BlockHead::decode_fragment(&bytes[..])
|
||||||
|
.expect(&format!("error decoding cbor for file {}", idx));
|
||||||
|
|
||||||
|
println!("{:?}", block);
|
||||||
|
|
||||||
|
let bytes2 =
|
||||||
|
to_vec(block).expect(&format!("error encoding header cbor for file {}", idx));
|
||||||
|
|
||||||
|
assert_eq!(bytes, bytes2);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
1
pallas-primitives/src/byron/test_data/test1.header
Normal file
1
pallas-primitives/src/byron/test_data/test1.header
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
851A2D964A0958205C196E7394ACE0449BA5A51C919369699B13896E97432894B4F0354DCE8670B68483015820D09F2306C1CD4756C1A7FF3ADB5DC8D7CADEDF882DBCC06E098C381078449A495820080A7075FDD79C20F6DA7AEEAA8A9765A0F83175851F3BB1AF583BD99F84358B82035820D36A2619A672494604E11BB447CBCF5231E9F2BA25C2169177EDC941BD50AD6C5820AFC0DA64183BF2664F3D4EEC7238D524BA607FAEEAB24FC100EB861DBA69971B58204E66280CD94D591072349BEC0A3090A53AA945562EFB6D08D56E53654B0E4098848218CF19545B58401BC97A2FE02C297880CE8ECFD997FE4C1EC09EE10FEEEE9F686760166B05281D6283468FFD93BECB0C956CCDDD642DF9B1244C915911185FA49355F6F22BFAB9811A0044850A820282840058401BC97A2FE02C297880CE8ECFD997FE4C1EC09EE10FEEEE9F686760166B05281D6283468FFD93BECB0C956CCDDD642DF9B1244C915911185FA49355F6F22BFAB9584061261A95B7613EE6BF2067DAD77B70349729B0C50D57BC1CF30DE0DB4A1E73A885D0054AF7C23FC6C37919DBA41C602A57E2D0F9329A7954B867338D6FB2C9455840E03E62F083DF5576360E60A32E22BBB07B3C8DF4FCAB8079F1D6F61AF3954D242BA8A06516C395939F24096F3DF14E103A7D9C2B80A68A9363CF1F27C7A4E30758409F9CBAA9AE2751FC9D97E7DAE0CEF3E2C6D740627818B735E39EADF92F83A04DC36D42C42D258450F13C0BA3E1470EDE42A1F0D239A99EA284BCAA031A514A098483020000826A63617264616E6F2D736C01A058204BA92AA320C60ACC9AD7B9A64F2EDA55C4D2EC28E604FAF186708B4F0C4E8EDF
|
||||||
Loading…
Add table
Add a link
Reference in a new issue