Skip to content

Commit 8f78bbd

Browse files
authored
Merge pull request #1063 from galderz/t_total_fee_999
Add method to count total fees in a Route #999
2 parents 801d6e5 + 03bb808 commit 8f78bbd

File tree

1 file changed

+80
-1
lines changed

1 file changed

+80
-1
lines changed

lightning/src/routing/router.rs

Lines changed: 80 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,26 @@ pub struct Route {
7171
pub paths: Vec<Vec<RouteHop>>,
7272
}
7373

74+
impl Route {
75+
/// Returns the total amount of fees paid on this Route.
76+
/// This doesn't include any extra payment made to the recipient,
77+
/// which can happen in excess of the amount passed to `get_route`'s `final_value_msat`.
78+
pub fn get_total_fees(&self) -> u64 {
79+
// Do not count last hop of each path since that's the full value of the payment
80+
return self.paths.iter()
81+
.flat_map(|path| path.split_last().unwrap().1)
82+
.map(|hop| &hop.fee_msat)
83+
.sum();
84+
}
85+
/// Returns the total amount paid on this Route, excluding the fees.
86+
pub fn get_total_amount(&self) -> u64 {
87+
return self.paths.iter()
88+
.map(|path| path.split_last().unwrap().0)
89+
.map(|hop| &hop.fee_msat)
90+
.sum();
91+
}
92+
}
93+
7494
const SERIALIZATION_VERSION: u8 = 1;
7595
const MIN_SERIALIZATION_VERSION: u8 = 1;
7696

@@ -1245,7 +1265,7 @@ pub fn get_route<L: Deref>(our_node_id: &PublicKey, network: &NetworkGraph, paye
12451265

12461266
#[cfg(test)]
12471267
mod tests {
1248-
use routing::router::{get_route, Route, RouteHint, RouteHintHop, RoutingFees};
1268+
use routing::router::{get_route, Route, RouteHint, RouteHintHop, RouteHop, RoutingFees};
12491269
use routing::network_graph::{NetworkGraph, NetGraphMsgHandler};
12501270
use chain::transaction::OutPoint;
12511271
use ln::features::{ChannelFeatures, InitFeatures, InvoiceFeatures, NodeFeatures};
@@ -3791,6 +3811,7 @@ mod tests {
37913811
total_amount_paid_msat += path.last().unwrap().fee_msat;
37923812
}
37933813
assert_eq!(total_amount_paid_msat, 200_000);
3814+
assert_eq!(route.get_total_fees(), 150_000);
37943815
}
37953816

37963817
}
@@ -4198,6 +4219,64 @@ mod tests {
41984219
}
41994220
}
42004221

4222+
#[test]
4223+
fn total_fees_single_path() {
4224+
let route = Route {
4225+
paths: vec![vec![
4226+
RouteHop {
4227+
pubkey: PublicKey::from_slice(&hex::decode("02eec7245d6b7d2ccb30380bfbe2a3648cd7a942653f5aa340edcea1f283686619").unwrap()[..]).unwrap(),
4228+
channel_features: ChannelFeatures::empty(), node_features: NodeFeatures::empty(),
4229+
short_channel_id: 0, fee_msat: 100, cltv_expiry_delta: 0 // Test vectors are garbage and not generateble from a RouteHop, we fill in payloads manually
4230+
},
4231+
RouteHop {
4232+
pubkey: PublicKey::from_slice(&hex::decode("0324653eac434488002cc06bbfb7f10fe18991e35f9fe4302dbea6d2353dc0ab1c").unwrap()[..]).unwrap(),
4233+
channel_features: ChannelFeatures::empty(), node_features: NodeFeatures::empty(),
4234+
short_channel_id: 0, fee_msat: 150, cltv_expiry_delta: 0 // Test vectors are garbage and not generateble from a RouteHop, we fill in payloads manually
4235+
},
4236+
RouteHop {
4237+
pubkey: PublicKey::from_slice(&hex::decode("027f31ebc5462c1fdce1b737ecff52d37d75dea43ce11c74d25aa297165faa2007").unwrap()[..]).unwrap(),
4238+
channel_features: ChannelFeatures::empty(), node_features: NodeFeatures::empty(),
4239+
short_channel_id: 0, fee_msat: 225, cltv_expiry_delta: 0 // Test vectors are garbage and not generateble from a RouteHop, we fill in payloads manually
4240+
},
4241+
]],
4242+
};
4243+
4244+
assert_eq!(route.get_total_fees(), 250);
4245+
assert_eq!(route.get_total_amount(), 225);
4246+
}
4247+
4248+
#[test]
4249+
fn total_fees_multi_path() {
4250+
let route = Route {
4251+
paths: vec![vec![
4252+
RouteHop {
4253+
pubkey: PublicKey::from_slice(&hex::decode("02eec7245d6b7d2ccb30380bfbe2a3648cd7a942653f5aa340edcea1f283686619").unwrap()[..]).unwrap(),
4254+
channel_features: ChannelFeatures::empty(), node_features: NodeFeatures::empty(),
4255+
short_channel_id: 0, fee_msat: 100, cltv_expiry_delta: 0 // Test vectors are garbage and not generateble from a RouteHop, we fill in payloads manually
4256+
},
4257+
RouteHop {
4258+
pubkey: PublicKey::from_slice(&hex::decode("0324653eac434488002cc06bbfb7f10fe18991e35f9fe4302dbea6d2353dc0ab1c").unwrap()[..]).unwrap(),
4259+
channel_features: ChannelFeatures::empty(), node_features: NodeFeatures::empty(),
4260+
short_channel_id: 0, fee_msat: 150, cltv_expiry_delta: 0 // Test vectors are garbage and not generateble from a RouteHop, we fill in payloads manually
4261+
},
4262+
],vec![
4263+
RouteHop {
4264+
pubkey: PublicKey::from_slice(&hex::decode("02eec7245d6b7d2ccb30380bfbe2a3648cd7a942653f5aa340edcea1f283686619").unwrap()[..]).unwrap(),
4265+
channel_features: ChannelFeatures::empty(), node_features: NodeFeatures::empty(),
4266+
short_channel_id: 0, fee_msat: 100, cltv_expiry_delta: 0 // Test vectors are garbage and not generateble from a RouteHop, we fill in payloads manually
4267+
},
4268+
RouteHop {
4269+
pubkey: PublicKey::from_slice(&hex::decode("0324653eac434488002cc06bbfb7f10fe18991e35f9fe4302dbea6d2353dc0ab1c").unwrap()[..]).unwrap(),
4270+
channel_features: ChannelFeatures::empty(), node_features: NodeFeatures::empty(),
4271+
short_channel_id: 0, fee_msat: 150, cltv_expiry_delta: 0 // Test vectors are garbage and not generateble from a RouteHop, we fill in payloads manually
4272+
},
4273+
]],
4274+
};
4275+
4276+
assert_eq!(route.get_total_fees(), 200);
4277+
assert_eq!(route.get_total_amount(), 300);
4278+
}
4279+
42014280
#[cfg(not(feature = "no-std"))]
42024281
pub(super) fn random_init_seed() -> u64 {
42034282
// Because the default HashMap in std pulls OS randomness, we can use it as a (bad) RNG.

0 commit comments

Comments
 (0)