Skip to content

Commit 4d964d4

Browse files
authored
Merge pull request #232 from TheBlueMatt/master
Fix a full_stack_target crash
2 parents b297d5b + 46f573b commit 4d964d4

File tree

5 files changed

+85
-39
lines changed

5 files changed

+85
-39
lines changed

fuzz/fuzz_targets/full_stack_target.rs

Lines changed: 52 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ use secp256k1::key::{PublicKey,SecretKey};
3333
use secp256k1::Secp256k1;
3434

3535
use std::cell::RefCell;
36-
use std::collections::HashMap;
36+
use std::collections::{HashMap, hash_map};
3737
use std::cmp;
3838
use std::hash::Hash;
3939
use std::sync::Arc;
@@ -140,10 +140,11 @@ struct MoneyLossDetector<'a> {
140140

141141
peers: &'a RefCell<[bool; 256]>,
142142
funding_txn: Vec<Transaction>,
143+
txids_confirmed: HashMap<Sha256dHash, usize>,
143144
header_hashes: Vec<Sha256dHash>,
144145
height: usize,
145146
max_height: usize,
146-
147+
blocks_connected: u32,
147148
}
148149
impl<'a> MoneyLossDetector<'a> {
149150
pub fn new(peers: &'a RefCell<[bool; 256]>, manager: Arc<ChannelManager>, monitor: Arc<channelmonitor::SimpleManyChannelMonitor<OutPoint>>, handler: PeerManager<Peer<'a>>) -> Self {
@@ -154,17 +155,34 @@ impl<'a> MoneyLossDetector<'a> {
154155

155156
peers,
156157
funding_txn: Vec::new(),
158+
txids_confirmed: HashMap::new(),
157159
header_hashes: vec![Default::default()],
158160
height: 0,
159161
max_height: 0,
162+
blocks_connected: 0,
160163
}
161164
}
162165

163-
fn connect_block(&mut self, txn: &[&Transaction], txn_idxs: &[u32]) {
164-
let header = BlockHeader { version: 0x20000000, prev_blockhash: self.header_hashes[self.height], merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
166+
fn connect_block(&mut self, all_txn: &[Transaction]) {
167+
let mut txn = Vec::with_capacity(all_txn.len());
168+
let mut txn_idxs = Vec::with_capacity(all_txn.len());
169+
for (idx, tx) in all_txn.iter().enumerate() {
170+
let txid = Sha256dHash::from_data(&serialize(tx).unwrap()[..]);
171+
match self.txids_confirmed.entry(txid) {
172+
hash_map::Entry::Vacant(e) => {
173+
e.insert(self.height);
174+
txn.push(tx);
175+
txn_idxs.push(idx as u32 + 1);
176+
},
177+
_ => {},
178+
}
179+
}
180+
181+
let header = BlockHeader { version: 0x20000000, prev_blockhash: self.header_hashes[self.height], merkle_root: Default::default(), time: self.blocks_connected, bits: 42, nonce: 42 };
165182
self.height += 1;
166-
self.manager.block_connected(&header, self.height as u32, txn, txn_idxs);
167-
(*self.monitor).block_connected(&header, self.height as u32, txn, txn_idxs);
183+
self.blocks_connected += 1;
184+
self.manager.block_connected(&header, self.height as u32, &txn[..], &txn_idxs[..]);
185+
(*self.monitor).block_connected(&header, self.height as u32, &txn[..], &txn_idxs[..]);
168186
if self.header_hashes.len() > self.height {
169187
self.header_hashes[self.height] = header.bitcoin_hash();
170188
} else {
@@ -180,6 +198,10 @@ impl<'a> MoneyLossDetector<'a> {
180198
let header = BlockHeader { version: 0x20000000, prev_blockhash: self.header_hashes[self.height], merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
181199
self.manager.block_disconnected(&header);
182200
self.monitor.block_disconnected(&header);
201+
let removal_height = self.height;
202+
self.txids_confirmed.retain(|_, height| {
203+
removal_height != *height
204+
});
183205
}
184206
}
185207
}
@@ -280,7 +302,7 @@ pub fn do_test(data: &[u8], logger: &Arc<Logger>) {
280302

281303
let watch = Arc::new(ChainWatchInterfaceUtil::new(Network::Bitcoin, Arc::clone(&logger)));
282304
let broadcast = Arc::new(TestBroadcaster{});
283-
let monitor = channelmonitor::SimpleManyChannelMonitor::new(watch.clone(), broadcast.clone());
305+
let monitor = channelmonitor::SimpleManyChannelMonitor::new(watch.clone(), broadcast.clone(), Arc::clone(&logger));
284306

285307
let keys_manager = Arc::new(KeyProvider { node_secret: our_network_key.clone() });
286308
let channelmanager = ChannelManager::new(slice_to_be32(get_slice!(4)), get_slice!(1)[0] != 0, Network::Bitcoin, fee_est.clone(), monitor.clone(), watch.clone(), broadcast.clone(), Arc::clone(&logger), keys_manager.clone()).unwrap();
@@ -398,36 +420,36 @@ pub fn do_test(data: &[u8], logger: &Arc<Logger>) {
398420
}
399421
},
400422
10 => {
401-
for funding_generation in pending_funding_generation.drain(..) {
423+
'outer_loop: for funding_generation in pending_funding_generation.drain(..) {
402424
let mut tx = Transaction { version: 0, lock_time: 0, input: Vec::new(), output: vec![TxOut {
403425
value: funding_generation.1, script_pubkey: funding_generation.2,
404426
}] };
405-
let funding_output = OutPoint::new(Sha256dHash::from_data(&serialize(&tx).unwrap()[..]), 0);
406-
let mut found_duplicate_txo = false;
407-
for chan in channelmanager.list_channels() {
408-
if chan.channel_id == funding_output.to_channel_id() {
409-
found_duplicate_txo = true;
427+
let funding_output = 'search_loop: loop {
428+
let funding_txid = Sha256dHash::from_data(&serialize(&tx).unwrap()[..]);
429+
if let None = loss_detector.txids_confirmed.get(&funding_txid) {
430+
let outpoint = OutPoint::new(funding_txid, 0);
431+
for chan in channelmanager.list_channels() {
432+
if chan.channel_id == outpoint.to_channel_id() {
433+
tx.version += 1;
434+
continue 'search_loop;
435+
}
436+
}
437+
break outpoint;
410438
}
411-
}
412-
if !found_duplicate_txo {
413-
channelmanager.funding_transaction_generated(&funding_generation.0, funding_output.clone());
414-
pending_funding_signatures.insert(funding_output, tx);
415-
}
439+
tx.version += 1;
440+
if tx.version > 0xff {
441+
continue 'outer_loop;
442+
}
443+
};
444+
channelmanager.funding_transaction_generated(&funding_generation.0, funding_output.clone());
445+
pending_funding_signatures.insert(funding_output, tx);
416446
}
417447
},
418448
11 => {
419449
if !pending_funding_relay.is_empty() {
420-
let mut txn = Vec::with_capacity(pending_funding_relay.len());
421-
let mut txn_idxs = Vec::with_capacity(pending_funding_relay.len());
422-
for (idx, tx) in pending_funding_relay.iter().enumerate() {
423-
txn.push(tx);
424-
txn_idxs.push(idx as u32 + 1);
425-
}
426-
427-
loss_detector.connect_block(&txn[..], &txn_idxs[..]);
428-
txn_idxs.clear();
450+
loss_detector.connect_block(&pending_funding_relay[..]);
429451
for _ in 2..100 {
430-
loss_detector.connect_block(&txn[..], &txn_idxs[..]);
452+
loss_detector.connect_block(&[]);
431453
}
432454
}
433455
for tx in pending_funding_relay.drain(..) {
@@ -437,11 +459,11 @@ pub fn do_test(data: &[u8], logger: &Arc<Logger>) {
437459
12 => {
438460
let txlen = slice_to_be16(get_slice!(2));
439461
if txlen == 0 {
440-
loss_detector.connect_block(&[], &[]);
462+
loss_detector.connect_block(&[]);
441463
} else {
442464
let txres: Result<Transaction, _> = deserialize(get_slice!(txlen));
443465
if let Ok(tx) = txres {
444-
loss_detector.connect_block(&[&tx], &[1]);
466+
loss_detector.connect_block(&[tx]);
445467
} else {
446468
return;
447469
}

src/ln/channelmanager.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4051,7 +4051,7 @@ mod tests {
40514051
let mut seed = [0; 32];
40524052
rng.fill_bytes(&mut seed);
40534053
let keys_manager = Arc::new(keysinterface::KeysManager::new(&seed, Network::Testnet, Arc::clone(&logger)));
4054-
let chan_monitor = Arc::new(test_utils::TestChannelMonitor::new(chain_monitor.clone(), tx_broadcaster.clone()));
4054+
let chan_monitor = Arc::new(test_utils::TestChannelMonitor::new(chain_monitor.clone(), tx_broadcaster.clone(), logger.clone()));
40554055
let node = ChannelManager::new(0, true, Network::Testnet, feeest.clone(), chan_monitor.clone(), chain_monitor.clone(), tx_broadcaster.clone(), Arc::clone(&logger), keys_manager.clone()).unwrap();
40564056
let router = Router::new(PublicKey::from_secret_key(&secp_ctx, &keys_manager.get_node_secret()), chain_monitor.clone(), Arc::clone(&logger));
40574057
nodes.push(Node { chain_monitor, tx_broadcaster, chan_monitor, node, router, node_seed: seed,
@@ -6881,7 +6881,7 @@ mod tests {
68816881
let mut chan_0_monitor_serialized = VecWriter(Vec::new());
68826882
nodes[0].chan_monitor.simple_monitor.monitors.lock().unwrap().iter().next().unwrap().1.write_for_disk(&mut chan_0_monitor_serialized).unwrap();
68836883

6884-
nodes[0].chan_monitor = Arc::new(test_utils::TestChannelMonitor::new(nodes[0].chain_monitor.clone(), nodes[0].tx_broadcaster.clone()));
6884+
nodes[0].chan_monitor = Arc::new(test_utils::TestChannelMonitor::new(nodes[0].chain_monitor.clone(), nodes[0].tx_broadcaster.clone(), Arc::new(test_utils::TestLogger::new())));
68856885
let mut chan_0_monitor_read = &chan_0_monitor_serialized.0[..];
68866886
let (_, chan_0_monitor) = <(Sha256dHash, ChannelMonitor)>::read(&mut chan_0_monitor_read, Arc::new(test_utils::TestLogger::new())).unwrap();
68876887
assert!(chan_0_monitor_read.is_empty());
@@ -6945,7 +6945,7 @@ mod tests {
69456945
let mut chan_0_monitor_serialized = VecWriter(Vec::new());
69466946
nodes[0].chan_monitor.simple_monitor.monitors.lock().unwrap().iter().next().unwrap().1.write_for_disk(&mut chan_0_monitor_serialized).unwrap();
69476947

6948-
nodes[0].chan_monitor = Arc::new(test_utils::TestChannelMonitor::new(nodes[0].chain_monitor.clone(), nodes[0].tx_broadcaster.clone()));
6948+
nodes[0].chan_monitor = Arc::new(test_utils::TestChannelMonitor::new(nodes[0].chain_monitor.clone(), nodes[0].tx_broadcaster.clone(), Arc::new(test_utils::TestLogger::new())));
69496949
let mut chan_0_monitor_read = &chan_0_monitor_serialized.0[..];
69506950
let (_, chan_0_monitor) = <(Sha256dHash, ChannelMonitor)>::read(&mut chan_0_monitor_read, Arc::new(test_utils::TestLogger::new())).unwrap();
69516951
assert!(chan_0_monitor_read.is_empty());
@@ -7004,7 +7004,7 @@ mod tests {
70047004
node_0_monitors_serialized.push(writer.0);
70057005
}
70067006

7007-
nodes[0].chan_monitor = Arc::new(test_utils::TestChannelMonitor::new(nodes[0].chain_monitor.clone(), nodes[0].tx_broadcaster.clone()));
7007+
nodes[0].chan_monitor = Arc::new(test_utils::TestChannelMonitor::new(nodes[0].chain_monitor.clone(), nodes[0].tx_broadcaster.clone(), Arc::new(test_utils::TestLogger::new())));
70087008
let mut node_0_monitors = Vec::new();
70097009
for serialized in node_0_monitors_serialized.iter() {
70107010
let mut read = &serialized[..];

src/ln/channelmonitor.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ pub struct SimpleManyChannelMonitor<Key> {
112112
chain_monitor: Arc<ChainWatchInterface>,
113113
broadcaster: Arc<BroadcasterInterface>,
114114
pending_events: Mutex<Vec<events::Event>>,
115+
logger: Arc<Logger>,
115116
}
116117

117118
impl<Key : Send + cmp::Eq + hash::Hash> ChainListener for SimpleManyChannelMonitor<Key> {
@@ -144,12 +145,13 @@ impl<Key : Send + cmp::Eq + hash::Hash> ChainListener for SimpleManyChannelMonit
144145
impl<Key : Send + cmp::Eq + hash::Hash + 'static> SimpleManyChannelMonitor<Key> {
145146
/// Creates a new object which can be used to monitor several channels given the chain
146147
/// interface with which to register to receive notifications.
147-
pub fn new(chain_monitor: Arc<ChainWatchInterface>, broadcaster: Arc<BroadcasterInterface>) -> Arc<SimpleManyChannelMonitor<Key>> {
148+
pub fn new(chain_monitor: Arc<ChainWatchInterface>, broadcaster: Arc<BroadcasterInterface>, logger: Arc<Logger>) -> Arc<SimpleManyChannelMonitor<Key>> {
148149
let res = Arc::new(SimpleManyChannelMonitor {
149150
monitors: Mutex::new(HashMap::new()),
150151
chain_monitor,
151152
broadcaster,
152153
pending_events: Mutex::new(Vec::new()),
154+
logger,
153155
});
154156
let weak_res = Arc::downgrade(&res);
155157
res.chain_monitor.register_listener(weak_res);
@@ -160,12 +162,19 @@ impl<Key : Send + cmp::Eq + hash::Hash + 'static> SimpleManyChannelMonitor<Key>
160162
pub fn add_update_monitor_by_key(&self, key: Key, monitor: ChannelMonitor) -> Result<(), HandleError> {
161163
let mut monitors = self.monitors.lock().unwrap();
162164
match monitors.get_mut(&key) {
163-
Some(orig_monitor) => return orig_monitor.insert_combine(monitor),
165+
Some(orig_monitor) => {
166+
log_trace!(self, "Updating Channel Monitor for channel {}", log_funding_option!(monitor.funding_txo));
167+
return orig_monitor.insert_combine(monitor);
168+
},
164169
None => {}
165170
};
166171
match &monitor.funding_txo {
167-
&None => self.chain_monitor.watch_all_txn(),
172+
&None => {
173+
log_trace!(self, "Got new Channel Monitor for no-funding-set channel (monitoring all txn!)");
174+
self.chain_monitor.watch_all_txn()
175+
},
168176
&Some((ref outpoint, ref script)) => {
177+
log_trace!(self, "Got new Channel Monitor for channel {}", log_bytes!(outpoint.to_channel_id()[..]));
169178
self.chain_monitor.install_watch_tx(&outpoint.txid, script);
170179
self.chain_monitor.install_watch_outpoint((outpoint.txid, outpoint.index as u32), script);
171180
},

src/util/macro_logger.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,21 @@ macro_rules! log_funding_channel_id {
5252
}
5353
}
5454

55+
pub(crate) struct DebugFundingOption<'a, T: 'a>(pub &'a Option<(OutPoint, T)>);
56+
impl<'a, T> std::fmt::Display for DebugFundingOption<'a, T> {
57+
fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
58+
match self.0.as_ref() {
59+
Some(&(ref funding_output, _)) => DebugBytes(&funding_output.to_channel_id()[..]).fmt(f),
60+
None => write!(f, "without funding output set"),
61+
}
62+
}
63+
}
64+
macro_rules! log_funding_option {
65+
($funding_option: expr) => {
66+
::util::macro_logger::DebugFundingOption(&$funding_option)
67+
}
68+
}
69+
5570
pub(crate) struct DebugRoute<'a>(pub &'a Route);
5671
impl<'a> std::fmt::Display for DebugRoute<'a> {
5772
fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {

src/util/test_utils.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,10 @@ pub struct TestChannelMonitor {
4242
pub update_ret: Mutex<Result<(), channelmonitor::ChannelMonitorUpdateErr>>,
4343
}
4444
impl TestChannelMonitor {
45-
pub fn new(chain_monitor: Arc<chaininterface::ChainWatchInterface>, broadcaster: Arc<chaininterface::BroadcasterInterface>) -> Self {
45+
pub fn new(chain_monitor: Arc<chaininterface::ChainWatchInterface>, broadcaster: Arc<chaininterface::BroadcasterInterface>, logger: Arc<Logger>) -> Self {
4646
Self {
4747
added_monitors: Mutex::new(Vec::new()),
48-
simple_monitor: channelmonitor::SimpleManyChannelMonitor::new(chain_monitor, broadcaster),
48+
simple_monitor: channelmonitor::SimpleManyChannelMonitor::new(chain_monitor, broadcaster, logger),
4949
update_ret: Mutex::new(Ok(())),
5050
}
5151
}

0 commit comments

Comments
 (0)