Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Forward over substitute channels #1578

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
9864a26
Add `counterparty_node_id` to `short_to_id` map
ViktorTigerstrom May 17, 2022
0780fb9
Rename `short_to_id` map to `short_to_chan_info`
ViktorTigerstrom Jun 9, 2022
7833589
Add id_to_peer map
ViktorTigerstrom Jun 3, 2022
b0975eb
Add `ChannelManager:id_to_peer` map coverage test
ViktorTigerstrom Jun 6, 2022
d3667d9
Add `counterparty_node` to test macros
ViktorTigerstrom May 27, 2022
6c62533
Store channels per-peer
ViktorTigerstrom May 25, 2022
519fcb4
f - Store per peer: aquire locks inside get_channel_ref
ViktorTigerstrom Jun 9, 2022
c37b984
f - Make per_peer_state a FairRwLock
ViktorTigerstrom Jun 6, 2022
f7b51d2
f - Remove unreacable branches that can be reached
ViktorTigerstrom Jun 6, 2022
2c112d7
f - Store channels per-peer: Update per_peer_state docs
ViktorTigerstrom Jun 7, 2022
7b594ee
Remove unnecessary `per_peer_state` branch
ViktorTigerstrom Jun 10, 2022
7e9ac7b
Avoid retaking locks
ViktorTigerstrom Jun 6, 2022
6c4b80d
Update failure to query `Channel` error messages
ViktorTigerstrom Jun 6, 2022
4991456
Add duplicate temporary_channel_id for 2 peers test
ViktorTigerstrom May 31, 2022
ae665ce
Add handle unkown peer test
ViktorTigerstrom Jun 13, 2022
ef4107a
Enable htlc forwarding over substitute channels
ViktorTigerstrom Jun 20, 2022
1d44945
Test htlc forwarding over substitute channels
ViktorTigerstrom Jun 20, 2022
1dec1f9
f - Move creation of CommitmentUpdate structs
ViktorTigerstrom Jun 27, 2022
6b9a261
-f DRY up htlc_msg macros
ViktorTigerstrom Jun 27, 2022
13dbfe3
f - cleanup channel selection order
ViktorTigerstrom Jun 29, 2022
92a067c
f - cleanup tests
ViktorTigerstrom Jun 29, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions lightning/src/ln/chanmon_update_fail_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,9 @@ fn test_monitor_and_persister_update_fail() {
let updates = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id());
assert_eq!(updates.update_fulfill_htlcs.len(), 1);
nodes[0].node.handle_update_fulfill_htlc(&nodes[1].node.get_our_node_id(), &updates.update_fulfill_htlcs[0]);
if let Some(ref mut channel) = nodes[0].node.channel_state.lock().unwrap().by_id.get_mut(&chan.2) {
if let Some(ref mut channel) = nodes[0].node.per_peer_state.write().unwrap().get_mut(&nodes[1].node.get_our_node_id())
.unwrap().lock().unwrap().channel_by_id.get_mut(&chan.2)
{
if let Ok((_, _, update)) = channel.commitment_signed(&updates.commitment_signed, &node_cfgs[0].logger) {
// Check that even though the persister is returning a TemporaryFailure,
// because the update is bogus, ultimately the error that's returned
Expand Down Expand Up @@ -1411,9 +1413,12 @@ fn monitor_failed_no_reestablish_response() {
let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
let channel_id = create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known()).2;
{
let mut lock;
get_channel_ref!(nodes[0], lock, channel_id).announcement_sigs_state = AnnouncementSigsState::PeerReceived;
get_channel_ref!(nodes[1], lock, channel_id).announcement_sigs_state = AnnouncementSigsState::PeerReceived;
let mut node_0_per_peer_lock;
let mut node_0_peer_state_lock;
let mut node_1_per_peer_lock;
let mut node_1_peer_state_lock;
get_channel_ref!(nodes[0], nodes[1], node_0_per_peer_lock, node_0_peer_state_lock, channel_id).announcement_sigs_state = AnnouncementSigsState::PeerReceived;
get_channel_ref!(nodes[1], nodes[0], node_1_per_peer_lock, node_1_peer_state_lock, channel_id).announcement_sigs_state = AnnouncementSigsState::PeerReceived;
}

// Route the payment and deliver the initial commitment_signed (with a monitor update failure
Expand Down
5 changes: 3 additions & 2 deletions lightning/src/ln/channel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4828,8 +4828,9 @@ impl<Signer: Sign> Channel<Signer> {
// the funding transaction is at least still in the mempool of most nodes).
//
// Note that ideally we wouldn't force-close if we see *any* reorg on a 1-conf or
// 0-conf channel, but not doing so may lead to the `ChannelManager::short_to_id` map
// being inconsistent, so we currently have to.
// 0-conf channel, but not doing so may lead to the
// `ChannelManager::short_to_chan_info` map being inconsistent, so we currently have
// to.
if funding_tx_confirmations == 0 && self.funding_tx_confirmed_in.is_some() {
let err_reason = format!("Funding transaction was un-confirmed. Locked at {} confs, now have {} confs.",
self.minimum_depth.unwrap(), funding_tx_confirmations);
Expand Down
3,000 changes: 1,832 additions & 1,168 deletions lightning/src/ln/channelmanager.rs

Large diffs are not rendered by default.

42 changes: 26 additions & 16 deletions lightning/src/ln/functional_test_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -510,31 +510,34 @@ macro_rules! get_htlc_update_msgs {

#[cfg(test)]
macro_rules! get_channel_ref {
($node: expr, $lock: ident, $channel_id: expr) => {
($node: expr, $counterparty_node: expr, $per_peer_state_lock: ident, $peer_state_lock: ident, $channel_id: expr) => {
{
$lock = $node.node.channel_state.lock().unwrap();
$lock.by_id.get_mut(&$channel_id).unwrap()
$per_peer_state_lock = $node.node.per_peer_state.write().unwrap();
$peer_state_lock = $per_peer_state_lock.get(&$counterparty_node.node.get_our_node_id()).unwrap().lock().unwrap();
$peer_state_lock.channel_by_id.get_mut(&$channel_id).unwrap()
}
}
}

#[cfg(test)]
macro_rules! get_feerate {
($node: expr, $channel_id: expr) => {
($node: expr, $counterparty_node: expr, $channel_id: expr) => {
{
let mut lock;
let chan = get_channel_ref!($node, lock, $channel_id);
let mut per_peer_state_lock;
let mut peer_state_lock;
let chan = get_channel_ref!($node, $counterparty_node, per_peer_state_lock, peer_state_lock, $channel_id);
chan.get_feerate()
}
}
}

#[cfg(test)]
macro_rules! get_opt_anchors {
($node: expr, $channel_id: expr) => {
($node: expr, $counterparty_node: expr, $channel_id: expr) => {
{
let mut lock;
let chan = get_channel_ref!($node, lock, $channel_id);
let mut per_peer_state_lock;
let mut peer_state_lock;
let chan = get_channel_ref!($node, $counterparty_node, per_peer_state_lock, peer_state_lock, $channel_id);
chan.opt_anchors()
}
}
Expand Down Expand Up @@ -1558,12 +1561,18 @@ pub fn send_along_route_with_secret<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>,
payment_id
}

pub fn do_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, clear_recipient_events: bool, expected_preimage: Option<PaymentPreimage>) {
pub fn do_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, clear_recipient_events: bool, expected_preimage: Option<PaymentPreimage>, expected_channels: Option<&Vec<[u8; 32]>>) {
let mut payment_event = SendEvent::from_event(ev);
let mut prev_node = origin_node;
if let Some(channel_ids) = expected_channels {
assert_eq!(expected_path.len(), channel_ids.len());
}

for (idx, &node) in expected_path.iter().enumerate() {
assert_eq!(node.node.get_our_node_id(), payment_event.node_id);
if let Some(channel_ids) = expected_channels {
assert_eq!(payment_event.msgs[0].channel_id, channel_ids[idx]);
}

node.node.handle_update_add_htlc(&prev_node.node.get_our_node_id(), &payment_event.msgs[0]);
check_added_monitors!(node, 0);
Expand Down Expand Up @@ -1608,7 +1617,7 @@ pub fn do_pass_along_path<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_p
}

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, expected_preimage: Option<PaymentPreimage>) {
do_pass_along_path(origin_node, expected_path, recv_value, our_payment_hash, our_payment_secret, ev, payment_received_expected, true, expected_preimage);
do_pass_along_path(origin_node, expected_path, recv_value, our_payment_hash, our_payment_secret, ev, payment_received_expected, true, expected_preimage, None);
}

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) {
Expand Down Expand Up @@ -1689,8 +1698,8 @@ pub fn do_claim_payment_along_route<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>,
($node: expr, $prev_node: expr, $next_node: expr, $new_msgs: expr) => {
{
$node.node.handle_update_fulfill_htlc(&$prev_node.node.get_our_node_id(), &next_msgs.as_ref().unwrap().0);
let fee = $node.node.channel_state.lock().unwrap()
.by_id.get(&next_msgs.as_ref().unwrap().0.channel_id).unwrap()
let fee = $node.node.per_peer_state.read().unwrap().get(&$prev_node.node.get_our_node_id())
.unwrap().lock().unwrap().channel_by_id.get(&next_msgs.as_ref().unwrap().0.channel_id).unwrap()
.config.options.forwarding_fee_base_msat;
expect_payment_forwarded!($node, $next_node, $prev_node, Some(fee as u64), false, false);
expected_total_fee_msat += fee as u64;
Expand Down Expand Up @@ -2181,9 +2190,10 @@ pub fn get_announce_close_broadcast_events<'a, 'b, 'c>(nodes: &Vec<Node<'a, 'b,

#[cfg(test)]
macro_rules! get_channel_value_stat {
($node: expr, $channel_id: expr) => {{
let chan_lock = $node.node.channel_state.lock().unwrap();
let chan = chan_lock.by_id.get(&$channel_id).unwrap();
($node: expr, $counterparty_node: expr, $channel_id: expr) => {{
let peer_state_lock = $node.node.per_peer_state.read().unwrap();
let chan_lock = peer_state_lock.get(&$counterparty_node.node.get_our_node_id()).unwrap().lock().unwrap();
let chan = chan_lock.channel_by_id.get(&$channel_id).unwrap();
chan.get_value_stat()
}}
}
Expand Down
Loading