Skip to content

Commit 43db395

Browse files
committed
Fail channel for batched commitment_signed appropriately
If a message in a commitment_signed batch does not contain a funding_txid or has duplicates, the channel should be failed. Move this check from PeerManager to FundedChannel such that this can be done.
1 parent d4bbd42 commit 43db395

File tree

6 files changed

+37
-52
lines changed

6 files changed

+37
-52
lines changed

lightning-net-tokio/src/lib.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -622,7 +622,7 @@ impl Hash for SocketDescriptor {
622622
mod tests {
623623
use bitcoin::constants::ChainHash;
624624
use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey};
625-
use bitcoin::{Network, Txid};
625+
use bitcoin::Network;
626626
use lightning::ln::msgs::*;
627627
use lightning::ln::peer_handler::{IgnoringMessageHandler, MessageHandler, PeerManager};
628628
use lightning::ln::types::ChannelId;
@@ -632,7 +632,6 @@ mod tests {
632632

633633
use tokio::sync::mpsc;
634634

635-
use std::collections::BTreeMap;
636635
use std::mem;
637636
use std::sync::atomic::{AtomicBool, Ordering};
638637
use std::sync::{Arc, Mutex};
@@ -726,8 +725,7 @@ mod tests {
726725
}
727726
fn handle_commitment_signed(&self, _their_node_id: PublicKey, _msg: &CommitmentSigned) {}
728727
fn handle_commitment_signed_batch(
729-
&self, _their_node_id: PublicKey, _channel_id: ChannelId,
730-
_batch: BTreeMap<Txid, CommitmentSigned>,
728+
&self, _their_node_id: PublicKey, _channel_id: ChannelId, _batch: Vec<CommitmentSigned>,
731729
) {
732730
}
733731
fn handle_revoke_and_ack(&self, _their_node_id: PublicKey, _msg: &RevokeAndACK) {}

lightning/src/ln/channel.rs

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ use crate::util::errors::APIError;
6868
use crate::util::config::{UserConfig, ChannelConfig, LegacyChannelConfig, ChannelHandshakeConfig, ChannelHandshakeLimits, MaxDustHTLCExposure};
6969
use crate::util::scid_utils::scid_from_parts;
7070

71-
use alloc::collections::BTreeMap;
71+
use alloc::collections::{btree_map, BTreeMap};
7272

7373
use crate::io;
7474
use crate::prelude::*;
@@ -5987,18 +5987,35 @@ impl<SP: Deref> FundedChannel<SP> where
59875987
self.commitment_signed_update_monitor(updates, logger)
59885988
}
59895989

5990-
pub fn commitment_signed_batch<L: Deref>(&mut self, batch: &BTreeMap<Txid, msgs::CommitmentSigned>, logger: &L) -> Result<Option<ChannelMonitorUpdate>, ChannelError>
5990+
pub fn commitment_signed_batch<L: Deref>(&mut self, batch: Vec<msgs::CommitmentSigned>, logger: &L) -> Result<Option<ChannelMonitorUpdate>, ChannelError>
59915991
where L::Target: Logger
59925992
{
59935993
self.commitment_signed_check_state()?;
59945994

5995+
let mut messages = BTreeMap::new();
5996+
for msg in batch {
5997+
let funding_txid = match msg.funding_txid {
5998+
Some(funding_txid) => funding_txid,
5999+
None => {
6000+
return Err(ChannelError::close("Peer sent batched commitment_signed without a funding_txid".to_string()));
6001+
},
6002+
};
6003+
6004+
match messages.entry(funding_txid) {
6005+
btree_map::Entry::Vacant(entry) => { entry.insert(msg); },
6006+
btree_map::Entry::Occupied(_) => {
6007+
return Err(ChannelError::close(format!("Peer sent batched commitment_signed with duplicate funding_txid {}", funding_txid)));
6008+
}
6009+
}
6010+
}
6011+
59956012
// Any commitment_signed not associated with a FundingScope is ignored below if a
59966013
// pending splice transaction has confirmed since receiving the batch.
59976014
let updates = core::iter::once(&self.funding)
59986015
.chain(self.pending_funding.iter())
59996016
.map(|funding| {
60006017
let funding_txid = funding.get_funding_txo().unwrap().txid;
6001-
let msg = batch
6018+
let msg = messages
60026019
.get(&funding_txid)
60036020
.ok_or_else(|| ChannelError::close(format!("Peer did not send a commitment_signed for pending splice transaction: {}", funding_txid)))?;
60046021
self.context

lightning/src/ln/channelmanager.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9263,7 +9263,7 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
92639263
}
92649264

92659265
#[rustfmt::skip]
9266-
fn internal_commitment_signed_batch(&self, counterparty_node_id: &PublicKey, channel_id: ChannelId, batch: &BTreeMap<Txid, msgs::CommitmentSigned>) -> Result<(), MsgHandleErrInternal> {
9266+
fn internal_commitment_signed_batch(&self, counterparty_node_id: &PublicKey, channel_id: ChannelId, batch: Vec<msgs::CommitmentSigned>) -> Result<(), MsgHandleErrInternal> {
92679267
let per_peer_state = self.per_peer_state.read().unwrap();
92689268
let peer_state_mutex = per_peer_state.get(counterparty_node_id)
92699269
.ok_or_else(|| {
@@ -12330,9 +12330,9 @@ where
1233012330
}
1233112331

1233212332
#[rustfmt::skip]
12333-
fn handle_commitment_signed_batch(&self, counterparty_node_id: PublicKey, channel_id: ChannelId, batch: BTreeMap<Txid, msgs::CommitmentSigned>) {
12333+
fn handle_commitment_signed_batch(&self, counterparty_node_id: PublicKey, channel_id: ChannelId, batch: Vec<msgs::CommitmentSigned>) {
1233412334
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(self);
12335-
let _ = handle_error!(self, self.internal_commitment_signed_batch(&counterparty_node_id, channel_id, &batch), counterparty_node_id);
12335+
let _ = handle_error!(self, self.internal_commitment_signed_batch(&counterparty_node_id, channel_id, batch), counterparty_node_id);
1233612336
}
1233712337

1233812338
#[rustfmt::skip]

lightning/src/ln/msgs.rs

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,6 @@ use crate::types::payment::{PaymentHash, PaymentPreimage, PaymentSecret};
4747
#[allow(unused_imports)]
4848
use crate::prelude::*;
4949

50-
use alloc::collections::BTreeMap;
51-
5250
use crate::io::{self, Cursor, Read};
5351
use crate::io_extras::read_to_end;
5452
use core::fmt;
@@ -1967,8 +1965,7 @@ pub trait ChannelMessageHandler: BaseMessageHandler {
19671965
fn handle_commitment_signed(&self, their_node_id: PublicKey, msg: &CommitmentSigned);
19681966
/// Handle a batch of incoming `commitment_signed` message from the given peer.
19691967
fn handle_commitment_signed_batch(
1970-
&self, their_node_id: PublicKey, channel_id: ChannelId,
1971-
batch: BTreeMap<Txid, CommitmentSigned>,
1968+
&self, their_node_id: PublicKey, channel_id: ChannelId, batch: Vec<CommitmentSigned>,
19721969
);
19731970
/// Handle an incoming `revoke_and_ack` message from the given peer.
19741971
fn handle_revoke_and_ack(&self, their_node_id: PublicKey, msg: &RevokeAndACK);
@@ -1982,15 +1979,7 @@ pub trait ChannelMessageHandler: BaseMessageHandler {
19821979
self.handle_commitment_signed(their_node_id, &batch[0]);
19831980
} else {
19841981
let channel_id = batch[0].channel_id;
1985-
let batch: BTreeMap<Txid, CommitmentSigned> = batch
1986-
.iter()
1987-
.cloned()
1988-
.map(|cs| {
1989-
let funding_txid = cs.funding_txid.unwrap();
1990-
(funding_txid, cs)
1991-
})
1992-
.collect();
1993-
self.handle_commitment_signed_batch(their_node_id, channel_id, batch);
1982+
self.handle_commitment_signed_batch(their_node_id, channel_id, batch.clone());
19941983
}
19951984
}
19961985

lightning/src/ln/peer_handler.rs

Lines changed: 9 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
//! call into the provided message handlers (probably a ChannelManager and P2PGossipSync) with
1818
//! messages they should handle, and encoding/sending response messages.
1919
20-
use bitcoin::Txid;
2120
use bitcoin::constants::ChainHash;
2221
use bitcoin::secp256k1::{self, Secp256k1, SecretKey, PublicKey};
2322

@@ -44,8 +43,6 @@ use crate::util::string::PrintableString;
4443
#[allow(unused_imports)]
4544
use crate::prelude::*;
4645

47-
use alloc::collections::{btree_map, BTreeMap};
48-
4946
use crate::io;
5047
use crate::sync::{Mutex, MutexGuard, FairRwLock};
5148
use core::sync::atomic::{AtomicBool, AtomicU32, AtomicI32, Ordering};
@@ -337,8 +334,7 @@ impl ChannelMessageHandler for ErroringMessageHandler {
337334
ErroringMessageHandler::push_error(self, their_node_id, msg.channel_id);
338335
}
339336
fn handle_commitment_signed_batch(
340-
&self, their_node_id: PublicKey, channel_id: ChannelId,
341-
_batch: BTreeMap<Txid, msgs::CommitmentSigned>,
337+
&self, their_node_id: PublicKey, channel_id: ChannelId, _batch: Vec<msgs::CommitmentSigned>,
342338
) {
343339
ErroringMessageHandler::push_error(self, their_node_id, channel_id);
344340
}
@@ -553,8 +549,8 @@ struct MessageBatch {
553549

554550
/// The representation of the message batch, which may different for each message type.
555551
enum MessageBatchImpl {
556-
/// A batch of `commitment_signed` messages, where each has a unique `funding_txid`.
557-
CommitmentSigned(BTreeMap<Txid, msgs::CommitmentSigned>),
552+
/// A batch of `commitment_signed` messages used when there are pending splices.
553+
CommitmentSigned(Vec<msgs::CommitmentSigned>),
558554
}
559555

560556
/// The ratio between buffer sizes at which we stop sending initial sync messages vs when we stop
@@ -891,7 +887,7 @@ pub struct PeerManager<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: D
891887

892888
enum LogicalMessage<T: core::fmt::Debug + wire::Type + wire::TestEq> {
893889
FromWire(wire::Message<T>),
894-
CommitmentSignedBatch(ChannelId, BTreeMap<Txid, msgs::CommitmentSigned>),
890+
CommitmentSignedBatch(ChannelId, Vec<msgs::CommitmentSigned>),
895891
}
896892

897893
enum MessageHandlingError {
@@ -1838,7 +1834,8 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
18381834

18391835
let messages = match msg.message_type {
18401836
Some(message_type) if message_type == msgs::CommitmentSigned::TYPE => {
1841-
MessageBatchImpl::CommitmentSigned(BTreeMap::new())
1837+
let messages = Vec::with_capacity(batch_size);
1838+
MessageBatchImpl::CommitmentSigned(messages)
18421839
},
18431840
_ => {
18441841
let error = format!("Peer {} sent start_batch for channel {} without a known message type", log_pubkey!(their_node_id), &msg.channel_id);
@@ -1867,7 +1864,7 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
18671864

18681865
if let wire::Message::CommitmentSigned(msg) = message {
18691866
if let Some(message_batch) = &mut peer_lock.message_batch {
1870-
let MessageBatchImpl::CommitmentSigned(ref mut buffer) = &mut message_batch.messages;
1867+
let MessageBatchImpl::CommitmentSigned(ref mut messages) = &mut message_batch.messages;
18711868

18721869
if msg.channel_id != message_batch.channel_id {
18731870
let error = format!("Peer {} sent batched commitment_signed for the wrong channel (expected: {}, actual: {})", log_pubkey!(their_node_id), message_batch.channel_id, &msg.channel_id);
@@ -1883,23 +1880,9 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
18831880
}.into());
18841881
}
18851882

1886-
let funding_txid = match msg.funding_txid {
1887-
Some(funding_txid) => funding_txid,
1888-
None => {
1889-
log_debug!(logger, "Peer {} sent batched commitment_signed without a funding_txid for channel {}", log_pubkey!(their_node_id), message_batch.channel_id);
1890-
return Err(PeerHandleError { }.into());
1891-
},
1892-
};
1893-
1894-
match buffer.entry(funding_txid) {
1895-
btree_map::Entry::Vacant(entry) => { entry.insert(msg); },
1896-
btree_map::Entry::Occupied(_) => {
1897-
log_debug!(logger, "Peer {} sent batched commitment_signed with duplicate funding_txid {} for channel {}", log_pubkey!(their_node_id), funding_txid, message_batch.channel_id);
1898-
return Err(PeerHandleError { }.into());
1899-
}
1900-
}
1883+
messages.push(msg);
19011884

1902-
if buffer.len() == message_batch.batch_size {
1885+
if messages.len() == message_batch.batch_size {
19031886
let MessageBatch { channel_id, batch_size: _, messages } = peer_lock.message_batch.take().expect("batch should have been inserted");
19041887
let MessageBatchImpl::CommitmentSigned(batch) = messages;
19051888

lightning/src/util/test_utils.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,6 @@ use bitcoin::secp256k1::{self, PublicKey, Scalar, Secp256k1, SecretKey};
7979

8080
use lightning_invoice::RawBolt11Invoice;
8181

82-
use alloc::collections::BTreeMap;
83-
8482
use crate::io;
8583
use crate::prelude::*;
8684
use crate::sign::{EntropySource, NodeSigner, RandomBytes, Recipient, SignerProvider};
@@ -1057,7 +1055,7 @@ impl msgs::ChannelMessageHandler for TestChannelMessageHandler {
10571055
}
10581056
fn handle_commitment_signed_batch(
10591057
&self, _their_node_id: PublicKey, _channel_id: ChannelId,
1060-
_batch: BTreeMap<Txid, msgs::CommitmentSigned>,
1058+
_batch: Vec<msgs::CommitmentSigned>,
10611059
) {
10621060
unreachable!()
10631061
}

0 commit comments

Comments
 (0)