Skip to content

Commit ada2a7f

Browse files
committed
tests: Add unit tests for PeerManager
Use the newly abstracted Transport layer to write unit tests for most of the PeerManager functionality. This uses dependency inversion with the PeerManager to pass in a Transport test double that is configured to exercise the interesting code paths. To enable this, a new struct PeerManagerImpl has been created that has all of the original functionality of PeerManager, but includes a type parameter for the Transport implementation that should be used. To keep this test-feature hidden from public docs, the PeerManager struct is now just a shim that delegates all the calls to PeerManagerImpl. This provides a nice balance of a clean public interface with the features needed to create isolated tests. The tests make use of the Spy and Stub test patterns to control input state and validate the output state.
1 parent 94721bd commit ada2a7f

File tree

8 files changed

+2648
-102
lines changed

8 files changed

+2648
-102
lines changed

lightning/src/ln/features.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -480,6 +480,10 @@ impl<T: sealed::StaticRemoteKey> Features<T> {
480480
pub(crate) fn requires_static_remote_key(&self) -> bool {
481481
<T as sealed::StaticRemoteKey>::requires_feature(&self.flags)
482482
}
483+
#[cfg(test)]
484+
pub(crate) fn clear_requires_static_remote_key(&mut self) {
485+
<T as sealed::StaticRemoteKey>::clear_bits(&mut self.flags)
486+
}
483487
}
484488

485489
impl<T: sealed::InitialRoutingSync> Features<T> {

lightning/src/ln/msgs.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -460,6 +460,7 @@ pub enum ErrorAction {
460460
}
461461

462462
/// An Err type for failure to process messages.
463+
#[derive(Clone)]
463464
pub struct LightningError {
464465
/// A human-readable message describing the error
465466
pub err: &'static str,

lightning/src/ln/peers/handler.rs

Lines changed: 1943 additions & 95 deletions
Large diffs are not rendered by default.

lightning/src/ln/peers/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@
77
#[macro_use]
88
mod test_util;
99

10+
#[cfg(test)]
11+
#[macro_use]
12+
mod test_message_macros;
13+
1014
mod chacha;
1115
pub mod handler;
1216
mod hkdf5869rfc;
Lines changed: 268 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,268 @@
1+
/// Helper macros that construct fake Messages. Useful in tests that don't care about the contents.
2+
3+
macro_rules! fake_public_key {
4+
() => {{
5+
let their_node_secret = SecretKey::from_slice(&[0x_11_u8; 32]).unwrap();
6+
PublicKey::from_secret_key(&Secp256k1::new(), &their_node_secret)
7+
}}
8+
}
9+
10+
macro_rules! fake_valid_sig {
11+
() => {{
12+
use bitcoin::secp256k1::ffi::Signature as FFISignature;
13+
Signature::from(FFISignature::new())
14+
}}
15+
}
16+
17+
macro_rules! fake_open_channel_msg {
18+
() => {{
19+
OpenChannel {
20+
chain_hash: Default::default(),
21+
temporary_channel_id: [0; 32],
22+
funding_satoshis: 0,
23+
push_msat: 0,
24+
dust_limit_satoshis: 0,
25+
max_htlc_value_in_flight_msat: 0,
26+
channel_reserve_satoshis: 0,
27+
htlc_minimum_msat: 0,
28+
feerate_per_kw: 0,
29+
to_self_delay: 0,
30+
max_accepted_htlcs: 0,
31+
funding_pubkey: fake_public_key!(),
32+
revocation_basepoint: fake_public_key!(),
33+
delayed_payment_basepoint: fake_public_key!(),
34+
htlc_basepoint: fake_public_key!(),
35+
payment_point: fake_public_key!(),
36+
first_per_commitment_point: fake_public_key!(),
37+
channel_flags: 0,
38+
shutdown_scriptpubkey: OptionalField::Absent
39+
}
40+
}}
41+
}
42+
43+
macro_rules! fake_accept_channel_msg {
44+
() => {{
45+
AcceptChannel {
46+
temporary_channel_id: [0; 32],
47+
dust_limit_satoshis: 0,
48+
max_htlc_value_in_flight_msat: 0,
49+
channel_reserve_satoshis: 0,
50+
htlc_minimum_msat: 0,
51+
minimum_depth: 0,
52+
to_self_delay: 0,
53+
max_accepted_htlcs: 0,
54+
funding_pubkey: fake_public_key!(),
55+
revocation_basepoint: fake_public_key!(),
56+
payment_point: fake_public_key!(),
57+
delayed_payment_basepoint: fake_public_key!(),
58+
htlc_basepoint: fake_public_key!(),
59+
first_per_commitment_point: fake_public_key!(),
60+
shutdown_scriptpubkey: OptionalField::Absent
61+
}
62+
}}
63+
}
64+
macro_rules! fake_funding_created_msg {
65+
() => {{
66+
FundingCreated {
67+
temporary_channel_id: [0; 32],
68+
funding_txid: Default::default(),
69+
funding_output_index: 0,
70+
signature: fake_valid_sig!()
71+
}
72+
}}
73+
}
74+
75+
macro_rules! fake_funding_signed_msg {
76+
() => {{
77+
FundingSigned {
78+
channel_id: [0; 32],
79+
signature: fake_valid_sig!()
80+
}
81+
}}
82+
}
83+
84+
macro_rules! fake_funding_locked_msg {
85+
() => {{
86+
FundingLocked {
87+
channel_id: [0; 32],
88+
next_per_commitment_point: fake_public_key!()
89+
}
90+
}}
91+
}
92+
93+
macro_rules! fake_shutdown_msg {
94+
() => {{
95+
Shutdown {
96+
channel_id: [0; 32],
97+
scriptpubkey: Default::default()
98+
}
99+
}}
100+
}
101+
102+
macro_rules! fake_closing_signed_msg {
103+
() => {{
104+
ClosingSigned {
105+
channel_id: [0; 32],
106+
fee_satoshis: 0,
107+
signature: fake_valid_sig!()
108+
}
109+
}}
110+
}
111+
112+
macro_rules! fake_update_add_htlc_msg {
113+
() => {{
114+
UpdateAddHTLC {
115+
channel_id: [0; 32],
116+
htlc_id: 0,
117+
amount_msat: 0,
118+
payment_hash: PaymentHash([0; 32]),
119+
cltv_expiry: 0,
120+
onion_routing_packet: OnionPacket {
121+
version: 0,
122+
public_key: Ok(fake_public_key!()),
123+
hop_data: [0; 1300],
124+
hmac: [0; 32]
125+
}
126+
}
127+
}}
128+
}
129+
130+
macro_rules! fake_update_fulfill_htlc_msg {
131+
() => {{
132+
UpdateFulfillHTLC {
133+
channel_id: [0; 32],
134+
htlc_id: 0,
135+
payment_preimage: PaymentPreimage([0; 32])
136+
}
137+
}}
138+
}
139+
140+
141+
macro_rules! fake_update_fail_htlc_msg {
142+
() => {{
143+
UpdateFailHTLC {
144+
channel_id: [0; 32],
145+
htlc_id: 0,
146+
reason: OnionErrorPacket { data: vec![] }
147+
}
148+
}}
149+
}
150+
151+
macro_rules! fake_update_fail_malformed_htlc_msg {
152+
() => {
153+
UpdateFailMalformedHTLC {
154+
channel_id: [0; 32],
155+
htlc_id: 0,
156+
sha256_of_onion: [0; 32],
157+
failure_code: 0
158+
}
159+
}
160+
}
161+
162+
macro_rules! fake_commitment_signed_msg {
163+
() => {{
164+
CommitmentSigned {
165+
channel_id: [0; 32],
166+
signature: fake_valid_sig!(),
167+
htlc_signatures: vec![]
168+
}
169+
}}
170+
}
171+
172+
macro_rules! fake_revoke_and_ack_msg {
173+
() => {{
174+
RevokeAndACK {
175+
channel_id: [0; 32],
176+
per_commitment_secret: [0; 32],
177+
next_per_commitment_point: fake_public_key!()
178+
}
179+
}}
180+
}
181+
macro_rules! fake_update_fee_msg {
182+
() => {{
183+
UpdateFee {
184+
channel_id: [0; 32],
185+
feerate_per_kw: 0
186+
}
187+
}}
188+
}
189+
190+
macro_rules! fake_channel_reestablish_msg {
191+
() => {{
192+
ChannelReestablish {
193+
channel_id: [0; 32],
194+
next_local_commitment_number: 0,
195+
next_remote_commitment_number: 0,
196+
data_loss_protect: OptionalField::Absent
197+
}
198+
}}
199+
}
200+
201+
macro_rules! fake_announcement_signatures_msg {
202+
() => {{
203+
AnnouncementSignatures {
204+
channel_id: [0;32],
205+
short_channel_id: 0,
206+
node_signature: fake_valid_sig!(),
207+
bitcoin_signature: fake_valid_sig!()
208+
}
209+
}}
210+
}
211+
212+
macro_rules! fake_channel_announcement_msg {
213+
($channel_id: expr, $node_id_1: expr, $node_id_2: expr) => {{
214+
ChannelAnnouncement {
215+
node_signature_1: fake_valid_sig!(),
216+
node_signature_2: fake_valid_sig!(),
217+
bitcoin_signature_1: fake_valid_sig!(),
218+
bitcoin_signature_2: fake_valid_sig!(),
219+
contents: UnsignedChannelAnnouncement {
220+
features: ChannelFeatures::empty(),
221+
chain_hash: Default::default(),
222+
short_channel_id: $channel_id,
223+
node_id_1: $node_id_1,
224+
node_id_2: $node_id_2,
225+
bitcoin_key_1: fake_public_key!(),
226+
bitcoin_key_2: fake_public_key!(),
227+
excess_data: vec![]
228+
}
229+
}
230+
}}
231+
}
232+
233+
macro_rules! fake_node_announcement_msg {
234+
() => {{
235+
NodeAnnouncement {
236+
signature: fake_valid_sig!(),
237+
contents: UnsignedNodeAnnouncement {
238+
features: NodeFeatures::empty(),
239+
timestamp: 0,
240+
node_id: fake_public_key!(),
241+
rgb: [0; 3],
242+
alias: [0; 32],
243+
addresses: vec![],
244+
excess_address_data: vec![],
245+
excess_data: vec![]
246+
}
247+
}
248+
}}
249+
}
250+
251+
macro_rules! fake_channel_update_msg {
252+
() => {{
253+
ChannelUpdate {
254+
signature: fake_valid_sig!(),
255+
contents: UnsignedChannelUpdate {
256+
chain_hash: Default::default(),
257+
short_channel_id: 0,
258+
timestamp: 0,
259+
flags: 0,
260+
cltv_expiry_delta: 0,
261+
htlc_minimum_msat: 0,
262+
fee_base_msat: 0,
263+
fee_proportional_millionths: 0,
264+
excess_data: vec![]
265+
}
266+
}
267+
}}
268+
}

0 commit comments

Comments
 (0)