Skip to content

Commit aa0b02a

Browse files
committed
Merge rust-bitcoin#5103: Remove length prefix from the BytesEncoder
c9c41f7 Remove BytesEncoder::with_length_prefix (Tobin C. Harding) ccd86cb Use an Encoder2 when encoding a script (Tobin C. Harding) Pull request description: First remove usage of `BytesEncoder::with_length_prefix` when encoding a script. Then remove the constructor and the length prefix all together from the `BytesEncoder`. This is based on discussion in rust-bitcoin#5097, as suggested originally by jrakibi, and is a cleaner alternative to my first effort in rust-bitcoin#5098 (which tried to remove the _other_ constructor). The idea here is to have only one constructor per encoder so an encoders usage is unambiguous. ACKs for top commit: jrakibi: ACK c9c41f7 apoelstra: ACK c9c41f7; successfully ran local tests Tree-SHA512: 3629b5359788fb0b8fa9d0608bad65d025005b09ea3b917014d97ad34889ae3f5549833177fd661d89ba6881ab6dceb8e96975484bd11ef60d77e1f2a8799854
2 parents d8ad98a + c9c41f7 commit aa0b02a

File tree

3 files changed

+24
-133
lines changed

3 files changed

+24
-133
lines changed

consensus_encoding/src/encode/encoders.rs

Lines changed: 12 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -22,38 +22,21 @@ const SIZE: usize = compact_size::MAX_ENCODING_SIZE;
2222
/// An encoder for a single byte slice.
2323
pub struct BytesEncoder<'sl> {
2424
sl: Option<&'sl [u8]>,
25-
compact_size: Option<ArrayVec<u8, SIZE>>,
2625
}
2726

2827
impl<'sl> BytesEncoder<'sl> {
2928
/// Constructs a byte encoder which encodes the given byte slice, with no length prefix.
3029
pub fn without_length_prefix(sl: &'sl [u8]) -> Self {
31-
Self { sl: Some(sl), compact_size: None }
32-
}
33-
34-
/// Constructs a byte encoder which encodes the given byte slice, with the length prefix.
35-
pub fn with_length_prefix(sl: &'sl [u8]) -> Self {
36-
Self { sl: Some(sl), compact_size: Some(compact_size::encode(sl.len())) }
30+
Self { sl: Some(sl) }
3731
}
3832
}
3933

4034
impl Encoder for BytesEncoder<'_> {
41-
fn current_chunk(&self) -> Option<&[u8]> {
42-
if let Some(compact_size) = self.compact_size.as_ref() {
43-
Some(compact_size)
44-
} else {
45-
self.sl
46-
}
47-
}
35+
fn current_chunk(&self) -> Option<&[u8]> { self.sl }
4836

4937
fn advance(&mut self) -> bool {
50-
if self.compact_size.is_some() {
51-
self.compact_size = None;
52-
true
53-
} else {
54-
self.sl = None;
55-
false
56-
}
38+
self.sl = None;
39+
false
5740
}
5841
}
5942

@@ -275,7 +258,7 @@ impl Encoder for CompactSizeEncoder {
275258
mod tests {
276259
use super::*;
277260

278-
struct TestBytes<'a>(&'a [u8], bool);
261+
struct TestBytes<'a>(&'a [u8]);
279262

280263
impl<'a> Encodable for TestBytes<'a> {
281264
type Encoder<'s>
@@ -284,11 +267,7 @@ mod tests {
284267
Self: 's;
285268

286269
fn encoder(&self) -> Self::Encoder<'_> {
287-
if self.1 {
288-
BytesEncoder::with_length_prefix(self.0)
289-
} else {
290-
BytesEncoder::without_length_prefix(self.0)
291-
}
270+
BytesEncoder::without_length_prefix(self.0)
292271
}
293272
}
294273

@@ -327,7 +306,7 @@ mod tests {
327306
fn encode_byte_slice_without_prefix() {
328307
// Should have one chunk with the byte data, then exhausted.
329308
let obj = [1u8, 2, 3];
330-
let test_bytes = TestBytes(&obj, false);
309+
let test_bytes = TestBytes(&obj);
331310
let mut encoder = test_bytes.encoder();
332311

333312
assert_eq!(encoder.current_chunk(), Some(&[1u8, 2, 3][..]));
@@ -339,41 +318,14 @@ mod tests {
339318
fn encode_empty_byte_slice_without_prefix() {
340319
// Should have one empty chunk, then exhausted.
341320
let obj = [];
342-
let test_bytes = TestBytes(&obj, false);
321+
let test_bytes = TestBytes(&obj);
343322
let mut encoder = test_bytes.encoder();
344323

345324
assert_eq!(encoder.current_chunk(), Some(&[][..]));
346325
assert!(!encoder.advance());
347326
assert_eq!(encoder.current_chunk(), None);
348327
}
349328

350-
#[test]
351-
fn encode_byte_slice_with_prefix() {
352-
// Should have length prefix chunk, then data chunk, then exhausted.
353-
let obj = [1u8, 2, 3];
354-
let test_bytes = TestBytes(&obj, true);
355-
let mut encoder = test_bytes.encoder();
356-
357-
assert_eq!(encoder.current_chunk(), Some(&[3u8][..]));
358-
assert!(encoder.advance());
359-
assert_eq!(encoder.current_chunk(), Some(&[1u8, 2, 3][..]));
360-
assert!(!encoder.advance());
361-
assert_eq!(encoder.current_chunk(), None);
362-
}
363-
364-
#[test]
365-
fn encode_empty_byte_slice_with_prefix() {
366-
// Should have length prefix chunk (0), then empty data chunk, then exhausted.
367-
let obj = [];
368-
let test_bytes = TestBytes(&obj, true);
369-
let mut encoder = test_bytes.encoder();
370-
371-
assert_eq!(encoder.current_chunk(), Some(&[0u8][..]));
372-
assert!(encoder.advance());
373-
assert_eq!(encoder.current_chunk(), Some(&[][..]));
374-
assert!(!encoder.advance());
375-
assert_eq!(encoder.current_chunk(), None);
376-
}
377329

378330
#[test]
379331
fn encode_slice_with_elements() {
@@ -444,22 +396,6 @@ mod tests {
444396
assert_eq!(encoder.current_chunk(), None);
445397
}
446398

447-
#[test]
448-
fn encode_two_byte_slices_mixed() {
449-
// Should encode byte slice without prefix, then with prefix, then exhausted.
450-
let enc1 = TestBytes(&[0xAA, 0xBB], false).encoder();
451-
let enc2 = TestBytes(&[0xCC], true).encoder();
452-
let mut encoder = Encoder2::new(enc1, enc2);
453-
454-
assert_eq!(encoder.current_chunk(), Some(&[0xAA, 0xBB][..]));
455-
assert!(encoder.advance());
456-
assert_eq!(encoder.current_chunk(), Some(&[1u8][..]));
457-
assert!(encoder.advance());
458-
assert_eq!(encoder.current_chunk(), Some(&[0xCC][..]));
459-
assert!(!encoder.advance());
460-
assert_eq!(encoder.current_chunk(), None);
461-
}
462-
463399
#[test]
464400
fn encode_three_arrays() {
465401
// Should encode three arrays in sequence, then exhausted.
@@ -525,13 +461,11 @@ mod tests {
525461

526462
#[test]
527463
fn encode_mixed_composition_with_byte_slices() {
528-
// Should encode byte slice with prefix, then array, then exhausted.
529-
let enc1 = TestBytes(&[0xFF, 0xEE], true).encoder();
464+
// Should encode byte slice, then array, then exhausted.
465+
let enc1 = TestBytes(&[0xFF, 0xEE]).encoder();
530466
let enc2 = TestArray([0xDD, 0xCC]).encoder();
531467
let mut encoder = Encoder2::new(enc1, enc2);
532468

533-
assert_eq!(encoder.current_chunk(), Some(&[2u8][..]));
534-
assert!(encoder.advance());
535469
assert_eq!(encoder.current_chunk(), Some(&[0xFF, 0xEE][..]));
536470
assert!(encoder.advance());
537471
assert_eq!(encoder.current_chunk(), Some(&[0xDD, 0xCC][..]));
@@ -627,35 +561,13 @@ mod tests {
627561
assert_eq!(encoder.current_chunk(), None);
628562
}
629563

630-
#[test]
631-
fn encode_slice_with_mixed_byte_encoders() {
632-
// Should encode slice of mixed byte encoders with different prefix settings, then exhausted.
633-
let bytes1 = TestBytes(&[0x11, 0x12], false);
634-
let bytes2 = TestBytes(&[0x21, 0x22, 0x23], true);
635-
let bytes3 = TestBytes(&[], false);
636-
let slice = &[bytes1, bytes2, bytes3];
637-
let mut encoder = SliceEncoder::with_length_prefix(slice);
638-
639-
assert_eq!(encoder.current_chunk(), Some(&[3u8][..]));
640-
assert!(encoder.advance());
641-
assert_eq!(encoder.current_chunk(), Some(&[0x11, 0x12][..]));
642-
assert!(encoder.advance());
643-
assert_eq!(encoder.current_chunk(), Some(&[3u8][..]));
644-
assert!(encoder.advance());
645-
assert_eq!(encoder.current_chunk(), Some(&[0x21, 0x22, 0x23][..]));
646-
assert!(encoder.advance());
647-
assert_eq!(encoder.current_chunk(), Some(&[][..]));
648-
assert!(!encoder.advance());
649-
assert_eq!(encoder.current_chunk(), None);
650-
}
651-
652564
#[test]
653565
fn encode_complex_nested_structure() {
654566
// Should encode header, slice with elements, and footer with prefix, then exhausted.
655-
let header = TestBytes(&[0xDE, 0xAD], false).encoder();
567+
let header = TestBytes(&[0xDE, 0xAD]).encoder();
656568
let data_slice = &[TestArray([0x01, 0x02]), TestArray([0x03, 0x04])];
657569
let slice_enc = SliceEncoder::with_length_prefix(data_slice);
658-
let footer = TestBytes(&[0xBE, 0xEF], true).encoder();
570+
let footer = TestBytes(&[0xBE, 0xEF]).encoder();
659571
let mut encoder = Encoder3::new(header, slice_enc, footer);
660572

661573
assert_eq!(encoder.current_chunk(), Some(&[0xDE, 0xAD][..]));
@@ -666,8 +578,6 @@ mod tests {
666578
assert!(encoder.advance());
667579
assert_eq!(encoder.current_chunk(), Some(&[0x03, 0x04][..]));
668580
assert!(encoder.advance());
669-
assert_eq!(encoder.current_chunk(), Some(&[2u8][..]));
670-
assert!(encoder.advance());
671581
assert_eq!(encoder.current_chunk(), Some(&[0xBE, 0xEF][..]));
672582
assert!(!encoder.advance());
673583
assert_eq!(encoder.current_chunk(), None);

consensus_encoding/tests/wrappers.rs

Lines changed: 4 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -59,52 +59,28 @@ fn bytes_encoder_without_length_prefix() {
5959
assert_eq!(got, want);
6060
}
6161

62-
#[test]
63-
fn bytes_encoder_with_length_prefix() {
64-
#[derive(Debug, Default, Clone)]
65-
pub struct Test(Vec<u8>);
66-
67-
impl Encodable for Test {
68-
type Encoder<'e>
69-
= TestBytesEncoder<'e>
70-
where
71-
Self: 'e;
72-
73-
fn encoder(&self) -> Self::Encoder<'_> {
74-
TestBytesEncoder(BytesEncoder::with_length_prefix(self.0.as_ref()))
75-
}
76-
}
77-
78-
let t = Test(vec![0xca, 0xfe]);
79-
80-
let want = [0x02, 0xca, 0xfe];
81-
let got = encoding::encode_to_vec(&t);
82-
83-
assert_eq!(got, want);
84-
}
85-
8662
#[test]
8763
fn two_encoder() {
8864
#[derive(Debug, Default, Clone)]
8965
pub struct Test {
90-
a: Vec<u8>, // Encode without prefix.
91-
b: Vec<u8>, // Encode with prefix.
66+
a: Vec<u8>,
67+
b: Vec<u8>,
9268
}
9369

9470
impl Encodable for Test {
9571
type Encoder<'e> = Encoder2<TestBytesEncoder<'e>, TestBytesEncoder<'e>>;
9672

9773
fn encoder(&self) -> Self::Encoder<'_> {
9874
let a = TestBytesEncoder(BytesEncoder::without_length_prefix(self.a.as_ref()));
99-
let b = TestBytesEncoder(BytesEncoder::with_length_prefix(self.b.as_ref()));
75+
let b = TestBytesEncoder(BytesEncoder::without_length_prefix(self.b.as_ref()));
10076

10177
Encoder2::new(a, b)
10278
}
10379
}
10480

10581
let t = Test { a: vec![0xca, 0xfe], b: (vec![0xba, 0xbe]) };
10682

107-
let want = [0xca, 0xfe, 0x02, 0xba, 0xbe];
83+
let want = [0xca, 0xfe, 0xba, 0xbe];
10884
let got = encoding::encode_to_vec(&t);
10985

11086
assert_eq!(got, want);

primitives/src/script/borrowed.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use core::ops::{
77

88
#[cfg(feature = "arbitrary")]
99
use arbitrary::{Arbitrary, Unstructured};
10-
use encoding::{BytesEncoder, Encodable};
10+
use encoding::{BytesEncoder, CompactSizeEncoder, Encodable, Encoder2};
1111

1212
use super::ScriptBuf;
1313
use crate::prelude::{Box, ToOwned, Vec};
@@ -155,7 +155,7 @@ impl<T> Script<T> {
155155

156156
encoding::encoder_newtype! {
157157
/// The encoder for the [`Script<T>`] type.
158-
pub struct ScriptEncoder<'e>(BytesEncoder<'e>);
158+
pub struct ScriptEncoder<'e>(Encoder2<CompactSizeEncoder, BytesEncoder<'e>>);
159159
}
160160

161161
impl<T> Encodable for Script<T> {
@@ -165,7 +165,12 @@ impl<T> Encodable for Script<T> {
165165
Self: 'a;
166166

167167
fn encoder(&self) -> Self::Encoder<'_> {
168-
ScriptEncoder(BytesEncoder::with_length_prefix(self.as_bytes()))
168+
ScriptEncoder(
169+
Encoder2::new(
170+
CompactSizeEncoder::new(self.as_bytes().len()),
171+
BytesEncoder::without_length_prefix(self.as_bytes())
172+
)
173+
)
169174
}
170175
}
171176

0 commit comments

Comments
 (0)