fix: fixed edge cases to get flat encode and decode working with stress test case

This commit is contained in:
Kasey White 2022-06-08 03:33:09 -04:00
parent 21d713ece3
commit be477917f2
5 changed files with 52 additions and 45 deletions

View File

@ -36,7 +36,9 @@ fn main() -> anyhow::Result<()> {
let program = Program::<FakeNamedDeBruijn>::from_flat(&bytes)?; let program = Program::<FakeNamedDeBruijn>::from_flat(&bytes)?;
println!("{:#?}", program); let encoded_flat = program.to_flat()?;
println!("{}", encoded_flat.len());
assert!(bytes == encoded_flat)
} }
}, },
} }

View File

@ -2,10 +2,11 @@ use crate::{decode::Decode, zigzag};
use super::Error; use super::Error;
#[derive(Debug)]
pub struct Decoder<'b> { pub struct Decoder<'b> {
buffer: &'b [u8], pub buffer: &'b [u8],
used_bits: i64, pub used_bits: i64,
pos: usize, pub pos: usize,
} }
impl<'b> Decoder<'b> { impl<'b> Decoder<'b> {
@ -71,7 +72,7 @@ impl<'b> Decoder<'b> {
let mut final_word: usize = 0; let mut final_word: usize = 0;
let mut shl: usize = 0; let mut shl: usize = 0;
// continue looping if lead bit is 1 otherwise exit // continue looping if lead bit is 1 otherwise exit
while leading_bit == 1 { while leading_bit > 0 {
let word8 = self.bits8(8)?; let word8 = self.bits8(8)?;
let word7 = word8 & 127; let word7 = word8 & 127;
final_word |= (word7 as usize) << shl; final_word |= (word7 as usize) << shl;
@ -134,6 +135,7 @@ impl<'b> Decoder<'b> {
blk_len = self.buffer[self.pos]; blk_len = self.buffer[self.pos];
} }
self.pos += 1;
Ok(blk_array) Ok(blk_array)
} }

View File

@ -102,16 +102,17 @@ impl Encoder {
} }
pub fn word(&mut self, c: usize) -> &mut Self { pub fn word(&mut self, c: usize) -> &mut Self {
let mut d = c;
loop { loop {
let mut w = (c & 127) as u8; let mut w = (d & 127) as u8;
let c = c >> 7; d >>= 7;
if c != 0 { if d != 0 {
w |= 128; w |= 128;
} }
self.bits(8, w); self.bits(8, w);
if c == 0 { if d == 0 {
break; break;
} }
} }

View File

@ -32,52 +32,52 @@ pub enum DefaultFunction {
Sha3_256 = 19, Sha3_256 = 19,
Blake2b_256 = 20, Blake2b_256 = 20,
VerifySignature = 21, VerifySignature = 21,
VerifyEcdsaSecp256k1Signature = 22, VerifyEcdsaSecp256k1Signature = 52,
VerifySchnorrSecp256k1Signature = 23, VerifySchnorrSecp256k1Signature = 53,
// String functions // String functions
AppendString = 24, AppendString = 22,
EqualsString = 25, EqualsString = 23,
EncodeUtf8 = 26, EncodeUtf8 = 24,
DecodeUtf8 = 27, DecodeUtf8 = 25,
// Bool function // Bool function
IfThenElse = 28, IfThenElse = 26,
// Unit function // Unit function
ChooseUnit = 29, ChooseUnit = 27,
// Tracing function // Tracing function
Trace = 30, Trace = 28,
// Pairs functions // Pairs functions
FstPair = 31, FstPair = 29,
SndPair = 32, SndPair = 30,
// List functions // List functions
ChooseList = 33, ChooseList = 31,
MkCons = 34, MkCons = 32,
HeadList = 35, HeadList = 33,
TailList = 36, TailList = 34,
NullList = 37, NullList = 35,
// Data functions // Data functions
// It is convenient to have a "choosing" function for a data type that has more than two // 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 // 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. // types, hence we include the name of the data type as a suffix.
ChooseData = 38, ChooseData = 36,
ConstrData = 39, ConstrData = 37,
MapData = 40, MapData = 38,
ListData = 41, ListData = 39,
IData = 42, IData = 40,
BData = 43, BData = 41,
UnConstrData = 44, UnConstrData = 42,
UnMapData = 45, UnMapData = 43,
UnListData = 46, UnListData = 44,
UnIData = 47, UnIData = 45,
UnBData = 48, UnBData = 46,
EqualsData = 49, EqualsData = 47,
SerialiseData = 50, SerialiseData = 51,
// Misc constructors // Misc constructors
// Constructors that we need for constructing e.g. Data. Polymorphic builtin // Constructors that we need for constructing e.g. Data. Polymorphic builtin
// constructors are often problematic (See note [Representable built-in // constructors are often problematic (See note [Representable built-in
// functions over polymorphic built-in types]) // functions over polymorphic built-in types])
MkPairData = 51, MkPairData = 48,
MkNilData = 52, MkNilData = 49,
MkNilPairData = 53, MkNilPairData = 50,
} }
impl TryFrom<u8> for DefaultFunction { impl TryFrom<u8> for DefaultFunction {

View File

@ -1,3 +1,5 @@
use std::fmt::Debug;
use flat::{ use flat::{
de::{self, Decode, Decoder}, de::{self, Decode, Decoder},
en::{self, Encode, Encoder}, en::{self, Encode, Encoder},
@ -18,11 +20,11 @@ pub trait Binder<'b>: Encode + Decode<'b> {
fn binder_decode(d: &mut Decoder) -> Result<Self, de::Error>; fn binder_decode(d: &mut Decoder) -> Result<Self, de::Error>;
} }
impl<'b, T> Flat<'b> for Program<T> where T: Binder<'b> {} impl<'b, T> Flat<'b> for Program<T> where T: Binder<'b> + Debug {}
impl<'b, T> Program<T> impl<'b, T> Program<T>
where where
T: Binder<'b>, T: Binder<'b> + Debug,
{ {
// convenient so that people don't need to depend on the flat crate // convenient so that people don't need to depend on the flat crate
// directly to call programs flat function // directly to call programs flat function
@ -45,7 +47,7 @@ where
impl<'b, T> Encode for Program<T> impl<'b, T> Encode for Program<T>
where where
T: Binder<'b>, T: Binder<'b> + Debug,
{ {
fn encode(&self, e: &mut Encoder) -> Result<(), en::Error> { fn encode(&self, e: &mut Encoder) -> Result<(), en::Error> {
let (major, minor, patch) = self.version; let (major, minor, patch) = self.version;
@ -73,7 +75,7 @@ where
impl<'b, T> Encode for Term<T> impl<'b, T> Encode for Term<T>
where where
T: Binder<'b>, T: Binder<'b> + Debug,
{ {
fn encode(&self, e: &mut Encoder) -> Result<(), en::Error> { fn encode(&self, e: &mut Encoder) -> Result<(), en::Error> {
match self { match self {