From c1a3d00ec824c52851cd7e8b0014aff832a60dfc Mon Sep 17 00:00:00 2001 From: jouzo Date: Mon, 22 Jan 2024 12:35:04 +0100 Subject: [PATCH] With dummy TxOutV2 serialization handling --- bitcoin/src/blockdata/transaction.rs | 55 ++++++++++++++++++++++++++-- bitcoin/src/consensus/encode.rs | 2 + 2 files changed, 54 insertions(+), 3 deletions(-) diff --git a/bitcoin/src/blockdata/transaction.rs b/bitcoin/src/blockdata/transaction.rs index bb8d58d2..54c7b9b7 100644 --- a/bitcoin/src/blockdata/transaction.rs +++ b/bitcoin/src/blockdata/transaction.rs @@ -564,6 +564,25 @@ fn size_from_script_pubkey(script_pubkey: &Script) -> usize { Amount::SIZE + VarInt::from(len).size() + len } +#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", serde(crate = "actual_serde"))] +pub struct TxOutV2 { + /// The value of the output, in satoshis. + pub value: Amount, + /// The script which must be satisfied for the output to be spent. + pub script_pubkey: ScriptBuf, +} + +impl From for TxOutV2 { + fn from(tx: TxOut) -> Self { TxOutV2 { value: tx.value, script_pubkey: tx.script_pubkey } } +} + +impl From for TxOut { + fn from(tx: TxOutV2) -> Self { + TxOut { value: tx.value, script_pubkey: tx.script_pubkey, unused_token_id: 0 } + } +} /// Bitcoin transaction. /// /// An authenticated movement of coins. @@ -993,6 +1012,9 @@ impl Version { /// The second Bitcoin transaction version (post-BIP-68). pub const TWO: Self = Self(2); + /// The Fourth Defichain transaction version. + pub const FOUR: Self = Self(4); + /// Creates a non-standard transaction version. pub fn non_standard(version: i32) -> Version { Self(version) } @@ -1013,6 +1035,7 @@ impl Decodable for Version { } impl_consensus_encoding!(TxOut, value, script_pubkey, unused_token_id); +impl_consensus_encoding!(TxOutV2, value, script_pubkey); impl Encodable for OutPoint { fn consensus_encode(&self, w: &mut W) -> Result { @@ -1078,7 +1101,17 @@ impl Encodable for Transaction { len += SEGWIT_MARKER.consensus_encode(w)?; len += SEGWIT_FLAG.consensus_encode(w)?; len += self.input.consensus_encode(w)?; - len += self.output.consensus_encode(w)?; + + len += if self.version == Version::TWO { + self.output.iter().try_fold(0usize, |acc, tx| { + let value_len = tx.value.consensus_encode(w)?; + let script_len = tx.script_pubkey.consensus_encode(w)?; + Ok::(acc + value_len + script_len) + })? + } else { + self.output.consensus_encode(w)? + }; + for input in &self.input { len += input.witness.consensus_encode(w)?; } @@ -1101,7 +1134,14 @@ impl Decodable for Transaction { // BIP144 input witnesses 1 => { let mut input = Vec::::consensus_decode_from_finite_reader(r)?; - let output = Vec::::consensus_decode_from_finite_reader(r)?; + let output = if version == Version::TWO { + Vec::::consensus_decode_from_finite_reader(r)? + .into_iter() + .map(Into::into) + .collect() + } else { + Decodable::consensus_decode_from_finite_reader(r)? + }; for txin in input.iter_mut() { txin.witness = Decodable::consensus_decode_from_finite_reader(r)?; } @@ -1124,7 +1164,16 @@ impl Decodable for Transaction { Ok(Transaction { version, input, - output: Decodable::consensus_decode_from_finite_reader(r)?, + output: { + if version == Version::TWO { + Vec::::consensus_decode_from_finite_reader(r)? + .into_iter() + .map(Into::into) + .collect() + } else { + Decodable::consensus_decode_from_finite_reader(r)? + } + }, lock_time: Decodable::consensus_decode_from_finite_reader(r)?, }) } diff --git a/bitcoin/src/consensus/encode.rs b/bitcoin/src/consensus/encode.rs index e618c925..6b68efe7 100644 --- a/bitcoin/src/consensus/encode.rs +++ b/bitcoin/src/consensus/encode.rs @@ -33,6 +33,7 @@ use crate::p2p::{ }; use crate::prelude::*; use crate::taproot::TapLeafHash; +use crate::transaction::TxOutV2; /// Encoding error. #[derive(Debug)] @@ -628,6 +629,7 @@ impl_vec!(FilterHeader); impl_vec!(TxMerkleNode); impl_vec!(Transaction); impl_vec!(TxOut); +impl_vec!(TxOutV2); impl_vec!(TxIn); impl_vec!(Vec); impl_vec!(u64);