Skip to content

Commit 7c3cbb3

Browse files
committed
Merge #325: Replace ExecTracker trait and add PruneTracker extension trait
3bf7cef bit_machine: add example StderrTracker which outputs stuff to stderr (Andrew Poelstra) 6013bd5 bit_machine: replace `ExecTracker` API with a much more general one (Andrew Poelstra) 4134976 bit_machine: add PruneTracker trait and RedeemNode::prune_with_tracker (Andrew Poelstra) ca4e497 bit_machine: move tracker stuff to its own module (Andrew Poelstra) eaa02d0 bit_machine: rename private new/move/drop methods and variants (Andrew Poelstra) 228a85f bit_machine: put pub(super) on all public methods of Frame (Andrew Poelstra) 8622a8f bit_machine: return concrete type from `as_bit_iter` (Andrew Poelstra) 7ecf394 BitIter: add ExactSizeIterator bound, size_hint and tests (Andrew Poelstra) Pull request description: Adds the ability for the execution tracker to track every visited node, to view the "input" (top read frame) of every node and the "output" (top write frame after execution) of every terminal node. Allows it to read this data in the form of a bit iterator, which is much easier to work with than the `&[UWORD]` that the old jet interface provided. Allows tracking "debug" nodes without special-purpose methods that enable/disable costly conversions. Also adds a `PruneTracker` extension trait which can be used to introspect or manipulate the pruning process. See #323 and #324 for motivation. Fixes #324. ACKs for top commit: KyrylR: ACK 3bf7cef Tree-SHA512: 81969779ca6f45d0ae3556475f10de6e661a8169c65409e15d697277e6806689b104644f5e5f25ce22d806f51fbfd892ebd0649ae8d24f2cd58bd551f4b476e7
2 parents 7654c80 + 3bf7cef commit 7c3cbb3

File tree

5 files changed

+357
-166
lines changed

5 files changed

+357
-166
lines changed

src/bit_encoding/bititer.rs

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,11 +194,29 @@ impl<I: Iterator<Item = u8>> Iterator for BitIter<I> {
194194
self.next()
195195
}
196196
}
197+
198+
fn size_hint(&self) -> (usize, Option<usize>) {
199+
let (lo, hi) = self.iter.size_hint();
200+
let adj = |n| 8 - self.read_bits + 8 * n;
201+
(adj(lo), hi.map(adj))
202+
}
203+
}
204+
205+
impl<I> core::iter::FusedIterator for BitIter<I> where
206+
I: Iterator<Item = u8> + core::iter::FusedIterator
207+
{
208+
}
209+
210+
impl<I> core::iter::ExactSizeIterator for BitIter<I> where
211+
I: Iterator<Item = u8> + core::iter::ExactSizeIterator
212+
{
197213
}
198214

199215
impl<'a> BitIter<std::iter::Copied<std::slice::Iter<'a, u8>>> {
200-
/// Creates a new bitwise iterator from a bytewise one. Equivalent
201-
/// to using `From`
216+
/// Creates a new bitwise iterator from a bytewise one.
217+
///
218+
/// Takes start and end indices *in bits*. If you want to use the entire slice,
219+
/// `BitIter::from` is equivalent and easier to call.
202220
pub fn byte_slice_window(sl: &'a [u8], start: usize, end: usize) -> Self {
203221
assert!(start <= end);
204222
assert!(end <= sl.len() * 8);
@@ -423,6 +441,8 @@ mod tests {
423441
#[test]
424442
fn empty_iter() {
425443
let mut iter = BitIter::from([].iter().cloned());
444+
assert_eq!(iter.len(), 0);
445+
assert!(iter.next().is_none());
426446
assert!(iter.next().is_none());
427447
assert_eq!(iter.read_bit(), Err(EarlyEndOfStreamError));
428448
assert_eq!(iter.read_u2(), Err(EarlyEndOfStreamError));
@@ -434,26 +454,34 @@ mod tests {
434454
#[test]
435455
fn one_bit_iter() {
436456
let mut iter = BitIter::from([0x80].iter().cloned());
457+
assert_eq!(iter.len(), 8);
437458
assert_eq!(iter.read_bit(), Ok(true));
459+
assert_eq!(iter.len(), 7);
438460
assert_eq!(iter.read_bit(), Ok(false));
461+
assert_eq!(iter.len(), 6);
439462
assert_eq!(iter.read_u8(), Err(EarlyEndOfStreamError));
440463
assert_eq!(iter.n_total_read(), 2);
441464
}
442465

443466
#[test]
444467
fn bit_by_bit() {
445468
let mut iter = BitIter::from([0x0f, 0xaa].iter().cloned());
469+
assert_eq!(iter.len(), 16);
446470
for _ in 0..4 {
447471
assert_eq!(iter.next(), Some(false));
448472
}
473+
assert_eq!(iter.len(), 12);
449474
for _ in 0..4 {
450475
assert_eq!(iter.next(), Some(true));
451476
}
477+
assert_eq!(iter.len(), 8);
452478
for _ in 0..4 {
453479
assert_eq!(iter.next(), Some(true));
454480
assert_eq!(iter.next(), Some(false));
455481
}
482+
assert_eq!(iter.len(), 0);
456483
assert_eq!(iter.next(), None);
484+
assert_eq!(iter.len(), 0);
457485
}
458486

459487
#[test]
@@ -480,7 +508,9 @@ mod tests {
480508
let data = [0x12, 0x23, 0x34];
481509

482510
let mut full = BitIter::byte_slice_window(&data, 0, 24);
511+
assert_eq!(full.len(), 24);
483512
assert_eq!(full.read_u8(), Ok(0x12));
513+
assert_eq!(full.len(), 16);
484514
assert_eq!(full.n_total_read(), 8);
485515
assert_eq!(full.read_u8(), Ok(0x23));
486516
assert_eq!(full.n_total_read(), 16);
@@ -489,7 +519,9 @@ mod tests {
489519
assert_eq!(full.read_u8(), Err(EarlyEndOfStreamError));
490520

491521
let mut mid = BitIter::byte_slice_window(&data, 8, 16);
522+
assert_eq!(mid.len(), 8);
492523
assert_eq!(mid.read_u8(), Ok(0x23));
524+
assert_eq!(mid.len(), 0);
493525
assert_eq!(mid.read_u8(), Err(EarlyEndOfStreamError));
494526

495527
let mut offs = BitIter::byte_slice_window(&data, 4, 20);
@@ -498,13 +530,21 @@ mod tests {
498530
assert_eq!(offs.read_u8(), Err(EarlyEndOfStreamError));
499531

500532
let mut shift1 = BitIter::byte_slice_window(&data, 1, 24);
533+
assert_eq!(shift1.len(), 23);
501534
assert_eq!(shift1.read_u8(), Ok(0x24));
535+
assert_eq!(shift1.len(), 15);
502536
assert_eq!(shift1.read_u8(), Ok(0x46));
537+
assert_eq!(shift1.len(), 7);
503538
assert_eq!(shift1.read_u8(), Err(EarlyEndOfStreamError));
539+
assert_eq!(shift1.len(), 7);
504540

505541
let mut shift7 = BitIter::byte_slice_window(&data, 7, 24);
542+
assert_eq!(shift7.len(), 17);
506543
assert_eq!(shift7.read_u8(), Ok(0x11));
544+
assert_eq!(shift7.len(), 9);
507545
assert_eq!(shift7.read_u8(), Ok(0x9a));
546+
assert_eq!(shift7.len(), 1);
508547
assert_eq!(shift7.read_u8(), Err(EarlyEndOfStreamError));
548+
assert_eq!(shift7.len(), 1);
509549
}
510550
}

src/bit_machine/frame.rs

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,28 @@ impl Frame {
3434
}
3535

3636
/// Return the start index of the frame inside the referenced data.
37-
pub fn start(&self) -> usize {
37+
pub(super) fn start(&self) -> usize {
3838
self.start
3939
}
4040

4141
/// Return the bit width of the frame.
42-
pub fn bit_width(&self) -> usize {
42+
pub(super) fn bit_width(&self) -> usize {
4343
self.len
4444
}
4545

46+
/// Makes a copy of the frame.
47+
///
48+
/// This copies *only the indices* and none of the underlying
49+
/// data. It is the caller's responsibility to make sure that
50+
/// the indices are not invalidated.
51+
pub(super) fn shallow_copy(&self) -> Self {
52+
Self {
53+
cursor: self.cursor,
54+
start: self.start,
55+
len: self.len,
56+
}
57+
}
58+
4659
/// Reset the cursor to the start.
4760
pub(super) fn reset_cursor(&mut self) {
4861
self.cursor = self.start;
@@ -104,7 +117,10 @@ impl Frame {
104117

105118
/// Extend the present frame with a read-only reference the the data
106119
/// and return the resulting struct.
107-
pub fn as_bit_iter<'a>(&self, data: &'a [u8]) -> BitIter<impl Iterator<Item = u8> + 'a> {
120+
pub(super) fn as_bit_iter<'a>(
121+
&self,
122+
data: &'a [u8],
123+
) -> BitIter<core::iter::Copied<core::slice::Iter<'a, u8>>> {
108124
BitIter::byte_slice_window(data, self.start, self.start + self.len)
109125
}
110126
}

0 commit comments

Comments
 (0)