@@ -4685,6 +4685,150 @@ macro_rules! check_spendable_outputs {
46854685 }
46864686}
46874687
4688+ #[test]
4689+ fn test_peer_storage_on_revoked_txn() {
4690+ let chanmon_cfgs = create_chanmon_cfgs(2);
4691+ let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
4692+ let (persister, chain_monitor);
4693+
4694+ let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
4695+ let nodes_0_deserialized;
4696+ let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
4697+ let nodes_0_serialized = nodes[0].node.encode();
4698+
4699+ let (_a, _b, channel_id, funding_tx) = create_announced_chan_between_nodes(&nodes, 1, 0);
4700+
4701+ send_payment(&nodes[1], &vec!(&nodes[0])[..], 10000);
4702+ send_payment(&nodes[1], &vec!(&nodes[0])[..], 10000);
4703+
4704+ let revoked_local_txn = get_local_commitment_txn!(nodes[1], channel_id);
4705+ assert_eq!(revoked_local_txn[0].input.len(), 1);
4706+ assert_eq!(revoked_local_txn[0].input[0].previous_output.txid, funding_tx.txid());
4707+
4708+ send_payment(&nodes[1], &vec!(&nodes[0])[..], 10000);
4709+
4710+ nodes[0].node.peer_disconnected(nodes[1].node.get_our_node_id());
4711+ nodes[1].node.peer_disconnected(nodes[0].node.get_our_node_id());
4712+
4713+ // // Lets drop the monitor and clear the chain_monitor as well.
4714+ nodes[0].chain_source.clear_watched_txn_and_outputs();
4715+ reload_node!(nodes[0], test_default_channel_config(), &nodes_0_serialized, &[], persister, chain_monitor, nodes_0_deserialized);
4716+ let persister: &dyn Persist<TestChannelSigner> = &chanmon_cfgs[0].persister;
4717+
4718+ let fundrecoverer
4719+ = FundRecoverer::new(node_cfgs[0].keys_manager, node_cfgs[0].logger,test_default_channel_config(), ChainParameters {network: Network::Testnet,
4720+ best_block: BestBlock::from_network(Network::Testnet)}, node_cfgs[0].keys_manager, node_cfgs[0].keys_manager, Some(&chanmon_cfgs[0].chain_source),
4721+ persister, node_cfgs[0].fee_estimator, node_cfgs[0].tx_broadcaster, Vec::new());
4722+
4723+ fundrecoverer.peer_connected(nodes[1].node.get_our_node_id(), &msgs::Init {
4724+ features: nodes[0].node.init_features(), networks: None, remote_network_address: None
4725+ }, true).unwrap();
4726+
4727+ nodes[1].node.peer_connected(nodes[0].node.get_our_node_id(), &msgs::Init {
4728+ features: nodes[0].node.init_features(), networks: None, remote_network_address: None
4729+ }, true).unwrap();
4730+ let msg_events = nodes[1].node.get_and_clear_pending_msg_events();
4731+ // 0th - SendYourPeerStorageMessage
4732+ // 1st - SendPeerStorage
4733+ // 2nd - SendChannelReestablish
4734+ assert_eq!(msg_events.len(), 3);
4735+
4736+ for msg in msg_events {
4737+ if let MessageSendEvent::SendChannelReestablish { ref node_id, ref msg } = msg {
4738+ fundrecoverer.handle_channel_reestablish(nodes[1].node.get_our_node_id(), msg);
4739+ assert_eq!(*node_id, nodes[0].node.get_our_node_id());
4740+ } else if let MessageSendEvent::SendPeerStorageMessage { ref node_id, ref msg } = msg {
4741+ fundrecoverer.handle_peer_storage(nodes[1].node.get_our_node_id(), msg);
4742+ assert_eq!(*node_id, nodes[0].node.get_our_node_id());
4743+ } else if let MessageSendEvent::SendYourPeerStorageMessage { ref node_id, ref msg } = msg {
4744+ fundrecoverer.handle_your_peer_storage(nodes[1].node.get_our_node_id(), msg);
4745+ assert_eq!(*node_id, nodes[0].node.get_our_node_id());
4746+ } else {
4747+ panic!("Unexpected event")
4748+ }
4749+ }
4750+
4751+ let recovery_event = fundrecoverer.get_and_clear_recovery_pending_events();
4752+ assert_eq!(recovery_event.len(), 1);
4753+ match recovery_event[0] {
4754+ RecoveryEvent::RescanBlock{..} => {},
4755+ _ => panic!("Unexpected event"),
4756+ };
4757+
4758+ let bogus_chan_reestablish = fundrecoverer.get_and_clear_pending_msg_events();
4759+ assert_eq!(bogus_chan_reestablish.len(), 1);
4760+
4761+ match bogus_chan_reestablish[0] {
4762+ MessageSendEvent::SendChannelReestablish {ref node_id, ref msg} => {
4763+ assert_eq!(nodes[1].node.get_our_node_id(), *node_id);
4764+ nodes[1].node.handle_channel_reestablish(nodes[0].node.get_our_node_id(), msg);
4765+ },
4766+ _ => panic!("Unexpected event"),
4767+ }
4768+
4769+
4770+
4771+ let block = create_dummy_block(nodes[0].best_block_hash(), 42, vec![revoked_local_txn[0].clone()]);
4772+ connect_block(&nodes[1], &block);
4773+ // Since we are using fundrecoverer as Chain::watch.
4774+ let txdata: Vec<_> = block.txdata.iter().enumerate().collect();
4775+ let height = nodes[0].best_block_info().1 + 1;
4776+
4777+ nodes[0].blocks.lock().unwrap().push((block.clone(), height));
4778+ fundrecoverer.best_block_updated(&block.header, height);
4779+ fundrecoverer.transactions_confirmed(&block.header, &txdata, height);
4780+
4781+ check_closed_broadcast!(nodes[1], true);
4782+
4783+ let events_2 = nodes[1].node.get_and_clear_pending_events();
4784+ assert_eq!(events_2.len(), 1);
4785+ match events_2[0] {
4786+ Event::ChannelClosed {..} => {}, // If we actually processed we'd receive the payment
4787+ _ => panic!("Unexpected event"),
4788+ }
4789+ check_added_monitors!(nodes[1], 1);
4790+
4791+ let panelty = node_cfgs[0].tx_broadcaster.txn_broadcasted.lock().unwrap().clone();
4792+ assert_eq!(panelty.len(), 1);
4793+ assert_eq!(panelty[0].input.len(), 1);
4794+
4795+ let block = create_dummy_block(nodes[1].best_block_hash(), 42, vec![panelty[0].clone()]);
4796+ let txdata: Vec<_> = block.txdata.iter().enumerate().collect();
4797+ connect_block(&nodes[1], &block);
4798+
4799+ nodes[0].blocks.lock().unwrap().push((block.clone(), height + 1));
4800+ fundrecoverer.best_block_updated(&block.header, height + 1);
4801+ fundrecoverer.transactions_confirmed(&block.header, &txdata, height + 1);
4802+
4803+ let mut dummy_block = create_dummy_block(nodes[1].best_block_hash(), height, Vec::new());
4804+ for i in 1..CHAN_CONFIRM_DEPTH {
4805+ let prev_blockhash = dummy_block.header.block_hash();
4806+ let dummy_txdata: Vec<_> = dummy_block.txdata.iter().enumerate().collect();
4807+ fundrecoverer.best_block_updated(&dummy_block.header, height + i + 1);
4808+ fundrecoverer.transactions_confirmed(&dummy_block.header, &dummy_txdata, height + i + 1);
4809+ dummy_block = create_dummy_block(prev_blockhash, height + i + 1, Vec::new());
4810+ }
4811+
4812+ // Lets drop the monitor and clear the chain_monitor as well.
4813+ nodes[0].chain_source.clear_watched_txn_and_outputs();
4814+
4815+ for event in fundrecoverer.get_and_clear_pending_events() {
4816+ match event {
4817+ Event::SpendableOutputs { mut outputs, channel_id: _ } => {
4818+ for outp in outputs.drain(..) {
4819+ match outp {
4820+ SpendableOutputDescriptor::StaticOutput{output, ..} => {
4821+ assert_eq!(output.value.to_sat(), panelty[0].output[0].value.to_sat());
4822+ },
4823+ _ => panic!("Unexpected event"),
4824+ }
4825+ }
4826+ },
4827+ _ => panic!("Unexpected event"),
4828+ };
4829+ }
4830+ }
4831+
46884832#[test]
46894833fn test_claim_sizeable_push_msat() {
46904834 // Incidentally test SpendableOutput event generation due to detection of to_local output on commitment tx
0 commit comments