feat(primitives): Implement length-preserving uints (#92)
This commit is contained in:
parent
ac757eb8e9
commit
7fb7860602
3 changed files with 93 additions and 5 deletions
|
|
@ -375,3 +375,87 @@ where
|
||||||
Ok(())
|
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 pallas_crypto::hash::Hash;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
|
|
||||||
use pallas_codec::utils::{KeyValuePairs, MaybeIndefArray};
|
use pallas_codec::utils::{AnyUInt, KeyValuePairs, MaybeIndefArray};
|
||||||
|
|
||||||
// required for derive attrs to work
|
// required for derive attrs to work
|
||||||
use pallas_codec::minicbor;
|
use pallas_codec::minicbor;
|
||||||
|
|
@ -114,12 +114,12 @@ pub type Multiasset<A> = KeyValuePairs<PolicyId, KeyValuePairs<AssetName, A>>;
|
||||||
|
|
||||||
pub type Mint = Multiasset<i64>;
|
pub type Mint = Multiasset<i64>;
|
||||||
|
|
||||||
pub type Coin = u64;
|
pub type Coin = AnyUInt;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub enum Value {
|
pub enum Value {
|
||||||
Coin(Coin),
|
Coin(Coin),
|
||||||
Multiasset(Coin, Multiasset<u64>),
|
Multiasset(Coin, Multiasset<Coin>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'b> minicbor::decode::Decode<'b> for Value {
|
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::U64 => Ok(Value::Coin(d.decode()?)),
|
||||||
minicbor::data::Type::Array => {
|
minicbor::data::Type::Array => {
|
||||||
d.array()?;
|
d.array()?;
|
||||||
let coin = d.u64()?;
|
let coin = d.decode()?;
|
||||||
let multiasset = d.decode()?;
|
let multiasset = d.decode()?;
|
||||||
Ok(Value::Multiasset(coin, multiasset))
|
Ok(Value::Multiasset(coin, multiasset))
|
||||||
}
|
}
|
||||||
|
|
@ -170,7 +170,7 @@ pub struct TransactionOutput {
|
||||||
pub amount: Value,
|
pub amount: Value,
|
||||||
|
|
||||||
#[n(2)]
|
#[n(2)]
|
||||||
pub datum_hash: Option<ByteVec>,
|
pub datum_hash: Option<Hash<32>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type PoolKeyhash = Hash<28>;
|
pub type PoolKeyhash = Hash<28>;
|
||||||
|
|
@ -699,6 +699,7 @@ pub enum TransactionBodyComponent {
|
||||||
RequiredSigners(MaybeIndefArray<AddrKeyhash>),
|
RequiredSigners(MaybeIndefArray<AddrKeyhash>),
|
||||||
NetworkId(NetworkId),
|
NetworkId(NetworkId),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'b> minicbor::decode::Decode<'b> for TransactionBodyComponent {
|
impl<'b> minicbor::decode::Decode<'b> for TransactionBodyComponent {
|
||||||
fn decode(d: &mut minicbor::Decoder<'b>) -> Result<Self, minicbor::decode::Error> {
|
fn decode(d: &mut minicbor::Decoder<'b>) -> Result<Self, minicbor::decode::Error> {
|
||||||
let key: u32 = d.decode()?;
|
let key: u32 = d.decode()?;
|
||||||
|
|
@ -1442,6 +1443,8 @@ mod tests {
|
||||||
include_str!("test_data/test19.block"),
|
include_str!("test_data/test19.block"),
|
||||||
// peculiar block with very BigInt in plutus code
|
// peculiar block with very BigInt in plutus code
|
||||||
include_str!("test_data/test20.block"),
|
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() {
|
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