feat(traverse): Improve MultiEraOutput ergonomics (#141)
This commit is contained in:
parent
c7227c0234
commit
98f71289b5
3 changed files with 87 additions and 13 deletions
|
|
@ -1,4 +1,4 @@
|
|||
use std::{borrow::Cow, fmt::Display, ops::Deref};
|
||||
use std::{borrow::Cow, fmt::Display, ops::Deref, str::FromStr};
|
||||
|
||||
use pallas_codec::utils::CborWrap;
|
||||
use pallas_crypto::hash::Hash;
|
||||
|
|
@ -6,7 +6,11 @@ use pallas_primitives::{alonzo, byron};
|
|||
|
||||
use crate::{MultiEraInput, OutputRef};
|
||||
|
||||
impl OutputRef<'_> {
|
||||
impl OutputRef {
|
||||
pub fn new(hash: Hash<32>, index: u64) -> Self {
|
||||
Self(hash, index)
|
||||
}
|
||||
|
||||
pub fn tx_id(&self) -> &Hash<32> {
|
||||
&self.0
|
||||
}
|
||||
|
|
@ -16,12 +20,29 @@ impl OutputRef<'_> {
|
|||
}
|
||||
}
|
||||
|
||||
impl Display for OutputRef<'_> {
|
||||
impl Display for OutputRef {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{}#{}", self.tx_id(), self.tx_index())
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for OutputRef {
|
||||
type Err = crate::Error;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
let parts: Vec<_> = s.trim().split('#').collect();
|
||||
let (hash, idx) = match &parts[..] {
|
||||
&[a, b] => (
|
||||
Hash::<32>::from_str(a).map_err(|_| crate::Error::invalid_utxo_ref(s))?,
|
||||
u64::from_str(b).map_err(|_| crate::Error::invalid_utxo_ref(s))?,
|
||||
),
|
||||
_ => return Err(crate::Error::invalid_utxo_ref(s)),
|
||||
};
|
||||
|
||||
Ok(Self::new(hash, idx))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'b> MultiEraInput<'b> {
|
||||
pub fn from_byron(input: &'b byron::TxIn) -> Self {
|
||||
Self::Byron(Box::new(Cow::Borrowed(input)))
|
||||
|
|
@ -34,14 +55,10 @@ impl<'b> MultiEraInput<'b> {
|
|||
pub fn output_ref(&self) -> Option<OutputRef> {
|
||||
match self {
|
||||
MultiEraInput::Byron(x) => match x.deref().deref() {
|
||||
byron::TxIn::Variant0(CborWrap((tx, idx))) => {
|
||||
Some(OutputRef(Cow::Borrowed(tx), *idx as u64))
|
||||
}
|
||||
byron::TxIn::Variant0(CborWrap((tx, idx))) => Some(OutputRef(*tx, *idx as u64)),
|
||||
byron::TxIn::Other(_, _) => None,
|
||||
},
|
||||
MultiEraInput::AlonzoCompatible(x) => {
|
||||
Some(OutputRef(Cow::Borrowed(&x.transaction_id), x.index))
|
||||
}
|
||||
MultiEraInput::AlonzoCompatible(x) => Some(OutputRef(x.transaction_id, x.index)),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -62,6 +79,8 @@ impl<'b> MultiEraInput<'b> {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::str::FromStr;
|
||||
|
||||
use crate::*;
|
||||
|
||||
#[test]
|
||||
|
|
@ -99,4 +118,22 @@ mod tests {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_utxo_ref_parsing() {
|
||||
let valid_vectors = [
|
||||
"da832fb5ef57df5b91817e9a7448d26e92552afb34f8ee5adb491b24bbe990d5#14",
|
||||
" da832fb5ef57df5b91817e9a7448d26e92552afb34f8ee5adb491b24bbe990d5#14 ",
|
||||
];
|
||||
|
||||
for vector in valid_vectors.iter() {
|
||||
let sample = OutputRef::from_str(vector).unwrap();
|
||||
|
||||
assert_eq!(
|
||||
sample.tx_id().to_string(),
|
||||
"da832fb5ef57df5b91817e9a7448d26e92552afb34f8ee5adb491b24bbe990d5"
|
||||
);
|
||||
assert_eq!(sample.tx_index(), 14);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ pub enum MultiEraTx<'b> {
|
|||
Byron(Box<Cow<'b, byron::MintedTxPayload<'b>>>),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Clone)]
|
||||
#[non_exhaustive]
|
||||
pub enum MultiEraOutput<'b> {
|
||||
AlonzoCompatible(Box<Cow<'b, alonzo::TransactionOutput>>),
|
||||
|
|
@ -75,7 +75,7 @@ pub enum MultiEraOutput<'b> {
|
|||
Byron(Box<Cow<'b, byron::TxOut>>),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Clone)]
|
||||
#[non_exhaustive]
|
||||
pub enum MultiEraInput<'b> {
|
||||
Byron(Box<Cow<'b, byron::TxIn>>),
|
||||
|
|
@ -87,7 +87,8 @@ pub enum MultiEraCert<'b> {
|
|||
AlonzoCompatible(Box<Cow<'b, alonzo::Certificate>>),
|
||||
}
|
||||
|
||||
pub struct OutputRef<'a>(Cow<'a, Hash<32>>, u64);
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct OutputRef(Hash<32>, u64);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum Error {
|
||||
|
|
@ -102,6 +103,9 @@ pub enum Error {
|
|||
|
||||
#[error("Invalid era for request: {0}")]
|
||||
InvalidEra(Era),
|
||||
|
||||
#[error("Invalid UTxO ref: {0}")]
|
||||
InvalidUtxoRef(String),
|
||||
}
|
||||
|
||||
impl Error {
|
||||
|
|
@ -112,4 +116,8 @@ impl Error {
|
|||
pub fn unknown_cbor(bytes: &[u8]) -> Self {
|
||||
Error::UnknownCbor(hex::encode(bytes))
|
||||
}
|
||||
|
||||
pub fn invalid_utxo_ref(str: &str) -> Self {
|
||||
Error::InvalidUtxoRef(str.to_owned())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
use std::{borrow::Cow, ops::Deref};
|
||||
|
||||
use pallas_codec::minicbor;
|
||||
use pallas_primitives::{alonzo, babbage, byron};
|
||||
|
||||
use crate::MultiEraOutput;
|
||||
use crate::{Era, MultiEraOutput};
|
||||
|
||||
impl<'b> MultiEraOutput<'b> {
|
||||
pub fn from_byron(output: &'b byron::TxOut) -> Self {
|
||||
|
|
@ -70,4 +71,32 @@ impl<'b> MultiEraOutput<'b> {
|
|||
MultiEraOutput::Byron(x) => Some(x),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn encode(&self) -> Result<Vec<u8>, minicbor::encode::Error<std::io::Error>> {
|
||||
match self {
|
||||
Self::AlonzoCompatible(x) => minicbor::to_vec(x),
|
||||
Self::Babbage(x) => minicbor::to_vec(x),
|
||||
Self::Byron(x) => minicbor::to_vec(x),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn decode(era: Era, cbor: &'b [u8]) -> Result<Self, minicbor::decode::Error> {
|
||||
match era {
|
||||
Era::Byron => {
|
||||
let tx = minicbor::decode(cbor)?;
|
||||
let tx = Box::new(Cow::Owned(tx));
|
||||
Ok(Self::Byron(tx))
|
||||
}
|
||||
Era::Shelley | Era::Allegra | Era::Mary | Era::Alonzo => {
|
||||
let tx = minicbor::decode(cbor)?;
|
||||
let tx = Box::new(Cow::Owned(tx));
|
||||
Ok(Self::AlonzoCompatible(tx))
|
||||
}
|
||||
Era::Babbage => {
|
||||
let tx = minicbor::decode(cbor)?;
|
||||
let tx = Box::new(Cow::Owned(tx));
|
||||
Ok(Self::Babbage(tx))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue