csv_adapter_bitcoin/
types.rs1use serde::{Deserialize, Serialize};
4
5#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
7pub struct BitcoinSealRef {
8 pub txid: [u8; 32],
10 pub vout: u32,
12 pub nonce: Option<u64>,
14}
15
16impl BitcoinSealRef {
17 pub fn new(txid: [u8; 32], vout: u32, nonce: Option<u64>) -> Self {
19 Self { txid, vout, nonce }
20 }
21
22 pub fn to_vec(&self) -> Vec<u8> {
24 let mut out = Vec::with_capacity(32 + 4 + 8);
25 out.extend_from_slice(&self.txid);
26 out.extend_from_slice(&self.vout.to_le_bytes());
27 if let Some(nonce) = self.nonce {
28 out.extend_from_slice(&nonce.to_le_bytes());
29 } else {
30 out.extend_from_slice(&[0u8; 8]);
31 }
32 out
33 }
34
35 pub fn txid_hex(&self) -> String {
37 hex::encode(self.txid)
38 }
39}
40
41#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
43pub struct BitcoinAnchorRef {
44 pub txid: [u8; 32],
46 pub output_index: u32,
48 pub block_height: u64,
50}
51
52impl BitcoinAnchorRef {
53 pub fn new(txid: [u8; 32], output_index: u32, block_height: u64) -> Self {
55 Self {
56 txid,
57 output_index,
58 block_height,
59 }
60 }
61}
62
63#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
65pub struct BitcoinInclusionProof {
66 pub merkle_branch: Vec<[u8; 32]>,
68 pub block_hash: [u8; 32],
70 pub tx_index: u32,
72 pub block_height: u64,
74}
75
76impl BitcoinInclusionProof {
77 pub fn new(
79 merkle_branch: Vec<[u8; 32]>,
80 block_hash: [u8; 32],
81 tx_index: u32,
82 block_height: u64,
83 ) -> Self {
84 Self {
85 merkle_branch,
86 block_hash,
87 tx_index,
88 block_height,
89 }
90 }
91
92 pub fn is_confirmed(&self, current_height: u64, required_depth: u32) -> bool {
94 self.block_height + required_depth as u64 <= current_height
95 }
96}
97
98#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
100pub struct BitcoinFinalityProof {
101 pub confirmations: u64,
103 pub meets_required_depth: bool,
105 pub required_depth: u32,
107}
108
109impl BitcoinFinalityProof {
110 pub fn new(confirmations: u64, required_depth: u32) -> Self {
112 Self {
113 confirmations,
114 meets_required_depth: confirmations >= required_depth as u64,
115 required_depth,
116 }
117 }
118}
119
120#[cfg(test)]
121mod tests {
122 use super::*;
123
124 #[test]
125 fn test_seal_ref_creation() {
126 let seal = BitcoinSealRef::new([1u8; 32], 0, Some(42));
127 assert_eq!(seal.vout, 0);
128 assert_eq!(seal.nonce, Some(42));
129 }
130
131 #[test]
132 fn test_anchor_ref_creation() {
133 let anchor = BitcoinAnchorRef::new([2u8; 32], 1, 100);
134 assert_eq!(anchor.output_index, 1);
135 assert_eq!(anchor.block_height, 100);
136 }
137
138 #[test]
139 fn test_inclusion_proof_confirmed() {
140 let proof = BitcoinInclusionProof::new(vec![], [3u8; 32], 0, 100);
141 assert!(proof.is_confirmed(106, 6));
142 assert!(!proof.is_confirmed(105, 6));
143 }
144
145 #[test]
146 fn test_finality_proof() {
147 let proof = BitcoinFinalityProof::new(6, 6);
148 assert!(proof.meets_required_depth);
149
150 let proof = BitcoinFinalityProof::new(5, 6);
151 assert!(!proof.meets_required_depth);
152 }
153}