Skip to content

Commit 0ed9416

Browse files
Limit OnionMessenger outbound buffer size
Drop OMs if they push us over the max OnionMessenger outbound buffer size
1 parent 030955d commit 0ed9416

File tree

2 files changed

+32
-1
lines changed

2 files changed

+32
-1
lines changed

lightning/src/onion_message/functional_tests.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,3 +170,13 @@ fn reply_path() {
170170
"lightning::onion_message::messenger".to_string(),
171171
format!("Received an onion message with path_id: None and reply_path").to_string(), 2);
172172
}
173+
174+
#[test]
175+
fn peer_buffer_full() {
176+
let nodes = create_nodes(2);
177+
for _ in 0..188 {
178+
nodes[0].messenger.send_onion_message(&[], Destination::Node(nodes[1].get_node_pk()), None).unwrap();
179+
}
180+
let err = nodes[0].messenger.send_onion_message(&[], Destination::Node(nodes[1].get_node_pk()), None).unwrap_err();
181+
assert_eq!(err, SendError::PeerBufferFull);
182+
}

lightning/src/onion_message/messenger.rs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ use super::packet::{BIG_PACKET_HOP_DATA_LEN, ForwardControlTlvs, Packet, Payload
2323
use super::utils;
2424
use util::events::OnionMessageProvider;
2525
use util::logger::Logger;
26+
use util::ser::Writeable;
2627

2728
use core::ops::Deref;
2829
use sync::{Arc, Mutex};
@@ -122,6 +123,8 @@ pub enum SendError {
122123
TooFewBlindedHops,
123124
/// Our next-hop peer was offline or does not support onion message forwarding.
124125
InvalidFirstHop,
126+
/// Our next-hop peer's buffer was full.
127+
PeerBufferFull,
125128
}
126129

127130
impl<Signer: Sign, K: Deref, L: Deref> OnionMessenger<Signer, K, L>
@@ -169,6 +172,7 @@ impl<Signer: Sign, K: Deref, L: Deref> OnionMessenger<Signer, K, L>
169172
packet_payloads, packet_keys, prng_seed).map_err(|()| SendError::TooBigPacket)?;
170173

171174
let mut pending_per_peer_msgs = self.pending_messages.lock().unwrap();
175+
if outbound_buffer_full(&pending_per_peer_msgs) { return Err(SendError::PeerBufferFull) }
172176
match pending_per_peer_msgs.entry(introduction_node_id) {
173177
hash_map::Entry::Vacant(_) => Err(SendError::InvalidFirstHop),
174178
hash_map::Entry::Occupied(mut e) => {
@@ -177,7 +181,6 @@ impl<Signer: Sign, K: Deref, L: Deref> OnionMessenger<Signer, K, L>
177181
}
178182
}
179183
}
180-
181184
#[cfg(test)]
182185
pub(super) fn release_pending_msgs(&self) -> HashMap<PublicKey, VecDeque<msgs::OnionMessage>> {
183186
let mut pending_msgs = self.pending_messages.lock().unwrap();
@@ -192,6 +195,20 @@ impl<Signer: Sign, K: Deref, L: Deref> OnionMessenger<Signer, K, L>
192195
}
193196
}
194197

198+
fn outbound_buffer_full(buffer: &HashMap<PublicKey, VecDeque<msgs::OnionMessage>>) -> bool {
199+
const MAX_BUFFER_SIZE: usize = 262144; // 256KiB
200+
let mut buffered_bytes = 0;
201+
for peer_buf in buffer.values() {
202+
for om in peer_buf {
203+
buffered_bytes += om.serialized_length();
204+
if buffered_bytes >= MAX_BUFFER_SIZE {
205+
return true
206+
}
207+
}
208+
}
209+
false
210+
}
211+
195212
impl<Signer: Sign, K: Deref, L: Deref> OnionMessageHandler for OnionMessenger<Signer, K, L>
196213
where K::Target: KeysInterface<Signer = Signer>,
197214
L::Target: Logger,
@@ -256,6 +273,10 @@ impl<Signer: Sign, K: Deref, L: Deref> OnionMessageHandler for OnionMessenger<Si
256273
};
257274

258275
let mut pending_per_peer_msgs = self.pending_messages.lock().unwrap();
276+
if outbound_buffer_full(&pending_per_peer_msgs) {
277+
log_trace!(self.logger, "Dropping forwarded onion message to peer {:?}: outbound buffer full", next_node_id);
278+
return
279+
}
259280
match pending_per_peer_msgs.entry(next_node_id) {
260281
hash_map::Entry::Vacant(_) => {
261282
log_trace!(self.logger, "Dropping forwarded onion message to disconnected peer {:?}", next_node_id);

0 commit comments

Comments
 (0)