Skip to content

Commit 07e0a82

Browse files
committed
Fix fuzzing issue with revocation
1 parent c8c6995 commit 07e0a82

File tree

2 files changed

+44
-18
lines changed

2 files changed

+44
-18
lines changed

fuzz/src/chanmon_consistency.rs

Lines changed: 42 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ use lightning::chain::keysinterface::{KeysInterface, InMemoryChannelKeys};
3838
use lightning::ln::channelmanager::{ChannelManager, PaymentHash, PaymentPreimage, PaymentSecret, PaymentSendFailure, ChannelManagerReadArgs};
3939
use lightning::ln::features::{ChannelFeatures, InitFeatures, NodeFeatures};
4040
use lightning::ln::msgs::{CommitmentUpdate, ChannelMessageHandler, DecodeError, ErrorAction, UpdateAddHTLC, Init};
41-
use lightning::util::enforcing_trait_impls::EnforcingChannelKeys;
41+
use lightning::util::enforcing_trait_impls::{EnforcingChannelKeys, INITIAL_REVOKED_COMMITMENT_NUMBER};
4242
use lightning::util::errors::APIError;
4343
use lightning::util::events;
4444
use lightning::util::logger::Logger;
@@ -146,6 +146,7 @@ impl chain::Watch for TestChainMonitor {
146146
struct KeyProvider {
147147
node_id: u8,
148148
rand_bytes_id: atomic::AtomicU8,
149+
revoked_commitments: Mutex<HashMap<[u8;32], Arc<Mutex<u64>>>>,
149150
}
150151
impl KeysInterface for KeyProvider {
151152
type ChanKeySigner = EnforcingChannelKeys;
@@ -168,26 +169,51 @@ impl KeysInterface for KeyProvider {
168169

169170
fn get_channel_keys(&self, _inbound: bool, channel_value_satoshis: u64) -> EnforcingChannelKeys {
170171
let secp_ctx = Secp256k1::signing_only();
171-
EnforcingChannelKeys::new(InMemoryChannelKeys::new(
172+
let id = self.rand_bytes_id.fetch_add(1, atomic::Ordering::Relaxed);
173+
let keys = InMemoryChannelKeys::new(
172174
&secp_ctx,
173175
SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, self.node_id]).unwrap(),
174176
SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, self.node_id]).unwrap(),
175177
SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, self.node_id]).unwrap(),
176178
SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, self.node_id]).unwrap(),
177179
SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, self.node_id]).unwrap(),
178-
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, self.node_id],
180+
[id, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, self.node_id],
179181
channel_value_satoshis,
180182
(0, 0),
181-
))
183+
);
184+
let revoked_commitment = self.make_revoked_commitment_cell(keys.commitment_seed);
185+
EnforcingChannelKeys::new_with_revoked(keys, revoked_commitment)
182186
}
183187

184188
fn get_secure_random_bytes(&self) -> [u8; 32] {
185189
let id = self.rand_bytes_id.fetch_add(1, atomic::Ordering::Relaxed);
186190
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, id, 11, self.node_id]
187191
}
188192

189-
fn read_chan_signer(&self, data: &[u8]) -> Result<EnforcingChannelKeys, DecodeError> {
190-
EnforcingChannelKeys::read(&mut std::io::Cursor::new(data))
193+
fn read_chan_signer(&self, buffer: &[u8]) -> Result<Self::ChanKeySigner, DecodeError> {
194+
let mut reader = std::io::Cursor::new(buffer);
195+
196+
let inner: InMemoryChannelKeys = Readable::read(&mut reader)?;
197+
let revoked_commitment = self.make_revoked_commitment_cell(inner.commitment_seed);
198+
199+
let obscure_and_last = Readable::read(&mut reader)?;
200+
201+
Ok(EnforcingChannelKeys {
202+
inner,
203+
commitment_number_obscure_and_last: Arc::new(Mutex::new(obscure_and_last)),
204+
revoked_commitment,
205+
})
206+
}
207+
}
208+
209+
impl KeyProvider {
210+
fn make_revoked_commitment_cell(&self, commitment_seed: [u8; 32]) -> Arc<Mutex<u64>> {
211+
let mut revoked_commitments = self.revoked_commitments.lock().unwrap();
212+
if !revoked_commitments.contains_key(&commitment_seed) {
213+
revoked_commitments.insert(commitment_seed, Arc::new(Mutex::new(INITIAL_REVOKED_COMMITMENT_NUMBER)));
214+
}
215+
let cell = revoked_commitments.get(&commitment_seed).unwrap();
216+
Arc::clone(cell)
191217
}
192218
}
193219

@@ -288,22 +314,22 @@ pub fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
288314
let logger: Arc<dyn Logger> = Arc::new(test_logger::TestLogger::new($node_id.to_string(), out.clone()));
289315
let monitor = Arc::new(TestChainMonitor::new(broadcast.clone(), logger.clone(), fee_est.clone(), Arc::new(TestPersister{})));
290316

291-
let keys_manager = Arc::new(KeyProvider { node_id: $node_id, rand_bytes_id: atomic::AtomicU8::new(0) });
317+
let keys_manager = Arc::new(KeyProvider { node_id: $node_id, rand_bytes_id: atomic::AtomicU8::new(0), revoked_commitments: Mutex::new(HashMap::new()) });
292318
let mut config = UserConfig::default();
293319
config.channel_options.fee_proportional_millionths = 0;
294320
config.channel_options.announced_channel = true;
295321
config.peer_channel_config_limits.min_dust_limit_satoshis = 0;
296322
(ChannelManager::new(Network::Bitcoin, fee_est.clone(), monitor.clone(), broadcast.clone(), Arc::clone(&logger), keys_manager.clone(), config, 0),
297-
monitor)
323+
monitor, keys_manager)
298324
} }
299325
}
300326

301327
macro_rules! reload_node {
302-
($ser: expr, $node_id: expr, $old_monitors: expr) => { {
328+
($ser: expr, $node_id: expr, $old_monitors: expr, $keys_manager: expr) => { {
329+
let keys_manager = Arc::clone(& $keys_manager);
303330
let logger: Arc<dyn Logger> = Arc::new(test_logger::TestLogger::new($node_id.to_string(), out.clone()));
304331
let chain_monitor = Arc::new(TestChainMonitor::new(broadcast.clone(), logger.clone(), fee_est.clone(), Arc::new(TestPersister{})));
305332

306-
let keys_manager = Arc::new(KeyProvider { node_id: $node_id, rand_bytes_id: atomic::AtomicU8::new(0) });
307333
let mut config = UserConfig::default();
308334
config.channel_options.fee_proportional_millionths = 0;
309335
config.channel_options.announced_channel = true;
@@ -440,9 +466,9 @@ pub fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
440466

441467
// 3 nodes is enough to hit all the possible cases, notably unknown-source-unknown-dest
442468
// forwarding.
443-
let (node_a, mut monitor_a) = make_node!(0);
444-
let (node_b, mut monitor_b) = make_node!(1);
445-
let (node_c, mut monitor_c) = make_node!(2);
469+
let (node_a, mut monitor_a, keys_manager_a) = make_node!(0);
470+
let (node_b, mut monitor_b, keys_manager_b) = make_node!(1);
471+
let (node_c, mut monitor_c, keys_manager_c) = make_node!(2);
446472

447473
let mut nodes = [node_a, node_b, node_c];
448474

@@ -793,7 +819,7 @@ pub fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
793819
chan_a_disconnected = true;
794820
drain_msg_events_on_disconnect!(0);
795821
}
796-
let (new_node_a, new_monitor_a) = reload_node!(node_a_ser, 0, monitor_a);
822+
let (new_node_a, new_monitor_a) = reload_node!(node_a_ser, 0, monitor_a, keys_manager_a);
797823
nodes[0] = new_node_a;
798824
monitor_a = new_monitor_a;
799825
},
@@ -810,7 +836,7 @@ pub fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
810836
nodes[2].get_and_clear_pending_msg_events();
811837
bc_events.clear();
812838
}
813-
let (new_node_b, new_monitor_b) = reload_node!(node_b_ser, 1, monitor_b);
839+
let (new_node_b, new_monitor_b) = reload_node!(node_b_ser, 1, monitor_b, keys_manager_b);
814840
nodes[1] = new_node_b;
815841
monitor_b = new_monitor_b;
816842
},
@@ -820,7 +846,7 @@ pub fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
820846
chan_b_disconnected = true;
821847
drain_msg_events_on_disconnect!(2);
822848
}
823-
let (new_node_c, new_monitor_c) = reload_node!(node_c_ser, 2, monitor_c);
849+
let (new_node_c, new_monitor_c) = reload_node!(node_c_ser, 2, monitor_c, keys_manager_c);
824850
nodes[2] = new_node_c;
825851
monitor_c = new_monitor_c;
826852
},

lightning/src/util/enforcing_trait_impls.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ pub const INITIAL_REVOKED_COMMITMENT_NUMBER: u64 = 1 << 48;
3434
#[derive(Clone)]
3535
pub struct EnforcingChannelKeys {
3636
pub inner: InMemoryChannelKeys,
37-
pub(crate) last_commitment_number: Arc<Mutex<Option<u64>>>,
38-
pub(crate) revoked_commitment: Arc<Mutex<u64>>,
37+
pub last_commitment_number: Arc<Mutex<Option<u64>>>,
38+
pub revoked_commitment: Arc<Mutex<u64>>,
3939
}
4040

4141
impl EnforcingChannelKeys {

0 commit comments

Comments
 (0)