Skip to main content

blvm_protocol/
commons.rs

1//! Commons-specific protocol extensions
2//!
3//! This module defines protocol messages specific to Bitcoin Commons,
4//! including UTXO commitments, filtered blocks, and ban list sharing.
5
6use crate::{BlockHeader, Hash, Transaction};
7use serde::{Deserialize, Serialize};
8
9/// GetUTXOSet message - Request UTXO set at specific height
10#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
11pub struct GetUTXOSetMessage {
12    /// Block height for which to request UTXO set
13    pub height: u64,
14    /// Block hash at requested height (for verification)
15    pub block_hash: Hash,
16}
17
18/// UTXO commitment structure
19#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
20pub struct UTXOCommitment {
21    pub merkle_root: Hash,
22    pub total_supply: u64,
23    pub utxo_count: u64,
24    pub block_height: u64,
25    pub block_hash: Hash,
26}
27
28/// UTXOSet message - Response with UTXO set commitment
29#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
30pub struct UTXOSetMessage {
31    /// Request ID (echo from GetUTXOSet for matching)
32    pub request_id: u64,
33    /// UTXO commitment (Merkle root, supply, count, etc.)
34    pub commitment: UTXOCommitment,
35    /// UTXO set size hint (for chunking)
36    pub utxo_count: u64,
37    /// Indicates if this is a complete set or partial chunk
38    pub is_complete: bool,
39    /// Chunk identifier if partial
40    pub chunk_id: Option<u32>,
41}
42
43/// FilterPreferences - Configure spam filtering
44#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
45pub struct FilterPreferences {
46    /// Filter Ordinals/Inscriptions
47    pub filter_ordinals: bool,
48    /// Filter dust outputs (default: < 546 satoshis)
49    pub filter_dust: bool,
50    /// Filter BRC-20 patterns
51    pub filter_brc20: bool,
52    /// Minimum output value to include (satoshis)
53    pub min_output_value: u64,
54}
55
56/// SpamSummary - Summary of filtered spam
57#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
58pub struct SpamSummary {
59    /// Number of filtered transactions
60    pub filtered_count: u32,
61    /// Total filtered value (satoshis)
62    pub filtered_value: u64,
63    /// Filter reasons (bitfield)
64    pub filter_reasons: u32,
65}
66
67/// GetFilteredBlock message - Request filtered block (spam-filtered)
68#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
69pub struct GetFilteredBlockMessage {
70    /// Request ID for async request-response matching
71    pub request_id: u64,
72    /// Block hash to request
73    pub block_hash: Hash,
74    /// Filter preferences (what spam types to filter)
75    pub filter_preferences: FilterPreferences,
76    /// Request BIP158 compact block filter in response (optional)
77    pub include_bip158_filter: bool,
78}
79
80/// FilteredBlock message - Response with filtered transactions
81#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
82pub struct FilteredBlockMessage {
83    /// Request ID (echo from GetFilteredBlock for matching)
84    pub request_id: u64,
85    /// Block header
86    pub header: BlockHeader,
87    /// UTXO commitment for this block
88    pub commitment: UTXOCommitment,
89    /// Filtered transactions (only non-spam)
90    pub transactions: Vec<Transaction>,
91    /// Transaction indices in original block (for verification)
92    pub transaction_indices: Vec<u32>,
93    /// Summary of filtered spam
94    pub spam_summary: SpamSummary,
95}
96
97/// GetBanList message - Request ban list from peer
98#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
99pub struct GetBanListMessage {
100    /// Request ID for async request-response matching
101    pub request_id: u64,
102    /// Minimum ban score threshold (optional filter)
103    pub min_score: Option<u32>,
104}
105
106/// BanEntry - Single ban list entry
107#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
108pub struct BanEntry {
109    /// IP address (IPv6 format, 16 bytes)
110    pub ip: [u8; 16],
111    /// Ban score (higher = more severe)
112    pub score: u32,
113    /// Ban reason code
114    pub reason: u8,
115    /// Timestamp when ban was added
116    pub timestamp: u64,
117    /// Optional signature (if ban list is signed)
118    pub signature: Option<Vec<u8>>,
119}
120
121/// BanList message - Response with ban list
122#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
123pub struct BanListMessage {
124    /// Request ID (echo from GetBanList for matching)
125    pub request_id: u64,
126    /// Ban entries
127    pub entries: Vec<BanEntry>,
128    /// Optional signature over entire ban list
129    pub list_signature: Option<Vec<u8>>,
130}
131
132/// GetUTXOProof message - Request Merkle proof for a specific UTXO
133#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
134pub struct GetUTXOProofMessage {
135    /// Request ID for async request-response matching
136    pub request_id: u64,
137    /// OutPoint to request proof for (transaction hash + output index)
138    pub tx_hash: Hash,
139    pub output_index: u32,
140    /// Block height/hash for which to request proof (must match commitment)
141    pub block_height: u64,
142    pub block_hash: Hash,
143}
144
145/// UTXOProof message - Response with Merkle proof for a UTXO
146#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
147pub struct UTXOProofMessage {
148    /// Request ID (echo from GetUTXOProof for matching)
149    pub request_id: u64,
150    /// The transaction hash this proof is for
151    pub tx_hash: Hash,
152    /// The output index this proof is for
153    pub output_index: u32,
154    /// The UTXO data (for verification)
155    pub value: i64,
156    pub script_pubkey: Vec<u8>,
157    pub height: u64,
158    pub is_coinbase: bool,
159    /// The Merkle proof (serialized as bytes)
160    pub proof: Vec<u8>,
161}