Add a method to get session secret for onion packet to KeysInterface
[rust-lightning] / src / ln / channelmanager.rs
index bb61fe901986b122062b1f3a8b3617d63322b488..ac4fa819f52d7447adb6bce7c181496f1a48297f 100644 (file)
@@ -1199,11 +1199,7 @@ impl ChannelManager {
                        }
                }
 
-               let session_priv = SecretKey::from_slice(&self.secp_ctx, &{
-                       let mut session_key = [0; 32];
-                       rng::fill_bytes(&mut session_key);
-                       session_key
-               }).expect("RNG is bad!");
+               let session_priv = self.keys_manager.get_session_key();
 
                let cur_height = self.latest_block_height.load(Ordering::Acquire) as u32 + 1;
 
@@ -1988,10 +1984,20 @@ impl ChannelManager {
                                        // but if we've sent a shutdown and they haven't acknowledged it yet, we just
                                        // want to reject the new HTLC and fail it backwards instead of forwarding.
                                        if let PendingHTLCStatus::Forward(PendingForwardHTLCInfo { incoming_shared_secret, .. }) = pending_forward_info {
+                                               let chan_update = self.get_channel_update(chan);
                                                pending_forward_info = PendingHTLCStatus::Fail(HTLCFailureMsg::Relay(msgs::UpdateFailHTLC {
                                                        channel_id: msg.channel_id,
                                                        htlc_id: msg.htlc_id,
-                                                       reason: ChannelManager::build_first_hop_failure_packet(&incoming_shared_secret, 0x1000|20, &self.get_channel_update(chan).unwrap().encode_with_len()[..]),
+                                                       reason: if let Ok(update) = chan_update {
+                                                               ChannelManager::build_first_hop_failure_packet(&incoming_shared_secret, 0x1000|20, &update.encode_with_len()[..])
+                                                       } else {
+                                                               // This can only happen if the channel isn't in the fully-funded
+                                                               // state yet, implying our counterparty is trying to route payments
+                                                               // over the channel back to themselves (cause no one else should
+                                                               // know the short_id is a lightning channel yet). We should have no
+                                                               // problem just calling this unknown_next_peer
+                                                               ChannelManager::build_first_hop_failure_packet(&incoming_shared_secret, 0x4000|10, &[])
+                                                       },
                                                }));
                                        }
                                }
@@ -7756,6 +7762,36 @@ mod tests {
                check_spends!(spend_txn[0], node_txn[0].clone());
        }
 
+       #[test]
+       fn test_claim_on_remote_revoked_sizeable_push_msat() {
+               // Same test as previous, just test on remote revoked commitment tx, as per_commitment_point registration changes following you're funder/fundee and
+               // to_remote output is encumbered by a P2WPKH
+
+               let nodes = create_network(2);
+
+               let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 59000000);
+               let payment_preimage = route_payment(&nodes[0], &vec!(&nodes[1])[..], 3000000).0;
+               let revoked_local_txn = nodes[0].node.channel_state.lock().unwrap().by_id.get(&chan.2).unwrap().last_local_commitment_txn.clone();
+               assert_eq!(revoked_local_txn[0].input.len(), 1);
+               assert_eq!(revoked_local_txn[0].input[0].previous_output.txid, chan.3.txid());
+
+               claim_payment(&nodes[0], &vec!(&nodes[1])[..], payment_preimage);
+               let  header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
+               nodes[1].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![revoked_local_txn[0].clone()] }, 1);
+               let events = nodes[1].node.get_and_clear_pending_msg_events();
+               match events[0] {
+                       MessageSendEvent::BroadcastChannelUpdate { .. } => {},
+                       _ => panic!("Unexpected event"),
+               }
+               let node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap();
+               let spend_txn = check_spendable_outputs!(nodes[1], 1);
+               assert_eq!(spend_txn.len(), 4);
+               assert_eq!(spend_txn[0], spend_txn[2]); // to_remote output on revoked remote commitment_tx
+               check_spends!(spend_txn[0], revoked_local_txn[0].clone());
+               assert_eq!(spend_txn[1], spend_txn[3]); // to_local output on local commitment tx
+               check_spends!(spend_txn[1], node_txn[0].clone());
+       }
+
        #[test]
        fn test_static_spendable_outputs_preimage_tx() {
                let nodes = create_network(2);