feat: Add Vasil / Babbage compatibility (#126)
* feat: Bump n2n protocol versions for Babbage (#125) * feat: Allow a specified timeout on tcp connection (#127) * feat: Add Babbage primitives (#128) * fix: Inaccurate header-body CDDL (#129) * fix: Babbage CBOR codec issues (#130) * feat: Include Babbage in traverse lib * Parse Babbage headers (#131) * Add Babbage nonce/leader vrf extension (#132) Co-authored-by: Andrew Westberg <andrewwestberg@gmail.com>
This commit is contained in:
parent
dd42b951a3
commit
4e08620bc4
22 changed files with 1826 additions and 90 deletions
|
|
@ -2,7 +2,7 @@ use std::borrow::Cow;
|
|||
|
||||
use pallas_codec::minicbor;
|
||||
use pallas_crypto::hash::Hash;
|
||||
use pallas_primitives::{alonzo, byron, ToHash};
|
||||
use pallas_primitives::{alonzo, babbage, byron, ToHash};
|
||||
|
||||
use crate::{probe, support, Era, Error, MultiEraBlock, MultiEraTx};
|
||||
|
||||
|
|
@ -63,6 +63,13 @@ impl<'b> MultiEraBlock<'b> {
|
|||
))
|
||||
}
|
||||
|
||||
pub fn decode_babbage(cbor: &'b [u8]) -> Result<Self, Error> {
|
||||
let (_, block): BlockWrapper<babbage::MintedBlock> =
|
||||
minicbor::decode(cbor).map_err(Error::invalid_cbor)?;
|
||||
|
||||
Ok(Self::Babbage(Box::new(Cow::Owned(block))))
|
||||
}
|
||||
|
||||
pub fn decode(cbor: &'b [u8]) -> Result<MultiEraBlock<'b>, Error> {
|
||||
match probe::block_era(cbor) {
|
||||
probe::Outcome::EpochBoundary => Self::decode_epoch_boundary(cbor),
|
||||
|
|
@ -72,6 +79,7 @@ impl<'b> MultiEraBlock<'b> {
|
|||
Era::Allegra => Self::decode_allegra(cbor),
|
||||
Era::Mary => Self::decode_mary(cbor),
|
||||
Era::Alonzo => Self::decode_alonzo(cbor),
|
||||
Era::Babbage => Self::decode_babbage(cbor),
|
||||
},
|
||||
probe::Outcome::Inconclusive => Err(Error::unknown_cbor(cbor)),
|
||||
}
|
||||
|
|
@ -81,6 +89,7 @@ impl<'b> MultiEraBlock<'b> {
|
|||
match self {
|
||||
MultiEraBlock::EpochBoundary(_) => Era::Byron,
|
||||
MultiEraBlock::AlonzoCompatible(_, x) => *x,
|
||||
MultiEraBlock::Babbage(_) => Era::Babbage,
|
||||
MultiEraBlock::Byron(_) => Era::Byron,
|
||||
}
|
||||
}
|
||||
|
|
@ -89,6 +98,7 @@ impl<'b> MultiEraBlock<'b> {
|
|||
match self {
|
||||
MultiEraBlock::EpochBoundary(x) => x.header.to_hash(),
|
||||
MultiEraBlock::AlonzoCompatible(x, _) => x.header.to_hash(),
|
||||
MultiEraBlock::Babbage(x) => x.header.to_hash(),
|
||||
MultiEraBlock::Byron(x) => x.header.to_hash(),
|
||||
}
|
||||
}
|
||||
|
|
@ -97,6 +107,7 @@ impl<'b> MultiEraBlock<'b> {
|
|||
match self {
|
||||
MultiEraBlock::EpochBoundary(x) => x.header.to_abs_slot(),
|
||||
MultiEraBlock::AlonzoCompatible(x, _) => x.header.header_body.slot,
|
||||
MultiEraBlock::Babbage(x) => x.header.header_body.slot,
|
||||
MultiEraBlock::Byron(x) => x.header.consensus_data.0.to_abs_slot(),
|
||||
}
|
||||
}
|
||||
|
|
@ -107,6 +118,10 @@ impl<'b> MultiEraBlock<'b> {
|
|||
.into_iter()
|
||||
.map(|x| MultiEraTx::AlonzoCompatible(Box::new(Cow::Owned(x)), *era))
|
||||
.collect(),
|
||||
MultiEraBlock::Babbage(x) => support::clone_babbage_txs(x)
|
||||
.into_iter()
|
||||
.map(|x| MultiEraTx::Babbage(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))))
|
||||
|
|
@ -119,6 +134,16 @@ impl<'b> MultiEraBlock<'b> {
|
|||
match self {
|
||||
MultiEraBlock::EpochBoundary(_) => None,
|
||||
MultiEraBlock::AlonzoCompatible(x, _) => Some(x),
|
||||
MultiEraBlock::Babbage(_) => None,
|
||||
MultiEraBlock::Byron(_) => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_babbage(&self) -> Option<&babbage::MintedBlock> {
|
||||
match self {
|
||||
MultiEraBlock::EpochBoundary(_) => None,
|
||||
MultiEraBlock::AlonzoCompatible(_, _) => None,
|
||||
MultiEraBlock::Babbage(x) => Some(x),
|
||||
MultiEraBlock::Byron(_) => None,
|
||||
}
|
||||
}
|
||||
|
|
@ -127,6 +152,7 @@ impl<'b> MultiEraBlock<'b> {
|
|||
match self {
|
||||
MultiEraBlock::EpochBoundary(_) => None,
|
||||
MultiEraBlock::AlonzoCompatible(_, _) => None,
|
||||
MultiEraBlock::Babbage(_) => None,
|
||||
MultiEraBlock::Byron(x) => Some(x),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,17 +1,18 @@
|
|||
use std::fmt::{Display, Formatter};
|
||||
|
||||
use crate::{Era, Feature};
|
||||
|
||||
impl Era {
|
||||
#[allow(clippy::match_like_matches_macro)]
|
||||
pub fn has_feature(&self, feature: Feature) -> bool {
|
||||
match (self, feature) {
|
||||
(Era::Byron, _) => false,
|
||||
(Era::Shelley, Feature::SmartContracts) => false,
|
||||
(Era::Shelley, Feature::TimeLocks) => false,
|
||||
(Era::Shelley, Feature::MultiAssets) => false,
|
||||
(Era::Allegra, Feature::MultiAssets) => false,
|
||||
(Era::Allegra, Feature::SmartContracts) => false,
|
||||
(Era::Mary, Feature::SmartContracts) => false,
|
||||
_ => true,
|
||||
match feature {
|
||||
Feature::Staking => self.ge(&Era::Shelley),
|
||||
Feature::MultiAssets => self.ge(&Era::Mary),
|
||||
Feature::TimeLocks => self.ge(&Era::Allegra),
|
||||
Feature::SmartContracts => self.ge(&Era::Alonzo),
|
||||
Feature::CIP31 => self.ge(&Era::Babbage),
|
||||
Feature::CIP32 => self.ge(&Era::Babbage),
|
||||
Feature::CIP33 => self.ge(&Era::Babbage),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -29,7 +30,8 @@ impl TryFrom<u16> for Era {
|
|||
3 => Ok(Era::Allegra),
|
||||
4 => Ok(Era::Mary),
|
||||
5 => Ok(Era::Alonzo),
|
||||
x => Err(crate::Error::UnkownEra(x)),
|
||||
6 => Ok(Era::Babbage),
|
||||
x => Err(crate::Error::UnknownEra(x)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -42,6 +44,20 @@ impl From<Era> for u16 {
|
|||
Era::Allegra => 3,
|
||||
Era::Mary => 4,
|
||||
Era::Alonzo => 5,
|
||||
Era::Babbage => 6,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Era {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Era::Byron => write!(f, "Byron"),
|
||||
Era::Shelley => write!(f, "Shelley"),
|
||||
Era::Allegra => write!(f, "Allegra"),
|
||||
Era::Mary => write!(f, "Mary"),
|
||||
Era::Alonzo => write!(f, "Alonzo"),
|
||||
Era::Babbage => write!(f, "Babbage"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
use pallas_codec::minicbor;
|
||||
use pallas_crypto::hash::Hash;
|
||||
use pallas_crypto::hash::{Hash, Hasher};
|
||||
use pallas_primitives::ToHash;
|
||||
|
||||
use crate::Era::Byron;
|
||||
use crate::{Error, MultiEraHeader};
|
||||
|
||||
impl<'b> MultiEraHeader<'b> {
|
||||
|
|
@ -17,6 +18,10 @@ impl<'b> MultiEraHeader<'b> {
|
|||
Ok(MultiEraHeader::Byron(header))
|
||||
}
|
||||
},
|
||||
5 => {
|
||||
let header = minicbor::decode(cbor).map_err(Error::invalid_cbor)?;
|
||||
Ok(MultiEraHeader::Babbage(header))
|
||||
}
|
||||
_ => {
|
||||
let header = minicbor::decode(cbor).map_err(Error::invalid_cbor)?;
|
||||
Ok(MultiEraHeader::AlonzoCompatible(header))
|
||||
|
|
@ -28,6 +33,7 @@ impl<'b> MultiEraHeader<'b> {
|
|||
match self {
|
||||
MultiEraHeader::EpochBoundary(x) => x.to_abs_slot(),
|
||||
MultiEraHeader::AlonzoCompatible(x) => x.header_body.slot,
|
||||
MultiEraHeader::Babbage(x) => x.header_body.slot,
|
||||
MultiEraHeader::Byron(x) => x.consensus_data.0.to_abs_slot(),
|
||||
}
|
||||
}
|
||||
|
|
@ -36,7 +42,34 @@ impl<'b> MultiEraHeader<'b> {
|
|||
match self {
|
||||
MultiEraHeader::EpochBoundary(x) => x.to_hash(),
|
||||
MultiEraHeader::AlonzoCompatible(x) => x.to_hash(),
|
||||
MultiEraHeader::Babbage(x) => x.to_hash(),
|
||||
MultiEraHeader::Byron(x) => x.to_hash(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn leader_vrf_output(&self) -> Result<Vec<u8>, Error> {
|
||||
match self {
|
||||
MultiEraHeader::EpochBoundary(_) => Err(Error::InvalidEra(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)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn nonce_vrf_output(&self) -> Result<Vec<u8>, Error> {
|
||||
match self {
|
||||
MultiEraHeader::EpochBoundary(_) => Err(Error::InvalidEra(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)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,10 +3,11 @@
|
|||
use std::borrow::Cow;
|
||||
use std::fmt::Display;
|
||||
|
||||
use thiserror::Error;
|
||||
|
||||
use pallas_codec::utils::KeepRaw;
|
||||
use pallas_crypto::hash::Hash;
|
||||
use pallas_primitives::{alonzo, byron};
|
||||
use thiserror::Error;
|
||||
use pallas_primitives::{alonzo, babbage, byron};
|
||||
|
||||
pub mod block;
|
||||
pub mod cert;
|
||||
|
|
@ -26,6 +27,7 @@ pub enum Era {
|
|||
Allegra, // time-locks
|
||||
Mary, // multi-assets
|
||||
Alonzo, // smart-contracts
|
||||
Babbage, // CIP-31/32/33
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||
|
|
@ -35,12 +37,16 @@ pub enum Feature {
|
|||
MultiAssets,
|
||||
Staking,
|
||||
SmartContracts,
|
||||
CIP31,
|
||||
CIP32,
|
||||
CIP33,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum MultiEraHeader<'b> {
|
||||
EpochBoundary(KeepRaw<'b, byron::EbbHead>),
|
||||
AlonzoCompatible(KeepRaw<'b, alonzo::Header>),
|
||||
Babbage(KeepRaw<'b, babbage::Header>),
|
||||
Byron(KeepRaw<'b, byron::BlockHead>),
|
||||
}
|
||||
|
||||
|
|
@ -49,6 +55,7 @@ pub enum MultiEraHeader<'b> {
|
|||
pub enum MultiEraBlock<'b> {
|
||||
EpochBoundary(Box<Cow<'b, byron::EbBlock>>),
|
||||
AlonzoCompatible(Box<Cow<'b, alonzo::MintedBlock<'b>>>, Era),
|
||||
Babbage(Box<Cow<'b, babbage::MintedBlock<'b>>>),
|
||||
Byron(Box<Cow<'b, byron::MintedBlock<'b>>>),
|
||||
}
|
||||
|
||||
|
|
@ -56,14 +63,16 @@ pub enum MultiEraBlock<'b> {
|
|||
#[non_exhaustive]
|
||||
pub enum MultiEraTx<'b> {
|
||||
AlonzoCompatible(Box<Cow<'b, alonzo::MintedTx<'b>>>, Era),
|
||||
Babbage(Box<Cow<'b, babbage::MintedTx<'b>>>),
|
||||
Byron(Box<Cow<'b, byron::MintedTxPayload<'b>>>),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[non_exhaustive]
|
||||
pub enum MultiEraOutput<'b> {
|
||||
Byron(Box<Cow<'b, byron::TxOut>>),
|
||||
AlonzoCompatible(Box<Cow<'b, alonzo::TransactionOutput>>),
|
||||
Babbage(Box<Cow<'b, babbage::TransactionOutput>>),
|
||||
Byron(Box<Cow<'b, byron::TxOut>>),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
|
@ -89,7 +98,10 @@ pub enum Error {
|
|||
UnknownCbor(String),
|
||||
|
||||
#[error("Unknown era tag: {0}")]
|
||||
UnkownEra(u16),
|
||||
UnknownEra(u16),
|
||||
|
||||
#[error("Invalid era for request: {0}")]
|
||||
InvalidEra(Era),
|
||||
}
|
||||
|
||||
impl Error {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use std::borrow::Cow;
|
||||
use std::{borrow::Cow, ops::Deref};
|
||||
|
||||
use pallas_primitives::{alonzo::{self, Value}, byron};
|
||||
use pallas_primitives::{alonzo, babbage, byron};
|
||||
|
||||
use crate::MultiEraOutput;
|
||||
|
||||
|
|
@ -13,36 +13,61 @@ impl<'b> MultiEraOutput<'b> {
|
|||
Self::AlonzoCompatible(Box::new(Cow::Borrowed(output)))
|
||||
}
|
||||
|
||||
pub fn from_babbage(output: &'b babbage::TransactionOutput) -> Self {
|
||||
Self::Babbage(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")
|
||||
}
|
||||
MultiEraOutput::Babbage(x) => x.to_bech32_address(hrp).expect("invalid address value"),
|
||||
MultiEraOutput::Byron(x) => x.address.to_addr_string().expect("invalid address value"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ada_amount(&self) -> u64 {
|
||||
match self {
|
||||
MultiEraOutput::Byron(x) => x.amount,
|
||||
MultiEraOutput::Babbage(x) => match x.deref().deref() {
|
||||
babbage::TransactionOutput::Legacy(x) => match x.amount {
|
||||
babbage::Value::Coin(c) => u64::from(c),
|
||||
babbage::Value::Multiasset(c, _) => u64::from(c),
|
||||
},
|
||||
babbage::TransactionOutput::PostAlonzo(x) => match x.value {
|
||||
babbage::Value::Coin(c) => u64::from(c),
|
||||
babbage::Value::Multiasset(c, _) => u64::from(c),
|
||||
},
|
||||
},
|
||||
MultiEraOutput::AlonzoCompatible(x) => match x.amount {
|
||||
Value::Coin(c) => u64::from(c),
|
||||
Value::Multiasset(c, _) => u64::from(c)
|
||||
}
|
||||
alonzo::Value::Coin(c) => u64::from(c),
|
||||
alonzo::Value::Multiasset(c, _) => u64::from(c),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_babbage(&self) -> Option<&babbage::TransactionOutput> {
|
||||
match self {
|
||||
MultiEraOutput::AlonzoCompatible(_) => None,
|
||||
MultiEraOutput::Babbage(x) => Some(x),
|
||||
MultiEraOutput::Byron(_) => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_alonzo(&self) -> Option<&alonzo::TransactionOutput> {
|
||||
match self {
|
||||
MultiEraOutput::Byron(_) => None,
|
||||
MultiEraOutput::AlonzoCompatible(x) => Some(x),
|
||||
MultiEraOutput::Babbage(_) => None,
|
||||
MultiEraOutput::Byron(_) => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_byron(&self) -> Option<&byron::TxOut> {
|
||||
match self {
|
||||
MultiEraOutput::Byron(x) => Some(x),
|
||||
MultiEraOutput::AlonzoCompatible(_) => None,
|
||||
MultiEraOutput::Babbage(_) => None,
|
||||
MultiEraOutput::Byron(x) => Some(x),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,44 +1,57 @@
|
|||
//! Internal supporting utilities
|
||||
|
||||
use pallas_primitives::{alonzo, byron};
|
||||
use pallas_primitives::{alonzo, babbage, 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()?;
|
||||
macro_rules! clone_tx_fn {
|
||||
($fn_name:ident, $era:tt) => {
|
||||
fn $fn_name<'b>(block: &'b $era::MintedBlock, index: usize) -> Option<$era::MintedTx<'b>> {
|
||||
let transaction_body = block.transaction_bodies.get(index).cloned()?;
|
||||
|
||||
let transaction_witness_set = block.transaction_witness_sets.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 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();
|
||||
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,
|
||||
})
|
||||
let x = $era::MintedTx {
|
||||
transaction_body,
|
||||
transaction_witness_set,
|
||||
success,
|
||||
auxiliary_data,
|
||||
};
|
||||
|
||||
Some(x)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
clone_tx_fn!(babbage_clone_tx_at, babbage);
|
||||
clone_tx_fn!(alonzo_clone_tx_at, alonzo);
|
||||
|
||||
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))
|
||||
.filter_map(|idx| alonzo_clone_tx_at(block, idx))
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn clone_babbage_txs<'b>(block: &'b babbage::MintedBlock) -> Vec<babbage::MintedTx<'b>> {
|
||||
(0..block.transaction_bodies.len())
|
||||
.step_by(1)
|
||||
.filter_map(|idx| babbage_clone_tx_at(block, idx))
|
||||
.collect()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use pallas_codec::minicbor;
|
||||
use pallas_crypto::hash::Hash;
|
||||
use pallas_primitives::{alonzo, byron, ToHash};
|
||||
use pallas_primitives::{alonzo, babbage, byron, ToHash};
|
||||
use std::borrow::Cow;
|
||||
|
||||
use crate::{Era, MultiEraCert, MultiEraInput, MultiEraOutput, MultiEraTx};
|
||||
|
|
@ -14,9 +14,14 @@ impl<'b> MultiEraTx<'b> {
|
|||
Self::AlonzoCompatible(Box::new(Cow::Borrowed(tx)), era)
|
||||
}
|
||||
|
||||
pub fn from_babbage(tx: &'b babbage::MintedTx<'b>) -> Self {
|
||||
Self::Babbage(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::Babbage(x) => minicbor::to_vec(x),
|
||||
MultiEraTx::Byron(x) => minicbor::to_vec(x),
|
||||
}
|
||||
}
|
||||
|
|
@ -33,12 +38,18 @@ impl<'b> MultiEraTx<'b> {
|
|||
let tx = Box::new(Cow::Owned(tx));
|
||||
Ok(MultiEraTx::AlonzoCompatible(tx, era))
|
||||
}
|
||||
Era::Babbage => {
|
||||
let tx = minicbor::decode(cbor)?;
|
||||
let tx = Box::new(Cow::Owned(tx));
|
||||
Ok(MultiEraTx::Babbage(tx))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn era(&self) -> Era {
|
||||
match self {
|
||||
MultiEraTx::AlonzoCompatible(_, era) => *era,
|
||||
MultiEraTx::Babbage(_) => Era::Babbage,
|
||||
MultiEraTx::Byron(_) => Era::Byron,
|
||||
}
|
||||
}
|
||||
|
|
@ -46,6 +57,7 @@ impl<'b> MultiEraTx<'b> {
|
|||
pub fn hash(&self) -> Hash<32> {
|
||||
match self {
|
||||
MultiEraTx::AlonzoCompatible(x, _) => x.transaction_body.to_hash(),
|
||||
MultiEraTx::Babbage(x) => x.transaction_body.to_hash(),
|
||||
MultiEraTx::Byron(x) => x.transaction.to_hash(),
|
||||
}
|
||||
}
|
||||
|
|
@ -58,6 +70,12 @@ impl<'b> MultiEraTx<'b> {
|
|||
.iter()
|
||||
.map(MultiEraOutput::from_alonzo_compatible)
|
||||
.collect(),
|
||||
MultiEraTx::Babbage(x) => x
|
||||
.transaction_body
|
||||
.outputs
|
||||
.iter()
|
||||
.map(MultiEraOutput::from_babbage)
|
||||
.collect(),
|
||||
MultiEraTx::Byron(x) => x
|
||||
.transaction
|
||||
.outputs
|
||||
|
|
@ -74,6 +92,11 @@ impl<'b> MultiEraTx<'b> {
|
|||
.outputs
|
||||
.get(index)
|
||||
.map(MultiEraOutput::from_alonzo_compatible),
|
||||
MultiEraTx::Babbage(x) => x
|
||||
.transaction_body
|
||||
.outputs
|
||||
.get(index)
|
||||
.map(MultiEraOutput::from_babbage),
|
||||
MultiEraTx::Byron(x) => x
|
||||
.transaction
|
||||
.outputs
|
||||
|
|
@ -90,7 +113,12 @@ impl<'b> MultiEraTx<'b> {
|
|||
.iter()
|
||||
.map(MultiEraInput::from_alonzo_compatible)
|
||||
.collect(),
|
||||
|
||||
MultiEraTx::Babbage(x) => x
|
||||
.transaction_body
|
||||
.inputs
|
||||
.iter()
|
||||
.map(MultiEraInput::from_alonzo_compatible)
|
||||
.collect(),
|
||||
MultiEraTx::Byron(x) => x
|
||||
.transaction
|
||||
.inputs
|
||||
|
|
@ -109,13 +137,29 @@ impl<'b> MultiEraTx<'b> {
|
|||
.flat_map(|c| c.iter())
|
||||
.map(|c| MultiEraCert::AlonzoCompatible(Box::new(Cow::Borrowed(c))))
|
||||
.collect(),
|
||||
MultiEraTx::Babbage(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_babbage(&self) -> Option<&babbage::MintedTx> {
|
||||
match self {
|
||||
MultiEraTx::AlonzoCompatible(_, _) => None,
|
||||
MultiEraTx::Babbage(x) => Some(x),
|
||||
MultiEraTx::Byron(_) => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_alonzo(&self) -> Option<&alonzo::MintedTx> {
|
||||
match self {
|
||||
MultiEraTx::AlonzoCompatible(x, _) => Some(x),
|
||||
MultiEraTx::Babbage(_) => None,
|
||||
MultiEraTx::Byron(_) => None,
|
||||
}
|
||||
}
|
||||
|
|
@ -123,6 +167,7 @@ impl<'b> MultiEraTx<'b> {
|
|||
pub fn as_byron(&self) -> Option<&byron::MintedTxPayload> {
|
||||
match self {
|
||||
MultiEraTx::AlonzoCompatible(_, _) => None,
|
||||
MultiEraTx::Babbage(_) => None,
|
||||
MultiEraTx::Byron(x) => Some(x),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue