Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor trait Decodable (sketch) #1019

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 7 additions & 1 deletion src/blockdata/script.rs
Expand Up @@ -23,6 +23,7 @@
//! This module provides the structures and functions needed to support scripts.
//!

use crate::consensus::encode::MAX_VEC_SIZE;
use crate::prelude::*;

use crate::io;
Expand Down Expand Up @@ -1075,9 +1076,14 @@ impl Encodable for Script {
}

impl Decodable for Script {
#[inline]
fn consensus_decode_from_finite_reader<D: io::Read>(d: D) -> Result<Self, encode::Error> {
Ok(Script(Decodable::consensus_decode_from_finite_reader(d)?))
}

#[inline]
fn consensus_decode<D: io::Read>(d: D) -> Result<Self, encode::Error> {
Ok(Script(Decodable::consensus_decode(d)?))
Self::consensus_decode_from_finite_reader(d.take(MAX_VEC_SIZE as u64))
}
}

Expand Down
42 changes: 25 additions & 17 deletions src/blockdata/transaction.rs
Expand Up @@ -621,10 +621,10 @@ impl Encodable for OutPoint {
}
}
impl Decodable for OutPoint {
fn consensus_decode<D: io::Read>(mut d: D) -> Result<Self, encode::Error> {
fn consensus_decode_from_finite_reader<D: io::Read>(mut d: D) -> Result<Self, encode::Error> {
Ok(OutPoint {
txid: Decodable::consensus_decode(&mut d)?,
vout: Decodable::consensus_decode(d)?,
txid: Decodable::consensus_decode_from_finite_reader(&mut d)?,
vout: Decodable::consensus_decode_from_finite_reader(d)?,
})
}
}
Expand All @@ -639,14 +639,18 @@ impl Encodable for TxIn {
}
}
impl Decodable for TxIn {
fn consensus_decode<D: io::Read>(mut d: D) -> Result<Self, encode::Error> {
fn consensus_decode_from_finite_reader<D: io::Read>(mut d: D) -> Result<Self, encode::Error> {
Ok(TxIn {
previous_output: Decodable::consensus_decode(&mut d)?,
script_sig: Decodable::consensus_decode(&mut d)?,
sequence: Decodable::consensus_decode(d)?,
previous_output: Decodable::consensus_decode_from_finite_reader(&mut d)?,
script_sig: Decodable::consensus_decode_from_finite_reader(&mut d)?,
sequence: Decodable::consensus_decode_from_finite_reader(d)?,
witness: Witness::default(),
})
}

fn consensus_decode<D: io::Read>(d: D) -> Result<Self, encode::Error> {
Self::consensus_decode_from_finite_reader(d.take(MAX_VEC_SIZE as u64))
}
}

impl Encodable for Transaction {
Expand Down Expand Up @@ -680,20 +684,20 @@ impl Encodable for Transaction {
}

impl Decodable for Transaction {
fn consensus_decode<D: io::Read>(d: D) -> Result<Self, encode::Error> {
fn consensus_decode_from_finite_reader<D: io::Read>(d: D) -> Result<Self, encode::Error> {
let mut d = d.take(MAX_VEC_SIZE as u64);
let version = i32::consensus_decode(&mut d)?;
let input = Vec::<TxIn>::consensus_decode(&mut d)?;
let version = i32::consensus_decode_from_finite_reader(&mut d)?;
let input = Vec::<TxIn>::consensus_decode_from_finite_reader(&mut d)?;
// segwit
if input.is_empty() {
let segwit_flag = u8::consensus_decode(&mut d)?;
let segwit_flag = u8::consensus_decode_from_finite_reader(&mut d)?;
match segwit_flag {
// BIP144 input witnesses
1 => {
let mut input = Vec::<TxIn>::consensus_decode(&mut d)?;
let output = Vec::<TxOut>::consensus_decode(&mut d)?;
let mut input = Vec::<TxIn>::consensus_decode_from_finite_reader(&mut d)?;
let output = Vec::<TxOut>::consensus_decode_from_finite_reader(&mut d)?;
for txin in input.iter_mut() {
txin.witness = Decodable::consensus_decode(&mut d)?;
txin.witness = Decodable::consensus_decode_from_finite_reader(&mut d)?;
}
if !input.is_empty() && input.iter().all(|input| input.witness.is_empty()) {
Err(encode::Error::ParseFailed("witness flag set but no witnesses present"))
Expand All @@ -702,7 +706,7 @@ impl Decodable for Transaction {
version,
input,
output,
lock_time: Decodable::consensus_decode(d)?,
lock_time: Decodable::consensus_decode_from_finite_reader(d)?,
})
}
}
Expand All @@ -714,11 +718,15 @@ impl Decodable for Transaction {
Ok(Transaction {
version,
input,
output: Decodable::consensus_decode(&mut d)?,
lock_time: Decodable::consensus_decode(d)?,
output: Decodable::consensus_decode_from_finite_reader(&mut d)?,
lock_time: Decodable::consensus_decode_from_finite_reader(d)?,
})
}
}

fn consensus_decode<D: io::Read>(d: D) -> Result<Self, encode::Error> {
Self::consensus_decode_from_finite_reader(d.take(MAX_VEC_SIZE as u64))
}
}

/// This type is consensus valid but an input including it would prevent the transaction from
Expand Down
12 changes: 8 additions & 4 deletions src/blockdata/witness.rs
Expand Up @@ -6,7 +6,7 @@
use crate::blockdata::transaction::EcdsaSighashType;
use crate::consensus::encode::{Error, MAX_VEC_SIZE};
use crate::consensus::{Decodable, Encodable, WriteExt};
use crate::io::{self, Read, Write};
use crate::io::{self, Write};
use crate::prelude::*;
use secp256k1::ecdsa;
use crate::VarInt;
Expand Down Expand Up @@ -46,8 +46,8 @@ pub struct Witness {
pub struct Iter<'a>(::core::slice::Iter<'a, u8>);

impl Decodable for Witness {
fn consensus_decode<D: Read>(mut d: D) -> Result<Self, Error> {
let witness_elements = VarInt::consensus_decode(&mut d)?.0 as usize;
fn consensus_decode_from_finite_reader<D: io::Read>(mut d: D) -> Result<Self, Error> {
let witness_elements = VarInt::consensus_decode_from_finite_reader(&mut d)?.0 as usize;
if witness_elements == 0 {
Ok(Witness::default())
} else {
Expand All @@ -62,7 +62,7 @@ impl Decodable for Witness {
for _ in 0..witness_elements {
second_to_last = last;
last = cursor;
let element_size_varint = VarInt::consensus_decode(&mut d)?;
let element_size_varint = VarInt::consensus_decode_from_finite_reader(&mut d)?;
let element_size_varint_len = element_size_varint.len();
let element_size = element_size_varint.0 as usize;
let required_len = cursor
Expand Down Expand Up @@ -100,6 +100,10 @@ impl Decodable for Witness {
})
}
}

fn consensus_decode<D: io::Read>(d: D) -> Result<Self, Error> {
Self::consensus_decode_from_finite_reader(d.take(MAX_VEC_SIZE as u64))
}
}

fn resize_if_needed(vec: &mut Vec<u8>, required_len: usize) {
Expand Down