cashweb_bitcoin/transaction/
input.rs1use bytes::{Buf, BufMut};
5use thiserror::Error;
6
7use super::{
8 outpoint::{DecodeError as OutpointDecodeError, Outpoint},
9 script::Script,
10};
11use crate::{
12 var_int::{DecodeError as VarIntDecodeError, VarInt},
13 Decodable, Encodable,
14};
15
16#[derive(Clone, Debug, PartialEq, Eq, Error)]
18pub enum DecodeError {
19 #[error("outpoint: {0}")]
21 Outpoint(OutpointDecodeError),
22 #[error("script length: {0}")]
24 ScriptLen(VarIntDecodeError),
25 #[error("script too short")]
27 ScriptTooShort,
28 #[error("sequence number too short")]
30 SequenceTooShort,
31}
32
33#[derive(Clone, Debug, Default, PartialEq, Eq)]
35#[allow(missing_docs)]
36pub struct Input {
37 pub outpoint: Outpoint,
38 pub script: Script,
39 pub sequence: u32,
40}
41
42impl Encodable for Input {
43 #[inline]
44 fn encoded_len(&self) -> usize {
45 self.outpoint.encoded_len()
46 + self.script.len_varint().encoded_len()
47 + self.script.encoded_len()
48 + 4
49 }
50
51 #[inline]
52 fn encode_raw<B: BufMut>(&self, buf: &mut B) {
53 self.outpoint.encode_raw(buf);
54 self.script.len_varint().encode_raw(buf);
55 self.script.encode_raw(buf);
56 buf.put_u32_le(self.sequence);
57 }
58}
59
60impl Decodable for Input {
61 type Error = DecodeError;
62
63 #[inline]
64 fn decode<B: Buf>(mut buf: &mut B) -> Result<Self, Self::Error> {
65 let outpoint = Outpoint::decode(&mut buf).map_err(Self::Error::Outpoint)?;
67
68 let script_len: u64 = VarInt::decode(&mut buf)
70 .map_err(Self::Error::ScriptLen)?
71 .into();
72 let script_len = script_len as usize;
73 if buf.remaining() < script_len {
74 return Err(Self::Error::ScriptTooShort);
75 }
76 let mut raw_script = vec![0; script_len];
77 buf.copy_to_slice(&mut raw_script);
78 let script = raw_script.into();
79
80 if buf.remaining() < 4 {
82 return Err(Self::Error::SequenceTooShort);
83 }
84 let sequence = buf.get_u32_le();
85
86 Ok(Input {
87 outpoint,
88 script,
89 sequence,
90 })
91 }
92}