Skip to content

Commit 69c3eb2

Browse files
authored
Merge pull request #503 from TheBlueMatt/2020-02-chanmon-ser-roundtrip
Fix Two Bugs around ChannelManager serialization round-trip
2 parents 29d14dd + 4b189bd commit 69c3eb2

File tree

4 files changed

+134
-8
lines changed

4 files changed

+134
-8
lines changed

lightning/src/ln/channel.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3670,12 +3670,15 @@ impl<ChanSigner: ChannelKeys + Writeable> Writeable for Channel<ChanSigner> {
36703670
}
36713671
(self.pending_inbound_htlcs.len() as u64 - dropped_inbound_htlcs).write(writer)?;
36723672
for htlc in self.pending_inbound_htlcs.iter() {
3673+
if let &InboundHTLCState::RemoteAnnounced(_) = &htlc.state {
3674+
continue; // Drop
3675+
}
36733676
htlc.htlc_id.write(writer)?;
36743677
htlc.amount_msat.write(writer)?;
36753678
htlc.cltv_expiry.write(writer)?;
36763679
htlc.payment_hash.write(writer)?;
36773680
match &htlc.state {
3678-
&InboundHTLCState::RemoteAnnounced(_) => {}, // Drop
3681+
&InboundHTLCState::RemoteAnnounced(_) => unreachable!(),
36793682
&InboundHTLCState::AwaitingRemoteRevokeToAnnounce(ref htlc_state) => {
36803683
1u8.write(writer)?;
36813684
htlc_state.write(writer)?;

lightning/src/ln/channelmanager.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3310,7 +3310,7 @@ impl<'a, R : ::std::io::Read, ChanSigner: ChannelKeys + Readable<R>, M: Deref> R
33103310
let mut short_to_id = HashMap::with_capacity(cmp::min(channel_count as usize, 128));
33113311
for _ in 0..channel_count {
33123312
let mut channel: Channel<ChanSigner> = ReadableArgs::read(reader, args.logger.clone())?;
3313-
if channel.last_block_connected != last_block_hash {
3313+
if channel.last_block_connected != Default::default() && channel.last_block_connected != last_block_hash {
33143314
return Err(DecodeError::InvalidValue);
33153315
}
33163316

lightning/src/ln/functional_test_utils.rs

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
use chain::chaininterface;
55
use chain::transaction::OutPoint;
66
use chain::keysinterface::KeysInterface;
7-
use ln::channelmanager::{ChannelManager,RAACommitmentOrder, PaymentPreimage, PaymentHash};
7+
use ln::channelmanager::{ChannelManager, ChannelManagerReadArgs, RAACommitmentOrder, PaymentPreimage, PaymentHash};
88
use ln::channelmonitor::{ChannelMonitor, ManyChannelMonitor};
99
use ln::router::{Route, Router};
1010
use ln::features::InitFeatures;
@@ -17,7 +17,7 @@ use util::events::{Event, EventsProvider, MessageSendEvent, MessageSendEventsPro
1717
use util::errors::APIError;
1818
use util::logger::Logger;
1919
use util::config::UserConfig;
20-
use util::ser::ReadableArgs;
20+
use util::ser::{ReadableArgs, Writeable};
2121

2222
use bitcoin::util::hash::BitcoinHash;
2323
use bitcoin::blockdata::block::BlockHeader;
@@ -37,7 +37,7 @@ use std::cell::RefCell;
3737
use std::rc::Rc;
3838
use std::sync::{Arc, Mutex};
3939
use std::mem;
40-
use std::collections::HashSet;
40+
use std::collections::{HashSet, HashMap};
4141

4242
pub const CHAN_CONFIRM_DEPTH: u32 = 100;
4343
pub fn confirm_transaction<'a, 'b: 'a>(notifier: &'a chaininterface::BlockNotifierRef<'b>, chain: &chaininterface::ChainWatchInterfaceUtil, tx: &Transaction, chan_id: u32) {
@@ -95,20 +95,45 @@ impl<'a, 'b> Drop for Node<'a, 'b> {
9595
// Check that if we serialize and then deserialize all our channel monitors we get the
9696
// same set of outputs to watch for on chain as we have now. Note that if we write
9797
// tests that fully close channels and remove the monitors at some point this may break.
98-
let chain_watch = Arc::new(chaininterface::ChainWatchInterfaceUtil::new(Network::Testnet, Arc::clone(&self.logger) as Arc<Logger>));
9998
let feeest = Arc::new(test_utils::TestFeeEstimator { sat_per_kw: 253 });
100-
let channel_monitor = test_utils::TestChannelMonitor::new(chain_watch.clone(), self.tx_broadcaster.clone(), self.logger.clone(), feeest);
10199
let old_monitors = self.chan_monitor.simple_monitor.monitors.lock().unwrap();
100+
let mut deserialized_monitors = Vec::new();
102101
for (_, old_monitor) in old_monitors.iter() {
103102
let mut w = test_utils::TestVecWriter(Vec::new());
104103
old_monitor.write_for_disk(&mut w).unwrap();
105104
let (_, deserialized_monitor) = <(Sha256d, ChannelMonitor<EnforcingChannelKeys>)>::read(
106105
&mut ::std::io::Cursor::new(&w.0), Arc::clone(&self.logger) as Arc<Logger>).unwrap();
106+
deserialized_monitors.push(deserialized_monitor);
107+
}
108+
109+
// Before using all the new monitors to check the watch outpoints, use the full set of
110+
// them to ensure we can write and reload our ChannelManager.
111+
{
112+
let mut channel_monitors = HashMap::new();
113+
for monitor in deserialized_monitors.iter_mut() {
114+
channel_monitors.insert(monitor.get_funding_txo().unwrap(), monitor);
115+
}
116+
117+
let mut w = test_utils::TestVecWriter(Vec::new());
118+
self.node.write(&mut w).unwrap();
119+
<(Sha256d, ChannelManager<EnforcingChannelKeys, &test_utils::TestChannelMonitor>)>::read(&mut ::std::io::Cursor::new(w.0), ChannelManagerReadArgs {
120+
default_config: UserConfig::default(),
121+
keys_manager: self.keys_manager.clone(),
122+
fee_estimator: Arc::new(test_utils::TestFeeEstimator { sat_per_kw: 253 }),
123+
monitor: self.chan_monitor,
124+
tx_broadcaster: self.tx_broadcaster.clone(),
125+
logger: Arc::new(test_utils::TestLogger::new()),
126+
channel_monitors: &mut channel_monitors,
127+
}).unwrap();
128+
}
129+
130+
let chain_watch = Arc::new(chaininterface::ChainWatchInterfaceUtil::new(Network::Testnet, Arc::clone(&self.logger) as Arc<Logger>));
131+
let channel_monitor = test_utils::TestChannelMonitor::new(chain_watch.clone(), self.tx_broadcaster.clone(), self.logger.clone(), feeest);
132+
for deserialized_monitor in deserialized_monitors.drain(..) {
107133
if let Err(_) = channel_monitor.add_update_monitor(deserialized_monitor.get_funding_txo().unwrap(), deserialized_monitor) {
108134
panic!();
109135
}
110136
}
111-
112137
if *chain_watch != *self.chain_monitor {
113138
panic!();
114139
}

lightning/src/ln/functional_tests.rs

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,104 @@ fn test_1_conf_open() {
413413
}
414414
}
415415

416+
fn do_test_sanity_on_in_flight_opens(steps: u8) {
417+
// Previously, we had issues deserializing channels when we hadn't connected the first block
418+
// after creation. To catch that and similar issues, we lean on the Node::drop impl to test
419+
// serialization round-trips and simply do steps towards opening a channel and then drop the
420+
// Node objects.
421+
422+
let node_cfgs = create_node_cfgs(2);
423+
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
424+
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
425+
426+
if steps & 0b1000_0000 != 0{
427+
let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
428+
nodes[0].block_notifier.block_connected_checked(&header, 1, &Vec::new(), &[0; 0]);
429+
nodes[1].block_notifier.block_connected_checked(&header, 1, &Vec::new(), &[0; 0]);
430+
}
431+
432+
if steps & 0x0f == 0 { return; }
433+
nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 100000, 10001, 42).unwrap();
434+
let open_channel = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id());
435+
436+
if steps & 0x0f == 1 { return; }
437+
nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), InitFeatures::supported(), &open_channel);
438+
let accept_channel = get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id());
439+
440+
if steps & 0x0f == 2 { return; }
441+
nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), InitFeatures::supported(), &accept_channel);
442+
443+
let (temporary_channel_id, tx, funding_output) = create_funding_transaction(&nodes[0], 100000, 42);
444+
445+
if steps & 0x0f == 3 { return; }
446+
{
447+
nodes[0].node.funding_transaction_generated(&temporary_channel_id, funding_output);
448+
let mut added_monitors = nodes[0].chan_monitor.added_monitors.lock().unwrap();
449+
assert_eq!(added_monitors.len(), 1);
450+
assert_eq!(added_monitors[0].0, funding_output);
451+
added_monitors.clear();
452+
}
453+
let funding_created = get_event_msg!(nodes[0], MessageSendEvent::SendFundingCreated, nodes[1].node.get_our_node_id());
454+
455+
if steps & 0x0f == 4 { return; }
456+
nodes[1].node.handle_funding_created(&nodes[0].node.get_our_node_id(), &funding_created);
457+
{
458+
let mut added_monitors = nodes[1].chan_monitor.added_monitors.lock().unwrap();
459+
assert_eq!(added_monitors.len(), 1);
460+
assert_eq!(added_monitors[0].0, funding_output);
461+
added_monitors.clear();
462+
}
463+
let funding_signed = get_event_msg!(nodes[1], MessageSendEvent::SendFundingSigned, nodes[0].node.get_our_node_id());
464+
465+
if steps & 0x0f == 5 { return; }
466+
nodes[0].node.handle_funding_signed(&nodes[1].node.get_our_node_id(), &funding_signed);
467+
{
468+
let mut added_monitors = nodes[0].chan_monitor.added_monitors.lock().unwrap();
469+
assert_eq!(added_monitors.len(), 1);
470+
assert_eq!(added_monitors[0].0, funding_output);
471+
added_monitors.clear();
472+
}
473+
474+
let events_4 = nodes[0].node.get_and_clear_pending_events();
475+
assert_eq!(events_4.len(), 1);
476+
match events_4[0] {
477+
Event::FundingBroadcastSafe { ref funding_txo, user_channel_id } => {
478+
assert_eq!(user_channel_id, 42);
479+
assert_eq!(*funding_txo, funding_output);
480+
},
481+
_ => panic!("Unexpected event"),
482+
};
483+
484+
if steps & 0x0f == 6 { return; }
485+
create_chan_between_nodes_with_value_confirm_first(&nodes[0], &nodes[1], &tx);
486+
487+
if steps & 0x0f == 7 { return; }
488+
confirm_transaction(&nodes[0].block_notifier, &nodes[0].chain_monitor, &tx, tx.version);
489+
create_chan_between_nodes_with_value_confirm_second(&nodes[1], &nodes[0]);
490+
}
491+
492+
#[test]
493+
fn test_sanity_on_in_flight_opens() {
494+
do_test_sanity_on_in_flight_opens(0);
495+
do_test_sanity_on_in_flight_opens(0 | 0b1000_0000);
496+
do_test_sanity_on_in_flight_opens(1);
497+
do_test_sanity_on_in_flight_opens(1 | 0b1000_0000);
498+
do_test_sanity_on_in_flight_opens(2);
499+
do_test_sanity_on_in_flight_opens(2 | 0b1000_0000);
500+
do_test_sanity_on_in_flight_opens(3);
501+
do_test_sanity_on_in_flight_opens(3 | 0b1000_0000);
502+
do_test_sanity_on_in_flight_opens(4);
503+
do_test_sanity_on_in_flight_opens(4 | 0b1000_0000);
504+
do_test_sanity_on_in_flight_opens(5);
505+
do_test_sanity_on_in_flight_opens(5 | 0b1000_0000);
506+
do_test_sanity_on_in_flight_opens(6);
507+
do_test_sanity_on_in_flight_opens(6 | 0b1000_0000);
508+
do_test_sanity_on_in_flight_opens(7);
509+
do_test_sanity_on_in_flight_opens(7 | 0b1000_0000);
510+
do_test_sanity_on_in_flight_opens(8);
511+
do_test_sanity_on_in_flight_opens(8 | 0b1000_0000);
512+
}
513+
416514
#[test]
417515
fn test_update_fee_vanilla() {
418516
let node_cfgs = create_node_cfgs(2);

0 commit comments

Comments
 (0)