feat: Add Byron header hashing (#45)
This commit is contained in:
parent
230cc28c31
commit
6abf87eec3
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 mod crypto;
|
||||
pub mod crypto;
|
||||
|
|
|
|||
|
|
@ -29,10 +29,10 @@ pub type EpochId = u64;
|
|||
#[derive(Encode, Decode, Debug)]
|
||||
pub struct SlotId {
|
||||
#[n(0)]
|
||||
epoch: EpochId,
|
||||
pub epoch: EpochId,
|
||||
|
||||
#[n(1)]
|
||||
slot: u64,
|
||||
pub slot: u64,
|
||||
}
|
||||
|
||||
pub type PubKey = ByteVec;
|
||||
|
|
@ -489,16 +489,16 @@ impl minicbor::Encode for SscProof {
|
|||
#[derive(Debug, Encode, Decode)]
|
||||
pub struct Dlg {
|
||||
#[n(0)]
|
||||
epoch: EpochId,
|
||||
pub epoch: EpochId,
|
||||
|
||||
#[n(1)]
|
||||
issuer: PubKey,
|
||||
pub issuer: PubKey,
|
||||
|
||||
#[n(2)]
|
||||
delegate: PubKey,
|
||||
pub delegate: PubKey,
|
||||
|
||||
#[n(3)]
|
||||
certificate: Signature,
|
||||
pub certificate: Signature,
|
||||
}
|
||||
|
||||
pub type DlgSig = (Dlg, Signature);
|
||||
|
|
@ -506,16 +506,16 @@ pub type DlgSig = (Dlg, Signature);
|
|||
#[derive(Debug, Encode, Decode)]
|
||||
pub struct Lwdlg {
|
||||
#[n(0)]
|
||||
epoch_range: (EpochId, EpochId),
|
||||
pub epoch_range: (EpochId, EpochId),
|
||||
|
||||
#[n(1)]
|
||||
issuer: PubKey,
|
||||
pub issuer: PubKey,
|
||||
|
||||
#[n(2)]
|
||||
delegate: PubKey,
|
||||
pub delegate: PubKey,
|
||||
|
||||
#[n(3)]
|
||||
certificate: Signature,
|
||||
pub certificate: Signature,
|
||||
}
|
||||
|
||||
pub type LwdlgSig = (Lwdlg, Signature);
|
||||
|
|
@ -573,46 +573,46 @@ impl minicbor::Encode for TxFeePol {
|
|||
#[derive(Debug, Encode, Decode)]
|
||||
pub struct BVerMod {
|
||||
#[n(0)]
|
||||
script_version: (Option<u16>,),
|
||||
pub script_version: (Option<u16>,),
|
||||
|
||||
#[n(1)]
|
||||
slot_duration: (Option<u64>,),
|
||||
pub slot_duration: (Option<u64>,),
|
||||
|
||||
#[n(2)]
|
||||
max_block_size: (Option<u64>,),
|
||||
pub max_block_size: (Option<u64>,),
|
||||
|
||||
#[n(3)]
|
||||
max_header_size: (Option<u64>,),
|
||||
pub max_header_size: (Option<u64>,),
|
||||
|
||||
#[n(4)]
|
||||
max_tx_size: (Option<u64>,),
|
||||
pub max_tx_size: (Option<u64>,),
|
||||
|
||||
#[n(5)]
|
||||
max_proposal_size: (Option<u64>,),
|
||||
pub max_proposal_size: (Option<u64>,),
|
||||
|
||||
#[n(6)]
|
||||
mpc_thd: (Option<u64>,),
|
||||
pub mpc_thd: (Option<u64>,),
|
||||
|
||||
#[n(7)]
|
||||
heavy_del_thd: (Option<u64>,),
|
||||
pub heavy_del_thd: (Option<u64>,),
|
||||
|
||||
#[n(8)]
|
||||
update_vote_thd: (Option<u64>,),
|
||||
pub update_vote_thd: (Option<u64>,),
|
||||
|
||||
#[n(9)]
|
||||
update_proposal_thd: (Option<u64>,),
|
||||
pub update_proposal_thd: (Option<u64>,),
|
||||
|
||||
#[n(10)]
|
||||
update_implicit: (Option<u64>,),
|
||||
pub update_implicit: (Option<u64>,),
|
||||
|
||||
#[n(11)]
|
||||
soft_fork_rule: (Option<(u64, u64, u64)>,),
|
||||
pub soft_fork_rule: (Option<(u64, u64, u64)>,),
|
||||
|
||||
#[n(12)]
|
||||
tx_fee_policy: (Option<TxFeePol>,),
|
||||
pub tx_fee_policy: (Option<TxFeePol>,),
|
||||
|
||||
#[n(13)]
|
||||
unlock_stake_epoch: (Option<EpochId>,),
|
||||
pub unlock_stake_epoch: (Option<EpochId>,),
|
||||
}
|
||||
|
||||
pub type UpData = (ByronHash, ByronHash, ByronHash, ByronHash);
|
||||
|
|
@ -620,49 +620,49 @@ pub type UpData = (ByronHash, ByronHash, ByronHash, ByronHash);
|
|||
#[derive(Debug, Encode, Decode)]
|
||||
pub struct UpProp {
|
||||
#[n(0)]
|
||||
block_version: Option<BVer>,
|
||||
pub block_version: Option<BVer>,
|
||||
|
||||
#[n(1)]
|
||||
block_version_mod: Option<BVerMod>,
|
||||
pub block_version_mod: Option<BVerMod>,
|
||||
|
||||
#[n(2)]
|
||||
software_version: Option<(String, u32)>,
|
||||
pub software_version: Option<(String, u32)>,
|
||||
|
||||
#[n(3)]
|
||||
data: Option<TagWrap<(String, UpData), 258>>,
|
||||
pub data: Option<TagWrap<(String, UpData), 258>>,
|
||||
|
||||
#[n(4)]
|
||||
attributes: Option<Attributes>,
|
||||
pub attributes: Option<Attributes>,
|
||||
|
||||
#[n(5)]
|
||||
from: Option<PubKey>,
|
||||
pub from: Option<PubKey>,
|
||||
|
||||
#[n(6)]
|
||||
signature: Option<Signature>,
|
||||
pub signature: Option<Signature>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Encode, Decode)]
|
||||
pub struct UpVote {
|
||||
#[n(0)]
|
||||
voter: PubKey,
|
||||
pub voter: PubKey,
|
||||
|
||||
#[n(1)]
|
||||
proposal_id: UpdId,
|
||||
pub proposal_id: UpdId,
|
||||
|
||||
#[n(2)]
|
||||
vote: bool,
|
||||
pub vote: bool,
|
||||
|
||||
#[n(3)]
|
||||
signature: Signature,
|
||||
pub signature: Signature,
|
||||
}
|
||||
|
||||
#[derive(Debug, Encode, Decode)]
|
||||
pub struct Up {
|
||||
#[n(0)]
|
||||
proposal: Option<UpProp>,
|
||||
pub proposal: Option<UpProp>,
|
||||
|
||||
#[n(1)]
|
||||
votes: MaybeIndefArray<UpVote>,
|
||||
pub votes: MaybeIndefArray<UpVote>,
|
||||
}
|
||||
|
||||
// Blocks
|
||||
|
|
@ -726,58 +726,58 @@ impl minicbor::Encode for BlockSig {
|
|||
|
||||
#[derive(Encode, Decode, Debug)]
|
||||
pub struct BlockCons(
|
||||
#[n(0)] SlotId,
|
||||
#[n(1)] PubKey,
|
||||
#[n(2)] Difficulty,
|
||||
#[n(3)] BlockSig,
|
||||
#[n(0)] pub SlotId,
|
||||
#[n(1)] pub PubKey,
|
||||
#[n(2)] pub Difficulty,
|
||||
#[n(3)] pub BlockSig,
|
||||
);
|
||||
|
||||
#[derive(Encode, Decode, Debug)]
|
||||
pub struct BlockHeadEx {
|
||||
#[n(0)]
|
||||
block_version: BVer,
|
||||
pub block_version: BVer,
|
||||
|
||||
#[n(1)]
|
||||
software_version: (String, u32),
|
||||
pub software_version: (String, u32),
|
||||
|
||||
#[n(2)]
|
||||
attributes: Option<Attributes>,
|
||||
pub attributes: Option<Attributes>,
|
||||
|
||||
#[n(3)]
|
||||
extra_proof: ByronHash,
|
||||
pub extra_proof: ByronHash,
|
||||
}
|
||||
|
||||
#[derive(Encode, Decode, Debug)]
|
||||
pub struct BlockProof {
|
||||
#[n(0)]
|
||||
tx_proof: TxProof,
|
||||
pub tx_proof: TxProof,
|
||||
|
||||
#[n(1)]
|
||||
ssc_proof: SscProof,
|
||||
pub ssc_proof: SscProof,
|
||||
|
||||
#[n(2)]
|
||||
dlg_proof: ByronHash,
|
||||
pub dlg_proof: ByronHash,
|
||||
|
||||
#[n(3)]
|
||||
upd_proof: ByronHash,
|
||||
pub upd_proof: ByronHash,
|
||||
}
|
||||
|
||||
#[derive(Encode, Decode, Debug)]
|
||||
pub struct BlockHead {
|
||||
#[n(0)]
|
||||
protocol_magic: u32,
|
||||
pub protocol_magic: u32,
|
||||
|
||||
#[n(1)]
|
||||
prev_block: BlockId,
|
||||
pub prev_block: BlockId,
|
||||
|
||||
#[n(2)]
|
||||
body_proof: BlockProof,
|
||||
pub body_proof: BlockProof,
|
||||
|
||||
#[n(3)]
|
||||
consensus_data: BlockCons,
|
||||
pub consensus_data: BlockCons,
|
||||
|
||||
#[n(4)]
|
||||
extra_data: BlockHeadEx,
|
||||
pub extra_data: BlockHeadEx,
|
||||
}
|
||||
|
||||
// [tx, [* twit]]
|
||||
|
|
@ -786,16 +786,16 @@ pub type TxPayload = (Tx, Vec<Twit>);
|
|||
#[derive(Encode, Decode, Debug)]
|
||||
pub struct BlockBody {
|
||||
#[n(0)]
|
||||
tx_payload: MaybeIndefArray<TxPayload>,
|
||||
pub tx_payload: MaybeIndefArray<TxPayload>,
|
||||
|
||||
#[n(1)]
|
||||
ssc_payload: Ssc,
|
||||
pub ssc_payload: Ssc,
|
||||
|
||||
#[n(2)]
|
||||
dlg_payload: MaybeIndefArray<Dlg>,
|
||||
pub dlg_payload: MaybeIndefArray<Dlg>,
|
||||
|
||||
#[n(3)]
|
||||
upd_payload: Up,
|
||||
pub upd_payload: Up,
|
||||
}
|
||||
|
||||
// Epoch Boundary Blocks
|
||||
|
|
@ -803,52 +803,52 @@ pub struct BlockBody {
|
|||
#[derive(Encode, Decode, Debug)]
|
||||
pub struct EbbCons {
|
||||
#[n(0)]
|
||||
epoch_id: EpochId,
|
||||
pub epoch_id: EpochId,
|
||||
|
||||
#[n(1)]
|
||||
difficulty: Difficulty,
|
||||
pub difficulty: Difficulty,
|
||||
}
|
||||
|
||||
#[derive(Encode, Decode, Debug)]
|
||||
pub struct EbbHead {
|
||||
#[n(0)]
|
||||
protocol_magic: u32,
|
||||
pub protocol_magic: u32,
|
||||
|
||||
#[n(1)]
|
||||
prev_block: BlockId,
|
||||
pub prev_block: BlockId,
|
||||
|
||||
#[n(2)]
|
||||
body_proof: ByronHash,
|
||||
pub body_proof: ByronHash,
|
||||
|
||||
#[n(3)]
|
||||
consensus_data: EbbCons,
|
||||
pub consensus_data: EbbCons,
|
||||
|
||||
#[n(4)]
|
||||
extra_data: (Attributes,),
|
||||
pub extra_data: (Attributes,),
|
||||
}
|
||||
|
||||
#[derive(Encode, Decode, Debug)]
|
||||
pub struct MainBlock {
|
||||
#[n(0)]
|
||||
header: BlockHead,
|
||||
pub header: BlockHead,
|
||||
|
||||
#[n(1)]
|
||||
body: BlockBody,
|
||||
pub body: BlockBody,
|
||||
|
||||
#[n(2)]
|
||||
extra: MaybeIndefArray<Attributes>,
|
||||
pub extra: MaybeIndefArray<Attributes>,
|
||||
}
|
||||
|
||||
#[derive(Encode, Decode, Debug)]
|
||||
pub struct EbBlock {
|
||||
#[n(0)]
|
||||
header: EbbHead,
|
||||
pub header: EbbHead,
|
||||
|
||||
#[n(1)]
|
||||
body: MaybeIndefArray<StakeholderId>,
|
||||
pub body: MaybeIndefArray<StakeholderId>,
|
||||
|
||||
#[n(2)]
|
||||
extra: Option<Attributes>,
|
||||
pub extra: Option<Attributes>,
|
||||
}
|
||||
|
||||
#[allow(clippy::large_enum_variant)]
|
||||
|
|
@ -900,7 +900,7 @@ impl minicbor::Encode for Block {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::byron::Block;
|
||||
use crate::byron::{Block, BlockHead};
|
||||
use crate::Fragment;
|
||||
|
||||
use minicbor::{self, to_vec};
|
||||
|
|
@ -928,4 +928,24 @@ mod tests {
|
|||
// 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