Skip to content

Commit c6d62c9

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 b1abb5d commit c6d62c9

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;
@@ -1950,8 +1948,7 @@ pub trait ChannelMessageHandler: BaseMessageHandler {
19501948
fn handle_commitment_signed(&self, their_node_id: PublicKey, msg: &CommitmentSigned);
19511949
/// Handle a batch of incoming `commitment_signed` message from the given peer.
19521950
fn handle_commitment_signed_batch(
1953-
&self, their_node_id: PublicKey, channel_id: ChannelId,
1954-
batch: BTreeMap<Txid, CommitmentSigned>,
1951+
&self, their_node_id: PublicKey, channel_id: ChannelId, batch: Vec<CommitmentSigned>,
19551952
);
19561953
/// Handle an incoming `revoke_and_ack` message from the given peer.
19571954
fn handle_revoke_and_ack(&self, their_node_id: PublicKey, msg: &RevokeAndACK);
@@ -1965,15 +1962,7 @@ pub trait ChannelMessageHandler: BaseMessageHandler {
19651962
self.handle_commitment_signed(their_node_id, &batch[0]);
19661963
} else {
19671964
let channel_id = batch[0].channel_id;
1968-
let batch: BTreeMap<Txid, CommitmentSigned> = batch
1969-
.iter()
1970-
.cloned()
1971-
.map(|cs| {
1972-
let funding_txid = cs.funding_txid.unwrap();
1973-
(funding_txid, cs)
1974-
})
1975-
.collect();
1976-
self.handle_commitment_signed_batch(their_node_id, channel_id, batch);
1965+
self.handle_commitment_signed_batch(their_node_id, channel_id, batch.clone());
19771966
}
19781967
}
19791968

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
}
@@ -555,8 +551,8 @@ enum MessageBatchImpl {
555551
/// batch is not yet known.
556552
Unknown,
557553

558-
/// A batch of `commitment_signed` messages, where each has a unique `funding_txid`.
559-
CommitmentSigned(BTreeMap<Txid, msgs::CommitmentSigned>),
554+
/// A batch of `commitment_signed` messages used when there are pending splices.
555+
CommitmentSigned(Vec<msgs::CommitmentSigned>),
560556
}
561557

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

894890
enum LogicalMessage<T: core::fmt::Debug + wire::Type + wire::TestEq> {
895891
FromWire(wire::Message<T>),
896-
CommitmentSignedBatch(ChannelId, BTreeMap<Txid, msgs::CommitmentSigned>),
892+
CommitmentSignedBatch(ChannelId, Vec<msgs::CommitmentSigned>),
897893
}
898894

899895
enum MessageHandlingError {
@@ -1851,10 +1847,11 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
18511847
if let wire::Message::CommitmentSigned(msg) = message {
18521848
if let Some(message_batch) = &mut peer_lock.message_batch {
18531849
if let MessageBatchImpl::Unknown = message_batch.messages {
1854-
message_batch.messages = MessageBatchImpl::CommitmentSigned(BTreeMap::new());
1850+
let messages = Vec::with_capacity(message_batch.batch_size);
1851+
message_batch.messages = MessageBatchImpl::CommitmentSigned(messages);
18551852
}
18561853

1857-
let buffer = match &mut message_batch.messages {
1854+
let messages = match &mut message_batch.messages {
18581855
MessageBatchImpl::Unknown => unreachable!(),
18591856
MessageBatchImpl::CommitmentSigned(ref mut messages) => messages,
18601857
};
@@ -1873,23 +1870,9 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
18731870
}.into());
18741871
}
18751872

1876-
let funding_txid = match msg.funding_txid {
1877-
Some(funding_txid) => funding_txid,
1878-
None => {
1879-
log_debug!(logger, "Peer {} sent batched commitment_signed without a funding_txid for channel {}", log_pubkey!(their_node_id), message_batch.channel_id);
1880-
return Err(PeerHandleError { }.into());
1881-
},
1882-
};
1883-
1884-
match buffer.entry(funding_txid) {
1885-
btree_map::Entry::Vacant(entry) => { entry.insert(msg); },
1886-
btree_map::Entry::Occupied(_) => {
1887-
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);
1888-
return Err(PeerHandleError { }.into());
1889-
}
1890-
}
1873+
messages.push(msg);
18911874

1892-
if buffer.len() == message_batch.batch_size {
1875+
if messages.len() == message_batch.batch_size {
18931876
let MessageBatch { channel_id, batch_size: _, messages } = peer_lock.message_batch.take().expect("batch should have been inserted");
18941877
let batch = match messages {
18951878
MessageBatchImpl::Unknown => unreachable!(),

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)