Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
91 changes: 91 additions & 0 deletions lightning/src/ln/accountable_tests.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
use crate::ln::channelmanager::{
HTLCForwardInfo, PaymentId, PendingAddHTLCInfo, PendingHTLCInfo, RecipientOnionFields, Retry,
};
use crate::ln::functional_test_utils::*;
use crate::ln::msgs::{accountable_from_bool, ChannelMessageHandler, ExperimentalAccountable};
use crate::routing::router::{PaymentParameters, RouteParameters};

fn test_accountable_forwarding_with_override(
override_accountable: ExperimentalAccountable, expected_forwarded: bool,
) {
let chanmon_cfgs = create_chanmon_cfgs(3);
let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
let nodes = create_network(3, &node_cfgs, &node_chanmgrs);

let _chan_ab = create_announced_chan_between_nodes(&nodes, 0, 1);
let _chan_bc = create_announced_chan_between_nodes(&nodes, 1, 2);

let (payment_preimage, payment_hash, payment_secret) = get_payment_preimage_hash!(nodes[2]);
let route_params = RouteParameters::from_payment_params_and_value(
PaymentParameters::from_node_id(nodes[2].node.get_our_node_id(), TEST_FINAL_CLTV),
100_000,
);
let onion_fields = RecipientOnionFields::secret_only(payment_secret);
let payment_id = PaymentId(payment_hash.0);
nodes[0]
.node
.send_payment(payment_hash, onion_fields, payment_id, route_params, Retry::Attempts(0))
.unwrap();
check_added_monitors(&nodes[0], 1);

let updates_ab = get_htlc_update_msgs(&nodes[0], &nodes[1].node.get_our_node_id());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like this test does not cover the serialization logic of UpdateAddHTLC with the new accountable field - we pass the struct itself from node to node. Would be cool have a separate test where UpdateAddHTLC is serialized to the wire format, and transmits the accountable signal that way.

assert_eq!(updates_ab.update_add_htlcs.len(), 1);
let mut htlc_ab = updates_ab.update_add_htlcs[0].clone();
assert_eq!(htlc_ab.accountable, accountable_from_bool(false));

// Override accountable value if requested
if let Some(override_value) = override_accountable {
htlc_ab.accountable = Some(override_value);
}

nodes[1].node.handle_update_add_htlc(nodes[0].node.get_our_node_id(), &htlc_ab);
do_commitment_signed_dance(&nodes[1], &nodes[0], &updates_ab.commitment_signed, false, false);
expect_and_process_pending_htlcs(&nodes[1], false);
check_added_monitors(&nodes[1], 1);

let updates_bc = get_htlc_update_msgs(&nodes[1], &nodes[2].node.get_our_node_id());
assert_eq!(updates_bc.update_add_htlcs.len(), 1);
let htlc_bc = &updates_bc.update_add_htlcs[0];
let expected_acountable_signal = accountable_from_bool(expected_forwarded);
assert_eq!(
htlc_bc.accountable, expected_acountable_signal,
"B -> C should have accountable = {:?}",
expected_acountable_signal
);

nodes[2].node.handle_update_add_htlc(nodes[1].node.get_our_node_id(), htlc_bc);
do_commitment_signed_dance(&nodes[2], &nodes[1], &updates_bc.commitment_signed, false, false);

// Accountable signal is not surfaced in PaymentClaimable, so we do our next-best and check
// that the received htlcs that will be processed has the signal set as we expect. We manually
// process pending update adds so that we can access the htlc in forward_htlcs.
nodes[2].node.test_process_pending_update_add_htlcs();
{
let fwds_lock = nodes[2].node.forward_htlcs.lock().unwrap();
let recvs = fwds_lock.get(&0).unwrap();
assert_eq!(recvs.len(), 1);
match recvs[0] {
HTLCForwardInfo::AddHTLC(PendingAddHTLCInfo {
forward_info: PendingHTLCInfo { incoming_accountable, .. },
..
}) => {
assert_eq!(incoming_accountable, expected_forwarded)
},
_ => panic!("Unexpected forward"),
}
}

expect_and_process_pending_htlcs(&nodes[2], false);
check_added_monitors(&nodes[2], 0);
expect_payment_claimable!(nodes[2], payment_hash, payment_secret, 100_000);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

didn't give it a shot mysef, could dig into the PendingHTLCInfo of node 2 here to cover the create_recv_pending_htlc_info case ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will do - should be possible to grab it out of the recipient's forward_htlcs and check it there.

claim_payment(&nodes[0], &[&nodes[1], &nodes[2]], payment_preimage);
}

#[test]
fn test_accountable_signal() {
// Tests forwarding of accountable signal for various incoming signal values.
test_accountable_forwarding_with_override(None, false);
test_accountable_forwarding_with_override(Some(7), true);
test_accountable_forwarding_with_override(Some(3), false);
}
1 change: 1 addition & 0 deletions lightning/src/ln/blinded_payment_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1526,6 +1526,7 @@ fn update_add_msg(
skimmed_fee_msat: None,
blinding_point,
hold_htlc: None,
accountable: None,
}
}

Expand Down
Loading
Loading