mirror of
https://github.com/lightningdevkit/rust-lightning.git
synced 2025-02-25 07:17:40 +01:00
Merge pull request #893 from TheBlueMatt/2021-04-features-chanman
Require payment secrets and track them in ChannelManager
This commit is contained in:
commit
a8bc8fb349
12 changed files with 1240 additions and 889 deletions
|
@ -262,44 +262,57 @@ fn check_payment_err(send_err: PaymentSendFailure) {
|
|||
type ChanMan = ChannelManager<EnforcingSigner, Arc<TestChainMonitor>, Arc<TestBroadcaster>, Arc<KeyProvider>, Arc<FuzzEstimator>, Arc<dyn Logger>>;
|
||||
|
||||
#[inline]
|
||||
fn send_payment(source: &ChanMan, dest: &ChanMan, dest_chan_id: u64, amt: u64, payment_id: &mut u8) -> bool {
|
||||
let payment_hash = Sha256::hash(&[*payment_id; 1]);
|
||||
fn get_payment_secret_hash(dest: &ChanMan, payment_id: &mut u8) -> Option<(PaymentSecret, PaymentHash)> {
|
||||
let mut payment_hash;
|
||||
for _ in 0..256 {
|
||||
payment_hash = PaymentHash(Sha256::hash(&[*payment_id; 1]).into_inner());
|
||||
if let Ok(payment_secret) = dest.create_inbound_payment_for_hash(payment_hash, None, 7200, 0) {
|
||||
return Some((payment_secret, payment_hash));
|
||||
}
|
||||
*payment_id = payment_id.wrapping_add(1);
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn send_payment(source: &ChanMan, dest: &ChanMan, dest_chan_id: u64, amt: u64, payment_id: &mut u8) -> bool {
|
||||
let (payment_secret, payment_hash) =
|
||||
if let Some((secret, hash)) = get_payment_secret_hash(dest, payment_id) { (secret, hash) } else { return true; };
|
||||
if let Err(err) = source.send_payment(&Route {
|
||||
paths: vec![vec![RouteHop {
|
||||
pubkey: dest.get_our_node_id(),
|
||||
node_features: NodeFeatures::empty(),
|
||||
node_features: NodeFeatures::known(),
|
||||
short_channel_id: dest_chan_id,
|
||||
channel_features: ChannelFeatures::empty(),
|
||||
channel_features: ChannelFeatures::known(),
|
||||
fee_msat: amt,
|
||||
cltv_expiry_delta: 200,
|
||||
}]],
|
||||
}, PaymentHash(payment_hash.into_inner()), &None) {
|
||||
}, payment_hash, &Some(payment_secret)) {
|
||||
check_payment_err(err);
|
||||
false
|
||||
} else { true }
|
||||
}
|
||||
#[inline]
|
||||
fn send_hop_payment(source: &ChanMan, middle: &ChanMan, middle_chan_id: u64, dest: &ChanMan, dest_chan_id: u64, amt: u64, payment_id: &mut u8) -> bool {
|
||||
let payment_hash = Sha256::hash(&[*payment_id; 1]);
|
||||
*payment_id = payment_id.wrapping_add(1);
|
||||
let (payment_secret, payment_hash) =
|
||||
if let Some((secret, hash)) = get_payment_secret_hash(dest, payment_id) { (secret, hash) } else { return true; };
|
||||
if let Err(err) = source.send_payment(&Route {
|
||||
paths: vec![vec![RouteHop {
|
||||
pubkey: middle.get_our_node_id(),
|
||||
node_features: NodeFeatures::empty(),
|
||||
node_features: NodeFeatures::known(),
|
||||
short_channel_id: middle_chan_id,
|
||||
channel_features: ChannelFeatures::empty(),
|
||||
channel_features: ChannelFeatures::known(),
|
||||
fee_msat: 50000,
|
||||
cltv_expiry_delta: 100,
|
||||
},RouteHop {
|
||||
pubkey: dest.get_our_node_id(),
|
||||
node_features: NodeFeatures::empty(),
|
||||
node_features: NodeFeatures::known(),
|
||||
short_channel_id: dest_chan_id,
|
||||
channel_features: ChannelFeatures::empty(),
|
||||
channel_features: ChannelFeatures::known(),
|
||||
fee_msat: amt,
|
||||
cltv_expiry_delta: 200,
|
||||
}]],
|
||||
}, PaymentHash(payment_hash.into_inner()), &None) {
|
||||
}, payment_hash, &Some(payment_secret)) {
|
||||
check_payment_err(err);
|
||||
false
|
||||
} else { true }
|
||||
|
@ -523,48 +536,6 @@ pub fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
|
|||
}
|
||||
|
||||
loop {
|
||||
macro_rules! send_payment_with_secret {
|
||||
($source: expr, $middle: expr, $dest: expr) => { {
|
||||
let payment_hash = Sha256::hash(&[payment_id; 1]);
|
||||
payment_id = payment_id.wrapping_add(1);
|
||||
let payment_secret = Sha256::hash(&[payment_id; 1]);
|
||||
payment_id = payment_id.wrapping_add(1);
|
||||
if let Err(err) = $source.send_payment(&Route {
|
||||
paths: vec![vec![RouteHop {
|
||||
pubkey: $middle.0.get_our_node_id(),
|
||||
node_features: NodeFeatures::empty(),
|
||||
short_channel_id: $middle.1,
|
||||
channel_features: ChannelFeatures::empty(),
|
||||
fee_msat: 50_000,
|
||||
cltv_expiry_delta: 100,
|
||||
},RouteHop {
|
||||
pubkey: $dest.0.get_our_node_id(),
|
||||
node_features: NodeFeatures::empty(),
|
||||
short_channel_id: $dest.1,
|
||||
channel_features: ChannelFeatures::empty(),
|
||||
fee_msat: 10_000_000,
|
||||
cltv_expiry_delta: 200,
|
||||
}],vec![RouteHop {
|
||||
pubkey: $middle.0.get_our_node_id(),
|
||||
node_features: NodeFeatures::empty(),
|
||||
short_channel_id: $middle.1,
|
||||
channel_features: ChannelFeatures::empty(),
|
||||
fee_msat: 50_000,
|
||||
cltv_expiry_delta: 100,
|
||||
},RouteHop {
|
||||
pubkey: $dest.0.get_our_node_id(),
|
||||
node_features: NodeFeatures::empty(),
|
||||
short_channel_id: $dest.1,
|
||||
channel_features: ChannelFeatures::empty(),
|
||||
fee_msat: 10_000_000,
|
||||
cltv_expiry_delta: 200,
|
||||
}]],
|
||||
}, PaymentHash(payment_hash.into_inner()), &Some(PaymentSecret(payment_secret.into_inner()))) {
|
||||
check_payment_err(err);
|
||||
}
|
||||
} }
|
||||
}
|
||||
|
||||
macro_rules! process_msg_events {
|
||||
($node: expr, $corrupt_forward: expr) => { {
|
||||
let events = if $node == 1 {
|
||||
|
@ -716,12 +687,12 @@ pub fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
|
|||
let had_events = !events.is_empty();
|
||||
for event in events.drain(..) {
|
||||
match event {
|
||||
events::Event::PaymentReceived { payment_hash, payment_secret, amt } => {
|
||||
events::Event::PaymentReceived { payment_hash, .. } => {
|
||||
if claim_set.insert(payment_hash.0) {
|
||||
if $fail {
|
||||
assert!(nodes[$node].fail_htlc_backwards(&payment_hash, &payment_secret));
|
||||
assert!(nodes[$node].fail_htlc_backwards(&payment_hash));
|
||||
} else {
|
||||
assert!(nodes[$node].claim_funds(PaymentPreimage(payment_hash.0), &payment_secret, amt));
|
||||
assert!(nodes[$node].claim_funds(PaymentPreimage(payment_hash.0)));
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -788,15 +759,15 @@ pub fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
|
|||
},
|
||||
0x0e => {
|
||||
if chan_a_disconnected {
|
||||
nodes[0].peer_connected(&nodes[1].get_our_node_id(), &Init { features: InitFeatures::empty() });
|
||||
nodes[1].peer_connected(&nodes[0].get_our_node_id(), &Init { features: InitFeatures::empty() });
|
||||
nodes[0].peer_connected(&nodes[1].get_our_node_id(), &Init { features: InitFeatures::known() });
|
||||
nodes[1].peer_connected(&nodes[0].get_our_node_id(), &Init { features: InitFeatures::known() });
|
||||
chan_a_disconnected = false;
|
||||
}
|
||||
},
|
||||
0x0f => {
|
||||
if chan_b_disconnected {
|
||||
nodes[1].peer_connected(&nodes[2].get_our_node_id(), &Init { features: InitFeatures::empty() });
|
||||
nodes[2].peer_connected(&nodes[1].get_our_node_id(), &Init { features: InitFeatures::empty() });
|
||||
nodes[1].peer_connected(&nodes[2].get_our_node_id(), &Init { features: InitFeatures::known() });
|
||||
nodes[2].peer_connected(&nodes[1].get_our_node_id(), &Init { features: InitFeatures::known() });
|
||||
chan_b_disconnected = false;
|
||||
}
|
||||
},
|
||||
|
@ -860,9 +831,6 @@ pub fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
|
|||
0x24 => { send_hop_payment(&nodes[0], &nodes[1], chan_a, &nodes[2], chan_b, 10_000_000, &mut payment_id); },
|
||||
0x25 => { send_hop_payment(&nodes[2], &nodes[1], chan_b, &nodes[0], chan_a, 10_000_000, &mut payment_id); },
|
||||
|
||||
0x26 => { send_payment_with_secret!(nodes[0], (&nodes[1], chan_a), (&nodes[2], chan_b)); },
|
||||
0x27 => { send_payment_with_secret!(nodes[2], (&nodes[1], chan_b), (&nodes[0], chan_a)); },
|
||||
|
||||
0x28 => { send_payment(&nodes[0], &nodes[1], chan_a, 1_000_000, &mut payment_id); },
|
||||
0x29 => { send_payment(&nodes[1], &nodes[0], chan_a, 1_000_000, &mut payment_id); },
|
||||
0x2a => { send_payment(&nodes[1], &nodes[2], chan_b, 1_000_000, &mut payment_id); },
|
||||
|
@ -936,13 +904,13 @@ pub fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
|
|||
|
||||
// Next, make sure peers are all connected to each other
|
||||
if chan_a_disconnected {
|
||||
nodes[0].peer_connected(&nodes[1].get_our_node_id(), &Init { features: InitFeatures::empty() });
|
||||
nodes[1].peer_connected(&nodes[0].get_our_node_id(), &Init { features: InitFeatures::empty() });
|
||||
nodes[0].peer_connected(&nodes[1].get_our_node_id(), &Init { features: InitFeatures::known() });
|
||||
nodes[1].peer_connected(&nodes[0].get_our_node_id(), &Init { features: InitFeatures::known() });
|
||||
chan_a_disconnected = false;
|
||||
}
|
||||
if chan_b_disconnected {
|
||||
nodes[1].peer_connected(&nodes[2].get_our_node_id(), &Init { features: InitFeatures::empty() });
|
||||
nodes[2].peer_connected(&nodes[1].get_our_node_id(), &Init { features: InitFeatures::empty() });
|
||||
nodes[1].peer_connected(&nodes[2].get_our_node_id(), &Init { features: InitFeatures::known() });
|
||||
nodes[2].peer_connected(&nodes[1].get_our_node_id(), &Init { features: InitFeatures::known() });
|
||||
chan_b_disconnected = false;
|
||||
}
|
||||
|
||||
|
|
|
@ -371,7 +371,7 @@ pub fn do_test(data: &[u8], logger: &Arc<dyn Logger>) {
|
|||
}, our_network_key, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0], Arc::clone(&logger)));
|
||||
|
||||
let mut should_forward = false;
|
||||
let mut payments_received: Vec<(PaymentHash, Option<PaymentSecret>, u64)> = Vec::new();
|
||||
let mut payments_received: Vec<PaymentHash> = Vec::new();
|
||||
let mut payments_sent = 0;
|
||||
let mut pending_funding_generation: Vec<([u8; 32], u64, Script)> = Vec::new();
|
||||
let mut pending_funding_signatures = HashMap::new();
|
||||
|
@ -476,23 +476,32 @@ pub fn do_test(data: &[u8], logger: &Arc<dyn Logger>) {
|
|||
}
|
||||
},
|
||||
8 => {
|
||||
for (payment, payment_secret, amt) in payments_received.drain(..) {
|
||||
for payment in payments_received.drain(..) {
|
||||
// SHA256 is defined as XOR of all input bytes placed in the first byte, and 0s
|
||||
// for the remaining bytes. Thus, if not all remaining bytes are 0s we cannot
|
||||
// fulfill this HTLC, but if they are, we can just take the first byte and
|
||||
// place that anywhere in our preimage.
|
||||
if &payment.0[1..] != &[0; 31] {
|
||||
channelmanager.fail_htlc_backwards(&payment, &payment_secret);
|
||||
channelmanager.fail_htlc_backwards(&payment);
|
||||
} else {
|
||||
let mut payment_preimage = PaymentPreimage([0; 32]);
|
||||
payment_preimage.0[0] = payment.0[0];
|
||||
channelmanager.claim_funds(payment_preimage, &payment_secret, amt);
|
||||
channelmanager.claim_funds(payment_preimage);
|
||||
}
|
||||
}
|
||||
},
|
||||
16 => {
|
||||
let payment_preimage = PaymentPreimage(keys_manager.get_secure_random_bytes());
|
||||
let mut sha = Sha256::engine();
|
||||
sha.input(&payment_preimage.0[..]);
|
||||
let payment_hash = PaymentHash(Sha256::from_engine(sha).into_inner());
|
||||
// Note that this may fail - our hashes may collide and we'll end up trying to
|
||||
// double-register the same payment_hash.
|
||||
let _ = channelmanager.create_inbound_payment_for_hash(payment_hash, None, 1, 0);
|
||||
},
|
||||
9 => {
|
||||
for (payment, payment_secret, _) in payments_received.drain(..) {
|
||||
channelmanager.fail_htlc_backwards(&payment, &payment_secret);
|
||||
for payment in payments_received.drain(..) {
|
||||
channelmanager.fail_htlc_backwards(&payment);
|
||||
}
|
||||
},
|
||||
10 => {
|
||||
|
@ -571,9 +580,9 @@ pub fn do_test(data: &[u8], logger: &Arc<dyn Logger>) {
|
|||
Event::FundingGenerationReady { temporary_channel_id, channel_value_satoshis, output_script, .. } => {
|
||||
pending_funding_generation.push((temporary_channel_id, channel_value_satoshis, output_script));
|
||||
},
|
||||
Event::PaymentReceived { payment_hash, payment_secret, amt } => {
|
||||
Event::PaymentReceived { payment_hash, .. } => {
|
||||
//TODO: enhance by fetching random amounts from fuzz input?
|
||||
payments_received.push((payment_hash, payment_secret, amt));
|
||||
payments_received.push(payment_hash);
|
||||
},
|
||||
Event::PaymentSent {..} => {},
|
||||
Event::PaymentFailed {..} => {},
|
||||
|
|
|
@ -251,9 +251,9 @@ mod tests {
|
|||
check_persisted_data!(0);
|
||||
|
||||
// Send a few payments and make sure the monitors are updated to the latest.
|
||||
send_payment(&nodes[0], &vec!(&nodes[1])[..], 8000000, 8_000_000);
|
||||
send_payment(&nodes[0], &vec!(&nodes[1])[..], 8000000);
|
||||
check_persisted_data!(5);
|
||||
send_payment(&nodes[1], &vec!(&nodes[0])[..], 4000000, 4_000_000);
|
||||
send_payment(&nodes[1], &vec!(&nodes[0])[..], 4000000);
|
||||
check_persisted_data!(10);
|
||||
|
||||
// Force close because cooperative close doesn't result in any persisted
|
||||
|
|
|
@ -344,7 +344,7 @@ mod tests {
|
|||
let (commitment_tx, htlc_tx) = {
|
||||
let payment_preimage = route_payment(&nodes[0], &vec!(&nodes[1])[..], 5_000_000).0;
|
||||
let mut txn = get_local_commitment_txn!(nodes[0], channel.2);
|
||||
claim_payment(&nodes[0], &vec!(&nodes[1])[..], payment_preimage, 5_000_000);
|
||||
claim_payment(&nodes[0], &vec!(&nodes[1])[..], payment_preimage);
|
||||
|
||||
assert_eq!(txn.len(), 2);
|
||||
(txn.remove(0), txn.remove(0))
|
||||
|
|
|
@ -19,8 +19,8 @@ use chain::channelmonitor::{ChannelMonitor, ChannelMonitorUpdateErr};
|
|||
use chain::transaction::OutPoint;
|
||||
use chain::Listen;
|
||||
use chain::Watch;
|
||||
use ln::channelmanager::{RAACommitmentOrder, PaymentPreimage, PaymentHash, PaymentSecret, PaymentSendFailure};
|
||||
use ln::features::InitFeatures;
|
||||
use ln::channelmanager::{RAACommitmentOrder, PaymentPreimage, PaymentHash, PaymentSendFailure};
|
||||
use ln::features::{InitFeatures, InvoiceFeatures};
|
||||
use ln::msgs;
|
||||
use ln::msgs::{ChannelMessageHandler, ErrorAction, RoutingMessageHandler};
|
||||
use routing::router::get_route;
|
||||
|
@ -47,15 +47,15 @@ fn do_test_simple_monitor_permanent_update_fail(persister_fail: bool) {
|
|||
create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known());
|
||||
let logger = test_utils::TestLogger::new();
|
||||
|
||||
let (_, payment_hash_1) = get_payment_preimage_hash!(&nodes[0]);
|
||||
let (_, payment_hash_1, payment_secret_1) = get_payment_preimage_hash!(&nodes[1]);
|
||||
|
||||
match persister_fail {
|
||||
true => chanmon_cfgs[0].persister.set_update_ret(Err(ChannelMonitorUpdateErr::PermanentFailure)),
|
||||
false => *nodes[0].chain_monitor.update_ret.lock().unwrap() = Some(Err(ChannelMonitorUpdateErr::PermanentFailure))
|
||||
}
|
||||
let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
|
||||
let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), None, None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
|
||||
unwrap_send_err!(nodes[0].node.send_payment(&route, payment_hash_1, &None), true, APIError::ChannelUnavailable {..}, {});
|
||||
let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
|
||||
unwrap_send_err!(nodes[0].node.send_payment(&route, payment_hash_1, &Some(payment_secret_1)), true, APIError::ChannelUnavailable {..}, {});
|
||||
check_added_monitors!(nodes[0], 2);
|
||||
|
||||
let events_1 = nodes[0].node.get_and_clear_pending_msg_events();
|
||||
|
@ -90,7 +90,7 @@ fn test_monitor_and_persister_update_fail() {
|
|||
let outpoint = OutPoint { txid: chan.3.txid(), index: 0 };
|
||||
|
||||
// Rebalance the network to generate htlc in the two directions
|
||||
send_payment(&nodes[0], &vec!(&nodes[1])[..], 10_000_000, 10_000_000);
|
||||
send_payment(&nodes[0], &vec!(&nodes[1])[..], 10_000_000);
|
||||
|
||||
// Route an HTLC from node 0 to node 1 (but don't settle)
|
||||
let preimage = route_payment(&nodes[0], &vec!(&nodes[1])[..], 9_000_000).0;
|
||||
|
@ -121,7 +121,7 @@ fn test_monitor_and_persister_update_fail() {
|
|||
persister.set_update_ret(Err(ChannelMonitorUpdateErr::TemporaryFailure));
|
||||
|
||||
// Try to update ChannelMonitor
|
||||
assert!(nodes[1].node.claim_funds(preimage, &None, 9_000_000));
|
||||
assert!(nodes[1].node.claim_funds(preimage));
|
||||
check_added_monitors!(nodes[1], 1);
|
||||
let updates = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id());
|
||||
assert_eq!(updates.update_fulfill_htlcs.len(), 1);
|
||||
|
@ -162,7 +162,7 @@ fn do_test_simple_monitor_temporary_update_fail(disconnect: bool, persister_fail
|
|||
let channel_id = create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known()).2;
|
||||
let logger = test_utils::TestLogger::new();
|
||||
|
||||
let (payment_preimage_1, payment_hash_1) = get_payment_preimage_hash!(&nodes[0]);
|
||||
let (payment_preimage_1, payment_hash_1, payment_secret_1) = get_payment_preimage_hash!(&nodes[1]);
|
||||
|
||||
match persister_fail {
|
||||
true => chanmon_cfgs[0].persister.set_update_ret(Err(ChannelMonitorUpdateErr::TemporaryFailure)),
|
||||
|
@ -171,8 +171,8 @@ fn do_test_simple_monitor_temporary_update_fail(disconnect: bool, persister_fail
|
|||
|
||||
{
|
||||
let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
|
||||
let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), None, None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
|
||||
unwrap_send_err!(nodes[0].node.send_payment(&route, payment_hash_1, &None), false, APIError::MonitorUpdateFailed, {});
|
||||
let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
|
||||
unwrap_send_err!(nodes[0].node.send_payment(&route, payment_hash_1, &Some(payment_secret_1)), false, APIError::MonitorUpdateFailed, {});
|
||||
check_added_monitors!(nodes[0], 1);
|
||||
}
|
||||
|
||||
|
@ -206,26 +206,27 @@ fn do_test_simple_monitor_temporary_update_fail(disconnect: bool, persister_fail
|
|||
let events_3 = nodes[1].node.get_and_clear_pending_events();
|
||||
assert_eq!(events_3.len(), 1);
|
||||
match events_3[0] {
|
||||
Event::PaymentReceived { ref payment_hash, ref payment_secret, amt } => {
|
||||
Event::PaymentReceived { ref payment_hash, ref payment_preimage, ref payment_secret, amt, user_payment_id: _ } => {
|
||||
assert_eq!(payment_hash_1, *payment_hash);
|
||||
assert_eq!(*payment_secret, None);
|
||||
assert!(payment_preimage.is_none());
|
||||
assert_eq!(payment_secret_1, *payment_secret);
|
||||
assert_eq!(amt, 1000000);
|
||||
},
|
||||
_ => panic!("Unexpected event"),
|
||||
}
|
||||
|
||||
claim_payment(&nodes[0], &[&nodes[1]], payment_preimage_1, 1_000_000);
|
||||
claim_payment(&nodes[0], &[&nodes[1]], payment_preimage_1);
|
||||
|
||||
// Now set it to failed again...
|
||||
let (_, payment_hash_2) = get_payment_preimage_hash!(&nodes[0]);
|
||||
let (_, payment_hash_2, payment_secret_2) = get_payment_preimage_hash!(&nodes[1]);
|
||||
{
|
||||
match persister_fail {
|
||||
true => chanmon_cfgs[0].persister.set_update_ret(Err(ChannelMonitorUpdateErr::TemporaryFailure)),
|
||||
false => *nodes[0].chain_monitor.update_ret.lock().unwrap() = Some(Err(ChannelMonitorUpdateErr::TemporaryFailure))
|
||||
}
|
||||
let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
|
||||
let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), None, None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
|
||||
unwrap_send_err!(nodes[0].node.send_payment(&route, payment_hash_2, &None), false, APIError::MonitorUpdateFailed, {});
|
||||
let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
|
||||
unwrap_send_err!(nodes[0].node.send_payment(&route, payment_hash_2, &Some(payment_secret_2)), false, APIError::MonitorUpdateFailed, {});
|
||||
check_added_monitors!(nodes[0], 1);
|
||||
}
|
||||
|
||||
|
@ -287,15 +288,15 @@ fn do_test_monitor_temporary_update_fail(disconnect_count: usize) {
|
|||
let channel_id = create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known()).2;
|
||||
let logger = test_utils::TestLogger::new();
|
||||
|
||||
let (payment_preimage_1, _) = route_payment(&nodes[0], &[&nodes[1]], 1000000);
|
||||
let (payment_preimage_1, _, _) = route_payment(&nodes[0], &[&nodes[1]], 1000000);
|
||||
|
||||
// Now try to send a second payment which will fail to send
|
||||
let (payment_preimage_2, payment_hash_2) = get_payment_preimage_hash!(nodes[0]);
|
||||
let (payment_preimage_2, payment_hash_2, payment_secret_2) = get_payment_preimage_hash!(nodes[1]);
|
||||
{
|
||||
*nodes[0].chain_monitor.update_ret.lock().unwrap() = Some(Err(ChannelMonitorUpdateErr::TemporaryFailure));
|
||||
let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
|
||||
let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), None, None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
|
||||
unwrap_send_err!(nodes[0].node.send_payment(&route, payment_hash_2, &None), false, APIError::MonitorUpdateFailed, {});
|
||||
let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
|
||||
unwrap_send_err!(nodes[0].node.send_payment(&route, payment_hash_2, &Some(payment_secret_2)), false, APIError::MonitorUpdateFailed, {});
|
||||
check_added_monitors!(nodes[0], 1);
|
||||
}
|
||||
|
||||
|
@ -305,7 +306,7 @@ fn do_test_monitor_temporary_update_fail(disconnect_count: usize) {
|
|||
|
||||
// Claim the previous payment, which will result in a update_fulfill_htlc/CS from nodes[1]
|
||||
// but nodes[0] won't respond since it is frozen.
|
||||
assert!(nodes[1].node.claim_funds(payment_preimage_1, &None, 1_000_000));
|
||||
assert!(nodes[1].node.claim_funds(payment_preimage_1));
|
||||
check_added_monitors!(nodes[1], 1);
|
||||
let events_2 = nodes[1].node.get_and_clear_pending_msg_events();
|
||||
assert_eq!(events_2.len(), 1);
|
||||
|
@ -574,15 +575,16 @@ fn do_test_monitor_temporary_update_fail(disconnect_count: usize) {
|
|||
let events_5 = nodes[1].node.get_and_clear_pending_events();
|
||||
assert_eq!(events_5.len(), 1);
|
||||
match events_5[0] {
|
||||
Event::PaymentReceived { ref payment_hash, ref payment_secret, amt } => {
|
||||
Event::PaymentReceived { ref payment_hash, ref payment_preimage, ref payment_secret, amt, user_payment_id: _ } => {
|
||||
assert_eq!(payment_hash_2, *payment_hash);
|
||||
assert_eq!(*payment_secret, None);
|
||||
assert!(payment_preimage.is_none());
|
||||
assert_eq!(payment_secret_2, *payment_secret);
|
||||
assert_eq!(amt, 1000000);
|
||||
},
|
||||
_ => panic!("Unexpected event"),
|
||||
}
|
||||
|
||||
claim_payment(&nodes[0], &[&nodes[1]], payment_preimage_2, 1_000_000);
|
||||
claim_payment(&nodes[0], &[&nodes[1]], payment_preimage_2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -622,11 +624,11 @@ fn test_monitor_update_fail_cs() {
|
|||
let channel_id = create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known()).2;
|
||||
let logger = test_utils::TestLogger::new();
|
||||
|
||||
let (payment_preimage, our_payment_hash) = get_payment_preimage_hash!(nodes[0]);
|
||||
let (payment_preimage, our_payment_hash, our_payment_secret) = get_payment_preimage_hash!(nodes[1]);
|
||||
{
|
||||
let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
|
||||
let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), None, None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
|
||||
nodes[0].node.send_payment(&route, our_payment_hash, &None).unwrap();
|
||||
let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
|
||||
nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)).unwrap();
|
||||
check_added_monitors!(nodes[0], 1);
|
||||
}
|
||||
|
||||
|
@ -688,15 +690,16 @@ fn test_monitor_update_fail_cs() {
|
|||
let events = nodes[1].node.get_and_clear_pending_events();
|
||||
assert_eq!(events.len(), 1);
|
||||
match events[0] {
|
||||
Event::PaymentReceived { payment_hash, payment_secret, amt } => {
|
||||
Event::PaymentReceived { payment_hash, payment_preimage, payment_secret, amt, user_payment_id: _ } => {
|
||||
assert_eq!(payment_hash, our_payment_hash);
|
||||
assert_eq!(payment_secret, None);
|
||||
assert!(payment_preimage.is_none());
|
||||
assert_eq!(our_payment_secret, payment_secret);
|
||||
assert_eq!(amt, 1000000);
|
||||
},
|
||||
_ => panic!("Unexpected event"),
|
||||
};
|
||||
|
||||
claim_payment(&nodes[0], &[&nodes[1]], payment_preimage, 1_000_000);
|
||||
claim_payment(&nodes[0], &[&nodes[1]], payment_preimage);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -711,11 +714,11 @@ fn test_monitor_update_fail_no_rebroadcast() {
|
|||
let channel_id = create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known()).2;
|
||||
let logger = test_utils::TestLogger::new();
|
||||
|
||||
let (payment_preimage_1, our_payment_hash) = get_payment_preimage_hash!(nodes[0]);
|
||||
let (payment_preimage_1, our_payment_hash, payment_secret_1) = get_payment_preimage_hash!(nodes[1]);
|
||||
{
|
||||
let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
|
||||
let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), None, None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
|
||||
nodes[0].node.send_payment(&route, our_payment_hash, &None).unwrap();
|
||||
let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
|
||||
nodes[0].node.send_payment(&route, our_payment_hash, &Some(payment_secret_1)).unwrap();
|
||||
check_added_monitors!(nodes[0], 1);
|
||||
}
|
||||
|
||||
|
@ -747,7 +750,7 @@ fn test_monitor_update_fail_no_rebroadcast() {
|
|||
_ => panic!("Unexpected event"),
|
||||
}
|
||||
|
||||
claim_payment(&nodes[0], &[&nodes[1]], payment_preimage_1, 1_000_000);
|
||||
claim_payment(&nodes[0], &[&nodes[1]], payment_preimage_1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -761,21 +764,21 @@ fn test_monitor_update_raa_while_paused() {
|
|||
let channel_id = create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known()).2;
|
||||
let logger = test_utils::TestLogger::new();
|
||||
|
||||
send_payment(&nodes[0], &[&nodes[1]], 5000000, 5_000_000);
|
||||
let (payment_preimage_1, our_payment_hash_1) = get_payment_preimage_hash!(nodes[0]);
|
||||
send_payment(&nodes[0], &[&nodes[1]], 5000000);
|
||||
let (payment_preimage_1, our_payment_hash_1, our_payment_secret_1) = get_payment_preimage_hash!(nodes[1]);
|
||||
{
|
||||
let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
|
||||
let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), None, None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
|
||||
nodes[0].node.send_payment(&route, our_payment_hash_1, &None).unwrap();
|
||||
let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
|
||||
nodes[0].node.send_payment(&route, our_payment_hash_1, &Some(our_payment_secret_1)).unwrap();
|
||||
check_added_monitors!(nodes[0], 1);
|
||||
}
|
||||
let send_event_1 = SendEvent::from_event(nodes[0].node.get_and_clear_pending_msg_events().remove(0));
|
||||
|
||||
let (payment_preimage_2, our_payment_hash_2) = get_payment_preimage_hash!(nodes[0]);
|
||||
let (payment_preimage_2, our_payment_hash_2, our_payment_secret_2) = get_payment_preimage_hash!(nodes[0]);
|
||||
{
|
||||
let net_graph_msg_handler = &nodes[1].net_graph_msg_handler;
|
||||
let route = get_route(&nodes[1].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[0].node.get_our_node_id(), None, None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
|
||||
nodes[1].node.send_payment(&route, our_payment_hash_2, &None).unwrap();
|
||||
let route = get_route(&nodes[1].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[0].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
|
||||
nodes[1].node.send_payment(&route, our_payment_hash_2, &Some(our_payment_secret_2)).unwrap();
|
||||
check_added_monitors!(nodes[1], 1);
|
||||
}
|
||||
let send_event_2 = SendEvent::from_event(nodes[1].node.get_and_clear_pending_msg_events().remove(0));
|
||||
|
@ -818,15 +821,15 @@ fn test_monitor_update_raa_while_paused() {
|
|||
nodes[0].node.handle_revoke_and_ack(&nodes[1].node.get_our_node_id(), &bs_second_raa);
|
||||
check_added_monitors!(nodes[0], 1);
|
||||
expect_pending_htlcs_forwardable!(nodes[0]);
|
||||
expect_payment_received!(nodes[0], our_payment_hash_2, 1000000);
|
||||
expect_payment_received!(nodes[0], our_payment_hash_2, our_payment_secret_2, 1000000);
|
||||
|
||||
nodes[1].node.handle_revoke_and_ack(&nodes[0].node.get_our_node_id(), &as_second_raa);
|
||||
check_added_monitors!(nodes[1], 1);
|
||||
expect_pending_htlcs_forwardable!(nodes[1]);
|
||||
expect_payment_received!(nodes[1], our_payment_hash_1, 1000000);
|
||||
expect_payment_received!(nodes[1], our_payment_hash_1, our_payment_secret_1, 1000000);
|
||||
|
||||
claim_payment(&nodes[0], &[&nodes[1]], payment_preimage_1, 1_000_000);
|
||||
claim_payment(&nodes[1], &[&nodes[0]], payment_preimage_2, 1_000_000);
|
||||
claim_payment(&nodes[0], &[&nodes[1]], payment_preimage_1);
|
||||
claim_payment(&nodes[1], &[&nodes[0]], payment_preimage_2);
|
||||
}
|
||||
|
||||
fn do_test_monitor_update_fail_raa(test_ignore_second_cs: bool) {
|
||||
|
@ -840,13 +843,13 @@ fn do_test_monitor_update_fail_raa(test_ignore_second_cs: bool) {
|
|||
let logger = test_utils::TestLogger::new();
|
||||
|
||||
// Rebalance a bit so that we can send backwards from 2 to 1.
|
||||
send_payment(&nodes[0], &[&nodes[1], &nodes[2]], 5000000, 5_000_000);
|
||||
send_payment(&nodes[0], &[&nodes[1], &nodes[2]], 5000000);
|
||||
|
||||
// Route a first payment that we'll fail backwards
|
||||
let (_, payment_hash_1) = route_payment(&nodes[0], &[&nodes[1], &nodes[2]], 1000000);
|
||||
let (_, payment_hash_1, _) = route_payment(&nodes[0], &[&nodes[1], &nodes[2]], 1000000);
|
||||
|
||||
// Fail the payment backwards, failing the monitor update on nodes[1]'s receipt of the RAA
|
||||
assert!(nodes[2].node.fail_htlc_backwards(&payment_hash_1, &None));
|
||||
assert!(nodes[2].node.fail_htlc_backwards(&payment_hash_1));
|
||||
expect_pending_htlcs_forwardable!(nodes[2]);
|
||||
check_added_monitors!(nodes[2], 1);
|
||||
|
||||
|
@ -863,11 +866,11 @@ fn do_test_monitor_update_fail_raa(test_ignore_second_cs: bool) {
|
|||
|
||||
// While the second channel is AwaitingRAA, forward a second payment to get it into the
|
||||
// holding cell.
|
||||
let (payment_preimage_2, payment_hash_2) = get_payment_preimage_hash!(nodes[0]);
|
||||
let (payment_preimage_2, payment_hash_2, payment_secret_2) = get_payment_preimage_hash!(nodes[2]);
|
||||
{
|
||||
let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
|
||||
let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2].node.get_our_node_id(), None, None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
|
||||
nodes[0].node.send_payment(&route, payment_hash_2, &None).unwrap();
|
||||
let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
|
||||
nodes[0].node.send_payment(&route, payment_hash_2, &Some(payment_secret_2)).unwrap();
|
||||
check_added_monitors!(nodes[0], 1);
|
||||
}
|
||||
|
||||
|
@ -890,11 +893,11 @@ fn do_test_monitor_update_fail_raa(test_ignore_second_cs: bool) {
|
|||
|
||||
// Attempt to forward a third payment but fail due to the second channel being unavailable
|
||||
// for forwarding.
|
||||
let (_, payment_hash_3) = get_payment_preimage_hash!(nodes[0]);
|
||||
let (_, payment_hash_3, payment_secret_3) = get_payment_preimage_hash!(nodes[2]);
|
||||
{
|
||||
let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
|
||||
let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2].node.get_our_node_id(), None, None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
|
||||
nodes[0].node.send_payment(&route, payment_hash_3, &None).unwrap();
|
||||
let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
|
||||
nodes[0].node.send_payment(&route, payment_hash_3, &Some(payment_secret_3)).unwrap();
|
||||
check_added_monitors!(nodes[0], 1);
|
||||
}
|
||||
|
||||
|
@ -940,10 +943,10 @@ fn do_test_monitor_update_fail_raa(test_ignore_second_cs: bool) {
|
|||
|
||||
let (payment_preimage_4, payment_hash_4) = if test_ignore_second_cs {
|
||||
// Try to route another payment backwards from 2 to make sure 1 holds off on responding
|
||||
let (payment_preimage_4, payment_hash_4) = get_payment_preimage_hash!(nodes[0]);
|
||||
let (payment_preimage_4, payment_hash_4, payment_secret_4) = get_payment_preimage_hash!(nodes[0]);
|
||||
let net_graph_msg_handler = &nodes[2].net_graph_msg_handler;
|
||||
let route = get_route(&nodes[2].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[0].node.get_our_node_id(), None, None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
|
||||
nodes[2].node.send_payment(&route, payment_hash_4, &None).unwrap();
|
||||
let route = get_route(&nodes[2].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[0].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
|
||||
nodes[2].node.send_payment(&route, payment_hash_4, &Some(payment_secret_4)).unwrap();
|
||||
check_added_monitors!(nodes[2], 1);
|
||||
|
||||
send_event = SendEvent::from_event(nodes[2].node.get_and_clear_pending_msg_events().remove(0));
|
||||
|
@ -1079,10 +1082,10 @@ fn do_test_monitor_update_fail_raa(test_ignore_second_cs: bool) {
|
|||
Event::PaymentReceived { payment_hash, .. } => assert_eq!(payment_hash, payment_hash_4.unwrap()),
|
||||
_ => panic!("Unexpected event"),
|
||||
};
|
||||
claim_payment(&nodes[2], &[&nodes[1], &nodes[0]], payment_preimage_4.unwrap(), 1_000_000);
|
||||
claim_payment(&nodes[2], &[&nodes[1], &nodes[0]], payment_preimage_4.unwrap());
|
||||
}
|
||||
|
||||
claim_payment(&nodes[0], &[&nodes[1], &nodes[2]], payment_preimage_2, 1_000_000);
|
||||
claim_payment(&nodes[0], &[&nodes[1], &nodes[2]], payment_preimage_2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -1103,12 +1106,12 @@ fn test_monitor_update_fail_reestablish() {
|
|||
let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known());
|
||||
create_announced_chan_between_nodes(&nodes, 1, 2, InitFeatures::known(), InitFeatures::known());
|
||||
|
||||
let (our_payment_preimage, _) = route_payment(&nodes[0], &[&nodes[1], &nodes[2]], 1000000);
|
||||
let (our_payment_preimage, _, _) = route_payment(&nodes[0], &[&nodes[1], &nodes[2]], 1000000);
|
||||
|
||||
nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false);
|
||||
nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false);
|
||||
|
||||
assert!(nodes[2].node.claim_funds(our_payment_preimage, &None, 1_000_000));
|
||||
assert!(nodes[2].node.claim_funds(our_payment_preimage));
|
||||
check_added_monitors!(nodes[2], 1);
|
||||
let mut updates = get_htlc_update_msgs!(nodes[2], nodes[1].node.get_our_node_id());
|
||||
assert!(updates.update_add_htlcs.is_empty());
|
||||
|
@ -1185,9 +1188,9 @@ fn raa_no_response_awaiting_raa_state() {
|
|||
let channel_id = create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known()).2;
|
||||
let logger = test_utils::TestLogger::new();
|
||||
|
||||
let (payment_preimage_1, payment_hash_1) = get_payment_preimage_hash!(nodes[0]);
|
||||
let (payment_preimage_2, payment_hash_2) = get_payment_preimage_hash!(nodes[0]);
|
||||
let (payment_preimage_3, payment_hash_3) = get_payment_preimage_hash!(nodes[0]);
|
||||
let (payment_preimage_1, payment_hash_1, payment_secret_1) = get_payment_preimage_hash!(nodes[1]);
|
||||
let (payment_preimage_2, payment_hash_2, payment_secret_2) = get_payment_preimage_hash!(nodes[1]);
|
||||
let (payment_preimage_3, payment_hash_3, payment_secret_3) = get_payment_preimage_hash!(nodes[1]);
|
||||
|
||||
// Queue up two payments - one will be delivered right away, one immediately goes into the
|
||||
// holding cell as nodes[0] is AwaitingRAA. Ultimately this allows us to deliver an RAA
|
||||
|
@ -1196,10 +1199,10 @@ fn raa_no_response_awaiting_raa_state() {
|
|||
// generation during RAA while in monitor-update-failed state.
|
||||
{
|
||||
let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
|
||||
let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), None, None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
|
||||
nodes[0].node.send_payment(&route, payment_hash_1, &None).unwrap();
|
||||
let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
|
||||
nodes[0].node.send_payment(&route, payment_hash_1, &Some(payment_secret_1)).unwrap();
|
||||
check_added_monitors!(nodes[0], 1);
|
||||
nodes[0].node.send_payment(&route, payment_hash_2, &None).unwrap();
|
||||
nodes[0].node.send_payment(&route, payment_hash_2, &Some(payment_secret_2)).unwrap();
|
||||
check_added_monitors!(nodes[0], 0);
|
||||
}
|
||||
|
||||
|
@ -1243,15 +1246,15 @@ fn raa_no_response_awaiting_raa_state() {
|
|||
check_added_monitors!(nodes[1], 0);
|
||||
let bs_responses = get_revoke_commit_msgs!(nodes[1], nodes[0].node.get_our_node_id());
|
||||
expect_pending_htlcs_forwardable!(nodes[1]);
|
||||
expect_payment_received!(nodes[1], payment_hash_1, 1000000);
|
||||
expect_payment_received!(nodes[1], payment_hash_1, payment_secret_1, 1000000);
|
||||
|
||||
// We send a third payment here, which is somewhat of a redundant test, but the
|
||||
// chanmon_fail_consistency test required it to actually find the bug (by seeing out-of-sync
|
||||
// commitment transaction states) whereas here we can explicitly check for it.
|
||||
{
|
||||
let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
|
||||
let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), None, None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
|
||||
nodes[0].node.send_payment(&route, payment_hash_3, &None).unwrap();
|
||||
let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
|
||||
nodes[0].node.send_payment(&route, payment_hash_3, &Some(payment_secret_3)).unwrap();
|
||||
check_added_monitors!(nodes[0], 0);
|
||||
assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty());
|
||||
}
|
||||
|
@ -1274,7 +1277,7 @@ fn raa_no_response_awaiting_raa_state() {
|
|||
nodes[1].node.handle_revoke_and_ack(&nodes[0].node.get_our_node_id(), &as_raa);
|
||||
check_added_monitors!(nodes[1], 1);
|
||||
expect_pending_htlcs_forwardable!(nodes[1]);
|
||||
expect_payment_received!(nodes[1], payment_hash_2, 1000000);
|
||||
expect_payment_received!(nodes[1], payment_hash_2, payment_secret_2, 1000000);
|
||||
let bs_update = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id());
|
||||
|
||||
nodes[0].node.handle_revoke_and_ack(&nodes[1].node.get_our_node_id(), &bs_raa);
|
||||
|
@ -1287,11 +1290,11 @@ fn raa_no_response_awaiting_raa_state() {
|
|||
nodes[1].node.handle_revoke_and_ack(&nodes[0].node.get_our_node_id(), &as_raa);
|
||||
check_added_monitors!(nodes[1], 1);
|
||||
expect_pending_htlcs_forwardable!(nodes[1]);
|
||||
expect_payment_received!(nodes[1], payment_hash_3, 1000000);
|
||||
expect_payment_received!(nodes[1], payment_hash_3, payment_secret_3, 1000000);
|
||||
|
||||
claim_payment(&nodes[0], &[&nodes[1]], payment_preimage_1, 1_000_000);
|
||||
claim_payment(&nodes[0], &[&nodes[1]], payment_preimage_2, 1_000_000);
|
||||
claim_payment(&nodes[0], &[&nodes[1]], payment_preimage_3, 1_000_000);
|
||||
claim_payment(&nodes[0], &[&nodes[1]], payment_preimage_1);
|
||||
claim_payment(&nodes[0], &[&nodes[1]], payment_preimage_2);
|
||||
claim_payment(&nodes[0], &[&nodes[1]], payment_preimage_3);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -1310,12 +1313,12 @@ fn claim_while_disconnected_monitor_update_fail() {
|
|||
let logger = test_utils::TestLogger::new();
|
||||
|
||||
// Forward a payment for B to claim
|
||||
let (payment_preimage_1, _) = route_payment(&nodes[0], &[&nodes[1]], 1000000);
|
||||
let (payment_preimage_1, _, _) = route_payment(&nodes[0], &[&nodes[1]], 1000000);
|
||||
|
||||
nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false);
|
||||
nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false);
|
||||
|
||||
assert!(nodes[1].node.claim_funds(payment_preimage_1, &None, 1_000_000));
|
||||
assert!(nodes[1].node.claim_funds(payment_preimage_1));
|
||||
check_added_monitors!(nodes[1], 1);
|
||||
|
||||
nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() });
|
||||
|
@ -1339,11 +1342,11 @@ fn claim_while_disconnected_monitor_update_fail() {
|
|||
|
||||
// Send a second payment from A to B, resulting in a commitment update that gets swallowed with
|
||||
// the monitor still failed
|
||||
let (payment_preimage_2, payment_hash_2) = get_payment_preimage_hash!(nodes[0]);
|
||||
let (payment_preimage_2, payment_hash_2, payment_secret_2) = get_payment_preimage_hash!(nodes[1]);
|
||||
{
|
||||
let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
|
||||
let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), None, None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
|
||||
nodes[0].node.send_payment(&route, payment_hash_2, &None).unwrap();
|
||||
let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
|
||||
nodes[0].node.send_payment(&route, payment_hash_2, &Some(payment_secret_2)).unwrap();
|
||||
check_added_monitors!(nodes[0], 1);
|
||||
}
|
||||
|
||||
|
@ -1403,7 +1406,7 @@ fn claim_while_disconnected_monitor_update_fail() {
|
|||
check_added_monitors!(nodes[1], 1);
|
||||
|
||||
expect_pending_htlcs_forwardable!(nodes[1]);
|
||||
expect_payment_received!(nodes[1], payment_hash_2, 1000000);
|
||||
expect_payment_received!(nodes[1], payment_hash_2, payment_secret_2, 1000000);
|
||||
|
||||
nodes[0].node.handle_revoke_and_ack(&nodes[1].node.get_our_node_id(), &bs_raa);
|
||||
check_added_monitors!(nodes[0], 1);
|
||||
|
@ -1417,7 +1420,7 @@ fn claim_while_disconnected_monitor_update_fail() {
|
|||
_ => panic!("Unexpected event"),
|
||||
}
|
||||
|
||||
claim_payment(&nodes[0], &[&nodes[1]], payment_preimage_2, 1_000_000);
|
||||
claim_payment(&nodes[0], &[&nodes[1]], payment_preimage_2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -1435,11 +1438,11 @@ fn monitor_failed_no_reestablish_response() {
|
|||
|
||||
// Route the payment and deliver the initial commitment_signed (with a monitor update failure
|
||||
// on receipt).
|
||||
let (payment_preimage_1, payment_hash_1) = get_payment_preimage_hash!(nodes[0]);
|
||||
let (payment_preimage_1, payment_hash_1, payment_secret_1) = get_payment_preimage_hash!(nodes[1]);
|
||||
{
|
||||
let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
|
||||
let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), None, None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
|
||||
nodes[0].node.send_payment(&route, payment_hash_1, &None).unwrap();
|
||||
let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
|
||||
nodes[0].node.send_payment(&route, payment_hash_1, &Some(payment_secret_1)).unwrap();
|
||||
check_added_monitors!(nodes[0], 1);
|
||||
}
|
||||
|
||||
|
@ -1483,9 +1486,9 @@ fn monitor_failed_no_reestablish_response() {
|
|||
check_added_monitors!(nodes[1], 1);
|
||||
|
||||
expect_pending_htlcs_forwardable!(nodes[1]);
|
||||
expect_payment_received!(nodes[1], payment_hash_1, 1000000);
|
||||
expect_payment_received!(nodes[1], payment_hash_1, payment_secret_1, 1000000);
|
||||
|
||||
claim_payment(&nodes[0], &[&nodes[1]], payment_preimage_1, 1_000_000);
|
||||
claim_payment(&nodes[0], &[&nodes[1]], payment_preimage_1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -1509,11 +1512,11 @@ fn first_message_on_recv_ordering() {
|
|||
|
||||
// Route the first payment outbound, holding the last RAA for B until we are set up so that we
|
||||
// can deliver it and fail the monitor update.
|
||||
let (payment_preimage_1, payment_hash_1) = get_payment_preimage_hash!(nodes[0]);
|
||||
let (payment_preimage_1, payment_hash_1, payment_secret_1) = get_payment_preimage_hash!(nodes[1]);
|
||||
{
|
||||
let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
|
||||
let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), None, None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
|
||||
nodes[0].node.send_payment(&route, payment_hash_1, &None).unwrap();
|
||||
let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
|
||||
nodes[0].node.send_payment(&route, payment_hash_1, &Some(payment_secret_1)).unwrap();
|
||||
check_added_monitors!(nodes[0], 1);
|
||||
}
|
||||
|
||||
|
@ -1534,11 +1537,11 @@ fn first_message_on_recv_ordering() {
|
|||
let as_raa = get_event_msg!(nodes[0], MessageSendEvent::SendRevokeAndACK, nodes[1].node.get_our_node_id());
|
||||
|
||||
// Route the second payment, generating an update_add_htlc/commitment_signed
|
||||
let (payment_preimage_2, payment_hash_2) = get_payment_preimage_hash!(nodes[0]);
|
||||
let (payment_preimage_2, payment_hash_2, payment_secret_2) = get_payment_preimage_hash!(nodes[1]);
|
||||
{
|
||||
let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
|
||||
let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), None, None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
|
||||
nodes[0].node.send_payment(&route, payment_hash_2, &None).unwrap();
|
||||
let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
|
||||
nodes[0].node.send_payment(&route, payment_hash_2, &Some(payment_secret_2)).unwrap();
|
||||
check_added_monitors!(nodes[0], 1);
|
||||
}
|
||||
let mut events = nodes[0].node.get_and_clear_pending_msg_events();
|
||||
|
@ -1571,7 +1574,7 @@ fn first_message_on_recv_ordering() {
|
|||
check_added_monitors!(nodes[1], 0);
|
||||
|
||||
expect_pending_htlcs_forwardable!(nodes[1]);
|
||||
expect_payment_received!(nodes[1], payment_hash_1, 1000000);
|
||||
expect_payment_received!(nodes[1], payment_hash_1, payment_secret_1, 1000000);
|
||||
|
||||
let bs_responses = get_revoke_commit_msgs!(nodes[1], nodes[0].node.get_our_node_id());
|
||||
nodes[0].node.handle_revoke_and_ack(&nodes[1].node.get_our_node_id(), &bs_responses.0);
|
||||
|
@ -1584,10 +1587,10 @@ fn first_message_on_recv_ordering() {
|
|||
check_added_monitors!(nodes[1], 1);
|
||||
|
||||
expect_pending_htlcs_forwardable!(nodes[1]);
|
||||
expect_payment_received!(nodes[1], payment_hash_2, 1000000);
|
||||
expect_payment_received!(nodes[1], payment_hash_2, payment_secret_2, 1000000);
|
||||
|
||||
claim_payment(&nodes[0], &[&nodes[1]], payment_preimage_1, 1_000_000);
|
||||
claim_payment(&nodes[0], &[&nodes[1]], payment_preimage_2, 1_000_000);
|
||||
claim_payment(&nodes[0], &[&nodes[1]], payment_preimage_1);
|
||||
claim_payment(&nodes[0], &[&nodes[1]], payment_preimage_2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -1606,19 +1609,19 @@ fn test_monitor_update_fail_claim() {
|
|||
let logger = test_utils::TestLogger::new();
|
||||
|
||||
// Rebalance a bit so that we can send backwards from 3 to 2.
|
||||
send_payment(&nodes[0], &[&nodes[1], &nodes[2]], 5000000, 5_000_000);
|
||||
send_payment(&nodes[0], &[&nodes[1], &nodes[2]], 5000000);
|
||||
|
||||
let (payment_preimage_1, _) = route_payment(&nodes[0], &[&nodes[1]], 1000000);
|
||||
let (payment_preimage_1, _, _) = route_payment(&nodes[0], &[&nodes[1]], 1000000);
|
||||
|
||||
*nodes[1].chain_monitor.update_ret.lock().unwrap() = Some(Err(ChannelMonitorUpdateErr::TemporaryFailure));
|
||||
assert!(nodes[1].node.claim_funds(payment_preimage_1, &None, 1_000_000));
|
||||
assert!(nodes[1].node.claim_funds(payment_preimage_1));
|
||||
check_added_monitors!(nodes[1], 1);
|
||||
|
||||
let (_, payment_hash_2) = get_payment_preimage_hash!(nodes[0]);
|
||||
let (_, payment_hash_2, payment_secret_2) = get_payment_preimage_hash!(nodes[0]);
|
||||
{
|
||||
let net_graph_msg_handler = &nodes[2].net_graph_msg_handler;
|
||||
let route = get_route(&nodes[2].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[0].node.get_our_node_id(), None, None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
|
||||
nodes[2].node.send_payment(&route, payment_hash_2, &None).unwrap();
|
||||
let route = get_route(&nodes[2].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[0].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
|
||||
nodes[2].node.send_payment(&route, payment_hash_2, &Some(payment_secret_2)).unwrap();
|
||||
check_added_monitors!(nodes[2], 1);
|
||||
}
|
||||
|
||||
|
@ -1687,10 +1690,10 @@ fn test_monitor_update_on_pending_forwards() {
|
|||
let logger = test_utils::TestLogger::new();
|
||||
|
||||
// Rebalance a bit so that we can send backwards from 3 to 1.
|
||||
send_payment(&nodes[0], &[&nodes[1], &nodes[2]], 5000000, 5_000_000);
|
||||
send_payment(&nodes[0], &[&nodes[1], &nodes[2]], 5000000);
|
||||
|
||||
let (_, payment_hash_1) = route_payment(&nodes[0], &[&nodes[1], &nodes[2]], 1000000);
|
||||
assert!(nodes[2].node.fail_htlc_backwards(&payment_hash_1, &None));
|
||||
let (_, payment_hash_1, _) = route_payment(&nodes[0], &[&nodes[1], &nodes[2]], 1000000);
|
||||
assert!(nodes[2].node.fail_htlc_backwards(&payment_hash_1));
|
||||
expect_pending_htlcs_forwardable!(nodes[2]);
|
||||
check_added_monitors!(nodes[2], 1);
|
||||
|
||||
|
@ -1699,11 +1702,11 @@ fn test_monitor_update_on_pending_forwards() {
|
|||
commitment_signed_dance!(nodes[1], nodes[2], cs_fail_update.commitment_signed, true, true);
|
||||
assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
|
||||
|
||||
let (payment_preimage_2, payment_hash_2) = get_payment_preimage_hash!(nodes[0]);
|
||||
let (payment_preimage_2, payment_hash_2, payment_secret_2) = get_payment_preimage_hash!(nodes[0]);
|
||||
{
|
||||
let net_graph_msg_handler = &nodes[2].net_graph_msg_handler;
|
||||
let route = get_route(&nodes[2].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[0].node.get_our_node_id(), None, None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
|
||||
nodes[2].node.send_payment(&route, payment_hash_2, &None).unwrap();
|
||||
let route = get_route(&nodes[2].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[0].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
|
||||
nodes[2].node.send_payment(&route, payment_hash_2, &Some(payment_secret_2)).unwrap();
|
||||
check_added_monitors!(nodes[2], 1);
|
||||
}
|
||||
|
||||
|
@ -1740,9 +1743,9 @@ fn test_monitor_update_on_pending_forwards() {
|
|||
_ => panic!("Unexpected event"),
|
||||
};
|
||||
nodes[0].node.process_pending_htlc_forwards();
|
||||
expect_payment_received!(nodes[0], payment_hash_2, 1000000);
|
||||
expect_payment_received!(nodes[0], payment_hash_2, payment_secret_2, 1000000);
|
||||
|
||||
claim_payment(&nodes[2], &[&nodes[1], &nodes[0]], payment_preimage_2, 1_000_000);
|
||||
claim_payment(&nodes[2], &[&nodes[1], &nodes[0]], payment_preimage_2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -1759,14 +1762,14 @@ fn monitor_update_claim_fail_no_response() {
|
|||
let logger = test_utils::TestLogger::new();
|
||||
|
||||
// Forward a payment for B to claim
|
||||
let (payment_preimage_1, _) = route_payment(&nodes[0], &[&nodes[1]], 1000000);
|
||||
let (payment_preimage_1, _, _) = route_payment(&nodes[0], &[&nodes[1]], 1000000);
|
||||
|
||||
// Now start forwarding a second payment, skipping the last RAA so B is in AwaitingRAA
|
||||
let (payment_preimage_2, payment_hash_2) = get_payment_preimage_hash!(nodes[0]);
|
||||
let (payment_preimage_2, payment_hash_2, payment_secret_2) = get_payment_preimage_hash!(nodes[1]);
|
||||
{
|
||||
let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
|
||||
let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), None, None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
|
||||
nodes[0].node.send_payment(&route, payment_hash_2, &None).unwrap();
|
||||
let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
|
||||
nodes[0].node.send_payment(&route, payment_hash_2, &Some(payment_secret_2)).unwrap();
|
||||
check_added_monitors!(nodes[0], 1);
|
||||
}
|
||||
|
||||
|
@ -1777,7 +1780,7 @@ fn monitor_update_claim_fail_no_response() {
|
|||
let as_raa = commitment_signed_dance!(nodes[1], nodes[0], payment_event.commitment_msg, false, true, false, true);
|
||||
|
||||
*nodes[1].chain_monitor.update_ret.lock().unwrap() = Some(Err(ChannelMonitorUpdateErr::TemporaryFailure));
|
||||
assert!(nodes[1].node.claim_funds(payment_preimage_1, &None, 1_000_000));
|
||||
assert!(nodes[1].node.claim_funds(payment_preimage_1));
|
||||
check_added_monitors!(nodes[1], 1);
|
||||
let events = nodes[1].node.get_and_clear_pending_msg_events();
|
||||
assert_eq!(events.len(), 0);
|
||||
|
@ -1792,7 +1795,7 @@ fn monitor_update_claim_fail_no_response() {
|
|||
nodes[1].node.handle_revoke_and_ack(&nodes[0].node.get_our_node_id(), &as_raa);
|
||||
check_added_monitors!(nodes[1], 1);
|
||||
expect_pending_htlcs_forwardable!(nodes[1]);
|
||||
expect_payment_received!(nodes[1], payment_hash_2, 1000000);
|
||||
expect_payment_received!(nodes[1], payment_hash_2, payment_secret_2, 1000000);
|
||||
|
||||
let bs_updates = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id());
|
||||
nodes[0].node.handle_update_fulfill_htlc(&nodes[1].node.get_our_node_id(), &bs_updates.update_fulfill_htlcs[0]);
|
||||
|
@ -1807,7 +1810,7 @@ fn monitor_update_claim_fail_no_response() {
|
|||
_ => panic!("Unexpected event"),
|
||||
}
|
||||
|
||||
claim_payment(&nodes[0], &[&nodes[1]], payment_preimage_2, 1_000_000);
|
||||
claim_payment(&nodes[0], &[&nodes[1]], payment_preimage_2);
|
||||
}
|
||||
|
||||
// confirm_a_first and restore_b_before_conf are wholly unrelated to earlier bools and
|
||||
|
@ -1897,7 +1900,7 @@ fn do_during_funding_monitor_fail(confirm_a_first: bool, restore_b_before_conf:
|
|||
node.net_graph_msg_handler.handle_channel_update(&bs_update).unwrap();
|
||||
}
|
||||
|
||||
send_payment(&nodes[0], &[&nodes[1]], 8000000, 8_000_000);
|
||||
send_payment(&nodes[0], &[&nodes[1]], 8000000);
|
||||
close_channel(&nodes[0], &nodes[1], &channel_id, funding_tx, true);
|
||||
}
|
||||
|
||||
|
@ -1923,9 +1926,8 @@ fn test_path_paused_mpp() {
|
|||
let chan_4_id = create_announced_chan_between_nodes(&nodes, 2, 3, InitFeatures::known(), InitFeatures::known()).0.contents.short_channel_id;
|
||||
let logger = test_utils::TestLogger::new();
|
||||
|
||||
let (payment_preimage, payment_hash) = get_payment_preimage_hash!(&nodes[0]);
|
||||
let payment_secret = PaymentSecret([0xdb; 32]);
|
||||
let mut route = get_route(&nodes[0].node.get_our_node_id(), &nodes[0].net_graph_msg_handler.network_graph.read().unwrap(), &nodes[3].node.get_our_node_id(), None, None, &[], 100000, TEST_FINAL_CLTV, &logger).unwrap();
|
||||
let (payment_preimage, payment_hash, payment_secret) = get_payment_preimage_hash!(&nodes[3]);
|
||||
let mut route = get_route(&nodes[0].node.get_our_node_id(), &nodes[0].net_graph_msg_handler.network_graph.read().unwrap(), &nodes[3].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 100000, TEST_FINAL_CLTV, &logger).unwrap();
|
||||
|
||||
// Set us up to take multiple routes, one 0 -> 1 -> 3 and one 0 -> 2 -> 3:
|
||||
let path = route.paths[0].clone();
|
||||
|
@ -1956,7 +1958,7 @@ fn test_path_paused_mpp() {
|
|||
// Pass the first HTLC of the payment along to nodes[3].
|
||||
let mut events = nodes[0].node.get_and_clear_pending_msg_events();
|
||||
assert_eq!(events.len(), 1);
|
||||
pass_along_path(&nodes[0], &[&nodes[1], &nodes[3]], 0, payment_hash.clone(), Some(payment_secret), events.pop().unwrap(), false);
|
||||
pass_along_path(&nodes[0], &[&nodes[1], &nodes[3]], 0, payment_hash.clone(), payment_secret, events.pop().unwrap(), false);
|
||||
|
||||
// And check that, after we successfully update the monitor for chan_2 we can pass the second
|
||||
// HTLC along to nodes[3] and claim the whole payment back to nodes[0].
|
||||
|
@ -1964,7 +1966,7 @@ fn test_path_paused_mpp() {
|
|||
nodes[0].node.channel_monitor_updated(&outpoint, latest_update);
|
||||
let mut events = nodes[0].node.get_and_clear_pending_msg_events();
|
||||
assert_eq!(events.len(), 1);
|
||||
pass_along_path(&nodes[0], &[&nodes[2], &nodes[3]], 200_000, payment_hash.clone(), Some(payment_secret), events.pop().unwrap(), true);
|
||||
pass_along_path(&nodes[0], &[&nodes[2], &nodes[3]], 200_000, payment_hash.clone(), payment_secret, events.pop().unwrap(), true);
|
||||
|
||||
claim_payment_along_route_with_secret(&nodes[0], &[&[&nodes[1], &nodes[3]], &[&nodes[2], &nodes[3]]], false, payment_preimage, Some(payment_secret), 200_000);
|
||||
claim_payment_along_route(&nodes[0], &[&[&nodes[1], &nodes[3]], &[&nodes[2], &nodes[3]]], false, payment_preimage);
|
||||
}
|
||||
|
|
|
@ -96,7 +96,7 @@ enum PendingHTLCRouting {
|
|||
short_channel_id: u64, // This should be NonZero<u64> eventually when we bump MSRV
|
||||
},
|
||||
Receive {
|
||||
payment_data: Option<msgs::FinalOnionHopData>,
|
||||
payment_data: msgs::FinalOnionHopData,
|
||||
incoming_cltv_expiry: u32, // Used to track when we should expire pending HTLCs that go unclaimed
|
||||
},
|
||||
}
|
||||
|
@ -156,11 +156,10 @@ pub(crate) struct HTLCPreviousHopData {
|
|||
struct ClaimableHTLC {
|
||||
prev_hop: HTLCPreviousHopData,
|
||||
value: u64,
|
||||
/// Filled in when the HTLC was received with a payment_secret packet, which contains a
|
||||
/// total_msat (which may differ from value if this is a Multi-Path Payment) and a
|
||||
/// Contains a total_msat (which may differ from value if this is a Multi-Path Payment) and a
|
||||
/// payment_secret which prevents path-probing attacks and can associate different HTLCs which
|
||||
/// are part of the same payment.
|
||||
payment_data: Option<msgs::FinalOnionHopData>,
|
||||
payment_data: msgs::FinalOnionHopData,
|
||||
cltv_expiry: u32,
|
||||
}
|
||||
|
||||
|
@ -327,12 +326,11 @@ pub(super) struct ChannelHolder<Signer: Sign> {
|
|||
/// guarantees are made about the existence of a channel with the short id here, nor the short
|
||||
/// ids in the PendingHTLCInfo!
|
||||
pub(super) forward_htlcs: HashMap<u64, Vec<HTLCForwardInfo>>,
|
||||
/// (payment_hash, payment_secret) -> Vec<HTLCs> for tracking HTLCs that
|
||||
/// were to us and can be failed/claimed by the user
|
||||
/// Map from payment hash to any HTLCs which are to us and can be failed/claimed by the user.
|
||||
/// Note that while this is held in the same mutex as the channels themselves, no consistency
|
||||
/// guarantees are made about the channels given here actually existing anymore by the time you
|
||||
/// go to read them!
|
||||
claimable_htlcs: HashMap<(PaymentHash, Option<PaymentSecret>), Vec<ClaimableHTLC>>,
|
||||
claimable_htlcs: HashMap<PaymentHash, Vec<ClaimableHTLC>>,
|
||||
/// Messages to send to peers - pushed to in the same lock that they are generated in (except
|
||||
/// for broadcast messages, where ordering isn't as strict).
|
||||
pub(super) pending_msg_events: Vec<MessageSendEvent>,
|
||||
|
@ -353,6 +351,24 @@ struct PeerState {
|
|||
latest_features: InitFeatures,
|
||||
}
|
||||
|
||||
/// Stores a PaymentSecret and any other data we may need to validate an inbound payment is
|
||||
/// actually ours and not some duplicate HTLC sent to us by a node along the route.
|
||||
///
|
||||
/// For users who don't want to bother doing their own payment preimage storage, we also store that
|
||||
/// here.
|
||||
struct PendingInboundPayment {
|
||||
/// The payment secret that the sender must use for us to accept this payment
|
||||
payment_secret: PaymentSecret,
|
||||
/// Time at which this HTLC expires - blocks with a header time above this value will result in
|
||||
/// this payment being removed.
|
||||
expiry_time: u64,
|
||||
/// Arbitrary identifier the user specifies (or not)
|
||||
user_payment_id: u64,
|
||||
// Other required attributes of the payment, optionally enforced:
|
||||
payment_preimage: Option<PaymentPreimage>,
|
||||
min_value_msat: Option<u64>,
|
||||
}
|
||||
|
||||
/// SimpleArcChannelManager is useful when you need a ChannelManager with a static lifetime, e.g.
|
||||
/// when you're using lightning-net-tokio (since tokio::spawn requires parameters with static
|
||||
/// lifetimes). Other times you can afford a reference, which is more efficient, in which case
|
||||
|
@ -431,6 +447,14 @@ pub struct ChannelManager<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref,
|
|||
pub(super) channel_state: Mutex<ChannelHolder<Signer>>,
|
||||
#[cfg(not(any(test, feature = "_test_utils")))]
|
||||
channel_state: Mutex<ChannelHolder<Signer>>,
|
||||
|
||||
/// Storage for PaymentSecrets and any requirements on future inbound payments before we will
|
||||
/// expose them to users via a PaymentReceived event. HTLCs which do not meet the requirements
|
||||
/// here are failed when we process them as pending-forwardable-HTLCs, and entries are removed
|
||||
/// after we generate a PaymentReceived upon receipt of all MPP parts or when they time out.
|
||||
/// Locked *after* channel_state.
|
||||
pending_inbound_payments: Mutex<HashMap<PaymentHash, PendingInboundPayment>>,
|
||||
|
||||
our_network_key: SecretKey,
|
||||
our_network_pubkey: PublicKey,
|
||||
|
||||
|
@ -438,6 +462,11 @@ pub struct ChannelManager<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref,
|
|||
/// value increases strictly since we don't assume access to a time source.
|
||||
last_node_announcement_serial: AtomicUsize,
|
||||
|
||||
/// The highest block timestamp we've seen, which is usually a good guess at the current time.
|
||||
/// Assuming most miners are generating blocks with reasonable timestamps, this shouldn't be
|
||||
/// very far in the past, and can only ever be up to two hours in the future.
|
||||
highest_seen_timestamp: AtomicUsize,
|
||||
|
||||
/// The bulk of our storage will eventually be here (channels and message queues and the like).
|
||||
/// If we are connected to a peer we always at least have an entry here, even if no channels
|
||||
/// are currently open with that peer.
|
||||
|
@ -559,6 +588,11 @@ pub(crate) const MAX_LOCAL_BREAKDOWN_TIMEOUT: u16 = 2 * 6 * 24 * 7;
|
|||
pub const MIN_CLTV_EXPIRY_DELTA: u16 = 6 * 6;
|
||||
pub(super) const CLTV_FAR_FAR_AWAY: u32 = 6 * 24 * 7; //TODO?
|
||||
|
||||
/// Minimum CLTV difference between the current block height and received inbound payments.
|
||||
/// Invoices generated for payment to us must set their `min_final_cltv_expiry` field to at least
|
||||
/// this value.
|
||||
pub const MIN_FINAL_CLTV_EXPIRY: u32 = HTLC_FAIL_BACK_BUFFER;
|
||||
|
||||
// Check that our CLTV_EXPIRY is at least CLTV_CLAIM_BUFFER + ANTI_REORG_DELAY + LATENCY_GRACE_PERIOD_BLOCKS,
|
||||
// ie that if the next-hop peer fails the HTLC within
|
||||
// LATENCY_GRACE_PERIOD_BLOCKS then we'll still have CLTV_CLAIM_BUFFER left to timeout it onchain,
|
||||
|
@ -853,11 +887,14 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
|
|||
claimable_htlcs: HashMap::new(),
|
||||
pending_msg_events: Vec::new(),
|
||||
}),
|
||||
pending_inbound_payments: Mutex::new(HashMap::new()),
|
||||
|
||||
our_network_key: keys_manager.get_node_secret(),
|
||||
our_network_pubkey: PublicKey::from_secret_key(&secp_ctx, &keys_manager.get_node_secret()),
|
||||
secp_ctx,
|
||||
|
||||
last_node_announcement_serial: AtomicUsize::new(0),
|
||||
highest_seen_timestamp: AtomicUsize::new(0),
|
||||
|
||||
per_peer_state: RwLock::new(HashMap::new()),
|
||||
|
||||
|
@ -1215,6 +1252,10 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
|
|||
msgs::OnionHopDataFormat::FinalNode { payment_data } => payment_data,
|
||||
};
|
||||
|
||||
if payment_data.is_none() {
|
||||
return_err!("We require payment_secrets", 0x4000|0x2000|3, &[0;0]);
|
||||
}
|
||||
|
||||
// Note that we could obviously respond immediately with an update_fulfill_htlc
|
||||
// message, however that would leak that we are the recipient of this payment, so
|
||||
// instead we stay symmetric with the forwarding case, only responding (after a
|
||||
|
@ -1222,7 +1263,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
|
|||
|
||||
PendingHTLCStatus::Forward(PendingHTLCInfo {
|
||||
routing: PendingHTLCRouting::Receive {
|
||||
payment_data,
|
||||
payment_data: payment_data.unwrap(),
|
||||
incoming_cltv_expiry: msg.cltv_expiry,
|
||||
},
|
||||
payment_hash: msg.payment_hash.clone(),
|
||||
|
@ -1916,61 +1957,95 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
|
|||
routing: PendingHTLCRouting::Receive { payment_data, incoming_cltv_expiry },
|
||||
incoming_shared_secret, payment_hash, amt_to_forward, .. },
|
||||
prev_funding_outpoint } => {
|
||||
let prev_hop = HTLCPreviousHopData {
|
||||
let claimable_htlc = ClaimableHTLC {
|
||||
prev_hop: HTLCPreviousHopData {
|
||||
short_channel_id: prev_short_channel_id,
|
||||
outpoint: prev_funding_outpoint,
|
||||
htlc_id: prev_htlc_id,
|
||||
incoming_packet_shared_secret: incoming_shared_secret,
|
||||
};
|
||||
|
||||
let mut total_value = 0;
|
||||
let payment_secret_opt =
|
||||
if let &Some(ref data) = &payment_data { Some(data.payment_secret.clone()) } else { None };
|
||||
let htlcs = channel_state.claimable_htlcs.entry((payment_hash, payment_secret_opt))
|
||||
.or_insert(Vec::new());
|
||||
htlcs.push(ClaimableHTLC {
|
||||
prev_hop,
|
||||
},
|
||||
value: amt_to_forward,
|
||||
payment_data: payment_data.clone(),
|
||||
cltv_expiry: incoming_cltv_expiry,
|
||||
});
|
||||
if let &Some(ref data) = &payment_data {
|
||||
for htlc in htlcs.iter() {
|
||||
total_value += htlc.value;
|
||||
if htlc.payment_data.as_ref().unwrap().total_msat != data.total_msat {
|
||||
total_value = msgs::MAX_VALUE_MSAT;
|
||||
}
|
||||
if total_value >= msgs::MAX_VALUE_MSAT { break; }
|
||||
}
|
||||
if total_value >= msgs::MAX_VALUE_MSAT || total_value > data.total_msat {
|
||||
for htlc in htlcs.iter() {
|
||||
let mut htlc_msat_height_data = byte_utils::be64_to_array(htlc.value).to_vec();
|
||||
};
|
||||
|
||||
macro_rules! fail_htlc {
|
||||
($htlc: expr) => {
|
||||
let mut htlc_msat_height_data = byte_utils::be64_to_array($htlc.value).to_vec();
|
||||
htlc_msat_height_data.extend_from_slice(
|
||||
&byte_utils::be32_to_array(self.best_block.read().unwrap().height()),
|
||||
);
|
||||
failed_forwards.push((HTLCSource::PreviousHopData(HTLCPreviousHopData {
|
||||
short_channel_id: htlc.prev_hop.short_channel_id,
|
||||
short_channel_id: $htlc.prev_hop.short_channel_id,
|
||||
outpoint: prev_funding_outpoint,
|
||||
htlc_id: htlc.prev_hop.htlc_id,
|
||||
incoming_packet_shared_secret: htlc.prev_hop.incoming_packet_shared_secret,
|
||||
htlc_id: $htlc.prev_hop.htlc_id,
|
||||
incoming_packet_shared_secret: $htlc.prev_hop.incoming_packet_shared_secret,
|
||||
}), payment_hash,
|
||||
HTLCFailReason::Reason { failure_code: 0x4000 | 15, data: htlc_msat_height_data }
|
||||
));
|
||||
}
|
||||
} else if total_value == data.total_msat {
|
||||
new_events.push(events::Event::PaymentReceived {
|
||||
payment_hash,
|
||||
payment_secret: Some(data.payment_secret),
|
||||
amt: total_value,
|
||||
});
|
||||
}
|
||||
|
||||
// Check that the payment hash and secret are known. Note that we
|
||||
// MUST take care to handle the "unknown payment hash" and
|
||||
// "incorrect payment secret" cases here identically or we'd expose
|
||||
// that we are the ultimate recipient of the given payment hash.
|
||||
// Further, we must not expose whether we have any other HTLCs
|
||||
// associated with the same payment_hash pending or not.
|
||||
let mut payment_secrets = self.pending_inbound_payments.lock().unwrap();
|
||||
match payment_secrets.entry(payment_hash) {
|
||||
hash_map::Entry::Vacant(_) => {
|
||||
log_trace!(self.logger, "Failing new HTLC with payment_hash {} as we didn't have a corresponding inbound payment.", log_bytes!(payment_hash.0));
|
||||
fail_htlc!(claimable_htlc);
|
||||
},
|
||||
hash_map::Entry::Occupied(inbound_payment) => {
|
||||
if inbound_payment.get().payment_secret != payment_data.payment_secret {
|
||||
log_trace!(self.logger, "Failing new HTLC with payment_hash {} as it didn't match our expected payment secret.", log_bytes!(payment_hash.0));
|
||||
fail_htlc!(claimable_htlc);
|
||||
} else if inbound_payment.get().min_value_msat.is_some() && payment_data.total_msat < inbound_payment.get().min_value_msat.unwrap() {
|
||||
log_trace!(self.logger, "Failing new HTLC with payment_hash {} as it didn't match our minimum value (had {}, needed {}).",
|
||||
log_bytes!(payment_hash.0), payment_data.total_msat, inbound_payment.get().min_value_msat.unwrap());
|
||||
fail_htlc!(claimable_htlc);
|
||||
} else {
|
||||
let mut total_value = 0;
|
||||
let htlcs = channel_state.claimable_htlcs.entry(payment_hash)
|
||||
.or_insert(Vec::new());
|
||||
htlcs.push(claimable_htlc);
|
||||
for htlc in htlcs.iter() {
|
||||
total_value += htlc.value;
|
||||
if htlc.payment_data.total_msat != payment_data.total_msat {
|
||||
log_trace!(self.logger, "Failing HTLCs with payment_hash {} as the HTLCs had inconsistent total values (eg {} and {})",
|
||||
log_bytes!(payment_hash.0), payment_data.total_msat, htlc.payment_data.total_msat);
|
||||
total_value = msgs::MAX_VALUE_MSAT;
|
||||
}
|
||||
if total_value >= msgs::MAX_VALUE_MSAT { break; }
|
||||
}
|
||||
if total_value >= msgs::MAX_VALUE_MSAT || total_value > payment_data.total_msat {
|
||||
log_trace!(self.logger, "Failing HTLCs with payment_hash {} as the total value {} ran over expected value {} (or HTLCs were inconsistent)",
|
||||
log_bytes!(payment_hash.0), total_value, payment_data.total_msat);
|
||||
for htlc in htlcs.iter() {
|
||||
fail_htlc!(htlc);
|
||||
}
|
||||
} else if total_value == payment_data.total_msat {
|
||||
new_events.push(events::Event::PaymentReceived {
|
||||
payment_hash,
|
||||
payment_secret: None,
|
||||
amt: amt_to_forward,
|
||||
payment_preimage: inbound_payment.get().payment_preimage,
|
||||
payment_secret: payment_data.payment_secret,
|
||||
amt: total_value,
|
||||
user_payment_id: inbound_payment.get().user_payment_id,
|
||||
});
|
||||
// Only ever generate at most one PaymentReceived
|
||||
// per registered payment_hash, even if it isn't
|
||||
// claimed.
|
||||
inbound_payment.remove_entry();
|
||||
} else {
|
||||
// Nothing to do - we haven't reached the total
|
||||
// payment value yet, wait until we receive more
|
||||
// MPP parts.
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
HTLCForwardInfo::AddHTLC { .. } => {
|
||||
panic!("short_channel_id == 0 should imply any pending_forward entries are of type Receive");
|
||||
|
@ -2056,11 +2131,11 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
|
|||
/// along the path (including in our own channel on which we received it).
|
||||
/// Returns false if no payment was found to fail backwards, true if the process of failing the
|
||||
/// HTLC backwards has been started.
|
||||
pub fn fail_htlc_backwards(&self, payment_hash: &PaymentHash, payment_secret: &Option<PaymentSecret>) -> bool {
|
||||
pub fn fail_htlc_backwards(&self, payment_hash: &PaymentHash) -> bool {
|
||||
let _persistence_guard = PersistenceNotifierGuard::new(&self.total_consistency_lock, &self.persistence_notifier);
|
||||
|
||||
let mut channel_state = Some(self.channel_state.lock().unwrap());
|
||||
let removed_source = channel_state.as_mut().unwrap().claimable_htlcs.remove(&(*payment_hash, *payment_secret));
|
||||
let removed_source = channel_state.as_mut().unwrap().claimable_htlcs.remove(payment_hash);
|
||||
if let Some(mut sources) = removed_source {
|
||||
for htlc in sources.drain(..) {
|
||||
if channel_state.is_none() { channel_state = Some(self.channel_state.lock().unwrap()); }
|
||||
|
@ -2225,24 +2300,22 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
|
|||
/// generating message events for the net layer to claim the payment, if possible. Thus, you
|
||||
/// should probably kick the net layer to go send messages if this returns true!
|
||||
///
|
||||
/// You must specify the expected amounts for this HTLC, and we will only claim HTLCs
|
||||
/// available within a few percent of the expected amount. This is critical for several
|
||||
/// reasons : a) it avoids providing senders with `proof-of-payment` (in the form of the
|
||||
/// payment_preimage without having provided the full value and b) it avoids certain
|
||||
/// privacy-breaking recipient-probing attacks which may reveal payment activity to
|
||||
/// motivated attackers.
|
||||
///
|
||||
/// Note that the privacy concerns in (b) are not relevant in payments with a payment_secret
|
||||
/// set. Thus, for such payments we will claim any payments which do not under-pay.
|
||||
/// Note that if you did not set an `amount_msat` when calling [`create_inbound_payment`] or
|
||||
/// [`create_inbound_payment_for_hash`] you must check that the amount in the `PaymentReceived`
|
||||
/// event matches your expectation. If you fail to do so and call this method, you may provide
|
||||
/// the sender "proof-of-payment" when they did not fulfill the full expected payment.
|
||||
///
|
||||
/// May panic if called except in response to a PaymentReceived event.
|
||||
pub fn claim_funds(&self, payment_preimage: PaymentPreimage, payment_secret: &Option<PaymentSecret>, expected_amount: u64) -> bool {
|
||||
///
|
||||
/// [`create_inbound_payment`]: Self::create_inbound_payment
|
||||
/// [`create_inbound_payment_for_hash`]: Self::create_inbound_payment_for_hash
|
||||
pub fn claim_funds(&self, payment_preimage: PaymentPreimage) -> bool {
|
||||
let payment_hash = PaymentHash(Sha256::hash(&payment_preimage.0).into_inner());
|
||||
|
||||
let _persistence_guard = PersistenceNotifierGuard::new(&self.total_consistency_lock, &self.persistence_notifier);
|
||||
|
||||
let mut channel_state = Some(self.channel_state.lock().unwrap());
|
||||
let removed_source = channel_state.as_mut().unwrap().claimable_htlcs.remove(&(payment_hash, *payment_secret));
|
||||
let removed_source = channel_state.as_mut().unwrap().claimable_htlcs.remove(&payment_hash);
|
||||
if let Some(mut sources) = removed_source {
|
||||
assert!(!sources.is_empty());
|
||||
|
||||
|
@ -2257,27 +2330,19 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
|
|||
// we got all the HTLCs and then a channel closed while we were waiting for the user to
|
||||
// provide the preimage, so worrying too much about the optimal handling isn't worth
|
||||
// it.
|
||||
|
||||
let (is_mpp, mut valid_mpp) = if let &Some(ref data) = &sources[0].payment_data {
|
||||
assert!(payment_secret.is_some());
|
||||
(true, data.total_msat >= expected_amount)
|
||||
} else {
|
||||
assert!(payment_secret.is_none());
|
||||
(false, false)
|
||||
};
|
||||
|
||||
let mut valid_mpp = true;
|
||||
for htlc in sources.iter() {
|
||||
if !is_mpp || !valid_mpp { break; }
|
||||
if let None = channel_state.as_ref().unwrap().short_to_id.get(&htlc.prev_hop.short_channel_id) {
|
||||
valid_mpp = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
let mut errs = Vec::new();
|
||||
let mut claimed_any_htlcs = false;
|
||||
for htlc in sources.drain(..) {
|
||||
if !valid_mpp {
|
||||
if channel_state.is_none() { channel_state = Some(self.channel_state.lock().unwrap()); }
|
||||
if (is_mpp && !valid_mpp) || (!is_mpp && (htlc.value < expected_amount || htlc.value > expected_amount * 2)) {
|
||||
let mut htlc_msat_height_data = byte_utils::be64_to_array(htlc.value).to_vec();
|
||||
htlc_msat_height_data.extend_from_slice(&byte_utils::be32_to_array(
|
||||
self.best_block.read().unwrap().height()));
|
||||
|
@ -2294,10 +2359,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
|
|||
claimed_any_htlcs = true;
|
||||
} else { errs.push(e); }
|
||||
},
|
||||
Err(None) if is_mpp => unreachable!("We already checked for channel existence, we can't fail here!"),
|
||||
Err(None) => {
|
||||
log_warn!(self.logger, "Channel we expected to claim an HTLC from was closed.");
|
||||
},
|
||||
Err(None) => unreachable!("We already checked for channel existence, we can't fail here!"),
|
||||
Ok(()) => claimed_any_htlcs = true,
|
||||
}
|
||||
}
|
||||
|
@ -3321,6 +3383,102 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
|
|||
self.finish_force_close_channel(failure);
|
||||
}
|
||||
}
|
||||
|
||||
fn set_payment_hash_secret_map(&self, payment_hash: PaymentHash, payment_preimage: Option<PaymentPreimage>, min_value_msat: Option<u64>, invoice_expiry_delta_secs: u32, user_payment_id: u64) -> Result<PaymentSecret, APIError> {
|
||||
assert!(invoice_expiry_delta_secs <= 60*60*24*365); // Sadly bitcoin timestamps are u32s, so panic before 2106
|
||||
|
||||
let payment_secret = PaymentSecret(self.keys_manager.get_secure_random_bytes());
|
||||
|
||||
let _persistence_guard = PersistenceNotifierGuard::new(&self.total_consistency_lock, &self.persistence_notifier);
|
||||
let mut payment_secrets = self.pending_inbound_payments.lock().unwrap();
|
||||
match payment_secrets.entry(payment_hash) {
|
||||
hash_map::Entry::Vacant(e) => {
|
||||
e.insert(PendingInboundPayment {
|
||||
payment_secret, min_value_msat, user_payment_id, payment_preimage,
|
||||
// We assume that highest_seen_timestamp is pretty close to the current time -
|
||||
// its updated when we receive a new block with the maximum time we've seen in
|
||||
// a header. It should never be more than two hours in the future.
|
||||
// Thus, we add two hours here as a buffer to ensure we absolutely
|
||||
// never fail a payment too early.
|
||||
// Note that we assume that received blocks have reasonably up-to-date
|
||||
// timestamps.
|
||||
expiry_time: self.highest_seen_timestamp.load(Ordering::Acquire) as u64 + invoice_expiry_delta_secs as u64 + 7200,
|
||||
});
|
||||
},
|
||||
hash_map::Entry::Occupied(_) => return Err(APIError::APIMisuseError { err: "Duplicate payment hash".to_owned() }),
|
||||
}
|
||||
Ok(payment_secret)
|
||||
}
|
||||
|
||||
/// Gets a payment secret and payment hash for use in an invoice given to a third party wishing
|
||||
/// to pay us.
|
||||
///
|
||||
/// This differs from [`create_inbound_payment_for_hash`] only in that it generates the
|
||||
/// [`PaymentHash`] and [`PaymentPreimage`] for you, returning the first and storing the second.
|
||||
///
|
||||
/// The [`PaymentPreimage`] will ultimately be returned to you in the [`PaymentReceived`], which
|
||||
/// will have the [`PaymentReceived::payment_preimage`] field filled in. That should then be
|
||||
/// passed directly to [`claim_funds`].
|
||||
///
|
||||
/// See [`create_inbound_payment_for_hash`] for detailed documentation on behavior and requirements.
|
||||
///
|
||||
/// [`claim_funds`]: Self::claim_funds
|
||||
/// [`PaymentReceived`]: events::Event::PaymentReceived
|
||||
/// [`PaymentReceived::payment_preimage`]: events::Event::PaymentReceived::payment_preimage
|
||||
/// [`create_inbound_payment_for_hash`]: Self::create_inbound_payment_for_hash
|
||||
pub fn create_inbound_payment(&self, min_value_msat: Option<u64>, invoice_expiry_delta_secs: u32, user_payment_id: u64) -> (PaymentHash, PaymentSecret) {
|
||||
let payment_preimage = PaymentPreimage(self.keys_manager.get_secure_random_bytes());
|
||||
let payment_hash = PaymentHash(Sha256::hash(&payment_preimage.0).into_inner());
|
||||
|
||||
(payment_hash,
|
||||
self.set_payment_hash_secret_map(payment_hash, Some(payment_preimage), min_value_msat, invoice_expiry_delta_secs, user_payment_id)
|
||||
.expect("RNG Generated Duplicate PaymentHash"))
|
||||
}
|
||||
|
||||
/// Gets a [`PaymentSecret`] for a given [`PaymentHash`], for which the payment preimage is
|
||||
/// stored external to LDK.
|
||||
///
|
||||
/// A [`PaymentReceived`] event will only be generated if the [`PaymentSecret`] matches a
|
||||
/// payment secret fetched via this method or [`create_inbound_payment`], and which is at least
|
||||
/// the `min_value_msat` provided here, if one is provided.
|
||||
///
|
||||
/// The [`PaymentHash`] (and corresponding [`PaymentPreimage`]) must be globally unique. This
|
||||
/// method may return an Err if another payment with the same payment_hash is still pending.
|
||||
///
|
||||
/// `user_payment_id` will be provided back in [`PaymentReceived::user_payment_id`] events to
|
||||
/// allow tracking of which events correspond with which calls to this and
|
||||
/// [`create_inbound_payment`]. `user_payment_id` has no meaning inside of LDK, it is simply
|
||||
/// copied to events and otherwise ignored. It may be used to correlate PaymentReceived events
|
||||
/// with invoice metadata stored elsewhere.
|
||||
///
|
||||
/// `min_value_msat` should be set if the invoice being generated contains a value. Any payment
|
||||
/// received for the returned [`PaymentHash`] will be required to be at least `min_value_msat`
|
||||
/// before a [`PaymentReceived`] event will be generated, ensuring that we do not provide the
|
||||
/// sender "proof-of-payment" unless they have paid the required amount.
|
||||
///
|
||||
/// `invoice_expiry_delta_secs` describes the number of seconds that the invoice is valid for
|
||||
/// in excess of the current time. This should roughly match the expiry time set in the invoice.
|
||||
/// After this many seconds, we will remove the inbound payment, resulting in any attempts to
|
||||
/// pay the invoice failing. The BOLT spec suggests 7,200 secs as a default validity time for
|
||||
/// invoices when no timeout is set.
|
||||
///
|
||||
/// Note that we use block header time to time-out pending inbound payments (with some margin
|
||||
/// to compensate for the inaccuracy of block header timestamps). Thus, in practice we will
|
||||
/// accept a payment and generate a [`PaymentReceived`] event for some time after the expiry.
|
||||
/// If you need exact expiry semantics, you should enforce them upon receipt of
|
||||
/// [`PaymentReceived`].
|
||||
///
|
||||
/// May panic if `invoice_expiry_delta_secs` is greater than one year.
|
||||
///
|
||||
/// Note that invoices generated for inbound payments should have their `min_final_cltv_expiry`
|
||||
/// set to at least [`MIN_FINAL_CLTV_EXPIRY`].
|
||||
///
|
||||
/// [`create_inbound_payment`]: Self::create_inbound_payment
|
||||
/// [`PaymentReceived`]: events::Event::PaymentReceived
|
||||
/// [`PaymentReceived::user_payment_id`]: events::Event::PaymentReceived::user_payment_id
|
||||
pub fn create_inbound_payment_for_hash(&self, payment_hash: PaymentHash, min_value_msat: Option<u64>, invoice_expiry_delta_secs: u32, user_payment_id: u64) -> Result<PaymentSecret, APIError> {
|
||||
self.set_payment_hash_secret_map(payment_hash, None, min_value_msat, invoice_expiry_delta_secs, user_payment_id)
|
||||
}
|
||||
}
|
||||
|
||||
impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> MessageSendEventsProvider for ChannelManager<Signer, M, T, K, F, L>
|
||||
|
@ -3433,19 +3591,29 @@ where
|
|||
|
||||
self.do_chain_event(Some(height), |channel| channel.best_block_updated(height, header.time));
|
||||
|
||||
macro_rules! max_time {
|
||||
($timestamp: expr) => {
|
||||
loop {
|
||||
// Update last_node_announcement_serial to be the max of its current value and the
|
||||
// block timestamp. This should keep us close to the current time without relying on
|
||||
// Update $timestamp to be the max of its current value and the block
|
||||
// timestamp. This should keep us close to the current time without relying on
|
||||
// having an explicit local time source.
|
||||
// Just in case we end up in a race, we loop until we either successfully update
|
||||
// last_node_announcement_serial or decide we don't need to.
|
||||
let old_serial = self.last_node_announcement_serial.load(Ordering::Acquire);
|
||||
// Just in case we end up in a race, we loop until we either successfully
|
||||
// update $timestamp or decide we don't need to.
|
||||
let old_serial = $timestamp.load(Ordering::Acquire);
|
||||
if old_serial >= header.time as usize { break; }
|
||||
if self.last_node_announcement_serial.compare_exchange(old_serial, header.time as usize, Ordering::AcqRel, Ordering::Relaxed).is_ok() {
|
||||
if $timestamp.compare_exchange(old_serial, header.time as usize, Ordering::AcqRel, Ordering::Relaxed).is_ok() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
max_time!(self.last_node_announcement_serial);
|
||||
max_time!(self.highest_seen_timestamp);
|
||||
let mut payment_secrets = self.pending_inbound_payments.lock().unwrap();
|
||||
payment_secrets.retain(|_, inbound_payment| {
|
||||
inbound_payment.expiry_time > header.time as u64
|
||||
});
|
||||
}
|
||||
|
||||
fn get_relevant_txids(&self) -> Vec<Txid> {
|
||||
let channel_state = self.channel_state.lock().unwrap();
|
||||
|
@ -3542,7 +3710,7 @@ where
|
|||
});
|
||||
|
||||
if let Some(height) = height_opt {
|
||||
channel_state.claimable_htlcs.retain(|&(ref payment_hash, _), htlcs| {
|
||||
channel_state.claimable_htlcs.retain(|payment_hash, htlcs| {
|
||||
htlcs.retain(|htlc| {
|
||||
// If height is approaching the number of blocks we think it takes us to get
|
||||
// our commitment transaction confirmed before the HTLC expires, plus the
|
||||
|
@ -3916,7 +4084,8 @@ impl Writeable for PendingHTLCInfo {
|
|||
},
|
||||
&PendingHTLCRouting::Receive { ref payment_data, ref incoming_cltv_expiry } => {
|
||||
1u8.write(writer)?;
|
||||
payment_data.write(writer)?;
|
||||
payment_data.payment_secret.write(writer)?;
|
||||
payment_data.total_msat.write(writer)?;
|
||||
incoming_cltv_expiry.write(writer)?;
|
||||
},
|
||||
}
|
||||
|
@ -3937,7 +4106,10 @@ impl Readable for PendingHTLCInfo {
|
|||
short_channel_id: Readable::read(reader)?,
|
||||
},
|
||||
1u8 => PendingHTLCRouting::Receive {
|
||||
payment_data: Readable::read(reader)?,
|
||||
payment_data: msgs::FinalOnionHopData {
|
||||
payment_secret: Readable::read(reader)?,
|
||||
total_msat: Readable::read(reader)?,
|
||||
},
|
||||
incoming_cltv_expiry: Readable::read(reader)?,
|
||||
},
|
||||
_ => return Err(DecodeError::InvalidValue),
|
||||
|
@ -4009,12 +4181,29 @@ impl_writeable!(HTLCPreviousHopData, 0, {
|
|||
incoming_packet_shared_secret
|
||||
});
|
||||
|
||||
impl_writeable!(ClaimableHTLC, 0, {
|
||||
prev_hop,
|
||||
value,
|
||||
payment_data,
|
||||
cltv_expiry
|
||||
});
|
||||
impl Writeable for ClaimableHTLC {
|
||||
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), ::std::io::Error> {
|
||||
self.prev_hop.write(writer)?;
|
||||
self.value.write(writer)?;
|
||||
self.payment_data.payment_secret.write(writer)?;
|
||||
self.payment_data.total_msat.write(writer)?;
|
||||
self.cltv_expiry.write(writer)
|
||||
}
|
||||
}
|
||||
|
||||
impl Readable for ClaimableHTLC {
|
||||
fn read<R: ::std::io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
|
||||
Ok(ClaimableHTLC {
|
||||
prev_hop: Readable::read(reader)?,
|
||||
value: Readable::read(reader)?,
|
||||
payment_data: msgs::FinalOnionHopData {
|
||||
payment_secret: Readable::read(reader)?,
|
||||
total_msat: Readable::read(reader)?,
|
||||
},
|
||||
cltv_expiry: Readable::read(reader)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Writeable for HTLCSource {
|
||||
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), ::std::io::Error> {
|
||||
|
@ -4116,6 +4305,14 @@ impl Readable for HTLCForwardInfo {
|
|||
}
|
||||
}
|
||||
|
||||
impl_writeable!(PendingInboundPayment, 0, {
|
||||
payment_secret,
|
||||
expiry_time,
|
||||
user_payment_id,
|
||||
payment_preimage,
|
||||
min_value_msat
|
||||
});
|
||||
|
||||
impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> Writeable for ChannelManager<Signer, M, T, K, F, L>
|
||||
where M::Target: chain::Watch<Signer>,
|
||||
T::Target: BroadcasterInterface,
|
||||
|
@ -4195,6 +4392,14 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> Writeable f
|
|||
}
|
||||
|
||||
(self.last_node_announcement_serial.load(Ordering::Acquire) as u32).write(writer)?;
|
||||
(self.highest_seen_timestamp.load(Ordering::Acquire) as u32).write(writer)?;
|
||||
|
||||
let pending_inbound_payments = self.pending_inbound_payments.lock().unwrap();
|
||||
(pending_inbound_payments.len() as u64).write(writer)?;
|
||||
for (hash, pending_payment) in pending_inbound_payments.iter() {
|
||||
hash.write(writer)?;
|
||||
pending_payment.write(writer)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -4425,6 +4630,15 @@ impl<'a, Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
|
|||
}
|
||||
|
||||
let last_node_announcement_serial: u32 = Readable::read(reader)?;
|
||||
let highest_seen_timestamp: u32 = Readable::read(reader)?;
|
||||
|
||||
let pending_inbound_payment_count: u64 = Readable::read(reader)?;
|
||||
let mut pending_inbound_payments: HashMap<PaymentHash, PendingInboundPayment> = HashMap::with_capacity(cmp::min(pending_inbound_payment_count as usize, MAX_ALLOC_SIZE/(3*32)));
|
||||
for _ in 0..pending_inbound_payment_count {
|
||||
if pending_inbound_payments.insert(Readable::read(reader)?, Readable::read(reader)?).is_some() {
|
||||
return Err(DecodeError::InvalidValue);
|
||||
}
|
||||
}
|
||||
|
||||
let mut secp_ctx = Secp256k1::new();
|
||||
secp_ctx.seeded_randomize(&args.keys_manager.get_secure_random_bytes());
|
||||
|
@ -4444,11 +4658,14 @@ impl<'a, Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
|
|||
claimable_htlcs,
|
||||
pending_msg_events: Vec::new(),
|
||||
}),
|
||||
pending_inbound_payments: Mutex::new(pending_inbound_payments),
|
||||
|
||||
our_network_key: args.keys_manager.get_node_secret(),
|
||||
our_network_pubkey: PublicKey::from_secret_key(&secp_ctx, &args.keys_manager.get_node_secret()),
|
||||
secp_ctx,
|
||||
|
||||
last_node_announcement_serial: AtomicUsize::new(last_node_announcement_serial as usize),
|
||||
highest_seen_timestamp: AtomicUsize::new(highest_seen_timestamp as usize),
|
||||
|
||||
per_peer_state: RwLock::new(per_peer_state),
|
||||
|
||||
|
@ -4531,7 +4748,7 @@ pub mod bench {
|
|||
use chain::channelmonitor::Persist;
|
||||
use chain::keysinterface::{KeysManager, InMemorySigner};
|
||||
use ln::channelmanager::{BestBlock, ChainParameters, ChannelManager, PaymentHash, PaymentPreimage};
|
||||
use ln::features::InitFeatures;
|
||||
use ln::features::{InitFeatures, InvoiceFeatures};
|
||||
use ln::functional_test_utils::*;
|
||||
use ln::msgs::ChannelMessageHandler;
|
||||
use routing::network_graph::NetworkGraph;
|
||||
|
@ -4625,15 +4842,20 @@ pub mod bench {
|
|||
|
||||
let dummy_graph = NetworkGraph::new(genesis_hash);
|
||||
|
||||
let mut payment_count: u64 = 0;
|
||||
macro_rules! send_payment {
|
||||
($node_a: expr, $node_b: expr) => {
|
||||
let usable_channels = $node_a.list_usable_channels();
|
||||
let route = get_route(&$node_a.get_our_node_id(), &dummy_graph, &$node_b.get_our_node_id(), None, Some(&usable_channels.iter().map(|r| r).collect::<Vec<_>>()), &[], 10_000, TEST_FINAL_CLTV, &logger_a).unwrap();
|
||||
let route = get_route(&$node_a.get_our_node_id(), &dummy_graph, &$node_b.get_our_node_id(), Some(InvoiceFeatures::known()),
|
||||
Some(&usable_channels.iter().map(|r| r).collect::<Vec<_>>()), &[], 10_000, TEST_FINAL_CLTV, &logger_a).unwrap();
|
||||
|
||||
let payment_preimage = PaymentPreimage([0; 32]);
|
||||
let mut payment_preimage = PaymentPreimage([0; 32]);
|
||||
payment_preimage.0[0..8].copy_from_slice(&payment_count.to_le_bytes());
|
||||
payment_count += 1;
|
||||
let payment_hash = PaymentHash(Sha256::hash(&payment_preimage.0[..]).into_inner());
|
||||
let payment_secret = $node_b.create_inbound_payment_for_hash(payment_hash, None, 7200, 0).unwrap();
|
||||
|
||||
$node_a.send_payment(&route, payment_hash, &None).unwrap();
|
||||
$node_a.send_payment(&route, payment_hash, &Some(payment_secret)).unwrap();
|
||||
let payment_event = SendEvent::from_event($node_a.get_and_clear_pending_msg_events().pop().unwrap());
|
||||
$node_b.handle_update_add_htlc(&$node_a.get_our_node_id(), &payment_event.msgs[0]);
|
||||
$node_b.handle_commitment_signed(&$node_a.get_our_node_id(), &payment_event.commitment_msg);
|
||||
|
@ -4643,8 +4865,8 @@ pub mod bench {
|
|||
$node_b.handle_revoke_and_ack(&$node_a.get_our_node_id(), &get_event_msg!(NodeHolder { node: &$node_a }, MessageSendEvent::SendRevokeAndACK, $node_b.get_our_node_id()));
|
||||
|
||||
expect_pending_htlcs_forwardable!(NodeHolder { node: &$node_b });
|
||||
expect_payment_received!(NodeHolder { node: &$node_b }, payment_hash, 10_000);
|
||||
assert!($node_b.claim_funds(payment_preimage, &None, 10_000));
|
||||
expect_payment_received!(NodeHolder { node: &$node_b }, payment_hash, payment_secret, 10_000);
|
||||
assert!($node_b.claim_funds(payment_preimage));
|
||||
|
||||
match $node_b.get_and_clear_pending_msg_events().pop().unwrap() {
|
||||
MessageSendEvent::UpdateHTLCs { node_id, updates } => {
|
||||
|
|
|
@ -95,7 +95,7 @@ mod sealed {
|
|||
// Byte 0
|
||||
,
|
||||
// Byte 1
|
||||
StaticRemoteKey,
|
||||
StaticRemoteKey | PaymentSecret,
|
||||
// Byte 2
|
||||
,
|
||||
// Byte 3
|
||||
|
@ -105,7 +105,7 @@ mod sealed {
|
|||
// Byte 0
|
||||
DataLossProtect | InitialRoutingSync | UpfrontShutdownScript | GossipQueries,
|
||||
// Byte 1
|
||||
VariableLengthOnion | PaymentSecret,
|
||||
VariableLengthOnion,
|
||||
// Byte 2
|
||||
BasicMPP,
|
||||
// Byte 3
|
||||
|
@ -117,7 +117,7 @@ mod sealed {
|
|||
// Byte 0
|
||||
,
|
||||
// Byte 1
|
||||
StaticRemoteKey,
|
||||
StaticRemoteKey | PaymentSecret,
|
||||
// Byte 2
|
||||
,
|
||||
// Byte 3
|
||||
|
@ -127,7 +127,7 @@ mod sealed {
|
|||
// Byte 0
|
||||
DataLossProtect | UpfrontShutdownScript | GossipQueries,
|
||||
// Byte 1
|
||||
VariableLengthOnion | PaymentSecret,
|
||||
VariableLengthOnion,
|
||||
// Byte 2
|
||||
BasicMPP,
|
||||
// Byte 3
|
||||
|
@ -139,12 +139,19 @@ mod sealed {
|
|||
optional_features: [],
|
||||
});
|
||||
define_context!(InvoiceContext {
|
||||
required_features: [,,,],
|
||||
required_features: [
|
||||
// Byte 0
|
||||
,
|
||||
// Byte 1
|
||||
PaymentSecret,
|
||||
// Byte 2
|
||||
,
|
||||
],
|
||||
optional_features: [
|
||||
// Byte 0
|
||||
,
|
||||
// Byte 1
|
||||
VariableLengthOnion | PaymentSecret,
|
||||
VariableLengthOnion,
|
||||
// Byte 2
|
||||
BasicMPP,
|
||||
],
|
||||
|
@ -732,8 +739,8 @@ mod tests {
|
|||
|
||||
assert!(InitFeatures::known().supports_payment_secret());
|
||||
assert!(NodeFeatures::known().supports_payment_secret());
|
||||
assert!(!InitFeatures::known().requires_payment_secret());
|
||||
assert!(!NodeFeatures::known().requires_payment_secret());
|
||||
assert!(InitFeatures::known().requires_payment_secret());
|
||||
assert!(NodeFeatures::known().requires_payment_secret());
|
||||
|
||||
assert!(InitFeatures::known().supports_basic_mpp());
|
||||
assert!(NodeFeatures::known().supports_basic_mpp());
|
||||
|
@ -779,12 +786,12 @@ mod tests {
|
|||
{
|
||||
// Check that the flags are as expected:
|
||||
// - option_data_loss_protect
|
||||
// - var_onion_optin | static_remote_key (req) | payment_secret
|
||||
// - var_onion_optin | static_remote_key (req) | payment_secret(req)
|
||||
// - basic_mpp
|
||||
// - opt_shutdown_anysegwit
|
||||
assert_eq!(node_features.flags.len(), 4);
|
||||
assert_eq!(node_features.flags[0], 0b00000010);
|
||||
assert_eq!(node_features.flags[1], 0b10010010);
|
||||
assert_eq!(node_features.flags[1], 0b01010010);
|
||||
assert_eq!(node_features.flags[2], 0b00000010);
|
||||
assert_eq!(node_features.flags[3], 0b00001000);
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ use chain::transaction::OutPoint;
|
|||
use ln::channelmanager::{BestBlock, ChainParameters, ChannelManager, ChannelManagerReadArgs, RAACommitmentOrder, PaymentPreimage, PaymentHash, PaymentSecret, PaymentSendFailure};
|
||||
use routing::router::{Route, get_route};
|
||||
use routing::network_graph::{NetGraphMsgHandler, NetworkGraph};
|
||||
use ln::features::InitFeatures;
|
||||
use ln::features::{InitFeatures, InvoiceFeatures};
|
||||
use ln::msgs;
|
||||
use ln::msgs::{ChannelMessageHandler,RoutingMessageHandler};
|
||||
use util::enforcing_trait_impls::EnforcingSigner;
|
||||
|
@ -66,7 +66,7 @@ pub fn confirm_transaction_at<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, tx: &T
|
|||
connect_blocks(node, conf_height - first_connect_height);
|
||||
}
|
||||
let mut block = Block {
|
||||
header: BlockHeader { version: 0x20000000, prev_blockhash: node.best_block_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 },
|
||||
header: BlockHeader { version: 0x20000000, prev_blockhash: node.best_block_hash(), merkle_root: Default::default(), time: conf_height, bits: 42, nonce: 42 },
|
||||
txdata: Vec::new(),
|
||||
};
|
||||
for _ in 0..*node.network_chan_count.borrow() { // Make sure we don't end up with channels at the same short id by offsetting by chan_count
|
||||
|
@ -102,15 +102,16 @@ pub fn connect_blocks<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, depth: u32) ->
|
|||
_ => false,
|
||||
};
|
||||
|
||||
let height = node.best_block_info().1 + 1;
|
||||
let mut block = Block {
|
||||
header: BlockHeader { version: 0x2000000, prev_blockhash: node.best_block_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 },
|
||||
header: BlockHeader { version: 0x2000000, prev_blockhash: node.best_block_hash(), merkle_root: Default::default(), time: height, bits: 42, nonce: 42 },
|
||||
txdata: vec![],
|
||||
};
|
||||
assert!(depth >= 1);
|
||||
for _ in 0..depth - 1 {
|
||||
for i in 1..depth {
|
||||
do_connect_block(node, &block, skip_intermediaries);
|
||||
block = Block {
|
||||
header: BlockHeader { version: 0x20000000, prev_blockhash: block.header.block_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 },
|
||||
header: BlockHeader { version: 0x20000000, prev_blockhash: block.header.block_hash(), merkle_root: Default::default(), time: height + i, bits: 42, nonce: 42 },
|
||||
txdata: vec![],
|
||||
};
|
||||
}
|
||||
|
@ -894,16 +895,29 @@ macro_rules! commitment_signed_dance {
|
|||
/// Get a payment preimage and hash.
|
||||
#[macro_export]
|
||||
macro_rules! get_payment_preimage_hash {
|
||||
($node: expr) => {
|
||||
($dest_node: expr) => {
|
||||
{
|
||||
let payment_preimage = PaymentPreimage([*$node.network_payment_count.borrow(); 32]);
|
||||
*$node.network_payment_count.borrow_mut() += 1;
|
||||
let payment_preimage = PaymentPreimage([*$dest_node.network_payment_count.borrow(); 32]);
|
||||
*$dest_node.network_payment_count.borrow_mut() += 1;
|
||||
let payment_hash = PaymentHash(Sha256::hash(&payment_preimage.0[..]).into_inner());
|
||||
(payment_preimage, payment_hash)
|
||||
let payment_secret = $dest_node.node.create_inbound_payment_for_hash(payment_hash, None, 7200, 0).unwrap();
|
||||
(payment_preimage, payment_hash, payment_secret)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
macro_rules! get_route_and_payment_hash {
|
||||
($send_node: expr, $recv_node: expr, $recv_value: expr) => {{
|
||||
let (payment_preimage, payment_hash, payment_secret) = get_payment_preimage_hash!($recv_node);
|
||||
let net_graph_msg_handler = &$send_node.net_graph_msg_handler;
|
||||
let route = get_route(&$send_node.node.get_our_node_id(),
|
||||
&net_graph_msg_handler.network_graph.read().unwrap(),
|
||||
&$recv_node.node.get_our_node_id(), None, None, &Vec::new(), $recv_value, TEST_FINAL_CLTV, $send_node.logger).unwrap();
|
||||
(route, payment_hash, payment_preimage, payment_secret)
|
||||
}}
|
||||
}
|
||||
|
||||
macro_rules! expect_pending_htlcs_forwardable_ignore {
|
||||
($node: expr) => {{
|
||||
let events = $node.node.get_and_clear_pending_events();
|
||||
|
@ -924,13 +938,14 @@ macro_rules! expect_pending_htlcs_forwardable {
|
|||
|
||||
#[cfg(any(test, feature = "unstable"))]
|
||||
macro_rules! expect_payment_received {
|
||||
($node: expr, $expected_payment_hash: expr, $expected_recv_value: expr) => {
|
||||
($node: expr, $expected_payment_hash: expr, $expected_payment_secret: expr, $expected_recv_value: expr) => {
|
||||
let events = $node.node.get_and_clear_pending_events();
|
||||
assert_eq!(events.len(), 1);
|
||||
match events[0] {
|
||||
Event::PaymentReceived { ref payment_hash, ref payment_secret, amt } => {
|
||||
Event::PaymentReceived { ref payment_hash, ref payment_preimage, ref payment_secret, amt, user_payment_id: _ } => {
|
||||
assert_eq!($expected_payment_hash, *payment_hash);
|
||||
assert_eq!(None, *payment_secret);
|
||||
assert!(payment_preimage.is_none());
|
||||
assert_eq!($expected_payment_secret, *payment_secret);
|
||||
assert_eq!($expected_recv_value, amt);
|
||||
},
|
||||
_ => panic!("Unexpected event"),
|
||||
|
@ -972,13 +987,13 @@ macro_rules! expect_payment_failed {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn send_along_route_with_secret<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, route: Route, expected_paths: &[&[&Node<'a, 'b, 'c>]], recv_value: u64, our_payment_hash: PaymentHash, our_payment_secret: Option<PaymentSecret>) {
|
||||
origin_node.node.send_payment(&route, our_payment_hash, &our_payment_secret).unwrap();
|
||||
pub fn send_along_route_with_secret<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, route: Route, expected_paths: &[&[&Node<'a, 'b, 'c>]], recv_value: u64, our_payment_hash: PaymentHash, our_payment_secret: PaymentSecret) {
|
||||
origin_node.node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)).unwrap();
|
||||
check_added_monitors!(origin_node, expected_paths.len());
|
||||
pass_along_route(origin_node, expected_paths, recv_value, our_payment_hash, our_payment_secret);
|
||||
}
|
||||
|
||||
pub fn pass_along_path<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_path: &[&Node<'a, 'b, 'c>], recv_value: u64, our_payment_hash: PaymentHash, our_payment_secret: Option<PaymentSecret>, ev: MessageSendEvent, payment_received_expected: bool) {
|
||||
pub fn pass_along_path<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_path: &[&Node<'a, 'b, 'c>], recv_value: u64, our_payment_hash: PaymentHash, our_payment_secret: PaymentSecret, ev: MessageSendEvent, payment_received_expected: bool) {
|
||||
let mut payment_event = SendEvent::from_event(ev);
|
||||
let mut prev_node = origin_node;
|
||||
|
||||
|
@ -996,8 +1011,9 @@ pub fn pass_along_path<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_path
|
|||
if payment_received_expected {
|
||||
assert_eq!(events_2.len(), 1);
|
||||
match events_2[0] {
|
||||
Event::PaymentReceived { ref payment_hash, ref payment_secret, amt } => {
|
||||
Event::PaymentReceived { ref payment_hash, ref payment_preimage, ref payment_secret, amt, user_payment_id: _ } => {
|
||||
assert_eq!(our_payment_hash, *payment_hash);
|
||||
assert!(payment_preimage.is_none());
|
||||
assert_eq!(our_payment_secret, *payment_secret);
|
||||
assert_eq!(amt, recv_value);
|
||||
},
|
||||
|
@ -1018,7 +1034,7 @@ pub fn pass_along_path<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_path
|
|||
}
|
||||
}
|
||||
|
||||
pub fn pass_along_route<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_route: &[&[&Node<'a, 'b, 'c>]], recv_value: u64, our_payment_hash: PaymentHash, our_payment_secret: Option<PaymentSecret>) {
|
||||
pub fn pass_along_route<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_route: &[&[&Node<'a, 'b, 'c>]], recv_value: u64, our_payment_hash: PaymentHash, our_payment_secret: PaymentSecret) {
|
||||
let mut events = origin_node.node.get_and_clear_pending_msg_events();
|
||||
assert_eq!(events.len(), expected_route.len());
|
||||
for (path_idx, (ev, expected_path)) in events.drain(..).zip(expected_route.iter()).enumerate() {
|
||||
|
@ -1029,21 +1045,17 @@ pub fn pass_along_route<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_rou
|
|||
}
|
||||
}
|
||||
|
||||
pub fn send_along_route_with_hash<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, route: Route, expected_route: &[&Node<'a, 'b, 'c>], recv_value: u64, our_payment_hash: PaymentHash) {
|
||||
send_along_route_with_secret(origin_node, route, &[expected_route], recv_value, our_payment_hash, None);
|
||||
pub fn send_along_route<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, route: Route, expected_route: &[&Node<'a, 'b, 'c>], recv_value: u64) -> (PaymentPreimage, PaymentHash, PaymentSecret) {
|
||||
let (our_payment_preimage, our_payment_hash, our_payment_secret) = get_payment_preimage_hash!(expected_route.last().unwrap());
|
||||
send_along_route_with_secret(origin_node, route, &[expected_route], recv_value, our_payment_hash, our_payment_secret);
|
||||
(our_payment_preimage, our_payment_hash, our_payment_secret)
|
||||
}
|
||||
|
||||
pub fn send_along_route<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, route: Route, expected_route: &[&Node<'a, 'b, 'c>], recv_value: u64) -> (PaymentPreimage, PaymentHash) {
|
||||
let (our_payment_preimage, our_payment_hash) = get_payment_preimage_hash!(origin_node);
|
||||
send_along_route_with_hash(origin_node, route, expected_route, recv_value, our_payment_hash);
|
||||
(our_payment_preimage, our_payment_hash)
|
||||
}
|
||||
|
||||
pub fn claim_payment_along_route_with_secret<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_paths: &[&[&Node<'a, 'b, 'c>]], skip_last: bool, our_payment_preimage: PaymentPreimage, our_payment_secret: Option<PaymentSecret>, expected_amount: u64) {
|
||||
pub fn claim_payment_along_route<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_paths: &[&[&Node<'a, 'b, 'c>]], skip_last: bool, our_payment_preimage: PaymentPreimage) {
|
||||
for path in expected_paths.iter() {
|
||||
assert_eq!(path.last().unwrap().node.get_our_node_id(), expected_paths[0].last().unwrap().node.get_our_node_id());
|
||||
}
|
||||
assert!(expected_paths[0].last().unwrap().node.claim_funds(our_payment_preimage, &our_payment_secret, expected_amount));
|
||||
assert!(expected_paths[0].last().unwrap().node.claim_funds(our_payment_preimage));
|
||||
check_added_monitors!(expected_paths[0].last().unwrap(), expected_paths.len());
|
||||
|
||||
macro_rules! msgs_from_ev {
|
||||
|
@ -1127,20 +1139,16 @@ pub fn claim_payment_along_route_with_secret<'a, 'b, 'c>(origin_node: &Node<'a,
|
|||
}
|
||||
}
|
||||
|
||||
pub fn claim_payment_along_route<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_route: &[&Node<'a, 'b, 'c>], skip_last: bool, our_payment_preimage: PaymentPreimage, expected_amount: u64) {
|
||||
claim_payment_along_route_with_secret(origin_node, &[expected_route], skip_last, our_payment_preimage, None, expected_amount);
|
||||
}
|
||||
|
||||
pub fn claim_payment<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_route: &[&Node<'a, 'b, 'c>], our_payment_preimage: PaymentPreimage, expected_amount: u64) {
|
||||
claim_payment_along_route(origin_node, expected_route, false, our_payment_preimage, expected_amount);
|
||||
pub fn claim_payment<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_route: &[&Node<'a, 'b, 'c>], our_payment_preimage: PaymentPreimage) {
|
||||
claim_payment_along_route(origin_node, &[expected_route], false, our_payment_preimage);
|
||||
}
|
||||
|
||||
pub const TEST_FINAL_CLTV: u32 = 50;
|
||||
|
||||
pub fn route_payment<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_route: &[&Node<'a, 'b, 'c>], recv_value: u64) -> (PaymentPreimage, PaymentHash) {
|
||||
pub fn route_payment<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_route: &[&Node<'a, 'b, 'c>], recv_value: u64) -> (PaymentPreimage, PaymentHash, PaymentSecret) {
|
||||
let net_graph_msg_handler = &origin_node.net_graph_msg_handler;
|
||||
let logger = test_utils::TestLogger::new();
|
||||
let route = get_route(&origin_node.node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &expected_route.last().unwrap().node.get_our_node_id(), None, None, &Vec::new(), recv_value, TEST_FINAL_CLTV, &logger).unwrap();
|
||||
let route = get_route(&origin_node.node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &expected_route.last().unwrap().node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), recv_value, TEST_FINAL_CLTV, &logger).unwrap();
|
||||
assert_eq!(route.paths.len(), 1);
|
||||
assert_eq!(route.paths[0].len(), expected_route.len());
|
||||
for (node, hop) in expected_route.iter().zip(route.paths[0].iter()) {
|
||||
|
@ -1153,25 +1161,25 @@ pub fn route_payment<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_route:
|
|||
pub fn route_over_limit<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_route: &[&Node<'a, 'b, 'c>], recv_value: u64) {
|
||||
let logger = test_utils::TestLogger::new();
|
||||
let net_graph_msg_handler = &origin_node.net_graph_msg_handler;
|
||||
let route = get_route(&origin_node.node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &expected_route.last().unwrap().node.get_our_node_id(), None, None, &Vec::new(), recv_value, TEST_FINAL_CLTV, &logger).unwrap();
|
||||
let route = get_route(&origin_node.node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &expected_route.last().unwrap().node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), recv_value, TEST_FINAL_CLTV, &logger).unwrap();
|
||||
assert_eq!(route.paths.len(), 1);
|
||||
assert_eq!(route.paths[0].len(), expected_route.len());
|
||||
for (node, hop) in expected_route.iter().zip(route.paths[0].iter()) {
|
||||
assert_eq!(hop.pubkey, node.node.get_our_node_id());
|
||||
}
|
||||
|
||||
let (_, our_payment_hash) = get_payment_preimage_hash!(origin_node);
|
||||
unwrap_send_err!(origin_node.node.send_payment(&route, our_payment_hash, &None), true, APIError::ChannelUnavailable { ref err },
|
||||
let (_, our_payment_hash, our_payment_preimage) = get_payment_preimage_hash!(expected_route.last().unwrap());
|
||||
unwrap_send_err!(origin_node.node.send_payment(&route, our_payment_hash, &Some(our_payment_preimage)), true, APIError::ChannelUnavailable { ref err },
|
||||
assert!(err.contains("Cannot send value that would put us over the max HTLC value in flight our peer will accept")));
|
||||
}
|
||||
|
||||
pub fn send_payment<'a, 'b, 'c>(origin: &Node<'a, 'b, 'c>, expected_route: &[&Node<'a, 'b, 'c>], recv_value: u64, expected_value: u64) {
|
||||
pub fn send_payment<'a, 'b, 'c>(origin: &Node<'a, 'b, 'c>, expected_route: &[&Node<'a, 'b, 'c>], recv_value: u64) {
|
||||
let our_payment_preimage = route_payment(&origin, expected_route, recv_value).0;
|
||||
claim_payment(&origin, expected_route, our_payment_preimage, expected_value);
|
||||
claim_payment(&origin, expected_route, our_payment_preimage);
|
||||
}
|
||||
|
||||
pub fn fail_payment_along_route<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_route: &[&Node<'a, 'b, 'c>], skip_last: bool, our_payment_hash: PaymentHash) {
|
||||
assert!(expected_route.last().unwrap().node.fail_htlc_backwards(&our_payment_hash, &None));
|
||||
assert!(expected_route.last().unwrap().node.fail_htlc_backwards(&our_payment_hash));
|
||||
expect_pending_htlcs_forwardable!(expected_route.last().unwrap());
|
||||
check_added_monitors!(expected_route.last().unwrap(), 1);
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -12,10 +12,10 @@
|
|||
//! returned errors decode to the correct thing.
|
||||
|
||||
use chain::channelmonitor::{CLTV_CLAIM_BUFFER, LATENCY_GRACE_PERIOD_BLOCKS};
|
||||
use ln::channelmanager::{HTLCForwardInfo, PaymentPreimage, PaymentHash};
|
||||
use ln::channelmanager::{HTLCForwardInfo, PaymentPreimage, PaymentHash, PaymentSecret};
|
||||
use ln::onion_utils;
|
||||
use routing::router::{Route, get_route};
|
||||
use ln::features::InitFeatures;
|
||||
use ln::features::{InitFeatures, InvoiceFeatures};
|
||||
use ln::msgs;
|
||||
use ln::msgs::{ChannelMessageHandler, HTLCFailChannelUpdate, OptionalField};
|
||||
use util::test_utils;
|
||||
|
@ -36,11 +36,11 @@ use std::io;
|
|||
|
||||
use ln::functional_test_utils::*;
|
||||
|
||||
fn run_onion_failure_test<F1,F2>(_name: &str, test_case: u8, nodes: &Vec<Node>, route: &Route, payment_hash: &PaymentHash, callback_msg: F1, callback_node: F2, expected_retryable: bool, expected_error_code: Option<u16>, expected_channel_update: Option<HTLCFailChannelUpdate>)
|
||||
fn run_onion_failure_test<F1,F2>(_name: &str, test_case: u8, nodes: &Vec<Node>, route: &Route, payment_hash: &PaymentHash, payment_secret: &PaymentSecret, callback_msg: F1, callback_node: F2, expected_retryable: bool, expected_error_code: Option<u16>, expected_channel_update: Option<HTLCFailChannelUpdate>)
|
||||
where F1: for <'a> FnMut(&'a mut msgs::UpdateAddHTLC),
|
||||
F2: FnMut(),
|
||||
{
|
||||
run_onion_failure_test_with_fail_intercept(_name, test_case, nodes, route, payment_hash, callback_msg, |_|{}, callback_node, expected_retryable, expected_error_code, expected_channel_update);
|
||||
run_onion_failure_test_with_fail_intercept(_name, test_case, nodes, route, payment_hash, payment_secret, callback_msg, |_|{}, callback_node, expected_retryable, expected_error_code, expected_channel_update);
|
||||
}
|
||||
|
||||
// test_case
|
||||
|
@ -50,7 +50,7 @@ fn run_onion_failure_test<F1,F2>(_name: &str, test_case: u8, nodes: &Vec<Node>,
|
|||
// 3: final node fails backward (but tamper onion payloads from node0)
|
||||
// 100: trigger error in the intermediate node and tamper returning fail_htlc
|
||||
// 200: trigger error in the final node and tamper returning fail_htlc
|
||||
fn run_onion_failure_test_with_fail_intercept<F1,F2,F3>(_name: &str, test_case: u8, nodes: &Vec<Node>, route: &Route, payment_hash: &PaymentHash, mut callback_msg: F1, mut callback_fail: F2, mut callback_node: F3, expected_retryable: bool, expected_error_code: Option<u16>, expected_channel_update: Option<HTLCFailChannelUpdate>)
|
||||
fn run_onion_failure_test_with_fail_intercept<F1,F2,F3>(_name: &str, test_case: u8, nodes: &Vec<Node>, route: &Route, payment_hash: &PaymentHash, payment_secret: &PaymentSecret, mut callback_msg: F1, mut callback_fail: F2, mut callback_node: F3, expected_retryable: bool, expected_error_code: Option<u16>, expected_channel_update: Option<HTLCFailChannelUpdate>)
|
||||
where F1: for <'a> FnMut(&'a mut msgs::UpdateAddHTLC),
|
||||
F2: for <'a> FnMut(&'a mut msgs::UpdateFailHTLC),
|
||||
F3: FnMut(),
|
||||
|
@ -74,7 +74,7 @@ fn run_onion_failure_test_with_fail_intercept<F1,F2,F3>(_name: &str, test_case:
|
|||
}
|
||||
|
||||
// 0 ~~> 2 send payment
|
||||
nodes[0].node.send_payment(&route, payment_hash.clone(), &None).unwrap();
|
||||
nodes[0].node.send_payment(&route, payment_hash.clone(), &Some(*payment_secret)).unwrap();
|
||||
check_added_monitors!(nodes[0], 1);
|
||||
let update_0 = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id());
|
||||
// temper update_add (0 => 1)
|
||||
|
@ -267,15 +267,14 @@ fn test_onion_failure() {
|
|||
*node.keys_manager.override_session_priv.lock().unwrap() = Some([3; 32]);
|
||||
}
|
||||
let channels = [create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known()), create_announced_chan_between_nodes(&nodes, 1, 2, InitFeatures::known(), InitFeatures::known())];
|
||||
let (_, payment_hash) = get_payment_preimage_hash!(nodes[0]);
|
||||
let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
|
||||
let (_, payment_hash, payment_secret) = get_payment_preimage_hash!(nodes[2]);
|
||||
let logger = test_utils::TestLogger::new();
|
||||
let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2].node.get_our_node_id(), None, None, &Vec::new(), 40000, TEST_FINAL_CLTV, &logger).unwrap();
|
||||
let route = get_route(&nodes[0].node.get_our_node_id(), &nodes[0].net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 40000, TEST_FINAL_CLTV, &logger).unwrap();
|
||||
// positve case
|
||||
send_payment(&nodes[0], &vec!(&nodes[1], &nodes[2])[..], 40000, 40_000);
|
||||
send_payment(&nodes[0], &vec!(&nodes[1], &nodes[2])[..], 40000);
|
||||
|
||||
// intermediate node failure
|
||||
run_onion_failure_test("invalid_realm", 0, &nodes, &route, &payment_hash, |msg| {
|
||||
run_onion_failure_test("invalid_realm", 0, &nodes, &route, &payment_hash, &payment_secret, |msg| {
|
||||
let session_priv = SecretKey::from_slice(&[3; 32]).unwrap();
|
||||
let cur_height = nodes[0].best_block_info().1 + 1;
|
||||
let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route.paths[0], &session_priv).unwrap();
|
||||
|
@ -291,7 +290,7 @@ fn test_onion_failure() {
|
|||
}, ||{}, true, Some(PERM|22), Some(msgs::HTLCFailChannelUpdate::ChannelClosed{short_channel_id: channels[1].0.contents.short_channel_id, is_permanent: true}));//XXX incremented channels idx here
|
||||
|
||||
// final node failure
|
||||
run_onion_failure_test("invalid_realm", 3, &nodes, &route, &payment_hash, |msg| {
|
||||
run_onion_failure_test("invalid_realm", 3, &nodes, &route, &payment_hash, &payment_secret, |msg| {
|
||||
let session_priv = SecretKey::from_slice(&[3; 32]).unwrap();
|
||||
let cur_height = nodes[0].best_block_info().1 + 1;
|
||||
let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route.paths[0], &session_priv).unwrap();
|
||||
|
@ -309,7 +308,7 @@ fn test_onion_failure() {
|
|||
// the following three with run_onion_failure_test_with_fail_intercept() test only the origin node
|
||||
// receiving simulated fail messages
|
||||
// intermediate node failure
|
||||
run_onion_failure_test_with_fail_intercept("temporary_node_failure", 100, &nodes, &route, &payment_hash, |msg| {
|
||||
run_onion_failure_test_with_fail_intercept("temporary_node_failure", 100, &nodes, &route, &payment_hash, &payment_secret, |msg| {
|
||||
// trigger error
|
||||
msg.amount_msat -= 1;
|
||||
}, |msg| {
|
||||
|
@ -320,17 +319,18 @@ fn test_onion_failure() {
|
|||
}, ||{}, true, Some(NODE|2), Some(msgs::HTLCFailChannelUpdate::NodeFailure{node_id: route.paths[0][0].pubkey, is_permanent: false}));
|
||||
|
||||
// final node failure
|
||||
run_onion_failure_test_with_fail_intercept("temporary_node_failure", 200, &nodes, &route, &payment_hash, |_msg| {}, |msg| {
|
||||
run_onion_failure_test_with_fail_intercept("temporary_node_failure", 200, &nodes, &route, &payment_hash, &payment_secret, |_msg| {}, |msg| {
|
||||
// and tamper returning error message
|
||||
let session_priv = SecretKey::from_slice(&[3; 32]).unwrap();
|
||||
let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route.paths[0], &session_priv).unwrap();
|
||||
msg.reason = onion_utils::build_first_hop_failure_packet(&onion_keys[1].shared_secret[..], NODE|2, &[0;0]);
|
||||
}, ||{
|
||||
nodes[2].node.fail_htlc_backwards(&payment_hash, &None);
|
||||
nodes[2].node.fail_htlc_backwards(&payment_hash);
|
||||
}, true, Some(NODE|2), Some(msgs::HTLCFailChannelUpdate::NodeFailure{node_id: route.paths[0][1].pubkey, is_permanent: false}));
|
||||
let (_, payment_hash, payment_secret) = get_payment_preimage_hash!(nodes[2]);
|
||||
|
||||
// intermediate node failure
|
||||
run_onion_failure_test_with_fail_intercept("permanent_node_failure", 100, &nodes, &route, &payment_hash, |msg| {
|
||||
run_onion_failure_test_with_fail_intercept("permanent_node_failure", 100, &nodes, &route, &payment_hash, &payment_secret, |msg| {
|
||||
msg.amount_msat -= 1;
|
||||
}, |msg| {
|
||||
let session_priv = SecretKey::from_slice(&[3; 32]).unwrap();
|
||||
|
@ -339,44 +339,46 @@ fn test_onion_failure() {
|
|||
}, ||{}, true, Some(PERM|NODE|2), Some(msgs::HTLCFailChannelUpdate::NodeFailure{node_id: route.paths[0][0].pubkey, is_permanent: true}));
|
||||
|
||||
// final node failure
|
||||
run_onion_failure_test_with_fail_intercept("permanent_node_failure", 200, &nodes, &route, &payment_hash, |_msg| {}, |msg| {
|
||||
run_onion_failure_test_with_fail_intercept("permanent_node_failure", 200, &nodes, &route, &payment_hash, &payment_secret, |_msg| {}, |msg| {
|
||||
let session_priv = SecretKey::from_slice(&[3; 32]).unwrap();
|
||||
let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route.paths[0], &session_priv).unwrap();
|
||||
msg.reason = onion_utils::build_first_hop_failure_packet(&onion_keys[1].shared_secret[..], PERM|NODE|2, &[0;0]);
|
||||
}, ||{
|
||||
nodes[2].node.fail_htlc_backwards(&payment_hash, &None);
|
||||
nodes[2].node.fail_htlc_backwards(&payment_hash);
|
||||
}, false, Some(PERM|NODE|2), Some(msgs::HTLCFailChannelUpdate::NodeFailure{node_id: route.paths[0][1].pubkey, is_permanent: true}));
|
||||
let (_, payment_hash, payment_secret) = get_payment_preimage_hash!(nodes[2]);
|
||||
|
||||
// intermediate node failure
|
||||
run_onion_failure_test_with_fail_intercept("required_node_feature_missing", 100, &nodes, &route, &payment_hash, |msg| {
|
||||
run_onion_failure_test_with_fail_intercept("required_node_feature_missing", 100, &nodes, &route, &payment_hash, &payment_secret, |msg| {
|
||||
msg.amount_msat -= 1;
|
||||
}, |msg| {
|
||||
let session_priv = SecretKey::from_slice(&[3; 32]).unwrap();
|
||||
let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route.paths[0], &session_priv).unwrap();
|
||||
msg.reason = onion_utils::build_first_hop_failure_packet(&onion_keys[0].shared_secret[..], PERM|NODE|3, &[0;0]);
|
||||
}, ||{
|
||||
nodes[2].node.fail_htlc_backwards(&payment_hash, &None);
|
||||
nodes[2].node.fail_htlc_backwards(&payment_hash);
|
||||
}, true, Some(PERM|NODE|3), Some(msgs::HTLCFailChannelUpdate::NodeFailure{node_id: route.paths[0][0].pubkey, is_permanent: true}));
|
||||
|
||||
// final node failure
|
||||
run_onion_failure_test_with_fail_intercept("required_node_feature_missing", 200, &nodes, &route, &payment_hash, |_msg| {}, |msg| {
|
||||
run_onion_failure_test_with_fail_intercept("required_node_feature_missing", 200, &nodes, &route, &payment_hash, &payment_secret, |_msg| {}, |msg| {
|
||||
let session_priv = SecretKey::from_slice(&[3; 32]).unwrap();
|
||||
let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route.paths[0], &session_priv).unwrap();
|
||||
msg.reason = onion_utils::build_first_hop_failure_packet(&onion_keys[1].shared_secret[..], PERM|NODE|3, &[0;0]);
|
||||
}, ||{
|
||||
nodes[2].node.fail_htlc_backwards(&payment_hash, &None);
|
||||
nodes[2].node.fail_htlc_backwards(&payment_hash);
|
||||
}, false, Some(PERM|NODE|3), Some(msgs::HTLCFailChannelUpdate::NodeFailure{node_id: route.paths[0][1].pubkey, is_permanent: true}));
|
||||
let (_, payment_hash, payment_secret) = get_payment_preimage_hash!(nodes[2]);
|
||||
|
||||
run_onion_failure_test("invalid_onion_version", 0, &nodes, &route, &payment_hash, |msg| { msg.onion_routing_packet.version = 1; }, ||{}, true,
|
||||
run_onion_failure_test("invalid_onion_version", 0, &nodes, &route, &payment_hash, &payment_secret, |msg| { msg.onion_routing_packet.version = 1; }, ||{}, true,
|
||||
Some(BADONION|PERM|4), None);
|
||||
|
||||
run_onion_failure_test("invalid_onion_hmac", 0, &nodes, &route, &payment_hash, |msg| { msg.onion_routing_packet.hmac = [3; 32]; }, ||{}, true,
|
||||
run_onion_failure_test("invalid_onion_hmac", 0, &nodes, &route, &payment_hash, &payment_secret, |msg| { msg.onion_routing_packet.hmac = [3; 32]; }, ||{}, true,
|
||||
Some(BADONION|PERM|5), None);
|
||||
|
||||
run_onion_failure_test("invalid_onion_key", 0, &nodes, &route, &payment_hash, |msg| { msg.onion_routing_packet.public_key = Err(secp256k1::Error::InvalidPublicKey);}, ||{}, true,
|
||||
run_onion_failure_test("invalid_onion_key", 0, &nodes, &route, &payment_hash, &payment_secret, |msg| { msg.onion_routing_packet.public_key = Err(secp256k1::Error::InvalidPublicKey);}, ||{}, true,
|
||||
Some(BADONION|PERM|6), None);
|
||||
|
||||
run_onion_failure_test_with_fail_intercept("temporary_channel_failure", 100, &nodes, &route, &payment_hash, |msg| {
|
||||
run_onion_failure_test_with_fail_intercept("temporary_channel_failure", 100, &nodes, &route, &payment_hash, &payment_secret, |msg| {
|
||||
msg.amount_msat -= 1;
|
||||
}, |msg| {
|
||||
let session_priv = SecretKey::from_slice(&[3; 32]).unwrap();
|
||||
|
@ -384,7 +386,7 @@ fn test_onion_failure() {
|
|||
msg.reason = onion_utils::build_first_hop_failure_packet(&onion_keys[0].shared_secret[..], UPDATE|7, &ChannelUpdate::dummy().encode_with_len()[..]);
|
||||
}, ||{}, true, Some(UPDATE|7), Some(msgs::HTLCFailChannelUpdate::ChannelUpdateMessage{msg: ChannelUpdate::dummy()}));
|
||||
|
||||
run_onion_failure_test_with_fail_intercept("permanent_channel_failure", 100, &nodes, &route, &payment_hash, |msg| {
|
||||
run_onion_failure_test_with_fail_intercept("permanent_channel_failure", 100, &nodes, &route, &payment_hash, &payment_secret, |msg| {
|
||||
msg.amount_msat -= 1;
|
||||
}, |msg| {
|
||||
let session_priv = SecretKey::from_slice(&[3; 32]).unwrap();
|
||||
|
@ -393,7 +395,7 @@ fn test_onion_failure() {
|
|||
// short_channel_id from the processing node
|
||||
}, ||{}, true, Some(PERM|8), Some(msgs::HTLCFailChannelUpdate::ChannelClosed{short_channel_id: channels[1].0.contents.short_channel_id, is_permanent: true}));
|
||||
|
||||
run_onion_failure_test_with_fail_intercept("required_channel_feature_missing", 100, &nodes, &route, &payment_hash, |msg| {
|
||||
run_onion_failure_test_with_fail_intercept("required_channel_feature_missing", 100, &nodes, &route, &payment_hash, &payment_secret, |msg| {
|
||||
msg.amount_msat -= 1;
|
||||
}, |msg| {
|
||||
let session_priv = SecretKey::from_slice(&[3; 32]).unwrap();
|
||||
|
@ -404,50 +406,51 @@ fn test_onion_failure() {
|
|||
|
||||
let mut bogus_route = route.clone();
|
||||
bogus_route.paths[0][1].short_channel_id -= 1;
|
||||
run_onion_failure_test("unknown_next_peer", 0, &nodes, &bogus_route, &payment_hash, |_| {}, ||{}, true, Some(PERM|10),
|
||||
run_onion_failure_test("unknown_next_peer", 0, &nodes, &bogus_route, &payment_hash, &payment_secret, |_| {}, ||{}, true, Some(PERM|10),
|
||||
Some(msgs::HTLCFailChannelUpdate::ChannelClosed{short_channel_id: bogus_route.paths[0][1].short_channel_id, is_permanent:true}));
|
||||
|
||||
let amt_to_forward = nodes[1].node.channel_state.lock().unwrap().by_id.get(&channels[1].2).unwrap().get_counterparty_htlc_minimum_msat() - 1;
|
||||
let mut bogus_route = route.clone();
|
||||
let route_len = bogus_route.paths[0].len();
|
||||
bogus_route.paths[0][route_len-1].fee_msat = amt_to_forward;
|
||||
run_onion_failure_test("amount_below_minimum", 0, &nodes, &bogus_route, &payment_hash, |_| {}, ||{}, true, Some(UPDATE|11), Some(msgs::HTLCFailChannelUpdate::ChannelUpdateMessage{msg: ChannelUpdate::dummy()}));
|
||||
run_onion_failure_test("amount_below_minimum", 0, &nodes, &bogus_route, &payment_hash, &payment_secret, |_| {}, ||{}, true, Some(UPDATE|11), Some(msgs::HTLCFailChannelUpdate::ChannelUpdateMessage{msg: ChannelUpdate::dummy()}));
|
||||
|
||||
// Test a positive test-case with one extra msat, meeting the minimum.
|
||||
bogus_route.paths[0][route_len-1].fee_msat = amt_to_forward + 1;
|
||||
let (preimage, _) = send_along_route(&nodes[0], bogus_route, &[&nodes[1], &nodes[2]], amt_to_forward+1);
|
||||
claim_payment(&nodes[0], &[&nodes[1], &nodes[2]], preimage, amt_to_forward+1);
|
||||
let (preimage, _, _) = send_along_route(&nodes[0], bogus_route, &[&nodes[1], &nodes[2]], amt_to_forward+1);
|
||||
claim_payment(&nodes[0], &[&nodes[1], &nodes[2]], preimage);
|
||||
|
||||
//TODO: with new config API, we will be able to generate both valid and
|
||||
//invalid channel_update cases.
|
||||
run_onion_failure_test("fee_insufficient", 0, &nodes, &route, &payment_hash, |msg| {
|
||||
run_onion_failure_test("fee_insufficient", 0, &nodes, &route, &payment_hash, &payment_secret, |msg| {
|
||||
msg.amount_msat -= 1;
|
||||
}, || {}, true, Some(UPDATE|12), Some(msgs::HTLCFailChannelUpdate::ChannelClosed { short_channel_id: channels[0].0.contents.short_channel_id, is_permanent: true}));
|
||||
|
||||
run_onion_failure_test("incorrect_cltv_expiry", 0, &nodes, &route, &payment_hash, |msg| {
|
||||
run_onion_failure_test("incorrect_cltv_expiry", 0, &nodes, &route, &payment_hash, &payment_secret, |msg| {
|
||||
// need to violate: cltv_expiry - cltv_expiry_delta >= outgoing_cltv_value
|
||||
msg.cltv_expiry -= 1;
|
||||
}, || {}, true, Some(UPDATE|13), Some(msgs::HTLCFailChannelUpdate::ChannelClosed { short_channel_id: channels[0].0.contents.short_channel_id, is_permanent: true}));
|
||||
|
||||
run_onion_failure_test("expiry_too_soon", 0, &nodes, &route, &payment_hash, |msg| {
|
||||
run_onion_failure_test("expiry_too_soon", 0, &nodes, &route, &payment_hash, &payment_secret, |msg| {
|
||||
let height = msg.cltv_expiry - CLTV_CLAIM_BUFFER - LATENCY_GRACE_PERIOD_BLOCKS + 1;
|
||||
connect_blocks(&nodes[0], height - nodes[0].best_block_info().1);
|
||||
connect_blocks(&nodes[1], height - nodes[1].best_block_info().1);
|
||||
connect_blocks(&nodes[2], height - nodes[2].best_block_info().1);
|
||||
}, ||{}, true, Some(UPDATE|14), Some(msgs::HTLCFailChannelUpdate::ChannelUpdateMessage{msg: ChannelUpdate::dummy()}));
|
||||
|
||||
run_onion_failure_test("unknown_payment_hash", 2, &nodes, &route, &payment_hash, |_| {}, || {
|
||||
nodes[2].node.fail_htlc_backwards(&payment_hash, &None);
|
||||
run_onion_failure_test("unknown_payment_hash", 2, &nodes, &route, &payment_hash, &payment_secret, |_| {}, || {
|
||||
nodes[2].node.fail_htlc_backwards(&payment_hash);
|
||||
}, false, Some(PERM|15), None);
|
||||
let (_, payment_hash, payment_secret) = get_payment_preimage_hash!(nodes[2]);
|
||||
|
||||
run_onion_failure_test("final_expiry_too_soon", 1, &nodes, &route, &payment_hash, |msg| {
|
||||
run_onion_failure_test("final_expiry_too_soon", 1, &nodes, &route, &payment_hash, &payment_secret, |msg| {
|
||||
let height = msg.cltv_expiry - CLTV_CLAIM_BUFFER - LATENCY_GRACE_PERIOD_BLOCKS + 1;
|
||||
connect_blocks(&nodes[0], height - nodes[0].best_block_info().1);
|
||||
connect_blocks(&nodes[1], height - nodes[1].best_block_info().1);
|
||||
connect_blocks(&nodes[2], height - nodes[2].best_block_info().1);
|
||||
}, || {}, true, Some(17), None);
|
||||
|
||||
run_onion_failure_test("final_incorrect_cltv_expiry", 1, &nodes, &route, &payment_hash, |_| {}, || {
|
||||
run_onion_failure_test("final_incorrect_cltv_expiry", 1, &nodes, &route, &payment_hash, &payment_secret, |_| {}, || {
|
||||
for (_, pending_forwards) in nodes[1].node.channel_state.lock().unwrap().forward_htlcs.iter_mut() {
|
||||
for f in pending_forwards.iter_mut() {
|
||||
match f {
|
||||
|
@ -459,7 +462,7 @@ fn test_onion_failure() {
|
|||
}
|
||||
}, true, Some(18), None);
|
||||
|
||||
run_onion_failure_test("final_incorrect_htlc_amount", 1, &nodes, &route, &payment_hash, |_| {}, || {
|
||||
run_onion_failure_test("final_incorrect_htlc_amount", 1, &nodes, &route, &payment_hash, &payment_secret, |_| {}, || {
|
||||
// violate amt_to_forward > msg.amount_msat
|
||||
for (_, pending_forwards) in nodes[1].node.channel_state.lock().unwrap().forward_htlcs.iter_mut() {
|
||||
for f in pending_forwards.iter_mut() {
|
||||
|
@ -472,14 +475,14 @@ fn test_onion_failure() {
|
|||
}
|
||||
}, true, Some(19), None);
|
||||
|
||||
run_onion_failure_test("channel_disabled", 0, &nodes, &route, &payment_hash, |_| {}, || {
|
||||
run_onion_failure_test("channel_disabled", 0, &nodes, &route, &payment_hash, &payment_secret, |_| {}, || {
|
||||
// disconnect event to the channel between nodes[1] ~ nodes[2]
|
||||
nodes[1].node.peer_disconnected(&nodes[2].node.get_our_node_id(), false);
|
||||
nodes[2].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false);
|
||||
}, true, Some(UPDATE|20), Some(msgs::HTLCFailChannelUpdate::ChannelUpdateMessage{msg: ChannelUpdate::dummy()}));
|
||||
reconnect_nodes(&nodes[1], &nodes[2], (false, false), (0, 0), (0, 0), (0, 0), (0, 0), (false, false));
|
||||
|
||||
run_onion_failure_test("expiry_too_far", 0, &nodes, &route, &payment_hash, |msg| {
|
||||
run_onion_failure_test("expiry_too_far", 0, &nodes, &route, &payment_hash, &payment_secret, |msg| {
|
||||
let session_priv = SecretKey::from_slice(&[3; 32]).unwrap();
|
||||
let mut route = route.clone();
|
||||
let height = nodes[2].best_block_info().1;
|
||||
|
|
|
@ -56,10 +56,10 @@ fn do_test_onchain_htlc_reorg(local_commitment: bool, claim: bool) {
|
|||
connect_blocks(&nodes[1], 2*CHAN_CONFIRM_DEPTH + 1 - nodes[1].best_block_info().1);
|
||||
connect_blocks(&nodes[2], 2*CHAN_CONFIRM_DEPTH + 1 - nodes[2].best_block_info().1);
|
||||
|
||||
let (our_payment_preimage, our_payment_hash) = route_payment(&nodes[0], &[&nodes[1], &nodes[2]], 1000000);
|
||||
let (our_payment_preimage, our_payment_hash, _) = route_payment(&nodes[0], &[&nodes[1], &nodes[2]], 1000000);
|
||||
|
||||
// Provide preimage to node 2 by claiming payment
|
||||
nodes[2].node.claim_funds(our_payment_preimage, &None, 1000000);
|
||||
nodes[2].node.claim_funds(our_payment_preimage);
|
||||
check_added_monitors!(nodes[2], 1);
|
||||
get_htlc_update_msgs!(nodes[2], nodes[1].node.get_our_node_id());
|
||||
|
||||
|
@ -301,7 +301,7 @@ fn do_test_unconf_chan(reload_node: bool, reorg_after_reload: bool, use_funding_
|
|||
|
||||
// Now check that we can create a new channel
|
||||
create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known());
|
||||
send_payment(&nodes[0], &[&nodes[1]], 8000000, 8_000_000);
|
||||
send_payment(&nodes[0], &[&nodes[1]], 8000000);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -358,8 +358,8 @@ fn test_set_outpoints_partial_claiming() {
|
|||
|
||||
// Connect blocks on node A to advance height towards TEST_FINAL_CLTV
|
||||
// Provide node A with both preimage
|
||||
nodes[0].node.claim_funds(payment_preimage_1, &None, 3_000_000);
|
||||
nodes[0].node.claim_funds(payment_preimage_2, &None, 3_000_000);
|
||||
nodes[0].node.claim_funds(payment_preimage_1);
|
||||
nodes[0].node.claim_funds(payment_preimage_2);
|
||||
check_added_monitors!(nodes[0], 2);
|
||||
nodes[0].node.get_and_clear_pending_events();
|
||||
nodes[0].node.get_and_clear_pending_msg_events();
|
||||
|
|
|
@ -61,20 +61,37 @@ pub enum Event {
|
|||
PaymentReceived {
|
||||
/// The hash for which the preimage should be handed to the ChannelManager.
|
||||
payment_hash: PaymentHash,
|
||||
/// The preimage to the payment_hash, if the payment hash (and secret) were fetched via
|
||||
/// [`ChannelManager::create_inbound_payment`]. If provided, this can be handed directly to
|
||||
/// [`ChannelManager::claim_funds`].
|
||||
///
|
||||
/// [`ChannelManager::create_inbound_payment`]: crate::ln::channelmanager::ChannelManager::create_inbound_payment
|
||||
/// [`ChannelManager::claim_funds`]: crate::ln::channelmanager::ChannelManager::claim_funds
|
||||
payment_preimage: Option<PaymentPreimage>,
|
||||
/// The "payment secret". This authenticates the sender to the recipient, preventing a
|
||||
/// number of deanonymization attacks during the routing process.
|
||||
/// As nodes upgrade, the invoices you provide should likely migrate to setting the
|
||||
/// payment_secret feature to required, at which point you should fail_backwards any HTLCs
|
||||
/// which have a None here.
|
||||
/// Until then, however, values of None should be ignored, and only incorrect Some values
|
||||
/// should result in an HTLC fail_backwards.
|
||||
/// Note that, in any case, this value must be passed as-is to any fail or claim calls as
|
||||
/// the HTLC index includes this value.
|
||||
payment_secret: Option<PaymentSecret>,
|
||||
/// It is provided here for your reference, however its accuracy is enforced directly by
|
||||
/// [`ChannelManager`] using the values you previously provided to
|
||||
/// [`ChannelManager::create_inbound_payment`] or
|
||||
/// [`ChannelManager::create_inbound_payment_for_hash`].
|
||||
///
|
||||
/// [`ChannelManager`]: crate::ln::channelmanager::ChannelManager
|
||||
/// [`ChannelManager::create_inbound_payment`]: crate::ln::channelmanager::ChannelManager::create_inbound_payment
|
||||
/// [`ChannelManager::create_inbound_payment_for_hash`]: crate::ln::channelmanager::ChannelManager::create_inbound_payment_for_hash
|
||||
payment_secret: PaymentSecret,
|
||||
/// The value, in thousandths of a satoshi, that this payment is for. Note that you must
|
||||
/// compare this to the expected value before accepting the payment (as otherwise you are
|
||||
/// providing proof-of-payment for less than the value you expected!).
|
||||
amt: u64,
|
||||
/// This is the `user_payment_id` which was provided to
|
||||
/// [`ChannelManager::create_inbound_payment_for_hash`] or
|
||||
/// [`ChannelManager::create_inbound_payment`]. It has no meaning inside of LDK and is
|
||||
/// simply copied here. It may be used to correlate PaymentReceived events with invoice
|
||||
/// metadata stored elsewhere.
|
||||
///
|
||||
/// [`ChannelManager::create_inbound_payment`]: crate::ln::channelmanager::ChannelManager::create_inbound_payment
|
||||
/// [`ChannelManager::create_inbound_payment_for_hash`]: crate::ln::channelmanager::ChannelManager::create_inbound_payment_for_hash
|
||||
user_payment_id: u64,
|
||||
},
|
||||
/// Indicates an outbound payment we made succeeded (ie it made it all the way to its target
|
||||
/// and we got back the payment preimage for it).
|
||||
|
@ -129,11 +146,13 @@ impl Writeable for Event {
|
|||
// We never write out FundingGenerationReady events as, upon disconnection, peers
|
||||
// drop any channels which have not yet exchanged funding_signed.
|
||||
},
|
||||
&Event::PaymentReceived { ref payment_hash, ref payment_secret, ref amt } => {
|
||||
&Event::PaymentReceived { ref payment_hash, ref payment_preimage, ref payment_secret, ref amt, ref user_payment_id } => {
|
||||
1u8.write(writer)?;
|
||||
payment_hash.write(writer)?;
|
||||
payment_preimage.write(writer)?;
|
||||
payment_secret.write(writer)?;
|
||||
amt.write(writer)?;
|
||||
user_payment_id.write(writer)?;
|
||||
},
|
||||
&Event::PaymentSent { ref payment_preimage } => {
|
||||
2u8.write(writer)?;
|
||||
|
@ -175,8 +194,10 @@ impl MaybeReadable for Event {
|
|||
0u8 => Ok(None),
|
||||
1u8 => Ok(Some(Event::PaymentReceived {
|
||||
payment_hash: Readable::read(reader)?,
|
||||
payment_preimage: Readable::read(reader)?,
|
||||
payment_secret: Readable::read(reader)?,
|
||||
amt: Readable::read(reader)?,
|
||||
user_payment_id: Readable::read(reader)?,
|
||||
})),
|
||||
2u8 => Ok(Some(Event::PaymentSent {
|
||||
payment_preimage: Readable::read(reader)?,
|
||||
|
|
Loading…
Add table
Reference in a new issue