Skip to content

Commit c08382c

Browse files
committed
Copy ReadExt/WriteExt from bitcoin
Otherwise we miss them when upgrading to 0.32
1 parent 4aad862 commit c08382c

File tree

4 files changed

+240
-84
lines changed

4 files changed

+240
-84
lines changed

src/encode.rs

+11-62
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,6 @@ use crate::transaction::{Transaction, TxIn, TxOut};
2727

2828
pub use bitcoin::{self, consensus::encode::MAX_VEC_SIZE};
2929

30-
// Use the ReadExt/WriteExt traits as is from upstream
31-
pub use bitcoin::consensus::encode::{ReadExt, WriteExt};
32-
3330
use crate::taproot::TapLeafHash;
3431

3532
/// Encoding error
@@ -207,7 +204,7 @@ impl Decodable for sha256::Midstate {
207204
}
208205
}
209206

210-
pub(crate) fn consensus_encode_with_size<S: io::Write>(
207+
pub(crate) fn consensus_encode_with_size<S: crate::WriteExt>(
211208
data: &[u8],
212209
mut s: S,
213210
) -> Result<usize, Error> {
@@ -245,64 +242,16 @@ impl Decodable for crate::locktime::Time {
245242
}
246243
}
247244

248-
// TODO reuse bitcoin's `WriteExt::emit_varint`, `ReadExt::read_varint` when available
249-
250245
/// A variable sized integer.
251246
pub struct VarInt(pub u64);
252247
impl Encodable for VarInt {
253-
fn consensus_encode<W: io::Write>(&self, mut e: W) -> Result<usize, Error> {
254-
match self.0 {
255-
i @ 0..=0xFC => {
256-
e.emit_u8(i as u8)?;
257-
Ok(1)
258-
}
259-
i @ 0xFD..=0xFFFF => {
260-
e.emit_u8(0xFD)?;
261-
e.emit_u16(i as u16)?;
262-
Ok(3)
263-
}
264-
i @ 0x10000..=0xFFFFFFFF => {
265-
e.emit_u8(0xFE)?;
266-
e.emit_u32(i as u32)?;
267-
Ok(5)
268-
}
269-
i => {
270-
e.emit_u8(0xFF)?;
271-
e.emit_u64(i)?;
272-
Ok(9)
273-
}
274-
}
248+
fn consensus_encode<W: crate::WriteExt>(&self, mut e: W) -> Result<usize, Error> {
249+
Ok(e.emit_varint(self.0)?)
275250
}
276251
}
277252
impl Decodable for VarInt {
278-
fn consensus_decode<D: io::Read>(mut d: D) -> Result<Self, Error> {
279-
match d.read_u8()? {
280-
0xFF => {
281-
let x = d.read_u64()?;
282-
if x < 0x100000000 {
283-
Err(Error::NonMinimalVarInt)
284-
} else {
285-
Ok(VarInt(x))
286-
}
287-
}
288-
0xFE => {
289-
let x = d.read_u32()?;
290-
if x < 0x10000 {
291-
Err(Error::NonMinimalVarInt)
292-
} else {
293-
Ok(VarInt(x as u64))
294-
}
295-
}
296-
0xFD => {
297-
let x = d.read_u16()?;
298-
if x < 0xFD {
299-
Err(Error::NonMinimalVarInt)
300-
} else {
301-
Ok(VarInt(x as u64))
302-
}
303-
}
304-
n => Ok(VarInt(n as u64)),
305-
}
253+
fn consensus_decode<D: crate::ReadExt>(mut d: D) -> Result<Self, Error> {
254+
Ok(VarInt(d.read_varint()?))
306255
}
307256
}
308257
impl VarInt {
@@ -321,14 +270,14 @@ impl VarInt {
321270
macro_rules! impl_int {
322271
($ty:ident, $meth_dec:ident, $meth_enc:ident) => {
323272
impl Encodable for $ty {
324-
fn consensus_encode<W: io::Write>(&self, mut w: W) -> Result<usize, Error> {
273+
fn consensus_encode<W: crate::WriteExt>(&self, mut w: W) -> Result<usize, Error> {
325274
w.$meth_enc(*self)?;
326275
Ok(mem::size_of::<$ty>())
327276
}
328277
}
329278
impl Decodable for $ty {
330-
fn consensus_decode<R: io::Read>(mut r: R) -> Result<Self, Error> {
331-
Ok(ReadExt::$meth_dec(&mut r)?)
279+
fn consensus_decode<R: crate::ReadExt>(mut r: R) -> Result<Self, Error> {
280+
crate::ReadExt::$meth_dec(&mut r)
332281
}
333282
}
334283
};
@@ -411,7 +360,7 @@ macro_rules! impl_array {
411360
( $size:literal ) => {
412361
impl Encodable for [u8; $size] {
413362
#[inline]
414-
fn consensus_encode<W: WriteExt>(
363+
fn consensus_encode<W: crate::WriteExt>(
415364
&self,
416365
mut w: W,
417366
) -> core::result::Result<usize, Error> {
@@ -422,7 +371,7 @@ macro_rules! impl_array {
422371

423372
impl Decodable for [u8; $size] {
424373
#[inline]
425-
fn consensus_decode<R: ReadExt>(mut r: R) -> core::result::Result<Self, Error> {
374+
fn consensus_decode<R: crate::ReadExt>(mut r: R) -> core::result::Result<Self, Error> {
426375
let mut ret = [0; $size];
427376
r.read_slice(&mut ret)?;
428377
Ok(ret)
@@ -452,7 +401,7 @@ impl Encodable for Vec<u8> {
452401
}
453402
}
454403
impl Decodable for Vec<u8> {
455-
fn consensus_decode<D: io::Read>(mut d: D) -> Result<Self, Error> {
404+
fn consensus_decode<D: crate::ReadExt>(mut d: D) -> Result<Self, Error> {
456405
let s = VarInt::consensus_decode(&mut d)?.0 as usize;
457406
let mut v = vec![0; s];
458407
d.read_slice(&mut v)?;

src/ext.rs

+194
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
use std::io;
2+
3+
use crate::encode;
4+
5+
/// Extensions of `Write` to encode data as per Bitcoin consensus.
6+
pub trait WriteExt: io::Write {
7+
/// Outputs a 64-bit unsigned integer.
8+
fn emit_u64(&mut self, v: u64) -> Result<(), io::Error>;
9+
/// Outputs a 32-bit unsigned integer.
10+
fn emit_u32(&mut self, v: u32) -> Result<(), io::Error>;
11+
/// Outputs a 16-bit unsigned integer.
12+
fn emit_u16(&mut self, v: u16) -> Result<(), io::Error>;
13+
/// Outputs an 8-bit unsigned integer.
14+
fn emit_u8(&mut self, v: u8) -> Result<(), io::Error>;
15+
16+
/// Outputs a 64-bit signed integer.
17+
fn emit_i64(&mut self, v: i64) -> Result<(), io::Error>;
18+
/// Outputs a 32-bit signed integer.
19+
fn emit_i32(&mut self, v: i32) -> Result<(), io::Error>;
20+
/// Outputs a 16-bit signed integer.
21+
fn emit_i16(&mut self, v: i16) -> Result<(), io::Error>;
22+
/// Outputs an 8-bit signed integer.
23+
fn emit_i8(&mut self, v: i8) -> Result<(), io::Error>;
24+
25+
/// Outputs a variable sized integer.
26+
fn emit_varint(&mut self, v: u64) -> Result<usize, io::Error>;
27+
28+
/// Outputs a boolean.
29+
fn emit_bool(&mut self, v: bool) -> Result<(), io::Error>;
30+
31+
/// Outputs a byte slice.
32+
fn emit_slice(&mut self, v: &[u8]) -> Result<usize, io::Error>;
33+
}
34+
35+
/// Extensions of `Read` to decode data as per Bitcoin consensus.
36+
pub trait ReadExt: io::Read {
37+
/// Reads a 64-bit unsigned integer.
38+
fn read_u64(&mut self) -> Result<u64, encode::Error>;
39+
/// Reads a 32-bit unsigned integer.
40+
fn read_u32(&mut self) -> Result<u32, encode::Error>;
41+
/// Reads a 16-bit unsigned integer.
42+
fn read_u16(&mut self) -> Result<u16, encode::Error>;
43+
/// Reads an 8-bit unsigned integer.
44+
fn read_u8(&mut self) -> Result<u8, encode::Error>;
45+
46+
/// Reads a 64-bit signed integer.
47+
fn read_i64(&mut self) -> Result<i64, encode::Error>;
48+
/// Reads a 32-bit signed integer.
49+
fn read_i32(&mut self) -> Result<i32, encode::Error>;
50+
/// Reads a 16-bit signed integer.
51+
fn read_i16(&mut self) -> Result<i16, encode::Error>;
52+
/// Reads an 8-bit signed integer.
53+
fn read_i8(&mut self) -> Result<i8, encode::Error>;
54+
55+
/// Reads a variable sized integer.
56+
fn read_varint(&mut self) -> Result<u64, encode::Error>;
57+
58+
/// Reads a boolean.
59+
fn read_bool(&mut self) -> Result<bool, encode::Error>;
60+
61+
/// Reads a byte slice.
62+
fn read_slice(&mut self, slice: &mut [u8]) -> Result<(), encode::Error>;
63+
}
64+
65+
macro_rules! encoder_fn {
66+
($name:ident, $val_type:ty) => {
67+
#[inline]
68+
fn $name(&mut self, v: $val_type) -> core::result::Result<(), io::Error> {
69+
self.write_all(&v.to_le_bytes())
70+
}
71+
};
72+
}
73+
74+
macro_rules! decoder_fn {
75+
($name:ident, $val_type:ty, $byte_len: expr) => {
76+
#[inline]
77+
fn $name(&mut self) -> core::result::Result<$val_type, encode::Error> {
78+
let mut val = [0; $byte_len];
79+
self.read_exact(&mut val[..]).map_err(encode::Error::Io)?;
80+
Ok(<$val_type>::from_le_bytes(val))
81+
}
82+
};
83+
}
84+
85+
impl<W: io::Write + ?Sized> WriteExt for W {
86+
encoder_fn!(emit_u64, u64);
87+
encoder_fn!(emit_u32, u32);
88+
encoder_fn!(emit_u16, u16);
89+
encoder_fn!(emit_i64, i64);
90+
encoder_fn!(emit_i32, i32);
91+
encoder_fn!(emit_i16, i16);
92+
93+
#[inline]
94+
fn emit_i8(&mut self, v: i8) -> Result<(), io::Error> {
95+
self.write_all(&[v as u8])
96+
}
97+
#[inline]
98+
fn emit_u8(&mut self, v: u8) -> Result<(), io::Error> {
99+
self.write_all(&[v])
100+
}
101+
#[inline]
102+
fn emit_bool(&mut self, v: bool) -> Result<(), io::Error> {
103+
self.write_all(&[v as u8])
104+
}
105+
#[inline]
106+
fn emit_slice(&mut self, v: &[u8]) -> Result<usize, io::Error> {
107+
self.write_all(v)?;
108+
Ok(v.len())
109+
}
110+
#[inline]
111+
fn emit_varint(&mut self, v: u64) -> Result<usize, io::Error> {
112+
match v {
113+
i @ 0..=0xFC => {
114+
self.emit_u8(i as u8)?;
115+
Ok(1)
116+
}
117+
i @ 0xFD..=0xFFFF => {
118+
self.emit_u8(0xFD)?;
119+
self.emit_u16(i as u16)?;
120+
Ok(3)
121+
}
122+
i @ 0x10000..=0xFFFFFFFF => {
123+
self.emit_u8(0xFE)?;
124+
self.emit_u32(i as u32)?;
125+
Ok(5)
126+
}
127+
i => {
128+
self.emit_u8(0xFF)?;
129+
self.emit_u64(i)?;
130+
Ok(9)
131+
}
132+
}
133+
}
134+
}
135+
136+
impl<R: io::Read + ?Sized> ReadExt for R {
137+
decoder_fn!(read_u64, u64, 8);
138+
decoder_fn!(read_u32, u32, 4);
139+
decoder_fn!(read_u16, u16, 2);
140+
decoder_fn!(read_i64, i64, 8);
141+
decoder_fn!(read_i32, i32, 4);
142+
decoder_fn!(read_i16, i16, 2);
143+
144+
#[inline]
145+
fn read_u8(&mut self) -> Result<u8, encode::Error> {
146+
let mut slice = [0u8; 1];
147+
self.read_exact(&mut slice)?;
148+
Ok(slice[0])
149+
}
150+
#[inline]
151+
fn read_i8(&mut self) -> Result<i8, encode::Error> {
152+
let mut slice = [0u8; 1];
153+
self.read_exact(&mut slice)?;
154+
Ok(slice[0] as i8)
155+
}
156+
#[inline]
157+
fn read_bool(&mut self) -> Result<bool, encode::Error> {
158+
ReadExt::read_i8(self).map(|bit| bit != 0)
159+
}
160+
#[inline]
161+
fn read_slice(&mut self, slice: &mut [u8]) -> Result<(), encode::Error> {
162+
self.read_exact(slice).map_err(encode::Error::Io)
163+
}
164+
#[inline]
165+
fn read_varint(&mut self) -> Result<u64, encode::Error> {
166+
match self.read_u8()? {
167+
0xFF => {
168+
let x = self.read_u64()?;
169+
if x < 0x100000000 {
170+
Err(encode::Error::NonMinimalVarInt)
171+
} else {
172+
Ok(x)
173+
}
174+
}
175+
0xFE => {
176+
let x = self.read_u32()?;
177+
if x < 0x10000 {
178+
Err(encode::Error::NonMinimalVarInt)
179+
} else {
180+
Ok(x as u64)
181+
}
182+
}
183+
0xFD => {
184+
let x = self.read_u16()?;
185+
if x < 0xFD {
186+
Err(encode::Error::NonMinimalVarInt)
187+
} else {
188+
Ok(x as u64)
189+
}
190+
}
191+
n => Ok(n as u64),
192+
}
193+
}
194+
}

0 commit comments

Comments
 (0)