From be477917f2de800fac24b0ee686dd23f426d3448 Mon Sep 17 00:00:00 2001 From: Kasey White Date: Wed, 8 Jun 2022 03:33:09 -0400 Subject: [PATCH] fix: fixed edge cases to get flat encode and decode working with stress test case --- crates/cli/src/main.rs | 4 +- crates/flat/src/decode/decoder.rs | 10 +++-- crates/flat/src/encode/encoder.rs | 9 +++-- crates/uplc/src/builtins.rs | 64 +++++++++++++++---------------- crates/uplc/src/flat.rs | 10 +++-- 5 files changed, 52 insertions(+), 45 deletions(-) diff --git a/crates/cli/src/main.rs b/crates/cli/src/main.rs index 80f6a615..634ff773 100644 --- a/crates/cli/src/main.rs +++ b/crates/cli/src/main.rs @@ -36,7 +36,9 @@ fn main() -> anyhow::Result<()> { let program = Program::::from_flat(&bytes)?; - println!("{:#?}", program); + let encoded_flat = program.to_flat()?; + println!("{}", encoded_flat.len()); + assert!(bytes == encoded_flat) } }, } diff --git a/crates/flat/src/decode/decoder.rs b/crates/flat/src/decode/decoder.rs index 1fb02b73..c22bbe58 100644 --- a/crates/flat/src/decode/decoder.rs +++ b/crates/flat/src/decode/decoder.rs @@ -2,10 +2,11 @@ use crate::{decode::Decode, zigzag}; use super::Error; +#[derive(Debug)] pub struct Decoder<'b> { - buffer: &'b [u8], - used_bits: i64, - pos: usize, + pub buffer: &'b [u8], + pub used_bits: i64, + pub pos: usize, } impl<'b> Decoder<'b> { @@ -71,7 +72,7 @@ impl<'b> Decoder<'b> { let mut final_word: usize = 0; let mut shl: usize = 0; // continue looping if lead bit is 1 otherwise exit - while leading_bit == 1 { + while leading_bit > 0 { let word8 = self.bits8(8)?; let word7 = word8 & 127; final_word |= (word7 as usize) << shl; @@ -134,6 +135,7 @@ impl<'b> Decoder<'b> { blk_len = self.buffer[self.pos]; } + self.pos += 1; Ok(blk_array) } diff --git a/crates/flat/src/encode/encoder.rs b/crates/flat/src/encode/encoder.rs index 4f372d63..9793735d 100644 --- a/crates/flat/src/encode/encoder.rs +++ b/crates/flat/src/encode/encoder.rs @@ -102,16 +102,17 @@ impl Encoder { } pub fn word(&mut self, c: usize) -> &mut Self { + let mut d = c; loop { - let mut w = (c & 127) as u8; - let c = c >> 7; + let mut w = (d & 127) as u8; + d >>= 7; - if c != 0 { + if d != 0 { w |= 128; } self.bits(8, w); - if c == 0 { + if d == 0 { break; } } diff --git a/crates/uplc/src/builtins.rs b/crates/uplc/src/builtins.rs index d11d7292..2d7f9135 100644 --- a/crates/uplc/src/builtins.rs +++ b/crates/uplc/src/builtins.rs @@ -32,52 +32,52 @@ pub enum DefaultFunction { Sha3_256 = 19, Blake2b_256 = 20, VerifySignature = 21, - VerifyEcdsaSecp256k1Signature = 22, - VerifySchnorrSecp256k1Signature = 23, + VerifyEcdsaSecp256k1Signature = 52, + VerifySchnorrSecp256k1Signature = 53, // String functions - AppendString = 24, - EqualsString = 25, - EncodeUtf8 = 26, - DecodeUtf8 = 27, + AppendString = 22, + EqualsString = 23, + EncodeUtf8 = 24, + DecodeUtf8 = 25, // Bool function - IfThenElse = 28, + IfThenElse = 26, // Unit function - ChooseUnit = 29, + ChooseUnit = 27, // Tracing function - Trace = 30, + Trace = 28, // Pairs functions - FstPair = 31, - SndPair = 32, + FstPair = 29, + SndPair = 30, // List functions - ChooseList = 33, - MkCons = 34, - HeadList = 35, - TailList = 36, - NullList = 37, + ChooseList = 31, + MkCons = 32, + HeadList = 33, + TailList = 34, + NullList = 35, // Data functions // It is convenient to have a "choosing" function for a data type that has more than two // constructors to get pattern matching over it and we may end up having multiple such data // types, hence we include the name of the data type as a suffix. - ChooseData = 38, - ConstrData = 39, - MapData = 40, - ListData = 41, - IData = 42, - BData = 43, - UnConstrData = 44, - UnMapData = 45, - UnListData = 46, - UnIData = 47, - UnBData = 48, - EqualsData = 49, - SerialiseData = 50, + ChooseData = 36, + ConstrData = 37, + MapData = 38, + ListData = 39, + IData = 40, + BData = 41, + UnConstrData = 42, + UnMapData = 43, + UnListData = 44, + UnIData = 45, + UnBData = 46, + EqualsData = 47, + SerialiseData = 51, // Misc constructors // Constructors that we need for constructing e.g. Data. Polymorphic builtin // constructors are often problematic (See note [Representable built-in // functions over polymorphic built-in types]) - MkPairData = 51, - MkNilData = 52, - MkNilPairData = 53, + MkPairData = 48, + MkNilData = 49, + MkNilPairData = 50, } impl TryFrom for DefaultFunction { diff --git a/crates/uplc/src/flat.rs b/crates/uplc/src/flat.rs index 38a34343..95ec66ff 100644 --- a/crates/uplc/src/flat.rs +++ b/crates/uplc/src/flat.rs @@ -1,3 +1,5 @@ +use std::fmt::Debug; + use flat::{ de::{self, Decode, Decoder}, en::{self, Encode, Encoder}, @@ -18,11 +20,11 @@ pub trait Binder<'b>: Encode + Decode<'b> { fn binder_decode(d: &mut Decoder) -> Result; } -impl<'b, T> Flat<'b> for Program where T: Binder<'b> {} +impl<'b, T> Flat<'b> for Program where T: Binder<'b> + Debug {} impl<'b, T> Program where - T: Binder<'b>, + T: Binder<'b> + Debug, { // convenient so that people don't need to depend on the flat crate // directly to call programs flat function @@ -45,7 +47,7 @@ where impl<'b, T> Encode for Program where - T: Binder<'b>, + T: Binder<'b> + Debug, { fn encode(&self, e: &mut Encoder) -> Result<(), en::Error> { let (major, minor, patch) = self.version; @@ -73,7 +75,7 @@ where impl<'b, T> Encode for Term where - T: Binder<'b>, + T: Binder<'b> + Debug, { fn encode(&self, e: &mut Encoder) -> Result<(), en::Error> { match self {