Skip to content

Commit 7bff121

Browse files
authored
Merge pull request #15 from 2140-dev/8-29-pref
Make `Preferences` plain data
2 parents 4f67fbe + 8d2a08f commit 7bff121

4 files changed

Lines changed: 54 additions & 90 deletions

File tree

src/handshake.rs

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::{fmt::Display, sync::Arc, time::Duration};
1+
use std::{fmt::Display, time::Duration};
22

33
use bitcoin::{FeeRate, Network};
44
use p2p::{
@@ -68,7 +68,7 @@ impl ConnectionConfig {
6868
self.network
6969
}
7070

71-
/// Request the peer gossip new addresses at the beginning of the conneciton
71+
/// Request the peer gossip new addresses at the beginning of the connection
7272
pub fn request_addr(mut self) -> Self {
7373
self.request_addr = true;
7474
self
@@ -172,10 +172,9 @@ impl ConnectionConfig {
172172
net_time_difference,
173173
reported_height: version.start_height,
174174
};
175-
let preferences = Arc::new(Preferences::default());
176175
let handshake = InitializedHandshake {
177176
feeler,
178-
their_preferences: preferences,
177+
their_preferences: Preferences::default(),
179178
send_cmpct: self.send_cmpct,
180179
fee_filter: self.fee_filter,
181180
request_addr: self.request_addr,
@@ -193,15 +192,15 @@ impl Default for ConnectionConfig {
193192
#[derive(Debug, Clone)]
194193
pub(crate) struct InitializedHandshake {
195194
feeler: FeelerData,
196-
their_preferences: Arc<Preferences>,
195+
their_preferences: Preferences,
197196
fee_filter: FeeRate,
198197
send_cmpct: SendCmpct,
199198
request_addr: bool,
200199
}
201200

202201
impl InitializedHandshake {
203202
pub(crate) fn negotiate(
204-
&self,
203+
&mut self,
205204
message: NetworkMessage,
206205
) -> Result<Option<(CompletedHandshake, Vec<NetworkMessage>)>, Error> {
207206
match message {
@@ -216,25 +215,25 @@ impl InitializedHandshake {
216215
Ok(Some((
217216
CompletedHandshake {
218217
feeler: self.feeler,
219-
their_preferences: Arc::clone(&self.their_preferences),
218+
their_preferences: self.their_preferences,
220219
},
221220
messages,
222221
)))
223222
}
224223
NetworkMessage::WtxidRelay => {
225-
self.their_preferences.prefers_wtxid();
224+
self.their_preferences.sendwtxid = true;
226225
Ok(None)
227226
}
228227
NetworkMessage::SendAddrV2 => {
229-
self.their_preferences.prefers_addrv2();
228+
self.their_preferences.sendaddrv2 = true;
230229
Ok(None)
231230
}
232231
NetworkMessage::SendCmpct(cmpct) => {
233-
self.their_preferences.prefers_cmpct(cmpct.version);
232+
self.their_preferences.sendcmpct = cmpct;
234233
Ok(None)
235234
}
236235
NetworkMessage::SendHeaders => {
237-
self.their_preferences.prefers_header_announcment();
236+
self.their_preferences.sendheaders = true;
238237
Ok(None)
239238
}
240239
e => Err(Error::IrrelevantMessage(e.command())),
@@ -245,7 +244,7 @@ impl InitializedHandshake {
245244
#[derive(Debug, Clone)]
246245
pub(crate) struct CompletedHandshake {
247246
pub(crate) feeler: FeelerData,
248-
pub(crate) their_preferences: Arc<Preferences>,
247+
pub(crate) their_preferences: Preferences,
249248
}
250249

251250
/// Errors that occur during a handshake
@@ -307,7 +306,7 @@ mod tests {
307306
let connection_config = ConnectionConfig::new();
308307
let nonce = 43;
309308
let system_time = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
310-
let (init_handshake, messages) = connection_config
309+
let (mut init_handshake, messages) = connection_config
311310
.start_handshake(system_time, NetworkMessage::Version(mock), nonce)
312311
.unwrap();
313312
let mut message_iter = messages.into_iter();
@@ -333,9 +332,9 @@ mod tests {
333332
assert!(matches!(cmpct, NetworkMessage::SendCmpct(_)));
334333
let fee_filter = message_iter.next().unwrap();
335334
assert!(matches!(fee_filter, NetworkMessage::FeeFilter(_)));
336-
assert!(completed.their_preferences.wtxid());
337-
assert!(completed.their_preferences.addrv2());
338-
assert!(!completed.their_preferences.announce_by_headers());
335+
assert!(completed.their_preferences.sendwtxid);
336+
assert!(completed.their_preferences.sendaddrv2);
337+
assert!(!completed.their_preferences.sendheaders);
339338
}
340339

341340
#[test]
@@ -382,7 +381,7 @@ mod tests {
382381
let connection_config = ConnectionConfig::new().request_addr();
383382
let nonce = 43;
384383
let system_time = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
385-
let (init_handshake, _) = connection_config
384+
let (mut init_handshake, _) = connection_config
386385
.start_handshake(system_time, NetworkMessage::Version(mock), nonce)
387386
.unwrap();
388387
let (_, messages) = init_handshake

src/lib.rs

Lines changed: 24 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,12 @@
22
#![warn(missing_docs)]
33
use std::{
44
collections::HashMap,
5-
sync::{
6-
atomic::{AtomicBool, AtomicU64, Ordering},
7-
Arc, Mutex,
8-
},
5+
sync::{Arc, Mutex},
96
time::{Duration, Instant},
107
};
118

129
use bitcoin::Network;
13-
use p2p::{ProtocolVersion, ServiceFlags};
10+
use p2p::{message_compact_blocks::SendCmpct, ProtocolVersion, ServiceFlags};
1411

1512
pub extern crate p2p;
1613

@@ -37,59 +34,30 @@ pub struct FeelerData {
3734

3835
/// The peer's preferences during this connection. These are updated automatically as the peer
3936
/// shares information.
40-
#[derive(Debug)]
37+
#[derive(Debug, Clone, Copy)]
4138
pub struct Preferences {
42-
sendheaders: AtomicBool,
43-
sendaddrv2: AtomicBool,
44-
sendcmpct: AtomicU64,
45-
sendwtxid: AtomicBool,
39+
/// Announce blocks to this peer by block header.
40+
pub sendheaders: bool,
41+
/// Send `Addrv2` addresses.
42+
pub sendaddrv2: bool,
43+
/// Compact block relay preferences.
44+
pub sendcmpct: SendCmpct,
45+
/// Advertise transactions by WTXID.
46+
pub sendwtxid: bool,
4647
}
4748

4849
impl Preferences {
4950
fn new() -> Self {
5051
Self {
51-
sendheaders: AtomicBool::new(false),
52-
sendaddrv2: AtomicBool::new(false),
53-
sendcmpct: AtomicU64::new(0),
54-
sendwtxid: AtomicBool::new(false),
52+
sendheaders: false,
53+
sendaddrv2: false,
54+
sendcmpct: SendCmpct {
55+
send_compact: false,
56+
version: 0x00,
57+
},
58+
sendwtxid: false,
5559
}
5660
}
57-
58-
fn prefers_header_announcment(&self) {
59-
self.sendheaders.store(true, Ordering::Relaxed);
60-
}
61-
62-
fn prefers_addrv2(&self) {
63-
self.sendaddrv2.store(true, Ordering::Relaxed);
64-
}
65-
66-
fn prefers_wtxid(&self) {
67-
self.sendwtxid.store(true, Ordering::Relaxed);
68-
}
69-
70-
fn prefers_cmpct(&self, version: u64) {
71-
self.sendcmpct.store(version, Ordering::Relaxed);
72-
}
73-
74-
/// The peer prefers `addrv2` messages
75-
pub fn addrv2(&self) -> bool {
76-
self.sendaddrv2.load(Ordering::Relaxed)
77-
}
78-
79-
/// The peer prefers headers are announced by a `headers` message instead of `inv`
80-
pub fn announce_by_headers(&self) -> bool {
81-
self.sendheaders.load(Ordering::Relaxed)
82-
}
83-
84-
/// The peer prefers witness transaction IDs
85-
pub fn wtxid(&self) -> bool {
86-
self.sendwtxid.load(Ordering::Relaxed)
87-
}
88-
89-
/// The reported compact block relay version
90-
pub fn cmpct_version(&self) -> u64 {
91-
self.sendcmpct.load(Ordering::Relaxed)
92-
}
9361
}
9462

9563
impl Default for Preferences {
@@ -102,7 +70,7 @@ impl Default for Preferences {
10270
#[derive(Debug, Clone)]
10371
pub struct ConnectionMetrics {
10472
feeler: FeelerData,
105-
their_preferences: Arc<Preferences>,
73+
their_preferences: Arc<Mutex<Preferences>>,
10674
timed_messages: Arc<Mutex<TimedMessages>>,
10775
start_time: Instant,
10876
outbound_ping_state: Arc<Mutex<OutboundPing>>,
@@ -114,9 +82,10 @@ impl ConnectionMetrics {
11482
&self.feeler
11583
}
11684

117-
/// Their current preferences for message exchange
118-
pub fn their_preferences(&self) -> &Preferences {
119-
self.their_preferences.as_ref()
85+
/// Their current preferences for message exchange, if not currently being mutated.
86+
pub fn their_preferences(&self) -> Option<Preferences> {
87+
let pref = self.their_preferences.lock().ok();
88+
pref.as_deref().copied()
12089
}
12190

12291
/// The message rate for a time-sensitive message
@@ -300,7 +269,7 @@ impl SeedsExt for Network {
300269
mod tests {
301270
use std::time::{Duration, Instant};
302271

303-
use crate::{MessageRate, Preferences, TimedMessage, TimedMessages};
272+
use crate::{MessageRate, TimedMessage, TimedMessages};
304273

305274
#[test]
306275
fn test_message_rate() {
@@ -316,17 +285,6 @@ mod tests {
316285
assert_eq!(rate.messages_per_secs(later).unwrap(), 2.);
317286
}
318287

319-
#[test]
320-
fn test_preferences() {
321-
let pref = Preferences::new();
322-
pref.prefers_wtxid();
323-
pref.prefers_addrv2();
324-
pref.prefers_header_announcment();
325-
assert!(pref.addrv2());
326-
assert!(pref.announce_by_headers());
327-
assert!(pref.wtxid());
328-
}
329-
330288
#[test]
331289
fn test_timed_messages() {
332290
let now = Instant::now();

src/net.rs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ impl ConnectionExt for ConnectionConfig {
9494
let mut write_half = WriteTransport::V1(self.network().default_network_magic());
9595
let mut read_half = ReadTransport::V1(self.network().default_network_magic());
9696
write_half.write_message(NetworkMessage::Version(version), &mut tcp_stream)?;
97-
let (handshake, messages) = match read_half.read_message(&mut tcp_stream)? {
97+
let (mut handshake, messages) = match read_half.read_message(&mut tcp_stream)? {
9898
Some(message) => self.start_handshake(unix_time, message, nonce)?,
9999
None => return Err(Error::MissingVersion),
100100
};
@@ -116,9 +116,10 @@ impl ConnectionExt for ConnectionConfig {
116116
feeler,
117117
their_preferences,
118118
} = completed_handshake;
119+
let arc_pref = Arc::new(Mutex::new(their_preferences));
119120
let live_connection = ConnectionMetrics {
120121
feeler,
121-
their_preferences: Arc::clone(&their_preferences),
122+
their_preferences: Arc::clone(&arc_pref),
122123
timed_messages: Arc::clone(&timed_messages),
123124
start_time: Instant::now(),
124125
outbound_ping_state: Arc::clone(&outbound_ping),
@@ -141,7 +142,7 @@ impl ConnectionExt for ConnectionConfig {
141142
let reader = ConnectionReader {
142143
tcp_stream,
143144
transport: read_half,
144-
their_preferences,
145+
their_preferences: Arc::clone(&arc_pref),
145146
timed_messages,
146147
outbound_ping_state: Arc::clone(&outbound_ping),
147148
};
@@ -276,7 +277,7 @@ impl OpenWriter {
276277
pub struct ConnectionReader {
277278
tcp_stream: TcpStream,
278279
transport: ReadTransport,
279-
their_preferences: Arc<Preferences>,
280+
their_preferences: Arc<Mutex<Preferences>>,
280281
timed_messages: Arc<Mutex<TimedMessages>>,
281282
outbound_ping_state: Arc<Mutex<OutboundPing>>,
282283
}
@@ -287,9 +288,15 @@ impl ConnectionReader {
287288
let message = self.transport.read_message(&mut self.tcp_stream)?;
288289
if let Some(message) = &message {
289290
match message {
290-
NetworkMessage::SendHeaders => self.their_preferences.prefers_header_announcment(),
291+
NetworkMessage::SendHeaders => {
292+
if let Ok(mut lock) = self.their_preferences.lock() {
293+
lock.sendheaders = true;
294+
}
295+
}
291296
NetworkMessage::SendCmpct(cmpct) => {
292-
self.their_preferences.prefers_cmpct(cmpct.version)
297+
if let Ok(mut lock) = self.their_preferences.lock() {
298+
lock.sendcmpct = *cmpct;
299+
}
293300
}
294301
NetworkMessage::Block(_) => {
295302
if let Ok(mut lock) = self.timed_messages.lock() {

tests/std.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ fn can_accept_handshake() {
6161
.connect(bind)
6262
.start();
6363
let (_, _, metadata) = wait.join().unwrap().unwrap();
64-
assert!(metadata.their_preferences().wtxid());
64+
assert!(metadata.their_preferences().unwrap().sendwtxid);
6565
}
6666

6767
#[test]

0 commit comments

Comments
 (0)