feat(primitives): Implement length-preserving uints (#92)
This commit is contained in:
parent
4ce608ea6f
commit
016b76d747
3 changed files with 93 additions and 5 deletions
|
|
@ -375,3 +375,87 @@ where
|
|||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// A uint structure that preserves original int length
|
||||
#[derive(Debug, PartialEq, Copy, Clone, PartialOrd)]
|
||||
pub enum AnyUInt {
|
||||
MajorByte(u8),
|
||||
U8(u8),
|
||||
U16(u16),
|
||||
U32(u32),
|
||||
U64(u64),
|
||||
}
|
||||
|
||||
impl<'b> minicbor::decode::Decode<'b> for AnyUInt {
|
||||
fn decode(d: &mut minicbor::Decoder<'b>) -> Result<Self, minicbor::decode::Error> {
|
||||
match d.datatype()? {
|
||||
minicbor::data::Type::U8 => match d.u8()? {
|
||||
x @ 0..=0x17 => Ok(AnyUInt::MajorByte(x)),
|
||||
x @ 0x18..=0xff => Ok(AnyUInt::U8(x)),
|
||||
},
|
||||
minicbor::data::Type::U16 => Ok(AnyUInt::U16(d.u16()?)),
|
||||
minicbor::data::Type::U32 => Ok(AnyUInt::U32(d.u32()?)),
|
||||
minicbor::data::Type::U64 => Ok(AnyUInt::U64(d.u64()?)),
|
||||
_ => Err(minicbor::decode::Error::message(
|
||||
"invalid data type for AnyUInt",
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl minicbor::encode::Encode for AnyUInt {
|
||||
fn encode<W: minicbor::encode::Write>(
|
||||
&self,
|
||||
e: &mut minicbor::Encoder<W>,
|
||||
) -> Result<(), minicbor::encode::Error<W::Error>> {
|
||||
match self {
|
||||
AnyUInt::MajorByte(x) => {
|
||||
let b = &x.to_be_bytes()[..];
|
||||
e.encode(minicbor::data::Cbor::from(b))?;
|
||||
Ok(())
|
||||
}
|
||||
AnyUInt::U8(x) => {
|
||||
let x = x.to_be_bytes();
|
||||
let b = &[[24u8], x].concat()[..];
|
||||
e.encode(minicbor::data::Cbor::from(b))?;
|
||||
Ok(())
|
||||
}
|
||||
AnyUInt::U16(x) => {
|
||||
let x = &x.to_be_bytes()[..];
|
||||
let b = &[&[25u8], x].concat()[..];
|
||||
e.encode(minicbor::data::Cbor::from(b))?;
|
||||
Ok(())
|
||||
}
|
||||
AnyUInt::U32(x) => {
|
||||
let x = &x.to_be_bytes()[..];
|
||||
let b = &[&[26u8], x].concat()[..];
|
||||
e.encode(minicbor::data::Cbor::from(b))?;
|
||||
Ok(())
|
||||
}
|
||||
AnyUInt::U64(x) => {
|
||||
let x = &x.to_be_bytes()[..];
|
||||
let b = &[&[27u8], x].concat()[..];
|
||||
e.encode(minicbor::data::Cbor::from(b))?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<AnyUInt> for u64 {
|
||||
fn from(x: AnyUInt) -> Self {
|
||||
match x {
|
||||
AnyUInt::MajorByte(x) => x as u64,
|
||||
AnyUInt::U8(x) => x as u64,
|
||||
AnyUInt::U16(x) => x as u64,
|
||||
AnyUInt::U32(x) => x as u64,
|
||||
AnyUInt::U64(x) => x as u64,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&AnyUInt> for u64 {
|
||||
fn from(x: &AnyUInt) -> Self {
|
||||
u64::from(*x)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ use pallas_codec::minicbor::{bytes::ByteVec, data::Int, data::Tag, Decode, Encod
|
|||
use pallas_crypto::hash::Hash;
|
||||
use std::ops::Deref;
|
||||
|
||||
use pallas_codec::utils::{KeyValuePairs, MaybeIndefArray};
|
||||
use pallas_codec::utils::{AnyUInt, KeyValuePairs, MaybeIndefArray};
|
||||
|
||||
// required for derive attrs to work
|
||||
use pallas_codec::minicbor;
|
||||
|
|
@ -114,12 +114,12 @@ pub type Multiasset<A> = KeyValuePairs<PolicyId, KeyValuePairs<AssetName, A>>;
|
|||
|
||||
pub type Mint = Multiasset<i64>;
|
||||
|
||||
pub type Coin = u64;
|
||||
pub type Coin = AnyUInt;
|
||||
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub enum Value {
|
||||
Coin(Coin),
|
||||
Multiasset(Coin, Multiasset<u64>),
|
||||
Multiasset(Coin, Multiasset<Coin>),
|
||||
}
|
||||
|
||||
impl<'b> minicbor::decode::Decode<'b> for Value {
|
||||
|
|
@ -129,7 +129,7 @@ impl<'b> minicbor::decode::Decode<'b> for Value {
|
|||
minicbor::data::Type::U64 => Ok(Value::Coin(d.decode()?)),
|
||||
minicbor::data::Type::Array => {
|
||||
d.array()?;
|
||||
let coin = d.u64()?;
|
||||
let coin = d.decode()?;
|
||||
let multiasset = d.decode()?;
|
||||
Ok(Value::Multiasset(coin, multiasset))
|
||||
}
|
||||
|
|
@ -170,7 +170,7 @@ pub struct TransactionOutput {
|
|||
pub amount: Value,
|
||||
|
||||
#[n(2)]
|
||||
pub datum_hash: Option<ByteVec>,
|
||||
pub datum_hash: Option<Hash<32>>,
|
||||
}
|
||||
|
||||
pub type PoolKeyhash = Hash<28>;
|
||||
|
|
@ -699,6 +699,7 @@ pub enum TransactionBodyComponent {
|
|||
RequiredSigners(MaybeIndefArray<AddrKeyhash>),
|
||||
NetworkId(NetworkId),
|
||||
}
|
||||
|
||||
impl<'b> minicbor::decode::Decode<'b> for TransactionBodyComponent {
|
||||
fn decode(d: &mut minicbor::Decoder<'b>) -> Result<Self, minicbor::decode::Error> {
|
||||
let key: u32 = d.decode()?;
|
||||
|
|
@ -1442,6 +1443,8 @@ mod tests {
|
|||
include_str!("test_data/test19.block"),
|
||||
// peculiar block with very BigInt in plutus code
|
||||
include_str!("test_data/test20.block"),
|
||||
// peculiar block with bad tx hash
|
||||
include_str!("test_data/test21.block"),
|
||||
];
|
||||
|
||||
for (idx, block_str) in test_blocks.iter().enumerate() {
|
||||
|
|
|
|||
1
pallas-primitives/src/alonzo/test_data/test21.block
Normal file
1
pallas-primitives/src/alonzo/test_data/test21.block
Normal file
File diff suppressed because one or more lines are too long
Loading…
Add table
Add a link
Reference in a new issue