Skip to content

Commit f7c2023

Browse files
committed
- Add the new flag on de/serialization
- Add a functional test - Fix some typos I found while reading the code
1 parent 9445382 commit f7c2023

File tree

3 files changed

+89
-13
lines changed

3 files changed

+89
-13
lines changed

lightning/src/chain/channelmonitor.rs

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1013,6 +1013,7 @@ impl<Signer: Sign> Writeable for ChannelMonitorImpl<Signer> {
10131013

10141014
self.lockdown_from_offchain.write(writer)?;
10151015
self.holder_tx_signed.write(writer)?;
1016+
self.allow_automated_broadcast.write(writer)?;
10161017

10171018
write_tlv_fields!(writer, {
10181019
(1, self.funding_spend_confirmed, option),
@@ -2165,11 +2166,12 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
21652166
}
21662167
}
21672168

2169+
// Broadcasts the latest commitment transaction only if it's safe to do so.
21682170
pub(crate) fn maybe_broadcast_latest_holder_commitment_txn<B: Deref, L: Deref>(&mut self, broadcaster: &B, logger: &L)
21692171
where B::Target: BroadcasterInterface,
21702172
L::Target: Logger,
21712173
{
2172-
if self.allow_automated_broadcast{
2174+
if self.allow_automated_broadcast {
21732175
for tx in self.get_latest_holder_commitment_txn(logger).iter() {
21742176
log_info!(logger, "Broadcasting local {}", log_tx!(tx));
21752177
broadcaster.broadcast_transaction(tx);
@@ -2180,7 +2182,9 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
21802182
}
21812183
}
21822184

2183-
pub(crate) fn force_broadcast_latest_holder_commitment_txn_unsafe<B: Deref, L: Deref>(&mut self, broadcaster: &B, logger: &L)
2185+
// Broadcasts the latest commitment transaction, even if we can't ensure it's safe to do so
2186+
// due to missing information.
2187+
pub fn force_broadcast_latest_holder_commitment_txn_unsafe<B: Deref, L: Deref>(&mut self, broadcaster: &B, logger: &L)
21842188
where B::Target: BroadcasterInterface,
21852189
L::Target: Logger,
21862190
{
@@ -2248,14 +2252,16 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
22482252
self.lockdown_from_offchain = true;
22492253
if *should_broadcast {
22502254
self.maybe_broadcast_latest_holder_commitment_txn(broadcaster, logger);
2251-
} else if !self.holder_tx_signed {
2252-
self.allow_automated_broadcast = false;
2253-
log_error!(logger, "You have a toxic holder commitment transaction avaible in channel monitor, read comment in ChannelMonitor::get_latest_holder_commitment_txn to be informed of manual action to take");
22542255
} else {
2255-
// If we generated a MonitorEvent::CommitmentTxConfirmed, the ChannelManager
2256-
// will still give us a ChannelForceClosed event with !should_broadcast, but we
2257-
// shouldn't print the scary warning above.
2258-
log_info!(logger, "Channel off-chain state closed after we broadcasted our latest commitment transaction.");
2256+
self.allow_automated_broadcast = false;
2257+
if !self.holder_tx_signed {
2258+
log_error!(logger, "You have a toxic holder commitment transaction avaible in channel monitor, read comment in ChannelMonitor::get_latest_holder_commitment_txn to be informed of manual action to take");
2259+
} else {
2260+
// If we generated a MonitorEvent::CommitmentTxConfirmed, the ChannelManager
2261+
// will still give us a ChannelForceClosed event with !should_broadcast, but we
2262+
// shouldn't print the scary warning above.
2263+
log_info!(logger, "Channel off-chain state closed after we broadcasted our latest commitment transaction.");
2264+
}
22592265
}
22602266
},
22612267
ChannelMonitorUpdateStep::ShutdownScript { scriptpubkey } => {
@@ -3638,6 +3644,7 @@ impl<'a, Signer: Sign, K: KeysInterface<Signer = Signer>> ReadableArgs<&'a K>
36383644

36393645
let lockdown_from_offchain = Readable::read(reader)?;
36403646
let holder_tx_signed = Readable::read(reader)?;
3647+
let allow_automated_broadcast: bool = Readable::read(reader)?;
36413648

36423649
if let Some(prev_commitment_tx) = prev_holder_signed_commitment_tx.as_mut() {
36433650
let prev_holder_value = onchain_tx_handler.get_prev_holder_commitment_to_self_value();
@@ -3726,7 +3733,7 @@ impl<'a, Signer: Sign, K: KeysInterface<Signer = Signer>> ReadableArgs<&'a K>
37263733

37273734
secp_ctx,
37283735

3729-
allow_automated_broadcast: true,
3736+
allow_automated_broadcast,
37303737
})))
37313738
}
37323739
}

lightning/src/ln/functional_tests.rs

Lines changed: 71 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2471,7 +2471,7 @@ fn revoked_output_claim() {
24712471
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
24722472
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
24732473
let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known());
2474-
// node[0] is gonna to revoke an old state thus node[1] should be able to claim the revoked output
2474+
// node[0] is going to revoke an old state thus node[1] should be able to claim the revoked output
24752475
let revoked_local_txn = get_local_commitment_txn!(nodes[0], chan_1.2);
24762476
assert_eq!(revoked_local_txn.len(), 1);
24772477
// Only output is the full channel value back to nodes[0]:
@@ -4752,6 +4752,75 @@ fn test_manager_serialize_deserialize_inconsistent_monitor() {
47524752
}
47534753
}
47544754

4755+
#[test]
4756+
fn test_deserialize_monitor_force_closed_without_broadcasting_txn() {
4757+
// Test deserializing a manager with a monitor that was force closed with {should_broadcast: false}.
4758+
// We expect not to broadcast the txn during deseriliazization, but to still be able to force-broadcast it.
4759+
let chanmon_cfgs = create_chanmon_cfgs(2);
4760+
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
4761+
let logger;
4762+
let fee_estimator;
4763+
let persister: test_utils::TestPersister;
4764+
let new_chain_monitor: test_utils::TestChainMonitor;
4765+
let deserialized_chanmgr: ChannelManager<EnforcingSigner, &test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestLogger>;
4766+
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None, None, None]);
4767+
let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
4768+
let (_, _, channel_id, funding_tx) = create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known());
4769+
4770+
node_chanmgrs[0].force_close_without_broadcasting_txn(&channel_id, &nodes[1].node.get_our_node_id()).unwrap();
4771+
4772+
// Serialize the monitor and node.
4773+
let mut chanmon_writer = test_utils::TestVecWriter(Vec::new());
4774+
get_monitor!(nodes[0], channel_id).write(&mut chanmon_writer).unwrap();
4775+
let serialized_chanmon = chanmon_writer.0;
4776+
let serialized_node = nodes[0].node.encode();
4777+
4778+
logger = test_utils::TestLogger::new();
4779+
fee_estimator = test_utils::TestFeeEstimator { sat_per_kw: Mutex::new(253) };
4780+
persister = test_utils::TestPersister::new();
4781+
let keys_manager = &chanmon_cfgs[0].keys_manager;
4782+
new_chain_monitor = test_utils::TestChainMonitor::new(Some(nodes[0].chain_source), nodes[0].tx_broadcaster.clone(), &logger, &fee_estimator, &persister, keys_manager);
4783+
nodes[0].chain_monitor = &new_chain_monitor;
4784+
4785+
// Deserialize the result.
4786+
let mut chanmon_read = &serialized_chanmon[..];
4787+
let (_, mut deserialized_chanmon) = <(BlockHash, ChannelMonitor<EnforcingSigner>)>::read(&mut chanmon_read, keys_manager).unwrap();
4788+
assert!(chanmon_read.is_empty());
4789+
let mut node_read = &serialized_node[..];
4790+
let tx_broadcaster = nodes[0].tx_broadcaster.clone();
4791+
let channel_monitors = HashMap::from([(deserialized_chanmon.get_funding_txo().0, &mut deserialized_chanmon)]);
4792+
let (_, deserialized_chanmgr_temp) =
4793+
<(BlockHash, ChannelManager<EnforcingSigner, &test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestLogger>)>::read(&mut node_read, ChannelManagerReadArgs {
4794+
default_config: UserConfig::default(),
4795+
keys_manager,
4796+
fee_estimator: &fee_estimator,
4797+
chain_monitor: &new_chain_monitor,
4798+
tx_broadcaster,
4799+
logger: &logger,
4800+
channel_monitors,
4801+
}).unwrap();
4802+
deserialized_chanmgr = deserialized_chanmgr_temp;
4803+
nodes[0].node = &deserialized_chanmgr;
4804+
4805+
{ // Assert that the latest commitment txn hasn't been broadcasted.
4806+
let txn = tx_broadcaster.txn_broadcasted.lock().unwrap();
4807+
assert_eq!(txn.len(), 0);
4808+
}
4809+
4810+
{ // Assert that we can still force-broadcast the latest commitment txn.
4811+
deserialized_chanmon.force_broadcast_latest_holder_commitment_txn_unsafe(&tx_broadcaster, &&logger);
4812+
let txn = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap();
4813+
assert_eq!(txn.len(), 1);
4814+
check_spends!(txn[0], funding_tx);
4815+
assert_eq!(txn[0].input[0].previous_output.txid, funding_tx.txid());
4816+
}
4817+
4818+
assert!(nodes[0].chain_monitor.watch_channel(deserialized_chanmon.get_funding_txo().0, deserialized_chanmon).is_ok());
4819+
check_added_monitors!(nodes[0], 1);
4820+
nodes[0].node.get_and_clear_pending_msg_events();
4821+
nodes[0].node.get_and_clear_pending_events();
4822+
}
4823+
47554824
macro_rules! check_spendable_outputs {
47564825
($node: expr, $keysinterface: expr) => {
47574826
{
@@ -7578,7 +7647,7 @@ fn test_force_close_without_broadcast() {
75787647
#[test]
75797648
fn test_check_htlc_underpaying() {
75807649
// Send payment through A -> B but A is maliciously
7581-
// sending a probe payment (i.e less than expected value0
7650+
// sending a probe payment (i.e less than expected value)
75827651
// to B, B should refuse payment.
75837652

75847653
let chanmon_cfgs = create_chanmon_cfgs(2);

lightning/src/ln/reorg_tests.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -368,7 +368,7 @@ fn do_test_unconf_chan(reload_node: bool, reorg_after_reload: bool, use_funding_
368368
}
369369
}
370370
// With expect_channel_force_closed set the TestChainMonitor will enforce that the next update
371-
// is a ChannelForcClosed on the right channel with should_broadcast set.
371+
// is a ChannelForceClosed on the right channel with should_broadcast set.
372372
*nodes[0].chain_monitor.expect_channel_force_closed.lock().unwrap() = Some((chan.2, true));
373373
nodes[0].node.test_process_background_events(); // Required to free the pending background monitor update
374374
check_added_monitors!(nodes[0], 1);

0 commit comments

Comments
 (0)