Skip to content

Commit 2c21b0e

Browse files
committed
Support unsized R and W in consensus encode/decode
1 parent 78d26f8 commit 2c21b0e

20 files changed

+112
-99
lines changed

src/blockdata/script.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1091,14 +1091,14 @@ impl serde::Serialize for Script {
10911091

10921092
impl Encodable for Script {
10931093
#[inline]
1094-
fn consensus_encode<W: io::Write>(&self, w: &mut W) -> Result<usize, io::Error> {
1094+
fn consensus_encode<W: io::Write + ?Sized>(&self, w: &mut W) -> Result<usize, io::Error> {
10951095
self.0.consensus_encode(w)
10961096
}
10971097
}
10981098

10991099
impl Decodable for Script {
11001100
#[inline]
1101-
fn consensus_decode_from_finite_reader<R: io::Read>(r: &mut R) -> Result<Self, encode::Error> {
1101+
fn consensus_decode_from_finite_reader<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
11021102
Ok(Script(Decodable::consensus_decode_from_finite_reader(r)?))
11031103
}
11041104
}

src/blockdata/transaction.rs

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -652,13 +652,13 @@ impl Transaction {
652652
impl_consensus_encoding!(TxOut, value, script_pubkey);
653653

654654
impl Encodable for OutPoint {
655-
fn consensus_encode<W: io::Write>(&self, w: &mut W) -> Result<usize, io::Error> {
655+
fn consensus_encode<W: io::Write + ?Sized>(&self, w: &mut W) -> Result<usize, io::Error> {
656656
let len = self.txid.consensus_encode(w)?;
657657
Ok(len + self.vout.consensus_encode(w)?)
658658
}
659659
}
660660
impl Decodable for OutPoint {
661-
fn consensus_decode<R: io::Read>(r: &mut R) -> Result<Self, encode::Error> {
661+
fn consensus_decode<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
662662
Ok(OutPoint {
663663
txid: Decodable::consensus_decode(r)?,
664664
vout: Decodable::consensus_decode(r)?,
@@ -667,7 +667,7 @@ impl Decodable for OutPoint {
667667
}
668668

669669
impl Encodable for TxIn {
670-
fn consensus_encode<W: io::Write>(&self, w: &mut W) -> Result<usize, io::Error> {
670+
fn consensus_encode<W: io::Write + ?Sized>(&self, w: &mut W) -> Result<usize, io::Error> {
671671
let mut len = 0;
672672
len += self.previous_output.consensus_encode(w)?;
673673
len += self.script_sig.consensus_encode(w)?;
@@ -677,7 +677,7 @@ impl Encodable for TxIn {
677677
}
678678
impl Decodable for TxIn {
679679
#[inline]
680-
fn consensus_decode_from_finite_reader<R: io::Read>(r: &mut R) -> Result<Self, encode::Error> {
680+
fn consensus_decode_from_finite_reader<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
681681
Ok(TxIn {
682682
previous_output: Decodable::consensus_decode_from_finite_reader(r)?,
683683
script_sig: Decodable::consensus_decode_from_finite_reader(r)?,
@@ -688,7 +688,7 @@ impl Decodable for TxIn {
688688
}
689689

690690
impl Encodable for Transaction {
691-
fn consensus_encode<W: io::Write>(&self, w: &mut W) -> Result<usize, io::Error> {
691+
fn consensus_encode<W: io::Write + ?Sized>(&self, w: &mut W) -> Result<usize, io::Error> {
692692
let mut len = 0;
693693
len += self.version.consensus_encode(w)?;
694694
// To avoid serialization ambiguity, no inputs means we use BIP141 serialization (see
@@ -718,7 +718,7 @@ impl Encodable for Transaction {
718718
}
719719

720720
impl Decodable for Transaction {
721-
fn consensus_decode_from_finite_reader<R: io::Read>(r: &mut R) -> Result<Self, encode::Error> {
721+
fn consensus_decode_from_finite_reader<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
722722
let version = i32::consensus_decode_from_finite_reader(r)?;
723723
let input = Vec::<TxIn>::consensus_decode_from_finite_reader(r)?;
724724
// segwit
@@ -953,6 +953,19 @@ mod tests {
953953
use super::EcdsaSighashType;
954954
use crate::util::sighash::SighashCache;
955955

956+
const SOME_TX: &str = "0100000001a15d57094aa7a21a28cb20b59aab8fc7d1149a3bdbcddba9c622e4f5f6a99ece010000006c493046022100f93bb0e7d8db7bd46e40132d1f8242026e045f03a0efe71bbb8e3f475e970d790221009337cd7f1f929f00cc6ff01f03729b069a7c21b59b1736ddfee5db5946c5da8c0121033b9b137ee87d5a812d6f506efdd37f0affa7ffc310711c06c7f3e097c9447c52ffffffff0100e1f505000000001976a9140389035a9225b3839e2bbf32d826a1e222031fd888ac00000000";
957+
958+
#[test]
959+
fn encode_to_unsized_writer() {
960+
let mut buf = [0u8; 1024];
961+
let raw_tx = Vec::from_hex(SOME_TX).unwrap();
962+
let tx: Transaction = Decodable::consensus_decode(&mut raw_tx.as_slice()).unwrap();
963+
964+
let size = tx.consensus_encode(&mut &mut buf[..]).unwrap();
965+
assert_eq!(size, SOME_TX.len() / 2);
966+
assert_eq!(raw_tx, &buf[..size]);
967+
}
968+
956969
#[test]
957970
fn test_outpoint() {
958971
assert_eq!(OutPoint::from_str("i don't care"),

src/blockdata/witness.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ pub struct Iter<'a> {
4949
}
5050

5151
impl Decodable for Witness {
52-
fn consensus_decode<R: Read>(r: &mut R) -> Result<Self, Error> {
52+
fn consensus_decode<R: Read + ?Sized>(r: &mut R) -> Result<Self, Error> {
5353
let witness_elements = VarInt::consensus_decode(r)?.0 as usize;
5454
if witness_elements == 0 {
5555
Ok(Witness::default())
@@ -116,7 +116,7 @@ fn resize_if_needed(vec: &mut Vec<u8>, required_len: usize) {
116116
}
117117

118118
impl Encodable for Witness {
119-
fn consensus_encode<W: Write>(&self, w: &mut W) -> Result<usize, io::Error> {
119+
fn consensus_encode<W: Write + ?Sized>(&self, w: &mut W) -> Result<usize, io::Error> {
120120
let len = VarInt(self.witness_elements as u64);
121121
len.consensus_encode(w)?;
122122
w.emit_slice(&self.content[..])?;

0 commit comments

Comments
 (0)