mirror of
https://github.com/lightningdevkit/rust-lightning.git
synced 2025-02-25 15:20:24 +01:00
Add methods to count total fees and total amount in a Route #999
* Added `get_total_fees` method to route, to calculate all the fees paid accross each path. * Added `get_total_amount` method to route, to calculate the total of actual amounts paid in each path.
This commit is contained in:
parent
4368b56eb6
commit
03bb808e58
1 changed files with 80 additions and 1 deletions
|
@ -71,6 +71,26 @@ pub struct Route {
|
||||||
pub paths: Vec<Vec<RouteHop>>,
|
pub paths: Vec<Vec<RouteHop>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Route {
|
||||||
|
/// Returns the total amount of fees paid on this Route.
|
||||||
|
/// This doesn't include any extra payment made to the recipient,
|
||||||
|
/// which can happen in excess of the amount passed to `get_route`'s `final_value_msat`.
|
||||||
|
pub fn get_total_fees(&self) -> u64 {
|
||||||
|
// Do not count last hop of each path since that's the full value of the payment
|
||||||
|
return self.paths.iter()
|
||||||
|
.flat_map(|path| path.split_last().unwrap().1)
|
||||||
|
.map(|hop| &hop.fee_msat)
|
||||||
|
.sum();
|
||||||
|
}
|
||||||
|
/// Returns the total amount paid on this Route, excluding the fees.
|
||||||
|
pub fn get_total_amount(&self) -> u64 {
|
||||||
|
return self.paths.iter()
|
||||||
|
.map(|path| path.split_last().unwrap().0)
|
||||||
|
.map(|hop| &hop.fee_msat)
|
||||||
|
.sum();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const SERIALIZATION_VERSION: u8 = 1;
|
const SERIALIZATION_VERSION: u8 = 1;
|
||||||
const MIN_SERIALIZATION_VERSION: u8 = 1;
|
const MIN_SERIALIZATION_VERSION: u8 = 1;
|
||||||
|
|
||||||
|
@ -1191,7 +1211,7 @@ pub fn get_route<L: Deref>(our_node_id: &PublicKey, network: &NetworkGraph, paye
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use routing::router::{get_route, Route, RouteHint, RouteHintHop, RoutingFees};
|
use routing::router::{get_route, Route, RouteHint, RouteHintHop, RouteHop, RoutingFees};
|
||||||
use routing::network_graph::{NetworkGraph, NetGraphMsgHandler};
|
use routing::network_graph::{NetworkGraph, NetGraphMsgHandler};
|
||||||
use chain::transaction::OutPoint;
|
use chain::transaction::OutPoint;
|
||||||
use ln::features::{ChannelFeatures, InitFeatures, InvoiceFeatures, NodeFeatures};
|
use ln::features::{ChannelFeatures, InitFeatures, InvoiceFeatures, NodeFeatures};
|
||||||
|
@ -3425,6 +3445,7 @@ mod tests {
|
||||||
total_amount_paid_msat += path.last().unwrap().fee_msat;
|
total_amount_paid_msat += path.last().unwrap().fee_msat;
|
||||||
}
|
}
|
||||||
assert_eq!(total_amount_paid_msat, 200_000);
|
assert_eq!(total_amount_paid_msat, 200_000);
|
||||||
|
assert_eq!(route.get_total_fees(), 150_000);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -3831,6 +3852,64 @@ mod tests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn total_fees_single_path() {
|
||||||
|
let route = Route {
|
||||||
|
paths: vec![vec![
|
||||||
|
RouteHop {
|
||||||
|
pubkey: PublicKey::from_slice(&hex::decode("02eec7245d6b7d2ccb30380bfbe2a3648cd7a942653f5aa340edcea1f283686619").unwrap()[..]).unwrap(),
|
||||||
|
channel_features: ChannelFeatures::empty(), node_features: NodeFeatures::empty(),
|
||||||
|
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
|
||||||
|
},
|
||||||
|
RouteHop {
|
||||||
|
pubkey: PublicKey::from_slice(&hex::decode("0324653eac434488002cc06bbfb7f10fe18991e35f9fe4302dbea6d2353dc0ab1c").unwrap()[..]).unwrap(),
|
||||||
|
channel_features: ChannelFeatures::empty(), node_features: NodeFeatures::empty(),
|
||||||
|
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
|
||||||
|
},
|
||||||
|
RouteHop {
|
||||||
|
pubkey: PublicKey::from_slice(&hex::decode("027f31ebc5462c1fdce1b737ecff52d37d75dea43ce11c74d25aa297165faa2007").unwrap()[..]).unwrap(),
|
||||||
|
channel_features: ChannelFeatures::empty(), node_features: NodeFeatures::empty(),
|
||||||
|
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
|
||||||
|
},
|
||||||
|
]],
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_eq!(route.get_total_fees(), 250);
|
||||||
|
assert_eq!(route.get_total_amount(), 225);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn total_fees_multi_path() {
|
||||||
|
let route = Route {
|
||||||
|
paths: vec![vec![
|
||||||
|
RouteHop {
|
||||||
|
pubkey: PublicKey::from_slice(&hex::decode("02eec7245d6b7d2ccb30380bfbe2a3648cd7a942653f5aa340edcea1f283686619").unwrap()[..]).unwrap(),
|
||||||
|
channel_features: ChannelFeatures::empty(), node_features: NodeFeatures::empty(),
|
||||||
|
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
|
||||||
|
},
|
||||||
|
RouteHop {
|
||||||
|
pubkey: PublicKey::from_slice(&hex::decode("0324653eac434488002cc06bbfb7f10fe18991e35f9fe4302dbea6d2353dc0ab1c").unwrap()[..]).unwrap(),
|
||||||
|
channel_features: ChannelFeatures::empty(), node_features: NodeFeatures::empty(),
|
||||||
|
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
|
||||||
|
},
|
||||||
|
],vec![
|
||||||
|
RouteHop {
|
||||||
|
pubkey: PublicKey::from_slice(&hex::decode("02eec7245d6b7d2ccb30380bfbe2a3648cd7a942653f5aa340edcea1f283686619").unwrap()[..]).unwrap(),
|
||||||
|
channel_features: ChannelFeatures::empty(), node_features: NodeFeatures::empty(),
|
||||||
|
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
|
||||||
|
},
|
||||||
|
RouteHop {
|
||||||
|
pubkey: PublicKey::from_slice(&hex::decode("0324653eac434488002cc06bbfb7f10fe18991e35f9fe4302dbea6d2353dc0ab1c").unwrap()[..]).unwrap(),
|
||||||
|
channel_features: ChannelFeatures::empty(), node_features: NodeFeatures::empty(),
|
||||||
|
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
|
||||||
|
},
|
||||||
|
]],
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_eq!(route.get_total_fees(), 200);
|
||||||
|
assert_eq!(route.get_total_amount(), 300);
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "no-std"))]
|
#[cfg(not(feature = "no-std"))]
|
||||||
pub(super) fn random_init_seed() -> u64 {
|
pub(super) fn random_init_seed() -> u64 {
|
||||||
// Because the default HashMap in std pulls OS randomness, we can use it as a (bad) RNG.
|
// Because the default HashMap in std pulls OS randomness, we can use it as a (bad) RNG.
|
||||||
|
|
Loading…
Add table
Reference in a new issue