Stop relying on `std::io::Write`'s `&mut Write` blanket impl
`std::io::Write` is implemented for all `&mut std::io::Write`. This makes it easy to have APIs that mix and match owned `Write`s with mutable references to `Write`s. However, in the next commit we add our own `Write` trait which we intend to implement for all `std::io::Write`. Sadly, this is mutually exclusive with a blanket implementation on our own `&mut Write`, as that would conflict with an `std::io::Write` blanket impl. Thus, in order to use the `Write for all &mut Write` blanket impl in rust-bitcoin, we'd have to bound all `Write`s by `std::io::Write`, as we're unable to provide a blanket `Write for &mut Write` impl. Here we stop relying on that blanket impl in order to introduce the new trait in the next commit.
This commit is contained in:
parent
5e0209569c
commit
2348449d2a
|
@ -393,7 +393,7 @@ impl<'a, W: io::Write> GcsFilterWriter<'a, W> {
|
||||||
mapped.sort_unstable();
|
mapped.sort_unstable();
|
||||||
|
|
||||||
// write number of elements as varint
|
// write number of elements as varint
|
||||||
let mut wrote = VarInt::from(mapped.len()).consensus_encode(&mut self.writer)?;
|
let mut wrote = VarInt::from(mapped.len()).consensus_encode(self.writer)?;
|
||||||
|
|
||||||
// write out deltas of sorted values into a Golonb-Rice coded bit stream
|
// write out deltas of sorted values into a Golonb-Rice coded bit stream
|
||||||
let mut writer = BitStreamWriter::new(self.writer);
|
let mut writer = BitStreamWriter::new(self.writer);
|
||||||
|
|
|
@ -643,11 +643,11 @@ impl_vec!((u32, Address));
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl_vec!(AddrV2Message);
|
impl_vec!(AddrV2Message);
|
||||||
|
|
||||||
pub(crate) fn consensus_encode_with_size<W: io::Write>(
|
pub(crate) fn consensus_encode_with_size<W: io::Write + ?Sized>(
|
||||||
data: &[u8],
|
data: &[u8],
|
||||||
mut w: W,
|
w: &mut W,
|
||||||
) -> Result<usize, io::Error> {
|
) -> Result<usize, io::Error> {
|
||||||
let vi_len = VarInt(data.len() as u64).consensus_encode(&mut w)?;
|
let vi_len = VarInt(data.len() as u64).consensus_encode(w)?;
|
||||||
w.emit_slice(data)?;
|
w.emit_slice(data)?;
|
||||||
Ok(vi_len + data.len())
|
Ok(vi_len + data.len())
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,7 +68,7 @@ impl PublicKey {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Write the public key into a writer
|
/// Write the public key into a writer
|
||||||
pub fn write_into<W: io::Write>(&self, mut writer: W) -> Result<(), io::Error> {
|
pub fn write_into<W: io::Write>(&self, writer: &mut W) -> Result<(), io::Error> {
|
||||||
self.with_serialized(|bytes| writer.write_all(bytes))
|
self.with_serialized(|bytes| writer.write_all(bytes))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -675,7 +675,7 @@ impl<R: Borrow<Transaction>> SighashCache<R> {
|
||||||
/// [`io::Write`] trait.
|
/// [`io::Write`] trait.
|
||||||
pub fn taproot_encode_signing_data_to<Write: io::Write, T: Borrow<TxOut>>(
|
pub fn taproot_encode_signing_data_to<Write: io::Write, T: Borrow<TxOut>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
mut writer: Write,
|
writer: &mut Write,
|
||||||
input_index: usize,
|
input_index: usize,
|
||||||
prevouts: &Prevouts<T>,
|
prevouts: &Prevouts<T>,
|
||||||
annex: Option<Annex>,
|
annex: Option<Annex>,
|
||||||
|
@ -687,18 +687,18 @@ impl<R: Borrow<Transaction>> SighashCache<R> {
|
||||||
let (sighash, anyone_can_pay) = sighash_type.split_anyonecanpay_flag();
|
let (sighash, anyone_can_pay) = sighash_type.split_anyonecanpay_flag();
|
||||||
|
|
||||||
// epoch
|
// epoch
|
||||||
0u8.consensus_encode(&mut writer)?;
|
0u8.consensus_encode(writer)?;
|
||||||
|
|
||||||
// * Control:
|
// * Control:
|
||||||
// hash_type (1).
|
// hash_type (1).
|
||||||
(sighash_type as u8).consensus_encode(&mut writer)?;
|
(sighash_type as u8).consensus_encode(writer)?;
|
||||||
|
|
||||||
// * Transaction Data:
|
// * Transaction Data:
|
||||||
// nVersion (4): the nVersion of the transaction.
|
// nVersion (4): the nVersion of the transaction.
|
||||||
self.tx.borrow().version.consensus_encode(&mut writer)?;
|
self.tx.borrow().version.consensus_encode(writer)?;
|
||||||
|
|
||||||
// nLockTime (4): the nLockTime of the transaction.
|
// nLockTime (4): the nLockTime of the transaction.
|
||||||
self.tx.borrow().lock_time.consensus_encode(&mut writer)?;
|
self.tx.borrow().lock_time.consensus_encode(writer)?;
|
||||||
|
|
||||||
// If the hash_type & 0x80 does not equal SIGHASH_ANYONECANPAY:
|
// If the hash_type & 0x80 does not equal SIGHASH_ANYONECANPAY:
|
||||||
// sha_prevouts (32): the SHA256 of the serialization of all input outpoints.
|
// sha_prevouts (32): the SHA256 of the serialization of all input outpoints.
|
||||||
|
@ -706,16 +706,16 @@ impl<R: Borrow<Transaction>> SighashCache<R> {
|
||||||
// sha_scriptpubkeys (32): the SHA256 of the serialization of all spent output scriptPubKeys.
|
// sha_scriptpubkeys (32): the SHA256 of the serialization of all spent output scriptPubKeys.
|
||||||
// sha_sequences (32): the SHA256 of the serialization of all input nSequence.
|
// sha_sequences (32): the SHA256 of the serialization of all input nSequence.
|
||||||
if !anyone_can_pay {
|
if !anyone_can_pay {
|
||||||
self.common_cache().prevouts.consensus_encode(&mut writer)?;
|
self.common_cache().prevouts.consensus_encode(writer)?;
|
||||||
self.taproot_cache(prevouts.get_all()?).amounts.consensus_encode(&mut writer)?;
|
self.taproot_cache(prevouts.get_all()?).amounts.consensus_encode(writer)?;
|
||||||
self.taproot_cache(prevouts.get_all()?).script_pubkeys.consensus_encode(&mut writer)?;
|
self.taproot_cache(prevouts.get_all()?).script_pubkeys.consensus_encode(writer)?;
|
||||||
self.common_cache().sequences.consensus_encode(&mut writer)?;
|
self.common_cache().sequences.consensus_encode(writer)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If hash_type & 3 does not equal SIGHASH_NONE or SIGHASH_SINGLE:
|
// If hash_type & 3 does not equal SIGHASH_NONE or SIGHASH_SINGLE:
|
||||||
// sha_outputs (32): the SHA256 of the serialization of all outputs in CTxOut format.
|
// sha_outputs (32): the SHA256 of the serialization of all outputs in CTxOut format.
|
||||||
if sighash != TapSighashType::None && sighash != TapSighashType::Single {
|
if sighash != TapSighashType::None && sighash != TapSighashType::Single {
|
||||||
self.common_cache().outputs.consensus_encode(&mut writer)?;
|
self.common_cache().outputs.consensus_encode(writer)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// * Data about this input:
|
// * Data about this input:
|
||||||
|
@ -728,7 +728,7 @@ impl<R: Borrow<Transaction>> SighashCache<R> {
|
||||||
if leaf_hash_code_separator.is_some() {
|
if leaf_hash_code_separator.is_some() {
|
||||||
spend_type |= 2u8;
|
spend_type |= 2u8;
|
||||||
}
|
}
|
||||||
spend_type.consensus_encode(&mut writer)?;
|
spend_type.consensus_encode(writer)?;
|
||||||
|
|
||||||
// If hash_type & 0x80 equals SIGHASH_ANYONECANPAY:
|
// If hash_type & 0x80 equals SIGHASH_ANYONECANPAY:
|
||||||
// outpoint (36): the COutPoint of this input (32-byte hash + 4-byte little-endian).
|
// outpoint (36): the COutPoint of this input (32-byte hash + 4-byte little-endian).
|
||||||
|
@ -742,12 +742,12 @@ impl<R: Borrow<Transaction>> SighashCache<R> {
|
||||||
inputs_size: self.tx.borrow().input.len(),
|
inputs_size: self.tx.borrow().input.len(),
|
||||||
})?;
|
})?;
|
||||||
let previous_output = prevouts.get(input_index)?;
|
let previous_output = prevouts.get(input_index)?;
|
||||||
txin.previous_output.consensus_encode(&mut writer)?;
|
txin.previous_output.consensus_encode(writer)?;
|
||||||
previous_output.value.consensus_encode(&mut writer)?;
|
previous_output.value.consensus_encode(writer)?;
|
||||||
previous_output.script_pubkey.consensus_encode(&mut writer)?;
|
previous_output.script_pubkey.consensus_encode(writer)?;
|
||||||
txin.sequence.consensus_encode(&mut writer)?;
|
txin.sequence.consensus_encode(writer)?;
|
||||||
} else {
|
} else {
|
||||||
(input_index as u32).consensus_encode(&mut writer)?;
|
(input_index as u32).consensus_encode(writer)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If an annex is present (the lowest bit of spend_type is set):
|
// If an annex is present (the lowest bit of spend_type is set):
|
||||||
|
@ -757,7 +757,7 @@ impl<R: Borrow<Transaction>> SighashCache<R> {
|
||||||
let mut enc = sha256::Hash::engine();
|
let mut enc = sha256::Hash::engine();
|
||||||
annex.consensus_encode(&mut enc)?;
|
annex.consensus_encode(&mut enc)?;
|
||||||
let hash = sha256::Hash::from_engine(enc);
|
let hash = sha256::Hash::from_engine(enc);
|
||||||
hash.consensus_encode(&mut writer)?;
|
hash.consensus_encode(writer)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// * Data about this output:
|
// * Data about this output:
|
||||||
|
@ -775,7 +775,7 @@ impl<R: Borrow<Transaction>> SighashCache<R> {
|
||||||
})?
|
})?
|
||||||
.consensus_encode(&mut enc)?;
|
.consensus_encode(&mut enc)?;
|
||||||
let hash = sha256::Hash::from_engine(enc);
|
let hash = sha256::Hash::from_engine(enc);
|
||||||
hash.consensus_encode(&mut writer)?;
|
hash.consensus_encode(writer)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (scriptpath):
|
// if (scriptpath):
|
||||||
|
@ -783,9 +783,9 @@ impl<R: Borrow<Transaction>> SighashCache<R> {
|
||||||
// ss += bytes([0])
|
// ss += bytes([0])
|
||||||
// ss += struct.pack("<i", codeseparator_pos)
|
// ss += struct.pack("<i", codeseparator_pos)
|
||||||
if let Some((hash, code_separator_pos)) = leaf_hash_code_separator {
|
if let Some((hash, code_separator_pos)) = leaf_hash_code_separator {
|
||||||
hash.as_byte_array().consensus_encode(&mut writer)?;
|
hash.as_byte_array().consensus_encode(writer)?;
|
||||||
KEY_VERSION_0.consensus_encode(&mut writer)?;
|
KEY_VERSION_0.consensus_encode(writer)?;
|
||||||
code_separator_pos.consensus_encode(&mut writer)?;
|
code_separator_pos.consensus_encode(writer)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -862,7 +862,7 @@ impl<R: Borrow<Transaction>> SighashCache<R> {
|
||||||
/// [`Self::p2wpkh_signature_hash`] and [`SighashCache::p2wsh_signature_hash`].)
|
/// [`Self::p2wpkh_signature_hash`] and [`SighashCache::p2wsh_signature_hash`].)
|
||||||
pub fn segwit_v0_encode_signing_data_to<Write: io::Write>(
|
pub fn segwit_v0_encode_signing_data_to<Write: io::Write>(
|
||||||
&mut self,
|
&mut self,
|
||||||
mut writer: Write,
|
writer: &mut Write,
|
||||||
input_index: usize,
|
input_index: usize,
|
||||||
script_code: &Script,
|
script_code: &Script,
|
||||||
value: Amount,
|
value: Amount,
|
||||||
|
@ -872,21 +872,21 @@ impl<R: Borrow<Transaction>> SighashCache<R> {
|
||||||
|
|
||||||
let (sighash, anyone_can_pay) = sighash_type.split_anyonecanpay_flag();
|
let (sighash, anyone_can_pay) = sighash_type.split_anyonecanpay_flag();
|
||||||
|
|
||||||
self.tx.borrow().version.consensus_encode(&mut writer)?;
|
self.tx.borrow().version.consensus_encode(writer)?;
|
||||||
|
|
||||||
if !anyone_can_pay {
|
if !anyone_can_pay {
|
||||||
self.segwit_cache().prevouts.consensus_encode(&mut writer)?;
|
self.segwit_cache().prevouts.consensus_encode(writer)?;
|
||||||
} else {
|
} else {
|
||||||
zero_hash.consensus_encode(&mut writer)?;
|
zero_hash.consensus_encode(writer)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if !anyone_can_pay
|
if !anyone_can_pay
|
||||||
&& sighash != EcdsaSighashType::Single
|
&& sighash != EcdsaSighashType::Single
|
||||||
&& sighash != EcdsaSighashType::None
|
&& sighash != EcdsaSighashType::None
|
||||||
{
|
{
|
||||||
self.segwit_cache().sequences.consensus_encode(&mut writer)?;
|
self.segwit_cache().sequences.consensus_encode(writer)?;
|
||||||
} else {
|
} else {
|
||||||
zero_hash.consensus_encode(&mut writer)?;
|
zero_hash.consensus_encode(writer)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -896,14 +896,14 @@ impl<R: Borrow<Transaction>> SighashCache<R> {
|
||||||
inputs_size: self.tx.borrow().input.len(),
|
inputs_size: self.tx.borrow().input.len(),
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
txin.previous_output.consensus_encode(&mut writer)?;
|
txin.previous_output.consensus_encode(writer)?;
|
||||||
script_code.consensus_encode(&mut writer)?;
|
script_code.consensus_encode(writer)?;
|
||||||
value.consensus_encode(&mut writer)?;
|
value.consensus_encode(writer)?;
|
||||||
txin.sequence.consensus_encode(&mut writer)?;
|
txin.sequence.consensus_encode(writer)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if sighash != EcdsaSighashType::Single && sighash != EcdsaSighashType::None {
|
if sighash != EcdsaSighashType::Single && sighash != EcdsaSighashType::None {
|
||||||
self.segwit_cache().outputs.consensus_encode(&mut writer)?;
|
self.segwit_cache().outputs.consensus_encode(writer)?;
|
||||||
} else if sighash == EcdsaSighashType::Single && input_index < self.tx.borrow().output.len()
|
} else if sighash == EcdsaSighashType::Single && input_index < self.tx.borrow().output.len()
|
||||||
{
|
{
|
||||||
let mut single_enc = LegacySighash::engine();
|
let mut single_enc = LegacySighash::engine();
|
||||||
|
@ -914,8 +914,8 @@ impl<R: Borrow<Transaction>> SighashCache<R> {
|
||||||
writer.write_all(&zero_hash[..])?;
|
writer.write_all(&zero_hash[..])?;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.tx.borrow().lock_time.consensus_encode(&mut writer)?;
|
self.tx.borrow().lock_time.consensus_encode(writer)?;
|
||||||
sighash_type.to_u32().consensus_encode(&mut writer)?;
|
sighash_type.to_u32().consensus_encode(writer)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -986,7 +986,7 @@ impl<R: Borrow<Transaction>> SighashCache<R> {
|
||||||
/// that must be handled by the caller (see [`EncodeSigningDataResult::is_sighash_single_bug`]).
|
/// that must be handled by the caller (see [`EncodeSigningDataResult::is_sighash_single_bug`]).
|
||||||
pub fn legacy_encode_signing_data_to<Write: io::Write, U: Into<u32>>(
|
pub fn legacy_encode_signing_data_to<Write: io::Write, U: Into<u32>>(
|
||||||
&self,
|
&self,
|
||||||
writer: Write,
|
writer: &mut Write,
|
||||||
input_index: usize,
|
input_index: usize,
|
||||||
script_pubkey: &Script,
|
script_pubkey: &Script,
|
||||||
sighash_type: U,
|
sighash_type: U,
|
||||||
|
@ -1013,7 +1013,7 @@ impl<R: Borrow<Transaction>> SighashCache<R> {
|
||||||
|
|
||||||
fn encode_signing_data_to_inner<Write: io::Write>(
|
fn encode_signing_data_to_inner<Write: io::Write>(
|
||||||
self_: &Transaction,
|
self_: &Transaction,
|
||||||
mut writer: Write,
|
writer: &mut Write,
|
||||||
input_index: usize,
|
input_index: usize,
|
||||||
script_pubkey: &Script,
|
script_pubkey: &Script,
|
||||||
sighash_type: u32,
|
sighash_type: u32,
|
||||||
|
@ -1074,8 +1074,8 @@ impl<R: Borrow<Transaction>> SighashCache<R> {
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
// hash the result
|
// hash the result
|
||||||
tx.consensus_encode(&mut writer)?;
|
tx.consensus_encode(writer)?;
|
||||||
sighash_type.to_le_bytes().consensus_encode(&mut writer)?;
|
sighash_type.to_le_bytes().consensus_encode(writer)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1109,7 +1109,7 @@ impl TaprootMerkleBranch {
|
||||||
/// # Returns
|
/// # Returns
|
||||||
///
|
///
|
||||||
/// The number of bytes written to the writer.
|
/// The number of bytes written to the writer.
|
||||||
pub fn encode<Write: io::Write>(&self, mut writer: Write) -> io::Result<usize> {
|
pub fn encode<Write: io::Write>(&self, writer: &mut Write) -> io::Result<usize> {
|
||||||
for hash in self.0.iter() {
|
for hash in self.0.iter() {
|
||||||
writer.write_all(hash.as_ref())?;
|
writer.write_all(hash.as_ref())?;
|
||||||
}
|
}
|
||||||
|
@ -1237,12 +1237,12 @@ impl ControlBlock {
|
||||||
/// # Returns
|
/// # Returns
|
||||||
///
|
///
|
||||||
/// The number of bytes written to the writer.
|
/// The number of bytes written to the writer.
|
||||||
pub fn encode<Write: io::Write>(&self, mut writer: Write) -> io::Result<usize> {
|
pub fn encode<Write: io::Write>(&self, writer: &mut Write) -> io::Result<usize> {
|
||||||
let first_byte: u8 =
|
let first_byte: u8 =
|
||||||
i32::from(self.output_key_parity) as u8 | self.leaf_version.to_consensus();
|
i32::from(self.output_key_parity) as u8 | self.leaf_version.to_consensus();
|
||||||
writer.write_all(&[first_byte])?;
|
writer.write_all(&[first_byte])?;
|
||||||
writer.write_all(&self.internal_key.serialize())?;
|
writer.write_all(&self.internal_key.serialize())?;
|
||||||
self.merkle_branch.encode(&mut writer)?;
|
self.merkle_branch.encode(writer)?;
|
||||||
Ok(self.size())
|
Ok(self.size())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue