Skip to content

Commit 7f91572

Browse files
committed
Add very basic test of ChannelManager serialization round-trip
1 parent a2fb3cc commit 7f91572

File tree

1 file changed

+138
-4
lines changed

1 file changed

+138
-4
lines changed

src/ln/channelmanager.rs

Lines changed: 138 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3178,16 +3178,16 @@ mod tests {
31783178
use chain::chaininterface::ChainListener;
31793179
use chain::keysinterface::KeysInterface;
31803180
use chain::keysinterface;
3181-
use ln::channelmanager::{ChannelManager,OnionKeys,PaymentFailReason,RAACommitmentOrder};
3182-
use ln::channelmonitor::{ChannelMonitorUpdateErr, CLTV_CLAIM_BUFFER, HTLC_FAIL_TIMEOUT_BLOCKS};
3181+
use ln::channelmanager::{ChannelManager,ChannelManagerReadArgs,OnionKeys,PaymentFailReason,RAACommitmentOrder};
3182+
use ln::channelmonitor::{ChannelMonitor, ChannelMonitorUpdateErr, CLTV_CLAIM_BUFFER, HTLC_FAIL_TIMEOUT_BLOCKS, ManyChannelMonitor};
31833183
use ln::router::{Route, RouteHop, Router};
31843184
use ln::msgs;
31853185
use ln::msgs::{ChannelMessageHandler,RoutingMessageHandler};
31863186
use util::test_utils;
31873187
use util::events::{Event, EventsProvider, MessageSendEvent, MessageSendEventsProvider};
31883188
use util::errors::APIError;
31893189
use util::logger::Logger;
3190-
use util::ser::Writeable;
3190+
use util::ser::{Writeable, Writer, ReadableArgs};
31913191

31923192
use bitcoin::util::hash::Sha256dHash;
31933193
use bitcoin::blockdata::block::{Block, BlockHeader};
@@ -3382,6 +3382,7 @@ mod tests {
33823382
chan_monitor: Arc<test_utils::TestChannelMonitor>,
33833383
node: Arc<ChannelManager>,
33843384
router: Router,
3385+
node_seed: [u8; 32],
33853386
network_payment_count: Rc<RefCell<u8>>,
33863387
network_chan_count: Rc<RefCell<u32>>,
33873388
}
@@ -4053,7 +4054,7 @@ mod tests {
40534054
let chan_monitor = Arc::new(test_utils::TestChannelMonitor::new(chain_monitor.clone(), tx_broadcaster.clone()));
40544055
let node = ChannelManager::new(0, true, Network::Testnet, feeest.clone(), chan_monitor.clone(), chain_monitor.clone(), tx_broadcaster.clone(), Arc::clone(&logger), keys_manager.clone()).unwrap();
40554056
let router = Router::new(PublicKey::from_secret_key(&secp_ctx, &keys_manager.get_node_secret()), chain_monitor.clone(), Arc::clone(&logger));
4056-
nodes.push(Node { chain_monitor, tx_broadcaster, chan_monitor, node, router,
4057+
nodes.push(Node { chain_monitor, tx_broadcaster, chan_monitor, node, router, node_seed: seed,
40574058
network_payment_count: payment_count.clone(),
40584059
network_chan_count: chan_count.clone(),
40594060
});
@@ -6856,4 +6857,137 @@ mod tests {
68566857
sign_msg!(unsigned_msg);
68576858
assert!(nodes[0].router.handle_channel_announcement(&chan_announcement).is_err());
68586859
}
6860+
6861+
struct VecWriter(Vec<u8>);
6862+
impl Writer for VecWriter {
6863+
fn write_all(&mut self, buf: &[u8]) -> Result<(), ::std::io::Error> {
6864+
self.0.extend_from_slice(buf);
6865+
Ok(())
6866+
}
6867+
fn size_hint(&mut self, size: usize) {
6868+
self.0.reserve_exact(size);
6869+
}
6870+
}
6871+
6872+
#[test]
6873+
fn test_simple_manager_serialize_deserialize() {
6874+
let mut nodes = create_network(2);
6875+
create_announced_chan_between_nodes(&nodes, 0, 1);
6876+
6877+
let (our_payment_preimage, _) = route_payment(&nodes[0], &[&nodes[1]], 1000000);
6878+
let (_, our_payment_hash) = route_payment(&nodes[0], &[&nodes[1]], 1000000);
6879+
6880+
nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false);
6881+
6882+
let nodes_0_serialized = nodes[0].node.encode();
6883+
let mut chan_0_monitor_serialized = VecWriter(Vec::new());
6884+
nodes[0].chan_monitor.simple_monitor.monitors.lock().unwrap().iter().next().unwrap().1.write_for_disk(&mut chan_0_monitor_serialized).unwrap();
6885+
6886+
nodes[0].chan_monitor = Arc::new(test_utils::TestChannelMonitor::new(nodes[0].chain_monitor.clone(), nodes[0].tx_broadcaster.clone()));
6887+
let mut chan_0_monitor_read = &chan_0_monitor_serialized.0[..];
6888+
let (_, chan_0_monitor) = <(Sha256dHash, ChannelMonitor)>::read(&mut chan_0_monitor_read, Arc::new(test_utils::TestLogger::new())).unwrap();
6889+
assert!(chan_0_monitor_read.is_empty());
6890+
6891+
let mut nodes_0_read = &nodes_0_serialized[..];
6892+
let keys_manager = Arc::new(keysinterface::KeysManager::new(&nodes[0].node_seed, Network::Testnet, Arc::new(test_utils::TestLogger::new())));
6893+
let (_, nodes_0_deserialized) = {
6894+
let mut channel_monitors = HashMap::new();
6895+
channel_monitors.insert(chan_0_monitor.get_funding_txo().unwrap(), &chan_0_monitor);
6896+
<(Sha256dHash, ChannelManager)>::read(&mut nodes_0_read, ChannelManagerReadArgs {
6897+
keys_manager,
6898+
fee_estimator: Arc::new(test_utils::TestFeeEstimator { sat_per_kw: 253 }),
6899+
monitor: nodes[0].chan_monitor.clone(),
6900+
chain_monitor: nodes[0].chain_monitor.clone(),
6901+
tx_broadcaster: nodes[0].tx_broadcaster.clone(),
6902+
logger: Arc::new(test_utils::TestLogger::new()),
6903+
channel_monitors: &channel_monitors,
6904+
}).unwrap()
6905+
};
6906+
assert!(nodes_0_read.is_empty());
6907+
6908+
assert!(nodes[0].chan_monitor.add_update_monitor(chan_0_monitor.get_funding_txo().unwrap(), chan_0_monitor).is_ok());
6909+
nodes[0].node = Arc::new(nodes_0_deserialized);
6910+
check_added_monitors!(nodes[0], 1);
6911+
6912+
reconnect_nodes(&nodes[0], &nodes[1], false, (0, 0), (0, 0), (0, 0), (0, 0), (false, false));
6913+
6914+
fail_payment(&nodes[0], &[&nodes[1]], our_payment_hash);
6915+
claim_payment(&nodes[0], &[&nodes[1]], our_payment_preimage);
6916+
}
6917+
6918+
#[test]
6919+
fn test_manager_serialize_deserialize_inconsistent_monitor() {
6920+
// Test deserializing a ChannelManager with a out-of-date ChannelMonitor
6921+
let mut nodes = create_network(4);
6922+
create_announced_chan_between_nodes(&nodes, 0, 1);
6923+
create_announced_chan_between_nodes(&nodes, 2, 0);
6924+
let (_, _, channel_id, funding_tx) = create_announced_chan_between_nodes(&nodes, 0, 3);
6925+
6926+
let (our_payment_preimage, _) = route_payment(&nodes[2], &[&nodes[0], &nodes[1]], 1000000);
6927+
6928+
// Serialize the ChannelManager here, but the monitor we keep up-to-date
6929+
let nodes_0_serialized = nodes[0].node.encode();
6930+
6931+
route_payment(&nodes[0], &[&nodes[3]], 1000000);
6932+
nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false);
6933+
nodes[2].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false);
6934+
nodes[3].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false);
6935+
6936+
// Now the ChannelMonitor (which is now out-of-sync with ChannelManager for channel w/
6937+
// nodes[3])
6938+
let mut node_0_monitors_serialized = Vec::new();
6939+
for monitor in nodes[0].chan_monitor.simple_monitor.monitors.lock().unwrap().iter() {
6940+
let mut writer = VecWriter(Vec::new());
6941+
monitor.1.write_for_disk(&mut writer).unwrap();
6942+
node_0_monitors_serialized.push(writer.0);
6943+
}
6944+
6945+
nodes[0].chan_monitor = Arc::new(test_utils::TestChannelMonitor::new(nodes[0].chain_monitor.clone(), nodes[0].tx_broadcaster.clone()));
6946+
let mut node_0_monitors = Vec::new();
6947+
for serialized in node_0_monitors_serialized.iter() {
6948+
let mut read = &serialized[..];
6949+
let (_, monitor) = <(Sha256dHash, ChannelMonitor)>::read(&mut read, Arc::new(test_utils::TestLogger::new())).unwrap();
6950+
assert!(read.is_empty());
6951+
node_0_monitors.push(monitor);
6952+
}
6953+
6954+
let mut nodes_0_read = &nodes_0_serialized[..];
6955+
let keys_manager = Arc::new(keysinterface::KeysManager::new(&nodes[0].node_seed, Network::Testnet, Arc::new(test_utils::TestLogger::new())));
6956+
let (_, nodes_0_deserialized) = <(Sha256dHash, ChannelManager)>::read(&mut nodes_0_read, ChannelManagerReadArgs {
6957+
keys_manager,
6958+
fee_estimator: Arc::new(test_utils::TestFeeEstimator { sat_per_kw: 253 }),
6959+
monitor: nodes[0].chan_monitor.clone(),
6960+
chain_monitor: nodes[0].chain_monitor.clone(),
6961+
tx_broadcaster: nodes[0].tx_broadcaster.clone(),
6962+
logger: Arc::new(test_utils::TestLogger::new()),
6963+
channel_monitors: &node_0_monitors.iter().map(|monitor| { (monitor.get_funding_txo().unwrap(), monitor) }).collect(),
6964+
}).unwrap();
6965+
assert!(nodes_0_read.is_empty());
6966+
6967+
{ // Channel close should result in a commitment tx and an HTLC tx
6968+
let txn = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap();
6969+
assert_eq!(txn.len(), 2);
6970+
assert_eq!(txn[0].input[0].previous_output.txid, funding_tx.txid());
6971+
assert_eq!(txn[1].input[0].previous_output.txid, txn[0].txid());
6972+
}
6973+
6974+
for monitor in node_0_monitors.drain(..) {
6975+
assert!(nodes[0].chan_monitor.add_update_monitor(monitor.get_funding_txo().unwrap(), monitor).is_ok());
6976+
check_added_monitors!(nodes[0], 1);
6977+
}
6978+
nodes[0].node = Arc::new(nodes_0_deserialized);
6979+
6980+
// nodes[1] and nodes[2] have no lost state with nodes[0]...
6981+
reconnect_nodes(&nodes[0], &nodes[1], false, (0, 0), (0, 0), (0, 0), (0, 0), (false, false));
6982+
reconnect_nodes(&nodes[0], &nodes[2], false, (0, 0), (0, 0), (0, 0), (0, 0), (false, false));
6983+
//... and we can even still claim the payment!
6984+
claim_payment(&nodes[2], &[&nodes[0], &nodes[1]], our_payment_preimage);
6985+
6986+
nodes[3].node.peer_connected(&nodes[0].node.get_our_node_id());
6987+
let reestablish = get_event_msg!(nodes[3], MessageSendEvent::SendChannelReestablish, nodes[0].node.get_our_node_id());
6988+
nodes[0].node.peer_connected(&nodes[3].node.get_our_node_id());
6989+
if let Err(msgs::HandleError { action: Some(msgs::ErrorAction::SendErrorMessage { msg }), .. }) = nodes[0].node.handle_channel_reestablish(&nodes[3].node.get_our_node_id(), &reestablish) {
6990+
assert_eq!(msg.channel_id, channel_id);
6991+
} else { panic!("Unexpected result"); }
6992+
}
68596993
}

0 commit comments

Comments
 (0)