diff --git a/pallas-addresses/src/byron.rs b/pallas-addresses/src/byron.rs index 9bd4c21..c794f2e 100644 --- a/pallas-addresses/src/byron.rs +++ b/pallas-addresses/src/byron.rs @@ -12,7 +12,7 @@ pub type Blake2b224 = Hash<28>; pub type AddressId = Blake2b224; pub type StakeholderId = Blake2b224; -#[derive(Debug, Clone, PartialEq, PartialOrd)] +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] pub enum AddrDistr { Variant0(StakeholderId), Variant1, @@ -57,7 +57,7 @@ impl minicbor::Encode<()> for AddrDistr { } } -#[derive(Debug, Clone, PartialEq, PartialOrd)] +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] pub enum AddrType { PubKey, Script, @@ -98,7 +98,7 @@ impl minicbor::Encode for AddrType { } } -#[derive(Debug, Clone, PartialEq, PartialOrd)] +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] pub enum AddrAttrProperty { AddrDistr(AddrDistr), Bytes(ByteVec), @@ -148,7 +148,7 @@ impl minicbor::Encode for AddrAttrProperty { pub type AddrAttr = OrderPreservingProperties; -#[derive(Debug, Encode, Decode, Clone, PartialEq, PartialOrd)] +#[derive(Debug, Encode, Decode, Clone, PartialEq, Eq, PartialOrd)] pub struct AddressPayload { #[n(0)] pub root: AddressId, @@ -161,7 +161,7 @@ pub struct AddressPayload { } /// New type wrapping a Byron address primitive -#[derive(Debug, Encode, Decode, Clone, PartialEq, PartialOrd)] +#[derive(Debug, Encode, Decode, Clone, PartialEq, Eq, PartialOrd, Ord)] pub struct ByronAddress { #[n(0)] payload: TagWrap, diff --git a/pallas-addresses/src/lib.rs b/pallas-addresses/src/lib.rs index 82ad288..6bf4a93 100644 --- a/pallas-addresses/src/lib.rs +++ b/pallas-addresses/src/lib.rs @@ -63,7 +63,7 @@ pub type TxIdx = u64; pub type CertIdx = u64; /// An on-chain pointer to a stake key -#[derive(Debug, Clone, PartialEq, PartialOrd)] +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] pub struct Pointer(Slot, TxIdx, CertIdx); fn slice_to_hash(slice: &[u8]) -> Result, Error> { @@ -113,7 +113,7 @@ impl Pointer { } /// The payment part of a Shelley address -#[derive(Debug, Clone, PartialEq, PartialOrd)] +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd)] pub enum ShelleyPaymentPart { Key(PaymentKeyHash), Script(ScriptHash), @@ -151,7 +151,7 @@ impl ShelleyPaymentPart { } /// The delegation part of a Shelley address -#[derive(Debug, Clone, PartialEq, PartialOrd)] +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd)] pub enum ShelleyDelegationPart { Key(StakeKeyHash), Script(ScriptHash), @@ -212,7 +212,7 @@ impl StakePayload { } /// The network tag of an address -#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd)] pub enum Network { Testnet, Mainnet, @@ -230,24 +230,24 @@ impl From for Network { } /// A decoded Shelley address -#[derive(Debug, Clone, PartialEq, PartialOrd)] +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd)] pub struct ShelleyAddress(Network, ShelleyPaymentPart, ShelleyDelegationPart); /// The payload of a Stake address -#[derive(Debug, Clone, PartialEq, PartialOrd)] +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd)] pub enum StakePayload { Stake(StakeKeyHash), Script(ScriptHash), } /// A decoded Stake address -#[derive(Debug, Clone, PartialEq, PartialOrd)] +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd)] pub struct StakeAddress(Network, StakePayload); pub use byron::ByronAddress; /// A decoded Cardano address of any type -#[derive(Debug, Clone, PartialEq, PartialOrd)] +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd)] pub enum Address { Byron(ByronAddress), Shelley(ShelleyAddress), @@ -345,7 +345,7 @@ parse_stake_fn!(parse_type_14, stake_key); parse_stake_fn!(parse_type_15, script); fn bytes_to_address(bytes: &[u8]) -> Result { - let header = *bytes.get(0).ok_or(Error::MissingHeader)?; + let header = *bytes.first().ok_or(Error::MissingHeader)?; let payload = &bytes[1..]; match header & 0b1111_0000 { diff --git a/pallas-codec/Cargo.toml b/pallas-codec/Cargo.toml index b2140a6..42ae94f 100644 --- a/pallas-codec/Cargo.toml +++ b/pallas-codec/Cargo.toml @@ -13,5 +13,7 @@ authors = [ ] [dependencies] +hex = "0.4.3" minicbor = { version = "0.17", features = ["std", "half", "derive"] } +serde = { version = "1.0.143", features = ["derive"] } diff --git a/pallas-codec/src/utils.rs b/pallas-codec/src/utils.rs index 8ce5005..d8188aa 100644 --- a/pallas-codec/src/utils.rs +++ b/pallas-codec/src/utils.rs @@ -1,6 +1,6 @@ -use std::ops::Deref; - use minicbor::{data::Tag, Decode, Encode}; +use serde::{Deserialize, Serialize}; +use std::ops::Deref; /// Utility for skipping parts of the CBOR payload, use only for debugging #[derive(Debug, PartialEq, PartialOrd, Eq, Ord)] @@ -43,6 +43,21 @@ pub enum KeyValuePairs { Indef(Vec<(K, V)>), } +impl KeyValuePairs { + pub fn to_vec(self) -> Vec<(K, V)> { + self.into() + } +} + +impl From> for Vec<(K, V)> { + fn from(other: KeyValuePairs) -> Self { + match other { + KeyValuePairs::Def(x) => x, + KeyValuePairs::Indef(x) => x, + } + } +} + impl Deref for KeyValuePairs { type Target = Vec<(K, V)>; @@ -117,6 +132,12 @@ pub enum MaybeIndefArray { Indef(Vec), } +impl MaybeIndefArray { + pub fn to_vec(self) -> Vec { + self.into() + } +} + impl Deref for MaybeIndefArray { type Target = Vec; @@ -128,6 +149,15 @@ impl Deref for MaybeIndefArray { } } +impl From> for Vec { + fn from(other: MaybeIndefArray) -> Self { + match other { + MaybeIndefArray::Def(x) => x, + MaybeIndefArray::Indef(x) => x, + } + } +} + impl<'b, C, A> minicbor::decode::Decode<'b, C> for MaybeIndefArray where A: minicbor::decode::Decode<'b, C>, @@ -186,7 +216,7 @@ where /// transform key-value structures into an orderer vec of `properties`, where /// each entry represents a a cbor-encodable variant of an attribute of the /// struct. -#[derive(Debug, PartialEq, Clone, PartialOrd)] +#[derive(Debug, PartialEq, Eq, Clone, PartialOrd)] pub struct OrderPreservingProperties

(Vec

); impl

Deref for OrderPreservingProperties

{ @@ -229,7 +259,8 @@ where } /// Wraps a struct so that it is encoded/decoded as a cbor bytes -#[derive(Debug, Clone, PartialEq, PartialOrd)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd)] +#[serde(transparent)] pub struct CborWrap(pub T); impl<'b, C, T> minicbor::Decode<'b, C> for CborWrap @@ -273,7 +304,7 @@ impl Deref for CborWrap { } } -#[derive(Debug, Clone, PartialEq, PartialOrd)] +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] pub struct TagWrap(pub I); impl TagWrap { @@ -526,7 +557,7 @@ impl From<&AnyUInt> for u64 { /// let confirm: (u16, u16) = minicbor::decode(keeper.raw_cbor()).unwrap(); /// assert_eq!(confirm, (456u16, 789u16)); /// ``` -#[derive(Debug, PartialEq, PartialOrd, Clone)] +#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)] pub struct KeepRaw<'b, T> { raw: &'b [u8], inner: T, @@ -536,6 +567,10 @@ impl<'b, T> KeepRaw<'b, T> { pub fn raw_cbor(&self) -> &'b [u8] { self.raw } + + pub fn unwrap(self) -> T { + self.inner + } } impl<'b, T> Deref for KeepRaw<'b, T> { @@ -575,16 +610,37 @@ impl minicbor::Encode for KeepRaw<'_, T> { } } -#[derive(Clone, Debug)] -pub enum Nullable { +#[derive(Serialize, Deserialize, Clone, Debug)] +#[serde(from = "Option::", into = "Option::")] +pub enum Nullable +where + T: std::clone::Clone, +{ Some(T), Null, Undefined, } +impl Nullable +where + T: std::clone::Clone, +{ + pub fn map(self, f: F) -> Nullable + where + O: std::clone::Clone, + F: Fn(T) -> O, + { + match self { + Nullable::Some(x) => Nullable::Some(f(x)), + Nullable::Null => Nullable::Null, + Nullable::Undefined => Nullable::Undefined, + } + } +} + impl<'b, C, T> minicbor::Decode<'b, C> for Nullable where - T: minicbor::Decode<'b, C>, + T: minicbor::Decode<'b, C> + std::clone::Clone, { fn decode(d: &mut minicbor::Decoder<'b>, ctx: &mut C) -> Result { match d.datatype()? { @@ -606,7 +662,7 @@ where impl minicbor::Encode for Nullable where - T: minicbor::Encode, + T: minicbor::Encode + std::clone::Clone, { fn encode( &self, @@ -630,7 +686,10 @@ where } } -impl From> for Nullable { +impl From> for Nullable +where + T: std::clone::Clone, +{ fn from(x: Option) -> Self { match x { Some(x) => Nullable::Some(x), @@ -638,3 +697,92 @@ impl From> for Nullable { } } } + +impl From> for Option +where + T: std::clone::Clone, +{ + fn from(other: Nullable) -> Self { + match other { + Nullable::Some(x) => Some(x), + _ => None, + } + } +} + +#[derive(Serialize, Deserialize, Clone, Encode, Decode, Debug, PartialEq, Eq, PartialOrd, Ord)] +#[cbor(transparent)] +#[serde(into = "String")] +#[serde(try_from = "String")] +pub struct Bytes(#[n(0)] minicbor::bytes::ByteVec); + +impl From> for Bytes { + fn from(xs: Vec) -> Self { + Bytes(minicbor::bytes::ByteVec::from(xs)) + } +} + +impl From for Vec { + fn from(b: Bytes) -> Self { + b.0.into() + } +} + +impl Deref for Bytes { + type Target = Vec; + + fn deref(&self) -> &Self::Target { + self.0.deref() + } +} + +impl TryFrom for Bytes { + type Error = hex::FromHexError; + + fn try_from(value: String) -> Result { + let v = hex::decode(value)?; + Ok(Bytes(minicbor::bytes::ByteVec::from(v))) + } +} + +impl From for String { + fn from(b: Bytes) -> Self { + hex::encode(b.deref()) + } +} + +#[derive(Serialize, Deserialize, Clone, Encode, Decode, Debug, PartialEq, Eq, PartialOrd, Ord)] +#[cbor(transparent)] +#[serde(into = "i128")] +#[serde(try_from = "i128")] +pub struct Int(#[n(0)] pub minicbor::data::Int); + +impl Deref for Int { + type Target = minicbor::data::Int; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl From for i128 { + fn from(value: Int) -> Self { + i128::from(value.0) + } +} + +impl From for Int { + fn from(x: i64) -> Self { + let inner = minicbor::data::Int::from(x); + Self(inner) + } +} + +impl TryFrom for Int { + type Error = minicbor::data::TryFromIntError; + + fn try_from(value: i128) -> Result { + let inner = minicbor::data::Int::try_from(value)?; + Ok(Self(inner)) + } +} diff --git a/pallas-crypto/Cargo.toml b/pallas-crypto/Cargo.toml index b5f9319..e94b14e 100644 --- a/pallas-crypto/Cargo.toml +++ b/pallas-crypto/Cargo.toml @@ -18,8 +18,10 @@ cryptoxide = { version = "0.4.1" } thiserror = "1.0" rand_core = "0.6" pallas-codec = { version = "0.13.0", path = "../pallas-codec" } +serde = "1.0.143" [dev-dependencies] quickcheck = "1.0" quickcheck_macros = "1.0" rand = "0.8" +serde_test = "1.0.143" diff --git a/pallas-crypto/src/hash/mod.rs b/pallas-crypto/src/hash/mod.rs index ca3b15e..10a62b3 100644 --- a/pallas-crypto/src/hash/mod.rs +++ b/pallas-crypto/src/hash/mod.rs @@ -2,10 +2,9 @@ //! //! we expose two helper objects: //! -//! * [`Hasher`] to help streaming objects or bytes into a hasher -//! and computing a hash without allocating extra memory due to -//! the required **CBOR** encoding for everything by the cardano -//! protocol +//! * [`Hasher`] to help streaming objects or bytes into a hasher and computing +//! a hash without allocating extra memory due to the required **CBOR** +//! encoding for everything by the cardano protocol //! * [`struct@Hash`] a conveniently strongly typed byte array //! //! The algorithm exposed here is `Blake2b`. We currently support two @@ -30,5 +29,6 @@ #[allow(clippy::module_inception)] mod hash; mod hasher; +mod serde; pub use self::{hash::Hash, hasher::Hasher}; diff --git a/pallas-crypto/src/hash/serde.rs b/pallas-crypto/src/hash/serde.rs new file mode 100644 index 0000000..476b75c --- /dev/null +++ b/pallas-crypto/src/hash/serde.rs @@ -0,0 +1,97 @@ +use std::fmt; +use std::str::FromStr; + +use serde::de::{Error, Unexpected, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; + +use super::Hash; + +impl Serialize for Hash { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + serializer.serialize_str(&self.to_string()) + } +} + +struct HashVisitor {} + +impl<'de, const BYTES: usize> Visitor<'de> for HashVisitor { + type Value = Hash; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + write!(formatter, "a hex string representing {} bytes", BYTES) + } + + fn visit_str(self, s: &str) -> Result + where + E: Error, + { + match Hash::::from_str(s) { + Ok(x) => Ok(x), + Err(_) => Err(Error::invalid_value(Unexpected::Str(s), &self)), + } + } +} + +impl<'de, const BYTES: usize> Deserialize<'de> for Hash { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + deserializer.deserialize_str(HashVisitor:: {}) + } +} + +#[cfg(test)] +mod tests { + use serde_test::{assert_de_tokens_error, assert_tokens, Token}; + + use super::*; + + #[derive(Debug, Deserialize, Serialize, PartialEq, Eq)] + struct Dummy { + hash1: Hash<28>, + hash2: Hash<32>, + } + + #[test] + fn output_tokens() { + let dummy = Dummy { + hash1: "276fd18711931e2c0e21430192dbeac0e458093cd9d1fcd7210f64b3" + .parse() + .unwrap(), + hash2: "0d8d00cdd4657ac84d82f0a56067634a7adfdf43da41cb534bcaa45060973d21" + .parse() + .unwrap(), + }; + + assert_tokens( + &dummy, + &[ + Token::Struct { + name: "Dummy", + len: 2, + }, + Token::Str("hash1"), + Token::Str("276fd18711931e2c0e21430192dbeac0e458093cd9d1fcd7210f64b3"), + Token::Str("hash2"), + Token::Str("0d8d00cdd4657ac84d82f0a56067634a7adfdf43da41cb534bcaa45060973d21"), + Token::StructEnd, + ], + ); + } + + #[test] + fn invalid_str() { + assert_de_tokens_error::( + &[ + Token::Map { len: Some(2) }, + Token::Str("hash1"), + Token::Str("27"), + ], + "invalid value: string \"27\", expected a hex string representing 28 bytes", + ); + } +} diff --git a/pallas-miniprotocols/src/blockfetch/mod.rs b/pallas-miniprotocols/src/blockfetch/mod.rs index 6f8c2e7..23547f9 100644 --- a/pallas-miniprotocols/src/blockfetch/mod.rs +++ b/pallas-miniprotocols/src/blockfetch/mod.rs @@ -5,7 +5,7 @@ use crate::common::Point; use pallas_codec::minicbor::{decode, encode, Decode, Decoder, Encode, Encoder}; -#[derive(Debug, PartialEq, Clone)] +#[derive(Debug, PartialEq, Eq, Clone)] pub enum State { Idle, Busy, diff --git a/pallas-miniprotocols/src/chainsync/agents.rs b/pallas-miniprotocols/src/chainsync/agents.rs index 76d6661..fe57455 100644 --- a/pallas-miniprotocols/src/chainsync/agents.rs +++ b/pallas-miniprotocols/src/chainsync/agents.rs @@ -10,7 +10,7 @@ use crate::common::Point; use super::{BlockContent, HeaderContent, Message, SkippedContent, State, Tip}; -#[derive(Debug, PartialEq)] +#[derive(Debug, PartialEq, Eq)] pub enum Continuation { Proceed, DropOut, diff --git a/pallas-miniprotocols/src/chainsync/protocol.rs b/pallas-miniprotocols/src/chainsync/protocol.rs index 5fa5b95..8b8e984 100644 --- a/pallas-miniprotocols/src/chainsync/protocol.rs +++ b/pallas-miniprotocols/src/chainsync/protocol.rs @@ -5,7 +5,7 @@ use crate::common::Point; #[derive(Debug, Clone)] pub struct Tip(pub Point, pub u64); -#[derive(Debug, PartialEq, Clone)] +#[derive(Debug, PartialEq, Eq, Clone)] pub enum State { Idle, CanAwait, diff --git a/pallas-miniprotocols/src/localstate/mod.rs b/pallas-miniprotocols/src/localstate/mod.rs index 0650850..4675cdb 100644 --- a/pallas-miniprotocols/src/localstate/mod.rs +++ b/pallas-miniprotocols/src/localstate/mod.rs @@ -9,7 +9,7 @@ use crate::machines::{Agent, MachineError, Transition}; use crate::common::Point; -#[derive(Debug, PartialEq, Clone)] +#[derive(Debug, PartialEq, Eq, Clone)] pub enum State { Idle, Acquiring, diff --git a/pallas-miniprotocols/src/txmonitor/mod.rs b/pallas-miniprotocols/src/txmonitor/mod.rs index 153d76b..4510f90 100644 --- a/pallas-miniprotocols/src/txmonitor/mod.rs +++ b/pallas-miniprotocols/src/txmonitor/mod.rs @@ -8,14 +8,14 @@ type Slot = u64; type TxId = String; type Tx = String; -#[derive(Debug, PartialEq, Clone)] +#[derive(Debug, PartialEq, Eq, Clone)] pub enum StBusyKind { NextTx, HasTx, GetSizes, } -#[derive(Debug, PartialEq, Clone)] +#[derive(Debug, PartialEq, Eq, Clone)] pub enum State { StIdle, StAcquiring, @@ -24,7 +24,7 @@ pub enum State { StDone, } -#[derive(Debug, PartialEq, Clone)] +#[derive(Debug, PartialEq, Eq, Clone)] pub struct MempoolSizeAndCapacity { pub capacity_in_bytes: u32, pub size_in_bytes: u32, diff --git a/pallas-miniprotocols/src/txsubmission/mod.rs b/pallas-miniprotocols/src/txsubmission/mod.rs index d76c01e..c14fdbc 100644 --- a/pallas-miniprotocols/src/txsubmission/mod.rs +++ b/pallas-miniprotocols/src/txsubmission/mod.rs @@ -6,7 +6,7 @@ use pallas_codec::minicbor::{decode, encode, Decode, Decoder, Encode, Encoder}; use crate::machines::{Agent, MachineError, Transition}; -#[derive(Debug, PartialEq, Clone)] +#[derive(Debug, PartialEq, Eq, Clone)] pub enum State { Idle, TxIdsNonBlocking, diff --git a/pallas-primitives/Cargo.toml b/pallas-primitives/Cargo.toml index bf86407..9ec5958 100644 --- a/pallas-primitives/Cargo.toml +++ b/pallas-primitives/Cargo.toml @@ -20,8 +20,8 @@ pallas-crypto = { version = "0.13.0", path = "../pallas-crypto" } pallas-codec = { version = "0.13.0", path = "../pallas-codec" } base58 = "0.2.0" bech32 = "0.9.0" -serde = { version ="1.0.136", optional = true } -serde_json = { version ="1.0.79", optional = true } +serde = { version = "1.0.136", optional = true, features = ["derive"] } +serde_json = { version = "1.0.79", optional = true } [features] json = ["serde", "serde_json"] diff --git a/pallas-primitives/src/alonzo/crypto.rs b/pallas-primitives/src/alonzo/crypto.rs index 99c5acd..292cf7b 100644 --- a/pallas-primitives/src/alonzo/crypto.rs +++ b/pallas-primitives/src/alonzo/crypto.rs @@ -51,8 +51,7 @@ mod tests { use std::str::FromStr; use pallas_codec::minicbor; - use pallas_codec::minicbor::data::Int; - use pallas_codec::utils::MaybeIndefArray; + use pallas_codec::utils::Int; use pallas_crypto::hash::Hash; use crate::alonzo::{BigInt, Constr, MintedBlock, NativeScript, PlutusData, PlutusScript}; @@ -88,13 +87,13 @@ mod tests { #[test] fn native_script_hashes_as_cardano_cli() { // construct an arbitrary script to use as example - let ns = NativeScript::ScriptAll(MaybeIndefArray::Def(vec![ + 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"; @@ -111,26 +110,26 @@ mod tests { let pd = PlutusData::Constr(Constr:: { tag: 1280, any_constructor: None, - fields: MaybeIndefArray::Indef(vec![ + fields: vec![ PlutusData::BigInt(BigInt::Int(Int::from(4))), PlutusData::Constr(Constr:: { tag: 124, any_constructor: None, - fields: MaybeIndefArray::Indef(vec![ + fields: vec![ PlutusData::BigInt(BigInt::Int(Int::from(-4))), PlutusData::Constr(Constr:: { tag: 102, any_constructor: Some(453), - fields: MaybeIndefArray::Indef(vec![ + 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 diff --git a/pallas-primitives/src/alonzo/json.rs b/pallas-primitives/src/alonzo/json.rs index 35c89ef..6f3f784 100644 --- a/pallas-primitives/src/alonzo/json.rs +++ b/pallas-primitives/src/alonzo/json.rs @@ -1,3 +1,5 @@ +use std::ops::Deref; + use serde_json::json; use crate::ToCanonicalJson; @@ -29,9 +31,11 @@ impl ToCanonicalJson for super::PlutusData { json!({ "map": map }) } super::PlutusData::BigInt(int) => match int { - super::BigInt::Int(n) => match i64::try_from(*n) { + super::BigInt::Int(n) => match i64::try_from(*n.deref()) { Ok(x) => json!({ "int": x }), - Err(_) => json!({ "bignint": hex::encode(i128::from(*n).to_be_bytes()) }), + Err(_) => { + json!({ "bignint": hex::encode(i128::from(*n.deref()).to_be_bytes()) }) + } }, // WARNING / TODO: the CDDL shows a bignum variants of arbitrary length expressed as // bytes, but I can't find the corresponding mapping to JSON in the @@ -46,10 +50,6 @@ impl ToCanonicalJson for super::PlutusData { let list: Vec<_> = x.iter().map(|i| i.to_json()).collect(); json!({ "list": list }) } - super::PlutusData::ArrayIndef(x) => { - let list: Vec<_> = x.iter().map(|i| i.to_json()).collect(); - json!({ "list": list }) - } } } } diff --git a/pallas-primitives/src/alonzo/model.rs b/pallas-primitives/src/alonzo/model.rs index f32c2b5..555e95e 100644 --- a/pallas-primitives/src/alonzo/model.rs +++ b/pallas-primitives/src/alonzo/model.rs @@ -2,18 +2,22 @@ //! //! Handcrafted, idiomatic rust artifacts based on based on the [Alonzo CDDL](https://github.com/input-output-hk/cardano-ledger/blob/master/eras/alonzo/test-suite/cddl-files/alonzo.cddl) file in IOHK repo. -use pallas_codec::minicbor::{bytes::ByteVec, data::Int, data::Tag, Decode, Encode}; +use std::collections::BTreeMap; + +use serde::{Deserialize, Serialize}; + +use pallas_codec::minicbor::{data::Tag, Decode, Encode}; use pallas_crypto::hash::Hash; -use pallas_codec::utils::{AnyUInt, KeepRaw, KeyValuePairs, MaybeIndefArray, Nullable}; +use pallas_codec::utils::{Bytes, Int, KeepRaw, KeyValuePairs, MaybeIndefArray, Nullable}; // required for derive attrs to work use pallas_codec::minicbor; -#[derive(Encode, Decode, Debug, PartialEq, Clone)] -pub struct VrfCert(#[n(0)] pub ByteVec, #[n(1)] pub ByteVec); +#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)] +pub struct VrfCert(#[n(0)] pub Bytes, #[n(1)] pub Bytes); -#[derive(Encode, Decode, Debug, PartialEq, Clone)] +#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)] pub struct HeaderBody { #[n(0)] pub block_number: u64, @@ -25,10 +29,10 @@ pub struct HeaderBody { pub prev_hash: Option>, #[n(3)] - pub issuer_vkey: ByteVec, + pub issuer_vkey: Bytes, #[n(4)] - pub vrf_vkey: ByteVec, + pub vrf_vkey: Bytes, #[n(5)] pub nonce_vrf: VrfCert, @@ -43,7 +47,7 @@ pub struct HeaderBody { pub block_body_hash: Hash<32>, #[n(9)] - pub operational_cert_hot_vkey: ByteVec, + pub operational_cert_hot_vkey: Bytes, #[n(10)] pub operational_cert_sequence_number: u64, @@ -52,7 +56,7 @@ pub struct HeaderBody { pub operational_cert_kes_period: u64, #[n(12)] - pub operational_cert_sigma: ByteVec, + pub operational_cert_sigma: Bytes, #[n(13)] pub protocol_major: u64, @@ -63,19 +67,19 @@ pub struct HeaderBody { pub type ProtocolVersion = (u64, u64); -#[derive(Encode, Decode, Debug, PartialEq)] +#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq)] pub struct KesSignature {} -#[derive(Encode, Decode, Debug, PartialEq, Clone)] +#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)] pub struct Header { #[n(0)] pub header_body: HeaderBody, #[n(1)] - pub body_signature: ByteVec, + pub body_signature: Bytes, } -#[derive(Encode, Decode, Debug, PartialEq, Clone)] +#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)] pub struct TransactionInput { #[n(0)] pub transaction_id: Hash<32>, @@ -86,7 +90,7 @@ pub struct TransactionInput { // $nonce /= [ 0 // 1, bytes .size 32 ] -#[derive(Encode, Decode, Debug, PartialEq, Clone)] +#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)] #[cbor(index_only)] pub enum NonceVariant { #[n(0)] @@ -96,7 +100,7 @@ pub enum NonceVariant { Nonce, } -#[derive(Encode, Decode, Debug, PartialEq, Clone)] +#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)] pub struct Nonce { #[n(0)] pub variant: NonceVariant, @@ -105,19 +109,19 @@ pub struct Nonce { pub hash: Option>, } -pub type ScriptHash = ByteVec; +pub type ScriptHash = Bytes; -pub type PolicyId = ScriptHash; +pub type PolicyId = Hash<28>; -pub type AssetName = ByteVec; +pub type AssetName = Bytes; -pub type Multiasset = KeyValuePairs>; +pub type Multiasset = BTreeMap>; pub type Mint = Multiasset; -pub type Coin = AnyUInt; +pub type Coin = u64; -#[derive(Debug, PartialEq, Clone)] +#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)] pub enum Value { Coin(Coin), Multiasset(Coin, Multiasset), @@ -163,10 +167,10 @@ impl minicbor::encode::Encode for Value { } } -#[derive(Encode, Decode, Debug, PartialEq, Clone)] +#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)] pub struct TransactionOutput { #[n(0)] - pub address: ByteVec, + pub address: Bytes, #[n(1)] pub amount: Value, @@ -177,8 +181,8 @@ pub struct TransactionOutput { pub type PoolKeyhash = Hash<28>; pub type Epoch = u64; -pub type Genesishash = ByteVec; -pub type GenesisDelegateHash = ByteVec; +pub type Genesishash = Bytes; +pub type GenesisDelegateHash = Bytes; pub type VrfKeyhash = Hash<32>; /* move_instantaneous_reward = [ 0 / 1, { * stake_credential => delta_coin } / coin ] @@ -188,7 +192,7 @@ pub type VrfKeyhash = Hash<32>; ; otherwise the funds are given to the other accounting pot. */ -#[derive(Debug, PartialEq, PartialOrd, Clone)] +#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, PartialOrd, Ord, Clone)] pub enum InstantaneousRewardSource { Reserves, Treasury, @@ -226,9 +230,9 @@ impl minicbor::encode::Encode for InstantaneousRewardSource { } } -#[derive(Debug, PartialEq, PartialOrd, Clone)] +#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, PartialOrd, Ord, Clone)] pub enum InstantaneousRewardTarget { - StakeCredentials(KeyValuePairs), + StakeCredentials(BTreeMap), OtherAccountingPot(Coin), } @@ -268,7 +272,7 @@ impl minicbor::encode::Encode for InstantaneousRewardTarget { } } -#[derive(Encode, Decode, Debug, PartialEq, PartialOrd, Clone)] +#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, PartialOrd, Ord, Clone)] #[cbor] pub struct MoveInstantaneousReward { #[n(0)] @@ -278,18 +282,18 @@ pub struct MoveInstantaneousReward { pub target: InstantaneousRewardTarget, } -pub type RewardAccount = ByteVec; +pub type RewardAccount = Bytes; -pub type Withdrawals = KeyValuePairs; +pub type Withdrawals = BTreeMap; -pub type RequiredSigners = MaybeIndefArray; +pub type RequiredSigners = Vec; pub type Port = u32; -pub type IPv4 = ByteVec; -pub type IPv6 = ByteVec; +pub type IPv4 = Bytes; +pub type IPv6 = Bytes; pub type DnsName = String; -#[derive(Debug, PartialEq, Clone)] +#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)] pub enum Relay { SingleHostAddr(Option, Option, Option), SingleHostName(Option, DnsName), @@ -356,7 +360,7 @@ impl minicbor::encode::Encode for Relay { pub type PoolMetadataHash = Hash<32>; -#[derive(Encode, Decode, Debug, PartialEq, Clone)] +#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)] pub struct PoolMetadata { #[n(0)] pub url: String, @@ -368,7 +372,7 @@ pub struct PoolMetadata { pub type AddrKeyhash = Hash<28>; pub type Scripthash = Hash<28>; -#[derive(Debug, PartialEq, Clone)] +#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)] pub struct RationalNumber { pub numerator: i64, pub denominator: u64, @@ -406,7 +410,7 @@ pub type UnitInterval = RationalNumber; pub type PositiveInterval = RationalNumber; -#[derive(Debug, PartialEq, PartialOrd, Eq, Ord, Clone)] +#[derive(Serialize, Deserialize, Debug, PartialEq, PartialOrd, Eq, Ord, Clone)] pub enum StakeCredential { AddrKeyhash(AddrKeyhash), Scripthash(Scripthash), @@ -452,7 +456,7 @@ impl minicbor::encode::Encode for StakeCredential { } } -#[derive(Debug, PartialEq, Clone)] +#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)] pub enum Certificate { StakeRegistration(StakeCredential), StakeDeregistration(StakeCredential), @@ -464,8 +468,8 @@ pub enum Certificate { cost: Coin, margin: UnitInterval, reward_account: RewardAccount, - pool_owners: MaybeIndefArray, - relays: MaybeIndefArray, + pool_owners: Vec, + relays: Vec, pool_metadata: Option, }, PoolRetirement(PoolKeyhash, Epoch), @@ -620,7 +624,7 @@ impl minicbor::encode::Encode for Certificate { } } -#[derive(Encode, Decode, Debug, PartialEq, Eq, PartialOrd, Ord, Clone)] +#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, PartialOrd, Ord, Clone)] #[cbor(index_only)] pub enum NetworkId { #[n(0)] @@ -629,18 +633,18 @@ pub enum NetworkId { Two, } -#[derive(Encode, Decode, Debug, PartialEq, Clone)] +#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, PartialOrd, Ord, Clone)] #[cbor(index_only)] pub enum Language { #[n(0)] PlutusV1, } -pub type CostModel = MaybeIndefArray; +pub type CostModel = Vec; -pub type CostMdls = KeyValuePairs; +pub type CostMdls = BTreeMap; -#[derive(Encode, Decode, Debug, PartialEq, Clone)] +#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)] #[cbor(map)] pub struct ProtocolParamUpdate { #[n(0)] @@ -693,10 +697,10 @@ pub struct ProtocolParamUpdate { pub max_collateral_inputs: Option, } -#[derive(Encode, Decode, Debug, PartialEq, Clone)] +#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)] pub struct Update { #[n(0)] - pub proposed_protocol_parameter_updates: KeyValuePairs, + pub proposed_protocol_parameter_updates: BTreeMap, #[n(1)] pub epoch: Epoch, @@ -704,14 +708,14 @@ pub struct Update { // Can't derive encode for TransactionBody because it seems to require a very // particular order for each key in the map -#[derive(Encode, Decode, Debug, PartialEq, Clone)] +#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)] #[cbor(map)] pub struct TransactionBody { #[n(0)] - pub inputs: MaybeIndefArray, + pub inputs: Vec, #[n(1)] - pub outputs: MaybeIndefArray, + pub outputs: Vec, #[n(2)] pub fee: u64, @@ -720,7 +724,7 @@ pub struct TransactionBody { pub ttl: Option, #[n(4)] - pub certificates: Option>, + pub certificates: Option>, #[n(5)] pub withdrawals: Option, @@ -729,7 +733,7 @@ pub struct TransactionBody { pub update: Option, #[n(7)] - pub auxiliary_data_hash: Option, + pub auxiliary_data_hash: Option, #[n(8)] pub validity_interval_start: Option, @@ -741,7 +745,7 @@ pub struct TransactionBody { pub script_data_hash: Option>, #[n(13)] - pub collateral: Option>, + pub collateral: Option>, #[n(14)] pub required_signers: Option, @@ -750,21 +754,21 @@ pub struct TransactionBody { pub network_id: Option, } -#[derive(Encode, Decode, Debug, PartialEq, Clone)] +#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)] pub struct VKeyWitness { #[n(0)] - pub vkey: ByteVec, + pub vkey: Bytes, #[n(1)] - pub signature: ByteVec, + pub signature: Bytes, } -#[derive(Debug, PartialEq, Clone)] +#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)] pub enum NativeScript { ScriptPubkey(AddrKeyhash), - ScriptAll(MaybeIndefArray), - ScriptAny(MaybeIndefArray), - ScriptNOfK(u32, MaybeIndefArray), + ScriptAll(Vec), + ScriptAny(Vec), + ScriptNOfK(u32, Vec), InvalidBefore(u64), InvalidHereafter(u64), } @@ -831,9 +835,9 @@ impl minicbor::encode::Encode for NativeScript { } } -#[derive(Encode, Decode, Debug, PartialEq, Clone)] +#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)] #[cbor(transparent)] -pub struct PlutusScript(#[n(0)] pub ByteVec); +pub struct PlutusScript(#[n(0)] pub Bytes); impl AsRef<[u8]> for PlutusScript { fn as_ref(&self) -> &[u8] { @@ -847,11 +851,11 @@ big_uint = #6.2(bounded_bytes) ; New big_nint = #6.3(bounded_bytes) ; New */ -#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)] +#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, PartialOrd, Ord, Clone)] pub enum BigInt { Int(Int), - BigUInt(ByteVec), - BigNInt(ByteVec), + BigUInt(Bytes), + BigNInt(Bytes), } impl<'b, C> minicbor::decode::Decode<'b, C> for BigInt { @@ -909,14 +913,13 @@ impl minicbor::encode::Encode for BigInt { } } -#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)] +#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, PartialOrd, Ord, Clone)] pub enum PlutusData { Constr(Constr), - Map(KeyValuePairs), + Map(BTreeMap), BigInt(BigInt), - BoundedBytes(ByteVec), - Array(MaybeIndefArray), - ArrayIndef(MaybeIndefArray), + BoundedBytes(Bytes), + Array(Vec), } impl<'b, C> minicbor::decode::Decode<'b, C> for PlutusData { @@ -955,10 +958,11 @@ impl<'b, C> minicbor::decode::Decode<'b, C> for PlutusData { full.extend(slice?); } - Ok(Self::BoundedBytes(ByteVec::from(full))) + Ok(Self::BoundedBytes(Bytes::from(full))) + } + minicbor::data::Type::Array | minicbor::data::Type::ArrayIndef => { + Ok(Self::Array(d.decode_with(ctx)?)) } - minicbor::data::Type::Array => Ok(Self::Array(d.decode_with(ctx)?)), - minicbor::data::Type::ArrayIndef => Ok(Self::ArrayIndef(d.decode_with(ctx)?)), _ => Err(minicbor::decode::Error::message( "bad cbor data type for plutus data", @@ -978,7 +982,13 @@ impl minicbor::encode::Encode for PlutusData { e.encode_with(a, ctx)?; } Self::Map(a) => { - e.encode_with(a, ctx)?; + // we use indef array by default to match the approach used by the cardano-cli + e.begin_map()?; + for (k, v) in a.iter() { + k.encode(e, ctx)?; + v.encode(e, ctx)?; + } + e.end()?; } Self::BigInt(a) => { e.encode_with(a, ctx)?; @@ -987,10 +997,12 @@ impl minicbor::encode::Encode for PlutusData { e.encode_with(a, ctx)?; } Self::Array(a) => { - e.encode_with(a, ctx)?; - } - Self::ArrayIndef(a) => { - e.encode_with(a, ctx)?; + // we use indef array by default to match the approach used by the cardano-cli + e.begin_array()?; + for v in a.iter() { + e.encode_with(v, ctx)?; + } + e.end()?; } } @@ -998,11 +1010,11 @@ impl minicbor::encode::Encode for PlutusData { } } -#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)] +#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, PartialOrd, Ord, Clone)] pub struct Constr { pub tag: u64, pub any_constructor: Option, - pub fields: MaybeIndefArray, + pub fields: Vec, } impl<'b, C, A> minicbor::decode::Decode<'b, C> for Constr @@ -1054,12 +1066,23 @@ where 102 => { e.array(2)?; e.encode_with(self.any_constructor.unwrap_or_default(), ctx)?; - e.encode_with(&self.fields, ctx)?; + + // we use indef array by default to match the approach used by the cardano-cli + e.begin_array()?; + for v in self.fields.iter() { + e.encode_with(v, ctx)?; + } + e.end()?; Ok(()) } _ => { - e.encode_with(&self.fields, ctx)?; + // we use indef array by default to match the approach used by the cardano-cli + e.begin_array()?; + for v in self.fields.iter() { + e.encode_with(v, ctx)?; + } + e.end()?; Ok(()) } @@ -1067,7 +1090,7 @@ where } } -#[derive(Encode, Decode, Debug, PartialEq, Clone)] +#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)] pub struct ExUnits { #[n(0)] pub mem: u32, @@ -1075,7 +1098,7 @@ pub struct ExUnits { pub steps: u64, } -#[derive(Encode, Decode, Debug, PartialEq, Clone)] +#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)] pub struct ExUnitPrices { #[n(0)] mem_price: PositiveInterval, @@ -1084,7 +1107,7 @@ pub struct ExUnitPrices { step_price: PositiveInterval, } -#[derive(Encode, Decode, Debug, PartialEq, Clone)] +#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)] #[cbor(index_only)] pub enum RedeemerTag { #[n(0)] @@ -1097,7 +1120,7 @@ pub enum RedeemerTag { Reward, } -#[derive(Encode, Decode, Debug, PartialEq, Clone)] +#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)] pub struct Redeemer { #[n(0)] pub tag: RedeemerTag, @@ -1119,102 +1142,78 @@ pub struct Redeemer { , attributes : bytes ] */ -#[derive(Encode, Decode, Debug, PartialEq, Clone)] +#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)] pub struct BootstrapWitness { #[n(0)] - pub public_key: ByteVec, + pub public_key: Bytes, #[n(1)] - pub signature: ByteVec, + pub signature: Bytes, #[n(2)] - pub chain_code: ByteVec, + pub chain_code: Bytes, #[n(3)] - pub attributes: ByteVec, + pub attributes: Bytes, } -#[derive(Encode, Decode, Debug, PartialEq, Clone)] +#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Clone)] #[cbor(map)] pub struct TransactionWitnessSet { #[n(0)] - pub vkeywitness: Option>, + pub vkeywitness: Option>, #[n(1)] - pub native_script: Option>, + pub native_script: Option>, #[n(2)] - pub bootstrap_witness: Option>, + pub bootstrap_witness: Option>, #[n(3)] - pub plutus_script: Option>, + pub plutus_script: Option>, #[n(4)] - pub plutus_data: Option>, + pub plutus_data: Option>, #[n(5)] - pub redeemer: Option>, + pub redeemer: Option>, } -#[derive(Encode, Decode, Debug, PartialEq, Clone)] +#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Clone)] #[cbor(map)] pub struct PostAlonzoAuxiliaryData { #[n(0)] pub metadata: Option, #[n(1)] - pub native_scripts: Option>, + pub native_scripts: Option>, #[n(2)] - pub plutus_scripts: Option>, + pub plutus_scripts: Option>, } -#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)] +#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, PartialOrd, Ord, Clone)] pub enum Metadatum { Int(Int), - Bytes(ByteVec), + Bytes(Bytes), Text(String), - Array(MaybeIndefArray), - Map(KeyValuePairs), + Array(Vec), + Map(BTreeMap), } impl<'b, C> minicbor::Decode<'b, C> for Metadatum { fn decode(d: &mut minicbor::Decoder<'b>, ctx: &mut C) -> Result { match d.datatype()? { - minicbor::data::Type::U8 => { - let i = d.u8()?; - Ok(Metadatum::Int(i.into())) - } - minicbor::data::Type::U16 => { - let i = d.u16()?; - Ok(Metadatum::Int(i.into())) - } - minicbor::data::Type::U32 => { - let i = d.u32()?; - Ok(Metadatum::Int(i.into())) - } - minicbor::data::Type::U64 => { - let i = d.u64()?; - Ok(Metadatum::Int(i.into())) - } - minicbor::data::Type::I8 => { - let i = d.i8()?; - Ok(Metadatum::Int(i.into())) - } - minicbor::data::Type::I16 => { - let i = d.i16()?; - Ok(Metadatum::Int(i.into())) - } - minicbor::data::Type::I32 => { - let i = d.i32()?; - Ok(Metadatum::Int(i.into())) - } - minicbor::data::Type::I64 => { - let i = d.i64()?; - Ok(Metadatum::Int(i.into())) - } - minicbor::data::Type::Int => { - let i = d.int()?; + minicbor::data::Type::U8 + | minicbor::data::Type::U16 + | minicbor::data::Type::U32 + | minicbor::data::Type::U64 + | minicbor::data::Type::I8 + | minicbor::data::Type::I16 + | minicbor::data::Type::I32 + | minicbor::data::Type::I64 + | minicbor::data::Type::Int => { + let i = d.decode()?; Ok(Metadatum::Int(i)) } minicbor::data::Type::Bytes => Ok(Metadatum::Bytes(d.decode_with(ctx)?)), @@ -1256,23 +1255,23 @@ impl minicbor::Encode for Metadatum { } } -pub type MetadatumLabel = AnyUInt; +pub type MetadatumLabel = u64; -pub type Metadata = KeyValuePairs; +pub type Metadata = BTreeMap; -#[derive(Encode, Decode, Debug, PartialEq, Clone)] -pub struct ShelleyMaAuxiliaryDAta { +#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Clone)] +pub struct ShelleyMaAuxiliaryData { #[n(0)] pub transaction_metadata: Metadata, #[n(1)] - pub auxiliary_scripts: Option>, + pub auxiliary_scripts: Option>, } -#[derive(Debug, PartialEq, Clone)] +#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)] pub enum AuxiliaryData { Shelley(Metadata), - ShelleyMa(ShelleyMaAuxiliaryDAta), + ShelleyMa(ShelleyMaAuxiliaryData), PostAlonzo(PostAlonzoAuxiliaryData), } @@ -1320,22 +1319,22 @@ impl minicbor::Encode for AuxiliaryData { pub type TransactionIndex = u32; -#[derive(Encode, Decode, Debug, PartialEq, Clone)] +#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Clone)] pub struct Block { #[n(0)] pub header: Header, #[b(1)] - pub transaction_bodies: MaybeIndefArray, + pub transaction_bodies: Vec, #[n(2)] - pub transaction_witness_sets: MaybeIndefArray, + pub transaction_witness_sets: Vec, #[n(3)] - pub auxiliary_data_set: KeyValuePairs, + pub auxiliary_data_set: BTreeMap, #[n(4)] - pub invalid_transactions: Option>, + pub invalid_transactions: Option>, } /// A memory representation of an already minted block @@ -1361,7 +1360,34 @@ pub struct MintedBlock<'b> { pub invalid_transactions: Option>, } -#[derive(Encode, Decode, Debug)] +impl<'b> From> for Block { + fn from(x: MintedBlock<'b>) -> Self { + Block { + header: x.header.unwrap(), + transaction_bodies: x + .transaction_bodies + .to_vec() + .into_iter() + .map(|x| x.unwrap()) + .collect(), + transaction_witness_sets: x + .transaction_witness_sets + .to_vec() + .into_iter() + .map(|x| x.unwrap()) + .collect(), + auxiliary_data_set: x + .auxiliary_data_set + .to_vec() + .into_iter() + .map(|(k, v)| (k, v.unwrap())) + .collect(), + invalid_transactions: x.invalid_transactions.map(|x| x.into()), + } + } +} + +#[derive(Serialize, Deserialize, Encode, Decode, Debug)] pub struct Tx { #[n(0)] pub transaction_body: TransactionBody, diff --git a/pallas-primitives/src/babbage/model.rs b/pallas-primitives/src/babbage/model.rs index 2dedd9f..f9eeac3 100644 --- a/pallas-primitives/src/babbage/model.rs +++ b/pallas-primitives/src/babbage/model.rs @@ -2,17 +2,21 @@ //! //! Handcrafted, idiomatic rust artifacts based on based on the [Babbage CDDL](https://github.com/input-output-hk/cardano-ledger/blob/master/eras/babbage/test-suite/cddl-files/babbage.cddl) file in IOHK repo. -use pallas_codec::minicbor::{bytes::ByteVec, Decode, Encode}; +use std::collections::BTreeMap; + +use serde::{Deserialize, Serialize}; + +use pallas_codec::minicbor::{Decode, Encode}; use pallas_crypto::hash::Hash; -use pallas_codec::utils::{CborWrap, KeepRaw, KeyValuePairs, MaybeIndefArray, Nullable}; +use pallas_codec::utils::{Bytes, CborWrap, KeepRaw, KeyValuePairs, MaybeIndefArray, Nullable}; // required for derive attrs to work use pallas_codec::minicbor; pub use crate::alonzo::VrfCert; -#[derive(Encode, Decode, Debug, PartialEq, Clone)] +#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)] pub struct HeaderBody { #[n(0)] pub block_number: u64, @@ -24,10 +28,10 @@ pub struct HeaderBody { pub prev_hash: Option>, #[n(3)] - pub issuer_vkey: ByteVec, + pub issuer_vkey: Bytes, #[n(4)] - pub vrf_vkey: ByteVec, + pub vrf_vkey: Bytes, #[n(5)] pub vrf_result: VrfCert, @@ -45,10 +49,10 @@ pub struct HeaderBody { pub protocol_version: ProtocolVersion, } -#[derive(Encode, Decode, Debug, Clone, PartialEq, PartialOrd)] +#[derive(Serialize, Deserialize, Encode, Decode, Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] pub struct OperationalCert { #[n(0)] - pub operational_cert_hot_vkey: ByteVec, + pub operational_cert_hot_vkey: Bytes, #[n(1)] pub operational_cert_sequence_number: u64, @@ -57,20 +61,20 @@ pub struct OperationalCert { pub operational_cert_kes_period: u64, #[n(3)] - pub operational_cert_sigma: ByteVec, + pub operational_cert_sigma: Bytes, } pub use crate::alonzo::ProtocolVersion; pub use crate::alonzo::KesSignature; -#[derive(Encode, Decode, Debug, PartialEq, Clone)] +#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)] pub struct Header { #[n(0)] pub header_body: HeaderBody, #[n(1)] - pub body_signature: ByteVec, + pub body_signature: Bytes, } pub use crate::alonzo::TransactionInput; @@ -113,9 +117,9 @@ pub use crate::alonzo::MoveInstantaneousReward; pub use crate::alonzo::RewardAccount; -pub type Withdrawals = KeyValuePairs; +pub type Withdrawals = BTreeMap; -pub type RequiredSigners = MaybeIndefArray; +pub type RequiredSigners = Vec; pub use crate::alonzo::Port; @@ -147,7 +151,7 @@ pub use crate::alonzo::Certificate; pub use crate::alonzo::NetworkId; -#[derive(Encode, Decode, Debug, PartialEq, Clone)] +#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)] #[cbor(index_only)] pub enum Language { #[n(0)] @@ -159,7 +163,7 @@ pub enum Language { pub use crate::alonzo::CostModel; -#[derive(Encode, Decode, Debug, PartialEq, Clone)] +#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)] #[cbor(map)] pub struct CostMdls { #[n(0)] @@ -169,7 +173,7 @@ pub struct CostMdls { pub plutus_v2: Option, } -#[derive(Encode, Decode, Debug, PartialEq, Clone)] +#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)] #[cbor(map)] pub struct ProtocolParamUpdate { #[n(0)] @@ -219,23 +223,23 @@ pub struct ProtocolParamUpdate { pub max_collateral_inputs: Option, } -#[derive(Encode, Decode, Debug, PartialEq, Clone)] +#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)] pub struct Update { #[n(0)] - pub proposed_protocol_parameter_updates: KeyValuePairs, + pub proposed_protocol_parameter_updates: BTreeMap, #[n(1)] pub epoch: Epoch, } -#[derive(Encode, Decode, Debug, PartialEq, Clone)] +#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Clone)] #[cbor(map)] pub struct TransactionBody { #[n(0)] - pub inputs: MaybeIndefArray, + pub inputs: Vec, #[n(1)] - pub outputs: MaybeIndefArray, + pub outputs: Vec, #[n(2)] pub fee: u64, @@ -244,16 +248,16 @@ pub struct TransactionBody { pub ttl: Option, #[n(4)] - pub certificates: Option>, + pub certificates: Option>, #[n(5)] - pub withdrawals: Option>, + pub withdrawals: Option>, #[n(6)] pub update: Option, #[n(7)] - pub auxiliary_data_hash: Option, + pub auxiliary_data_hash: Option, #[n(8)] pub validity_interval_start: Option, @@ -265,10 +269,10 @@ pub struct TransactionBody { pub script_data_hash: Option>, #[n(13)] - pub collateral: Option>, + pub collateral: Option>, #[n(14)] - pub required_signers: Option>, + pub required_signers: Option>, #[n(15)] pub network_id: Option, @@ -280,10 +284,10 @@ pub struct TransactionBody { pub total_collateral: Option, #[n(18)] - pub reference_inputs: Option>, + pub reference_inputs: Option>, } -#[derive(Debug, PartialEq, Clone)] +#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)] pub enum TransactionOutput { Legacy(LegacyTransactionOutput), PostAlonzo(PostAlonzoTransactionOutput), @@ -321,11 +325,11 @@ impl minicbor::Encode for TransactionOutput { } } -#[derive(Encode, Decode, Debug, PartialEq, Clone)] +#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Clone)] #[cbor(map)] pub struct PostAlonzoTransactionOutput { #[n(0)] - pub address: ByteVec, + pub address: Bytes, #[n(1)] pub value: Value, @@ -343,9 +347,9 @@ pub use crate::alonzo::NativeScript; pub use crate::alonzo::PlutusScript as PlutusV1Script; -#[derive(Encode, Decode, Debug, PartialEq, Clone)] +#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)] #[cbor(transparent)] -pub struct PlutusV2Script(#[n(0)] pub ByteVec); +pub struct PlutusV2Script(#[n(0)] pub Bytes); impl AsRef<[u8]> for PlutusV2Script { fn as_ref(&self) -> &[u8] { @@ -369,45 +373,45 @@ pub use crate::alonzo::Redeemer; pub use crate::alonzo::BootstrapWitness; -#[derive(Encode, Decode, Debug, PartialEq, Clone)] +#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Clone)] #[cbor(map)] pub struct TransactionWitnessSet { #[n(0)] - pub vkeywitness: Option>, + pub vkeywitness: Option>, #[n(1)] - pub native_script: Option>, + pub native_script: Option>, #[n(2)] - pub bootstrap_witness: Option>, + pub bootstrap_witness: Option>, #[n(3)] - pub plutus_v1_script: Option>, + pub plutus_v1_script: Option>, #[n(4)] - pub plutus_data: Option>, + pub plutus_data: Option>, #[n(5)] - pub redeemer: Option>, + pub redeemer: Option>, #[n(6)] - pub plutus_v2_script: Option>, + pub plutus_v2_script: Option>, } -#[derive(Encode, Decode, Debug, PartialEq, Clone)] +#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Clone)] #[cbor(map)] pub struct PostAlonzoAuxiliaryData { #[n(0)] pub metadata: Option, #[n(1)] - pub native_scripts: Option>, + pub native_scripts: Option>, #[n(2)] - pub plutus_v1_scripts: Option>, + pub plutus_v1_scripts: Option>, #[n(3)] - pub plutus_v2_scripts: Option>, + pub plutus_v2_scripts: Option>, } pub type DatumHash = Hash<32>; @@ -415,7 +419,7 @@ pub type DatumHash = Hash<32>; pub type Data = CborWrap; // datum_option = [ 0, $hash32 // 1, data ] -#[derive(Debug, PartialEq, Clone)] +#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)] pub enum DatumOption { Hash(Hash<32>), Data(Data), @@ -457,7 +461,7 @@ impl minicbor::Encode for DatumOption { pub type ScriptRef = CborWrap