1use core::fmt;
14#[cfg(feature = "alloc")]
15use core::{cmp, mem};
16
17#[cfg(feature = "arbitrary")]
18use arbitrary::{Arbitrary, Unstructured};
19#[cfg(feature = "hex")]
20#[cfg(feature = "alloc")]
21use encoding::FromHexError;
22use encoding::{ArrayEncoder, BytesEncoder, Encoder2};
23#[cfg(feature = "alloc")]
24use encoding::{
25 Decoder2, Decoder3, DecoderStatus, Encode as _, Encoder3, Encoder6, EncoderStatus,
26 PrefixedSliceEncoder, VecDecoder,
27};
28#[cfg(feature = "alloc")]
29use hashes::sha256d;
30use internals::array::ArrayExt as _;
31#[cfg(feature = "serde")]
32use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
33#[cfg(feature = "alloc")]
34#[cfg(feature = "hex")]
35use units::parse_int;
36
37#[cfg(feature = "alloc")]
38use self::error::TransactionDecoderErrorInner;
39#[cfg(feature = "alloc")]
40use crate::amount::{AmountDecoder, AmountEncoder};
41#[cfg(feature = "alloc")]
42#[cfg(feature = "hex")]
43use crate::hex_codec::HexPrimitive;
44#[cfg(feature = "alloc")]
45use crate::locktime::absolute::{LockTimeDecoder, LockTimeEncoder};
46#[cfg(feature = "alloc")]
47use crate::prelude::Vec;
48#[cfg(feature = "alloc")]
49use crate::script::{ScriptEncoder, ScriptPubKeyBufDecoder, ScriptSigBufDecoder};
50#[cfg(feature = "alloc")]
51use crate::sequence::{SequenceDecoder, SequenceEncoder};
52#[cfg(feature = "alloc")]
53use crate::witness::{WitnessDecoder, WitnessEncoder};
54#[cfg(feature = "alloc")]
55use crate::{absolute, Amount, ScriptPubKeyBuf, ScriptSigBuf, Sequence, Weight, Witness};
56
57#[rustfmt::skip] #[cfg(feature = "hex")]
59#[cfg(feature = "alloc")]
60#[doc(no_inline)]
61pub use self::error::ParseOutPointError;
62#[doc(no_inline)]
63pub use self::error::{OutPointDecoderError, VersionDecoderError};
64#[cfg(feature = "alloc")]
65#[doc(no_inline)]
66pub use self::error::{TransactionDecoderError, TxInDecoderError, TxOutDecoderError};
67#[doc(no_inline)]
68pub use crate::hash_types::BlockHashDecoderError;
69#[doc(inline)]
70pub use crate::hash_types::{BlockHashDecoder, Ntxid, Txid, Wtxid};
71
72#[derive(Clone, PartialEq, Eq, Debug, Hash)]
128#[cfg(feature = "alloc")]
129pub struct Transaction {
130 pub version: Version,
132 pub lock_time: absolute::LockTime,
139 pub inputs: Vec<TxIn>,
141 pub outputs: Vec<TxOut>,
143}
144
145#[cfg(feature = "alloc")]
146impl Transaction {
147 pub const MAX_STANDARD_WEIGHT: Weight = Weight::from_wu(400_000);
150
151 #[doc(alias = "ntxid")]
161 pub fn compute_ntxid(&self) -> Ntxid {
162 let normalized = Self {
163 version: self.version,
164 lock_time: self.lock_time,
165 inputs: self
166 .inputs
167 .iter()
168 .map(|txin| TxIn {
169 script_sig: ScriptSigBuf::new(),
170 witness: Witness::default(),
171 ..*txin
172 })
173 .collect(),
174 outputs: self.outputs.clone(),
175 };
176 Ntxid::from_byte_array(normalized.compute_txid().to_byte_array())
177 }
178
179 #[doc(alias = "txid")]
185 #[inline]
186 pub fn compute_txid(&self) -> Txid {
187 let hash = hash_transaction(self, false);
188 Txid::from_byte_array(hash.to_byte_array())
189 }
190
191 #[doc(alias = "wtxid")]
197 #[inline]
198 pub fn compute_wtxid(&self) -> Wtxid {
199 let hash = hash_transaction(self, self.uses_segwit_serialization());
200 Wtxid::from_byte_array(hash.to_byte_array())
201 }
202
203 #[inline]
206 fn uses_segwit_serialization(&self) -> bool {
207 if self.inputs.iter().any(|input| !input.witness.is_empty()) {
208 return true;
209 }
210 self.inputs.is_empty()
213 }
214
215 #[doc(alias = "is_coin_base")] pub fn is_coinbase(&self) -> bool {
223 self.inputs.len() == 1 && self.inputs[0].previous_output == OutPoint::COINBASE_PREVOUT
224 }
225}
226
227#[cfg(feature = "alloc")]
228impl cmp::PartialOrd for Transaction {
229 #[inline]
230 fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> { Some(self.cmp(other)) }
231}
232
233#[cfg(feature = "alloc")]
234impl cmp::Ord for Transaction {
235 fn cmp(&self, other: &Self) -> cmp::Ordering {
236 self.version
237 .cmp(&other.version)
238 .then(self.lock_time.to_consensus_u32().cmp(&other.lock_time.to_consensus_u32()))
239 .then(self.inputs.cmp(&other.inputs))
240 .then(self.outputs.cmp(&other.outputs))
241 }
242}
243
244#[cfg(feature = "alloc")]
245#[cfg(feature = "hex")]
246impl core::str::FromStr for Transaction {
247 type Err = FromHexError<TransactionDecoderError>;
248
249 fn from_str(s: &str) -> Result<Self, Self::Err> { encoding::decode_from_hex(s) }
250}
251
252#[cfg(feature = "alloc")]
253#[cfg(feature = "hex")]
254impl fmt::Display for Transaction {
255 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
256 fmt::Display::fmt(&HexPrimitive(self), f)
257 }
258}
259
260#[cfg(feature = "alloc")]
261#[cfg(feature = "hex")]
262impl fmt::LowerHex for Transaction {
263 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
264 fmt::LowerHex::fmt(&HexPrimitive(self), f)
265 }
266}
267
268#[cfg(feature = "alloc")]
269#[cfg(feature = "hex")]
270impl fmt::UpperHex for Transaction {
271 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
272 fmt::UpperHex::fmt(&HexPrimitive(self), f)
273 }
274}
275
276#[cfg(feature = "alloc")]
277impl From<Transaction> for Txid {
278 #[inline]
279 fn from(tx: Transaction) -> Self { tx.compute_txid() }
280}
281
282#[cfg(feature = "alloc")]
283impl From<&Transaction> for Txid {
284 #[inline]
285 fn from(tx: &Transaction) -> Self { tx.compute_txid() }
286}
287
288#[cfg(feature = "alloc")]
289impl From<Transaction> for Wtxid {
290 #[inline]
291 fn from(tx: Transaction) -> Self { tx.compute_wtxid() }
292}
293
294#[cfg(feature = "alloc")]
295impl From<&Transaction> for Wtxid {
296 #[inline]
297 fn from(tx: &Transaction) -> Self { tx.compute_wtxid() }
298}
299
300pub(crate) trait TxIdentifier: AsRef<[u8]> {}
302
303impl TxIdentifier for Txid {}
304impl TxIdentifier for Wtxid {}
305
306#[cfg(feature = "alloc")]
309const SEGWIT_MARKER: u8 = 0x00;
310#[cfg(feature = "alloc")]
312const SEGWIT_FLAG: u8 = 0x01;
313
314#[cfg(feature = "alloc")]
316fn hash_transaction(tx: &Transaction, uses_segwit_serialization: bool) -> sha256d::Hash {
317 use hashes::HashEngine as _;
318
319 let mut enc = sha256d::Hash::engine();
320 enc.input(&tx.version.0.to_le_bytes()); if uses_segwit_serialization {
323 enc.input(&[SEGWIT_MARKER]);
325 enc.input(&[SEGWIT_FLAG]);
326 }
327
328 let input_len = tx.inputs.len();
330 enc.input(crate::compact_size_encode(input_len).as_slice());
331 for input in &tx.inputs {
332 enc.input(input.previous_output.txid.as_byte_array());
334 enc.input(&input.previous_output.vout.to_le_bytes());
335
336 let script_sig_bytes = input.script_sig.as_bytes();
337 enc.input(crate::compact_size_encode(script_sig_bytes.len()).as_slice());
338 enc.input(script_sig_bytes);
339
340 enc.input(&input.sequence.0.to_le_bytes());
341 }
342
343 let output_len = tx.outputs.len();
345 enc.input(crate::compact_size_encode(output_len).as_slice());
346 for output in &tx.outputs {
347 enc.input(&output.amount.to_sat().to_le_bytes());
349
350 let script_pubkey_bytes = output.script_pubkey.as_bytes();
351 enc.input(crate::compact_size_encode(script_pubkey_bytes.len()).as_slice());
352 enc.input(script_pubkey_bytes);
353 }
354
355 if uses_segwit_serialization {
356 for input in &tx.inputs {
358 enc.input(crate::compact_size_encode(input.witness.len()).as_slice());
360 for element in &input.witness {
361 enc.input(crate::compact_size_encode(element.len()).as_slice());
362 enc.input(element);
363 }
364 }
365 }
366
367 enc.input(&tx.lock_time.to_consensus_u32().to_le_bytes());
369
370 sha256d::Hash::from_engine(enc)
371}
372
373#[cfg(feature = "alloc")]
374impl encoding::Encode for Transaction {
375 type Encoder<'e>
376 = TransactionEncoder<'e>
377 where
378 Self: 'e;
379
380 fn encoder(&self) -> Self::Encoder<'_> {
381 let version = self.version.encoder();
382 let inputs = PrefixedSliceEncoder::new(self.inputs.as_ref());
383 let outputs = PrefixedSliceEncoder::new(self.outputs.as_ref());
384 let lock_time = self.lock_time.encoder();
385
386 if self.uses_segwit_serialization() {
387 let segwit = ArrayEncoder::without_length_prefix([0x00, 0x01]);
388 let witnesses = WitnessesEncoder::new(self.inputs.as_slice());
389 TransactionEncoder::new(Encoder6::new(
390 version,
391 Some(segwit),
392 inputs,
393 outputs,
394 Some(witnesses),
395 lock_time,
396 ))
397 } else {
398 TransactionEncoder::new(Encoder6::new(version, None, inputs, outputs, None, lock_time))
399 }
400 }
401}
402
403#[cfg(feature = "alloc")]
404impl encoding::Decode for Transaction {
405 type Decoder = TransactionDecoder;
406}
407
408#[cfg(feature = "alloc")]
409type TransactionEncoderInner<'e> = Encoder6<
410 VersionEncoder<'e>,
411 Option<ArrayEncoder<2>>,
412 PrefixedSliceEncoder<'e, TxIn>,
413 PrefixedSliceEncoder<'e, TxOut>,
414 Option<WitnessesEncoder<'e>>,
415 LockTimeEncoder<'e>,
416>;
417
418#[cfg(feature = "alloc")]
419encoding::encoder_newtype! {
420 #[derive(Debug, Clone)]
422 pub struct TransactionEncoder<'e>(TransactionEncoderInner<'e>);
423}
424
425#[cfg(feature = "alloc")]
427#[derive(Debug, Clone)]
428pub struct TransactionDecoder {
429 state: TransactionDecoderState,
430}
431
432#[cfg(feature = "alloc")]
433impl TransactionDecoder {
434 pub const fn new() -> Self {
436 Self { state: TransactionDecoderState::Version(VersionDecoder::new()) }
437 }
438}
439
440#[cfg(feature = "alloc")]
441impl Default for TransactionDecoder {
442 fn default() -> Self { Self::new() }
443}
444
445#[cfg(feature = "alloc")]
446#[allow(clippy::too_many_lines)] impl encoding::Decoder for TransactionDecoder {
448 type Output = Transaction;
449 type Error = TransactionDecoderError;
450
451 #[inline]
452 fn push_bytes(&mut self, bytes: &mut &[u8]) -> Result<DecoderStatus, Self::Error> {
453 use TransactionDecoderError as E;
454 use TransactionDecoderErrorInner as Inner;
455 use TransactionDecoderState as State;
456
457 loop {
458 match &mut self.state {
460 State::Version(decoder) => {
461 if decoder.push_bytes(bytes).map_err(|e| E(Inner::Version(e)))?.needs_more() {
462 return Ok(DecoderStatus::NeedsMore);
464 }
465 }
466 State::Inputs(_, _, decoder) =>
467 if decoder.push_bytes(bytes).map_err(|e| E(Inner::Inputs(e)))?.needs_more() {
468 return Ok(DecoderStatus::NeedsMore);
469 },
470 State::SegwitFlag(_) =>
471 if bytes.is_empty() {
472 return Ok(DecoderStatus::NeedsMore);
473 },
474 State::Outputs(_, _, _, decoder) =>
475 if decoder.push_bytes(bytes).map_err(|e| E(Inner::Outputs(e)))?.needs_more() {
476 return Ok(DecoderStatus::NeedsMore);
477 },
478 State::Witnesses(_, _, _, _, decoder) =>
479 if decoder.push_bytes(bytes).map_err(|e| E(Inner::Witness(e)))?.needs_more() {
480 return Ok(DecoderStatus::NeedsMore);
481 },
482 State::LockTime(_, _, _, decoder) =>
483 if decoder.push_bytes(bytes).map_err(|e| E(Inner::LockTime(e)))?.needs_more() {
484 return Ok(DecoderStatus::NeedsMore);
485 },
486 State::Done(..) => return Ok(DecoderStatus::Ready),
487 State::Errored => panic!("call to push_bytes() after decoder errored"),
488 }
489
490 match mem::replace(&mut self.state, State::Errored) {
492 State::Version(decoder) => {
493 let version = decoder.end().map_err(|e| E(Inner::Version(e)))?;
494 self.state = State::Inputs(version, Attempt::First, VecDecoder::<TxIn>::new());
495 }
496 State::Inputs(version, attempt, decoder) => {
497 let inputs = decoder.end().map_err(|e| E(Inner::Inputs(e)))?;
498
499 if Attempt::First == attempt {
500 if inputs.is_empty() {
501 self.state = State::SegwitFlag(version);
502 } else {
503 self.state = State::Outputs(
504 version,
505 inputs,
506 IsSegwit::No,
507 VecDecoder::<TxOut>::new(),
508 );
509 }
510 } else {
511 self.state = State::Outputs(
512 version,
513 inputs,
514 IsSegwit::Yes,
515 VecDecoder::<TxOut>::new(),
516 );
517 }
518 }
519 State::SegwitFlag(version) => {
520 let segwit_flag = bytes[0];
521 *bytes = &bytes[1..];
522
523 if segwit_flag != 1 {
524 return Err(E(Inner::UnsupportedSegwitFlag(segwit_flag)));
525 }
526 self.state = State::Inputs(version, Attempt::Second, VecDecoder::<TxIn>::new());
527 }
528 State::Outputs(version, inputs, is_segwit, decoder) => {
529 let outputs = decoder.end().map_err(|e| E(Inner::Outputs(e)))?;
530 if is_segwit == IsSegwit::Yes && !inputs.is_empty() {
532 self.state = State::Witnesses(
533 version,
534 inputs,
535 outputs,
536 Iteration(0),
537 WitnessDecoder::new(),
538 );
539 } else {
540 self.state =
541 State::LockTime(version, inputs, outputs, LockTimeDecoder::new());
542 }
543 }
544 State::Witnesses(version, mut inputs, outputs, iteration, decoder) => {
545 let iteration = iteration.0;
546
547 inputs[iteration].witness = decoder.end().map_err(|e| E(Inner::Witness(e)))?;
548 if iteration < inputs.len() - 1 {
549 self.state = State::Witnesses(
550 version,
551 inputs,
552 outputs,
553 Iteration(iteration + 1),
554 WitnessDecoder::new(),
555 );
556 } else {
557 if !inputs.is_empty() && inputs.iter().all(|input| input.witness.is_empty())
558 {
559 return Err(E(Inner::NoWitnesses));
560 }
561 self.state =
562 State::LockTime(version, inputs, outputs, LockTimeDecoder::new());
563 }
564 }
565 State::LockTime(version, inputs, outputs, decoder) => {
566 let lock_time = decoder.end().map_err(|e| E(Inner::LockTime(e)))?;
567 self.state = State::Done(Transaction { version, lock_time, inputs, outputs });
568 return Ok(DecoderStatus::Ready);
569 }
570 State::Done(..) => return Ok(DecoderStatus::Ready),
571 State::Errored => unreachable!("checked above"),
572 }
573 }
574 }
575
576 #[inline]
577 fn end(self) -> Result<Self::Output, Self::Error> {
578 use TransactionDecoderError as E;
579 use TransactionDecoderErrorInner as Inner;
580 use TransactionDecoderState as State;
581
582 match self.state {
583 State::Version(_) => Err(E(Inner::EarlyEnd("version"))),
584 State::Inputs(..) => Err(E(Inner::EarlyEnd("inputs"))),
585 State::SegwitFlag(..) => Err(E(Inner::EarlyEnd("segwit flag"))),
586 State::Outputs(..) => Err(E(Inner::EarlyEnd("outputs"))),
587 State::Witnesses(..) => Err(E(Inner::EarlyEnd("witnesses"))),
588 State::LockTime(..) => Err(E(Inner::EarlyEnd("locktime"))),
589 State::Done(tx) => {
590 if tx.outputs.is_empty() {
592 return Err(E(Inner::NoOutputs));
593 }
594 if tx.inputs.len() > 1 {
596 for (index, input) in tx.inputs.iter().enumerate() {
597 if input.previous_output == OutPoint::COINBASE_PREVOUT {
598 return Err(E(Inner::NullPrevoutInNonCoinbase(index)));
599 }
600 }
601 }
602 if tx.is_coinbase() {
604 let len = tx.inputs[0].script_sig.len();
605 if len < 2 {
606 return Err(E(Inner::CoinbaseScriptSigTooSmall(len)));
607 }
608 if len > 100 {
609 return Err(E(Inner::CoinbaseScriptSigTooLarge(len)));
610 }
611 }
612 let mut outpoints: Vec<_> = tx.inputs.iter().map(|i| i.previous_output).collect();
614 outpoints.sort_unstable();
615 for pair in outpoints.windows(2) {
616 if pair[0] == pair[1] {
617 return Err(E(Inner::DuplicateInput(pair[0])));
618 }
619 }
620 let mut total_out: u64 = 0;
624 for output in &tx.outputs {
625 total_out = total_out.saturating_add(output.amount.to_sat());
626 if total_out > Amount::MAX_MONEY.to_sat() {
627 return Err(E(Inner::OutputValueSumTooLarge(total_out)));
628 }
629 }
630 Ok(tx)
631 }
632 State::Errored => panic!("call to end() after decoder errored"),
633 }
634 }
635
636 #[inline]
637 fn read_limit(&self) -> usize {
638 use TransactionDecoderState as State;
639
640 match &self.state {
641 State::Version(decoder) => decoder.read_limit(),
642 State::Inputs(_, _, decoder) => decoder.read_limit(),
643 State::SegwitFlag(_) => 1,
644 State::Outputs(_, _, _, decoder) => decoder.read_limit(),
645 State::Witnesses(_, _, _, _, decoder) => decoder.read_limit(),
646 State::LockTime(_, _, _, decoder) => decoder.read_limit(),
647 State::Done(_) => 0,
648 State::Errored => 0,
651 }
652 }
653}
654
655#[cfg(feature = "alloc")]
657#[derive(Debug, Clone)]
658enum TransactionDecoderState {
659 Version(VersionDecoder),
661 Inputs(Version, Attempt, VecDecoder<TxIn>),
663 SegwitFlag(Version),
665 Outputs(Version, Vec<TxIn>, IsSegwit, VecDecoder<TxOut>),
667 Witnesses(Version, Vec<TxIn>, Vec<TxOut>, Iteration, WitnessDecoder),
669 LockTime(Version, Vec<TxIn>, Vec<TxOut>, LockTimeDecoder),
671 Done(Transaction),
673 Errored,
676}
677
678#[cfg(feature = "alloc")]
680#[derive(Debug, Copy, Clone, PartialEq, Eq)]
681enum Attempt {
682 First,
684 Second,
686}
687
688#[cfg(feature = "alloc")]
690#[derive(Debug, Copy, Clone, PartialEq, Eq)]
691enum IsSegwit {
692 Yes,
694 No,
696}
697
698#[cfg(feature = "alloc")]
700#[derive(Debug, Copy, Clone, PartialEq, Eq)]
701struct Iteration(usize);
702
703#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
713#[cfg(feature = "alloc")]
714pub struct TxIn {
715 pub previous_output: OutPoint,
717 pub script_sig: ScriptSigBuf,
720 pub sequence: Sequence,
725 pub witness: Witness,
731}
732
733#[cfg(feature = "alloc")]
734impl TxIn {
735 pub const EMPTY_COINBASE: Self = Self {
741 previous_output: OutPoint::COINBASE_PREVOUT,
742 script_sig: ScriptSigBuf::new(),
743 sequence: Sequence::MAX,
744 witness: Witness::new(),
745 };
746}
747
748#[cfg(feature = "alloc")]
749encoding::encoder_newtype_exact! {
750 #[derive(Debug, Clone)]
752 pub struct TxInEncoder<'e>(
753 Encoder3<OutPointEncoder<'e>, ScriptEncoder<'e>, SequenceEncoder<'e>>
754 );
755}
756
757#[cfg(feature = "alloc")]
758impl encoding::Encode for TxIn {
759 type Encoder<'e>
760 = TxInEncoder<'e>
761 where
762 Self: 'e;
763
764 fn encoder(&self) -> Self::Encoder<'_> {
765 TxInEncoder::new(Encoder3::new(
766 self.previous_output.encoder(),
767 self.script_sig.encoder(),
768 self.sequence.encoder(),
769 ))
770 }
771}
772
773#[cfg(feature = "alloc")]
775#[derive(Debug, Clone)]
776pub struct WitnessesEncoder<'e> {
777 inputs: &'e [TxIn],
778 cur_enc: Option<WitnessEncoder<'e>>,
780}
781
782#[cfg(feature = "alloc")]
783impl<'e> WitnessesEncoder<'e> {
784 pub fn new(inputs: &'e [TxIn]) -> Self {
786 Self { inputs, cur_enc: inputs.first().map(|input| input.witness.encoder()) }
787 }
788}
789
790#[cfg(feature = "alloc")]
791impl encoding::Encoder for WitnessesEncoder<'_> {
792 #[inline]
793 fn current_chunk(&self) -> &[u8] {
794 self.cur_enc.as_ref().map(WitnessEncoder::current_chunk).unwrap_or_default()
795 }
796
797 #[inline]
798 fn advance(&mut self) -> EncoderStatus {
799 let Some(cur) = self.cur_enc.as_mut() else {
800 return EncoderStatus::Finished;
801 };
802
803 loop {
804 if cur.advance().has_more() {
807 return EncoderStatus::HasMore;
808 }
809 self.inputs = &self.inputs[1..];
811
812 if let Some(input) = self.inputs.first() {
814 *cur = input.witness.encoder();
815 if !cur.current_chunk().is_empty() {
816 return EncoderStatus::HasMore;
817 }
818 } else {
819 self.cur_enc = None; return EncoderStatus::Finished;
821 }
822 }
823 }
824}
825
826#[cfg(feature = "alloc")]
827type TxInInnerDecoder = Decoder3<OutPointDecoder, ScriptSigBufDecoder, SequenceDecoder>;
828
829#[cfg(feature = "alloc")]
830crate::decoder_newtype! {
831 #[derive(Debug, Clone)]
833 pub struct TxInDecoder(TxInInnerDecoder);
834
835 pub const fn new() -> Self {
837 Self(Decoder3::new(
838 OutPointDecoder::new(),
839 ScriptSigBufDecoder::new(),
840 SequenceDecoder::new(),
841 ))
842 }
843
844 fn end(
845 result: Result<<TxInInnerDecoder as encoding::Decoder>::Output, <TxInInnerDecoder as encoding::Decoder>::Error>
846 ) -> Result<TxIn, TxInDecoderError> {
847 let (previous_output, script_sig, sequence) = result.map_err(TxInDecoderError)?;
848 Ok(TxIn { previous_output, script_sig, sequence, witness: Witness::default() })
849 }
850}
851
852#[cfg(feature = "alloc")]
853impl encoding::Decode for TxIn {
854 type Decoder = TxInDecoder;
855}
856
857#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
869#[cfg(feature = "alloc")]
870pub struct TxOut {
871 pub amount: Amount,
873 pub script_pubkey: ScriptPubKeyBuf,
875}
876
877#[cfg(feature = "alloc")]
878encoding::encoder_newtype_exact! {
879 #[derive(Debug, Clone)]
881 pub struct TxOutEncoder<'e>(Encoder2<AmountEncoder<'e>, ScriptEncoder<'e>>);
882}
883
884#[cfg(feature = "alloc")]
885impl encoding::Encode for TxOut {
886 type Encoder<'e>
887 = TxOutEncoder<'e>
888 where
889 Self: 'e;
890
891 fn encoder(&self) -> Self::Encoder<'_> {
892 TxOutEncoder::new(Encoder2::new(self.amount.encoder(), self.script_pubkey.encoder()))
893 }
894}
895
896#[cfg(feature = "alloc")]
897type TxOutInnerDecoder = Decoder2<AmountDecoder, ScriptPubKeyBufDecoder>;
898
899#[cfg(feature = "alloc")]
900crate::decoder_newtype! {
901 #[derive(Debug, Clone)]
903 pub struct TxOutDecoder(TxOutInnerDecoder);
904
905 pub const fn new() -> Self {
907 Self(Decoder2::new(AmountDecoder::new(), ScriptPubKeyBufDecoder::new()))
908 }
909
910 fn end(
911 result: Result<<TxOutInnerDecoder as encoding::Decoder>::Output, <TxOutInnerDecoder as encoding::Decoder>::Error>
912 ) -> Result<TxOut, TxOutDecoderError> {
913 let (amount, script_pubkey) = result.map_err(TxOutDecoderError)?;
914 Ok(TxOut { amount, script_pubkey })
915 }
916}
917
918#[cfg(feature = "alloc")]
919impl encoding::Decode for TxOut {
920 type Decoder = TxOutDecoder;
921}
922
923#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)]
929pub struct OutPoint {
930 pub txid: Txid,
932 pub vout: u32,
934}
935
936impl OutPoint {
937 pub const SIZE: usize = 32 + 4; pub const COINBASE_PREVOUT: Self = Self { txid: Txid::COINBASE_PREVOUT, vout: u32::MAX };
945}
946
947encoding::encoder_newtype_exact! {
948 #[derive(Debug, Clone)]
950 pub struct OutPointEncoder<'e>(Encoder2<BytesEncoder<'e>, ArrayEncoder<4>>);
951}
952
953impl encoding::Encode for OutPoint {
954 type Encoder<'e>
955 = OutPointEncoder<'e>
956 where
957 Self: 'e;
958
959 fn encoder(&self) -> Self::Encoder<'_> {
960 OutPointEncoder::new(Encoder2::new(
961 BytesEncoder::without_length_prefix(self.txid.as_byte_array()),
962 ArrayEncoder::without_length_prefix(self.vout.to_le_bytes()),
963 ))
964 }
965}
966
967#[cfg(feature = "hex")]
968impl fmt::Display for OutPoint {
969 #[inline]
970 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
971 write!(f, "{}:{}", self.txid, self.vout)
972 }
973}
974
975#[cfg(feature = "alloc")]
976#[cfg(feature = "hex")]
977impl core::str::FromStr for OutPoint {
978 type Err = ParseOutPointError;
979
980 fn from_str(s: &str) -> Result<Self, Self::Err> {
981 if s.len() > 75 {
982 return Err(ParseOutPointError::TooLong);
984 }
985 let find = s.find(':');
986 if find.is_none() || find != s.rfind(':') {
987 return Err(ParseOutPointError::Format);
988 }
989 let colon = find.unwrap();
990 if colon == 0 || colon == s.len() - 1 {
991 return Err(ParseOutPointError::Format);
992 }
993 Ok(Self {
994 txid: s[..colon].parse().map_err(ParseOutPointError::Txid)?,
995 vout: parse_vout(&s[colon + 1..])?,
996 })
997 }
998}
999
1000#[cfg(feature = "alloc")]
1004#[cfg(feature = "hex")]
1005fn parse_vout(s: &str) -> Result<u32, ParseOutPointError> {
1006 if s.len() > 1 {
1007 let first = s.chars().next().unwrap();
1008 if first == '0' || first == '+' {
1009 return Err(ParseOutPointError::VoutNotCanonical);
1010 }
1011 }
1012 parse_int::int_from_str(s).map_err(ParseOutPointError::Vout)
1013}
1014
1015crate::decoder_newtype! {
1016 #[derive(Debug, Clone)]
1019 pub struct OutPointDecoder(encoding::ArrayDecoder<36>);
1020
1021 pub const fn new() -> Self { Self(encoding::ArrayDecoder::new()) }
1023
1024 fn end(result: Result<[u8; 36], encoding::UnexpectedEofError>) -> Result<OutPoint, OutPointDecoderError> {
1025 let encoded = result.map_err(OutPointDecoderError)?;
1026 let (txid_buf, vout_buf) = encoded.split_array::<32, 4>();
1027
1028 let txid = Txid::from_byte_array(*txid_buf);
1029 let vout = u32::from_le_bytes(*vout_buf);
1030
1031 Ok(OutPoint { txid, vout })
1032 }
1033}
1034
1035impl encoding::Decode for OutPoint {
1036 type Decoder = OutPointDecoder;
1037}
1038
1039#[cfg(feature = "serde")]
1040impl Serialize for OutPoint {
1041 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1042 where
1043 S: Serializer,
1044 {
1045 if serializer.is_human_readable() {
1046 serializer.collect_str(&self)
1047 } else {
1048 use crate::serde::ser::SerializeStruct as _;
1049
1050 let mut state = serializer.serialize_struct("OutPoint", 2)?;
1051 state.serialize_field("txid", self.txid.as_byte_array().as_slice())?;
1055 state.serialize_field("vout", &self.vout.to_le_bytes())?;
1056 state.end()
1057 }
1058 }
1059}
1060
1061#[cfg(feature = "serde")]
1062impl<'de> Deserialize<'de> for OutPoint {
1063 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1064 where
1065 D: Deserializer<'de>,
1066 {
1067 if deserializer.is_human_readable() {
1068 struct StringVisitor;
1069
1070 impl de::Visitor<'_> for StringVisitor {
1071 type Value = OutPoint;
1072
1073 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
1074 formatter.write_str("a string in format 'txid:vout'")
1075 }
1076
1077 fn visit_str<E>(self, value: &str) -> Result<OutPoint, E>
1078 where
1079 E: de::Error,
1080 {
1081 value.parse::<OutPoint>().map_err(de::Error::custom)
1082 }
1083 }
1084
1085 deserializer.deserialize_str(StringVisitor)
1086 } else {
1087 #[derive(Deserialize)]
1088 #[serde(field_identifier, rename_all = "lowercase")]
1089 enum Field {
1090 Txid,
1091 Vout,
1092 }
1093
1094 struct OutPointVisitor;
1095
1096 impl<'de> de::Visitor<'de> for OutPointVisitor {
1097 type Value = OutPoint;
1098
1099 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
1100 formatter.write_str("OutPoint struct with fields")
1101 }
1102
1103 fn visit_seq<V>(self, mut seq: V) -> Result<OutPoint, V::Error>
1104 where
1105 V: de::SeqAccess<'de>,
1106 {
1107 let txid =
1108 seq.next_element()?.ok_or_else(|| de::Error::invalid_length(0, &self))?;
1109 let vout =
1110 seq.next_element()?.ok_or_else(|| de::Error::invalid_length(1, &self))?;
1111 Ok(OutPoint { txid, vout })
1112 }
1113
1114 fn visit_map<V>(self, mut map: V) -> Result<OutPoint, V::Error>
1115 where
1116 V: de::MapAccess<'de>,
1117 {
1118 let mut txid = None;
1119 let mut vout = None;
1120
1121 while let Some(key) = map.next_key()? {
1122 match key {
1123 Field::Txid => {
1124 if txid.is_some() {
1125 return Err(de::Error::duplicate_field("txid"));
1126 }
1127 let bytes: [u8; 32] = map.next_value()?;
1128 txid = Some(Txid::from_byte_array(bytes));
1129 }
1130 Field::Vout => {
1131 if vout.is_some() {
1132 return Err(de::Error::duplicate_field("vout"));
1133 }
1134 let bytes: [u8; 4] = map.next_value()?;
1135 vout = Some(u32::from_le_bytes(bytes));
1136 }
1137 }
1138 }
1139
1140 let txid = txid.ok_or_else(|| de::Error::missing_field("txid"))?;
1141 let vout = vout.ok_or_else(|| de::Error::missing_field("vout"))?;
1142
1143 Ok(OutPoint { txid, vout })
1144 }
1145 }
1146
1147 const FIELDS: &[&str] = &["txid", "vout"];
1148 deserializer.deserialize_struct("OutPoint", FIELDS, OutPointVisitor)
1149 }
1150 }
1151}
1152
1153#[derive(Copy, PartialEq, Eq, Clone, Debug, PartialOrd, Ord, Hash)]
1164#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1165pub struct Version(u32);
1166
1167impl Version {
1168 pub const ONE: Self = Self(1);
1170
1171 pub const TWO: Self = Self(2);
1173
1174 pub const THREE: Self = Self(3);
1176
1177 #[inline]
1181 pub const fn maybe_non_standard(version: u32) -> Self { Self(version) }
1182
1183 #[inline]
1185 pub const fn to_u32(self) -> u32 { self.0 }
1186
1187 #[inline]
1194 pub const fn is_standard(self) -> bool {
1195 self.0 == Self::ONE.0 || self.0 == Self::TWO.0 || self.0 == Self::THREE.0
1196 }
1197}
1198
1199impl fmt::Display for Version {
1200 #[inline]
1201 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Display::fmt(&self.0, f) }
1202}
1203
1204impl fmt::LowerHex for Version {
1205 #[inline]
1206 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::LowerHex::fmt(&self.0, f) }
1207}
1208
1209impl fmt::UpperHex for Version {
1210 #[inline]
1211 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::UpperHex::fmt(&self.0, f) }
1212}
1213
1214impl fmt::Octal for Version {
1215 #[inline]
1216 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Octal::fmt(&self.0, f) }
1217}
1218
1219impl fmt::Binary for Version {
1220 #[inline]
1221 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Binary::fmt(&self.0, f) }
1222}
1223
1224impl From<Version> for u32 {
1225 #[inline]
1226 fn from(version: Version) -> Self { version.0 }
1227}
1228
1229encoding::encoder_newtype_exact! {
1230 #[derive(Debug, Clone)]
1232 pub struct VersionEncoder<'e>(encoding::ArrayEncoder<4>);
1233}
1234
1235impl encoding::Encode for Version {
1236 type Encoder<'e> = VersionEncoder<'e>;
1237 fn encoder(&self) -> Self::Encoder<'_> {
1238 VersionEncoder::new(encoding::ArrayEncoder::without_length_prefix(
1239 self.to_u32().to_le_bytes(),
1240 ))
1241 }
1242}
1243
1244crate::decoder_newtype! {
1245 #[derive(Debug, Clone)]
1247 pub struct VersionDecoder(encoding::ArrayDecoder<4>);
1248
1249 pub const fn new() -> Self { Self(encoding::ArrayDecoder::new()) }
1251
1252 fn end(result: Result<[u8; 4], encoding::UnexpectedEofError>) -> Result<Version, VersionDecoderError> {
1253 let bytes = result.map_err(VersionDecoderError)?;
1254 let n = u32::from_le_bytes(bytes);
1255 Ok(Version::maybe_non_standard(n))
1256 }
1257}
1258
1259impl encoding::Decode for Version {
1260 type Decoder = VersionDecoder;
1261}
1262
1263pub mod error {
1265 use core::convert::Infallible;
1266 use core::fmt;
1267
1268 use internals::write_err;
1269
1270 #[cfg(feature = "hex")]
1271 #[cfg(feature = "alloc")]
1272 use super::parse_int;
1273 #[cfg(feature = "alloc")]
1274 use super::OutPoint;
1275 #[cfg(feature = "alloc")]
1276 use crate::locktime::absolute::LockTimeDecoderError;
1277 #[cfg(feature = "alloc")]
1278 use crate::witness::WitnessDecoderError;
1279
1280 #[cfg(feature = "alloc")]
1282 #[derive(Debug, Clone, PartialEq, Eq)]
1283 pub struct TransactionDecoderError(pub(super) TransactionDecoderErrorInner);
1284
1285 #[cfg(feature = "alloc")]
1286 #[derive(Debug, Clone, PartialEq, Eq)]
1287 pub(super) enum TransactionDecoderErrorInner {
1288 Version(VersionDecoderError),
1290 UnsupportedSegwitFlag(u8),
1292 Inputs(encoding::VecDecoderError<TxInDecoderError>),
1294 Outputs(encoding::VecDecoderError<TxOutDecoderError>),
1296 Witness(WitnessDecoderError),
1298 NoWitnesses,
1300 LockTime(LockTimeDecoderError),
1302 EarlyEnd(&'static str),
1305 NullPrevoutInNonCoinbase(usize),
1307 CoinbaseScriptSigTooSmall(usize),
1309 CoinbaseScriptSigTooLarge(usize),
1311 DuplicateInput(OutPoint),
1313 OutputValueSumTooLarge(u64),
1315 NoOutputs,
1317 }
1318
1319 #[cfg(feature = "alloc")]
1320 impl From<Infallible> for TransactionDecoderError {
1321 fn from(never: Infallible) -> Self { match never {} }
1322 }
1323
1324 #[cfg(feature = "alloc")]
1325 impl fmt::Display for TransactionDecoderError {
1326 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1327 use TransactionDecoderErrorInner as E;
1328
1329 match self.0 {
1330 E::Version(ref e) => write_err!(f, "transaction decoder error"; e),
1331 E::UnsupportedSegwitFlag(v) => {
1332 write!(f, "we only support segwit flag value 0x01: {}", v)
1333 }
1334 E::Inputs(ref e) => write_err!(f, "transaction decoder error"; e),
1335 E::Outputs(ref e) => write_err!(f, "transaction decoder error"; e),
1336 E::Witness(ref e) => write_err!(f, "transaction decoder error"; e),
1337 E::NoWitnesses => write!(f, "non-empty Segwit transaction with no witnesses"),
1338 E::LockTime(ref e) => write_err!(f, "transaction decoder error"; e),
1339 E::EarlyEnd(s) => write!(f, "early end of transaction (still decoding {})", s),
1340 E::NullPrevoutInNonCoinbase(index) =>
1341 write!(f, "null prevout in non-coinbase transaction at input {}", index),
1342 E::CoinbaseScriptSigTooSmall(len) =>
1343 write!(f, "coinbase scriptSig too small: {} bytes (min 2)", len),
1344 E::CoinbaseScriptSigTooLarge(len) =>
1345 write!(f, "coinbase scriptSig too large: {} bytes (max 100)", len),
1346 E::DuplicateInput(ref outpoint) =>
1347 write!(f, "duplicate input: {:?}:{}", outpoint.txid, outpoint.vout),
1348 E::OutputValueSumTooLarge(val) =>
1349 write!(f, "sum of output values {} satoshis exceeds MAX_MONEY", val),
1350 E::NoOutputs => write!(f, "transaction has no outputs"),
1351 }
1352 }
1353 }
1354
1355 #[cfg(feature = "std")]
1356 #[cfg(feature = "alloc")]
1357 impl std::error::Error for TransactionDecoderError {
1358 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
1359 use TransactionDecoderErrorInner as E;
1360
1361 match self.0 {
1362 E::Version(ref e) => Some(e),
1363 E::UnsupportedSegwitFlag(_) => None,
1364 E::Inputs(ref e) => Some(e),
1365 E::Outputs(ref e) => Some(e),
1366 E::Witness(ref e) => Some(e),
1367 E::NoWitnesses => None,
1368 E::LockTime(ref e) => Some(e),
1369 E::EarlyEnd(_) => None,
1370 E::NullPrevoutInNonCoinbase(_) => None,
1371 E::CoinbaseScriptSigTooSmall(_) => None,
1372 E::CoinbaseScriptSigTooLarge(_) => None,
1373 E::DuplicateInput(_) => None,
1374 E::OutputValueSumTooLarge(_) => None,
1375 E::NoOutputs => None,
1376 }
1377 }
1378 }
1379
1380 #[cfg(feature = "alloc")]
1382 #[derive(Debug, Clone, PartialEq, Eq)]
1383 pub struct TxInDecoderError(pub(super) <super::TxInInnerDecoder as encoding::Decoder>::Error);
1384
1385 #[cfg(feature = "alloc")]
1386 impl From<Infallible> for TxInDecoderError {
1387 fn from(never: Infallible) -> Self { match never {} }
1388 }
1389
1390 #[cfg(feature = "alloc")]
1391 impl fmt::Display for TxInDecoderError {
1392 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1393 write_err!(f, "txin decoder error"; self.0)
1394 }
1395 }
1396
1397 #[cfg(feature = "alloc")]
1398 #[cfg(feature = "std")]
1399 impl std::error::Error for TxInDecoderError {
1400 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { Some(&self.0) }
1401 }
1402
1403 #[cfg(feature = "alloc")]
1405 #[derive(Debug, Clone, PartialEq, Eq)]
1406 pub struct TxOutDecoderError(pub(super) <super::TxOutInnerDecoder as encoding::Decoder>::Error);
1407
1408 #[cfg(feature = "alloc")]
1409 impl From<Infallible> for TxOutDecoderError {
1410 fn from(never: Infallible) -> Self { match never {} }
1411 }
1412
1413 #[cfg(feature = "alloc")]
1414 impl fmt::Display for TxOutDecoderError {
1415 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1416 write_err!(f, "txout decoder error"; self.0)
1417 }
1418 }
1419
1420 #[cfg(feature = "std")]
1421 impl std::error::Error for TxOutDecoderError {
1422 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { Some(&self.0) }
1423 }
1424
1425 #[derive(Debug, Clone, PartialEq, Eq)]
1427 pub struct OutPointDecoderError(pub(super) encoding::UnexpectedEofError);
1428
1429 impl From<Infallible> for OutPointDecoderError {
1430 fn from(never: Infallible) -> Self { match never {} }
1431 }
1432
1433 impl core::fmt::Display for OutPointDecoderError {
1434 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1435 write_err!(f, "out point decoder error"; self.0)
1436 }
1437 }
1438
1439 #[cfg(feature = "std")]
1440 impl std::error::Error for OutPointDecoderError {
1441 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { Some(&self.0) }
1442 }
1443
1444 #[derive(Debug, Clone, PartialEq, Eq)]
1446 #[non_exhaustive]
1447 #[cfg(feature = "alloc")]
1448 #[cfg(feature = "hex")]
1449 pub enum ParseOutPointError {
1450 Txid(hex::DecodeFixedLengthBytesError),
1452 Vout(parse_int::ParseIntError),
1454 Format,
1456 TooLong,
1458 VoutNotCanonical,
1460 }
1461
1462 #[cfg(feature = "alloc")]
1463 #[cfg(feature = "hex")]
1464 impl From<Infallible> for ParseOutPointError {
1465 #[inline]
1466 fn from(never: Infallible) -> Self { match never {} }
1467 }
1468
1469 #[cfg(feature = "alloc")]
1470 #[cfg(feature = "hex")]
1471 impl fmt::Display for ParseOutPointError {
1472 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1473 match *self {
1474 Self::Txid(ref e) => write_err!(f, "error parsing TXID"; e),
1475 Self::Vout(ref e) => write_err!(f, "error parsing vout"; e),
1476 Self::Format => write!(f, "OutPoint not in <txid>:<vout> format"),
1477 Self::TooLong => write!(f, "vout should be at most 10 digits"),
1478 Self::VoutNotCanonical => write!(f, "no leading zeroes or + allowed in vout part"),
1479 }
1480 }
1481 }
1482
1483 #[cfg(feature = "std")]
1484 #[cfg(feature = "hex")]
1485 impl std::error::Error for ParseOutPointError {
1486 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
1487 match self {
1488 Self::Txid(e) => Some(e),
1489 Self::Vout(e) => Some(e),
1490 Self::Format | Self::TooLong | Self::VoutNotCanonical => None,
1491 }
1492 }
1493 }
1494
1495 #[derive(Debug, Clone, PartialEq, Eq)]
1497 pub struct VersionDecoderError(pub(super) encoding::UnexpectedEofError);
1498
1499 impl From<Infallible> for VersionDecoderError {
1500 fn from(never: Infallible) -> Self { match never {} }
1501 }
1502
1503 impl fmt::Display for VersionDecoderError {
1504 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1505 write_err!(f, "version decoder error"; self.0)
1506 }
1507 }
1508
1509 #[cfg(feature = "std")]
1510 impl std::error::Error for VersionDecoderError {
1511 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { Some(&self.0) }
1512 }
1513}
1514
1515#[cfg(feature = "arbitrary")]
1516#[cfg(feature = "alloc")]
1517impl<'a> Arbitrary<'a> for Transaction {
1518 fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result<Self> {
1519 let version = Version::arbitrary(u)?;
1520 let lock_time = absolute::LockTime::arbitrary(u)?;
1521 let mut inputs = Vec::<TxIn>::arbitrary(u)?;
1522 let mut outputs = Vec::<TxOut>::arbitrary(u)?;
1523
1524 let mut seen = alloc::collections::BTreeSet::new();
1525 inputs.retain(|input| seen.insert(input.previous_output));
1526
1527 if inputs.len() > 1 {
1528 inputs.retain(|input| input.previous_output != OutPoint::COINBASE_PREVOUT);
1529 }
1530
1531 if inputs.len() == 1 && inputs[0].previous_output == OutPoint::COINBASE_PREVOUT {
1532 let len = inputs[0].script_sig.len();
1533 if len < 2 || len > 100 {
1534 inputs[0].script_sig = ScriptSigBuf::from_bytes(Vec::from([0u8; 2]));
1535 }
1536 }
1537
1538 if outputs.is_empty() {
1539 outputs.push(TxOut::arbitrary(u)?);
1540 }
1541
1542 let mut remaining = Amount::MAX_MONEY.to_sat();
1543 for output in &mut outputs {
1544 let capped = output.amount.to_sat().min(remaining);
1545 output.amount = Amount::from_sat(capped).expect("capped <= MAX_MONEY");
1546 remaining -= capped;
1547 }
1548
1549 Ok(Self { version, lock_time, inputs, outputs })
1550 }
1551}
1552
1553#[cfg(feature = "arbitrary")]
1554#[cfg(feature = "alloc")]
1555impl<'a> Arbitrary<'a> for TxIn {
1556 fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result<Self> {
1557 Ok(Self {
1558 previous_output: OutPoint::arbitrary(u)?,
1559 script_sig: ScriptSigBuf::arbitrary(u)?,
1560 sequence: Sequence::arbitrary(u)?,
1561 witness: Witness::arbitrary(u)?,
1562 })
1563 }
1564}
1565
1566#[cfg(feature = "arbitrary")]
1567#[cfg(feature = "alloc")]
1568impl<'a> Arbitrary<'a> for TxOut {
1569 fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result<Self> {
1570 Ok(Self { amount: Amount::arbitrary(u)?, script_pubkey: ScriptPubKeyBuf::arbitrary(u)? })
1571 }
1572}
1573
1574#[cfg(feature = "arbitrary")]
1575impl<'a> Arbitrary<'a> for OutPoint {
1576 fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result<Self> {
1577 Ok(Self { txid: Txid::arbitrary(u)?, vout: u32::arbitrary(u)? })
1578 }
1579}
1580
1581#[cfg(feature = "arbitrary")]
1582impl<'a> Arbitrary<'a> for Version {
1583 fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result<Self> {
1584 let choice = u.int_in_range(0..=3)?;
1586 match choice {
1587 0 => Ok(Self::ONE),
1588 1 => Ok(Self::TWO),
1589 2 => Ok(Self::THREE),
1590 _ => Ok(Self(u.arbitrary()?)),
1591 }
1592 }
1593}
1594
1595#[cfg(feature = "alloc")]
1596#[cfg(test)]
1597mod tests {
1598 use alloc::string::ToString;
1599 use alloc::{format, vec};
1600 #[cfg(feature = "hex")]
1601 use core::str::FromStr as _;
1602 #[cfg(feature = "std")]
1603 use std::error::Error as _;
1604
1605 use encoding::{Decode as _, Decoder as _};
1606 #[cfg(feature = "hex")]
1607 use hex::hex;
1608
1609 use super::*;
1610
1611 const TC_TXID_BYTES: [u8; 32] = [
1612 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10,
1613 9, 8, 7, 6, 5, 4, 3, 2, 1,
1614 ];
1615 const TC_VOUT_BYTES: [u8; 4] = [1, 0, 0, 0];
1616 const TC_SCRIPT_BYTES: [u8; 3] = [1, 2, 3];
1617 const TC_ONE_SAT_BYTES: [u8; 8] = [1, 0, 0, 0, 0, 0, 0, 0];
1618
1619 #[test]
1620 fn sanity_check() {
1621 let version = Version(123);
1622 assert_eq!(version.to_u32(), 123);
1623 assert_eq!(u32::from(version), 123);
1624
1625 assert!(!version.is_standard());
1626 assert!(Version::ONE.is_standard());
1627 assert!(Version::TWO.is_standard());
1628 assert!(Version::THREE.is_standard());
1629 }
1630
1631 #[test]
1632 fn transaction_functions() {
1633 let txin = TxIn {
1634 previous_output: OutPoint {
1635 txid: Txid::from_byte_array([0xAA; 32]), vout: 0,
1637 },
1638 script_sig: ScriptSigBuf::new(),
1639 sequence: Sequence::MAX,
1640 witness: Witness::new(),
1641 };
1642
1643 let txout = TxOut {
1644 amount: Amount::from_sat(123_456_789).unwrap(),
1645 script_pubkey: ScriptPubKeyBuf::new(),
1646 };
1647
1648 let tx_orig = Transaction {
1649 version: Version::ONE,
1650 lock_time: absolute::LockTime::from_consensus(1_738_968_231), inputs: vec![txin],
1652 outputs: vec![txout],
1653 };
1654
1655 let mut tx = tx_orig.clone();
1657 tx.inputs[0].previous_output.txid = Txid::from_byte_array([0xFF; 32]);
1658 tx.outputs[0].amount = Amount::from_sat(987_654_321).unwrap();
1659 assert_eq!(tx.inputs[0].previous_output.txid.to_byte_array(), [0xFF; 32]);
1660 assert_eq!(tx.outputs[0].amount.to_sat(), 987_654_321);
1661
1662 assert!(!tx.uses_segwit_serialization());
1664 tx.inputs[0].witness.push(vec![0xAB, 0xCD, 0xEF]);
1665 assert!(tx.uses_segwit_serialization());
1666
1667 assert!(tx > tx_orig);
1669 }
1670
1671 #[test]
1672 #[cfg(feature = "hex")]
1673 fn transaction_hex_display() {
1674 let txin = TxIn {
1675 previous_output: OutPoint {
1676 txid: Txid::from_byte_array([0xAA; 32]), vout: 0,
1678 },
1679 script_sig: ScriptSigBuf::new(),
1680 sequence: Sequence::MAX,
1681 witness: Witness::new(),
1682 };
1683
1684 let txout = TxOut {
1685 amount: Amount::from_sat(123_456_789).unwrap(),
1686 script_pubkey: ScriptPubKeyBuf::new(),
1687 };
1688
1689 let tx_orig = Transaction {
1690 version: Version::ONE,
1691 lock_time: absolute::LockTime::from_consensus(1_765_112_030), inputs: vec![txin],
1693 outputs: vec![txout],
1694 };
1695
1696 let encoded_tx = "0100000001aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0000000000ffffffff0115cd5b070000000000de783569";
1697 let lower_hex_tx = format!("{:x}", tx_orig);
1698 let upper_hex_tx = format!("{:X}", tx_orig);
1699
1700 assert_eq!(encoded_tx, lower_hex_tx);
1702 assert_eq!(encoded_tx, format!("{}", tx_orig));
1703 assert_eq!(format!("0x{encoded_tx}"), format!("{:#x}", tx_orig));
1704 assert_eq!(format!("{:>132}", encoded_tx), format!("{:>132x}", tx_orig));
1705 assert_eq!(format!("{:<132}", encoded_tx), format!("{:<132x}", tx_orig));
1706 assert_eq!(format!("{:^132}", encoded_tx), format!("{:^132x}", tx_orig));
1707 assert_eq!(format!("{:.20}", encoded_tx), format!("{:.20x}", tx_orig));
1708
1709 let upper_encoded = encoded_tx
1711 .chars()
1712 .map(|chr| chr.to_ascii_uppercase())
1713 .collect::<alloc::string::String>();
1714 assert_eq!(upper_encoded, upper_hex_tx);
1715 assert_eq!(format!("0X{upper_encoded}"), format!("{:#X}", tx_orig));
1716 }
1717
1718 #[test]
1719 #[cfg(feature = "hex")]
1720 fn transaction_from_hex_str_round_trip() {
1721 let tx_in_1 = segwit_tx_in();
1723 let mut tx_in_2 = segwit_tx_in();
1724 tx_in_2.previous_output.vout = 2;
1725
1726 let tx = Transaction {
1728 version: Version::TWO,
1729 lock_time: absolute::LockTime::ZERO,
1730 inputs: vec![tx_in_1, tx_in_2],
1731 outputs: vec![tx_out(), tx_out()],
1732 };
1733
1734 let lower_hex_tx = format!("{:x}", tx);
1735 let upper_hex_tx = format!("{:X}", tx);
1736
1737 let parsed_lower = Transaction::from_str(&lower_hex_tx).unwrap();
1739 let parsed_upper = Transaction::from_str(&upper_hex_tx).unwrap();
1740
1741 assert_eq!(tx, parsed_lower);
1743 assert_eq!(tx, parsed_upper);
1744 }
1745
1746 #[test]
1747 #[cfg(feature = "hex")]
1748 #[cfg(feature = "std")]
1749 fn transaction_from_hex_str_error() {
1750 let odd = "abc"; let err = Transaction::from_str(odd).unwrap_err();
1753 assert!(matches!(
1754 err.source().unwrap().downcast_ref::<hex::OddLengthStringError>().unwrap(),
1755 hex::OddLengthStringError { .. },
1756 ));
1757
1758 let invalid = "zz";
1760 let err = Transaction::from_str(invalid).unwrap_err();
1761 assert!(matches!(
1762 err.source().unwrap().downcast_ref::<hex::InvalidCharError>().unwrap(),
1763 hex::InvalidCharError { .. },
1764 ));
1765
1766 let bad = "deadbeef00"; let err = Transaction::from_str(bad).unwrap_err();
1769 assert!(matches!(
1770 err.source()
1771 .unwrap()
1772 .source()
1773 .unwrap()
1774 .downcast_ref::<TransactionDecoderError>()
1775 .unwrap(),
1776 TransactionDecoderError { .. },
1777 ));
1778 }
1779
1780 #[test]
1781 #[cfg(feature = "hex")]
1782 fn outpoint_from_str() {
1783 let mut outpoint_str = "0".repeat(64); let outpoint: Result<OutPoint, ParseOutPointError> = outpoint_str.parse();
1786 assert_eq!(outpoint, Err(ParseOutPointError::Format));
1787
1788 outpoint_str.push(':'); let outpoint: Result<OutPoint, ParseOutPointError> = outpoint_str.parse();
1790 assert_eq!(outpoint, Err(ParseOutPointError::Format));
1791
1792 outpoint_str.push('0'); let outpoint: OutPoint = outpoint_str.parse().unwrap();
1794 assert_eq!(outpoint.txid, Txid::from_byte_array([0; 32]));
1795 assert_eq!(outpoint.vout, 0);
1796
1797 let outpoint_size = outpoint.txid.as_byte_array().len() + outpoint.vout.to_le_bytes().len();
1799 assert_eq!(outpoint_size, OutPoint::SIZE);
1800 }
1801
1802 #[test]
1803 #[cfg(feature = "hex")]
1804 fn outpoint_from_str_too_long() {
1805 let mut outpoint_str = "0".repeat(64);
1807 outpoint_str.push_str(":1234567890");
1808 assert_eq!(outpoint_str.len(), 75);
1809 assert!(outpoint_str.parse::<OutPoint>().is_ok());
1810
1811 outpoint_str.push('0');
1813 assert_eq!(outpoint_str.len(), 76);
1814 let outpoint: Result<OutPoint, ParseOutPointError> = outpoint_str.parse();
1815 assert_eq!(outpoint, Err(ParseOutPointError::TooLong));
1816 }
1817
1818 #[test]
1819 #[cfg(feature = "hex")]
1820 #[cfg(feature = "alloc")]
1821 fn outpoint() {
1822 assert_eq!("i don't care".parse::<OutPoint>(), Err(ParseOutPointError::Format));
1823 assert_eq!(
1824 "5df6e0e2761359d30a8275058e299fcc0381534545f55cf43e41983f5d4c9456:1:1"
1825 .parse::<OutPoint>(),
1826 Err(ParseOutPointError::Format)
1827 );
1828 assert_eq!(
1829 "5df6e0e2761359d30a8275058e299fcc0381534545f55cf43e41983f5d4c9456:".parse::<OutPoint>(),
1830 Err(ParseOutPointError::Format)
1831 );
1832 assert_eq!(
1833 "5df6e0e2761359d30a8275058e299fcc0381534545f55cf43e41983f5d4c9456:11111111111"
1834 .parse::<OutPoint>(),
1835 Err(ParseOutPointError::TooLong)
1836 );
1837 assert_eq!(
1838 "5df6e0e2761359d30a8275058e299fcc0381534545f55cf43e41983f5d4c9456:01"
1839 .parse::<OutPoint>(),
1840 Err(ParseOutPointError::VoutNotCanonical)
1841 );
1842 assert_eq!(
1843 "5df6e0e2761359d30a8275058e299fcc0381534545f55cf43e41983f5d4c9456:+42"
1844 .parse::<OutPoint>(),
1845 Err(ParseOutPointError::VoutNotCanonical)
1846 );
1847 assert_eq!(
1848 "i don't care:1".parse::<OutPoint>(),
1849 Err(ParseOutPointError::Txid("i don't care".parse::<Txid>().unwrap_err()))
1850 );
1851 assert_eq!(
1852 "5df6e0e2761359d30a8275058e299fcc0381534545f55cf43e41983f5d4c945X:1"
1853 .parse::<OutPoint>(),
1854 Err(ParseOutPointError::Txid(
1855 "5df6e0e2761359d30a8275058e299fcc0381534545f55cf43e41983f5d4c945X"
1856 .parse::<Txid>()
1857 .unwrap_err()
1858 ))
1859 );
1860 assert_eq!(
1861 "5df6e0e2761359d30a8275058e299fcc0381534545f55cf43e41983f5d4c9456:lol"
1862 .parse::<OutPoint>(),
1863 Err(ParseOutPointError::Vout(parse_int::int_from_str::<u32>("lol").unwrap_err()))
1864 );
1865
1866 assert_eq!(
1867 "5df6e0e2761359d30a8275058e299fcc0381534545f55cf43e41983f5d4c9456:42"
1868 .parse::<OutPoint>(),
1869 Ok(OutPoint {
1870 txid: "5df6e0e2761359d30a8275058e299fcc0381534545f55cf43e41983f5d4c9456"
1871 .parse()
1872 .unwrap(),
1873 vout: 42,
1874 })
1875 );
1876 assert_eq!(
1877 "5df6e0e2761359d30a8275058e299fcc0381534545f55cf43e41983f5d4c9456:0"
1878 .parse::<OutPoint>(),
1879 Ok(OutPoint {
1880 txid: "5df6e0e2761359d30a8275058e299fcc0381534545f55cf43e41983f5d4c9456"
1881 .parse()
1882 .unwrap(),
1883 vout: 0,
1884 })
1885 );
1886 }
1887
1888 #[test]
1889 #[cfg(feature = "hex")]
1890 fn canonical_vout() {
1891 assert_eq!(parse_vout("0").unwrap(), 0);
1892 assert_eq!(parse_vout("1").unwrap(), 1);
1893 assert!(parse_vout("01").is_err()); assert!(parse_vout("+1").is_err()); }
1896
1897 #[test]
1898 #[cfg(feature = "alloc")]
1899 #[cfg(feature = "hex")]
1900 fn outpoint_display_roundtrip() {
1901 let outpoint_str = "0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20:1";
1902 let outpoint: OutPoint = outpoint_str.parse().unwrap();
1903 assert_eq!(format!("{}", outpoint), outpoint_str);
1904 }
1905
1906 #[test]
1907 #[cfg(feature = "alloc")]
1908 #[cfg(feature = "hex")]
1909 fn outpoint_format() {
1910 let outpoint = OutPoint::COINBASE_PREVOUT;
1911
1912 let debug = "OutPoint { txid: Txid(bitcoin_hashes::sha256d::Hash(0000000000000000000000000000000000000000000000000000000000000000)), vout: 4294967295 }";
1913 assert_eq!(debug, format!("{:?}", outpoint));
1914
1915 let display = "0000000000000000000000000000000000000000000000000000000000000000:4294967295";
1916 assert_eq!(display, format!("{}", outpoint));
1917
1918 let pretty_debug = "OutPoint {
1919 txid: Txid(
1920 bitcoin_hashes::sha256d::Hash(
1921 0x0000000000000000000000000000000000000000000000000000000000000000,
1922 ),
1923 ),
1924 vout: 4294967295,
1925}";
1926 assert_eq!(pretty_debug, format!("{:#?}", outpoint));
1927
1928 let debug_txid = "Txid(bitcoin_hashes::sha256d::Hash(0000000000000000000000000000000000000000000000000000000000000000))";
1929 assert_eq!(debug_txid, format!("{:?}", outpoint.txid));
1930
1931 let display_txid = "0000000000000000000000000000000000000000000000000000000000000000";
1932 assert_eq!(display_txid, format!("{}", outpoint.txid));
1933
1934 let pretty_txid = "0x0000000000000000000000000000000000000000000000000000000000000000";
1935 assert_eq!(pretty_txid, format!("{:#}", outpoint.txid));
1936 }
1937
1938 #[test]
1939 fn version_display() {
1940 let version = Version(123);
1941 assert_eq!(format!("{}", version), "123");
1942 assert_eq!(format!("{:x}", version), "7b");
1943 assert_eq!(format!("{:#x}", version), "0x7b");
1944 assert_eq!(format!("{:X}", version), "7B");
1945 assert_eq!(format!("{:#X}", version), "0x7B");
1946 assert_eq!(format!("{:o}", version), "173");
1947 assert_eq!(format!("{:#o}", version), "0o173");
1948 assert_eq!(format!("{:b}", version), "1111011");
1949 assert_eq!(format!("{:#b}", version), "0b1111011");
1950 }
1951
1952 #[cfg(any(feature = "hex", feature = "serde"))]
1954 fn tc_out_point() -> OutPoint {
1955 let s = "0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20:1";
1956 s.parse::<OutPoint>().unwrap()
1957 }
1958
1959 #[test]
1960 #[cfg(feature = "serde")]
1961 fn out_point_serde_deserialize_human_readable() {
1962 let ser = "\"0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20:1\"";
1964 let got = serde_json::from_str::<OutPoint>(ser).unwrap();
1965 let want = tc_out_point();
1966
1967 assert_eq!(got, want);
1968 }
1969
1970 #[test]
1971 #[cfg(feature = "serde")]
1972 fn out_point_serde_deserialize_non_human_readable() {
1973 #[rustfmt::skip]
1974 let bytes = [
1975 32, 0, 0, 0, 0, 0, 0, 0,
1978 32, 31, 30, 29, 28, 27, 26, 25,
1980 24, 23, 22, 21, 20, 19, 18, 17,
1981 16, 15, 14, 13, 12, 11, 10, 9,
1982 8, 7, 6, 5, 4, 3, 2, 1,
1983 1, 0, 0, 0
1985 ];
1986
1987 let got = bincode::deserialize::<OutPoint>(&bytes).unwrap();
1988 let want = tc_out_point();
1989
1990 assert_eq!(got, want);
1991 }
1992
1993 #[test]
1994 #[cfg(feature = "serde")]
1995 fn out_point_serde_human_readable_rountrips() {
1996 let out_point = tc_out_point();
1997
1998 let ser = serde_json::to_string(&out_point).unwrap();
1999 let got = serde_json::from_str::<OutPoint>(&ser).unwrap();
2000
2001 assert_eq!(got, out_point);
2002 }
2003
2004 #[test]
2005 #[cfg(feature = "serde")]
2006 fn out_point_serde_non_human_readable_rountrips() {
2007 let out_point = tc_out_point();
2008
2009 let ser = bincode::serialize(&out_point).unwrap();
2010 let got = bincode::deserialize::<OutPoint>(&ser).unwrap();
2011
2012 assert_eq!(got, out_point);
2013 }
2014
2015 #[cfg(feature = "alloc")]
2016 fn tx_out() -> TxOut { TxOut { amount: Amount::ONE_SAT, script_pubkey: tc_script_pubkey() } }
2017
2018 #[cfg(any(feature = "hex", feature = "serde"))]
2019 fn segwit_tx_in() -> TxIn {
2020 let data = [&TC_SCRIPT_BYTES[..]];
2021 let witness = Witness::from_iter(data);
2022
2023 TxIn {
2024 previous_output: tc_out_point(),
2025 script_sig: tc_script_sig(),
2026 sequence: Sequence::MAX,
2027 witness,
2028 }
2029 }
2030
2031 #[cfg(feature = "alloc")]
2032 fn tc_script_pubkey() -> ScriptPubKeyBuf {
2033 ScriptPubKeyBuf::from_bytes(TC_SCRIPT_BYTES.to_vec())
2034 }
2035
2036 #[cfg(any(feature = "hex", feature = "serde"))]
2037 fn tc_script_sig() -> ScriptSigBuf { ScriptSigBuf::from_bytes(TC_SCRIPT_BYTES.to_vec()) }
2038
2039 #[test]
2040 #[cfg(feature = "alloc")]
2041 #[cfg(feature = "hex")]
2042 fn reject_null_prevout_in_non_coinbase_transaction() {
2043 let tx_bytes = hex!("01000000020000000000000000000000000000000000000000000000000000000000000000ffffffff00ffffffff00010000000000000000000000000000000000000000000000000000000000000000000000ffffffff010000000000000000015100000000");
2047
2048 let mut decoder = Transaction::decoder();
2049 let mut slice = tx_bytes.as_slice();
2050 decoder.push_bytes(&mut slice).unwrap();
2051 let err = decoder.end().expect_err("null prevout in non-coinbase tx should be rejected");
2052
2053 assert_eq!(
2054 err,
2055 TransactionDecoderError(TransactionDecoderErrorInner::NullPrevoutInNonCoinbase(0))
2056 );
2057 }
2058
2059 #[test]
2060 #[cfg(feature = "alloc")]
2061 #[cfg(feature = "hex")]
2062 fn reject_coinbase_scriptsig_too_small() {
2063 let tx_bytes = hex!("01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0151ffffffff010000000000000000015100000000");
2067
2068 let mut decoder = Transaction::decoder();
2069 let mut slice = tx_bytes.as_slice();
2070 decoder.push_bytes(&mut slice).unwrap();
2071 let err = decoder.end().expect_err("coinbase with 1-byte scriptSig should be rejected");
2072
2073 assert_eq!(
2074 err,
2075 TransactionDecoderError(TransactionDecoderErrorInner::CoinbaseScriptSigTooSmall(1))
2076 );
2077 }
2078
2079 #[test]
2080 #[cfg(feature = "alloc")]
2081 #[cfg(feature = "hex")]
2082 fn reject_coinbase_scriptsig_too_large() {
2083 let tx_bytes = hex!("01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff655151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151ffffffff010000000000000000015100000000");
2087
2088 let mut decoder = Transaction::decoder();
2089 let mut slice = tx_bytes.as_slice();
2090 decoder.push_bytes(&mut slice).unwrap();
2091 let err = decoder.end().expect_err("coinbase with 101-byte scriptSig should be rejected");
2092
2093 assert_eq!(
2094 err,
2095 TransactionDecoderError(TransactionDecoderErrorInner::CoinbaseScriptSigTooLarge(101))
2096 );
2097 }
2098
2099 #[test]
2100 #[cfg(feature = "alloc")]
2101 #[cfg(feature = "hex")]
2102 fn accept_coinbase_scriptsig_min_valid() {
2103 let tx_bytes = hex!("01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff025151ffffffff010000000000000000015100000000");
2105
2106 let mut decoder = Transaction::decoder();
2107 let mut slice = tx_bytes.as_slice();
2108 decoder.push_bytes(&mut slice).unwrap();
2109 let tx = decoder.end().expect("coinbase with 2-byte scriptSig should be accepted");
2110
2111 assert_eq!(tx.inputs[0].script_sig.len(), 2);
2112 }
2113
2114 #[test]
2115 #[cfg(feature = "alloc")]
2116 #[cfg(feature = "hex")]
2117 fn accept_coinbase_scriptsig_max_valid() {
2118 let tx_bytes = hex!("01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff6451515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151ffffffff010000000000000000015100000000");
2120
2121 let mut decoder = Transaction::decoder();
2122 let mut slice = tx_bytes.as_slice();
2123 decoder.push_bytes(&mut slice).unwrap();
2124 let tx = decoder.end().expect("coinbase with 100-byte scriptSig should be accepted");
2125
2126 assert_eq!(tx.inputs[0].script_sig.len(), 100);
2127 }
2128
2129 #[test]
2130 #[cfg(feature = "alloc")]
2131 #[cfg(feature = "hex")]
2132 fn reject_duplicate_inputs() {
2133 let tx_bytes = hex!("01000000020001000000000000000000000000000000000000000000000000000000000000000000006c47304402204bb1197053d0d7799bf1b30cd503c44b58d6240cccbdc85b6fe76d087980208f02204beeed78200178ffc6c74237bb74b3f276bbb4098b5605d814304fe128bf1431012321039e8815e15952a7c3fada1905f8cf55419837133bd7756c0ef14fc8dfe50c0deaacffffffff0001000000000000000000000000000000000000000000000000000000000000000000006c47304402202306489afef52a6f62e90bf750bbcdf40c06f5c6b138286e6b6b86176bb9341802200dba98486ea68380f47ebb19a7df173b99e6bc9c681d6ccf3bde31465d1f16b3012321039e8815e15952a7c3fada1905f8cf55419837133bd7756c0ef14fc8dfe50c0deaacffffffff010000000000000000015100000000");
2137
2138 let mut decoder = Transaction::decoder();
2139 let mut slice = tx_bytes.as_slice();
2140 decoder.push_bytes(&mut slice).unwrap();
2141 let err = decoder.end().expect_err("transaction with duplicate inputs should be rejected");
2142
2143 let expected_outpoint = OutPoint {
2144 txid: Txid::from_byte_array([
2145 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2146 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2147 0x00, 0x00, 0x00, 0x00,
2148 ]),
2149 vout: 0,
2150 };
2151 assert_eq!(
2152 err,
2153 TransactionDecoderError(TransactionDecoderErrorInner::DuplicateInput(
2154 expected_outpoint
2155 ))
2156 );
2157 }
2158
2159 #[test]
2160 #[cfg(feature = "alloc")]
2161 #[cfg(feature = "hex")]
2162 fn reject_output_value_sum_too_large() {
2163 let tx_bytes = hex!("01000000010001000000000000000000000000000000000000000000000000000000000000000000006d483045022027deccc14aa6668e78a8c9da3484fbcd4f9dcc9bb7d1b85146314b21b9ae4d86022100d0b43dece8cfb07348de0ca8bc5b86276fa88f7f2138381128b7c36ab2e42264012321029bb13463ddd5d2cc05da6e84e37536cb9525703cfd8f43afdb414988987a92f6acffffffff020040075af075070001510001000000000000015100000000");
2167
2168 let mut decoder = Transaction::decoder();
2169 let mut slice = tx_bytes.as_slice();
2170 decoder.push_bytes(&mut slice).unwrap();
2171 let err = decoder.end().expect_err("sum of output values > MAX_MONEY should be rejected");
2172
2173 assert!(matches!(err.0, TransactionDecoderErrorInner::OutputValueSumTooLarge(_)));
2174 }
2175
2176 #[test]
2177 #[cfg(feature = "alloc")]
2178 #[cfg(feature = "hex")]
2179 fn accept_output_value_sum_equal_to_max_money() {
2180 let tx_bytes = hex!("01000000010001000000000000000000000000000000000000000000000000000000000000000000006d483045022027deccc14aa6668e78a8c9da3484fbcd4f9dcc9bb7d1b85146314b21b9ae4d86022100d0b43dece8cfb07348de0ca8bc5b86276fa88f7f2138381128b7c36ab2e42264012321029bb13463ddd5d2cc05da6e84e37536cb9525703cfd8f43afdb414988987a92f6acffffffff020080c6a47e8d0300015100c040b571e80300015100000000");
2181
2182 let mut decoder = Transaction::decoder();
2183 let mut slice = tx_bytes.as_slice();
2184 decoder.push_bytes(&mut slice).unwrap();
2185 let tx = decoder.end().expect("sum of output values == MAX_MONEY should be accepted");
2186
2187 let total: u64 = tx.outputs.iter().map(|o| o.amount.to_sat()).sum();
2188 assert_eq!(total, Amount::MAX_MONEY.to_sat());
2189 }
2190
2191 #[test]
2192 #[cfg(feature = "alloc")]
2193 #[cfg(feature = "hex")]
2194 fn reject_output_value_greater_than_max_money() {
2195 let tx_bytes = hex!("01000000010001000000000000000000000000000000000000000000000000000000000000000000006e493046022100e1eadba00d9296c743cb6ecc703fd9ddc9b3cd12906176a226ae4c18d6b00796022100a71aef7d2874deff681ba6080f1b278bac7bb99c61b08a85f4311970ffe7f63f012321030c0588dc44d92bdcbf8e72093466766fdc265ead8db64517b0c542275b70fffbacffffffff010140075af0750700015100000000");
2199
2200 let mut decoder = Transaction::decoder();
2201 let mut slice = tx_bytes.as_slice();
2202 let result = decoder.push_bytes(&mut slice);
2203 assert!(result.is_err(), "output value > MAX_MONEY should be rejected during decoding");
2204 }
2205
2206 #[test]
2207 #[cfg(feature = "alloc")]
2208 #[cfg(feature = "hex")]
2209 fn reject_transaction_with_no_outputs() {
2210 let tx_bytes = hex!("01000000010001000000000000000000000000000000000000000000000000000000000000000000006d483045022100f16703104aab4e4088317c862daec83440242411b039d14280e03dd33b487ab802201318a7be236672c5c56083eb7a5a195bc57a40af7923ff8545016cd3b571e2a601232103c40e5d339df3f30bf753e7e04450ae4ef76c9e45587d1d993bdc4cd06f0651c7acffffffff0000000000");
2214
2215 let mut decoder = Transaction::decoder();
2216 let mut slice = tx_bytes.as_slice();
2217 decoder.push_bytes(&mut slice).unwrap();
2218 let err = decoder.end().unwrap_err();
2219 assert_eq!(err, TransactionDecoderError(TransactionDecoderErrorInner::NoOutputs));
2220 }
2221
2222 #[test]
2223 #[cfg(feature = "alloc")]
2224 fn compute_ntxid_ignores_script_sig_and_witness() {
2225 let mut tx_in = TxIn::EMPTY_COINBASE;
2226 tx_in.script_sig = ScriptSigBuf::from_bytes(vec![1, 2, 3]);
2227 tx_in.witness = Witness::from_slice(&[&[0xAAu8][..]]);
2228
2229 let mut tx = Transaction {
2230 version: Version::ONE,
2231 lock_time: absolute::LockTime::ZERO,
2232 inputs: vec![tx_in],
2233 outputs: vec![TxOut { amount: Amount::ONE_SAT, script_pubkey: ScriptPubKeyBuf::new() }],
2234 };
2235
2236 let ntxid = tx.compute_ntxid();
2237
2238 tx.inputs[0].script_sig = ScriptSigBuf::new();
2239 tx.inputs[0].witness = Witness::default();
2240
2241 assert_eq!(ntxid, Ntxid::from_byte_array(tx.compute_txid().to_byte_array()));
2242 }
2243
2244 #[test]
2245 #[cfg(feature = "alloc")]
2246 fn transaction_decoder_push_bytes_after_done_is_false() {
2247 let tx_bytes = [
2248 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2252 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2253 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ];
2261
2262 let mut decoder = TransactionDecoder::new();
2263 let mut bytes = tx_bytes.as_slice();
2264 assert!(decoder.push_bytes(&mut bytes).unwrap().is_ready());
2265
2266 let mut empty = [].as_slice();
2267 assert!(decoder.push_bytes(&mut empty).unwrap().is_ready());
2268 }
2269
2270 #[test]
2271 #[cfg(feature = "alloc")]
2272 fn transaction_decoder_push_bytes_inputs_needs_more() {
2273 use TransactionDecoderState as S;
2274 let mut decoder = TransactionDecoder {
2275 state: S::Inputs(Version::ONE, Attempt::First, VecDecoder::new()),
2276 };
2277 let mut bytes = [].as_slice();
2278 assert!(decoder.push_bytes(&mut bytes).unwrap().needs_more());
2279 }
2280
2281 #[test]
2282 #[cfg(feature = "alloc")]
2283 fn transaction_decoder_push_bytes_lock_time_completes() {
2284 use TransactionDecoderState as S;
2285
2286 let mut decoder = TransactionDecoder {
2287 state: S::LockTime(
2288 Version::ONE,
2289 vec![],
2290 vec![TxOut { amount: Amount::ONE_SAT, script_pubkey: ScriptPubKeyBuf::new() }],
2291 LockTimeDecoder::new(),
2292 ),
2293 };
2294 let mut bytes = [0u8, 0, 0, 0].as_slice();
2295
2296 assert!(decoder.push_bytes(&mut bytes).unwrap().is_ready());
2297 assert!(bytes.is_empty());
2298
2299 let tx = decoder.end().unwrap();
2300 assert_eq!(tx.lock_time, absolute::LockTime::ZERO);
2301 assert!(tx.inputs.is_empty());
2302 assert_eq!(tx.outputs.len(), 1);
2303 }
2304
2305 #[test]
2306 #[cfg(feature = "alloc")]
2307 fn transaction_decoder_push_bytes_lock_time_needs_more() {
2308 use TransactionDecoderState as S;
2309 let mut decoder = TransactionDecoder {
2310 state: S::LockTime(
2311 Version::ONE,
2312 vec![],
2313 vec![TxOut { amount: Amount::ONE_SAT, script_pubkey: ScriptPubKeyBuf::new() }],
2314 LockTimeDecoder::new(),
2315 ),
2316 };
2317 let mut bytes = [].as_slice();
2318 assert!(decoder.push_bytes(&mut bytes).unwrap().needs_more());
2319 }
2320
2321 #[test]
2322 #[cfg(feature = "alloc")]
2323 fn transaction_decoder_push_bytes_outputs_needs_more() {
2324 use TransactionDecoderState as S;
2325 let mut decoder = TransactionDecoder {
2326 state: S::Outputs(Version::ONE, vec![], IsSegwit::No, VecDecoder::new()),
2327 };
2328 let mut bytes = [].as_slice();
2329 assert!(decoder.push_bytes(&mut bytes).unwrap().needs_more());
2330 }
2331
2332 #[test]
2333 #[cfg(feature = "alloc")]
2334 fn transaction_decoder_push_bytes_segwit_flag_empty_needs_more() {
2335 use TransactionDecoderState as S;
2336 let mut decoder = TransactionDecoder { state: S::SegwitFlag(Version::ONE) };
2337 let mut bytes = [].as_slice();
2338 assert!(decoder.push_bytes(&mut bytes).unwrap().needs_more());
2339 }
2340
2341 #[test]
2342 #[cfg(feature = "alloc")]
2343 fn transaction_decoder_push_bytes_version_needs_more() {
2344 let mut decoder = TransactionDecoder::new();
2345 let mut bytes = [].as_slice();
2346 assert!(decoder.push_bytes(&mut bytes).unwrap().needs_more());
2347 }
2348
2349 #[test]
2350 #[cfg(feature = "alloc")]
2351 fn transaction_decoder_push_bytes_witnesses_needs_more() {
2352 use TransactionDecoderState as S;
2353 let tx_in = TxIn::EMPTY_COINBASE;
2354 let mut decoder = TransactionDecoder {
2355 state: S::Witnesses(
2356 Version::ONE,
2357 vec![tx_in],
2358 vec![],
2359 Iteration(0),
2360 WitnessDecoder::new(),
2361 ),
2362 };
2363 let mut bytes = [].as_slice();
2364 assert!(decoder.push_bytes(&mut bytes).unwrap().needs_more());
2365 }
2366
2367 #[test]
2368 #[cfg(feature = "alloc")]
2369 fn transaction_decoder_rejects_unsupported_segwit_flag() {
2370 let mut decoder = TransactionDecoder::new();
2371 let mut bytes = [1u8, 0, 0, 0, 0, 2].as_slice();
2372 let err = decoder.push_bytes(&mut bytes).unwrap_err();
2373 assert!(matches!(err.0, TransactionDecoderErrorInner::UnsupportedSegwitFlag(2)));
2374 }
2375
2376 #[test]
2377 #[cfg(feature = "alloc")]
2378 fn transaction_end_rejects_null_prevout_at_nonzero_index() {
2379 use TransactionDecoderState as S;
2380
2381 let input_0 = TxIn {
2382 previous_output: OutPoint { txid: Txid::from_byte_array([1u8; 32]), vout: 0 },
2383 script_sig: ScriptSigBuf::new(),
2384 sequence: Sequence::MAX,
2385 witness: Witness::default(),
2386 };
2387 let input_1 = TxIn {
2388 previous_output: OutPoint::COINBASE_PREVOUT,
2389 script_sig: ScriptSigBuf::new(),
2390 sequence: Sequence::MAX,
2391 witness: Witness::default(),
2392 };
2393 let tx = Transaction {
2394 version: Version::ONE,
2395 lock_time: absolute::LockTime::ZERO,
2396 inputs: vec![input_0, input_1],
2397 outputs: vec![TxOut { amount: Amount::ONE_SAT, script_pubkey: ScriptPubKeyBuf::new() }],
2398 };
2399
2400 let decoder = TransactionDecoder { state: S::Done(tx) };
2401 let err = decoder.end().unwrap_err();
2402 assert!(matches!(err.0, TransactionDecoderErrorInner::NullPrevoutInNonCoinbase(1)));
2403 }
2404
2405 #[test]
2406 #[cfg(feature = "alloc")]
2407 #[allow(clippy::should_panic_without_expect)]
2408 #[should_panic]
2409 fn transaction_decoder_end_after_error_panics() {
2410 use TransactionDecoderState as S;
2411 let decoder = TransactionDecoder { state: S::Errored };
2412 let _ = decoder.end();
2413 }
2414
2415 #[test]
2416 #[cfg(feature = "alloc")]
2417 #[allow(clippy::should_panic_without_expect)]
2418 #[should_panic]
2419 fn transaction_decoder_push_bytes_after_error_panics() {
2420 use TransactionDecoderState as S;
2421
2422 let mut decoder = TransactionDecoder { state: S::Errored };
2423 let mut bytes = [].as_slice();
2424 let _ = decoder.push_bytes(&mut bytes);
2425 }
2426
2427 #[test]
2428 #[cfg(feature = "alloc")]
2429 fn txid_from_transaction_matches_compute_txid() {
2430 let tx = Transaction {
2431 version: Version::ONE,
2432 lock_time: absolute::LockTime::ZERO,
2433 inputs: vec![TxIn::EMPTY_COINBASE],
2434 outputs: vec![TxOut { amount: Amount::ONE_SAT, script_pubkey: ScriptPubKeyBuf::new() }],
2435 };
2436
2437 assert_eq!(Txid::from(&tx), tx.compute_txid());
2438 assert_eq!(Txid::from(tx.clone()), tx.compute_txid());
2439 }
2440
2441 #[test]
2442 #[cfg(feature = "alloc")]
2443 fn wtxid_from_transaction_matches_compute_wtxid() {
2444 let tx = Transaction {
2445 version: Version::ONE,
2446 lock_time: absolute::LockTime::ZERO,
2447 inputs: vec![TxIn::EMPTY_COINBASE],
2448 outputs: vec![TxOut { amount: Amount::ONE_SAT, script_pubkey: ScriptPubKeyBuf::new() }],
2449 };
2450
2451 assert_eq!(Wtxid::from(&tx), tx.compute_wtxid());
2452 assert_eq!(Wtxid::from(tx.clone()), tx.compute_wtxid());
2453 }
2454
2455 #[test]
2456 #[cfg(feature = "alloc")]
2457 fn witnesses_encoder_empty_inputs() {
2458 let mut encoder = WitnessesEncoder::new(&[]);
2459 encoding::check_encoder(&mut encoder, &[]);
2460 }
2461
2462 #[test]
2463 #[cfg(feature = "alloc")]
2464 fn out_point_decoder_default_read_limit() {
2465 let decoder_default = OutPointDecoder::default();
2466 assert_eq!(decoder_default.read_limit(), 36);
2468
2469 let mut decoder = OutPoint::decoder();
2470 assert_eq!(decoder.read_limit(), 36);
2471
2472 let mut bytes = [0u8].as_slice();
2474 decoder.push_bytes(&mut bytes).unwrap();
2475 assert_eq!(decoder.read_limit(), 35);
2476
2477 let mut bytes = [0u8; 35].as_slice();
2479 decoder.push_bytes(&mut bytes).unwrap();
2480 assert_eq!(decoder.read_limit(), 0);
2481 }
2482
2483 #[test]
2484 #[cfg(feature = "alloc")]
2485 fn transaction_decoder_read_limit() {
2486 use TransactionDecoderState as S;
2487
2488 let decoder = TransactionDecoder::default();
2489 assert_eq!(decoder.read_limit(), 4);
2491
2492 let decoder = TransactionDecoder {
2493 state: S::Inputs(Version::ONE, Attempt::First, VecDecoder::<TxIn>::new()),
2494 };
2495 assert_eq!(decoder.read_limit(), 1);
2497
2498 let decoder = TransactionDecoder { state: S::SegwitFlag(Version::ONE) };
2499 assert_eq!(decoder.read_limit(), 1);
2501
2502 let decoder = TransactionDecoder {
2503 state: S::Outputs(Version::ONE, vec![], IsSegwit::No, VecDecoder::<TxOut>::new()),
2504 };
2505 assert_eq!(decoder.read_limit(), 1);
2507
2508 let decoder = TransactionDecoder {
2509 state: S::Witnesses(
2510 Version::ONE,
2511 vec![TxIn::EMPTY_COINBASE],
2512 vec![],
2513 Iteration(0),
2514 WitnessDecoder::new(),
2515 ),
2516 };
2517 assert_eq!(decoder.read_limit(), 1);
2519
2520 let decoder = TransactionDecoder {
2521 state: S::LockTime(Version::ONE, vec![], vec![], LockTimeDecoder::new()),
2522 };
2523 assert_eq!(decoder.read_limit(), 4);
2525
2526 let tx = Transaction {
2527 version: Version::ONE,
2528 lock_time: absolute::LockTime::ZERO,
2529 inputs: vec![TxIn::EMPTY_COINBASE],
2530 outputs: vec![TxOut { amount: Amount::ONE_SAT, script_pubkey: ScriptPubKeyBuf::new() }],
2531 };
2532 let decoder = TransactionDecoder { state: S::Done(tx) };
2533 assert_eq!(decoder.read_limit(), 0);
2535
2536 let decoder = TransactionDecoder { state: S::Errored };
2537 assert_eq!(decoder.read_limit(), 0);
2538 }
2539
2540 #[test]
2541 #[cfg(feature = "alloc")]
2542 fn txin_decoder_read_limit() {
2543 let mut decoder = TxIn::decoder();
2544 assert_eq!(decoder.read_limit(), 41);
2546
2547 let mut bytes = [0u8; 36].as_slice();
2549 decoder.push_bytes(&mut bytes).unwrap();
2550 assert_eq!(decoder.read_limit(), 5);
2552
2553 let mut bytes = [0x00u8].as_slice();
2555 decoder.push_bytes(&mut bytes).unwrap();
2556 assert_eq!(decoder.read_limit(), 4);
2558
2559 let mut bytes = [0x00u8].as_slice();
2561 decoder.push_bytes(&mut bytes).unwrap();
2562 assert_eq!(decoder.read_limit(), 3);
2563 }
2564
2565 #[test]
2566 #[cfg(feature = "alloc")]
2567 fn txout_decoder_read_limit() {
2568 let mut decoder = TxOut::decoder();
2569 assert_eq!(decoder.read_limit(), 9);
2571
2572 let mut bytes = [0u8; 8].as_slice();
2574 decoder.push_bytes(&mut bytes).unwrap();
2575 assert_eq!(decoder.read_limit(), 1);
2577
2578 let mut bytes = [0x00u8].as_slice();
2580 decoder.push_bytes(&mut bytes).unwrap();
2581 assert_eq!(decoder.read_limit(), 0);
2582 }
2583
2584 #[test]
2585 #[cfg(feature = "alloc")]
2586 fn version_decoder_default_read_limit() {
2587 let decoder_default = VersionDecoder::default();
2588 assert_eq!(decoder_default.read_limit(), 4);
2590
2591 let mut decoder = Version::decoder();
2592 assert_eq!(decoder.read_limit(), 4);
2593
2594 let mut bytes = [0u8].as_slice();
2596 decoder.push_bytes(&mut bytes).unwrap();
2597 assert_eq!(decoder.read_limit(), 3);
2598 }
2599
2600 #[test]
2601 #[cfg(feature = "alloc")]
2602 fn out_point_decoder_error() {
2603 let mut decoder = OutPoint::decoder();
2604 let mut slice = &[][..];
2605
2606 let status = decoder.push_bytes(&mut slice).unwrap();
2607 assert!(status.needs_more());
2608
2609 let err = decoder.end().unwrap_err();
2610 assert!(matches!(err, OutPointDecoderError(_)));
2611
2612 assert!(!err.to_string().is_empty());
2613 #[cfg(feature = "std")]
2614 assert!(err.source().is_some());
2615 }
2616
2617 #[test]
2618 #[cfg(feature = "alloc")]
2619 #[cfg(feature = "hex")]
2620 fn parse_out_point_txid_error() {
2621 let err = ("z".repeat(64) + ":0").parse::<OutPoint>().unwrap_err();
2622 assert!(matches!(err, ParseOutPointError::Txid(_)));
2623
2624 assert!(!err.to_string().is_empty());
2625 #[cfg(feature = "std")]
2626 assert!(err.source().is_some());
2627 }
2628
2629 #[test]
2630 #[cfg(feature = "alloc")]
2631 #[cfg(feature = "hex")]
2632 fn parse_out_point_vout_error() {
2633 let txid = "0".repeat(64);
2634
2635 let err = format!("{}:{}", txid, "x").parse::<OutPoint>().unwrap_err();
2636 assert!(matches!(err, ParseOutPointError::Vout(_)));
2637
2638 assert!(!err.to_string().is_empty());
2639 #[cfg(feature = "std")]
2640 assert!(err.source().is_some());
2641 }
2642
2643 #[test]
2644 #[cfg(feature = "alloc")]
2645 #[cfg(feature = "hex")]
2646 fn parse_out_point_format_error() {
2647 let txid = "0".repeat(64);
2648 let err = txid.parse::<OutPoint>().unwrap_err();
2649 assert!(matches!(err, ParseOutPointError::Format));
2650
2651 assert!(!err.to_string().is_empty());
2652 #[cfg(feature = "std")]
2653 assert!(err.source().is_none());
2654 }
2655
2656 #[test]
2657 #[cfg(feature = "alloc")]
2658 #[cfg(feature = "hex")]
2659 fn parse_out_point_too_long_error() {
2660 let txid = "0".repeat(64);
2661 let err = format!("{}:{}", txid, "12345678900").parse::<OutPoint>().unwrap_err();
2662 assert!(matches!(err, ParseOutPointError::TooLong));
2663
2664 assert!(!err.to_string().is_empty());
2665 #[cfg(feature = "std")]
2666 assert!(err.source().is_none());
2667 }
2668
2669 #[test]
2670 #[cfg(feature = "alloc")]
2671 #[cfg(feature = "hex")]
2672 fn parse_out_point_vout_not_canonical_error() {
2673 let txid = "0".repeat(64);
2674 let err = format!("{}:{}", txid, "01").parse::<OutPoint>().unwrap_err();
2675 assert!(matches!(err, ParseOutPointError::VoutNotCanonical));
2676
2677 assert!(!err.to_string().is_empty());
2678 #[cfg(feature = "std")]
2679 assert!(err.source().is_none());
2680 }
2681
2682 #[test]
2683 #[cfg(feature = "alloc")]
2684 fn version_decoder_error() {
2685 let mut decoder = Version::decoder();
2686 let mut slice = &[][..];
2687
2688 let status = decoder.push_bytes(&mut slice).unwrap();
2689 assert!(status.needs_more());
2690
2691 let err = decoder.end().unwrap_err();
2692 assert!(matches!(err, VersionDecoderError(_)));
2693
2694 assert!(!err.to_string().is_empty());
2695 #[cfg(feature = "std")]
2696 assert!(err.source().is_some());
2697 }
2698
2699 #[test]
2700 #[cfg(feature = "alloc")]
2701 fn transaction_decoder_version_error() {
2702 let mut decoder = VersionDecoder::new();
2703 let mut bytes = [0u8, 0, 0].as_slice();
2704 assert!(decoder.push_bytes(&mut bytes).unwrap().needs_more());
2705 let err = TransactionDecoderError(TransactionDecoderErrorInner::Version(
2706 decoder.end().unwrap_err(),
2707 ));
2708 assert!(matches!(err.0, TransactionDecoderErrorInner::Version(_)));
2709
2710 assert!(!err.to_string().is_empty());
2711 #[cfg(feature = "std")]
2712 assert!(err.source().is_some());
2713 }
2714
2715 #[test]
2716 #[cfg(feature = "alloc")]
2717 fn transaction_decoder_unsupported_segwit_flag_error() {
2718 let mut decoder = TransactionDecoder::new();
2719 let mut bytes = [1u8, 0, 0, 0, 0, 2].as_slice();
2720 let err = decoder.push_bytes(&mut bytes).unwrap_err();
2721 assert!(matches!(err.0, TransactionDecoderErrorInner::UnsupportedSegwitFlag(2)));
2722
2723 assert!(!err.to_string().is_empty());
2724 #[cfg(feature = "std")]
2725 assert!(err.source().is_none());
2726 }
2727
2728 #[test]
2729 #[cfg(feature = "alloc")]
2730 fn transaction_decoder_inputs_error() {
2731 let mut decoder = VecDecoder::<TxIn>::new();
2732 let mut bytes = [1u8].as_slice();
2733 assert!(decoder.push_bytes(&mut bytes).unwrap().needs_more());
2734 let err = TransactionDecoderError(TransactionDecoderErrorInner::Inputs(
2735 decoder.end().unwrap_err(),
2736 ));
2737 assert!(matches!(err.0, TransactionDecoderErrorInner::Inputs(_)));
2738
2739 assert!(!err.to_string().is_empty());
2740 #[cfg(feature = "std")]
2741 assert!(err.source().is_some());
2742 }
2743
2744 #[test]
2745 #[cfg(feature = "alloc")]
2746 fn transaction_decoder_outputs_error() {
2747 let mut decoder = VecDecoder::<TxOut>::new();
2748 let mut bytes = [1u8].as_slice();
2749 assert!(decoder.push_bytes(&mut bytes).unwrap().needs_more());
2750 let err = TransactionDecoderError(TransactionDecoderErrorInner::Outputs(
2751 decoder.end().unwrap_err(),
2752 ));
2753 assert!(matches!(err.0, TransactionDecoderErrorInner::Outputs(_)));
2754
2755 assert!(!err.to_string().is_empty());
2756 #[cfg(feature = "std")]
2757 assert!(err.source().is_some());
2758 }
2759
2760 #[test]
2761 #[cfg(feature = "alloc")]
2762 fn transaction_decoder_witness_error() {
2763 let mut decoder = WitnessDecoder::new();
2764 let mut bytes = [1u8].as_slice();
2765 assert!(decoder.push_bytes(&mut bytes).unwrap().needs_more());
2766 let err = TransactionDecoderError(TransactionDecoderErrorInner::Witness(
2767 decoder.end().unwrap_err(),
2768 ));
2769 assert!(matches!(err.0, TransactionDecoderErrorInner::Witness(_)));
2770
2771 assert!(!err.to_string().is_empty());
2772 #[cfg(feature = "std")]
2773 assert!(err.source().is_some());
2774 }
2775
2776 #[test]
2777 #[cfg(feature = "alloc")]
2778 fn transaction_decoder_no_witnesses_error() {
2779 let tx_bytes = [
2780 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2785 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2786 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ];
2794
2795 let mut slice = tx_bytes.as_slice();
2796 let err = Transaction::decoder().push_bytes(&mut slice).unwrap_err();
2797 assert!(matches!(err.0, TransactionDecoderErrorInner::NoWitnesses));
2798
2799 assert!(!err.to_string().is_empty());
2800 #[cfg(feature = "std")]
2801 assert!(err.source().is_none());
2802 }
2803
2804 #[test]
2805 #[cfg(feature = "alloc")]
2806 fn transaction_decoder_lock_time_error() {
2807 let mut decoder = LockTimeDecoder::new();
2808 let mut bytes = [0u8, 0, 0].as_slice();
2809 assert!(decoder.push_bytes(&mut bytes).unwrap().needs_more());
2810 let err = TransactionDecoderError(TransactionDecoderErrorInner::LockTime(
2811 decoder.end().unwrap_err(),
2812 ));
2813 assert!(matches!(err.0, TransactionDecoderErrorInner::LockTime(_)));
2814
2815 assert!(!err.to_string().is_empty());
2816 #[cfg(feature = "std")]
2817 assert!(err.source().is_some());
2818 }
2819
2820 #[test]
2821 #[cfg(feature = "alloc")]
2822 fn transaction_decoder_early_end_version_error() {
2823 let err = decode_error_from_bytes(&[0u8, 0, 0]);
2824 assert!(matches!(err.0, TransactionDecoderErrorInner::EarlyEnd("version")));
2825
2826 assert!(!err.to_string().is_empty());
2827 #[cfg(feature = "std")]
2828 assert!(err.source().is_none());
2829 }
2830
2831 #[test]
2832 #[cfg(feature = "alloc")]
2833 fn transaction_decoder_early_end_inputs_error() {
2834 let bytes = [
2835 0x01, 0x00, 0x00, 0x00, ];
2837 let err = decode_error_from_bytes(&bytes);
2838 assert!(matches!(err.0, TransactionDecoderErrorInner::EarlyEnd("inputs")));
2839
2840 assert!(!err.to_string().is_empty());
2841 #[cfg(feature = "std")]
2842 assert!(err.source().is_none());
2843 }
2844
2845 #[test]
2846 #[cfg(feature = "alloc")]
2847 fn transaction_decoder_early_end_segwit_flag_error() {
2848 let bytes = [
2849 0x01, 0x00, 0x00, 0x00, 0x00, ];
2852 let err = decode_error_from_bytes(&bytes);
2853 assert!(matches!(err.0, TransactionDecoderErrorInner::EarlyEnd("segwit flag")));
2854
2855 assert!(!err.to_string().is_empty());
2856 #[cfg(feature = "std")]
2857 assert!(err.source().is_none());
2858 }
2859
2860 #[test]
2861 #[cfg(feature = "alloc")]
2862 fn transaction_decoder_early_end_outputs_error() {
2863 let bytes = [
2864 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2868 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2869 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, ];
2873 let err = decode_error_from_bytes(&bytes);
2874 assert!(matches!(err.0, TransactionDecoderErrorInner::EarlyEnd("outputs")));
2875
2876 assert!(!err.to_string().is_empty());
2877 #[cfg(feature = "std")]
2878 assert!(err.source().is_none());
2879 }
2880
2881 #[test]
2882 #[cfg(feature = "alloc")]
2883 fn transaction_decoder_early_end_witnesses_error() {
2884 let tx_bytes = [
2885 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2890 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2891 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ];
2898
2899 let err = decode_error_from_bytes(&tx_bytes);
2900 assert!(matches!(err.0, TransactionDecoderErrorInner::EarlyEnd("witnesses")));
2901
2902 assert!(!err.to_string().is_empty());
2903 #[cfg(feature = "std")]
2904 assert!(err.source().is_none());
2905 }
2906
2907 #[test]
2908 #[cfg(feature = "alloc")]
2909 fn transaction_decoder_early_end_locktime_error() {
2910 let tx_bytes = [
2911 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2915 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2916 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ];
2923
2924 let err = decode_error_from_bytes(&tx_bytes);
2925 assert!(matches!(err.0, TransactionDecoderErrorInner::EarlyEnd("locktime")));
2926
2927 assert!(!err.to_string().is_empty());
2928 #[cfg(feature = "std")]
2929 assert!(err.source().is_none());
2930 }
2931
2932 #[test]
2933 #[cfg(feature = "alloc")]
2934 fn transaction_decoder_null_prevout_in_non_coinbase_error() {
2935 let input_0 = TxIn::EMPTY_COINBASE;
2936 let input_1 = TxIn {
2937 previous_output: OutPoint { txid: Txid::from_byte_array([1u8; 32]), vout: 0 },
2938 script_sig: ScriptSigBuf::new(),
2939 sequence: Sequence::MAX,
2940 witness: Witness::default(),
2941 };
2942 let tx = Transaction {
2943 version: Version::ONE,
2944 lock_time: absolute::LockTime::ZERO,
2945 inputs: vec![input_0, input_1],
2946 outputs: vec![TxOut { amount: Amount::ONE_SAT, script_pubkey: ScriptPubKeyBuf::new() }],
2947 };
2948
2949 let err = decode_error_from_tx(&tx);
2950 assert!(matches!(err.0, TransactionDecoderErrorInner::NullPrevoutInNonCoinbase(0)));
2951
2952 assert!(!err.to_string().is_empty());
2953 #[cfg(feature = "std")]
2954 assert!(err.source().is_none());
2955 }
2956
2957 #[test]
2958 #[cfg(feature = "alloc")]
2959 fn transaction_decoder_coinbase_script_sig_too_small_error() {
2960 let input_0 = TxIn {
2961 previous_output: OutPoint::COINBASE_PREVOUT,
2962 script_sig: ScriptSigBuf::from_bytes(vec![0x51]),
2963 sequence: Sequence::MAX,
2964 witness: Witness::default(),
2965 };
2966 let tx = Transaction {
2967 version: Version::ONE,
2968 lock_time: absolute::LockTime::ZERO,
2969 inputs: vec![input_0],
2970 outputs: vec![TxOut { amount: Amount::ONE_SAT, script_pubkey: ScriptPubKeyBuf::new() }],
2971 };
2972
2973 let err = decode_error_from_tx(&tx);
2974 assert!(matches!(err.0, TransactionDecoderErrorInner::CoinbaseScriptSigTooSmall(1)));
2975
2976 assert!(!err.to_string().is_empty());
2977 #[cfg(feature = "std")]
2978 assert!(err.source().is_none());
2979 }
2980
2981 #[test]
2982 #[cfg(feature = "alloc")]
2983 fn transaction_decoder_coinbase_script_sig_too_large_error() {
2984 let input_0 = TxIn {
2985 previous_output: OutPoint::COINBASE_PREVOUT,
2986 script_sig: ScriptSigBuf::from_bytes(vec![0x51; 101]),
2987 sequence: Sequence::MAX,
2988 witness: Witness::default(),
2989 };
2990 let tx = Transaction {
2991 version: Version::ONE,
2992 lock_time: absolute::LockTime::ZERO,
2993 inputs: vec![input_0],
2994 outputs: vec![TxOut { amount: Amount::ONE_SAT, script_pubkey: ScriptPubKeyBuf::new() }],
2995 };
2996
2997 let err = decode_error_from_tx(&tx);
2998 assert!(matches!(err.0, TransactionDecoderErrorInner::CoinbaseScriptSigTooLarge(101)));
2999
3000 assert!(!err.to_string().is_empty());
3001 #[cfg(feature = "std")]
3002 assert!(err.source().is_none());
3003 }
3004
3005 #[test]
3006 #[cfg(feature = "alloc")]
3007 fn transaction_decoder_duplicate_input_error() {
3008 let outpoint = OutPoint { txid: Txid::from_byte_array([2u8; 32]), vout: 1 };
3009 let input_0 = TxIn {
3010 previous_output: outpoint,
3011 script_sig: ScriptSigBuf::new(),
3012 sequence: Sequence::MAX,
3013 witness: Witness::default(),
3014 };
3015 let input_1 = input_0.clone();
3016 let tx = Transaction {
3017 version: Version::ONE,
3018 lock_time: absolute::LockTime::ZERO,
3019 inputs: vec![input_0, input_1],
3020 outputs: vec![TxOut { amount: Amount::ONE_SAT, script_pubkey: ScriptPubKeyBuf::new() }],
3021 };
3022
3023 let err = decode_error_from_tx(&tx);
3024 assert!(matches!(
3025 err.0,
3026 TransactionDecoderErrorInner::DuplicateInput(got) if got == outpoint
3027 ));
3028
3029 assert!(!err.to_string().is_empty());
3030 #[cfg(feature = "std")]
3031 assert!(err.source().is_none());
3032 }
3033
3034 #[test]
3035 #[cfg(feature = "alloc")]
3036 fn transaction_decoder_output_value_sum_too_large_error() {
3037 let expected = Amount::MAX_MONEY.to_sat() + 1;
3038 let tx = Transaction {
3039 version: Version::ONE,
3040 lock_time: absolute::LockTime::ZERO,
3041 inputs: vec![TxIn {
3042 previous_output: OutPoint { txid: Txid::from_byte_array([1u8; 32]), vout: 0 },
3043 script_sig: ScriptSigBuf::new(),
3044 sequence: Sequence::MAX,
3045 witness: Witness::default(),
3046 }],
3047 outputs: vec![
3048 TxOut { amount: Amount::MAX_MONEY, script_pubkey: ScriptPubKeyBuf::new() },
3049 TxOut { amount: Amount::ONE_SAT, script_pubkey: ScriptPubKeyBuf::new() },
3050 ],
3051 };
3052
3053 let err = decode_error_from_tx(&tx);
3054 assert!(matches!(
3055 err.0,
3056 TransactionDecoderErrorInner::OutputValueSumTooLarge(got) if got == expected
3057 ));
3058
3059 assert!(!err.to_string().is_empty());
3060 #[cfg(feature = "std")]
3061 assert!(err.source().is_none());
3062 }
3063
3064 #[test]
3065 #[cfg(feature = "alloc")]
3066 fn transaction_decoder_no_outputs_error() {
3067 let tx = Transaction {
3068 version: Version::ONE,
3069 lock_time: absolute::LockTime::ZERO,
3070 inputs: vec![TxIn {
3071 previous_output: OutPoint { txid: Txid::from_byte_array([1u8; 32]), vout: 0 },
3072 script_sig: ScriptSigBuf::new(),
3073 sequence: Sequence::MAX,
3074 witness: Witness::default(),
3075 }],
3076 outputs: vec![],
3077 };
3078
3079 let err = decode_error_from_tx(&tx);
3080 assert!(matches!(err.0, TransactionDecoderErrorInner::NoOutputs));
3081
3082 assert!(!err.to_string().is_empty());
3083 #[cfg(feature = "std")]
3084 assert!(err.source().is_none());
3085 }
3086
3087 #[test]
3088 #[cfg(feature = "alloc")]
3089 fn txin_decoder_first_error() {
3090 let mut decoder = TxIn::decoder();
3091 let mut slice = [].as_slice();
3092 assert!(decoder.push_bytes(&mut slice).unwrap().needs_more());
3093
3094 let err = decoder.end().unwrap_err();
3095 assert!(matches!(err.0, encoding::Decoder3Error::First(_)));
3096
3097 assert!(!err.to_string().is_empty());
3098 #[cfg(feature = "std")]
3099 assert!(err.source().is_some());
3100 }
3101
3102 #[test]
3103 #[cfg(feature = "alloc")]
3104 fn txin_decoder_second_error() {
3105 let mut bytes = vec![];
3106 bytes.extend_from_slice(&TC_TXID_BYTES);
3107 bytes.extend_from_slice(&TC_VOUT_BYTES);
3108 bytes.push(1); let mut decoder = TxIn::decoder();
3111 let mut slice = bytes.as_slice();
3112
3113 assert!(decoder.push_bytes(&mut slice).unwrap().needs_more());
3114
3115 let err = decoder.end().unwrap_err();
3116 assert!(matches!(err.0, encoding::Decoder3Error::Second(_)));
3117
3118 assert!(!err.to_string().is_empty());
3119 #[cfg(feature = "std")]
3120 assert!(err.source().is_some());
3121 }
3122
3123 #[test]
3124 #[cfg(feature = "alloc")]
3125 fn txin_decoder_third_error() {
3126 let mut bytes = vec![];
3127 bytes.extend_from_slice(&TC_TXID_BYTES);
3128 bytes.extend_from_slice(&TC_VOUT_BYTES);
3129 bytes.push(0); let mut decoder = TxIn::decoder();
3132 let mut slice = bytes.as_slice();
3133
3134 assert!(decoder.push_bytes(&mut slice).unwrap().needs_more());
3135
3136 let err = decoder.end().unwrap_err();
3137 assert!(matches!(err.0, encoding::Decoder3Error::Third(_)));
3138
3139 assert!(!err.to_string().is_empty());
3140 #[cfg(feature = "std")]
3141 assert!(err.source().is_some());
3142 }
3143
3144 #[test]
3145 #[cfg(feature = "alloc")]
3146 fn txout_decoder_first_error() {
3147 let mut decoder = TxOut::decoder();
3148 let mut slice = [].as_slice();
3149 assert!(decoder.push_bytes(&mut slice).unwrap().needs_more());
3150
3151 let err = decoder.end().unwrap_err();
3152 assert!(matches!(err.0, encoding::Decoder2Error::First(_)));
3153
3154 assert!(!err.to_string().is_empty());
3155 #[cfg(feature = "std")]
3156 assert!(err.source().is_some());
3157 }
3158
3159 #[test]
3160 #[cfg(feature = "alloc")]
3161 fn txout_decoder_second_error() {
3162 let mut bytes = vec![];
3163 bytes.extend_from_slice(&TC_ONE_SAT_BYTES);
3164 let mut decoder = TxOut::decoder();
3165 let mut slice = bytes.as_slice();
3166
3167 assert!(decoder.push_bytes(&mut slice).unwrap().needs_more());
3168
3169 let err = decoder.end().unwrap_err();
3170 assert!(matches!(err.0, encoding::Decoder2Error::Second(_)));
3171
3172 assert!(!err.to_string().is_empty());
3173 #[cfg(feature = "std")]
3174 assert!(err.source().is_some());
3175 }
3176
3177 #[cfg(feature = "alloc")]
3179 fn decode_error_from_bytes(bytes: &[u8]) -> TransactionDecoderError {
3180 let mut decoder = TransactionDecoder::new();
3181 let mut slice = bytes;
3182 decoder.push_bytes(&mut slice).unwrap();
3183 decoder.end().unwrap_err()
3184 }
3185
3186 #[cfg(feature = "alloc")]
3188 fn decode_error_from_tx(tx: &Transaction) -> TransactionDecoderError {
3189 let tx_bytes = encoding::encode_to_vec(tx);
3190 decode_error_from_bytes(&tx_bytes)
3191 }
3192
3193 #[test]
3194 #[cfg(feature = "hex")]
3195 fn txin() {
3196 let txin: Result<TxIn, _> = encoding::decode_from_slice(&hex!("a15d57094aa7a21a28cb20b59aab8fc7d1149a3bdbcddba9c622e4f5f6a99ece010000006c493046022100f93bb0e7d8db7bd46e40132d1f8242026e045f03a0efe71bbb8e3f475e970d790221009337cd7f1f929f00cc6ff01f03729b069a7c21b59b1736ddfee5db5946c5da8c0121033b9b137ee87d5a812d6f506efdd37f0affa7ffc310711c06c7f3e097c9447c52ffffffff"));
3197 assert!(txin.is_ok());
3198 }
3199
3200 #[test]
3201 #[cfg(feature = "hex")]
3202 fn segwit_invalid_transaction() {
3203 let tx_bytes = hex!("0000fd000001021921212121212121212121f8b372b0239cc1dff600000000004f4f4f4f4f4f4f4f000000000000000000000000000000333732343133380d000000000000000000000000000000ff000000000009000dff000000000000000800000000000000000d");
3204 let tx: Result<Transaction, _> = encoding::decode_from_slice(&tx_bytes);
3205 assert!(tx.is_err());
3206 }
3207
3208 #[test]
3209 #[cfg(feature = "hex")]
3210 fn transaction_version() {
3211 let tx_bytes = hex!("ffffffff0100000000000000000000000000000000000000000000000000000000000000000000000000ffffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000");
3212 let tx: Result<Transaction, _> = encoding::decode_from_slice(&tx_bytes);
3213 assert!(tx.is_ok());
3214 let realtx = tx.unwrap();
3215 assert_eq!(realtx.version, Version::maybe_non_standard(u32::MAX));
3216 }
3217
3218 #[test]
3219 #[cfg(feature = "hex")]
3220 fn tx_no_input_deserialization() {
3221 let tx_bytes = hex!(
3222 "010000000001000100e1f505000000001976a9140389035a9225b3839e2bbf32d826a1e222031fd888ac00000000"
3223 );
3224 let tx: Transaction = encoding::decode_from_slice(&tx_bytes).expect("deserialize tx");
3225
3226 assert_eq!(tx.inputs.len(), 0);
3227 assert_eq!(tx.outputs.len(), 1);
3228
3229 let reser = encoding::encode_to_vec(&tx);
3230 assert_eq!(&tx_bytes[..], reser.as_slice());
3231 }
3232
3233 #[test]
3234 #[cfg(feature = "hex")]
3235 fn ntxid() {
3236 let tx_bytes = hex!("0100000001a15d57094aa7a21a28cb20b59aab8fc7d1149a3bdbcddba9c622e4f5f6a99ece010000006c493046022100f93bb0e7d8db7bd46e40132d1f8242026e045f03a0efe71bbb8e3f475e970d790221009337cd7f1f929f00cc6ff01f03729b069a7c21b59b1736ddfee5db5946c5da8c0121033b9b137ee87d5a812d6f506efdd37f0affa7ffc310711c06c7f3e097c9447c52ffffffff0100e1f505000000001976a9140389035a9225b3839e2bbf32d826a1e222031fd888ac00000000");
3237 let mut tx: Transaction = encoding::decode_from_slice(&tx_bytes).unwrap();
3238
3239 let old_ntxid = tx.compute_ntxid();
3240 assert_eq!(
3241 format!("{:x}", old_ntxid),
3242 "c3573dbea28ce24425c59a189391937e00d255150fa973d59d61caf3a06b601d"
3243 );
3244 tx.inputs[0].script_sig = ScriptSigBuf::new();
3246 assert_eq!(old_ntxid, tx.compute_ntxid());
3247 tx.outputs[0].script_pubkey = ScriptPubKeyBuf::new();
3249 assert!(old_ntxid != tx.compute_ntxid());
3250 }
3251}