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