chore: Move hash logic out of primitives (#172)
This commit is contained in:
parent
bfc46a7ccb
commit
d72f9e42de
12 changed files with 292 additions and 327 deletions
|
|
@ -1,163 +0,0 @@
|
|||
use crate::ToHash;
|
||||
|
||||
use super::{AuxiliaryData, Header, NativeScript, PlutusData, PlutusScript, TransactionBody};
|
||||
use pallas_codec::utils::KeepRaw;
|
||||
use pallas_crypto::hash::{Hash, Hasher};
|
||||
|
||||
impl ToHash<32> for Header {
|
||||
fn to_hash(&self) -> pallas_crypto::hash::Hash<32> {
|
||||
Hasher::<256>::hash_cbor(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToHash<32> for AuxiliaryData {
|
||||
fn to_hash(&self) -> pallas_crypto::hash::Hash<32> {
|
||||
Hasher::<256>::hash_cbor(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToHash<28> for NativeScript {
|
||||
fn to_hash(&self) -> Hash<28> {
|
||||
Hasher::<224>::hash_tagged_cbor(self, 0)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToHash<28> for PlutusScript {
|
||||
fn to_hash(&self) -> Hash<28> {
|
||||
Hasher::<224>::hash_tagged_cbor(self, 1)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToHash<32> for PlutusData {
|
||||
fn to_hash(&self) -> Hash<32> {
|
||||
Hasher::<256>::hash_cbor(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToHash<32> for TransactionBody {
|
||||
fn to_hash(&self) -> Hash<32> {
|
||||
Hasher::<256>::hash_cbor(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToHash<32> for KeepRaw<'_, TransactionBody> {
|
||||
fn to_hash(&self) -> pallas_crypto::hash::Hash<32> {
|
||||
Hasher::<256>::hash(self.raw_cbor())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::str::FromStr;
|
||||
|
||||
use pallas_codec::minicbor;
|
||||
use pallas_codec::utils::Int;
|
||||
use pallas_crypto::hash::Hash;
|
||||
|
||||
use crate::alonzo::{BigInt, Constr, MintedBlock, NativeScript, PlutusData, PlutusScript};
|
||||
use crate::ToHash;
|
||||
|
||||
type BlockWrapper<'b> = (u16, MintedBlock<'b>);
|
||||
|
||||
#[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/alonzo1.block");
|
||||
|
||||
let block_bytes = hex::decode(block_str).expect(&format!("bad block file {}", block_idx));
|
||||
let (_, block_model): BlockWrapper = minicbor::decode(&block_bytes[..])
|
||||
.expect(&format!("error decoding cbor for file {}", block_idx));
|
||||
|
||||
let valid_hashes = vec![
|
||||
"8ae0cd531635579a9b52b954a840782d12235251fb1451e5c699e864c677514a",
|
||||
"bb5bb4e1c09c02aa199c60e9f330102912e3ef977bb73ecfd8f790945c6091d4",
|
||||
"8cdd88042ddb6c800714fb1469fb1a1a93152aae3c87a81f2a3016f2ee5c664a",
|
||||
"10add6bdaa7ade06466bdd768456e756709090846b58bf473f240c484db517fa",
|
||||
"8838f5ab27894a6543255aeaec086f7b3405a6db6e7457a541409cdbbf0cd474",
|
||||
];
|
||||
|
||||
for (tx_idx, tx) in block_model.transaction_bodies.iter().enumerate() {
|
||||
let computed_hash = tx.to_hash();
|
||||
let known_hash = valid_hashes[tx_idx];
|
||||
assert_eq!(hex::encode(computed_hash), known_hash)
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn native_script_hashes_as_cardano_cli() {
|
||||
// construct an arbitrary script to use as example
|
||||
let ns = NativeScript::ScriptAll(vec![
|
||||
NativeScript::ScriptPubkey(
|
||||
Hash::<28>::from_str("4d04380dcb9fbad5aff8e2f4e19394ef4e5e11b37932838f01984a12")
|
||||
.unwrap(),
|
||||
),
|
||||
NativeScript::InvalidBefore(112500819),
|
||||
]);
|
||||
|
||||
// hash that we assume correct since it was generated through the cardano-cli
|
||||
let cardano_cli_output = "d6a8ced01ecdfbb26c90850010a06fbc20a7c23632fc92f531667f36";
|
||||
|
||||
assert_eq!(
|
||||
ns.to_hash(),
|
||||
Hash::<28>::from_str(cardano_cli_output).unwrap()
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn plutus_data_hashes_as_cardano_cli() {
|
||||
// construct an arbitrary complex datum to use as example
|
||||
let pd = PlutusData::Constr(Constr::<PlutusData> {
|
||||
tag: 1280,
|
||||
any_constructor: None,
|
||||
fields: vec![
|
||||
PlutusData::BigInt(BigInt::Int(Int::from(4))),
|
||||
PlutusData::Constr(Constr::<PlutusData> {
|
||||
tag: 124,
|
||||
any_constructor: None,
|
||||
fields: vec![
|
||||
PlutusData::BigInt(BigInt::Int(Int::from(-4))),
|
||||
PlutusData::Constr(Constr::<PlutusData> {
|
||||
tag: 102,
|
||||
any_constructor: Some(453),
|
||||
fields: vec![
|
||||
PlutusData::BigInt(BigInt::Int(Int::from(2))),
|
||||
PlutusData::BigInt(BigInt::Int(Int::from(3434))),
|
||||
],
|
||||
}),
|
||||
PlutusData::BigInt(BigInt::Int(Int::from(-11828293))),
|
||||
],
|
||||
}),
|
||||
PlutusData::BigInt(BigInt::Int(Int::from(11828293))),
|
||||
],
|
||||
});
|
||||
|
||||
// if you need to try this out in the cardano-cli, uncomment this line to see
|
||||
// the json representation of the above struct:
|
||||
// println!("{}", crate::ToCanonicalJson::to_json(&pd));
|
||||
|
||||
// hash that we assume correct since it was generated through the cardano-cli
|
||||
let cardano_cli_output = "d9bc0eb6ac664286155f70d720cafd2af16277fbd9014a930997431a2ffbe554";
|
||||
|
||||
assert_eq!(
|
||||
pd.to_hash(),
|
||||
Hash::<32>::from_str(cardano_cli_output).unwrap()
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn plutus_script_hashes_as_cardano_cli() {
|
||||
let bytecode_hex = include_str!("../../../test_data/jpgstore.plutus");
|
||||
let bytecode = hex::decode(bytecode_hex).unwrap();
|
||||
let script: PlutusScript = pallas_codec::minicbor::decode(&bytecode).unwrap();
|
||||
|
||||
let generated = script.to_hash().to_string();
|
||||
|
||||
assert_eq!(
|
||||
generated,
|
||||
// this is the payment script hash from the address:
|
||||
// addr1w999n67e86jn6xal07pzxtrmqynspgx0fwmcmpua4wc6yzsxpljz3
|
||||
"4a59ebd93ea53d1bbf7f82232c7b012700a0cf4bb78d879dabb1a20a"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,5 @@
|
|||
mod model;
|
||||
|
||||
pub mod crypto;
|
||||
|
||||
#[cfg(feature = "json")]
|
||||
pub mod json;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,67 +0,0 @@
|
|||
use crate::ToHash;
|
||||
|
||||
use super::{DatumOption, Header, PlutusV2Script, TransactionBody};
|
||||
use pallas_codec::utils::KeepRaw;
|
||||
use pallas_crypto::hash::{Hash, Hasher};
|
||||
|
||||
impl ToHash<32> for Header {
|
||||
fn to_hash(&self) -> pallas_crypto::hash::Hash<32> {
|
||||
Hasher::<256>::hash_cbor(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToHash<28> for PlutusV2Script {
|
||||
fn to_hash(&self) -> Hash<28> {
|
||||
Hasher::<224>::hash_tagged_cbor(self, 1)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToHash<32> for TransactionBody {
|
||||
fn to_hash(&self) -> Hash<32> {
|
||||
Hasher::<256>::hash_cbor(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToHash<32> for KeepRaw<'_, TransactionBody> {
|
||||
fn to_hash(&self) -> pallas_crypto::hash::Hash<32> {
|
||||
Hasher::<256>::hash(self.raw_cbor())
|
||||
}
|
||||
}
|
||||
|
||||
impl ToHash<32> for DatumOption {
|
||||
fn to_hash(&self) -> Hash<32> {
|
||||
match self {
|
||||
DatumOption::Hash(hash) => *hash,
|
||||
DatumOption::Data(data) => data.to_hash(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use pallas_codec::minicbor;
|
||||
|
||||
use crate::babbage::MintedBlock;
|
||||
use crate::ToHash;
|
||||
|
||||
type BlockWrapper<'b> = (u16, MintedBlock<'b>);
|
||||
|
||||
#[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/babbage1.block");
|
||||
|
||||
let block_bytes = hex::decode(block_str).expect(&format!("bad block file {}", block_idx));
|
||||
let (_, block_model): BlockWrapper = minicbor::decode(&block_bytes[..])
|
||||
.expect(&format!("error decoding cbor for file {}", block_idx));
|
||||
|
||||
let valid_hashes = vec!["3fad302595665b004971a6b76909854a39a0a7ecdbff3692f37b77ae37dbe882"];
|
||||
|
||||
for (tx_idx, tx) in block_model.transaction_bodies.iter().enumerate() {
|
||||
let computed_hash = tx.to_hash();
|
||||
let known_hash = valid_hashes[tx_idx];
|
||||
assert_eq!(hex::encode(computed_hash), known_hash)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,3 @@
|
|||
mod crypto;
|
||||
mod model;
|
||||
|
||||
pub use model::*;
|
||||
|
|
|
|||
|
|
@ -1,72 +0,0 @@
|
|||
use crate::ToHash;
|
||||
|
||||
use super::{BlockHead, EbbHead, Tx};
|
||||
use pallas_codec::utils::KeepRaw;
|
||||
use pallas_crypto::hash::{Hash, Hasher};
|
||||
|
||||
impl ToHash<32> for EbbHead {
|
||||
fn to_hash(&self) -> Hash<32> {
|
||||
// hash expects to have a prefix for the type of block
|
||||
Hasher::<256>::hash_cbor(&(0, self))
|
||||
}
|
||||
}
|
||||
|
||||
impl ToHash<32> for KeepRaw<'_, EbbHead> {
|
||||
fn to_hash(&self) -> Hash<32> {
|
||||
// hash expects to have a prefix for the type of block
|
||||
Hasher::<256>::hash_cbor(&(0, self))
|
||||
}
|
||||
}
|
||||
|
||||
impl ToHash<32> for BlockHead {
|
||||
fn to_hash(&self) -> Hash<32> {
|
||||
// hash expects to have a prefix for the type of block
|
||||
Hasher::<256>::hash_cbor(&(1, self))
|
||||
}
|
||||
}
|
||||
|
||||
impl ToHash<32> for KeepRaw<'_, BlockHead> {
|
||||
fn to_hash(&self) -> Hash<32> {
|
||||
// hash expects to have a prefix for the type of block
|
||||
Hasher::<256>::hash_cbor(&(1, self))
|
||||
}
|
||||
}
|
||||
|
||||
impl ToHash<32> for Tx {
|
||||
fn to_hash(&self) -> Hash<32> {
|
||||
Hasher::<256>::hash_cbor(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToHash<32> for KeepRaw<'_, Tx> {
|
||||
fn to_hash(&self) -> Hash<32> {
|
||||
Hasher::<256>::hash(self.raw_cbor())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use pallas_codec::minicbor;
|
||||
|
||||
use crate::{byron::MintedBlock, ToHash};
|
||||
|
||||
type BlockWrapper<'b> = (u16, MintedBlock<'b>);
|
||||
|
||||
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/byron1.block");
|
||||
|
||||
let block_bytes = hex::decode(block_str).expect(&format!("bad block file {}", block_idx));
|
||||
let (_, block_model): BlockWrapper = minicbor::decode(&block_bytes[..])
|
||||
.expect(&format!("error decoding cbor for file {}", block_idx));
|
||||
|
||||
let computed_hash = block_model.header.to_hash();
|
||||
|
||||
assert_eq!(hex::encode(computed_hash), KNOWN_HASH)
|
||||
}
|
||||
}
|
||||
|
|
@ -48,7 +48,7 @@ impl TxPayload {
|
|||
mod tests {
|
||||
use pallas_codec::minicbor;
|
||||
|
||||
use crate::{byron::Block, ToHash};
|
||||
use crate::byron::Block;
|
||||
|
||||
type BlockWrapper = (u16, Block);
|
||||
|
||||
|
|
@ -66,7 +66,6 @@ mod tests {
|
|||
assert!(block.body.tx_payload.len() > 0);
|
||||
|
||||
for tx in block.body.tx_payload.iter().take(1) {
|
||||
println!("{}", tx.transaction.to_hash());
|
||||
let fee = tx.compute_fee_with_defaults().unwrap();
|
||||
assert_eq!(fee, 171070);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
//! Ledger primitives and cbor codec for the Byron era
|
||||
|
||||
mod crypto;
|
||||
mod fees;
|
||||
mod model;
|
||||
mod time;
|
||||
|
|
|
|||
|
|
@ -27,7 +27,3 @@ where
|
|||
pub trait ToCanonicalJson {
|
||||
fn to_json(&self) -> serde_json::Value;
|
||||
}
|
||||
|
||||
pub trait ToHash<const BYTES: usize> {
|
||||
fn to_hash(&self) -> pallas_crypto::hash::Hash<BYTES>;
|
||||
}
|
||||
|
|
|
|||
277
pallas-traverse/src/hashes.rs
Normal file
277
pallas-traverse/src/hashes.rs
Normal file
|
|
@ -0,0 +1,277 @@
|
|||
use pallas_codec::utils::KeepRaw;
|
||||
use pallas_crypto::hash::{Hash, Hasher};
|
||||
use pallas_primitives::{alonzo, babbage, byron};
|
||||
|
||||
pub(crate) trait ToHash<const BYTES: usize> {
|
||||
fn to_hash(&self) -> pallas_crypto::hash::Hash<BYTES>;
|
||||
}
|
||||
|
||||
impl ToHash<32> for byron::EbbHead {
|
||||
fn to_hash(&self) -> Hash<32> {
|
||||
// hash expects to have a prefix for the type of block
|
||||
Hasher::<256>::hash_cbor(&(0, self))
|
||||
}
|
||||
}
|
||||
|
||||
impl ToHash<32> for KeepRaw<'_, byron::EbbHead> {
|
||||
fn to_hash(&self) -> Hash<32> {
|
||||
// hash expects to have a prefix for the type of block
|
||||
Hasher::<256>::hash_cbor(&(0, self))
|
||||
}
|
||||
}
|
||||
|
||||
impl ToHash<32> for byron::BlockHead {
|
||||
fn to_hash(&self) -> Hash<32> {
|
||||
// hash expects to have a prefix for the type of block
|
||||
Hasher::<256>::hash_cbor(&(1, self))
|
||||
}
|
||||
}
|
||||
|
||||
impl ToHash<32> for KeepRaw<'_, byron::BlockHead> {
|
||||
fn to_hash(&self) -> Hash<32> {
|
||||
// hash expects to have a prefix for the type of block
|
||||
Hasher::<256>::hash_cbor(&(1, self))
|
||||
}
|
||||
}
|
||||
|
||||
impl ToHash<32> for byron::Tx {
|
||||
fn to_hash(&self) -> Hash<32> {
|
||||
Hasher::<256>::hash_cbor(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToHash<32> for KeepRaw<'_, byron::Tx> {
|
||||
fn to_hash(&self) -> Hash<32> {
|
||||
Hasher::<256>::hash(self.raw_cbor())
|
||||
}
|
||||
}
|
||||
|
||||
impl ToHash<32> for alonzo::Header {
|
||||
fn to_hash(&self) -> pallas_crypto::hash::Hash<32> {
|
||||
Hasher::<256>::hash_cbor(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToHash<32> for alonzo::AuxiliaryData {
|
||||
fn to_hash(&self) -> pallas_crypto::hash::Hash<32> {
|
||||
Hasher::<256>::hash_cbor(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToHash<28> for alonzo::NativeScript {
|
||||
fn to_hash(&self) -> Hash<28> {
|
||||
Hasher::<224>::hash_tagged_cbor(self, 0)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToHash<28> for alonzo::PlutusScript {
|
||||
fn to_hash(&self) -> Hash<28> {
|
||||
Hasher::<224>::hash_tagged_cbor(self, 1)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToHash<32> for alonzo::PlutusData {
|
||||
fn to_hash(&self) -> Hash<32> {
|
||||
Hasher::<256>::hash_cbor(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToHash<32> for alonzo::TransactionBody {
|
||||
fn to_hash(&self) -> Hash<32> {
|
||||
Hasher::<256>::hash_cbor(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToHash<32> for KeepRaw<'_, alonzo::TransactionBody> {
|
||||
fn to_hash(&self) -> pallas_crypto::hash::Hash<32> {
|
||||
Hasher::<256>::hash(self.raw_cbor())
|
||||
}
|
||||
}
|
||||
|
||||
impl ToHash<32> for babbage::Header {
|
||||
fn to_hash(&self) -> pallas_crypto::hash::Hash<32> {
|
||||
Hasher::<256>::hash_cbor(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToHash<28> for babbage::PlutusV2Script {
|
||||
fn to_hash(&self) -> Hash<28> {
|
||||
Hasher::<224>::hash_tagged_cbor(self, 1)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToHash<32> for babbage::TransactionBody {
|
||||
fn to_hash(&self) -> Hash<32> {
|
||||
Hasher::<256>::hash_cbor(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToHash<32> for KeepRaw<'_, babbage::TransactionBody> {
|
||||
fn to_hash(&self) -> pallas_crypto::hash::Hash<32> {
|
||||
Hasher::<256>::hash(self.raw_cbor())
|
||||
}
|
||||
}
|
||||
|
||||
impl ToHash<32> for babbage::DatumOption {
|
||||
fn to_hash(&self) -> Hash<32> {
|
||||
match self {
|
||||
babbage::DatumOption::Hash(hash) => *hash,
|
||||
babbage::DatumOption::Data(data) => data.to_hash(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::ToHash;
|
||||
use pallas_codec::minicbor;
|
||||
use pallas_codec::utils::Int;
|
||||
use pallas_crypto::hash::Hash;
|
||||
use pallas_primitives::{alonzo, babbage, byron};
|
||||
use std::str::FromStr;
|
||||
|
||||
const KNOWN_HASH: &'static str =
|
||||
"5c196e7394ace0449ba5a51c919369699b13896e97432894b4f0354dce8670b6";
|
||||
|
||||
#[test]
|
||||
fn byron_transaction_hash_works() {
|
||||
type BlockWrapper<'b> = (u16, byron::MintedBlock<'b>);
|
||||
|
||||
// TODO: expand this test to include more test blocks
|
||||
let block_idx = 1;
|
||||
let block_str = include_str!("../../test_data/byron1.block");
|
||||
|
||||
let block_bytes = hex::decode(block_str).expect(&format!("bad block file {}", block_idx));
|
||||
let (_, block_model): BlockWrapper = minicbor::decode(&block_bytes[..])
|
||||
.expect(&format!("error decoding cbor for file {}", block_idx));
|
||||
|
||||
let computed_hash = block_model.header.to_hash();
|
||||
|
||||
assert_eq!(hex::encode(computed_hash), KNOWN_HASH)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn alonzo_transaction_hash_works() {
|
||||
type BlockWrapper<'b> = (u16, alonzo::MintedBlock<'b>);
|
||||
|
||||
// TODO: expand this test to include more test blocks
|
||||
let block_idx = 1;
|
||||
let block_str = include_str!("../../test_data/alonzo1.block");
|
||||
|
||||
let block_bytes = hex::decode(block_str).expect(&format!("bad block file {}", block_idx));
|
||||
let (_, block_model): BlockWrapper = minicbor::decode(&block_bytes[..])
|
||||
.expect(&format!("error decoding cbor for file {}", block_idx));
|
||||
|
||||
let valid_hashes = vec![
|
||||
"8ae0cd531635579a9b52b954a840782d12235251fb1451e5c699e864c677514a",
|
||||
"bb5bb4e1c09c02aa199c60e9f330102912e3ef977bb73ecfd8f790945c6091d4",
|
||||
"8cdd88042ddb6c800714fb1469fb1a1a93152aae3c87a81f2a3016f2ee5c664a",
|
||||
"10add6bdaa7ade06466bdd768456e756709090846b58bf473f240c484db517fa",
|
||||
"8838f5ab27894a6543255aeaec086f7b3405a6db6e7457a541409cdbbf0cd474",
|
||||
];
|
||||
|
||||
for (tx_idx, tx) in block_model.transaction_bodies.iter().enumerate() {
|
||||
let computed_hash = tx.to_hash();
|
||||
let known_hash = valid_hashes[tx_idx];
|
||||
assert_eq!(hex::encode(computed_hash), known_hash)
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn babbage_transaction_hash_works() {
|
||||
type BlockWrapper<'b> = (u16, babbage::MintedBlock<'b>);
|
||||
|
||||
// TODO: expand this test to include more test blocks
|
||||
let block_idx = 1;
|
||||
let block_str = include_str!("../../test_data/babbage1.block");
|
||||
|
||||
let block_bytes = hex::decode(block_str).expect(&format!("bad block file {}", block_idx));
|
||||
let (_, block_model): BlockWrapper = minicbor::decode(&block_bytes[..])
|
||||
.expect(&format!("error decoding cbor for file {}", block_idx));
|
||||
|
||||
let valid_hashes = vec!["3fad302595665b004971a6b76909854a39a0a7ecdbff3692f37b77ae37dbe882"];
|
||||
|
||||
for (tx_idx, tx) in block_model.transaction_bodies.iter().enumerate() {
|
||||
let computed_hash = tx.to_hash();
|
||||
let known_hash = valid_hashes[tx_idx];
|
||||
assert_eq!(hex::encode(computed_hash), known_hash)
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn native_script_hashes_as_cardano_cli() {
|
||||
// construct an arbitrary script to use as example
|
||||
let ns = alonzo::NativeScript::ScriptAll(vec![
|
||||
alonzo::NativeScript::ScriptPubkey(
|
||||
Hash::<28>::from_str("4d04380dcb9fbad5aff8e2f4e19394ef4e5e11b37932838f01984a12")
|
||||
.unwrap(),
|
||||
),
|
||||
alonzo::NativeScript::InvalidBefore(112500819),
|
||||
]);
|
||||
|
||||
// hash that we assume correct since it was generated through the cardano-cli
|
||||
let cardano_cli_output = "d6a8ced01ecdfbb26c90850010a06fbc20a7c23632fc92f531667f36";
|
||||
|
||||
assert_eq!(
|
||||
ns.to_hash(),
|
||||
Hash::<28>::from_str(cardano_cli_output).unwrap()
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn plutus_data_hashes_as_cardano_cli() {
|
||||
// construct an arbitrary complex datum to use as example
|
||||
let pd = alonzo::PlutusData::Constr(alonzo::Constr::<alonzo::PlutusData> {
|
||||
tag: 1280,
|
||||
any_constructor: None,
|
||||
fields: vec![
|
||||
alonzo::PlutusData::BigInt(alonzo::BigInt::Int(Int::from(4))),
|
||||
alonzo::PlutusData::Constr(alonzo::Constr::<alonzo::PlutusData> {
|
||||
tag: 124,
|
||||
any_constructor: None,
|
||||
fields: vec![
|
||||
alonzo::PlutusData::BigInt(alonzo::BigInt::Int(Int::from(-4))),
|
||||
alonzo::PlutusData::Constr(alonzo::Constr::<alonzo::PlutusData> {
|
||||
tag: 102,
|
||||
any_constructor: Some(453),
|
||||
fields: vec![
|
||||
alonzo::PlutusData::BigInt(alonzo::BigInt::Int(Int::from(2))),
|
||||
alonzo::PlutusData::BigInt(alonzo::BigInt::Int(Int::from(3434))),
|
||||
],
|
||||
}),
|
||||
alonzo::PlutusData::BigInt(alonzo::BigInt::Int(Int::from(-11828293))),
|
||||
],
|
||||
}),
|
||||
alonzo::PlutusData::BigInt(alonzo::BigInt::Int(Int::from(11828293))),
|
||||
],
|
||||
});
|
||||
|
||||
// if you need to try this out in the cardano-cli, uncomment this line to see
|
||||
// the json representation of the above struct:
|
||||
// println!("{}", crate::ToCanonicalJson::to_json(&pd));
|
||||
|
||||
// hash that we assume correct since it was generated through the cardano-cli
|
||||
let cardano_cli_output = "d9bc0eb6ac664286155f70d720cafd2af16277fbd9014a930997431a2ffbe554";
|
||||
|
||||
assert_eq!(
|
||||
pd.to_hash(),
|
||||
Hash::<32>::from_str(cardano_cli_output).unwrap()
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn plutus_script_hashes_as_cardano_cli() {
|
||||
let bytecode_hex = include_str!("../../test_data/jpgstore.plutus");
|
||||
let bytecode = hex::decode(bytecode_hex).unwrap();
|
||||
let script: alonzo::PlutusScript = pallas_codec::minicbor::decode(&bytecode).unwrap();
|
||||
|
||||
let generated = script.to_hash().to_string();
|
||||
|
||||
assert_eq!(
|
||||
generated,
|
||||
// this is the payment script hash from the address:
|
||||
// addr1w999n67e86jn6xal07pzxtrmqynspgx0fwmcmpua4wc6yzsxpljz3
|
||||
"4a59ebd93ea53d1bbf7f82232c7b012700a0cf4bb78d879dabb1a20a"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -3,10 +3,10 @@ use std::ops::Deref;
|
|||
|
||||
use pallas_codec::minicbor;
|
||||
use pallas_crypto::hash::{Hash, Hasher};
|
||||
use pallas_primitives::{alonzo, babbage, byron, ToHash};
|
||||
use pallas_primitives::{alonzo, babbage, byron};
|
||||
|
||||
use crate::Era::Byron;
|
||||
use crate::{Error, MultiEraHeader};
|
||||
use crate::hashes::ToHash;
|
||||
use crate::{Era, Error, MultiEraHeader};
|
||||
|
||||
impl<'b> MultiEraHeader<'b> {
|
||||
pub fn decode(tag: u8, subtag: Option<u8>, cbor: &'b [u8]) -> Result<Self, Error> {
|
||||
|
|
@ -75,27 +75,27 @@ impl<'b> MultiEraHeader<'b> {
|
|||
|
||||
pub fn leader_vrf_output(&self) -> Result<Vec<u8>, Error> {
|
||||
match self {
|
||||
MultiEraHeader::EpochBoundary(_) => Err(Error::InvalidEra(Byron)),
|
||||
MultiEraHeader::EpochBoundary(_) => Err(Error::InvalidEra(Era::Byron)),
|
||||
MultiEraHeader::AlonzoCompatible(x) => Ok(x.header_body.leader_vrf.0.to_vec()),
|
||||
MultiEraHeader::Babbage(x) => {
|
||||
let mut leader_tagged_vrf: Vec<u8> = vec![0x4C_u8]; /* "L" */
|
||||
leader_tagged_vrf.extend(&*x.header_body.vrf_result.0);
|
||||
Ok(Hasher::<256>::hash(&leader_tagged_vrf).to_vec())
|
||||
}
|
||||
MultiEraHeader::Byron(_) => Err(Error::InvalidEra(Byron)),
|
||||
MultiEraHeader::Byron(_) => Err(Error::InvalidEra(Era::Byron)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn nonce_vrf_output(&self) -> Result<Vec<u8>, Error> {
|
||||
match self {
|
||||
MultiEraHeader::EpochBoundary(_) => Err(Error::InvalidEra(Byron)),
|
||||
MultiEraHeader::EpochBoundary(_) => Err(Error::InvalidEra(Era::Byron)),
|
||||
MultiEraHeader::AlonzoCompatible(x) => Ok(x.header_body.nonce_vrf.0.to_vec()),
|
||||
MultiEraHeader::Babbage(x) => {
|
||||
let mut nonce_tagged_vrf: Vec<u8> = vec![0x4E_u8]; /* "N" */
|
||||
nonce_tagged_vrf.extend(&*x.header_body.vrf_result.0);
|
||||
Ok(Hasher::<256>::hash(&nonce_tagged_vrf).to_vec())
|
||||
}
|
||||
MultiEraHeader::Byron(_) => Err(Error::InvalidEra(Byron)),
|
||||
MultiEraHeader::Byron(_) => Err(Error::InvalidEra(Era::Byron)),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ use pallas_primitives::{alonzo, babbage, byron};
|
|||
pub mod block;
|
||||
pub mod cert;
|
||||
pub mod era;
|
||||
pub mod hashes;
|
||||
pub mod header;
|
||||
pub mod input;
|
||||
pub mod meta;
|
||||
|
|
|
|||
|
|
@ -1,9 +1,7 @@
|
|||
use crate::hashes::ToHash;
|
||||
use pallas_codec::{minicbor, utils::KeepRaw};
|
||||
use pallas_crypto::hash::Hash;
|
||||
use pallas_primitives::{
|
||||
alonzo::{self, AuxiliaryData},
|
||||
babbage, byron, ToHash,
|
||||
};
|
||||
use pallas_primitives::{alonzo, babbage, byron};
|
||||
use std::{borrow::Cow, ops::Deref};
|
||||
|
||||
use crate::{
|
||||
|
|
@ -234,7 +232,7 @@ impl<'b> MultiEraTx<'b> {
|
|||
}
|
||||
}
|
||||
|
||||
fn aux_data(&self) -> Option<&KeepRaw<'_, AuxiliaryData>> {
|
||||
fn aux_data(&self) -> Option<&KeepRaw<'_, alonzo::AuxiliaryData>> {
|
||||
match self {
|
||||
MultiEraTx::AlonzoCompatible(x, _) => match &x.auxiliary_data {
|
||||
pallas_codec::utils::Nullable::Some(x) => Some(x),
|
||||
|
|
@ -253,11 +251,11 @@ impl<'b> MultiEraTx<'b> {
|
|||
pub fn metadata(&self) -> MultiEraMeta {
|
||||
match self.aux_data() {
|
||||
Some(x) => match x.deref() {
|
||||
AuxiliaryData::Shelley(x) => MultiEraMeta::AlonzoCompatible(x),
|
||||
AuxiliaryData::ShelleyMa(x) => {
|
||||
alonzo::AuxiliaryData::Shelley(x) => MultiEraMeta::AlonzoCompatible(x),
|
||||
alonzo::AuxiliaryData::ShelleyMa(x) => {
|
||||
MultiEraMeta::AlonzoCompatible(&x.transaction_metadata)
|
||||
}
|
||||
AuxiliaryData::PostAlonzo(x) => x
|
||||
alonzo::AuxiliaryData::PostAlonzo(x) => x
|
||||
.metadata
|
||||
.as_ref()
|
||||
.map(MultiEraMeta::AlonzoCompatible)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue