feat: Implement common traverse iterators (#119)
This commit is contained in:
parent
2a43dd1061
commit
e67da5e7ef
12 changed files with 378 additions and 316 deletions
|
|
@ -16,7 +16,7 @@ fn main() {
|
||||||
|
|
||||||
println!("{} {}", block.slot(), block.hash());
|
println!("{} {}", block.slot(), block.hash());
|
||||||
|
|
||||||
for tx in block.tx_iter() {
|
for tx in &block.txs() {
|
||||||
println!("{:?}", tx);
|
println!("{:?}", tx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -273,7 +273,7 @@ impl<T> Deref for CborWrap<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct TagWrap<I, const T: u64>(I);
|
pub struct TagWrap<I, const T: u64>(I);
|
||||||
|
|
||||||
impl<I, const T: u64> TagWrap<I, T> {
|
impl<I, const T: u64> TagWrap<I, T> {
|
||||||
|
|
@ -342,7 +342,7 @@ impl<C> minicbor::encode::Encode<C> for EmptyMap {
|
||||||
/// A common pattern seen in the CDDL is to represent optional values as an
|
/// A common pattern seen in the CDDL is to represent optional values as an
|
||||||
/// array containing zero or more items. This structure reflects that pattern
|
/// array containing zero or more items. This structure reflects that pattern
|
||||||
/// while providing semantic meaning.
|
/// while providing semantic meaning.
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct ZeroOrOneArray<T>(Option<T>);
|
pub struct ZeroOrOneArray<T>(Option<T>);
|
||||||
|
|
||||||
impl<T> Deref for ZeroOrOneArray<T> {
|
impl<T> Deref for ZeroOrOneArray<T> {
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ impl TransactionOutput {
|
||||||
mod tests {
|
mod tests {
|
||||||
use pallas_codec::minicbor;
|
use pallas_codec::minicbor;
|
||||||
|
|
||||||
use crate::alonzo::{Block, TransactionBodyComponent};
|
use crate::alonzo::Block;
|
||||||
|
|
||||||
type BlockWrapper = (u16, Block);
|
type BlockWrapper = (u16, Block);
|
||||||
|
|
||||||
|
|
@ -49,18 +49,14 @@ mod tests {
|
||||||
assert!(block.transaction_bodies.len() > 0);
|
assert!(block.transaction_bodies.len() > 0);
|
||||||
|
|
||||||
for tx in block.transaction_bodies.iter() {
|
for tx in block.transaction_bodies.iter() {
|
||||||
for component in tx.iter() {
|
for output in tx.outputs.iter() {
|
||||||
if let TransactionBodyComponent::Outputs(outputs) = component {
|
let addr_str = output.to_bech32_address("addr_test").unwrap();
|
||||||
for output in outputs.iter() {
|
|
||||||
let addr_str = output.to_bech32_address("addr_test").unwrap();
|
|
||||||
|
|
||||||
assert!(
|
assert!(
|
||||||
KNOWN_ADDRESSES.contains(&addr_str.as_str()),
|
KNOWN_ADDRESSES.contains(&addr_str.as_str()),
|
||||||
"address {} not in known list",
|
"address {} not in known list",
|
||||||
addr_str
|
addr_str
|
||||||
);
|
);
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@
|
||||||
|
|
||||||
use pallas_codec::minicbor::{bytes::ByteVec, data::Int, data::Tag, Decode, Encode};
|
use pallas_codec::minicbor::{bytes::ByteVec, data::Int, data::Tag, Decode, Encode};
|
||||||
use pallas_crypto::hash::Hash;
|
use pallas_crypto::hash::Hash;
|
||||||
use std::ops::Deref;
|
|
||||||
|
|
||||||
use pallas_codec::utils::{AnyUInt, KeepRaw, KeyValuePairs, MaybeIndefArray};
|
use pallas_codec::utils::{AnyUInt, KeepRaw, KeyValuePairs, MaybeIndefArray};
|
||||||
|
|
||||||
|
|
@ -699,155 +698,52 @@ pub struct Update {
|
||||||
pub epoch: Epoch,
|
pub epoch: Epoch,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
|
||||||
pub enum TransactionBodyComponent {
|
|
||||||
Inputs(MaybeIndefArray<TransactionInput>),
|
|
||||||
Outputs(MaybeIndefArray<TransactionOutput>),
|
|
||||||
Fee(u64),
|
|
||||||
Ttl(u64),
|
|
||||||
Certificates(MaybeIndefArray<Certificate>),
|
|
||||||
Withdrawals(KeyValuePairs<RewardAccount, Coin>),
|
|
||||||
Update(Update),
|
|
||||||
AuxiliaryDataHash(ByteVec),
|
|
||||||
ValidityIntervalStart(u64),
|
|
||||||
Mint(Multiasset<i64>),
|
|
||||||
ScriptDataHash(Hash<32>),
|
|
||||||
Collateral(MaybeIndefArray<TransactionInput>),
|
|
||||||
RequiredSigners(MaybeIndefArray<AddrKeyhash>),
|
|
||||||
NetworkId(NetworkId),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'b, C> minicbor::decode::Decode<'b, C> for TransactionBodyComponent {
|
|
||||||
fn decode(d: &mut minicbor::Decoder<'b>, ctx: &mut C) -> Result<Self, minicbor::decode::Error> {
|
|
||||||
let key: u32 = d.decode_with(ctx)?;
|
|
||||||
|
|
||||||
match key {
|
|
||||||
0 => Ok(Self::Inputs(d.decode_with(ctx)?)),
|
|
||||||
1 => Ok(Self::Outputs(d.decode_with(ctx)?)),
|
|
||||||
2 => Ok(Self::Fee(d.decode_with(ctx)?)),
|
|
||||||
3 => Ok(Self::Ttl(d.decode_with(ctx)?)),
|
|
||||||
4 => Ok(Self::Certificates(d.decode_with(ctx)?)),
|
|
||||||
5 => Ok(Self::Withdrawals(d.decode_with(ctx)?)),
|
|
||||||
6 => Ok(Self::Update(d.decode_with(ctx)?)),
|
|
||||||
7 => Ok(Self::AuxiliaryDataHash(d.decode_with(ctx)?)),
|
|
||||||
8 => Ok(Self::ValidityIntervalStart(d.decode_with(ctx)?)),
|
|
||||||
9 => Ok(Self::Mint(d.decode_with(ctx)?)),
|
|
||||||
11 => Ok(Self::ScriptDataHash(d.decode_with(ctx)?)),
|
|
||||||
13 => Ok(Self::Collateral(d.decode_with(ctx)?)),
|
|
||||||
14 => Ok(Self::RequiredSigners(d.decode_with(ctx)?)),
|
|
||||||
15 => Ok(Self::NetworkId(d.decode_with(ctx)?)),
|
|
||||||
_ => Err(minicbor::decode::Error::message(
|
|
||||||
"invalid map key for transaction body component",
|
|
||||||
)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<C> minicbor::encode::Encode<C> for TransactionBodyComponent {
|
|
||||||
fn encode<W: minicbor::encode::Write>(
|
|
||||||
&self,
|
|
||||||
e: &mut minicbor::Encoder<W>,
|
|
||||||
ctx: &mut C,
|
|
||||||
) -> Result<(), minicbor::encode::Error<W::Error>> {
|
|
||||||
match self {
|
|
||||||
TransactionBodyComponent::Inputs(x) => {
|
|
||||||
e.encode_with(0, ctx)?;
|
|
||||||
e.encode_with(x, ctx)?;
|
|
||||||
}
|
|
||||||
TransactionBodyComponent::Outputs(x) => {
|
|
||||||
e.encode_with(1, ctx)?;
|
|
||||||
e.encode_with(x, ctx)?;
|
|
||||||
}
|
|
||||||
TransactionBodyComponent::Fee(x) => {
|
|
||||||
e.encode_with(2, ctx)?;
|
|
||||||
e.encode_with(x, ctx)?;
|
|
||||||
}
|
|
||||||
TransactionBodyComponent::Ttl(x) => {
|
|
||||||
e.encode_with(3, ctx)?;
|
|
||||||
e.encode_with(x, ctx)?;
|
|
||||||
}
|
|
||||||
TransactionBodyComponent::Certificates(x) => {
|
|
||||||
e.encode_with(4, ctx)?;
|
|
||||||
e.encode_with(x, ctx)?;
|
|
||||||
}
|
|
||||||
TransactionBodyComponent::Withdrawals(x) => {
|
|
||||||
e.encode_with(5, ctx)?;
|
|
||||||
e.encode_with(x, ctx)?;
|
|
||||||
}
|
|
||||||
TransactionBodyComponent::Update(x) => {
|
|
||||||
e.encode_with(6, ctx)?;
|
|
||||||
e.encode_with(x, ctx)?;
|
|
||||||
}
|
|
||||||
TransactionBodyComponent::AuxiliaryDataHash(x) => {
|
|
||||||
e.encode_with(7, ctx)?;
|
|
||||||
e.encode_with(x, ctx)?;
|
|
||||||
}
|
|
||||||
TransactionBodyComponent::ValidityIntervalStart(x) => {
|
|
||||||
e.encode_with(8, ctx)?;
|
|
||||||
e.encode_with(x, ctx)?;
|
|
||||||
}
|
|
||||||
TransactionBodyComponent::Mint(x) => {
|
|
||||||
e.encode_with(9, ctx)?;
|
|
||||||
e.encode_with(x, ctx)?;
|
|
||||||
}
|
|
||||||
TransactionBodyComponent::ScriptDataHash(x) => {
|
|
||||||
e.encode_with(11, ctx)?;
|
|
||||||
e.encode_with(x, ctx)?;
|
|
||||||
}
|
|
||||||
TransactionBodyComponent::Collateral(x) => {
|
|
||||||
e.encode_with(13, ctx)?;
|
|
||||||
e.encode_with(x, ctx)?;
|
|
||||||
}
|
|
||||||
TransactionBodyComponent::RequiredSigners(x) => {
|
|
||||||
e.encode_with(14, ctx)?;
|
|
||||||
e.encode_with(x, ctx)?;
|
|
||||||
}
|
|
||||||
TransactionBodyComponent::NetworkId(x) => {
|
|
||||||
e.encode_with(15, ctx)?;
|
|
||||||
e.encode_with(x, ctx)?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Can't derive encode for TransactionBody because it seems to require a very
|
// Can't derive encode for TransactionBody because it seems to require a very
|
||||||
// particular order for each key in the map
|
// particular order for each key in the map
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Encode, Decode, Debug, PartialEq, Clone)]
|
||||||
pub struct TransactionBody(Vec<TransactionBodyComponent>);
|
#[cbor(map)]
|
||||||
|
pub struct TransactionBody {
|
||||||
|
#[n(0)]
|
||||||
|
pub inputs: MaybeIndefArray<TransactionInput>,
|
||||||
|
|
||||||
impl Deref for TransactionBody {
|
#[n(1)]
|
||||||
type Target = Vec<TransactionBodyComponent>;
|
pub outputs: MaybeIndefArray<TransactionOutput>,
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target {
|
#[n(2)]
|
||||||
&self.0
|
pub fee: u64,
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'b, C> minicbor::decode::Decode<'b, C> for TransactionBody {
|
#[n(3)]
|
||||||
fn decode(d: &mut minicbor::Decoder<'b>, ctx: &mut C) -> Result<Self, minicbor::decode::Error> {
|
pub ttl: Option<u64>,
|
||||||
let len = d.map()?.unwrap_or_default();
|
|
||||||
|
|
||||||
let components: Result<_, _> = (0..len).map(|_| d.decode_with(ctx)).collect();
|
#[n(4)]
|
||||||
|
pub certificates: Option<MaybeIndefArray<Certificate>>,
|
||||||
|
|
||||||
Ok(Self(components?))
|
#[n(5)]
|
||||||
}
|
pub withdrawals: Option<KeyValuePairs<RewardAccount, Coin>>,
|
||||||
}
|
|
||||||
|
|
||||||
impl<C> minicbor::encode::Encode<C> for TransactionBody {
|
#[n(6)]
|
||||||
fn encode<W: minicbor::encode::Write>(
|
pub update: Option<Update>,
|
||||||
&self,
|
|
||||||
e: &mut minicbor::Encoder<W>,
|
|
||||||
ctx: &mut C,
|
|
||||||
) -> Result<(), minicbor::encode::Error<W::Error>> {
|
|
||||||
e.map(self.0.len() as u64)?;
|
|
||||||
for component in &self.0 {
|
|
||||||
e.encode_with(component, ctx)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
#[n(7)]
|
||||||
}
|
pub auxiliary_data_hash: Option<ByteVec>,
|
||||||
|
|
||||||
|
#[n(8)]
|
||||||
|
pub validity_interval_start: Option<u64>,
|
||||||
|
|
||||||
|
#[n(9)]
|
||||||
|
pub mint: Option<Multiasset<i64>>,
|
||||||
|
|
||||||
|
#[n(11)]
|
||||||
|
pub script_data_hash: Option<Hash<32>>,
|
||||||
|
|
||||||
|
#[n(13)]
|
||||||
|
pub collateral: Option<MaybeIndefArray<TransactionInput>>,
|
||||||
|
|
||||||
|
#[n(14)]
|
||||||
|
pub required_signers: Option<MaybeIndefArray<AddrKeyhash>>,
|
||||||
|
|
||||||
|
#[n(15)]
|
||||||
|
pub network_id: Option<NetworkId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Encode, Decode, Debug, PartialEq, Clone)]
|
#[derive(Encode, Decode, Debug, PartialEq, Clone)]
|
||||||
|
|
@ -1440,7 +1336,7 @@ pub struct Block {
|
||||||
/// This structure is analogous to [Block], but it allows to retrieve the
|
/// This structure is analogous to [Block], but it allows to retrieve the
|
||||||
/// original CBOR bytes for each structure that might require hashing. In this
|
/// original CBOR bytes for each structure that might require hashing. In this
|
||||||
/// way, we make sure that the resulting hash matches what exists on-chain.
|
/// way, we make sure that the resulting hash matches what exists on-chain.
|
||||||
#[derive(Encode, Decode, Debug, PartialEq)]
|
#[derive(Encode, Decode, Debug, PartialEq, Clone)]
|
||||||
pub struct MintedBlock<'b> {
|
pub struct MintedBlock<'b> {
|
||||||
#[n(0)]
|
#[n(0)]
|
||||||
pub header: KeepRaw<'b, Header>,
|
pub header: KeepRaw<'b, Header>,
|
||||||
|
|
@ -1473,7 +1369,7 @@ pub struct Tx {
|
||||||
pub auxiliary_data: Option<AuxiliaryData>,
|
pub auxiliary_data: Option<AuxiliaryData>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Encode, Decode, Debug)]
|
#[derive(Encode, Decode, Debug, Clone)]
|
||||||
pub struct MintedTx<'b> {
|
pub struct MintedTx<'b> {
|
||||||
#[b(0)]
|
#[b(0)]
|
||||||
pub transaction_body: KeepRaw<'b, TransactionBody>,
|
pub transaction_body: KeepRaw<'b, TransactionBody>,
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ pub type StakeholderId = Blake2b224;
|
||||||
|
|
||||||
pub type EpochId = u64;
|
pub type EpochId = u64;
|
||||||
|
|
||||||
#[derive(Encode, Decode, Debug)]
|
#[derive(Encode, Decode, Debug, Clone)]
|
||||||
pub struct SlotId {
|
pub struct SlotId {
|
||||||
#[n(0)]
|
#[n(0)]
|
||||||
pub epoch: EpochId,
|
pub epoch: EpochId,
|
||||||
|
|
@ -407,7 +407,7 @@ pub type SscCert = (VssPubKey, EpochId, PubKey, Signature);
|
||||||
// ssccerts = #6.258([* ssccert])
|
// ssccerts = #6.258([* ssccert])
|
||||||
pub type SscCerts = TagWrap<MaybeIndefArray<SscCert>, 258>;
|
pub type SscCerts = TagWrap<MaybeIndefArray<SscCert>, 258>;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum Ssc {
|
pub enum Ssc {
|
||||||
Variant0(SscComms, SscCerts),
|
Variant0(SscComms, SscCerts),
|
||||||
Variant1(SscOpens, SscCerts),
|
Variant1(SscOpens, SscCerts),
|
||||||
|
|
@ -473,7 +473,7 @@ impl<C> minicbor::Encode<C> for Ssc {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum SscProof {
|
pub enum SscProof {
|
||||||
Variant0(ByronHash, ByronHash),
|
Variant0(ByronHash, ByronHash),
|
||||||
Variant1(ByronHash, ByronHash),
|
Variant1(ByronHash, ByronHash),
|
||||||
|
|
@ -543,7 +543,7 @@ impl<C> minicbor::Encode<C> for SscProof {
|
||||||
|
|
||||||
// Delegation
|
// Delegation
|
||||||
|
|
||||||
#[derive(Debug, Encode, Decode)]
|
#[derive(Debug, Encode, Decode, Clone)]
|
||||||
pub struct Dlg {
|
pub struct Dlg {
|
||||||
#[n(0)]
|
#[n(0)]
|
||||||
pub epoch: EpochId,
|
pub epoch: EpochId,
|
||||||
|
|
@ -560,7 +560,7 @@ pub struct Dlg {
|
||||||
|
|
||||||
pub type DlgSig = (Dlg, Signature);
|
pub type DlgSig = (Dlg, Signature);
|
||||||
|
|
||||||
#[derive(Debug, Encode, Decode)]
|
#[derive(Debug, Encode, Decode, Clone)]
|
||||||
pub struct Lwdlg {
|
pub struct Lwdlg {
|
||||||
#[n(0)]
|
#[n(0)]
|
||||||
pub epoch_range: (EpochId, EpochId),
|
pub epoch_range: (EpochId, EpochId),
|
||||||
|
|
@ -581,7 +581,7 @@ pub type LwdlgSig = (Lwdlg, Signature);
|
||||||
|
|
||||||
pub type BVer = (u16, u16, u8);
|
pub type BVer = (u16, u16, u8);
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum TxFeePol {
|
pub enum TxFeePol {
|
||||||
//[0, #6.24(bytes .cbor ([bigint, bigint]))]
|
//[0, #6.24(bytes .cbor ([bigint, bigint]))]
|
||||||
Variant0(CborWrap<(i64, i64)>),
|
Variant0(CborWrap<(i64, i64)>),
|
||||||
|
|
@ -628,7 +628,7 @@ impl<C> minicbor::Encode<C> for TxFeePol {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Encode, Decode)]
|
#[derive(Debug, Encode, Decode, Clone)]
|
||||||
pub struct BVerMod {
|
pub struct BVerMod {
|
||||||
#[n(0)]
|
#[n(0)]
|
||||||
pub script_version: ZeroOrOneArray<u16>,
|
pub script_version: ZeroOrOneArray<u16>,
|
||||||
|
|
@ -675,7 +675,7 @@ pub struct BVerMod {
|
||||||
|
|
||||||
pub type UpData = (ByronHash, ByronHash, ByronHash, ByronHash);
|
pub type UpData = (ByronHash, ByronHash, ByronHash, ByronHash);
|
||||||
|
|
||||||
#[derive(Debug, Encode, Decode)]
|
#[derive(Debug, Encode, Decode, Clone)]
|
||||||
pub struct UpProp {
|
pub struct UpProp {
|
||||||
#[n(0)]
|
#[n(0)]
|
||||||
pub block_version: Option<BVer>,
|
pub block_version: Option<BVer>,
|
||||||
|
|
@ -701,7 +701,7 @@ pub struct UpProp {
|
||||||
pub signature: Option<Signature>,
|
pub signature: Option<Signature>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Encode, Decode)]
|
#[derive(Debug, Encode, Decode, Clone)]
|
||||||
pub struct UpVote {
|
pub struct UpVote {
|
||||||
#[n(0)]
|
#[n(0)]
|
||||||
pub voter: PubKey,
|
pub voter: PubKey,
|
||||||
|
|
@ -716,7 +716,7 @@ pub struct UpVote {
|
||||||
pub signature: Signature,
|
pub signature: Signature,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Encode, Decode)]
|
#[derive(Debug, Encode, Decode, Clone)]
|
||||||
pub struct Up {
|
pub struct Up {
|
||||||
#[n(0)]
|
#[n(0)]
|
||||||
pub proposal: ZeroOrOneArray<UpProp>,
|
pub proposal: ZeroOrOneArray<UpProp>,
|
||||||
|
|
@ -729,7 +729,7 @@ pub struct Up {
|
||||||
|
|
||||||
pub type Difficulty = MaybeIndefArray<u64>;
|
pub type Difficulty = MaybeIndefArray<u64>;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum BlockSig {
|
pub enum BlockSig {
|
||||||
Signature(Signature),
|
Signature(Signature),
|
||||||
LwdlgSig(LwdlgSig),
|
LwdlgSig(LwdlgSig),
|
||||||
|
|
@ -785,7 +785,7 @@ impl<C> minicbor::Encode<C> for BlockSig {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Encode, Decode, Debug)]
|
#[derive(Encode, Decode, Debug, Clone)]
|
||||||
pub struct BlockCons(
|
pub struct BlockCons(
|
||||||
#[n(0)] pub SlotId,
|
#[n(0)] pub SlotId,
|
||||||
#[n(1)] pub PubKey,
|
#[n(1)] pub PubKey,
|
||||||
|
|
@ -793,7 +793,7 @@ pub struct BlockCons(
|
||||||
#[n(3)] pub BlockSig,
|
#[n(3)] pub BlockSig,
|
||||||
);
|
);
|
||||||
|
|
||||||
#[derive(Encode, Decode, Debug)]
|
#[derive(Encode, Decode, Debug, Clone)]
|
||||||
pub struct BlockHeadEx {
|
pub struct BlockHeadEx {
|
||||||
#[n(0)]
|
#[n(0)]
|
||||||
pub block_version: BVer,
|
pub block_version: BVer,
|
||||||
|
|
@ -808,7 +808,7 @@ pub struct BlockHeadEx {
|
||||||
pub extra_proof: ByronHash,
|
pub extra_proof: ByronHash,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Encode, Decode, Debug)]
|
#[derive(Encode, Decode, Debug, Clone)]
|
||||||
pub struct BlockProof {
|
pub struct BlockProof {
|
||||||
#[n(0)]
|
#[n(0)]
|
||||||
pub tx_proof: TxProof,
|
pub tx_proof: TxProof,
|
||||||
|
|
@ -823,7 +823,7 @@ pub struct BlockProof {
|
||||||
pub upd_proof: ByronHash,
|
pub upd_proof: ByronHash,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Encode, Decode, Debug)]
|
#[derive(Encode, Decode, Debug, Clone)]
|
||||||
pub struct BlockHead {
|
pub struct BlockHead {
|
||||||
#[n(0)]
|
#[n(0)]
|
||||||
pub protocol_magic: u32,
|
pub protocol_magic: u32,
|
||||||
|
|
@ -874,7 +874,7 @@ pub struct BlockBody {
|
||||||
pub upd_payload: Up,
|
pub upd_payload: Up,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Encode, Decode, Debug)]
|
#[derive(Encode, Decode, Debug, Clone)]
|
||||||
pub struct MintedBlockBody<'b> {
|
pub struct MintedBlockBody<'b> {
|
||||||
#[b(0)]
|
#[b(0)]
|
||||||
pub tx_payload: MaybeIndefArray<MintedTxPayload<'b>>,
|
pub tx_payload: MaybeIndefArray<MintedTxPayload<'b>>,
|
||||||
|
|
@ -891,7 +891,7 @@ pub struct MintedBlockBody<'b> {
|
||||||
|
|
||||||
// Epoch Boundary Blocks
|
// Epoch Boundary Blocks
|
||||||
|
|
||||||
#[derive(Encode, Decode, Debug)]
|
#[derive(Encode, Decode, Debug, Clone)]
|
||||||
pub struct EbbCons {
|
pub struct EbbCons {
|
||||||
#[n(0)]
|
#[n(0)]
|
||||||
pub epoch_id: EpochId,
|
pub epoch_id: EpochId,
|
||||||
|
|
@ -900,7 +900,7 @@ pub struct EbbCons {
|
||||||
pub difficulty: Difficulty,
|
pub difficulty: Difficulty,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Encode, Decode, Debug)]
|
#[derive(Encode, Decode, Debug, Clone)]
|
||||||
pub struct EbbHead {
|
pub struct EbbHead {
|
||||||
#[n(0)]
|
#[n(0)]
|
||||||
pub protocol_magic: u32,
|
pub protocol_magic: u32,
|
||||||
|
|
@ -930,7 +930,7 @@ pub struct Block {
|
||||||
pub extra: MaybeIndefArray<Attributes>,
|
pub extra: MaybeIndefArray<Attributes>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Encode, Decode, Debug)]
|
#[derive(Encode, Decode, Debug, Clone)]
|
||||||
pub struct MintedBlock<'b> {
|
pub struct MintedBlock<'b> {
|
||||||
#[b(0)]
|
#[b(0)]
|
||||||
pub header: KeepRaw<'b, BlockHead>,
|
pub header: KeepRaw<'b, BlockHead>,
|
||||||
|
|
@ -942,7 +942,7 @@ pub struct MintedBlock<'b> {
|
||||||
pub extra: MaybeIndefArray<Attributes>,
|
pub extra: MaybeIndefArray<Attributes>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Encode, Decode, Debug)]
|
#[derive(Encode, Decode, Debug, Clone)]
|
||||||
pub struct EbBlock {
|
pub struct EbBlock {
|
||||||
#[n(0)]
|
#[n(0)]
|
||||||
pub header: EbbHead,
|
pub header: EbbHead,
|
||||||
|
|
|
||||||
|
|
@ -1,54 +1,94 @@
|
||||||
|
use std::borrow::Cow;
|
||||||
|
|
||||||
use pallas_codec::minicbor;
|
use pallas_codec::minicbor;
|
||||||
use pallas_crypto::hash::Hash;
|
use pallas_crypto::hash::Hash;
|
||||||
use pallas_primitives::{alonzo, byron, ToHash};
|
use pallas_primitives::{alonzo, byron, ToHash};
|
||||||
|
|
||||||
use crate::{probe, Era, Error, MultiEraBlock};
|
use crate::{probe, support, Era, Error, MultiEraBlock, MultiEraTx};
|
||||||
|
|
||||||
type BlockWrapper<T> = (u16, T);
|
type BlockWrapper<T> = (u16, T);
|
||||||
|
|
||||||
impl<'b> MultiEraBlock<'b> {
|
impl<'b> MultiEraBlock<'b> {
|
||||||
pub fn from_epoch_boundary(block: byron::EbBlock) -> Self {
|
pub fn decode_epoch_boundary(cbor: &'b [u8]) -> Result<Self, Error> {
|
||||||
Self::EpochBoundary(Box::new(block))
|
let (_, block): BlockWrapper<byron::EbBlock> =
|
||||||
|
minicbor::decode(cbor).map_err(Error::invalid_cbor)?;
|
||||||
|
|
||||||
|
Ok(Self::EpochBoundary(Box::new(Cow::Owned(block))))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_byron(block: byron::MintedBlock<'b>) -> Self {
|
pub fn decode_byron(cbor: &'b [u8]) -> Result<Self, Error> {
|
||||||
Self::Byron(Box::new(block))
|
let (_, block): BlockWrapper<byron::MintedBlock> =
|
||||||
|
minicbor::decode(cbor).map_err(Error::invalid_cbor)?;
|
||||||
|
|
||||||
|
Ok(Self::Byron(Box::new(Cow::Owned(block))))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_alonzo_compatible(block: alonzo::MintedBlock<'b>) -> Self {
|
pub fn decode_shelley(cbor: &'b [u8]) -> Result<Self, Error> {
|
||||||
Self::AlonzoCompatible(Box::new(block))
|
let (_, block): BlockWrapper<alonzo::MintedBlock> =
|
||||||
|
minicbor::decode(cbor).map_err(Error::invalid_cbor)?;
|
||||||
|
|
||||||
|
Ok(Self::AlonzoCompatible(
|
||||||
|
Box::new(Cow::Owned(block)),
|
||||||
|
Era::Shelley,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn decode_allegra(cbor: &'b [u8]) -> Result<Self, Error> {
|
||||||
|
let (_, block): BlockWrapper<alonzo::MintedBlock> =
|
||||||
|
minicbor::decode(cbor).map_err(Error::invalid_cbor)?;
|
||||||
|
|
||||||
|
Ok(Self::AlonzoCompatible(
|
||||||
|
Box::new(Cow::Owned(block)),
|
||||||
|
Era::Allegra,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn decode_mary(cbor: &'b [u8]) -> Result<Self, Error> {
|
||||||
|
let (_, block): BlockWrapper<alonzo::MintedBlock> =
|
||||||
|
minicbor::decode(cbor).map_err(Error::invalid_cbor)?;
|
||||||
|
|
||||||
|
Ok(Self::AlonzoCompatible(
|
||||||
|
Box::new(Cow::Owned(block)),
|
||||||
|
Era::Mary,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn decode_alonzo(cbor: &'b [u8]) -> Result<Self, Error> {
|
||||||
|
let (_, block): BlockWrapper<alonzo::MintedBlock> =
|
||||||
|
minicbor::decode(cbor).map_err(Error::invalid_cbor)?;
|
||||||
|
|
||||||
|
Ok(Self::AlonzoCompatible(
|
||||||
|
Box::new(Cow::Owned(block)),
|
||||||
|
Era::Alonzo,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn decode(cbor: &'b [u8]) -> Result<MultiEraBlock<'b>, Error> {
|
pub fn decode(cbor: &'b [u8]) -> Result<MultiEraBlock<'b>, Error> {
|
||||||
match probe::block_era(cbor) {
|
match probe::block_era(cbor) {
|
||||||
probe::Outcome::EpochBoundary => {
|
probe::Outcome::EpochBoundary => Self::decode_epoch_boundary(cbor),
|
||||||
let (_, block): BlockWrapper<byron::EbBlock> =
|
|
||||||
minicbor::decode(cbor).map_err(Error::invalid_cbor)?;
|
|
||||||
|
|
||||||
Ok(MultiEraBlock::from_epoch_boundary(block))
|
|
||||||
}
|
|
||||||
probe::Outcome::Matched(era) => match era {
|
probe::Outcome::Matched(era) => match era {
|
||||||
Era::Byron => {
|
Era::Byron => Self::decode_byron(cbor),
|
||||||
let (_, block): BlockWrapper<byron::MintedBlock> =
|
Era::Shelley => Self::decode_shelley(cbor),
|
||||||
minicbor::decode(cbor).map_err(Error::invalid_cbor)?;
|
Era::Allegra => Self::decode_allegra(cbor),
|
||||||
|
Era::Mary => Self::decode_mary(cbor),
|
||||||
Ok(Self::from_byron(block))
|
Era::Alonzo => Self::decode_alonzo(cbor),
|
||||||
}
|
|
||||||
Era::Shelley | Era::Allegra | Era::Mary | Era::Alonzo => {
|
|
||||||
let (_, block): BlockWrapper<alonzo::MintedBlock> =
|
|
||||||
minicbor::decode(cbor).map_err(Error::invalid_cbor)?;
|
|
||||||
|
|
||||||
Ok(Self::from_alonzo_compatible(block))
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
probe::Outcome::Inconclusive => Err(Error::unknown_cbor(cbor)),
|
probe::Outcome::Inconclusive => Err(Error::unknown_cbor(cbor)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn era(&self) -> Era {
|
||||||
|
match self {
|
||||||
|
MultiEraBlock::EpochBoundary(_) => Era::Byron,
|
||||||
|
MultiEraBlock::AlonzoCompatible(_, x) => *x,
|
||||||
|
MultiEraBlock::Byron(_) => Era::Byron,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn hash(&self) -> Hash<32> {
|
pub fn hash(&self) -> Hash<32> {
|
||||||
match self {
|
match self {
|
||||||
MultiEraBlock::EpochBoundary(x) => x.header.to_hash(),
|
MultiEraBlock::EpochBoundary(x) => x.header.to_hash(),
|
||||||
MultiEraBlock::AlonzoCompatible(x) => x.header.to_hash(),
|
MultiEraBlock::AlonzoCompatible(x, _) => x.header.to_hash(),
|
||||||
MultiEraBlock::Byron(x) => x.header.to_hash(),
|
MultiEraBlock::Byron(x) => x.header.to_hash(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -56,8 +96,60 @@ impl<'b> MultiEraBlock<'b> {
|
||||||
pub fn slot(&self) -> u64 {
|
pub fn slot(&self) -> u64 {
|
||||||
match self {
|
match self {
|
||||||
MultiEraBlock::EpochBoundary(x) => x.header.to_abs_slot(),
|
MultiEraBlock::EpochBoundary(x) => x.header.to_abs_slot(),
|
||||||
MultiEraBlock::AlonzoCompatible(x) => x.header.header_body.slot,
|
MultiEraBlock::AlonzoCompatible(x, _) => x.header.header_body.slot,
|
||||||
MultiEraBlock::Byron(x) => x.header.consensus_data.0.to_abs_slot(),
|
MultiEraBlock::Byron(x) => x.header.consensus_data.0.to_abs_slot(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn txs(&self) -> Vec<MultiEraTx> {
|
||||||
|
match self {
|
||||||
|
MultiEraBlock::AlonzoCompatible(x, _) => support::clone_alonzo_txs(x)
|
||||||
|
.into_iter()
|
||||||
|
.map(|x| MultiEraTx::AlonzoCompatible(Box::new(Cow::Owned(x))))
|
||||||
|
.collect(),
|
||||||
|
MultiEraBlock::Byron(x) => support::clone_byron_txs(x)
|
||||||
|
.into_iter()
|
||||||
|
.map(|x| MultiEraTx::Byron(Box::new(Cow::Owned(x))))
|
||||||
|
.collect(),
|
||||||
|
MultiEraBlock::EpochBoundary(_) => vec![],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn as_alonzo(&self) -> Option<&alonzo::MintedBlock> {
|
||||||
|
match self {
|
||||||
|
MultiEraBlock::EpochBoundary(_) => None,
|
||||||
|
MultiEraBlock::AlonzoCompatible(x, _) => Some(x),
|
||||||
|
MultiEraBlock::Byron(_) => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn as_byron(&self) -> Option<&byron::MintedBlock> {
|
||||||
|
match self {
|
||||||
|
MultiEraBlock::EpochBoundary(_) => None,
|
||||||
|
MultiEraBlock::AlonzoCompatible(_, _) => None,
|
||||||
|
MultiEraBlock::Byron(x) => Some(x),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_iteration() {
|
||||||
|
let blocks = vec![
|
||||||
|
(include_str!("../../test_data/byron2.block"), 2usize),
|
||||||
|
(include_str!("../../test_data/shelley1.block"), 0),
|
||||||
|
(include_str!("../../test_data/mary1.block"), 0),
|
||||||
|
(include_str!("../../test_data/allegra1.block"), 0),
|
||||||
|
(include_str!("../../test_data/alonzo1.block"), 5),
|
||||||
|
];
|
||||||
|
|
||||||
|
for (block_str, tx_count) in blocks.into_iter() {
|
||||||
|
let cbor = hex::decode(block_str).expect("invalid hex");
|
||||||
|
let block = MultiEraBlock::decode(&cbor).expect("invalid cbor");
|
||||||
|
assert_eq!(block.txs().len(), tx_count);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
12
pallas-traverse/src/cert.rs
Normal file
12
pallas-traverse/src/cert.rs
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
use pallas_primitives::alonzo;
|
||||||
|
|
||||||
|
use crate::MultiEraCert;
|
||||||
|
|
||||||
|
impl<'b> MultiEraCert<'b> {
|
||||||
|
pub fn as_alonzo(&self) -> Option<&alonzo::Certificate> {
|
||||||
|
match self {
|
||||||
|
MultiEraCert::NotApplicable => None,
|
||||||
|
MultiEraCert::AlonzoCompatible(x) => Some(x),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,96 +0,0 @@
|
||||||
//! Iterate over block data
|
|
||||||
|
|
||||||
use pallas_primitives::{alonzo, byron};
|
|
||||||
|
|
||||||
use crate::{MultiEraBlock, MultiEraTx};
|
|
||||||
|
|
||||||
fn clone_alonzo_tx_at<'b>(
|
|
||||||
block: &'b alonzo::MintedBlock,
|
|
||||||
index: usize,
|
|
||||||
) -> Option<alonzo::MintedTx<'b>> {
|
|
||||||
let transaction_body = block.transaction_bodies.get(index).cloned()?;
|
|
||||||
let transaction_witness_set = block.transaction_witness_sets.get(index).cloned()?;
|
|
||||||
let success = block
|
|
||||||
.invalid_transactions
|
|
||||||
.as_ref()?
|
|
||||||
.contains(&(index as u32));
|
|
||||||
|
|
||||||
let auxiliary_data = block
|
|
||||||
.auxiliary_data_set
|
|
||||||
.iter()
|
|
||||||
.find_map(|(idx, val)| {
|
|
||||||
if idx.eq(&(index as u32)) {
|
|
||||||
Some(val)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.cloned();
|
|
||||||
|
|
||||||
Some(alonzo::MintedTx {
|
|
||||||
transaction_body,
|
|
||||||
transaction_witness_set,
|
|
||||||
success,
|
|
||||||
auxiliary_data,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn clone_byron_tx_at<'b>(
|
|
||||||
block: &'b byron::MintedBlock,
|
|
||||||
index: usize,
|
|
||||||
) -> Option<byron::MintedTxPayload<'b>> {
|
|
||||||
block.body.tx_payload.get(index).cloned()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct TxIter<'b> {
|
|
||||||
block: &'b MultiEraBlock<'b>,
|
|
||||||
index: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'b> Iterator for TxIter<'b> {
|
|
||||||
type Item = MultiEraTx<'b>;
|
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
|
||||||
let tx = match self.block {
|
|
||||||
MultiEraBlock::EpochBoundary(_) => None,
|
|
||||||
MultiEraBlock::AlonzoCompatible(x) => {
|
|
||||||
clone_alonzo_tx_at(x, self.index).map(MultiEraTx::from_alonzo_compatible)
|
|
||||||
}
|
|
||||||
MultiEraBlock::Byron(x) => clone_byron_tx_at(x, self.index).map(MultiEraTx::from_byron),
|
|
||||||
}?;
|
|
||||||
|
|
||||||
self.index += 1;
|
|
||||||
Some(tx)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'b> MultiEraBlock<'b> {
|
|
||||||
pub fn tx_iter(&'b self) -> TxIter<'b> {
|
|
||||||
TxIter {
|
|
||||||
index: 0,
|
|
||||||
block: self,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_iteration() {
|
|
||||||
let blocks = vec![
|
|
||||||
(include_str!("../../test_data/byron2.block"), 2usize),
|
|
||||||
(include_str!("../../test_data/shelley1.block"), 0),
|
|
||||||
(include_str!("../../test_data/mary1.block"), 0),
|
|
||||||
(include_str!("../../test_data/allegra1.block"), 0),
|
|
||||||
(include_str!("../../test_data/alonzo1.block"), 5),
|
|
||||||
];
|
|
||||||
|
|
||||||
for (block_str, tx_count) in blocks.into_iter() {
|
|
||||||
let cbor = hex::decode(block_str).expect("invalid hex");
|
|
||||||
let block = MultiEraBlock::decode(&cbor).expect("invalid cbor");
|
|
||||||
assert_eq!(block.tx_iter().count(), tx_count);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,12 +1,16 @@
|
||||||
//! Utilities to traverse over multi-era block data
|
//! Utilities to traverse over multi-era block data
|
||||||
|
|
||||||
|
use std::borrow::Cow;
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
|
|
||||||
use pallas_primitives::{alonzo, byron};
|
use pallas_primitives::{alonzo, byron};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
pub mod block;
|
pub mod block;
|
||||||
pub mod iter;
|
pub mod cert;
|
||||||
|
pub mod output;
|
||||||
pub mod probe;
|
pub mod probe;
|
||||||
|
mod support;
|
||||||
pub mod tx;
|
pub mod tx;
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
|
|
@ -19,19 +23,31 @@ pub enum Era {
|
||||||
Alonzo, // smart-contracts
|
Alonzo, // smart-contracts
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone)]
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
pub enum MultiEraTx<'b> {
|
pub enum MultiEraBlock<'b> {
|
||||||
AlonzoCompatible(Box<alonzo::MintedTx<'b>>),
|
EpochBoundary(Box<Cow<'b, byron::EbBlock>>),
|
||||||
Byron(Box<byron::MintedTxPayload<'b>>),
|
AlonzoCompatible(Box<Cow<'b, alonzo::MintedBlock<'b>>>, Era),
|
||||||
|
Byron(Box<Cow<'b, byron::MintedBlock<'b>>>),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
pub enum MultiEraBlock<'b> {
|
pub enum MultiEraTx<'b> {
|
||||||
EpochBoundary(Box<byron::EbBlock>),
|
AlonzoCompatible(Box<Cow<'b, alonzo::MintedTx<'b>>>),
|
||||||
AlonzoCompatible(Box<alonzo::MintedBlock<'b>>),
|
Byron(Box<Cow<'b, byron::MintedTxPayload<'b>>>),
|
||||||
Byron(Box<byron::MintedBlock<'b>>),
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
#[non_exhaustive]
|
||||||
|
pub enum MultiEraOutput<'b> {
|
||||||
|
Byron(Box<Cow<'b, byron::TxOut>>),
|
||||||
|
AlonzoCompatible(Box<Cow<'b, alonzo::TransactionOutput>>),
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum MultiEraCert<'b> {
|
||||||
|
NotApplicable,
|
||||||
|
AlonzoCompatible(Box<Cow<'b, alonzo::Certificate>>),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error)]
|
||||||
|
|
|
||||||
38
pallas-traverse/src/output.rs
Normal file
38
pallas-traverse/src/output.rs
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
use std::borrow::Cow;
|
||||||
|
|
||||||
|
use pallas_primitives::{alonzo, byron};
|
||||||
|
|
||||||
|
use crate::MultiEraOutput;
|
||||||
|
|
||||||
|
impl<'b> MultiEraOutput<'b> {
|
||||||
|
pub fn from_byron(output: &'b byron::TxOut) -> Self {
|
||||||
|
Self::Byron(Box::new(Cow::Borrowed(output)))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn from_alonzo_compatible(output: &'b alonzo::TransactionOutput) -> Self {
|
||||||
|
Self::AlonzoCompatible(Box::new(Cow::Borrowed(output)))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn address(&self, hrp: &str) -> String {
|
||||||
|
match self {
|
||||||
|
MultiEraOutput::Byron(x) => x.address.to_addr_string().expect("invalid address value"),
|
||||||
|
MultiEraOutput::AlonzoCompatible(x) => {
|
||||||
|
x.to_bech32_address(hrp).expect("invalid address value")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn as_alonzo(&self) -> Option<&alonzo::TransactionOutput> {
|
||||||
|
match self {
|
||||||
|
MultiEraOutput::Byron(_) => None,
|
||||||
|
MultiEraOutput::AlonzoCompatible(x) => Some(x),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn as_byron(&self) -> Option<&byron::TxOut> {
|
||||||
|
match self {
|
||||||
|
MultiEraOutput::Byron(x) => Some(x),
|
||||||
|
MultiEraOutput::AlonzoCompatible(_) => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
47
pallas-traverse/src/support.rs
Normal file
47
pallas-traverse/src/support.rs
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
//! Internal supporting utilities
|
||||||
|
|
||||||
|
use pallas_primitives::{alonzo, byron};
|
||||||
|
|
||||||
|
pub fn clone_alonzo_tx_at<'b>(
|
||||||
|
block: &'b alonzo::MintedBlock,
|
||||||
|
index: usize,
|
||||||
|
) -> Option<alonzo::MintedTx<'b>> {
|
||||||
|
let transaction_body = block.transaction_bodies.get(index).cloned()?;
|
||||||
|
|
||||||
|
let transaction_witness_set = block.transaction_witness_sets.get(index).cloned()?;
|
||||||
|
|
||||||
|
let success = !block
|
||||||
|
.invalid_transactions
|
||||||
|
.as_ref()?
|
||||||
|
.contains(&(index as u32));
|
||||||
|
|
||||||
|
let auxiliary_data = block
|
||||||
|
.auxiliary_data_set
|
||||||
|
.iter()
|
||||||
|
.find_map(|(idx, val)| {
|
||||||
|
if idx.eq(&(index as u32)) {
|
||||||
|
Some(val)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.cloned();
|
||||||
|
|
||||||
|
Some(alonzo::MintedTx {
|
||||||
|
transaction_body,
|
||||||
|
transaction_witness_set,
|
||||||
|
success,
|
||||||
|
auxiliary_data,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn clone_alonzo_txs<'b>(block: &'b alonzo::MintedBlock) -> Vec<alonzo::MintedTx<'b>> {
|
||||||
|
(0..block.transaction_bodies.len())
|
||||||
|
.step_by(1)
|
||||||
|
.filter_map(|idx| clone_alonzo_tx_at(block, idx))
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn clone_byron_txs<'b>(block: &'b byron::MintedBlock) -> Vec<byron::MintedTxPayload<'b>> {
|
||||||
|
block.body.tx_payload.iter().cloned().collect()
|
||||||
|
}
|
||||||
|
|
@ -1,13 +1,74 @@
|
||||||
use pallas_primitives::{alonzo, byron};
|
use pallas_codec::minicbor;
|
||||||
|
use pallas_crypto::hash::Hash;
|
||||||
|
use pallas_primitives::{alonzo, byron, ToHash};
|
||||||
|
use std::borrow::Cow;
|
||||||
|
|
||||||
use crate::MultiEraTx;
|
use crate::{MultiEraCert, MultiEraOutput, MultiEraTx};
|
||||||
|
|
||||||
impl<'b> MultiEraTx<'b> {
|
impl<'b> MultiEraTx<'b> {
|
||||||
pub fn from_byron(tx: byron::MintedTxPayload<'b>) -> Self {
|
pub fn from_byron(tx: &'b byron::MintedTxPayload<'b>) -> Self {
|
||||||
Self::Byron(Box::new(tx))
|
Self::Byron(Box::new(Cow::Borrowed(tx)))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_alonzo_compatible(tx: alonzo::MintedTx<'b>) -> Self {
|
pub fn from_alonzo_compatible(tx: &'b alonzo::MintedTx<'b>) -> Self {
|
||||||
Self::AlonzoCompatible(Box::new(tx))
|
Self::AlonzoCompatible(Box::new(Cow::Borrowed(tx)))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn encode(&self) -> Result<Vec<u8>, minicbor::encode::Error<std::io::Error>> {
|
||||||
|
match self {
|
||||||
|
MultiEraTx::AlonzoCompatible(x) => minicbor::to_vec(x),
|
||||||
|
MultiEraTx::Byron(x) => minicbor::to_vec(x),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn hash(&self) -> Hash<32> {
|
||||||
|
match self {
|
||||||
|
MultiEraTx::AlonzoCompatible(x) => x.transaction_body.to_hash(),
|
||||||
|
MultiEraTx::Byron(x) => x.transaction.to_hash(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn outputs(&self) -> Vec<MultiEraOutput> {
|
||||||
|
match self {
|
||||||
|
MultiEraTx::AlonzoCompatible(x) => x
|
||||||
|
.transaction_body
|
||||||
|
.outputs
|
||||||
|
.iter()
|
||||||
|
.map(MultiEraOutput::from_alonzo_compatible)
|
||||||
|
.collect(),
|
||||||
|
MultiEraTx::Byron(x) => x
|
||||||
|
.transaction
|
||||||
|
.outputs
|
||||||
|
.iter()
|
||||||
|
.map(MultiEraOutput::from_byron)
|
||||||
|
.collect(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn certs(&self) -> Vec<MultiEraCert> {
|
||||||
|
match self {
|
||||||
|
MultiEraTx::AlonzoCompatible(x) => x
|
||||||
|
.transaction_body
|
||||||
|
.certificates
|
||||||
|
.iter()
|
||||||
|
.flat_map(|c| c.iter())
|
||||||
|
.map(|c| MultiEraCert::AlonzoCompatible(Box::new(Cow::Borrowed(c))))
|
||||||
|
.collect(),
|
||||||
|
MultiEraTx::Byron(_) => vec![],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn as_alonzo(&self) -> Option<&alonzo::MintedTx> {
|
||||||
|
match self {
|
||||||
|
MultiEraTx::AlonzoCompatible(x) => Some(x),
|
||||||
|
MultiEraTx::Byron(_) => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn as_byron(&self) -> Option<&byron::MintedTxPayload> {
|
||||||
|
match self {
|
||||||
|
MultiEraTx::AlonzoCompatible(_) => None,
|
||||||
|
MultiEraTx::Byron(x) => Some(x),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue