Skip to content

Commit 6fa6bcd

Browse files
committed
jets-bench: fix multiple issues with Ctx8 encoding
* changes `var_len_buf_from_slice` to interpret its `n` such that it's reading the type (2^8)^<2^n rather than (2^8)^<2^(n+1); subtract 1 from all instances of `n` except the loop counter. (Previously we were looping the wrong number of times, which this fixes.) * calls `var_len_buf_from_slice` with n = 6, which matches the type signature for Ctx8. Before we were calling with n = 8 which was just wrong * Changes `SimplicityCtx8::buffer` to have type `[u8; 64]` instead of the wrong `[u8; 512]` * Changes the nonsense "v.len() >= 1 << n" comparison to one that checks the bits of v.len() * Corrects various off-by-one errors See #318 for more information.
1 parent 06e656a commit 6fa6bcd

File tree

1 file changed

+19
-14
lines changed

1 file changed

+19
-14
lines changed

jets-bench/src/data_structures.rs

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use simplicity::{
1818
/// length.
1919
#[derive(Clone)]
2020
pub struct SimplicityCtx8 {
21-
buffer: [u8; 512],
21+
buffer: [u8; 64],
2222
h: [u32; 8],
2323
length: usize,
2424
}
@@ -31,7 +31,7 @@ impl Default for SimplicityCtx8 {
3131
0x5be0cd19,
3232
],
3333
length: 0,
34-
buffer: [0; 512],
34+
buffer: [0; 64],
3535
}
3636
}
3737
}
@@ -45,24 +45,29 @@ impl SimplicityCtx8 {
4545
}
4646
}
4747

48-
/// Read bytes from a Simplicity buffer of type (TWO^8)^<2^(n+1) as [`Value`].
48+
/// Read bytes from a Simplicity buffer of type (TWO^8)^<2^n as [`Value`].
4949
/// The notation X^<2 is notation for the type (S X)
5050
/// The notation X^<(2*n) is notation for the type S (X^n) * X^<n
5151
///
52-
/// Cannot represent >= 2**16 bytes 0 <= n < 16 as simplicity consensus rule.
52+
/// There is a precondition that 2 <= n <= 16.
5353
///
5454
/// # Panics:
5555
///
56-
/// Panics if the length of the slice is >= 2^(n + 1) bytes
56+
/// Panics if the length of the slice is >= 2^n bytes, if n <= 1, or if n > 16.
5757
pub fn var_len_buf_from_slice(v: &[u8], mut n: usize) -> Result<Value, EarlyEndOfStreamError> {
58-
// Simplicity consensus rule for n < 16 while reading buffers.
59-
assert!(n < 16);
60-
assert!(v.len() < (1 << (n + 1)));
58+
// This precondition is because "n = 0" is undefined and "n = 1"
59+
// is the same as (S X) which is not a "buffer", just an option.
60+
assert!(n >= 2);
61+
// This precondition can probably be removed or relaxed, though
62+
// we have no need to do so and it may require changing the type
63+
// of 'n' to something larger.
64+
assert!(n <= 16);
65+
assert!(v.len() < 1 << n);
6166
let mut iter = BitIter::new(v.iter().copied());
6267
let mut res = None;
63-
while n > 0 {
64-
let ty = Final::two_two_n(n);
65-
let v = if v.len() >= (1 << (n + 1)) {
68+
for i in (0..n).rev() {
69+
let ty = Final::two_two_n(i + 3);
70+
let v = if v.len() & 1 << i != 0 {
6671
let val = Value::from_compact_bits(&mut iter, &ty)?;
6772
Value::some(val)
6873
} else {
@@ -72,8 +77,8 @@ pub fn var_len_buf_from_slice(v: &[u8], mut n: usize) -> Result<Value, EarlyEndO
7277
Some(prod) => Some(Value::product(prod, v)),
7378
None => Some(v),
7479
};
75-
n -= 1;
7680
}
81+
assert_eq!(iter.next(), None);
7782
Ok(res.unwrap_or(Value::unit()))
7883
}
7984

@@ -157,8 +162,8 @@ pub trait SimplicityEncode {
157162

158163
impl SimplicityEncode for SimplicityCtx8 {
159164
fn value(&self) -> Value {
160-
let buf_len = self.length % 512;
161-
let buf = var_len_buf_from_slice(&self.buffer[..buf_len], 8).unwrap();
165+
let buf_len = self.length % 64;
166+
let buf = var_len_buf_from_slice(&self.buffer[..buf_len], 6).unwrap();
162167
let len = Value::u64(self.length as u64);
163168
// convert to 32 byte array
164169
let mut arr = [0u8; 32];

0 commit comments

Comments
 (0)