Skip to content

Commit 447148d

Browse files
committed
Add test coverage for process_onion_failure
1 parent eaeed77 commit 447148d

File tree

1 file changed

+105
-30
lines changed

1 file changed

+105
-30
lines changed

lightning/src/ln/onion_utils.rs

Lines changed: 105 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1764,7 +1764,10 @@ fn decode_next_hop<T, R: ReadableArgs<T>, N: NextPacketBytes>(
17641764

17651765
#[cfg(test)]
17661766
mod tests {
1767+
use std::sync::Arc;
1768+
17671769
use crate::io;
1770+
use crate::ln::channelmanager::PaymentId;
17681771
use crate::ln::msgs;
17691772
use crate::routing::router::{Path, PaymentParameters, Route, RouteHop};
17701773
use crate::types::features::{ChannelFeatures, NodeFeatures};
@@ -1773,6 +1776,7 @@ mod tests {
17731776

17741777
#[allow(unused_imports)]
17751778
use crate::prelude::*;
1779+
use crate::util::test_utils::TestLogger;
17761780

17771781
use bitcoin::hex::FromHex;
17781782
use bitcoin::secp256k1::Secp256k1;
@@ -1785,40 +1789,95 @@ mod tests {
17851789
SecretKey::from_slice(&<Vec<u8>>::from_hex(hex).unwrap()[..]).unwrap()
17861790
}
17871791

1792+
fn build_test_path() -> Path {
1793+
Path {
1794+
hops: vec![
1795+
RouteHop {
1796+
pubkey: PublicKey::from_slice(
1797+
&<Vec<u8>>::from_hex(
1798+
"02eec7245d6b7d2ccb30380bfbe2a3648cd7a942653f5aa340edcea1f283686619",
1799+
)
1800+
.unwrap()[..],
1801+
)
1802+
.unwrap(),
1803+
channel_features: ChannelFeatures::empty(),
1804+
node_features: NodeFeatures::empty(),
1805+
short_channel_id: 0,
1806+
fee_msat: 0,
1807+
cltv_expiry_delta: 0,
1808+
maybe_announced_channel: true, // We fill in the payloads manually instead of generating them from RouteHops.
1809+
},
1810+
RouteHop {
1811+
pubkey: PublicKey::from_slice(
1812+
&<Vec<u8>>::from_hex(
1813+
"0324653eac434488002cc06bbfb7f10fe18991e35f9fe4302dbea6d2353dc0ab1c",
1814+
)
1815+
.unwrap()[..],
1816+
)
1817+
.unwrap(),
1818+
channel_features: ChannelFeatures::empty(),
1819+
node_features: NodeFeatures::empty(),
1820+
short_channel_id: 1,
1821+
fee_msat: 0,
1822+
cltv_expiry_delta: 0,
1823+
maybe_announced_channel: true, // We fill in the payloads manually instead of generating them from RouteHops.
1824+
},
1825+
RouteHop {
1826+
pubkey: PublicKey::from_slice(
1827+
&<Vec<u8>>::from_hex(
1828+
"027f31ebc5462c1fdce1b737ecff52d37d75dea43ce11c74d25aa297165faa2007",
1829+
)
1830+
.unwrap()[..],
1831+
)
1832+
.unwrap(),
1833+
channel_features: ChannelFeatures::empty(),
1834+
node_features: NodeFeatures::empty(),
1835+
short_channel_id: 2,
1836+
fee_msat: 0,
1837+
cltv_expiry_delta: 0,
1838+
maybe_announced_channel: true, // We fill in the payloads manually instead of generating them from RouteHops.
1839+
},
1840+
RouteHop {
1841+
pubkey: PublicKey::from_slice(
1842+
&<Vec<u8>>::from_hex(
1843+
"032c0b7cf95324a07d05398b240174dc0c2be444d96b159aa6c7f7b1e668680991",
1844+
)
1845+
.unwrap()[..],
1846+
)
1847+
.unwrap(),
1848+
channel_features: ChannelFeatures::empty(),
1849+
node_features: NodeFeatures::empty(),
1850+
short_channel_id: 3,
1851+
fee_msat: 0,
1852+
cltv_expiry_delta: 0,
1853+
maybe_announced_channel: true, // We fill in the payloads manually instead of generating them from RouteHops.
1854+
},
1855+
RouteHop {
1856+
pubkey: PublicKey::from_slice(
1857+
&<Vec<u8>>::from_hex(
1858+
"02edabbd16b41c8371b92ef2f04c1185b4f03b6dcd52ba9b78d9d7c89c8f221145",
1859+
)
1860+
.unwrap()[..],
1861+
)
1862+
.unwrap(),
1863+
channel_features: ChannelFeatures::empty(),
1864+
node_features: NodeFeatures::empty(),
1865+
short_channel_id: 4,
1866+
fee_msat: 0,
1867+
cltv_expiry_delta: 0,
1868+
maybe_announced_channel: true, // We fill in the payloads manually instead of generating them from RouteHops.
1869+
},
1870+
],
1871+
blinded_tail: None,
1872+
}
1873+
}
1874+
17881875
fn build_test_onion_keys() -> Vec<OnionKeys> {
17891876
// Keys from BOLT 4, used in both test vector tests
17901877
let secp_ctx = Secp256k1::new();
17911878

1792-
let route = Route {
1793-
paths: vec![Path { hops: vec![
1794-
RouteHop {
1795-
pubkey: PublicKey::from_slice(&<Vec<u8>>::from_hex("02eec7245d6b7d2ccb30380bfbe2a3648cd7a942653f5aa340edcea1f283686619").unwrap()[..]).unwrap(),
1796-
channel_features: ChannelFeatures::empty(), node_features: NodeFeatures::empty(),
1797-
short_channel_id: 0, fee_msat: 0, cltv_expiry_delta: 0, maybe_announced_channel: true, // We fill in the payloads manually instead of generating them from RouteHops.
1798-
},
1799-
RouteHop {
1800-
pubkey: PublicKey::from_slice(&<Vec<u8>>::from_hex("0324653eac434488002cc06bbfb7f10fe18991e35f9fe4302dbea6d2353dc0ab1c").unwrap()[..]).unwrap(),
1801-
channel_features: ChannelFeatures::empty(), node_features: NodeFeatures::empty(),
1802-
short_channel_id: 0, fee_msat: 0, cltv_expiry_delta: 0, maybe_announced_channel: true, // We fill in the payloads manually instead of generating them from RouteHops.
1803-
},
1804-
RouteHop {
1805-
pubkey: PublicKey::from_slice(&<Vec<u8>>::from_hex("027f31ebc5462c1fdce1b737ecff52d37d75dea43ce11c74d25aa297165faa2007").unwrap()[..]).unwrap(),
1806-
channel_features: ChannelFeatures::empty(), node_features: NodeFeatures::empty(),
1807-
short_channel_id: 0, fee_msat: 0, cltv_expiry_delta: 0, maybe_announced_channel: true, // We fill in the payloads manually instead of generating them from RouteHops.
1808-
},
1809-
RouteHop {
1810-
pubkey: PublicKey::from_slice(&<Vec<u8>>::from_hex("032c0b7cf95324a07d05398b240174dc0c2be444d96b159aa6c7f7b1e668680991").unwrap()[..]).unwrap(),
1811-
channel_features: ChannelFeatures::empty(), node_features: NodeFeatures::empty(),
1812-
short_channel_id: 0, fee_msat: 0, cltv_expiry_delta: 0, maybe_announced_channel: true, // We fill in the payloads manually instead of generating them from RouteHops.
1813-
},
1814-
RouteHop {
1815-
pubkey: PublicKey::from_slice(&<Vec<u8>>::from_hex("02edabbd16b41c8371b92ef2f04c1185b4f03b6dcd52ba9b78d9d7c89c8f221145").unwrap()[..]).unwrap(),
1816-
channel_features: ChannelFeatures::empty(), node_features: NodeFeatures::empty(),
1817-
short_channel_id: 0, fee_msat: 0, cltv_expiry_delta: 0, maybe_announced_channel: true, // We fill in the payloads manually instead of generating them from RouteHops.
1818-
},
1819-
], blinded_tail: None }],
1820-
route_params: None,
1821-
};
1879+
let path = build_test_path();
1880+
let route = Route { paths: vec![path], route_params: None };
18221881

18231882
let onion_keys =
18241883
super::construct_onion_keys(&secp_ctx, &route.paths[0], &get_test_session_key())
@@ -2078,6 +2137,22 @@ mod tests {
20782137
);
20792138
let hex = "9c5add3963fc7f6ed7f148623c84134b5647e1306419dbe2174e523fa9e2fbed3a06a19f899145610741c83ad40b7712aefaddec8c6baf7325d92ea4ca4d1df8bce517f7e54554608bf2bd8071a4f52a7a2f7ffbb1413edad81eeea5785aa9d990f2865dc23b4bc3c301a94eec4eabebca66be5cf638f693ec256aec514620cc28ee4a94bd9565bc4d4962b9d3641d4278fb319ed2b84de5b665f307a2db0f7fbb757366067d88c50f7e829138fde4f78d39b5b5802f1b92a8a820865af5cc79f9f30bc3f461c66af95d13e5e1f0381c184572a91dee1c849048a647a1158cf884064deddbf1b0b88dfe2f791428d0ba0f6fb2f04e14081f69165ae66d9297c118f0907705c9c4954a199bae0bb96fad763d690e7daa6cfda59ba7f2c8d11448b604d12d";
20802139
assert_eq!(onion_packet_5.data, <Vec<u8>>::from_hex(hex).unwrap());
2140+
2141+
let logger: Arc<TestLogger> = Arc::new(TestLogger::new());
2142+
let ctx_full = Secp256k1::new();
2143+
let path = build_test_path();
2144+
let htlc_source = HTLCSource::OutboundRoute {
2145+
path,
2146+
session_priv: get_test_session_key(),
2147+
first_hop_htlc_msat: 0,
2148+
payment_id: PaymentId([1; 32]),
2149+
};
2150+
2151+
// Assert that the original failure can be retrieved and that all hmacs check out.
2152+
let decrypted_failure =
2153+
process_onion_failure(&ctx_full, &logger, &htlc_source, onion_packet_5.data);
2154+
2155+
assert_eq!(decrypted_failure.onion_error_code, Some(0x2002));
20812156
}
20822157

20832158
struct RawOnionHopData {

0 commit comments

Comments
 (0)