Skip to content

Commit e8866c2

Browse files
Aditya SharmaAditya Sharma
Aditya Sharma
authored and
Aditya Sharma
committed
chainmonitor: Add persistence logic for StubChannelMonitor and appropriate helpers to reload it.
1 parent ca8b93c commit e8866c2

File tree

7 files changed

+77
-4
lines changed

7 files changed

+77
-4
lines changed

fuzz/src/chanmon_consistency.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ use lightning::ln::channel::FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE;
4848
use lightning::ln::channel_state::ChannelDetails;
4949
use lightning::ln::channelmanager::{
5050
ChainParameters, ChannelManager, ChannelManagerReadArgs, PaymentId, PaymentSendFailure,
51-
RecipientOnionFields,
51+
RecipientOnionFields, StubChannel,
5252
};
5353
use lightning::ln::functional_test_utils::*;
5454
use lightning::ln::msgs::{
@@ -287,6 +287,10 @@ impl chain::Watch<TestChannelSigner> for TestChainMonitor {
287287
) -> Vec<(OutPoint, ChannelId, Vec<MonitorEvent>, Option<PublicKey>)> {
288288
return self.chain_monitor.release_pending_monitor_events();
289289
}
290+
291+
fn get_stub_cids_with_counterparty(&self, counterparty_node_id: PublicKey) -> Vec<ChannelId> {
292+
return self.chain_monitor.get_stub_cids_with_counterparty(counterparty_node_id);
293+
}
290294
}
291295

292296
struct KeyProvider {

lightning/src/chain/chainmonitor.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,7 @@ pub struct ChainMonitor<ChannelSigner: EcdsaChannelSigner, C: Deref, T: Deref, F
230230
P::Target: Persist<ChannelSigner>,
231231
{
232232
monitors: RwLock<HashMap<OutPoint, MonitorHolder<ChannelSigner>>>,
233+
233234
chain_source: Option<C>,
234235
broadcaster: T,
235236
logger: L,
@@ -266,7 +267,7 @@ where C::Target: chain::Filter,
266267
/// Calls which represent a new blockchain tip height should set `best_height`.
267268
fn process_chain_data<FN>(&self, header: &Header, best_height: Option<u32>, txdata: &TransactionData, process: FN)
268269
where
269-
FN: Fn(&ChannelMonitor<ChannelSigner>, &TransactionData) -> Vec<TransactionOutputs>
270+
FN: Fn(&ChannelMonitor<ChannelSigner>, &TransactionData) -> Vec<TransactionOutputs>,
270271
{
271272
let err_str = "ChannelMonitor[Update] persistence failed unrecoverably. This indicates we cannot continue normal operation and must shut down.";
272273
let funding_outpoints = hash_set_from_iter(self.monitors.read().unwrap().keys().cloned());
@@ -749,6 +750,17 @@ where C::Target: chain::Filter,
749750
L::Target: Logger,
750751
P::Target: Persist<ChannelSigner>,
751752
{
753+
fn get_stub_cids_with_counterparty(&self, counterparty_node_id: PublicKey) -> Vec<ChannelId> {
754+
let stub_monitors = self.stub_monitors.read().unwrap();
755+
let mut stubs = vec![];
756+
for (_, mon) in stub_monitors.iter() {
757+
if mon.get_counterparty_node_id() == Some(counterparty_node_id) {
758+
stubs.push(mon.channel_id());
759+
}
760+
}
761+
stubs
762+
}
763+
752764
fn watch_channel(&self, funding_outpoint: OutPoint, monitor: ChannelMonitor<ChannelSigner>) -> Result<ChannelMonitorUpdateStatus, ()> {
753765
let logger = WithChannelMonitor::from(&self.logger, &monitor, None);
754766
let mut monitors = self.monitors.write().unwrap();

lightning/src/chain/channelmonitor.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3727,6 +3727,15 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
37273727
self.current_holder_commitment_number
37283728
}
37293729

3730+
/// Updates the [`StubChannelMonitor`] when we receive a new more recent
3731+
/// peer storage from our peer. This souldn't be called through [`ChannelMonitor`].
3732+
fn update_latest_state_from_new_stubchannelmonitor(&mut self, stub: &StubChannelMonitor<Signer>) {
3733+
let inner = stub.inner.lock().unwrap();
3734+
self.commitment_secrets = inner.commitment_secrets.clone();
3735+
self.counterparty_claimable_outpoints = inner.counterparty_claimable_outpoints.clone();
3736+
self.their_cur_per_commitment_points = inner.their_cur_per_commitment_points.clone();
3737+
}
3738+
37303739
/// Attempts to claim a counterparty commitment transaction's outputs using the revocation key and
37313740
/// data in counterparty_claimable_outpoints. Will directly claim any HTLC outputs which expire at a
37323741
/// height > height + CLTV_SHARED_CLAIM_BUFFER. In any case, will install monitoring for

lightning/src/chain/mod.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use bitcoin::hash_types::{BlockHash, Txid};
1616
use bitcoin::network::Network;
1717
use bitcoin::secp256k1::PublicKey;
1818

19-
use crate::chain::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate, MonitorEvent};
19+
use crate::chain::channelmonitor::{ChannelMonitor, StubChannel, ChannelMonitorUpdate, MonitorEvent};
2020
use crate::ln::types::ChannelId;
2121
use crate::sign::ecdsa::EcdsaChannelSigner;
2222
use crate::chain::transaction::{OutPoint, TransactionData};
@@ -305,6 +305,15 @@ pub trait Watch<ChannelSigner: EcdsaChannelSigner> {
305305
/// For details on asynchronous [`ChannelMonitor`] updating and returning
306306
/// [`MonitorEvent::Completed`] here, see [`ChannelMonitorUpdateStatus::InProgress`].
307307
fn release_pending_monitor_events(&self) -> Vec<(OutPoint, ChannelId, Vec<MonitorEvent>, Option<PublicKey>)>;
308+
309+
/// Retrieves a list of channel IDs for [`StubChannelMonitor`] associated with a specific counterparty node ID.
310+
///
311+
/// This function searches through the collection of [`StubChannelMonitor`] and collects the channel IDs
312+
/// of those monitors that have the specified counterparty node ID.
313+
///
314+
/// This is used by [`FundRecoverer`] to fetch all the [`ChannelId`] with a peer that needs recovery so that we can send them
315+
/// `BogusChannelReestablish`.
316+
fn get_stub_cids_with_counterparty(&self, counterparty_node_id: PublicKey) -> Vec<ChannelId>;
308317
}
309318

310319
/// The `Filter` trait defines behavior for indicating chain activity of interest pertaining to

lightning/src/ln/blinded_payment_tests.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1466,6 +1466,7 @@ fn route_blinding_spec_test_vector() {
14661466
fn sign_invoice(
14671467
&self, _invoice: &RawBolt11Invoice, _recipient: Recipient,
14681468
) -> Result<RecoverableSignature, ()> { unreachable!() }
1469+
fn get_peer_storage_key(&self) -> [u8;32] { unreachable!() }
14691470
fn sign_bolt12_invoice_request(
14701471
&self, _invoice_request: &UnsignedInvoiceRequest,
14711472
) -> Result<schnorr::Signature, ()> { unreachable!() }

lightning/src/ln/functional_test_utils.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -715,6 +715,7 @@ impl<'a, 'b, 'c> Drop for Node<'a, 'b, 'c> {
715715
panic!();
716716
}
717717
}
718+
718719
assert_eq!(*chain_source.watched_txn.unsafe_well_ordered_double_lock_self(), *self.chain_source.watched_txn.unsafe_well_ordered_double_lock_self());
719720
assert_eq!(*chain_source.watched_outputs.unsafe_well_ordered_double_lock_self(), *self.chain_source.watched_outputs.unsafe_well_ordered_double_lock_self());
720721
}
@@ -2033,6 +2034,16 @@ pub fn do_main_commitment_signed_dance(node_a: &Node<'_, '_, '_>, node_b: &Node<
20332034
check_added_monitors!(node_b, 0);
20342035
assert!(node_b.node.get_and_clear_pending_msg_events().is_empty());
20352036
node_b.node.handle_revoke_and_ack(node_a.node.get_our_node_id(), &as_revoke_and_ack);
2037+
let events = node_b.node.get_and_clear_pending_msg_events();
2038+
assert!(events.len() == 1);
2039+
2040+
match events.get(0).unwrap() {
2041+
MessageSendEvent::SendPeerStorageMessage { ref node_id, ref msg } => {
2042+
assert_eq!(*node_id, node_a.node.get_our_node_id());
2043+
node_a.node.handle_peer_storage(node_b.node.get_our_node_id(), msg);
2044+
},
2045+
_ =>panic!("Unexpected event"),
2046+
}
20362047
assert!(node_b.node.get_and_clear_pending_msg_events().is_empty());
20372048
check_added_monitors!(node_b, 1);
20382049
node_b.node.handle_commitment_signed(node_a.node.get_our_node_id(), &as_commitment_signed);
@@ -2094,6 +2105,15 @@ pub fn do_commitment_signed_dance(node_a: &Node<'_, '_, '_>, node_b: &Node<'_, '
20942105
// Expecting the failure backwards event to the previous hop (not `node_b`)
20952106
assert_eq!(number_of_msg_events, 1);
20962107
} else {
2108+
let events = node_a.node.get_and_clear_pending_msg_events();
2109+
assert!(events.len() == 1);
2110+
match events.get(0).unwrap() {
2111+
MessageSendEvent::SendPeerStorageMessage { ref node_id, ref msg } => {
2112+
assert_eq!(*node_id, node_b.node.get_our_node_id());
2113+
node_b.node.handle_peer_storage(node_b.node.get_our_node_id(), msg);
2114+
},
2115+
_ =>panic!("Unexpected event"),
2116+
}
20972117
assert!(node_a.node.get_and_clear_pending_msg_events().is_empty());
20982118
}
20992119
}
@@ -3572,6 +3592,12 @@ macro_rules! get_chan_reestablish_msgs {
35723592
} else if let MessageSendEvent::SendChannelAnnouncement { ref node_id, ref msg, .. } = msg {
35733593
assert_eq!(*node_id, $dst_node.node.get_our_node_id());
35743594
announcements.insert(msg.contents.short_channel_id);
3595+
} else if let MessageSendEvent::SendPeerStorageMessage { ref node_id, ref msg } = msg {
3596+
$dst_node.node.handle_peer_storage($src_node.node.get_our_node_id(), msg);
3597+
assert_eq!(*node_id, $dst_node.node.get_our_node_id());
3598+
} else if let MessageSendEvent::SendYourPeerStorageMessage { ref node_id, ref msg } = msg {
3599+
$dst_node.node.handle_your_peer_storage($src_node.node.get_our_node_id(), msg);
3600+
assert_eq!(*node_id, $dst_node.node.get_our_node_id());
35753601
} else {
35763602
panic!("Unexpected event")
35773603
}

lightning/src/util/test_utils.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use crate::chain::chaininterface::ConfirmationTarget;
1818
use crate::chain::chaininterface::FEERATE_FLOOR_SATS_PER_KW;
1919
use crate::chain::chainmonitor;
2020
use crate::chain::channelmonitor;
21-
use crate::chain::channelmonitor::MonitorEvent;
21+
use crate::chain::channelmonitor::{MonitorEvent, StubChannel};
2222
use crate::chain::transaction::OutPoint;
2323
use crate::routing::router::{CandidateRouteHop, FirstHopCandidate, PublicHopCandidate, PrivateHopCandidate};
2424
use crate::sign;
@@ -423,6 +423,10 @@ impl<'a> chain::Watch<TestChannelSigner> for TestChainMonitor<'a> {
423423
fn release_pending_monitor_events(&self) -> Vec<(OutPoint, ChannelId, Vec<MonitorEvent>, Option<PublicKey>)> {
424424
return self.chain_monitor.release_pending_monitor_events();
425425
}
426+
427+
fn get_stub_cids_with_counterparty(&self, counterparty_node_id: PublicKey) -> Vec<ChannelId> {
428+
return self.chain_monitor.get_stub_cids_with_counterparty(counterparty_node_id);
429+
}
426430
}
427431

428432
#[cfg(test)]
@@ -1195,6 +1199,10 @@ impl NodeSigner for TestNodeSigner {
11951199
unreachable!()
11961200
}
11971201

1202+
fn get_peer_storage_key(&self) -> [u8;32] {
1203+
unreachable!()
1204+
}
1205+
11981206
fn get_node_id(&self, recipient: Recipient) -> Result<PublicKey, ()> {
11991207
let node_secret = match recipient {
12001208
Recipient::Node => Ok(&self.node_secret),
@@ -1271,6 +1279,10 @@ impl NodeSigner for TestKeysInterface {
12711279
self.backing.sign_invoice(invoice, recipient)
12721280
}
12731281

1282+
fn get_peer_storage_key(&self) -> [u8;32] {
1283+
self.backing.get_peer_storage_key()
1284+
}
1285+
12741286
fn sign_bolt12_invoice_request(
12751287
&self, invoice_request: &UnsignedInvoiceRequest
12761288
) -> Result<schnorr::Signature, ()> {

0 commit comments

Comments
 (0)