refactor: Re-organize and clean-up pallas-primitives (#523)
* Re-organize and clean-up pallas-primitives
Namely:
- Move _common_ (i.e. era-independent) types and structures up to the
`lib` module; to be shared across all eras. If any of those deviate
in a subsequent era, it is easy to bring them down and define new
types from the point of divergence onward. This simplifies the scope
of each era-specific module and make them slightly easier to
navigate.
Note that, each era module still re-export all of the common types
that's relevant to that particular era. So technically, this
reorganization doesn't really change anything for callers/users of
the library.
- Rename `Scripthash` to `ScriptHash`. Before this commit, both
actually existed as `ScriptHash` was introduced with the Conway era.
Yet, they refer to the same thing, so the duplication is simply
confusing.
- Rename `One` / `Two` constructors for `NetworkId` to `Testnet` and
`Mainnet` respectively. Also defined idiomatic `From` & `TryFrom`
implementation for conversion to and from `u8`. This is a lot let
confusing!
- Generalize `PlutusScript` with a constant generic, to avoid
repetition for each plutus script generated for specific version.
Note that a distinction is still _necessary_ if we want to provie
out-of-the-box serialisers for Plutus scripts, which are serialised
with a tag prefix depending on the language. All else apart, they
are strictly similar types.
- Rename `CostMdls` to `CostModels`. Because, common.
- Rename `plutus_script` to `plutus_v1_script` in the Alonzo's witness
set, for consistency with other eras.
* Fix ordering of ScriptHash variants.
This is an odd one. See the note.
* Bump minicbor to v0.25.1
* Add aliases with deprecation warnings to various fields and types.
* revert renaming plutus_script to plutus_v1_script in Alonzo witness
See https://github.com/txpipe/pallas/pull/523#discussion_r1807329742
This commit is contained in:
parent
4871342a8d
commit
969d5612b7
26 changed files with 972 additions and 1071 deletions
|
|
@ -3,18 +3,17 @@
|
|||
//! 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 serde::{Deserialize, Serialize};
|
||||
use std::{fmt, hash::Hash as StdHash, ops::Deref};
|
||||
|
||||
use pallas_codec::minicbor::{data::Tag, Decode, Encode};
|
||||
use pallas_crypto::hash::Hash;
|
||||
use pallas_codec::minicbor::{self, data::Tag, Decode, Encode};
|
||||
|
||||
use pallas_codec::utils::{Bytes, Int, KeepRaw, KeyValuePairs, MaybeIndefArray, Nullable};
|
||||
|
||||
// required for derive attrs to work
|
||||
use pallas_codec::minicbor;
|
||||
|
||||
#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)]
|
||||
pub struct VrfCert(#[n(0)] pub Bytes, #[n(1)] pub Bytes);
|
||||
pub use crate::{
|
||||
plutus_data::*, AddrKeyhash, AssetName, Bytes, Coin, CostModel, DatumHash, DnsName, Epoch,
|
||||
ExUnitPrices, ExUnits, GenesisDelegateHash, Genesishash, Hash, IPv4, IPv6, Int, KeepRaw,
|
||||
KeyValuePairs, MaybeIndefArray, Metadata, Metadatum, MetadatumLabel, NetworkId, Nonce,
|
||||
NonceVariant, Nullable, PlutusScript, PolicyId, PoolKeyhash, PoolMetadata, PoolMetadataHash,
|
||||
Port, PositiveInterval, ProtocolVersion, RationalNumber, Relay, RewardAccount, ScriptHash,
|
||||
StakeCredential, TransactionIndex, TransactionInput, UnitInterval, VrfCert, VrfKeyhash,
|
||||
};
|
||||
|
||||
#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)]
|
||||
pub struct HeaderBody {
|
||||
|
|
@ -64,11 +63,6 @@ pub struct HeaderBody {
|
|||
pub protocol_minor: u64,
|
||||
}
|
||||
|
||||
pub type ProtocolVersion = (u64, u64);
|
||||
|
||||
#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq)]
|
||||
pub struct KesSignature {}
|
||||
|
||||
pub type MintedHeaderBody<'a> = KeepRaw<'a, HeaderBody>;
|
||||
|
||||
#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)]
|
||||
|
|
@ -100,50 +94,10 @@ impl<'a> From<MintedHeaderBody<'a>> for HeaderBody {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(
|
||||
Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, PartialOrd, Ord, Clone, StdHash,
|
||||
)]
|
||||
pub struct TransactionInput {
|
||||
#[n(0)]
|
||||
pub transaction_id: Hash<32>,
|
||||
|
||||
#[n(1)]
|
||||
pub index: u64,
|
||||
}
|
||||
|
||||
// $nonce /= [ 0 // 1, bytes .size 32 ]
|
||||
|
||||
#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)]
|
||||
#[cbor(index_only)]
|
||||
pub enum NonceVariant {
|
||||
#[n(0)]
|
||||
NeutralNonce,
|
||||
|
||||
#[n(1)]
|
||||
Nonce,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)]
|
||||
pub struct Nonce {
|
||||
#[n(0)]
|
||||
pub variant: NonceVariant,
|
||||
|
||||
#[n(1)]
|
||||
pub hash: Option<Hash<32>>,
|
||||
}
|
||||
|
||||
pub type ScriptHash = Hash<28>;
|
||||
|
||||
pub type PolicyId = Hash<28>;
|
||||
|
||||
pub type AssetName = Bytes;
|
||||
|
||||
pub type Multiasset<A> = KeyValuePairs<PolicyId, KeyValuePairs<AssetName, A>>;
|
||||
|
||||
pub type Mint = Multiasset<i64>;
|
||||
|
||||
pub type Coin = u64;
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
|
||||
pub enum Value {
|
||||
Coin(Coin),
|
||||
|
|
@ -201,15 +155,9 @@ pub struct TransactionOutput {
|
|||
pub amount: Value,
|
||||
|
||||
#[n(2)]
|
||||
pub datum_hash: Option<Hash<32>>,
|
||||
pub datum_hash: Option<DatumHash>,
|
||||
}
|
||||
|
||||
pub type PoolKeyhash = Hash<28>;
|
||||
pub type Epoch = u64;
|
||||
pub type Genesishash = Bytes;
|
||||
pub type GenesisDelegateHash = Bytes;
|
||||
pub type VrfKeyhash = Hash<32>;
|
||||
|
||||
/* move_instantaneous_reward = [ 0 / 1, { * stake_credential => delta_coin } / coin ]
|
||||
; The first field determines where the funds are drawn from.
|
||||
; 0 denotes the reserves, 1 denotes the treasury.
|
||||
|
|
@ -298,7 +246,7 @@ impl<C> minicbor::encode::Encode<C> for InstantaneousRewardTarget {
|
|||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
|
||||
#[cbor]
|
||||
#[cbor()]
|
||||
pub struct MoveInstantaneousReward {
|
||||
#[n(0)]
|
||||
pub source: InstantaneousRewardSource,
|
||||
|
|
@ -307,180 +255,10 @@ pub struct MoveInstantaneousReward {
|
|||
pub target: InstantaneousRewardTarget,
|
||||
}
|
||||
|
||||
pub type RewardAccount = Bytes;
|
||||
|
||||
pub type Withdrawals = KeyValuePairs<RewardAccount, Coin>;
|
||||
|
||||
pub type RequiredSigners = Vec<AddrKeyhash>;
|
||||
|
||||
pub type Port = u32;
|
||||
pub type IPv4 = Bytes;
|
||||
pub type IPv6 = Bytes;
|
||||
pub type DnsName = String;
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
|
||||
pub enum Relay {
|
||||
SingleHostAddr(Nullable<Port>, Nullable<IPv4>, Nullable<IPv6>),
|
||||
SingleHostName(Nullable<Port>, DnsName),
|
||||
MultiHostName(DnsName),
|
||||
}
|
||||
|
||||
impl<'b, C> minicbor::decode::Decode<'b, C> for Relay {
|
||||
fn decode(d: &mut minicbor::Decoder<'b>, ctx: &mut C) -> Result<Self, minicbor::decode::Error> {
|
||||
d.array()?;
|
||||
let variant = d.u16()?;
|
||||
|
||||
match variant {
|
||||
0 => Ok(Relay::SingleHostAddr(
|
||||
d.decode_with(ctx)?,
|
||||
d.decode_with(ctx)?,
|
||||
d.decode_with(ctx)?,
|
||||
)),
|
||||
1 => Ok(Relay::SingleHostName(
|
||||
d.decode_with(ctx)?,
|
||||
d.decode_with(ctx)?,
|
||||
)),
|
||||
2 => Ok(Relay::MultiHostName(d.decode_with(ctx)?)),
|
||||
_ => Err(minicbor::decode::Error::message(
|
||||
"invalid variant id for Relay",
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<C> minicbor::encode::Encode<C> for Relay {
|
||||
fn encode<W: minicbor::encode::Write>(
|
||||
&self,
|
||||
e: &mut minicbor::Encoder<W>,
|
||||
ctx: &mut C,
|
||||
) -> Result<(), minicbor::encode::Error<W::Error>> {
|
||||
match self {
|
||||
Relay::SingleHostAddr(a, b, c) => {
|
||||
e.array(4)?;
|
||||
e.encode_with(0, ctx)?;
|
||||
e.encode_with(a, ctx)?;
|
||||
e.encode_with(b, ctx)?;
|
||||
e.encode_with(c, ctx)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Relay::SingleHostName(a, b) => {
|
||||
e.array(3)?;
|
||||
e.encode_with(1, ctx)?;
|
||||
e.encode_with(a, ctx)?;
|
||||
e.encode_with(b, ctx)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Relay::MultiHostName(a) => {
|
||||
e.array(2)?;
|
||||
e.encode_with(2, ctx)?;
|
||||
e.encode_with(a, ctx)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub type PoolMetadataHash = Hash<32>;
|
||||
|
||||
#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)]
|
||||
pub struct PoolMetadata {
|
||||
#[n(0)]
|
||||
pub url: String,
|
||||
|
||||
#[n(1)]
|
||||
pub hash: PoolMetadataHash,
|
||||
}
|
||||
|
||||
pub type AddrKeyhash = Hash<28>;
|
||||
pub type Scripthash = Hash<28>;
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
|
||||
pub struct RationalNumber {
|
||||
pub numerator: u64,
|
||||
pub denominator: u64,
|
||||
}
|
||||
|
||||
impl<'b, C> minicbor::decode::Decode<'b, C> for RationalNumber {
|
||||
fn decode(d: &mut minicbor::Decoder<'b>, ctx: &mut C) -> Result<Self, minicbor::decode::Error> {
|
||||
d.tag()?;
|
||||
d.array()?;
|
||||
|
||||
Ok(RationalNumber {
|
||||
numerator: d.decode_with(ctx)?,
|
||||
denominator: d.decode_with(ctx)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<C> minicbor::encode::Encode<C> for RationalNumber {
|
||||
fn encode<W: minicbor::encode::Write>(
|
||||
&self,
|
||||
e: &mut minicbor::Encoder<W>,
|
||||
ctx: &mut C,
|
||||
) -> Result<(), minicbor::encode::Error<W::Error>> {
|
||||
// TODO: check if this is the correct tag
|
||||
e.tag(Tag::Unassigned(30))?;
|
||||
e.array(2)?;
|
||||
e.encode_with(self.numerator, ctx)?;
|
||||
e.encode_with(self.denominator, ctx)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub type UnitInterval = RationalNumber;
|
||||
|
||||
pub type PositiveInterval = RationalNumber;
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, PartialEq, PartialOrd, Eq, Ord, Clone, Hash)]
|
||||
pub enum StakeCredential {
|
||||
AddrKeyhash(AddrKeyhash),
|
||||
Scripthash(Scripthash),
|
||||
}
|
||||
|
||||
impl<'b, C> minicbor::decode::Decode<'b, C> for StakeCredential {
|
||||
fn decode(d: &mut minicbor::Decoder<'b>, ctx: &mut C) -> Result<Self, minicbor::decode::Error> {
|
||||
d.array()?;
|
||||
let variant = d.u16()?;
|
||||
|
||||
match variant {
|
||||
0 => Ok(StakeCredential::AddrKeyhash(d.decode_with(ctx)?)),
|
||||
1 => Ok(StakeCredential::Scripthash(d.decode_with(ctx)?)),
|
||||
_ => Err(minicbor::decode::Error::message(
|
||||
"invalid variant id for StakeCredential",
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<C> minicbor::encode::Encode<C> for StakeCredential {
|
||||
fn encode<W: minicbor::encode::Write>(
|
||||
&self,
|
||||
e: &mut minicbor::Encoder<W>,
|
||||
ctx: &mut C,
|
||||
) -> Result<(), minicbor::encode::Error<W::Error>> {
|
||||
match self {
|
||||
StakeCredential::AddrKeyhash(a) => {
|
||||
e.array(2)?;
|
||||
e.encode_with(0, ctx)?;
|
||||
e.encode_with(a, ctx)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
StakeCredential::Scripthash(a) => {
|
||||
e.array(2)?;
|
||||
e.encode_with(1, ctx)?;
|
||||
e.encode_with(a, ctx)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
|
||||
pub enum Certificate {
|
||||
StakeRegistration(StakeCredential),
|
||||
|
|
@ -649,17 +427,6 @@ impl<C> minicbor::encode::Encode<C> for Certificate {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(
|
||||
Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy,
|
||||
)]
|
||||
#[cbor(index_only)]
|
||||
pub enum NetworkId {
|
||||
#[n(0)]
|
||||
One,
|
||||
#[n(1)]
|
||||
Two,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
|
||||
#[cbor(index_only)]
|
||||
pub enum Language {
|
||||
|
|
@ -667,9 +434,10 @@ pub enum Language {
|
|||
PlutusV1,
|
||||
}
|
||||
|
||||
pub type CostModel = Vec<i64>;
|
||||
#[deprecated(since = "0.31.0", note = "use `CostModels` instead")]
|
||||
pub type CostMdls = CostModels;
|
||||
|
||||
pub type CostMdls = KeyValuePairs<Language, CostModel>;
|
||||
pub type CostModels = KeyValuePairs<Language, CostModel>;
|
||||
|
||||
#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)]
|
||||
#[cbor(map)]
|
||||
|
|
@ -709,7 +477,7 @@ pub struct ProtocolParamUpdate {
|
|||
#[n(17)]
|
||||
pub ada_per_utxo_byte: Option<Coin>,
|
||||
#[n(18)]
|
||||
pub cost_models_for_script_languages: Option<CostMdls>,
|
||||
pub cost_models_for_script_languages: Option<CostModels>,
|
||||
#[n(19)]
|
||||
pub execution_costs: Option<ExUnitPrices>,
|
||||
#[n(20)]
|
||||
|
|
@ -862,380 +630,6 @@ impl<C> minicbor::encode::Encode<C> for NativeScript {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)]
|
||||
#[cbor(transparent)]
|
||||
pub struct PlutusScript(#[n(0)] pub Bytes);
|
||||
|
||||
impl AsRef<[u8]> for PlutusScript {
|
||||
fn as_ref(&self) -> &[u8] {
|
||||
self.0.as_slice()
|
||||
}
|
||||
}
|
||||
|
||||
/// Defined to encode PlutusData bytestring as it is done in the canonical
|
||||
/// plutus implementation
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
|
||||
#[serde(into = "String")]
|
||||
#[serde(try_from = "String")]
|
||||
pub struct BoundedBytes(Vec<u8>);
|
||||
|
||||
impl From<Vec<u8>> for BoundedBytes {
|
||||
fn from(xs: Vec<u8>) -> Self {
|
||||
BoundedBytes(xs)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<BoundedBytes> for Vec<u8> {
|
||||
fn from(b: BoundedBytes) -> Self {
|
||||
b.0
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for BoundedBytes {
|
||||
type Target = Vec<u8>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<String> for BoundedBytes {
|
||||
type Error = hex::FromHexError;
|
||||
|
||||
fn try_from(value: String) -> Result<Self, Self::Error> {
|
||||
let v = hex::decode(value)?;
|
||||
Ok(BoundedBytes(v))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<BoundedBytes> for String {
|
||||
fn from(b: BoundedBytes) -> Self {
|
||||
hex::encode(b.deref())
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for BoundedBytes {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let bytes: Vec<u8> = self.clone().into();
|
||||
|
||||
f.write_str(&hex::encode(bytes))
|
||||
}
|
||||
}
|
||||
|
||||
impl<C> Encode<C> for BoundedBytes {
|
||||
fn encode<W: minicbor::encode::Write>(
|
||||
&self,
|
||||
e: &mut minicbor::Encoder<W>,
|
||||
_: &mut C,
|
||||
) -> Result<(), minicbor::encode::Error<W::Error>> {
|
||||
// we match the haskell implementation by encoding bytestrings longer than 64
|
||||
// bytes as indefinite lists of bytes
|
||||
const CHUNK_SIZE: usize = 64;
|
||||
let bs: &Vec<u8> = self.deref();
|
||||
if bs.len() <= 64 {
|
||||
e.bytes(bs)?;
|
||||
} else {
|
||||
e.begin_bytes()?;
|
||||
for b in bs.chunks(CHUNK_SIZE) {
|
||||
e.bytes(b)?;
|
||||
}
|
||||
e.end()?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'b, C> minicbor::decode::Decode<'b, C> for BoundedBytes {
|
||||
fn decode(d: &mut minicbor::Decoder<'b>, _: &mut C) -> Result<Self, minicbor::decode::Error> {
|
||||
let mut res = Vec::new();
|
||||
for chunk in d.bytes_iter()? {
|
||||
let bs = chunk?;
|
||||
res.extend_from_slice(bs);
|
||||
}
|
||||
Ok(BoundedBytes::from(res))
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
big_int = int / big_uint / big_nint ; New
|
||||
big_uint = #6.2(bounded_bytes) ; New
|
||||
big_nint = #6.3(bounded_bytes) ; New
|
||||
*/
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
|
||||
pub enum BigInt {
|
||||
Int(Int),
|
||||
BigUInt(BoundedBytes),
|
||||
BigNInt(BoundedBytes),
|
||||
}
|
||||
|
||||
impl<'b, C> minicbor::decode::Decode<'b, C> for BigInt {
|
||||
fn decode(d: &mut minicbor::Decoder<'b>, ctx: &mut C) -> Result<Self, minicbor::decode::Error> {
|
||||
let datatype = d.datatype()?;
|
||||
|
||||
match datatype {
|
||||
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 => Ok(Self::Int(d.decode_with(ctx)?)),
|
||||
minicbor::data::Type::Tag => {
|
||||
let tag = d.tag()?;
|
||||
|
||||
match tag {
|
||||
minicbor::data::Tag::PosBignum => Ok(Self::BigUInt(d.decode_with(ctx)?)),
|
||||
minicbor::data::Tag::NegBignum => Ok(Self::BigNInt(d.decode_with(ctx)?)),
|
||||
_ => Err(minicbor::decode::Error::message(
|
||||
"invalid cbor tag for big int",
|
||||
)),
|
||||
}
|
||||
}
|
||||
_ => Err(minicbor::decode::Error::message(
|
||||
"invalid cbor data type for big int",
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<C> minicbor::encode::Encode<C> for BigInt {
|
||||
fn encode<W: minicbor::encode::Write>(
|
||||
&self,
|
||||
e: &mut minicbor::Encoder<W>,
|
||||
ctx: &mut C,
|
||||
) -> Result<(), minicbor::encode::Error<W::Error>> {
|
||||
match self {
|
||||
BigInt::Int(x) => {
|
||||
e.encode_with(x, ctx)?;
|
||||
}
|
||||
BigInt::BigUInt(x) => {
|
||||
e.tag(Tag::PosBignum)?;
|
||||
e.encode_with(x, ctx)?;
|
||||
}
|
||||
BigInt::BigNInt(x) => {
|
||||
e.tag(Tag::NegBignum)?;
|
||||
e.encode_with(x, ctx)?;
|
||||
}
|
||||
};
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
|
||||
pub enum PlutusData {
|
||||
Constr(Constr<PlutusData>),
|
||||
Map(KeyValuePairs<PlutusData, PlutusData>),
|
||||
BigInt(BigInt),
|
||||
BoundedBytes(BoundedBytes),
|
||||
Array(Vec<PlutusData>),
|
||||
}
|
||||
|
||||
impl<'b, C> minicbor::decode::Decode<'b, C> for PlutusData {
|
||||
fn decode(d: &mut minicbor::Decoder<'b>, ctx: &mut C) -> Result<Self, minicbor::decode::Error> {
|
||||
let type_ = d.datatype()?;
|
||||
|
||||
match type_ {
|
||||
minicbor::data::Type::Tag => {
|
||||
let mut probe = d.probe();
|
||||
let tag = probe.tag()?;
|
||||
|
||||
match tag {
|
||||
Tag::Unassigned(121..=127 | 1280..=1400 | 102) => {
|
||||
Ok(Self::Constr(d.decode_with(ctx)?))
|
||||
}
|
||||
Tag::PosBignum | Tag::NegBignum => Ok(Self::BigInt(d.decode_with(ctx)?)),
|
||||
_ => Err(minicbor::decode::Error::message(
|
||||
"unknown tag for plutus data tag",
|
||||
)),
|
||||
}
|
||||
}
|
||||
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 => Ok(Self::BigInt(d.decode_with(ctx)?)),
|
||||
minicbor::data::Type::Map | minicbor::data::Type::MapIndef => {
|
||||
Ok(Self::Map(d.decode_with(ctx)?))
|
||||
}
|
||||
minicbor::data::Type::Bytes => Ok(Self::BoundedBytes(d.decode_with(ctx)?)),
|
||||
minicbor::data::Type::BytesIndef => {
|
||||
let mut full = Vec::new();
|
||||
|
||||
for slice in d.bytes_iter()? {
|
||||
full.extend(slice?);
|
||||
}
|
||||
|
||||
Ok(Self::BoundedBytes(BoundedBytes::from(full)))
|
||||
}
|
||||
minicbor::data::Type::Array | minicbor::data::Type::ArrayIndef => {
|
||||
Ok(Self::Array(d.decode_with(ctx)?))
|
||||
}
|
||||
|
||||
any => Err(minicbor::decode::Error::message(format!(
|
||||
"bad cbor data type ({any:?}) for plutus data"
|
||||
))),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn encode_list<C, W: minicbor::encode::Write, A: minicbor::encode::Encode<C>>(
|
||||
a: &Vec<A>,
|
||||
e: &mut minicbor::Encoder<W>,
|
||||
ctx: &mut C,
|
||||
) -> Result<(), minicbor::encode::Error<W::Error>> {
|
||||
// Mimics default haskell list encoding from cborg:
|
||||
// We use indef array for non-empty arrays but definite 0-length array for empty
|
||||
if a.is_empty() {
|
||||
e.array(0)?;
|
||||
} else {
|
||||
e.begin_array()?;
|
||||
for v in a {
|
||||
e.encode_with(v, ctx)?;
|
||||
}
|
||||
e.end()?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
impl<C> minicbor::encode::Encode<C> for PlutusData {
|
||||
fn encode<W: minicbor::encode::Write>(
|
||||
&self,
|
||||
e: &mut minicbor::Encoder<W>,
|
||||
ctx: &mut C,
|
||||
) -> Result<(), minicbor::encode::Error<W::Error>> {
|
||||
match self {
|
||||
Self::Constr(a) => {
|
||||
e.encode_with(a, ctx)?;
|
||||
}
|
||||
Self::Map(a) => {
|
||||
// we use definite array to match the approach used by haskell's plutus
|
||||
// implementation https://github.com/input-output-hk/plutus/blob/9538fc9829426b2ecb0628d352e2d7af96ec8204/plutus-core/plutus-core/src/PlutusCore/Data.hs#L152
|
||||
e.map(a.len().try_into().unwrap())?;
|
||||
for (k, v) in a.iter() {
|
||||
k.encode(e, ctx)?;
|
||||
v.encode(e, ctx)?;
|
||||
}
|
||||
}
|
||||
Self::BigInt(a) => {
|
||||
e.encode_with(a, ctx)?;
|
||||
}
|
||||
Self::BoundedBytes(a) => {
|
||||
e.encode_with(a, ctx)?;
|
||||
}
|
||||
Self::Array(a) => {
|
||||
// we use definite array for empty array or indef array otherwise to match
|
||||
// haskell implementation https://github.com/input-output-hk/plutus/blob/9538fc9829426b2ecb0628d352e2d7af96ec8204/plutus-core/plutus-core/src/PlutusCore/Data.hs#L153
|
||||
// default encoder for a list:
|
||||
// https://github.com/well-typed/cborg/blob/4bdc818a1f0b35f38bc118a87944630043b58384/serialise/src/Codec/Serialise/Class.hs#L181
|
||||
encode_list(a, e, ctx)?;
|
||||
}
|
||||
};
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
|
||||
pub struct Constr<A> {
|
||||
pub tag: u64,
|
||||
pub any_constructor: Option<u64>,
|
||||
pub fields: Vec<A>,
|
||||
}
|
||||
|
||||
impl<'b, C, A> minicbor::decode::Decode<'b, C> for Constr<A>
|
||||
where
|
||||
A: minicbor::decode::Decode<'b, C>,
|
||||
{
|
||||
fn decode(d: &mut minicbor::Decoder<'b>, ctx: &mut C) -> Result<Self, minicbor::decode::Error> {
|
||||
let tag = d.tag()?;
|
||||
|
||||
match tag {
|
||||
Tag::Unassigned(x) => match x {
|
||||
121..=127 | 1280..=1400 => Ok(Constr {
|
||||
tag: x,
|
||||
fields: d.decode_with(ctx)?,
|
||||
any_constructor: None,
|
||||
}),
|
||||
102 => {
|
||||
d.array()?;
|
||||
|
||||
Ok(Constr {
|
||||
tag: x,
|
||||
any_constructor: Some(d.decode_with(ctx)?),
|
||||
fields: d.decode_with(ctx)?,
|
||||
})
|
||||
}
|
||||
_ => Err(minicbor::decode::Error::message(
|
||||
"bad tag code for plutus data",
|
||||
)),
|
||||
},
|
||||
_ => Err(minicbor::decode::Error::message(
|
||||
"bad tag code for plutus data",
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<C, A> minicbor::encode::Encode<C> for Constr<A>
|
||||
where
|
||||
A: minicbor::encode::Encode<C>,
|
||||
{
|
||||
fn encode<W: minicbor::encode::Write>(
|
||||
&self,
|
||||
e: &mut minicbor::Encoder<W>,
|
||||
ctx: &mut C,
|
||||
) -> Result<(), minicbor::encode::Error<W::Error>> {
|
||||
e.tag(Tag::Unassigned(self.tag))?;
|
||||
|
||||
match self.tag {
|
||||
102 => {
|
||||
// definite length array here
|
||||
// https://github.com/input-output-hk/plutus/blob/9538fc9829426b2ecb0628d352e2d7af96ec8204/plutus-core/plutus-core/src/PlutusCore/Data.hs#L152
|
||||
e.array(2)?;
|
||||
e.encode_with(self.any_constructor.unwrap_or_default(), ctx)?;
|
||||
|
||||
// we use definite array for empty array or indef array otherwise to match
|
||||
// haskell implementation https://github.com/input-output-hk/plutus/blob/9538fc9829426b2ecb0628d352e2d7af96ec8204/plutus-core/plutus-core/src/PlutusCore/Data.hs#L144
|
||||
// default encoder for a list:
|
||||
// https://github.com/well-typed/cborg/blob/4bdc818a1f0b35f38bc118a87944630043b58384/serialise/src/Codec/Serialise/Class.hs#L181
|
||||
encode_list(&self.fields, e, ctx)?;
|
||||
Ok(())
|
||||
}
|
||||
_ => {
|
||||
// we use definite array for empty array or indef array otherwise to match
|
||||
// haskell implementation. See above reference.
|
||||
encode_list(&self.fields, e, ctx)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone, Copy)]
|
||||
pub struct ExUnits {
|
||||
#[n(0)]
|
||||
pub mem: u64,
|
||||
#[n(1)]
|
||||
pub steps: u64,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)]
|
||||
pub struct ExUnitPrices {
|
||||
#[n(0)]
|
||||
pub mem_price: PositiveInterval,
|
||||
|
||||
#[n(1)]
|
||||
pub step_price: PositiveInterval,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone, Copy)]
|
||||
#[cbor(index_only)]
|
||||
pub enum RedeemerTag {
|
||||
|
|
@ -1308,7 +702,7 @@ pub struct WitnessSet {
|
|||
pub bootstrap_witness: Option<Vec<BootstrapWitness>>,
|
||||
|
||||
#[n(3)]
|
||||
pub plutus_script: Option<Vec<PlutusScript>>,
|
||||
pub plutus_script: Option<Vec<PlutusScript<1>>>,
|
||||
|
||||
#[n(4)]
|
||||
pub plutus_data: Option<Vec<PlutusData>>,
|
||||
|
|
@ -1330,7 +724,7 @@ pub struct MintedWitnessSet<'b> {
|
|||
pub bootstrap_witness: Option<Vec<BootstrapWitness>>,
|
||||
|
||||
#[n(3)]
|
||||
pub plutus_script: Option<Vec<PlutusScript>>,
|
||||
pub plutus_script: Option<Vec<PlutusScript<1>>>,
|
||||
|
||||
#[b(4)]
|
||||
pub plutus_data: Option<Vec<KeepRaw<'b, PlutusData>>>,
|
||||
|
|
@ -1340,6 +734,7 @@ pub struct MintedWitnessSet<'b> {
|
|||
}
|
||||
|
||||
impl<'b> From<MintedWitnessSet<'b>> for WitnessSet {
|
||||
#[allow(deprecated)]
|
||||
fn from(x: MintedWitnessSet<'b>) -> Self {
|
||||
WitnessSet {
|
||||
vkeywitness: x.vkeywitness,
|
||||
|
|
@ -1366,80 +761,9 @@ pub struct PostAlonzoAuxiliaryData {
|
|||
pub native_scripts: Option<Vec<NativeScript>>,
|
||||
|
||||
#[n(2)]
|
||||
pub plutus_scripts: Option<Vec<PlutusScript>>,
|
||||
pub plutus_scripts: Option<Vec<PlutusScript<1>>>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
|
||||
pub enum Metadatum {
|
||||
Int(Int),
|
||||
Bytes(Bytes),
|
||||
Text(String),
|
||||
Array(Vec<Metadatum>),
|
||||
Map(KeyValuePairs<Metadatum, Metadatum>),
|
||||
}
|
||||
|
||||
impl<'b, C> minicbor::Decode<'b, C> for Metadatum {
|
||||
fn decode(d: &mut minicbor::Decoder<'b>, ctx: &mut C) -> Result<Self, minicbor::decode::Error> {
|
||||
match d.datatype()? {
|
||||
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)?)),
|
||||
minicbor::data::Type::String => Ok(Metadatum::Text(d.decode_with(ctx)?)),
|
||||
minicbor::data::Type::Array | minicbor::data::Type::ArrayIndef => {
|
||||
Ok(Metadatum::Array(d.decode_with(ctx)?))
|
||||
}
|
||||
minicbor::data::Type::Map | minicbor::data::Type::MapIndef => {
|
||||
Ok(Metadatum::Map(d.decode_with(ctx)?))
|
||||
}
|
||||
_ => Err(minicbor::decode::Error::message(
|
||||
"Can't turn data type into metadatum",
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<C> minicbor::Encode<C> for Metadatum {
|
||||
fn encode<W: minicbor::encode::Write>(
|
||||
&self,
|
||||
e: &mut minicbor::Encoder<W>,
|
||||
ctx: &mut C,
|
||||
) -> Result<(), minicbor::encode::Error<W::Error>> {
|
||||
match self {
|
||||
Metadatum::Int(a) => {
|
||||
e.encode_with(a, ctx)?;
|
||||
}
|
||||
Metadatum::Bytes(a) => {
|
||||
e.encode_with(a, ctx)?;
|
||||
}
|
||||
Metadatum::Text(a) => {
|
||||
e.encode_with(a, ctx)?;
|
||||
}
|
||||
Metadatum::Array(a) => {
|
||||
e.encode_with(a, ctx)?;
|
||||
}
|
||||
Metadatum::Map(a) => {
|
||||
e.encode_with(a, ctx)?;
|
||||
}
|
||||
};
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub type MetadatumLabel = u64;
|
||||
|
||||
pub type Metadata = KeyValuePairs<MetadatumLabel, Metadatum>;
|
||||
|
||||
#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Clone)]
|
||||
pub struct ShelleyMaAuxiliaryData {
|
||||
#[n(0)]
|
||||
|
|
@ -1489,7 +813,7 @@ impl<C> minicbor::Encode<C> for AuxiliaryData {
|
|||
}
|
||||
AuxiliaryData::PostAlonzo(v) => {
|
||||
// TODO: check if this is the correct tag
|
||||
e.tag(Tag::Unassigned(259))?;
|
||||
e.tag(Tag::new(259))?;
|
||||
e.encode_with(v, ctx)?;
|
||||
}
|
||||
};
|
||||
|
|
@ -1498,8 +822,6 @@ impl<C> minicbor::Encode<C> for AuxiliaryData {
|
|||
}
|
||||
}
|
||||
|
||||
pub type TransactionIndex = u32;
|
||||
|
||||
#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Clone)]
|
||||
pub struct Block {
|
||||
#[n(0)]
|
||||
|
|
|
|||
|
|
@ -4,15 +4,19 @@
|
|||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use pallas_codec::minicbor::{Decode, Encode};
|
||||
use pallas_codec::{
|
||||
minicbor::{self, Decode, Encode},
|
||||
utils::{Bytes, CborWrap, KeepRaw, KeyValuePairs, MaybeIndefArray, Nullable},
|
||||
};
|
||||
use pallas_crypto::hash::{Hash, Hasher};
|
||||
|
||||
use pallas_codec::utils::{Bytes, CborWrap, KeepRaw, KeyValuePairs, MaybeIndefArray, Nullable};
|
||||
|
||||
// required for derive attrs to work
|
||||
use pallas_codec::minicbor;
|
||||
|
||||
use crate::alonzo::VrfCert;
|
||||
pub use crate::{
|
||||
plutus_data::*, AddrKeyhash, AssetName, DatumHash, DnsName, Epoch, ExUnitPrices, ExUnits,
|
||||
GenesisDelegateHash, Genesishash, IPv4, IPv6, Metadata, Metadatum, MetadatumLabel, NetworkId,
|
||||
Nonce, NonceVariant, PlutusScript, PolicyId, PoolKeyhash, PoolMetadata, PoolMetadataHash, Port,
|
||||
PositiveInterval, ProtocolVersion, RationalNumber, Relay, ScriptHash, StakeCredential,
|
||||
TransactionIndex, TransactionInput, UnitInterval, VrfCert, VrfKeyhash,
|
||||
};
|
||||
|
||||
#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)]
|
||||
pub struct HeaderBody {
|
||||
|
|
@ -62,10 +66,6 @@ pub struct OperationalCert {
|
|||
pub operational_cert_sigma: Bytes,
|
||||
}
|
||||
|
||||
pub use crate::alonzo::ProtocolVersion;
|
||||
|
||||
pub use crate::alonzo::KesSignature;
|
||||
|
||||
pub type MintedHeaderBody<'a> = KeepRaw<'a, HeaderBody>;
|
||||
|
||||
#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)]
|
||||
|
|
@ -97,18 +97,6 @@ impl<'a> From<MintedHeaderBody<'a>> for HeaderBody {
|
|||
}
|
||||
}
|
||||
|
||||
pub use crate::alonzo::TransactionInput;
|
||||
|
||||
pub use crate::alonzo::NonceVariant;
|
||||
|
||||
pub use crate::alonzo::Nonce;
|
||||
|
||||
pub use crate::alonzo::ScriptHash;
|
||||
|
||||
pub use crate::alonzo::PolicyId;
|
||||
|
||||
pub use crate::alonzo::AssetName;
|
||||
|
||||
pub use crate::alonzo::Multiasset;
|
||||
|
||||
pub use crate::alonzo::Mint;
|
||||
|
|
@ -119,16 +107,6 @@ pub use crate::alonzo::Value;
|
|||
|
||||
pub use crate::alonzo::TransactionOutput as LegacyTransactionOutput;
|
||||
|
||||
pub use crate::alonzo::PoolKeyhash;
|
||||
|
||||
pub use crate::alonzo::Epoch;
|
||||
|
||||
pub use crate::alonzo::Genesishash;
|
||||
|
||||
pub use crate::alonzo::GenesisDelegateHash;
|
||||
|
||||
pub use crate::alonzo::VrfKeyhash;
|
||||
|
||||
pub use crate::alonzo::InstantaneousRewardSource;
|
||||
|
||||
pub use crate::alonzo::InstantaneousRewardTarget;
|
||||
|
|
@ -137,40 +115,12 @@ pub use crate::alonzo::MoveInstantaneousReward;
|
|||
|
||||
pub use crate::alonzo::RewardAccount;
|
||||
|
||||
pub type Withdrawals = KeyValuePairs<RewardAccount, Coin>;
|
||||
pub use crate::alonzo::Withdrawals;
|
||||
|
||||
pub type RequiredSigners = Vec<AddrKeyhash>;
|
||||
|
||||
pub use crate::alonzo::Port;
|
||||
|
||||
pub use crate::alonzo::IPv4;
|
||||
|
||||
pub use crate::alonzo::IPv6;
|
||||
|
||||
pub use crate::alonzo::DnsName;
|
||||
|
||||
pub use crate::alonzo::Relay;
|
||||
|
||||
pub use crate::alonzo::PoolMetadataHash;
|
||||
|
||||
pub use crate::alonzo::PoolMetadata;
|
||||
|
||||
pub use crate::alonzo::AddrKeyhash;
|
||||
|
||||
pub use crate::alonzo::Scripthash;
|
||||
|
||||
pub use crate::alonzo::RationalNumber;
|
||||
|
||||
pub use crate::alonzo::UnitInterval;
|
||||
|
||||
pub use crate::alonzo::PositiveInterval;
|
||||
|
||||
pub use crate::alonzo::StakeCredential;
|
||||
pub use crate::alonzo::RequiredSigners;
|
||||
|
||||
pub use crate::alonzo::Certificate;
|
||||
|
||||
pub use crate::alonzo::NetworkId;
|
||||
|
||||
#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)]
|
||||
#[cbor(index_only)]
|
||||
pub enum Language {
|
||||
|
|
@ -181,11 +131,14 @@ pub enum Language {
|
|||
PlutusV2,
|
||||
}
|
||||
|
||||
#[deprecated(since = "0.31.0", note = "use `CostModels` instead")]
|
||||
pub type CostMdls = CostModels;
|
||||
|
||||
pub use crate::alonzo::CostModel;
|
||||
|
||||
#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)]
|
||||
#[cbor(map)]
|
||||
pub struct CostMdls {
|
||||
pub struct CostModels {
|
||||
#[n(0)]
|
||||
pub plutus_v1: Option<CostModel>,
|
||||
|
||||
|
|
@ -228,7 +181,7 @@ pub struct ProtocolParamUpdate {
|
|||
#[n(17)]
|
||||
pub ada_per_utxo_byte: Option<Coin>,
|
||||
#[n(18)]
|
||||
pub cost_models_for_script_languages: Option<CostMdls>,
|
||||
pub cost_models_for_script_languages: Option<CostModels>,
|
||||
#[n(19)]
|
||||
pub execution_costs: Option<ExUnitPrices>,
|
||||
#[n(20)]
|
||||
|
|
@ -455,28 +408,6 @@ pub use crate::alonzo::VKeyWitness;
|
|||
|
||||
pub use crate::alonzo::NativeScript;
|
||||
|
||||
pub use crate::alonzo::PlutusScript as PlutusV1Script;
|
||||
|
||||
#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)]
|
||||
#[cbor(transparent)]
|
||||
pub struct PlutusV2Script(#[n(0)] pub Bytes);
|
||||
|
||||
impl AsRef<[u8]> for PlutusV2Script {
|
||||
fn as_ref(&self) -> &[u8] {
|
||||
self.0.as_slice()
|
||||
}
|
||||
}
|
||||
|
||||
pub use crate::alonzo::BigInt;
|
||||
|
||||
pub use crate::alonzo::PlutusData;
|
||||
|
||||
pub use crate::alonzo::Constr;
|
||||
|
||||
pub use crate::alonzo::ExUnits;
|
||||
|
||||
pub use crate::alonzo::ExUnitPrices;
|
||||
|
||||
pub use crate::alonzo::RedeemerTag;
|
||||
|
||||
pub use crate::alonzo::Redeemer;
|
||||
|
|
@ -496,7 +427,7 @@ pub struct WitnessSet {
|
|||
pub bootstrap_witness: Option<Vec<BootstrapWitness>>,
|
||||
|
||||
#[n(3)]
|
||||
pub plutus_v1_script: Option<Vec<PlutusV1Script>>,
|
||||
pub plutus_v1_script: Option<Vec<PlutusScript<1>>>,
|
||||
|
||||
#[n(4)]
|
||||
pub plutus_data: Option<Vec<PlutusData>>,
|
||||
|
|
@ -505,7 +436,7 @@ pub struct WitnessSet {
|
|||
pub redeemer: Option<Vec<Redeemer>>,
|
||||
|
||||
#[n(6)]
|
||||
pub plutus_v2_script: Option<Vec<PlutusV2Script>>,
|
||||
pub plutus_v2_script: Option<Vec<PlutusScript<2>>>,
|
||||
}
|
||||
|
||||
#[derive(Encode, Decode, Debug, PartialEq, Clone)]
|
||||
|
|
@ -521,7 +452,7 @@ pub struct MintedWitnessSet<'b> {
|
|||
pub bootstrap_witness: Option<Vec<BootstrapWitness>>,
|
||||
|
||||
#[n(3)]
|
||||
pub plutus_v1_script: Option<Vec<PlutusV1Script>>,
|
||||
pub plutus_v1_script: Option<Vec<PlutusScript<1>>>,
|
||||
|
||||
#[b(4)]
|
||||
pub plutus_data: Option<Vec<KeepRaw<'b, PlutusData>>>,
|
||||
|
|
@ -530,7 +461,7 @@ pub struct MintedWitnessSet<'b> {
|
|||
pub redeemer: Option<Vec<Redeemer>>,
|
||||
|
||||
#[n(6)]
|
||||
pub plutus_v2_script: Option<Vec<PlutusV2Script>>,
|
||||
pub plutus_v2_script: Option<Vec<PlutusScript<2>>>,
|
||||
}
|
||||
|
||||
impl<'b> From<MintedWitnessSet<'b>> for WitnessSet {
|
||||
|
|
@ -561,20 +492,16 @@ pub struct PostAlonzoAuxiliaryData {
|
|||
pub native_scripts: Option<Vec<NativeScript>>,
|
||||
|
||||
#[n(2)]
|
||||
pub plutus_v1_scripts: Option<Vec<PlutusV1Script>>,
|
||||
pub plutus_v1_scripts: Option<Vec<PlutusScript<1>>>,
|
||||
|
||||
#[n(3)]
|
||||
pub plutus_v2_scripts: Option<Vec<PlutusV2Script>>,
|
||||
pub plutus_v2_scripts: Option<Vec<PlutusScript<2>>>,
|
||||
}
|
||||
|
||||
pub type DatumHash = Hash<32>;
|
||||
|
||||
//pub type Data = CborWrap<PlutusData>;
|
||||
|
||||
// datum_option = [ 0, $hash32 // 1, data ]
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
pub enum PseudoDatumOption<T1> {
|
||||
Hash(Hash<32>),
|
||||
Hash(DatumHash),
|
||||
Data(CborWrap<T1>),
|
||||
}
|
||||
|
||||
|
|
@ -626,12 +553,18 @@ impl<'b> From<MintedDatumOption<'b>> for DatumOption {
|
|||
}
|
||||
}
|
||||
|
||||
#[deprecated(since = "0.31.0", note = "use `PlutusScript<1>` instead")]
|
||||
pub type PlutusV1Script = PlutusScript<1>;
|
||||
|
||||
#[deprecated(since = "0.31.0", note = "use `PlutusScript<2>` instead")]
|
||||
pub type PlutusV2Script = PlutusScript<2>;
|
||||
|
||||
// script = [ 0, native_script // 1, plutus_v1_script // 2, plutus_v2_script ]
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
pub enum PseudoScript<T1> {
|
||||
NativeScript(T1),
|
||||
PlutusV1Script(PlutusV1Script),
|
||||
PlutusV2Script(PlutusV2Script),
|
||||
PlutusV1Script(PlutusScript<1>),
|
||||
PlutusV2Script(PlutusScript<2>),
|
||||
}
|
||||
|
||||
// script_ref = #6.24(bytes .cbor script)
|
||||
|
|
@ -689,16 +622,8 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
pub use crate::alonzo::Metadatum;
|
||||
|
||||
pub use crate::alonzo::MetadatumLabel;
|
||||
|
||||
pub use crate::alonzo::Metadata;
|
||||
|
||||
pub use crate::alonzo::AuxiliaryData;
|
||||
|
||||
pub use crate::alonzo::TransactionIndex;
|
||||
|
||||
#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Clone)]
|
||||
pub struct PseudoBlock<T1, T2, T3, T4>
|
||||
where
|
||||
|
|
|
|||
|
|
@ -2,53 +2,34 @@
|
|||
//!
|
||||
//! Handcrafted, idiomatic rust artifacts based on based on the [Conway CDDL](https://github.com/IntersectMBO/cardano-ledger/blob/master/eras/conway/impl/cddl-files/conway.cddl) file in IntersectMBO repo.
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::ops::Deref;
|
||||
|
||||
use pallas_codec::minicbor::decode::Error;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use pallas_codec::minicbor::{self, decode::Error, Decode, Encode};
|
||||
use pallas_codec::utils::CborWrap;
|
||||
|
||||
use pallas_codec::minicbor::{Decode, Encode};
|
||||
use pallas_crypto::hash::Hash;
|
||||
|
||||
use pallas_codec::utils::{
|
||||
Bytes, CborWrap, KeepRaw, KeyValuePairs, MaybeIndefArray, NonEmptyKeyValuePairs, NonEmptySet,
|
||||
NonZeroInt, Nullable, PositiveCoin, Set,
|
||||
pub use crate::{
|
||||
plutus_data::*, AddrKeyhash, AssetName, Bytes, Coin, CostModel, DnsName, Epoch, ExUnits,
|
||||
GenesisDelegateHash, Genesishash, Hash, IPv4, IPv6, KeepRaw, KeyValuePairs, MaybeIndefArray,
|
||||
Metadata, Metadatum, MetadatumLabel, NetworkId, NonEmptyKeyValuePairs, NonEmptySet, NonZeroInt,
|
||||
Nonce, NonceVariant, Nullable, PlutusScript, PolicyId, PoolKeyhash, PoolMetadata,
|
||||
PoolMetadataHash, Port, PositiveCoin, PositiveInterval, ProtocolVersion, RationalNumber, Relay,
|
||||
RewardAccount, ScriptHash, Set, StakeCredential, TransactionIndex, TransactionInput,
|
||||
UnitInterval, VrfCert, VrfKeyhash,
|
||||
};
|
||||
|
||||
// required for derive attrs to work
|
||||
use pallas_codec::minicbor;
|
||||
|
||||
pub use crate::alonzo::VrfCert;
|
||||
|
||||
use crate::babbage;
|
||||
|
||||
pub use crate::babbage::HeaderBody;
|
||||
|
||||
pub use crate::babbage::OperationalCert;
|
||||
|
||||
pub use crate::alonzo::ProtocolVersion;
|
||||
|
||||
pub use crate::alonzo::KesSignature;
|
||||
|
||||
pub use crate::babbage::Header;
|
||||
|
||||
pub use crate::alonzo::TransactionInput;
|
||||
|
||||
pub use crate::alonzo::NonceVariant;
|
||||
|
||||
pub use crate::alonzo::Nonce;
|
||||
|
||||
pub use crate::alonzo::ScriptHash;
|
||||
|
||||
pub use crate::alonzo::PolicyId;
|
||||
|
||||
pub use crate::alonzo::AssetName;
|
||||
|
||||
pub type Multiasset<A> = NonEmptyKeyValuePairs<PolicyId, NonEmptyKeyValuePairs<AssetName, A>>;
|
||||
|
||||
pub type Mint = Multiasset<NonZeroInt>;
|
||||
|
||||
pub use crate::alonzo::Coin;
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
|
||||
pub enum Value {
|
||||
Coin(Coin),
|
||||
|
|
@ -99,54 +80,10 @@ impl<C> minicbor::encode::Encode<C> for Value {
|
|||
|
||||
pub use crate::alonzo::TransactionOutput as LegacyTransactionOutput;
|
||||
|
||||
pub use crate::alonzo::PoolKeyhash;
|
||||
|
||||
pub use crate::alonzo::Epoch;
|
||||
|
||||
pub use crate::alonzo::Genesishash;
|
||||
|
||||
pub use crate::alonzo::GenesisDelegateHash;
|
||||
|
||||
pub use crate::alonzo::VrfKeyhash;
|
||||
|
||||
pub use crate::alonzo::InstantaneousRewardSource;
|
||||
|
||||
pub use crate::alonzo::InstantaneousRewardTarget;
|
||||
|
||||
pub use crate::alonzo::MoveInstantaneousReward;
|
||||
|
||||
pub use crate::alonzo::RewardAccount;
|
||||
|
||||
pub type Withdrawals = NonEmptyKeyValuePairs<RewardAccount, Coin>;
|
||||
|
||||
pub type RequiredSigners = NonEmptySet<AddrKeyhash>;
|
||||
|
||||
pub use crate::alonzo::Port;
|
||||
|
||||
pub use crate::alonzo::IPv4;
|
||||
|
||||
pub use crate::alonzo::IPv6;
|
||||
|
||||
pub use crate::alonzo::DnsName;
|
||||
|
||||
pub use crate::alonzo::Relay;
|
||||
|
||||
pub use crate::alonzo::PoolMetadataHash;
|
||||
|
||||
pub use crate::alonzo::PoolMetadata;
|
||||
|
||||
pub use crate::alonzo::AddrKeyhash;
|
||||
|
||||
pub use crate::alonzo::Scripthash;
|
||||
|
||||
pub use crate::alonzo::RationalNumber;
|
||||
|
||||
pub use crate::alonzo::UnitInterval;
|
||||
|
||||
pub use crate::alonzo::PositiveInterval;
|
||||
|
||||
pub use crate::alonzo::StakeCredential;
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
|
||||
pub enum Certificate {
|
||||
StakeRegistration(StakeCredential),
|
||||
|
|
@ -442,7 +379,7 @@ impl<C> minicbor::encode::Encode<C> for Certificate {
|
|||
#[derive(Serialize, Deserialize, Debug, PartialEq, PartialOrd, Eq, Ord, Clone)]
|
||||
pub enum DRep {
|
||||
Key(AddrKeyhash),
|
||||
Script(Scripthash),
|
||||
Script(ScriptHash),
|
||||
Abstain,
|
||||
NoConfidence,
|
||||
}
|
||||
|
|
@ -507,8 +444,6 @@ pub type CommitteeColdCredential = StakeCredential;
|
|||
|
||||
pub type CommitteeHotCredential = StakeCredential;
|
||||
|
||||
pub use crate::alonzo::NetworkId;
|
||||
|
||||
#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)]
|
||||
#[cbor(index_only)]
|
||||
pub enum Language {
|
||||
|
|
@ -522,11 +457,12 @@ pub enum Language {
|
|||
PlutusV3,
|
||||
}
|
||||
|
||||
pub use crate::alonzo::CostModel;
|
||||
#[deprecated(since = "0.31.0", note = "use `CostModels` instead")]
|
||||
pub type CostMdls = CostModels;
|
||||
|
||||
#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)]
|
||||
#[cbor(map)]
|
||||
pub struct CostMdls {
|
||||
pub struct CostModels {
|
||||
#[n(0)]
|
||||
pub plutus_v1: Option<CostModel>,
|
||||
|
||||
|
|
@ -570,7 +506,7 @@ pub struct ProtocolParamUpdate {
|
|||
#[n(17)]
|
||||
pub ada_per_utxo_byte: Option<Coin>,
|
||||
#[n(18)]
|
||||
pub cost_models_for_script_languages: Option<CostMdls>,
|
||||
pub cost_models_for_script_languages: Option<CostModels>,
|
||||
#[n(19)]
|
||||
pub execution_costs: Option<ExUnitPrices>,
|
||||
#[n(20)]
|
||||
|
|
@ -1285,28 +1221,6 @@ pub use crate::alonzo::VKeyWitness;
|
|||
|
||||
pub use crate::alonzo::NativeScript;
|
||||
|
||||
pub use crate::alonzo::PlutusScript as PlutusV1Script;
|
||||
|
||||
pub use crate::babbage::PlutusV2Script;
|
||||
|
||||
#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)]
|
||||
#[cbor(transparent)]
|
||||
pub struct PlutusV3Script(#[n(0)] pub Bytes);
|
||||
|
||||
impl AsRef<[u8]> for PlutusV3Script {
|
||||
fn as_ref(&self) -> &[u8] {
|
||||
self.0.as_slice()
|
||||
}
|
||||
}
|
||||
|
||||
pub use crate::alonzo::BigInt;
|
||||
|
||||
pub use crate::alonzo::PlutusData;
|
||||
|
||||
pub use crate::alonzo::Constr;
|
||||
|
||||
pub use crate::alonzo::ExUnits;
|
||||
|
||||
#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)]
|
||||
pub struct ExUnitPrices {
|
||||
#[n(0)]
|
||||
|
|
@ -1446,7 +1360,7 @@ pub struct WitnessSet {
|
|||
pub bootstrap_witness: Option<NonEmptySet<BootstrapWitness>>,
|
||||
|
||||
#[n(3)]
|
||||
pub plutus_v1_script: Option<NonEmptySet<PlutusV1Script>>,
|
||||
pub plutus_v1_script: Option<NonEmptySet<PlutusScript<1>>>,
|
||||
|
||||
#[n(4)]
|
||||
pub plutus_data: Option<NonEmptySet<PlutusData>>,
|
||||
|
|
@ -1455,10 +1369,10 @@ pub struct WitnessSet {
|
|||
pub redeemer: Option<Redeemers>,
|
||||
|
||||
#[n(6)]
|
||||
pub plutus_v2_script: Option<NonEmptySet<PlutusV2Script>>,
|
||||
pub plutus_v2_script: Option<NonEmptySet<PlutusScript<2>>>,
|
||||
|
||||
#[n(7)]
|
||||
pub plutus_v3_script: Option<NonEmptySet<PlutusV3Script>>,
|
||||
pub plutus_v3_script: Option<NonEmptySet<PlutusScript<3>>>,
|
||||
}
|
||||
|
||||
#[derive(Encode, Decode, Debug, PartialEq, Clone)]
|
||||
|
|
@ -1474,7 +1388,7 @@ pub struct MintedWitnessSet<'b> {
|
|||
pub bootstrap_witness: Option<NonEmptySet<BootstrapWitness>>,
|
||||
|
||||
#[n(3)]
|
||||
pub plutus_v1_script: Option<NonEmptySet<PlutusV1Script>>,
|
||||
pub plutus_v1_script: Option<NonEmptySet<PlutusScript<1>>>,
|
||||
|
||||
#[b(4)]
|
||||
pub plutus_data: Option<NonEmptySet<KeepRaw<'b, PlutusData>>>,
|
||||
|
|
@ -1483,10 +1397,10 @@ pub struct MintedWitnessSet<'b> {
|
|||
pub redeemer: Option<KeepRaw<'b, Redeemers>>,
|
||||
|
||||
#[n(6)]
|
||||
pub plutus_v2_script: Option<NonEmptySet<PlutusV2Script>>,
|
||||
pub plutus_v2_script: Option<NonEmptySet<PlutusScript<2>>>,
|
||||
|
||||
#[n(7)]
|
||||
pub plutus_v3_script: Option<NonEmptySet<PlutusV3Script>>,
|
||||
pub plutus_v3_script: Option<NonEmptySet<PlutusScript<3>>>,
|
||||
}
|
||||
|
||||
impl<'b> From<MintedWitnessSet<'b>> for WitnessSet {
|
||||
|
|
@ -1514,13 +1428,13 @@ pub struct PostAlonzoAuxiliaryData {
|
|||
pub native_scripts: Option<Vec<NativeScript>>,
|
||||
|
||||
#[n(2)]
|
||||
pub plutus_v1_scripts: Option<Vec<PlutusV1Script>>,
|
||||
pub plutus_v1_scripts: Option<Vec<PlutusScript<1>>>,
|
||||
|
||||
#[n(3)]
|
||||
pub plutus_v2_scripts: Option<Vec<PlutusV2Script>>,
|
||||
pub plutus_v2_scripts: Option<Vec<PlutusScript<2>>>,
|
||||
|
||||
#[n(4)]
|
||||
pub plutus_v3_scripts: Option<Vec<PlutusV3Script>>,
|
||||
pub plutus_v3_scripts: Option<Vec<PlutusScript<3>>>,
|
||||
}
|
||||
|
||||
pub use crate::babbage::DatumHash;
|
||||
|
|
@ -1531,13 +1445,22 @@ pub use crate::babbage::DatumOption;
|
|||
|
||||
pub use crate::babbage::MintedDatumOption;
|
||||
|
||||
#[deprecated(since = "0.31.0", note = "use `PlutusScript<1>` instead")]
|
||||
pub type PlutusV1Script = PlutusScript<1>;
|
||||
|
||||
#[deprecated(since = "0.31.0", note = "use `PlutusScript<2>` instead")]
|
||||
pub type PlutusV2Script = PlutusScript<2>;
|
||||
|
||||
#[deprecated(since = "0.31.0", note = "use `PlutusScript<3>` instead")]
|
||||
pub type PlutusV3Script = PlutusScript<3>;
|
||||
|
||||
// script = [ 0, native_script // 1, plutus_v1_script // 2, plutus_v2_script ]
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
pub enum PseudoScript<T1> {
|
||||
NativeScript(T1),
|
||||
PlutusV1Script(PlutusV1Script),
|
||||
PlutusV2Script(PlutusV2Script),
|
||||
PlutusV3Script(PlutusV3Script),
|
||||
PlutusV1Script(PlutusScript<1>),
|
||||
PlutusV2Script(PlutusScript<2>),
|
||||
PlutusV3Script(PlutusScript<3>),
|
||||
}
|
||||
|
||||
// script_ref = #6.24(bytes .cbor script)
|
||||
|
|
@ -1610,15 +1533,8 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
pub use crate::alonzo::Metadatum;
|
||||
|
||||
pub use crate::alonzo::MetadatumLabel;
|
||||
|
||||
pub use crate::alonzo::Metadata;
|
||||
|
||||
pub use crate::alonzo::AuxiliaryData;
|
||||
|
||||
pub use crate::alonzo::TransactionIndex;
|
||||
use crate::babbage::MintedHeader;
|
||||
|
||||
#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Clone)]
|
||||
|
|
|
|||
|
|
@ -1,10 +1,402 @@
|
|||
//! Ledger primitives and cbor codec for the Cardano eras
|
||||
|
||||
mod framework;
|
||||
mod plutus_data;
|
||||
|
||||
pub mod alonzo;
|
||||
pub mod babbage;
|
||||
pub mod byron;
|
||||
pub mod conway;
|
||||
pub use plutus_data::*;
|
||||
|
||||
pub use framework::*;
|
||||
|
||||
pub use pallas_codec::utils::{
|
||||
Bytes, Int, KeepRaw, KeyValuePairs, MaybeIndefArray, NonEmptyKeyValuePairs, NonEmptySet,
|
||||
NonZeroInt, Nullable, PositiveCoin, Set,
|
||||
};
|
||||
pub use pallas_crypto::hash::Hash;
|
||||
|
||||
use pallas_codec::minicbor::{self, data::Tag, Decode, Encode};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
// ----- Common type definitions
|
||||
|
||||
pub type AddrKeyhash = Hash<28>;
|
||||
|
||||
pub type AssetName = Bytes;
|
||||
|
||||
pub type Coin = u64;
|
||||
|
||||
pub type CostModel = Vec<i64>;
|
||||
|
||||
pub type DatumHash = Hash<32>;
|
||||
|
||||
pub type DnsName = String;
|
||||
|
||||
pub type Epoch = u64;
|
||||
|
||||
#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone, Copy)]
|
||||
pub struct ExUnits {
|
||||
#[n(0)]
|
||||
pub mem: u64,
|
||||
#[n(1)]
|
||||
pub steps: u64,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)]
|
||||
pub struct ExUnitPrices {
|
||||
#[n(0)]
|
||||
pub mem_price: PositiveInterval,
|
||||
|
||||
#[n(1)]
|
||||
pub step_price: PositiveInterval,
|
||||
}
|
||||
|
||||
pub type Genesishash = Bytes;
|
||||
|
||||
pub type GenesisDelegateHash = Bytes;
|
||||
|
||||
pub type IPv4 = Bytes;
|
||||
|
||||
pub type IPv6 = Bytes;
|
||||
|
||||
pub type Metadata = KeyValuePairs<MetadatumLabel, Metadatum>;
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
|
||||
pub enum Metadatum {
|
||||
Int(Int),
|
||||
Bytes(Bytes),
|
||||
Text(String),
|
||||
Array(Vec<Metadatum>),
|
||||
Map(KeyValuePairs<Metadatum, Metadatum>),
|
||||
}
|
||||
|
||||
impl<'b, C> minicbor::Decode<'b, C> for Metadatum {
|
||||
fn decode(d: &mut minicbor::Decoder<'b>, ctx: &mut C) -> Result<Self, minicbor::decode::Error> {
|
||||
match d.datatype()? {
|
||||
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)?)),
|
||||
minicbor::data::Type::String => Ok(Metadatum::Text(d.decode_with(ctx)?)),
|
||||
minicbor::data::Type::Array | minicbor::data::Type::ArrayIndef => {
|
||||
Ok(Metadatum::Array(d.decode_with(ctx)?))
|
||||
}
|
||||
minicbor::data::Type::Map | minicbor::data::Type::MapIndef => {
|
||||
Ok(Metadatum::Map(d.decode_with(ctx)?))
|
||||
}
|
||||
_ => Err(minicbor::decode::Error::message(
|
||||
"Can't turn data type into metadatum",
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<C> minicbor::Encode<C> for Metadatum {
|
||||
fn encode<W: minicbor::encode::Write>(
|
||||
&self,
|
||||
e: &mut minicbor::Encoder<W>,
|
||||
ctx: &mut C,
|
||||
) -> Result<(), minicbor::encode::Error<W::Error>> {
|
||||
match self {
|
||||
Metadatum::Int(a) => {
|
||||
e.encode_with(a, ctx)?;
|
||||
}
|
||||
Metadatum::Bytes(a) => {
|
||||
e.encode_with(a, ctx)?;
|
||||
}
|
||||
Metadatum::Text(a) => {
|
||||
e.encode_with(a, ctx)?;
|
||||
}
|
||||
Metadatum::Array(a) => {
|
||||
e.encode_with(a, ctx)?;
|
||||
}
|
||||
Metadatum::Map(a) => {
|
||||
e.encode_with(a, ctx)?;
|
||||
}
|
||||
};
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub type MetadatumLabel = u64;
|
||||
|
||||
#[derive(
|
||||
Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy,
|
||||
)]
|
||||
#[cbor(index_only)]
|
||||
pub enum NetworkId {
|
||||
#[n(0)]
|
||||
Testnet,
|
||||
#[n(1)]
|
||||
Mainnet,
|
||||
}
|
||||
|
||||
impl From<NetworkId> for u8 {
|
||||
fn from(network_id: NetworkId) -> u8 {
|
||||
match network_id {
|
||||
NetworkId::Testnet => 0,
|
||||
NetworkId::Mainnet => 1,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<u8> for NetworkId {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(i: u8) -> Result<Self, Self::Error> {
|
||||
match i {
|
||||
0 => Ok(Self::Testnet),
|
||||
1 => Ok(Self::Mainnet),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)]
|
||||
pub struct Nonce {
|
||||
#[n(0)]
|
||||
pub variant: NonceVariant,
|
||||
|
||||
#[n(1)]
|
||||
pub hash: Option<Hash<32>>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)]
|
||||
#[cbor(index_only)]
|
||||
pub enum NonceVariant {
|
||||
#[n(0)]
|
||||
NeutralNonce,
|
||||
|
||||
#[n(1)]
|
||||
Nonce,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)]
|
||||
#[cbor(transparent)]
|
||||
pub struct PlutusScript<const VERSION: usize>(#[n(0)] pub Bytes);
|
||||
|
||||
impl<const VERSION: usize> AsRef<[u8]> for PlutusScript<VERSION> {
|
||||
fn as_ref(&self) -> &[u8] {
|
||||
self.0.as_slice()
|
||||
}
|
||||
}
|
||||
|
||||
pub type PolicyId = Hash<28>;
|
||||
|
||||
pub type PoolKeyhash = Hash<28>;
|
||||
|
||||
#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)]
|
||||
pub struct PoolMetadata {
|
||||
#[n(0)]
|
||||
pub url: String,
|
||||
|
||||
#[n(1)]
|
||||
pub hash: PoolMetadataHash,
|
||||
}
|
||||
|
||||
pub type PoolMetadataHash = Hash<32>;
|
||||
|
||||
pub type Port = u32;
|
||||
|
||||
pub type PositiveInterval = RationalNumber;
|
||||
|
||||
pub type ProtocolVersion = (u64, u64);
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
|
||||
pub struct RationalNumber {
|
||||
pub numerator: u64,
|
||||
pub denominator: u64,
|
||||
}
|
||||
|
||||
impl<'b, C> minicbor::decode::Decode<'b, C> for RationalNumber {
|
||||
fn decode(d: &mut minicbor::Decoder<'b>, ctx: &mut C) -> Result<Self, minicbor::decode::Error> {
|
||||
// TODO: Enforce tag == 30 & array of size 2
|
||||
d.tag()?;
|
||||
d.array()?;
|
||||
Ok(RationalNumber {
|
||||
numerator: d.decode_with(ctx)?,
|
||||
denominator: d.decode_with(ctx)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<C> minicbor::encode::Encode<C> for RationalNumber {
|
||||
fn encode<W: minicbor::encode::Write>(
|
||||
&self,
|
||||
e: &mut minicbor::Encoder<W>,
|
||||
ctx: &mut C,
|
||||
) -> Result<(), minicbor::encode::Error<W::Error>> {
|
||||
e.tag(Tag::new(30))?;
|
||||
e.array(2)?;
|
||||
e.encode_with(self.numerator, ctx)?;
|
||||
e.encode_with(self.denominator, ctx)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
|
||||
pub enum Relay {
|
||||
SingleHostAddr(Nullable<Port>, Nullable<IPv4>, Nullable<IPv6>),
|
||||
SingleHostName(Nullable<Port>, DnsName),
|
||||
MultiHostName(DnsName),
|
||||
}
|
||||
|
||||
impl<'b, C> minicbor::decode::Decode<'b, C> for Relay {
|
||||
fn decode(d: &mut minicbor::Decoder<'b>, ctx: &mut C) -> Result<Self, minicbor::decode::Error> {
|
||||
d.array()?;
|
||||
let variant = d.u16()?;
|
||||
|
||||
match variant {
|
||||
0 => Ok(Relay::SingleHostAddr(
|
||||
d.decode_with(ctx)?,
|
||||
d.decode_with(ctx)?,
|
||||
d.decode_with(ctx)?,
|
||||
)),
|
||||
1 => Ok(Relay::SingleHostName(
|
||||
d.decode_with(ctx)?,
|
||||
d.decode_with(ctx)?,
|
||||
)),
|
||||
2 => Ok(Relay::MultiHostName(d.decode_with(ctx)?)),
|
||||
_ => Err(minicbor::decode::Error::message(
|
||||
"invalid variant id for Relay",
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<C> minicbor::encode::Encode<C> for Relay {
|
||||
fn encode<W: minicbor::encode::Write>(
|
||||
&self,
|
||||
e: &mut minicbor::Encoder<W>,
|
||||
ctx: &mut C,
|
||||
) -> Result<(), minicbor::encode::Error<W::Error>> {
|
||||
match self {
|
||||
Relay::SingleHostAddr(a, b, c) => {
|
||||
e.array(4)?;
|
||||
e.encode_with(0, ctx)?;
|
||||
e.encode_with(a, ctx)?;
|
||||
e.encode_with(b, ctx)?;
|
||||
e.encode_with(c, ctx)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Relay::SingleHostName(a, b) => {
|
||||
e.array(3)?;
|
||||
e.encode_with(1, ctx)?;
|
||||
e.encode_with(a, ctx)?;
|
||||
e.encode_with(b, ctx)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Relay::MultiHostName(a) => {
|
||||
e.array(2)?;
|
||||
e.encode_with(2, ctx)?;
|
||||
e.encode_with(a, ctx)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub type RewardAccount = Bytes;
|
||||
|
||||
pub type ScriptHash = Hash<28>;
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, PartialEq, PartialOrd, Eq, Ord, Clone, Hash)]
|
||||
// !! NOTE / IMPORTANT !!
|
||||
// It is tempting to swap the order of the two constructors so that AddrKeyHash
|
||||
// comes first. This indeed nicely maps the binary representation which
|
||||
// associates 0 to AddrKeyHash and 1 to ScriptHash.
|
||||
//
|
||||
// However, for historical reasons, the ScriptHash variant comes first in the
|
||||
// Haskell reference codebase. From this ordering is derived the `PartialOrd`
|
||||
// and `Ord` instances; which impacts how Maps/Dictionnaries indexed by
|
||||
// StakeCredential will be ordered. So, it is crucial to preserve this quirks to
|
||||
// avoid hard to troubleshoot issues down the line.
|
||||
pub enum StakeCredential {
|
||||
ScriptHash(ScriptHash),
|
||||
AddrKeyhash(AddrKeyhash),
|
||||
}
|
||||
|
||||
impl<'b, C> minicbor::decode::Decode<'b, C> for StakeCredential {
|
||||
fn decode(d: &mut minicbor::Decoder<'b>, ctx: &mut C) -> Result<Self, minicbor::decode::Error> {
|
||||
d.array()?;
|
||||
let variant = d.u16()?;
|
||||
|
||||
match variant {
|
||||
0 => Ok(StakeCredential::AddrKeyhash(d.decode_with(ctx)?)),
|
||||
1 => Ok(StakeCredential::ScriptHash(d.decode_with(ctx)?)),
|
||||
_ => Err(minicbor::decode::Error::message(
|
||||
"invalid variant id for StakeCredential",
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<C> minicbor::encode::Encode<C> for StakeCredential {
|
||||
fn encode<W: minicbor::encode::Write>(
|
||||
&self,
|
||||
e: &mut minicbor::Encoder<W>,
|
||||
ctx: &mut C,
|
||||
) -> Result<(), minicbor::encode::Error<W::Error>> {
|
||||
match self {
|
||||
StakeCredential::AddrKeyhash(a) => {
|
||||
e.array(2)?;
|
||||
e.encode_with(0, ctx)?;
|
||||
e.encode_with(a, ctx)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
StakeCredential::ScriptHash(a) => {
|
||||
e.array(2)?;
|
||||
e.encode_with(1, ctx)?;
|
||||
e.encode_with(a, ctx)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub type TransactionIndex = u32;
|
||||
|
||||
#[derive(
|
||||
Serialize,
|
||||
Deserialize,
|
||||
Encode,
|
||||
Decode,
|
||||
Debug,
|
||||
PartialEq,
|
||||
Eq,
|
||||
PartialOrd,
|
||||
Ord,
|
||||
Clone,
|
||||
std::hash::Hash,
|
||||
)]
|
||||
pub struct TransactionInput {
|
||||
#[n(0)]
|
||||
pub transaction_id: Hash<32>,
|
||||
|
||||
#[n(1)]
|
||||
pub index: u64,
|
||||
}
|
||||
|
||||
pub type UnitInterval = RationalNumber;
|
||||
|
||||
#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)]
|
||||
pub struct VrfCert(#[n(0)] pub Bytes, #[n(1)] pub Bytes);
|
||||
|
||||
pub type VrfKeyhash = Hash<32>;
|
||||
|
|
|
|||
353
pallas-primitives/src/plutus_data.rs
Normal file
353
pallas-primitives/src/plutus_data.rs
Normal file
|
|
@ -0,0 +1,353 @@
|
|||
use crate::KeyValuePairs;
|
||||
use pallas_codec::minicbor::{
|
||||
self,
|
||||
data::{IanaTag, Tag},
|
||||
Encode,
|
||||
};
|
||||
use pallas_codec::utils::Int;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{fmt, ops::Deref};
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
|
||||
pub enum PlutusData {
|
||||
Constr(Constr<PlutusData>),
|
||||
Map(KeyValuePairs<PlutusData, PlutusData>),
|
||||
BigInt(BigInt),
|
||||
BoundedBytes(BoundedBytes),
|
||||
Array(Vec<PlutusData>),
|
||||
}
|
||||
|
||||
impl<'b, C> minicbor::decode::Decode<'b, C> for PlutusData {
|
||||
fn decode(d: &mut minicbor::Decoder<'b>, ctx: &mut C) -> Result<Self, minicbor::decode::Error> {
|
||||
let type_ = d.datatype()?;
|
||||
|
||||
match type_ {
|
||||
minicbor::data::Type::Tag => {
|
||||
let mut probe = d.probe();
|
||||
let tag = probe.tag()?;
|
||||
|
||||
if tag == IanaTag::PosBignum.tag() || tag == IanaTag::NegBignum.tag() {
|
||||
Ok(Self::BigInt(d.decode_with(ctx)?))
|
||||
} else {
|
||||
match tag.as_u64() {
|
||||
(121..=127) | (1280..=1400) | 102 => Ok(Self::Constr(d.decode_with(ctx)?)),
|
||||
_ => Err(minicbor::decode::Error::message(
|
||||
"unknown tag for plutus data tag",
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
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 => Ok(Self::BigInt(d.decode_with(ctx)?)),
|
||||
minicbor::data::Type::Map | minicbor::data::Type::MapIndef => {
|
||||
Ok(Self::Map(d.decode_with(ctx)?))
|
||||
}
|
||||
minicbor::data::Type::Bytes => Ok(Self::BoundedBytes(d.decode_with(ctx)?)),
|
||||
minicbor::data::Type::BytesIndef => {
|
||||
let mut full = Vec::new();
|
||||
|
||||
for slice in d.bytes_iter()? {
|
||||
full.extend(slice?);
|
||||
}
|
||||
|
||||
Ok(Self::BoundedBytes(BoundedBytes::from(full)))
|
||||
}
|
||||
minicbor::data::Type::Array | minicbor::data::Type::ArrayIndef => {
|
||||
Ok(Self::Array(d.decode_with(ctx)?))
|
||||
}
|
||||
|
||||
any => Err(minicbor::decode::Error::message(format!(
|
||||
"bad cbor data type ({any:?}) for plutus data"
|
||||
))),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<C> minicbor::encode::Encode<C> for PlutusData {
|
||||
fn encode<W: minicbor::encode::Write>(
|
||||
&self,
|
||||
e: &mut minicbor::Encoder<W>,
|
||||
ctx: &mut C,
|
||||
) -> Result<(), minicbor::encode::Error<W::Error>> {
|
||||
match self {
|
||||
Self::Constr(a) => {
|
||||
e.encode_with(a, ctx)?;
|
||||
}
|
||||
Self::Map(a) => {
|
||||
// we use definite array to match the approach used by haskell's plutus
|
||||
// implementation https://github.com/input-output-hk/plutus/blob/9538fc9829426b2ecb0628d352e2d7af96ec8204/plutus-core/plutus-core/src/PlutusCore/Data.hs#L152
|
||||
e.map(a.len().try_into().unwrap())?;
|
||||
for (k, v) in a.iter() {
|
||||
k.encode(e, ctx)?;
|
||||
v.encode(e, ctx)?;
|
||||
}
|
||||
}
|
||||
Self::BigInt(a) => {
|
||||
e.encode_with(a, ctx)?;
|
||||
}
|
||||
Self::BoundedBytes(a) => {
|
||||
e.encode_with(a, ctx)?;
|
||||
}
|
||||
Self::Array(a) => {
|
||||
// we use definite array for empty array or indef array otherwise to match
|
||||
// haskell implementation https://github.com/input-output-hk/plutus/blob/9538fc9829426b2ecb0628d352e2d7af96ec8204/plutus-core/plutus-core/src/PlutusCore/Data.hs#L153
|
||||
// default encoder for a list:
|
||||
// https://github.com/well-typed/cborg/blob/4bdc818a1f0b35f38bc118a87944630043b58384/serialise/src/Codec/Serialise/Class.hs#L181
|
||||
encode_list(a, e, ctx)?;
|
||||
}
|
||||
};
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
big_int = int / big_uint / big_nint ; New
|
||||
big_uint = #6.2(bounded_bytes) ; New
|
||||
big_nint = #6.3(bounded_bytes) ; New
|
||||
*/
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
|
||||
pub enum BigInt {
|
||||
Int(Int),
|
||||
BigUInt(BoundedBytes),
|
||||
BigNInt(BoundedBytes),
|
||||
}
|
||||
|
||||
impl<'b, C> minicbor::decode::Decode<'b, C> for BigInt {
|
||||
fn decode(d: &mut minicbor::Decoder<'b>, ctx: &mut C) -> Result<Self, minicbor::decode::Error> {
|
||||
let datatype = d.datatype()?;
|
||||
|
||||
match datatype {
|
||||
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 => Ok(Self::Int(d.decode_with(ctx)?)),
|
||||
minicbor::data::Type::Tag => {
|
||||
let tag = d.tag()?;
|
||||
if tag == IanaTag::PosBignum.tag() {
|
||||
Ok(Self::BigUInt(d.decode_with(ctx)?))
|
||||
} else if tag == IanaTag::NegBignum.tag() {
|
||||
Ok(Self::BigNInt(d.decode_with(ctx)?))
|
||||
} else {
|
||||
Err(minicbor::decode::Error::message(
|
||||
"invalid cbor tag for big int",
|
||||
))
|
||||
}
|
||||
}
|
||||
_ => Err(minicbor::decode::Error::message(
|
||||
"invalid cbor data type for big int",
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<C> minicbor::encode::Encode<C> for BigInt {
|
||||
fn encode<W: minicbor::encode::Write>(
|
||||
&self,
|
||||
e: &mut minicbor::Encoder<W>,
|
||||
ctx: &mut C,
|
||||
) -> Result<(), minicbor::encode::Error<W::Error>> {
|
||||
match self {
|
||||
BigInt::Int(x) => {
|
||||
e.encode_with(x, ctx)?;
|
||||
}
|
||||
BigInt::BigUInt(x) => {
|
||||
e.tag(IanaTag::PosBignum)?;
|
||||
e.encode_with(x, ctx)?;
|
||||
}
|
||||
BigInt::BigNInt(x) => {
|
||||
e.tag(IanaTag::NegBignum)?;
|
||||
e.encode_with(x, ctx)?;
|
||||
}
|
||||
};
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
|
||||
pub struct Constr<A> {
|
||||
pub tag: u64,
|
||||
pub any_constructor: Option<u64>,
|
||||
pub fields: Vec<A>,
|
||||
}
|
||||
|
||||
impl<'b, C, A> minicbor::decode::Decode<'b, C> for Constr<A>
|
||||
where
|
||||
A: minicbor::decode::Decode<'b, C>,
|
||||
{
|
||||
fn decode(d: &mut minicbor::Decoder<'b>, ctx: &mut C) -> Result<Self, minicbor::decode::Error> {
|
||||
let tag = d.tag()?;
|
||||
let x = tag.as_u64();
|
||||
match x {
|
||||
121..=127 | 1280..=1400 => Ok(Constr {
|
||||
tag: x,
|
||||
fields: d.decode_with(ctx)?,
|
||||
any_constructor: None,
|
||||
}),
|
||||
102 => {
|
||||
d.array()?;
|
||||
|
||||
Ok(Constr {
|
||||
tag: x,
|
||||
any_constructor: Some(d.decode_with(ctx)?),
|
||||
fields: d.decode_with(ctx)?,
|
||||
})
|
||||
}
|
||||
_ => Err(minicbor::decode::Error::message(
|
||||
"bad tag code for plutus data",
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<C, A> minicbor::encode::Encode<C> for Constr<A>
|
||||
where
|
||||
A: minicbor::encode::Encode<C>,
|
||||
{
|
||||
fn encode<W: minicbor::encode::Write>(
|
||||
&self,
|
||||
e: &mut minicbor::Encoder<W>,
|
||||
ctx: &mut C,
|
||||
) -> Result<(), minicbor::encode::Error<W::Error>> {
|
||||
e.tag(Tag::new(self.tag))?;
|
||||
|
||||
match self.tag {
|
||||
102 => {
|
||||
// definite length array here
|
||||
// https://github.com/input-output-hk/plutus/blob/9538fc9829426b2ecb0628d352e2d7af96ec8204/plutus-core/plutus-core/src/PlutusCore/Data.hs#L152
|
||||
e.array(2)?;
|
||||
e.encode_with(self.any_constructor.unwrap_or_default(), ctx)?;
|
||||
|
||||
// we use definite array for empty array or indef array otherwise to match
|
||||
// haskell implementation https://github.com/input-output-hk/plutus/blob/9538fc9829426b2ecb0628d352e2d7af96ec8204/plutus-core/plutus-core/src/PlutusCore/Data.hs#L144
|
||||
// default encoder for a list:
|
||||
// https://github.com/well-typed/cborg/blob/4bdc818a1f0b35f38bc118a87944630043b58384/serialise/src/Codec/Serialise/Class.hs#L181
|
||||
encode_list(&self.fields, e, ctx)?;
|
||||
Ok(())
|
||||
}
|
||||
_ => {
|
||||
// we use definite array for empty array or indef array otherwise to match
|
||||
// haskell implementation. See above reference.
|
||||
encode_list(&self.fields, e, ctx)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Defined to encode PlutusData bytestring as it is done in the canonical
|
||||
/// plutus implementation
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
|
||||
#[serde(into = "String")]
|
||||
#[serde(try_from = "String")]
|
||||
pub struct BoundedBytes(Vec<u8>);
|
||||
|
||||
impl From<Vec<u8>> for BoundedBytes {
|
||||
fn from(xs: Vec<u8>) -> Self {
|
||||
BoundedBytes(xs)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<BoundedBytes> for Vec<u8> {
|
||||
fn from(b: BoundedBytes) -> Self {
|
||||
b.0
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for BoundedBytes {
|
||||
type Target = Vec<u8>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<String> for BoundedBytes {
|
||||
type Error = hex::FromHexError;
|
||||
|
||||
fn try_from(value: String) -> Result<Self, Self::Error> {
|
||||
let v = hex::decode(value)?;
|
||||
Ok(BoundedBytes(v))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<BoundedBytes> for String {
|
||||
fn from(b: BoundedBytes) -> Self {
|
||||
hex::encode(b.deref())
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for BoundedBytes {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let bytes: Vec<u8> = self.clone().into();
|
||||
|
||||
f.write_str(&hex::encode(bytes))
|
||||
}
|
||||
}
|
||||
|
||||
impl<C> Encode<C> for BoundedBytes {
|
||||
fn encode<W: minicbor::encode::Write>(
|
||||
&self,
|
||||
e: &mut minicbor::Encoder<W>,
|
||||
_: &mut C,
|
||||
) -> Result<(), minicbor::encode::Error<W::Error>> {
|
||||
// we match the haskell implementation by encoding bytestrings longer than 64
|
||||
// bytes as indefinite lists of bytes
|
||||
const CHUNK_SIZE: usize = 64;
|
||||
let bs: &Vec<u8> = self.deref();
|
||||
if bs.len() <= 64 {
|
||||
e.bytes(bs)?;
|
||||
} else {
|
||||
e.begin_bytes()?;
|
||||
for b in bs.chunks(CHUNK_SIZE) {
|
||||
e.bytes(b)?;
|
||||
}
|
||||
e.end()?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'b, C> minicbor::decode::Decode<'b, C> for BoundedBytes {
|
||||
fn decode(d: &mut minicbor::Decoder<'b>, _: &mut C) -> Result<Self, minicbor::decode::Error> {
|
||||
let mut res = Vec::new();
|
||||
for chunk in d.bytes_iter()? {
|
||||
let bs = chunk?;
|
||||
res.extend_from_slice(bs);
|
||||
}
|
||||
Ok(BoundedBytes::from(res))
|
||||
}
|
||||
}
|
||||
|
||||
fn encode_list<C, W: minicbor::encode::Write, A: minicbor::encode::Encode<C>>(
|
||||
a: &Vec<A>,
|
||||
e: &mut minicbor::Encoder<W>,
|
||||
ctx: &mut C,
|
||||
) -> Result<(), minicbor::encode::Error<W::Error>> {
|
||||
// Mimics default haskell list encoding from cborg:
|
||||
// We use indef array for non-empty arrays but definite 0-length array for empty
|
||||
if a.is_empty() {
|
||||
e.array(0)?;
|
||||
} else {
|
||||
e.begin_array()?;
|
||||
for v in a {
|
||||
e.encode_with(v, ctx)?;
|
||||
}
|
||||
e.end()?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue