Skip to content

Commit 7c86811

Browse files
committed
feat(tasm_object): Add decode_iter impls for various basic types
Needed for testing downstream in neptune-core.
1 parent 15ed18d commit 7c86811

File tree

1 file changed

+137
-14
lines changed

1 file changed

+137
-14
lines changed

tasm-lib/src/structure/manual_tasm_object_implementations.rs

Lines changed: 137 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
use itertools::Itertools;
2+
use num::Zero;
23
use triton_vm::prelude::*;
34
use twenty_first::error::BFieldCodecError;
5+
use twenty_first::math::x_field_element::EXTENSION_DEGREE;
46

57
use crate::{data_type::DataType, prelude::TasmObject};
68

@@ -219,8 +221,11 @@ impl TasmObject for BFieldElement {
219221
unreachable!("Size is known statically for BFieldElement encoding")
220222
}
221223

222-
fn decode_iter<Itr: Iterator<Item = BFieldElement>>(_iterator: &mut Itr) -> Result<Box<Self>> {
223-
todo!()
224+
fn decode_iter<Itr: Iterator<Item = BFieldElement>>(iterator: &mut Itr) -> Result<Box<Self>> {
225+
match iterator.next() {
226+
Some(word) => Ok(Box::new(word)),
227+
None => Err(Box::new(BFieldCodecError::SequenceTooShort)),
228+
}
224229
}
225230
}
226231

@@ -247,8 +252,16 @@ impl TasmObject for XFieldElement {
247252
unreachable!("Size is known statically for XFieldElement encoding")
248253
}
249254

250-
fn decode_iter<Itr: Iterator<Item = BFieldElement>>(_iterator: &mut Itr) -> Result<Box<Self>> {
251-
todo!()
255+
fn decode_iter<Itr: Iterator<Item = BFieldElement>>(iterator: &mut Itr) -> Result<Box<Self>> {
256+
let mut xfe = XFieldElement::zero();
257+
for i in 0..EXTENSION_DEGREE {
258+
match iterator.next() {
259+
Some(word) => xfe.coefficients[i] = word,
260+
None => return Err(Box::new(BFieldCodecError::SequenceTooShort)),
261+
}
262+
}
263+
264+
Ok(Box::new(xfe))
252265
}
253266
}
254267

@@ -275,8 +288,16 @@ impl TasmObject for Digest {
275288
unreachable!("Size is known statically for Digest encoding")
276289
}
277290

278-
fn decode_iter<Itr: Iterator<Item = BFieldElement>>(_iterator: &mut Itr) -> Result<Box<Self>> {
279-
todo!()
291+
fn decode_iter<Itr: Iterator<Item = BFieldElement>>(iterator: &mut Itr) -> Result<Box<Self>> {
292+
let mut digest = Digest::default();
293+
for i in 0..Digest::LEN {
294+
match iterator.next() {
295+
Some(word) => digest.0[i] = word,
296+
None => return Err(Box::new(BFieldCodecError::SequenceTooShort)),
297+
}
298+
}
299+
300+
Ok(Box::new(digest))
280301
}
281302
}
282303

@@ -303,8 +324,18 @@ impl TasmObject for bool {
303324
unreachable!("Size is known statically for u32 encoding")
304325
}
305326

306-
fn decode_iter<Itr: Iterator<Item = BFieldElement>>(_iterator: &mut Itr) -> Result<Box<Self>> {
307-
todo!()
327+
fn decode_iter<Itr: Iterator<Item = BFieldElement>>(iterator: &mut Itr) -> Result<Box<Self>> {
328+
match iterator.next() {
329+
Some(word) => {
330+
let bool_val: bool = match word.value() {
331+
0 => false,
332+
1 => true,
333+
_ => return Err(Box::new(BFieldCodecError::ElementOutOfRange)),
334+
};
335+
Ok(Box::new(bool_val))
336+
}
337+
None => Err(Box::new(BFieldCodecError::SequenceTooShort)),
338+
}
308339
}
309340
}
310341

@@ -331,8 +362,17 @@ impl TasmObject for u32 {
331362
unreachable!("Size is known statically for u32 encoding")
332363
}
333364

334-
fn decode_iter<Itr: Iterator<Item = BFieldElement>>(_iterator: &mut Itr) -> Result<Box<Self>> {
335-
todo!()
365+
fn decode_iter<Itr: Iterator<Item = BFieldElement>>(iterator: &mut Itr) -> Result<Box<Self>> {
366+
match iterator.next() {
367+
Some(word) => {
368+
let u32_val: u32 = match word.value().try_into() {
369+
Ok(u32_val) => u32_val,
370+
Err(_) => return Err(Box::new(BFieldCodecError::ElementOutOfRange)),
371+
};
372+
Ok(Box::new(u32_val))
373+
}
374+
None => Err(Box::new(BFieldCodecError::SequenceTooShort)),
375+
}
336376
}
337377
}
338378

@@ -359,8 +399,22 @@ impl TasmObject for u64 {
359399
unreachable!("Size is known statically for u64 encoding")
360400
}
361401

362-
fn decode_iter<Itr: Iterator<Item = BFieldElement>>(_iterator: &mut Itr) -> Result<Box<Self>> {
363-
todo!()
402+
fn decode_iter<Itr: Iterator<Item = BFieldElement>>(iterator: &mut Itr) -> Result<Box<Self>> {
403+
let mut val: u64 = 0;
404+
for i in 0..u64::static_length().unwrap() {
405+
match iterator.next() {
406+
Some(word) => {
407+
let u32_val: u32 = match word.value().try_into() {
408+
Ok(u32_val) => u32_val,
409+
Err(_) => return Err(Box::new(BFieldCodecError::ElementOutOfRange)),
410+
};
411+
val |= (u32_val as u64) << (32 * i);
412+
}
413+
None => return Err(Box::new(BFieldCodecError::SequenceTooShort)),
414+
}
415+
}
416+
417+
Ok(Box::new(val))
364418
}
365419
}
366420

@@ -387,8 +441,22 @@ impl TasmObject for u128 {
387441
unreachable!("Size is known statically for u128 encoding")
388442
}
389443

390-
fn decode_iter<Itr: Iterator<Item = BFieldElement>>(_iterator: &mut Itr) -> Result<Box<Self>> {
391-
todo!()
444+
fn decode_iter<Itr: Iterator<Item = BFieldElement>>(iterator: &mut Itr) -> Result<Box<Self>> {
445+
let mut val: u128 = 0;
446+
for i in 0..u128::static_length().unwrap() {
447+
match iterator.next() {
448+
Some(word) => {
449+
let u32_val: u32 = match word.value().try_into() {
450+
Ok(u32_val) => u32_val,
451+
Err(_) => return Err(Box::new(BFieldCodecError::ElementOutOfRange)),
452+
};
453+
val |= (u32_val as u128) << (32 * i);
454+
}
455+
None => return Err(Box::new(BFieldCodecError::SequenceTooShort)),
456+
}
457+
}
458+
459+
Ok(Box::new(val))
392460
}
393461
}
394462

@@ -689,3 +757,58 @@ impl<T: TasmObject + BFieldCodec> TasmObject for Option<T> {
689757
)
690758
}
691759
}
760+
761+
#[cfg(test)]
762+
mod tests {
763+
use std::collections::HashMap;
764+
use std::fmt::Debug;
765+
766+
use rand::random;
767+
768+
use crate::memory::encode_to_memory;
769+
770+
use super::*;
771+
772+
fn decode_iter_prop<T: TasmObject + BFieldCodec + Eq + Debug>(obj_written: T) {
773+
let mut memory = HashMap::default();
774+
let address = random();
775+
encode_to_memory(&mut memory, address, &obj_written);
776+
let obj_read = *T::decode_from_memory(&memory, address).unwrap();
777+
assert_eq!(obj_written, obj_read);
778+
}
779+
780+
#[test]
781+
fn decode_iter_bfe() {
782+
decode_iter_prop::<BFieldElement>(random());
783+
}
784+
785+
#[test]
786+
fn decode_iter_xfe() {
787+
decode_iter_prop::<XFieldElement>(random());
788+
}
789+
790+
#[test]
791+
fn decode_iter_digest() {
792+
decode_iter_prop::<Digest>(random());
793+
}
794+
795+
#[test]
796+
fn decode_iter_bool() {
797+
decode_iter_prop::<bool>(random());
798+
}
799+
800+
#[test]
801+
fn decode_iter_u32() {
802+
decode_iter_prop::<u32>(random());
803+
}
804+
805+
#[test]
806+
fn decode_iter_u64() {
807+
decode_iter_prop::<u64>(random());
808+
}
809+
810+
#[test]
811+
fn decode_iter_u128() {
812+
decode_iter_prop::<u128>(random());
813+
}
814+
}

0 commit comments

Comments
 (0)