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    /// Basic block filter bytes. `None` when this message is not a filter reply.
96    #[serde(default)]
97    pub bip158_filter: Option<Vec<u8>>,
98}
99
100/// GetBanList message - Request ban list from peer
101#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
102pub struct GetBanListMessage {
103    /// Request ID for async request-response matching
104    pub request_id: u64,
105    /// Minimum ban score threshold (optional filter)
106    pub min_score: Option<u32>,
107}
108
109/// BanEntry - Single ban list entry
110#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
111pub struct BanEntry {
112    /// IP address (IPv6 format, 16 bytes)
113    pub ip: [u8; 16],
114    /// Ban score (higher = more severe)
115    pub score: u32,
116    /// Ban reason code
117    pub reason: u8,
118    /// Timestamp when ban was added
119    pub timestamp: u64,
120    /// Optional signature (if ban list is signed)
121    pub signature: Option<Vec<u8>>,
122}
123
124/// BanList message - Response with ban list
125#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
126pub struct BanListMessage {
127    /// Request ID (echo from GetBanList for matching)
128    pub request_id: u64,
129    /// Ban entries
130    pub entries: Vec<BanEntry>,
131    /// Optional signature over entire ban list
132    pub list_signature: Option<Vec<u8>>,
133}
134
135/// GetUTXOProof message - Request Merkle proof for a specific UTXO
136#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
137pub struct GetUTXOProofMessage {
138    /// Request ID for async request-response matching
139    pub request_id: u64,
140    /// OutPoint to request proof for (transaction hash + output index)
141    pub tx_hash: Hash,
142    pub output_index: u32,
143    /// Block height/hash for which to request proof (must match commitment)
144    pub block_height: u64,
145    pub block_hash: Hash,
146}
147
148/// UTXOProof message - Response with Merkle proof for a UTXO
149#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
150pub struct UTXOProofMessage {
151    /// Request ID (echo from GetUTXOProof for matching)
152    pub request_id: u64,
153    /// The transaction hash this proof is for
154    pub tx_hash: Hash,
155    /// The output index this proof is for
156    pub output_index: u32,
157    /// The UTXO data (for verification)
158    pub value: i64,
159    pub script_pubkey: Vec<u8>,
160    pub height: u64,
161    pub is_coinbase: bool,
162    /// The Merkle proof (serialized as bytes)
163    pub proof: Vec<u8>,
164}