Skip to content

Commit 69e532d

Browse files
committed
om mailbox peer limit and test
1 parent b85b05e commit 69e532d

3 files changed

Lines changed: 80 additions & 17 deletions

File tree

src/event.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
use crate::om_mailbox::OnionMessageMailbox;
99
use crate::payment::asynchronous::static_invoice_store::StaticInvoiceStore;
10-
use crate::types::{CustomTlvRecord, DynStore, PaymentStore, Sweeper, Wallet};
10+
use crate::types::{CustomTlvRecord, DynStore, OnionMessenger, PaymentStore, Sweeper, Wallet};
1111
use crate::{
1212
hex_utils, BumpTransactionEventHandler, ChannelManager, Error, Graph, PeerInfo, PeerStore,
1313
UserChannelId,
@@ -460,6 +460,7 @@ where
460460
logger: L,
461461
config: Arc<Config>,
462462
static_invoice_store: Option<StaticInvoiceStore>,
463+
onion_messenger: Arc<OnionMessenger>,
463464
om_mailbox: OnionMessageMailbox,
464465
}
465466

@@ -474,8 +475,8 @@ where
474475
output_sweeper: Arc<Sweeper>, network_graph: Arc<Graph>,
475476
liquidity_source: Option<Arc<LiquiditySource<Arc<Logger>>>>,
476477
payment_store: Arc<PaymentStore>, peer_store: Arc<PeerStore<L>>,
477-
static_invoice_store: Option<StaticInvoiceStore>, om_mailbox: OnionMessageMailbox,
478-
runtime: Arc<Runtime>, logger: L, config: Arc<Config>,
478+
static_invoice_store: Option<StaticInvoiceStore>, onion_messenger: Arc<OnionMessenger>,
479+
om_mailbox: OnionMessageMailbox, runtime: Arc<Runtime>, logger: L, config: Arc<Config>,
479480
) -> Self {
480481
Self {
481482
event_queue,
@@ -492,6 +493,7 @@ where
492493
runtime,
493494
config,
494495
static_invoice_store,
496+
onion_messenger,
495497
om_mailbox,
496498
}
497499
}
@@ -1498,7 +1500,11 @@ where
14981500
self.om_mailbox.onion_message_intercepted(peer_node_id, message);
14991501
},
15001502
LdkEvent::OnionMessagePeerConnected { peer_node_id } => {
1501-
self.om_mailbox.onion_message_peer_connected(peer_node_id);
1503+
let messages = self.om_mailbox.onion_message_peer_connected(peer_node_id);
1504+
1505+
for message in messages {
1506+
let _ = self.onion_messenger.forward_onion_message(message, &peer_node_id);
1507+
}
15021508
},
15031509

15041510
LdkEvent::PersistStaticInvoice {

src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -507,7 +507,7 @@ impl Node {
507507
} else {
508508
None
509509
};
510-
let om_mailbox = OnionMessageMailbox::new(Arc::clone(&self.onion_messenger));
510+
let om_mailbox = OnionMessageMailbox::new();
511511

512512
let event_handler = Arc::new(EventHandler::new(
513513
Arc::clone(&self.event_queue),
@@ -521,6 +521,7 @@ impl Node {
521521
Arc::clone(&self.payment_store),
522522
Arc::clone(&self.peer_store),
523523
static_invoice_store,
524+
Arc::clone(&self.onion_messenger),
524525
om_mailbox,
525526
Arc::clone(&self.runtime),
526527
Arc::clone(&self.logger),

src/om_mailbox.rs

Lines changed: 68 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
use std::{
22
collections::{hash_map::Entry, HashMap, VecDeque},
3-
sync::{Arc, Mutex},
3+
sync::Mutex,
44
};
55

6-
use crate::types::OnionMessenger;
6+
use lightning::ln::msgs::OnionMessage;
77

88
pub(crate) struct OnionMessageMailbox {
99
map: Mutex<HashMap<bitcoin::secp256k1::PublicKey, VecDeque<lightning::ln::msgs::OnionMessage>>>,
10-
onion_messenger: Arc<OnionMessenger>,
1110
}
1211

1312
impl OnionMessageMailbox {
1413
const MAX_MESSAGES_PER_PEER: usize = 100;
14+
const MAX_PEERS: usize = 100;
1515

16-
pub fn new(onion_messenger: Arc<OnionMessenger>) -> Self {
17-
Self { map: Mutex::new(HashMap::new()), onion_messenger }
16+
pub fn new() -> Self {
17+
Self { map: Mutex::new(HashMap::new()) }
1818
}
1919

2020
pub(crate) fn onion_message_intercepted(
@@ -28,18 +28,74 @@ impl OnionMessageMailbox {
2828
queue.pop_front();
2929
}
3030
queue.push_back(message);
31+
32+
// Enforce a peers limit. If exceeded, evict the peer with the longest queue.
33+
if map.len() > Self::MAX_PEERS {
34+
let peer_to_remove = map
35+
.iter()
36+
.max_by_key(|(_, queue)| queue.len())
37+
.map(|(peer, _)| peer.clone())
38+
.unwrap();
39+
40+
map.remove(&peer_to_remove);
41+
}
3142
}
3243

33-
pub(crate) fn onion_message_peer_connected(&self, peer_node_id: bitcoin::secp256k1::PublicKey) {
44+
pub(crate) fn onion_message_peer_connected(
45+
&self, peer_node_id: bitcoin::secp256k1::PublicKey,
46+
) -> Vec<OnionMessage> {
3447
let mut map = self.map.lock().unwrap();
3548

36-
let queue = match map.entry(peer_node_id) {
37-
Entry::Occupied(entry) => entry.into_mut(),
38-
Entry::Vacant(_) => return,
49+
match map.entry(peer_node_id) {
50+
Entry::Occupied(mut entry) => {
51+
let queue = std::mem::take(entry.get_mut());
52+
queue.into()
53+
},
54+
Entry::Vacant(_) => Vec::new(),
55+
}
56+
}
57+
}
58+
59+
mod tests {
60+
use bitcoin::{
61+
key::Secp256k1,
62+
secp256k1::{PublicKey, SecretKey},
63+
};
64+
use lightning::onion_message;
65+
66+
use crate::om_mailbox::OnionMessageMailbox;
67+
68+
#[test]
69+
fn onion_message_mailbox() {
70+
let mailbox = OnionMessageMailbox::new();
71+
72+
let secp = Secp256k1::new();
73+
let sk_bytes = [12; 32];
74+
let sk = SecretKey::from_slice(&sk_bytes).unwrap();
75+
let peer_node_id = PublicKey::from_secret_key(&secp, &sk);
76+
77+
let blinding_sk = SecretKey::from_slice(&[13; 32]).unwrap();
78+
let blinding_point = PublicKey::from_secret_key(&secp, &blinding_sk);
79+
80+
let message_sk = SecretKey::from_slice(&[13; 32]).unwrap();
81+
let message_point = PublicKey::from_secret_key(&secp, &message_sk);
82+
83+
let message = lightning::ln::msgs::OnionMessage {
84+
blinding_point,
85+
onion_routing_packet: onion_message::packet::Packet {
86+
version: 0,
87+
public_key: message_point,
88+
hop_data: vec![1, 2, 3],
89+
hmac: [0; 32],
90+
},
3991
};
92+
mailbox.onion_message_intercepted(peer_node_id, message.clone());
4093

41-
while let Some(message) = queue.pop_front() {
42-
let _ = self.onion_messenger.forward_onion_message(message, &peer_node_id);
43-
}
94+
let messages = mailbox.onion_message_peer_connected(peer_node_id);
95+
assert_eq!(messages.len(), 1);
96+
assert_eq!(messages[0], message);
97+
98+
let messages = mailbox.onion_message_peer_connected(peer_node_id);
99+
assert_eq!(messages.len(), 0);
44100
}
45101
}

0 commit comments

Comments
 (0)