Skip to content

Commit 9f92dc3

Browse files
committed
Track the blocks a node has connected in the TestBroadcaster
1 parent 92f1147 commit 9f92dc3

File tree

6 files changed

+60
-29
lines changed

6 files changed

+60
-29
lines changed

lightning-background-processor/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ mod tests {
238238
fn create_nodes(num_nodes: usize, persist_dir: String) -> Vec<Node> {
239239
let mut nodes = Vec::new();
240240
for i in 0..num_nodes {
241-
let tx_broadcaster = Arc::new(test_utils::TestBroadcaster{txn_broadcasted: Mutex::new(Vec::new())});
241+
let tx_broadcaster = Arc::new(test_utils::TestBroadcaster{txn_broadcasted: Mutex::new(Vec::new()), blocks: Arc::new(Mutex::new(Vec::new()))});
242242
let fee_estimator = Arc::new(test_utils::TestFeeEstimator { sat_per_kw: 253 });
243243
let chain_source = Arc::new(test_utils::TestChainSource::new(Network::Testnet));
244244
let logger = Arc::new(test_utils::TestLogger::with_id(format!("node {}", i)));

lightning/src/chain/channelmonitor.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2918,7 +2918,7 @@ mod tests {
29182918
fn test_prune_preimages() {
29192919
let secp_ctx = Secp256k1::new();
29202920
let logger = Arc::new(TestLogger::new());
2921-
let broadcaster = Arc::new(TestBroadcaster{txn_broadcasted: Mutex::new(Vec::new())});
2921+
let broadcaster = Arc::new(TestBroadcaster{txn_broadcasted: Mutex::new(Vec::new()), blocks: Arc::new(Mutex::new(Vec::new()))});
29222922
let fee_estimator = Arc::new(TestFeeEstimator { sat_per_kw: 253 });
29232923

29242924
let dummy_key = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());

lightning/src/ln/chanmon_update_fail_tests.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
//! here. See also the chanmon_fail_consistency fuzz test.
1414
1515
use bitcoin::blockdata::block::{Block, BlockHeader};
16+
use bitcoin::blockdata::constants::genesis_block;
1617
use bitcoin::hash_types::BlockHash;
1718
use bitcoin::network::constants::Network;
1819
use chain::channelmonitor::{ChannelMonitor, ChannelMonitorUpdateErr};
@@ -30,6 +31,7 @@ use util::enforcing_trait_impls::EnforcingSigner;
3031
use util::events::{Event, MessageSendEvent, MessageSendEventsProvider};
3132
use util::errors::APIError;
3233
use util::ser::{ReadableArgs, Writeable};
34+
use util::test_utils::TestBroadcaster;
3335

3436
use bitcoin::hashes::sha256::Hash as Sha256;
3537
use bitcoin::hashes::Hash;
@@ -39,6 +41,7 @@ use ln::functional_test_utils::*;
3941
use util::test_utils;
4042

4143
use std::collections::HashMap;
44+
use std::sync::{Arc, Mutex};
4245

4346
// If persister_fail is true, we have the persister return a PermanentFailure
4447
// instead of the higher-level ChainMonitor.
@@ -106,6 +109,13 @@ fn test_monitor_and_persister_update_fail() {
106109
let chain_source = test_utils::TestChainSource::new(Network::Testnet);
107110
let logger = test_utils::TestLogger::with_id(format!("node {}", 0));
108111
let persister = test_utils::TestPersister::new();
112+
let tx_broadcaster = TestBroadcaster {
113+
txn_broadcasted: Mutex::new(Vec::new()),
114+
// Because we will connect a block at height 200 below, we need the TestBroadcaster to know
115+
// that we are at height 200 so that it doesn't think we're violating the time lock
116+
// requirements of transactions broadcasted at that point.
117+
blocks: Arc::new(Mutex::new(vec![(genesis_block(Network::Testnet).header, 0); 200])),
118+
};
109119
let chain_mon = {
110120
let monitors = nodes[0].chain_monitor.chain_monitor.monitors.read().unwrap();
111121
let monitor = monitors.get(&outpoint).unwrap();
@@ -114,7 +124,7 @@ fn test_monitor_and_persister_update_fail() {
114124
let new_monitor = <(BlockHash, ChannelMonitor<EnforcingSigner>)>::read(
115125
&mut ::std::io::Cursor::new(&w.0), &test_utils::OnlyReadsKeysInterface {}).unwrap().1;
116126
assert!(new_monitor == *monitor);
117-
let chain_mon = test_utils::TestChainMonitor::new(Some(&chain_source), &chanmon_cfgs[0].tx_broadcaster, &logger, &chanmon_cfgs[0].fee_estimator, &persister, &node_cfgs[0].keys_manager);
127+
let chain_mon = test_utils::TestChainMonitor::new(Some(&chain_source), &tx_broadcaster, &logger, &chanmon_cfgs[0].fee_estimator, &persister, &node_cfgs[0].keys_manager);
118128
assert!(chain_mon.watch_channel(outpoint, new_monitor).is_ok());
119129
chain_mon
120130
};

lightning/src/ln/functional_test_utils.rs

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ use bitcoin::secp256k1::key::PublicKey;
4141

4242
use core::cell::RefCell;
4343
use std::rc::Rc;
44-
use std::sync::Mutex;
44+
use std::sync::{Arc, Mutex};
4545
use core::mem;
4646
use std::collections::HashMap;
4747

@@ -148,14 +148,14 @@ fn do_connect_block<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, block: &Block, s
148148
}
149149
}
150150
node.node.test_process_background_events();
151-
node.blocks.borrow_mut().push((block.header, height));
151+
node.blocks.lock().unwrap().push((block.header, height));
152152
}
153153

154154
pub fn disconnect_blocks<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, count: u32) {
155155
for i in 0..count {
156-
let orig_header = node.blocks.borrow_mut().pop().unwrap();
156+
let orig_header = node.blocks.lock().unwrap().pop().unwrap();
157157
assert!(orig_header.1 > 0); // Cannot disconnect genesis
158-
let prev_header = node.blocks.borrow().last().unwrap().clone();
158+
let prev_header = node.blocks.lock().unwrap().last().unwrap().clone();
159159

160160
match *node.connect_style.borrow() {
161161
ConnectStyle::FullBlockViaListen => {
@@ -177,7 +177,7 @@ pub fn disconnect_blocks<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, count: u32)
177177
}
178178

179179
pub fn disconnect_all_blocks<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>) {
180-
let count = node.blocks.borrow_mut().len() as u32 - 1;
180+
let count = node.blocks.lock().unwrap().len() as u32 - 1;
181181
disconnect_blocks(node, count);
182182
}
183183

@@ -211,15 +211,15 @@ pub struct Node<'a, 'b: 'a, 'c: 'b> {
211211
pub network_payment_count: Rc<RefCell<u8>>,
212212
pub network_chan_count: Rc<RefCell<u32>>,
213213
pub logger: &'c test_utils::TestLogger,
214-
pub blocks: RefCell<Vec<(BlockHeader, u32)>>,
214+
pub blocks: Arc<Mutex<Vec<(BlockHeader, u32)>>>,
215215
pub connect_style: Rc<RefCell<ConnectStyle>>,
216216
}
217217
impl<'a, 'b, 'c> Node<'a, 'b, 'c> {
218218
pub fn best_block_hash(&self) -> BlockHash {
219-
self.blocks.borrow_mut().last().unwrap().0.block_hash()
219+
self.blocks.lock().unwrap().last().unwrap().0.block_hash()
220220
}
221221
pub fn best_block_info(&self) -> (BlockHash, u32) {
222-
self.blocks.borrow_mut().last().map(|(a, b)| (a.block_hash(), *b)).unwrap()
222+
self.blocks.lock().unwrap().last().map(|(a, b)| (a.block_hash(), *b)).unwrap()
223223
}
224224
}
225225

@@ -295,7 +295,8 @@ impl<'a, 'b, 'c> Drop for Node<'a, 'b, 'c> {
295295
fee_estimator: &test_utils::TestFeeEstimator { sat_per_kw: 253 },
296296
chain_monitor: self.chain_monitor,
297297
tx_broadcaster: &test_utils::TestBroadcaster {
298-
txn_broadcasted: Mutex::new(self.tx_broadcaster.txn_broadcasted.lock().unwrap().clone())
298+
txn_broadcasted: Mutex::new(self.tx_broadcaster.txn_broadcasted.lock().unwrap().clone()),
299+
blocks: Arc::new(Mutex::new(self.tx_broadcaster.blocks.lock().unwrap().clone())),
299300
},
300301
logger: &test_utils::TestLogger::new(),
301302
channel_monitors,
@@ -304,7 +305,8 @@ impl<'a, 'b, 'c> Drop for Node<'a, 'b, 'c> {
304305

305306
let persister = test_utils::TestPersister::new();
306307
let broadcaster = test_utils::TestBroadcaster {
307-
txn_broadcasted: Mutex::new(self.tx_broadcaster.txn_broadcasted.lock().unwrap().clone())
308+
txn_broadcasted: Mutex::new(self.tx_broadcaster.txn_broadcasted.lock().unwrap().clone()),
309+
blocks: Arc::new(Mutex::new(self.tx_broadcaster.blocks.lock().unwrap().clone())),
308310
};
309311
let chain_source = test_utils::TestChainSource::new(Network::Testnet);
310312
let chain_monitor = test_utils::TestChainMonitor::new(Some(&chain_source), &broadcaster, &self.logger, &feeest, &persister, &self.keys_manager);
@@ -1283,7 +1285,10 @@ pub fn fail_payment<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_route:
12831285
pub fn create_chanmon_cfgs(node_count: usize) -> Vec<TestChanMonCfg> {
12841286
let mut chan_mon_cfgs = Vec::new();
12851287
for i in 0..node_count {
1286-
let tx_broadcaster = test_utils::TestBroadcaster{txn_broadcasted: Mutex::new(Vec::new())};
1288+
let tx_broadcaster = test_utils::TestBroadcaster {
1289+
txn_broadcasted: Mutex::new(Vec::new()),
1290+
blocks: Arc::new(Mutex::new(vec![(genesis_block(Network::Testnet).header, 0)])),
1291+
};
12871292
let fee_estimator = test_utils::TestFeeEstimator { sat_per_kw: 253 };
12881293
let chain_source = test_utils::TestChainSource::new(Network::Testnet);
12891294
let logger = test_utils::TestLogger::with_id(format!("node {}", i));
@@ -1344,7 +1349,7 @@ pub fn create_network<'a, 'b: 'a, 'c: 'b>(node_count: usize, cfgs: &'b Vec<NodeC
13441349
keys_manager: &cfgs[i].keys_manager, node: &chan_mgrs[i], net_graph_msg_handler,
13451350
node_seed: cfgs[i].node_seed, network_chan_count: chan_count.clone(),
13461351
network_payment_count: payment_count.clone(), logger: cfgs[i].logger,
1347-
blocks: RefCell::new(vec![(genesis_block(Network::Testnet).header, 0)]),
1352+
blocks: Arc::clone(&cfgs[i].tx_broadcaster.blocks),
13481353
connect_style: Rc::clone(&connect_style),
13491354
})
13501355
}

lightning/src/ln/functional_tests.rs

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ use regex;
5252

5353
use std::collections::{BTreeSet, HashMap, HashSet};
5454
use core::default::Default;
55-
use std::sync::Mutex;
55+
use std::sync::{Arc, Mutex};
5656

5757
use ln::functional_test_utils::*;
5858
use ln::chan_utils::CommitmentTransaction;
@@ -2748,7 +2748,8 @@ fn test_htlc_on_chain_success() {
27482748
let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2, InitFeatures::known(), InitFeatures::known());
27492749

27502750
// Ensure all nodes are at the same height
2751-
let node_max_height = std::cmp::max(nodes[0].blocks.borrow().len(), std::cmp::max(nodes[1].blocks.borrow().len(), nodes[2].blocks.borrow().len())) as u32;
2751+
let node_max_height = std::cmp::max(nodes[0].blocks.lock().unwrap().len(),
2752+
std::cmp::max(nodes[1].blocks.lock().unwrap().len(), nodes[2].blocks.lock().unwrap().len())) as u32;
27522753
connect_blocks(&nodes[0], node_max_height - nodes[0].best_block_info().1);
27532754
connect_blocks(&nodes[1], node_max_height - nodes[1].best_block_info().1);
27542755
connect_blocks(&nodes[2], node_max_height - nodes[2].best_block_info().1);
@@ -4521,7 +4522,7 @@ fn test_dup_htlc_onchain_fails_on_reload() {
45214522
// Note that if we re-connect the block which exposed nodes[0] to the payment preimage (but
45224523
// which the current ChannelMonitor has not seen), the ChannelManager's de-duplication of
45234524
// payment events should kick in, leaving us with no pending events here.
4524-
nodes[0].chain_monitor.chain_monitor.block_connected(&claim_block, nodes[0].blocks.borrow().len() as u32 - 1);
4525+
nodes[0].chain_monitor.chain_monitor.block_connected(&claim_block, nodes[0].blocks.lock().unwrap().len() as u32 - 1);
45254526
assert!(nodes[0].node.get_and_clear_pending_events().is_empty());
45264527
}
45274528

@@ -5242,7 +5243,8 @@ fn test_onchain_to_onchain_claim() {
52425243
let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2, InitFeatures::known(), InitFeatures::known());
52435244

52445245
// Ensure all nodes are at the same height
5245-
let node_max_height = std::cmp::max(nodes[0].blocks.borrow().len(), std::cmp::max(nodes[1].blocks.borrow().len(), nodes[2].blocks.borrow().len())) as u32;
5246+
let node_max_height = std::cmp::max(nodes[0].blocks.lock().unwrap().len(),
5247+
std::cmp::max(nodes[1].blocks.lock().unwrap().len(), nodes[2].blocks.lock().unwrap().len())) as u32;
52465248
connect_blocks(&nodes[0], node_max_height - nodes[0].best_block_info().1);
52475249
connect_blocks(&nodes[1], node_max_height - nodes[1].best_block_info().1);
52485250
connect_blocks(&nodes[2], node_max_height - nodes[2].best_block_info().1);
@@ -5355,7 +5357,9 @@ fn test_duplicate_payment_hash_one_failure_one_success() {
53555357
let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2, InitFeatures::known(), InitFeatures::known());
53565358
create_announced_chan_between_nodes(&nodes, 2, 3, InitFeatures::known(), InitFeatures::known());
53575359

5358-
let node_max_height = std::cmp::max(std::cmp::max(nodes[0].blocks.borrow().len(), nodes[1].blocks.borrow().len()), std::cmp::max(nodes[2].blocks.borrow().len(), nodes[3].blocks.borrow().len())) as u32;
5360+
let node_max_height = std::cmp::max(
5361+
std::cmp::max(nodes[0].blocks.lock().unwrap().len(), nodes[1].blocks.lock().unwrap().len()),
5362+
std::cmp::max(nodes[2].blocks.lock().unwrap().len(), nodes[3].blocks.lock().unwrap().len())) as u32;
53595363
connect_blocks(&nodes[0], node_max_height - nodes[0].best_block_info().1);
53605364
connect_blocks(&nodes[1], node_max_height - nodes[1].best_block_info().1);
53615365
connect_blocks(&nodes[2], node_max_height - nodes[2].best_block_info().1);
@@ -7687,7 +7691,7 @@ fn test_data_loss_protect() {
76877691
logger = test_utils::TestLogger::with_id(format!("node {}", 0));
76887692
let mut chain_monitor = <(BlockHash, ChannelMonitor<EnforcingSigner>)>::read(&mut ::std::io::Cursor::new(previous_chain_monitor_state.0), keys_manager).unwrap().1;
76897693
chain_source = test_utils::TestChainSource::new(Network::Testnet);
7690-
tx_broadcaster = test_utils::TestBroadcaster{txn_broadcasted: Mutex::new(Vec::new())};
7694+
tx_broadcaster = test_utils::TestBroadcaster{txn_broadcasted: Mutex::new(Vec::new()), blocks: Arc::new(Mutex::new(Vec::new()))};
76917695
fee_estimator = test_utils::TestFeeEstimator { sat_per_kw: 253 };
76927696
persister = test_utils::TestPersister::new();
76937697
monitor = test_utils::TestChainMonitor::new(Some(&chain_source), &tx_broadcaster, &logger, &fee_estimator, &persister, keys_manager);
@@ -8472,14 +8476,18 @@ fn test_secret_timeout() {
84728476
if let Err(APIError::APIMisuseError { err }) = nodes[1].node.create_inbound_payment_for_hash(payment_hash, Some(100_000), 2, 0) {
84738477
assert_eq!(err, "Duplicate payment hash");
84748478
} else { panic!(); }
8475-
let mut block = Block {
8476-
header: BlockHeader {
8477-
version: 0x2000000,
8478-
prev_blockhash: nodes[1].blocks.borrow().last().unwrap().0.block_hash(),
8479-
merkle_root: Default::default(),
8480-
time: nodes[1].blocks.borrow().len() as u32 + 7200, bits: 42, nonce: 42 },
8481-
txdata: vec![],
8482-
};
8479+
let mut block;
8480+
{
8481+
let node_1_blocks = nodes[1].blocks.lock().unwrap();
8482+
block = Block {
8483+
header: BlockHeader {
8484+
version: 0x2000000,
8485+
prev_blockhash: node_1_blocks.last().unwrap().0.block_hash(),
8486+
merkle_root: Default::default(),
8487+
time: node_1_blocks.len() as u32 + 7200, bits: 42, nonce: 42 },
8488+
txdata: vec![],
8489+
};
8490+
}
84838491
connect_block(&nodes[1], &block);
84848492
if let Err(APIError::APIMisuseError { err }) = nodes[1].node.create_inbound_payment_for_hash(payment_hash, Some(100_000), 2, 0) {
84858493
assert_eq!(err, "Duplicate payment hash");
@@ -8628,6 +8636,9 @@ fn test_update_err_monitor_lockdown() {
86288636
watchtower
86298637
};
86308638
let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
8639+
// Make the tx_broadcaster aware of enough blocks that it doesn't think we're violating
8640+
// transaction lock time requirements here.
8641+
chanmon_cfgs[0].tx_broadcaster.blocks.lock().unwrap().resize(200, (header, 0));
86318642
watchtower.chain_monitor.block_connected(&Block { header, txdata: vec![] }, 200);
86328643

86338644
// Try to update ChannelMonitor
@@ -8687,6 +8698,9 @@ fn test_concurrent_monitor_claim() {
86878698
watchtower
86888699
};
86898700
let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
8701+
// Make the tx_broadcaster aware of enough blocks that it doesn't think we're violating
8702+
// transaction lock time requirements here.
8703+
chanmon_cfgs[0].tx_broadcaster.blocks.lock().unwrap().resize((CHAN_CONFIRM_DEPTH + 1 + TEST_FINAL_CLTV + LATENCY_GRACE_PERIOD_BLOCKS) as usize, (header, 0));
86908704
watchtower_alice.chain_monitor.block_connected(&Block { header, txdata: vec![] }, CHAN_CONFIRM_DEPTH + 1 + TEST_FINAL_CLTV + LATENCY_GRACE_PERIOD_BLOCKS);
86918705

86928706
// Watchtower Alice should have broadcast a commitment/HTLC-timeout

lightning/src/util/test_utils.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ use bitcoin::blockdata::constants::genesis_block;
2828
use bitcoin::blockdata::transaction::{Transaction, TxOut};
2929
use bitcoin::blockdata::script::{Builder, Script};
3030
use bitcoin::blockdata::opcodes;
31+
use bitcoin::blockdata::block::BlockHeader;
3132
use bitcoin::network::constants::Network;
3233
use bitcoin::hash_types::{BlockHash, Txid};
3334

@@ -200,6 +201,7 @@ impl<Signer: keysinterface::Sign> channelmonitor::Persist<Signer> for TestPersis
200201

201202
pub struct TestBroadcaster {
202203
pub txn_broadcasted: Mutex<Vec<Transaction>>,
204+
pub blocks: Arc<Mutex<Vec<(BlockHeader, u32)>>>,
203205
}
204206
impl chaininterface::BroadcasterInterface for TestBroadcaster {
205207
fn broadcast_transaction(&self, tx: &Transaction) {

0 commit comments

Comments
 (0)