Skip to content

Commit f373238

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 b7d1e3c commit f373238

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
@@ -66,7 +66,7 @@ use crate::util::errors::APIError;
6666
use crate::util::config::{UserConfig, ChannelConfig, LegacyChannelConfig, ChannelHandshakeConfig, ChannelHandshakeLimits, MaxDustHTLCExposure};
6767
use crate::util::scid_utils::scid_from_parts;
6868

69-
use alloc::collections::BTreeMap;
69+
use alloc::collections::{btree_map, BTreeMap};
7070

7171
use crate::io;
7272
use crate::prelude::*;
@@ -5950,18 +5950,35 @@ impl<SP: Deref> FundedChannel<SP> where
59505950
self.commitment_signed_update_monitor(updates, logger)
59515951
}
59525952

5953-
pub fn commitment_signed_batch<L: Deref>(&mut self, batch: &BTreeMap<Txid, msgs::CommitmentSigned>, logger: &L) -> Result<Option<ChannelMonitorUpdate>, ChannelError>
5953+
pub fn commitment_signed_batch<L: Deref>(&mut self, batch: Vec<msgs::CommitmentSigned>, logger: &L) -> Result<Option<ChannelMonitorUpdate>, ChannelError>
59545954
where L::Target: Logger
59555955
{
59565956
self.commitment_signed_check_state()?;
59575957

5958+
let mut messages = BTreeMap::new();
5959+
for msg in batch {
5960+
let funding_txid = match msg.funding_txid {
5961+
Some(funding_txid) => funding_txid,
5962+
None => {
5963+
return Err(ChannelError::close("Peer sent batched commitment_signed without a funding_txid".to_string()));
5964+
},
5965+
};
5966+
5967+
match messages.entry(funding_txid) {
5968+
btree_map::Entry::Vacant(entry) => { entry.insert(msg); },
5969+
btree_map::Entry::Occupied(_) => {
5970+
return Err(ChannelError::close(format!("Peer sent batched commitment_signed with duplicate funding_txid {}", funding_txid)));
5971+
}
5972+
}
5973+
}
5974+
59585975
// Any commitment_signed not associated with a FundingScope is ignored below if a
59595976
// pending splice transaction has confirmed since receiving the batch.
59605977
let updates = core::iter::once(&self.funding)
59615978
.chain(self.pending_funding.iter())
59625979
.map(|funding| {
59635980
let funding_txid = funding.get_funding_txo().unwrap().txid;
5964-
let msg = batch
5981+
let msg = messages
59655982
.get(&funding_txid)
59665983
.ok_or_else(|| ChannelError::close(format!("Peer did not send a commitment_signed for pending splice transaction: {}", funding_txid)))?;
59675984
self.context

lightning/src/ln/channelmanager.rs

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

9046-
fn internal_commitment_signed_batch(&self, counterparty_node_id: &PublicKey, channel_id: ChannelId, batch: &BTreeMap<Txid, msgs::CommitmentSigned>) -> Result<(), MsgHandleErrInternal> {
9046+
fn internal_commitment_signed_batch(&self, counterparty_node_id: &PublicKey, channel_id: ChannelId, batch: Vec<msgs::CommitmentSigned>) -> Result<(), MsgHandleErrInternal> {
90479047
let per_peer_state = self.per_peer_state.read().unwrap();
90489048
let peer_state_mutex = per_peer_state.get(counterparty_node_id)
90499049
.ok_or_else(|| {
@@ -12195,9 +12195,9 @@ where
1219512195
let _ = handle_error!(self, self.internal_commitment_signed(&counterparty_node_id, msg), counterparty_node_id);
1219612196
}
1219712197

12198-
fn handle_commitment_signed_batch(&self, counterparty_node_id: PublicKey, channel_id: ChannelId, batch: BTreeMap<Txid, msgs::CommitmentSigned>) {
12198+
fn handle_commitment_signed_batch(&self, counterparty_node_id: PublicKey, channel_id: ChannelId, batch: Vec<msgs::CommitmentSigned>) {
1219912199
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(self);
12200-
let _ = handle_error!(self, self.internal_commitment_signed_batch(&counterparty_node_id, channel_id, &batch), counterparty_node_id);
12200+
let _ = handle_error!(self, self.internal_commitment_signed_batch(&counterparty_node_id, channel_id, batch), counterparty_node_id);
1220112201
}
1220212202

1220312203
fn handle_revoke_and_ack(&self, counterparty_node_id: PublicKey, msg: &msgs::RevokeAndACK) {

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;
@@ -1952,8 +1950,7 @@ pub trait ChannelMessageHandler: BaseMessageHandler {
19521950
fn handle_commitment_signed(&self, their_node_id: PublicKey, msg: &CommitmentSigned);
19531951
/// Handle a batch of incoming `commitment_signed` message from the given peer.
19541952
fn handle_commitment_signed_batch(
1955-
&self, their_node_id: PublicKey, channel_id: ChannelId,
1956-
batch: BTreeMap<Txid, CommitmentSigned>,
1953+
&self, their_node_id: PublicKey, channel_id: ChannelId, batch: Vec<CommitmentSigned>,
19571954
);
19581955
/// Handle an incoming `revoke_and_ack` message from the given peer.
19591956
fn handle_revoke_and_ack(&self, their_node_id: PublicKey, msg: &RevokeAndACK);
@@ -1967,15 +1964,7 @@ pub trait ChannelMessageHandler: BaseMessageHandler {
19671964
self.handle_commitment_signed(their_node_id, &batch[0]);
19681965
} else {
19691966
let channel_id = batch[0].channel_id;
1970-
let batch: BTreeMap<Txid, CommitmentSigned> = batch
1971-
.iter()
1972-
.cloned()
1973-
.map(|cs| {
1974-
let funding_txid = cs.funding_txid.unwrap();
1975-
(funding_txid, cs)
1976-
})
1977-
.collect();
1978-
self.handle_commitment_signed_batch(their_node_id, channel_id, batch);
1967+
self.handle_commitment_signed_batch(their_node_id, channel_id, batch.clone());
19791968
}
19801969
}
19811970

lightning/src/ln/peer_handler.rs

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

@@ -42,8 +41,6 @@ use crate::util::string::PrintableString;
4241
#[allow(unused_imports)]
4342
use crate::prelude::*;
4443

45-
use alloc::collections::{btree_map, BTreeMap};
46-
4744
use crate::io;
4845
use crate::sync::{Mutex, MutexGuard, FairRwLock};
4946
use core::sync::atomic::{AtomicBool, AtomicU32, AtomicI32, Ordering};
@@ -335,8 +332,7 @@ impl ChannelMessageHandler for ErroringMessageHandler {
335332
ErroringMessageHandler::push_error(self, their_node_id, msg.channel_id);
336333
}
337334
fn handle_commitment_signed_batch(
338-
&self, their_node_id: PublicKey, channel_id: ChannelId,
339-
_batch: BTreeMap<Txid, msgs::CommitmentSigned>,
335+
&self, their_node_id: PublicKey, channel_id: ChannelId, _batch: Vec<msgs::CommitmentSigned>,
340336
) {
341337
ErroringMessageHandler::push_error(self, their_node_id, channel_id);
342338
}
@@ -551,8 +547,8 @@ struct MessageBatch {
551547

552548
/// The representation of the message batch, which may different for each message type.
553549
enum MessageBatchImpl {
554-
/// A batch of `commitment_signed` messages, where each has a unique `funding_txid`.
555-
CommitmentSigned(BTreeMap<Txid, msgs::CommitmentSigned>),
550+
/// A batch of `commitment_signed` messages used when there are pending splices.
551+
CommitmentSigned(Vec<msgs::CommitmentSigned>),
556552
}
557553

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

890886
enum LogicalMessage<T: core::fmt::Debug + wire::Type + wire::TestEq> {
891887
FromWire(wire::Message<T>),
892-
CommitmentSignedBatch(ChannelId, BTreeMap<Txid, msgs::CommitmentSigned>),
888+
CommitmentSignedBatch(ChannelId, Vec<msgs::CommitmentSigned>),
893889
}
894890

895891
enum MessageHandlingError {
@@ -1836,7 +1832,8 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
18361832

18371833
let messages = match msg.message_type {
18381834
Some(message_type) if message_type == msgs::CommitmentSigned::TYPE => {
1839-
MessageBatchImpl::CommitmentSigned(BTreeMap::new())
1835+
let messages = Vec::with_capacity(batch_size);
1836+
MessageBatchImpl::CommitmentSigned(messages)
18401837
},
18411838
_ => {
18421839
let error = format!("Peer {} sent start_batch for channel {} without a known message type", log_pubkey!(their_node_id), &msg.channel_id);
@@ -1865,7 +1862,7 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
18651862

18661863
if let wire::Message::CommitmentSigned(msg) = message {
18671864
if let Some(message_batch) = &mut peer_lock.message_batch {
1868-
let buffer = match &mut message_batch.messages {
1865+
let messages = match &mut message_batch.messages {
18691866
MessageBatchImpl::CommitmentSigned(ref mut messages) => messages,
18701867
};
18711868

@@ -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 batch = match messages {
19051888
MessageBatchImpl::CommitmentSigned(messages) => messages,

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)