Skip to content

Commit 1a80b7a

Browse files
committed
Combine ChannelManager's block hash and height
There is a possible race condition when both the latest block hash and height are needed. Combine these in one struct and place them behind a single lock.
1 parent 264fb9d commit 1a80b7a

File tree

6 files changed

+85
-73
lines changed

6 files changed

+85
-73
lines changed

background-processor/src/lib.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ mod tests {
129129
use lightning::chain::keysinterface::{Sign, InMemorySigner, KeysInterface, KeysManager};
130130
use lightning::chain::transaction::OutPoint;
131131
use lightning::get_event_msg;
132-
use lightning::ln::channelmanager::{ChainParameters, ChannelManager, SimpleArcChannelManager};
132+
use lightning::ln::channelmanager::{BestBlock, ChainParameters, ChannelManager, SimpleArcChannelManager};
133133
use lightning::ln::features::InitFeatures;
134134
use lightning::ln::msgs::ChannelMessageHandler;
135135
use lightning::ln::peer_handler::{PeerManager, MessageHandler, SocketDescriptor};
@@ -190,14 +190,12 @@ mod tests {
190190
let persister = Arc::new(FilesystemPersister::new(format!("{}_persister_{}", persist_dir, i)));
191191
let seed = [i as u8; 32];
192192
let network = Network::Testnet;
193-
let genesis_block = genesis_block(network);
194-
let now = Duration::from_secs(genesis_block.header.time as u64);
193+
let now = Duration::from_secs(genesis_block(network).header.time as u64);
195194
let keys_manager = Arc::new(KeysManager::new(&seed, now.as_secs(), now.subsec_nanos()));
196195
let chain_monitor = Arc::new(chainmonitor::ChainMonitor::new(Some(chain_source.clone()), tx_broadcaster.clone(), logger.clone(), fee_estimator.clone(), persister.clone()));
197196
let params = ChainParameters {
198197
network,
199-
latest_hash: genesis_block.block_hash(),
200-
latest_height: 0,
198+
best_block: BestBlock::from_genesis(network),
201199
};
202200
let manager = Arc::new(ChannelManager::new(fee_estimator.clone(), chain_monitor.clone(), tx_broadcaster, logger.clone(), keys_manager.clone(), UserConfig::default(), params));
203201
let msg_handler = MessageHandler { chan_handler: Arc::new(test_utils::TestChannelMessageHandler::new()), route_handler: Arc::new(test_utils::TestRoutingMessageHandler::new() )};

fuzz/src/chanmon_consistency.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ use lightning::chain::channelmonitor::{ChannelMonitor, ChannelMonitorUpdateErr,
3636
use lightning::chain::transaction::OutPoint;
3737
use lightning::chain::chaininterface::{BroadcasterInterface, ConfirmationTarget, FeeEstimator};
3838
use lightning::chain::keysinterface::{KeysInterface, InMemorySigner};
39-
use lightning::ln::channelmanager::{ChainParameters, ChannelManager, PaymentHash, PaymentPreimage, PaymentSecret, PaymentSendFailure, ChannelManagerReadArgs};
39+
use lightning::ln::channelmanager::{BestBlock, ChainParameters, ChannelManager, PaymentHash, PaymentPreimage, PaymentSecret, PaymentSendFailure, ChannelManagerReadArgs};
4040
use lightning::ln::features::{ChannelFeatures, InitFeatures, NodeFeatures};
4141
use lightning::ln::msgs::{CommitmentUpdate, ChannelMessageHandler, DecodeError, ErrorAction, UpdateAddHTLC, Init};
4242
use lightning::util::enforcing_trait_impls::{EnforcingSigner, INITIAL_REVOKED_COMMITMENT_NUMBER};
@@ -322,8 +322,7 @@ pub fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
322322
let network = Network::Bitcoin;
323323
let params = ChainParameters {
324324
network,
325-
latest_hash: genesis_block(network).block_hash(),
326-
latest_height: 0,
325+
best_block: BestBlock::from_genesis(network),
327326
};
328327
(ChannelManager::new(fee_est.clone(), monitor.clone(), broadcast.clone(), Arc::clone(&logger), keys_manager.clone(), config, params),
329328
monitor, keys_manager)

fuzz/src/full_stack.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ use lightning::chain::chaininterface::{BroadcasterInterface, ConfirmationTarget,
3232
use lightning::chain::chainmonitor;
3333
use lightning::chain::transaction::OutPoint;
3434
use lightning::chain::keysinterface::{InMemorySigner, KeysInterface};
35-
use lightning::ln::channelmanager::{ChainParameters, ChannelManager, PaymentHash, PaymentPreimage, PaymentSecret};
35+
use lightning::ln::channelmanager::{BestBlock, ChainParameters, ChannelManager, PaymentHash, PaymentPreimage, PaymentSecret};
3636
use lightning::ln::peer_handler::{MessageHandler,PeerManager,SocketDescriptor};
3737
use lightning::ln::msgs::DecodeError;
3838
use lightning::routing::router::get_route;
@@ -355,15 +355,13 @@ pub fn do_test(data: &[u8], logger: &Arc<dyn Logger>) {
355355
config.channel_options.announced_channel = get_slice!(1)[0] != 0;
356356
config.peer_channel_config_limits.min_dust_limit_satoshis = 0;
357357
let network = Network::Bitcoin;
358-
let genesis_hash = genesis_block(network).block_hash();
359358
let params = ChainParameters {
360359
network,
361-
latest_hash: genesis_hash,
362-
latest_height: 0,
360+
best_block: BestBlock::from_genesis(network),
363361
};
364362
let channelmanager = Arc::new(ChannelManager::new(fee_est.clone(), monitor.clone(), broadcast.clone(), Arc::clone(&logger), keys_manager.clone(), config, params));
365363
let our_id = PublicKey::from_secret_key(&Secp256k1::signing_only(), &keys_manager.get_node_secret());
366-
let net_graph_msg_handler = Arc::new(NetGraphMsgHandler::new(genesis_hash, None, Arc::clone(&logger)));
364+
let net_graph_msg_handler = Arc::new(NetGraphMsgHandler::new(genesis_block(network).block_hash(), None, Arc::clone(&logger)));
367365

368366
let peers = RefCell::new([false; 256]);
369367
let mut loss_detector = MoneyLossDetector::new(&peers, channelmanager.clone(), monitor.clone(), PeerManager::new(MessageHandler {

lightning/src/ln/channelmanager.rs

Lines changed: 70 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -352,9 +352,6 @@ struct PeerState {
352352
latest_features: InitFeatures,
353353
}
354354

355-
#[cfg(not(any(target_pointer_width = "32", target_pointer_width = "64")))]
356-
const ERR: () = "You need at least 32 bit pointers (well, usize, but we'll assume they're the same) for ChannelManager::latest_block_height";
357-
358355
/// SimpleArcChannelManager is useful when you need a ChannelManager with a static lifetime, e.g.
359356
/// when you're using lightning-net-tokio (since tokio::spawn requires parameters with static
360357
/// lifetimes). Other times you can afford a reference, which is more efficient, in which case
@@ -424,10 +421,9 @@ pub struct ChannelManager<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref,
424421
tx_broadcaster: T,
425422

426423
#[cfg(test)]
427-
pub(super) latest_block_height: AtomicUsize,
424+
pub(super) best_block: RwLock<BestBlock>,
428425
#[cfg(not(test))]
429-
latest_block_height: AtomicUsize,
430-
last_block_hash: RwLock<BlockHash>,
426+
best_block: RwLock<BestBlock>,
431427
secp_ctx: Secp256k1<secp256k1::All>,
432428

433429
#[cfg(any(test, feature = "_test_utils"))]
@@ -475,13 +471,37 @@ pub struct ChainParameters {
475471
/// The network for determining the `chain_hash` in Lightning messages.
476472
pub network: Network,
477473

478-
/// The hash of the latest block successfully connected.
479-
pub latest_hash: BlockHash,
480-
481-
/// The height of the latest block successfully connected.
474+
/// The hash and height of the latest block successfully connected.
482475
///
483476
/// Used to track on-chain channel funding outputs and send payments with reliable timelocks.
484-
pub latest_height: usize,
477+
pub best_block: BestBlock,
478+
}
479+
480+
/// The best known block as identified by its hash and height.
481+
pub struct BestBlock {
482+
block_hash: BlockHash,
483+
height: u32,
484+
}
485+
486+
impl BestBlock {
487+
/// Returns the best block from the genesis of the given network.
488+
pub fn from_genesis(network: Network) -> Self {
489+
BestBlock {
490+
block_hash: genesis_block(network).header.block_hash(),
491+
height: 0,
492+
}
493+
}
494+
495+
/// Returns the best block as identified by the given block hash and height.
496+
pub fn new(block_hash: BlockHash, height: u32) -> Self {
497+
BestBlock { block_hash, height }
498+
}
499+
500+
/// Returns the best block hash.
501+
pub fn block_hash(&self) -> BlockHash { self.block_hash }
502+
503+
/// Returns the best block height.
504+
pub fn height(&self) -> u32 { self.height }
485505
}
486506

487507
/// Whenever we release the `ChannelManager`'s `total_consistency_lock`, from read mode, it is
@@ -822,8 +842,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
822842
chain_monitor,
823843
tx_broadcaster,
824844

825-
latest_block_height: AtomicUsize::new(params.latest_height),
826-
last_block_hash: RwLock::new(params.latest_hash),
845+
best_block: RwLock::new(params.best_block),
827846

828847
channel_state: Mutex::new(ChannelHolder{
829848
by_id: HashMap::new(),
@@ -1171,7 +1190,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
11711190
// HTLC_FAIL_BACK_BUFFER blocks to go.
11721191
// Also, ensure that, in the case of an unknown payment hash, our payment logic has enough time to fail the HTLC backward
11731192
// before our onchain logic triggers a channel closure (see HTLC_FAIL_BACK_BUFFER rational).
1174-
if (msg.cltv_expiry as u64) <= self.latest_block_height.load(Ordering::Acquire) as u64 + HTLC_FAIL_BACK_BUFFER as u64 + 1 {
1193+
if (msg.cltv_expiry as u64) <= self.best_block.read().unwrap().height() as u64 + HTLC_FAIL_BACK_BUFFER as u64 + 1 {
11751194
return_err!("The final CLTV expiry is too soon to handle", 17, &[0;0]);
11761195
}
11771196
// final_incorrect_htlc_amount
@@ -1294,7 +1313,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
12941313
if (msg.cltv_expiry as u64) < (*outgoing_cltv_value) as u64 + chan.get_cltv_expiry_delta() as u64 { // incorrect_cltv_expiry
12951314
break Some(("Forwarding node has tampered with the intended HTLC values or origin node has an obsolete cltv_expiry_delta", 0x1000 | 13, Some(self.get_channel_update(chan).unwrap())));
12961315
}
1297-
let cur_height = self.latest_block_height.load(Ordering::Acquire) as u32 + 1;
1316+
let cur_height = self.best_block.read().unwrap().height() + 1;
12981317
// Theoretically, channel counterparty shouldn't send us a HTLC expiring now, but we want to be robust wrt to counterparty
12991318
// packet sanitization (see HTLC_FAIL_BACK_BUFFER rational)
13001319
if msg.cltv_expiry <= cur_height + HTLC_FAIL_BACK_BUFFER as u32 { // expiry_too_soon
@@ -1511,7 +1530,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
15111530
return Err(PaymentSendFailure::PathParameterError(path_errs));
15121531
}
15131532

1514-
let cur_height = self.latest_block_height.load(Ordering::Acquire) as u32 + 1;
1533+
let cur_height = self.best_block.read().unwrap().height() + 1;
15151534
let mut results = Vec::new();
15161535
for path in route.paths.iter() {
15171536
results.push(self.send_payment_along_path(&path, &payment_hash, payment_secret, total_value, cur_height));
@@ -1905,10 +1924,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
19051924
for htlc in htlcs.iter() {
19061925
let mut htlc_msat_height_data = byte_utils::be64_to_array(htlc.value).to_vec();
19071926
htlc_msat_height_data.extend_from_slice(
1908-
&byte_utils::be32_to_array(
1909-
self.latest_block_height.load(Ordering::Acquire)
1910-
as u32,
1911-
),
1927+
&byte_utils::be32_to_array(self.best_block.read().unwrap().height()),
19121928
);
19131929
failed_forwards.push((HTLCSource::PreviousHopData(HTLCPreviousHopData {
19141930
short_channel_id: htlc.prev_hop.short_channel_id,
@@ -2028,8 +2044,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
20282044
if channel_state.is_none() { channel_state = Some(self.channel_state.lock().unwrap()); }
20292045
let mut htlc_msat_height_data = byte_utils::be64_to_array(htlc.value).to_vec();
20302046
htlc_msat_height_data.extend_from_slice(&byte_utils::be32_to_array(
2031-
self.latest_block_height.load(Ordering::Acquire) as u32,
2032-
));
2047+
self.best_block.read().unwrap().height()));
20332048
self.fail_htlc_backwards_internal(channel_state.take().unwrap(),
20342049
HTLCSource::PreviousHopData(htlc.prev_hop), payment_hash,
20352050
HTLCFailReason::Reason { failure_code: 0x4000 | 15, data: htlc_msat_height_data });
@@ -2243,8 +2258,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
22432258
if (is_mpp && !valid_mpp) || (!is_mpp && (htlc.value < expected_amount || htlc.value > expected_amount * 2)) {
22442259
let mut htlc_msat_height_data = byte_utils::be64_to_array(htlc.value).to_vec();
22452260
htlc_msat_height_data.extend_from_slice(&byte_utils::be32_to_array(
2246-
self.latest_block_height.load(Ordering::Acquire) as u32,
2247-
));
2261+
self.best_block.read().unwrap().height()));
22482262
self.fail_htlc_backwards_internal(channel_state.take().unwrap(),
22492263
HTLCSource::PreviousHopData(htlc.prev_hop), &payment_hash,
22502264
HTLCFailReason::Reason { failure_code: 0x4000|15, data: htlc_msat_height_data });
@@ -2529,7 +2543,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
25292543

25302544
fn internal_funding_created(&self, counterparty_node_id: &PublicKey, msg: &msgs::FundingCreated) -> Result<(), MsgHandleErrInternal> {
25312545
let ((funding_msg, monitor), mut chan) = {
2532-
let last_block_hash = *self.last_block_hash.read().unwrap();
2546+
let last_block_hash = self.best_block.read().unwrap().block_hash();
25332547
let mut channel_lock = self.channel_state.lock().unwrap();
25342548
let channel_state = &mut *channel_lock;
25352549
match channel_state.by_id.entry(msg.temporary_channel_id.clone()) {
@@ -2586,7 +2600,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
25862600

25872601
fn internal_funding_signed(&self, counterparty_node_id: &PublicKey, msg: &msgs::FundingSigned) -> Result<(), MsgHandleErrInternal> {
25882602
let funding_tx = {
2589-
let last_block_hash = *self.last_block_hash.read().unwrap();
2603+
let last_block_hash = self.best_block.read().unwrap().block_hash();
25902604
let mut channel_lock = self.channel_state.lock().unwrap();
25912605
let channel_state = &mut *channel_lock;
25922606
match channel_state.by_id.entry(msg.channel_id) {
@@ -3334,24 +3348,30 @@ where
33343348
L::Target: Logger,
33353349
{
33363350
fn block_connected(&self, block: &Block, height: u32) {
3337-
assert_eq!(*self.last_block_hash.read().unwrap(), block.header.prev_blockhash,
3338-
"Blocks must be connected in chain-order - the connected header must build on the last connected header");
3339-
assert_eq!(self.latest_block_height.load(Ordering::Acquire) as u64, height as u64 - 1,
3340-
"Blocks must be connected in chain-order - the connected block height must be one greater than the previous height");
3351+
{
3352+
let best_block = self.best_block.read().unwrap();
3353+
assert_eq!(best_block.block_hash(), block.header.prev_blockhash,
3354+
"Blocks must be connected in chain-order - the connected header must build on the last connected header");
3355+
assert_eq!(best_block.height(), height - 1,
3356+
"Blocks must be connected in chain-order - the connected block height must be one greater than the previous height");
3357+
}
3358+
33413359
let txdata: Vec<_> = block.txdata.iter().enumerate().collect();
33423360
self.transactions_confirmed(&block.header, height, &txdata);
33433361
self.update_best_block(&block.header, height);
33443362
}
33453363

33463364
fn block_disconnected(&self, header: &BlockHeader, height: u32) {
3347-
assert_eq!(*self.last_block_hash.read().unwrap(), header.block_hash(),
3348-
"Blocks must be disconnected in chain-order - the disconnected header must be the last connected header");
3349-
33503365
let _persistence_guard = PersistenceNotifierGuard::new(&self.total_consistency_lock, &self.persistence_notifier);
3351-
let new_height = self.latest_block_height.fetch_sub(1, Ordering::AcqRel) as u32 - 1;
3352-
assert_eq!(new_height, height - 1,
3353-
"Blocks must be disconnected in chain-order - the disconnected block must have the correct height");
3354-
*self.last_block_hash.write().unwrap() = header.prev_blockhash;
3366+
let new_height = height - 1;
3367+
{
3368+
let mut best_block = self.best_block.write().unwrap();
3369+
assert_eq!(best_block.block_hash(), header.block_hash(),
3370+
"Blocks must be disconnected in chain-order - the disconnected header must be the last connected header");
3371+
assert_eq!(best_block.height(), height,
3372+
"Blocks must be disconnected in chain-order - the disconnected block must have the correct height");
3373+
*best_block = BestBlock::new(header.prev_blockhash, new_height)
3374+
}
33553375

33563376
self.do_chain_event(new_height, |channel| channel.update_best_block(new_height, header.time));
33573377
}
@@ -3503,8 +3523,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
35033523

35043524
let _persistence_guard = PersistenceNotifierGuard::new(&self.total_consistency_lock, &self.persistence_notifier);
35053525

3506-
self.latest_block_height.store(height as usize, Ordering::Release);
3507-
*self.last_block_hash.write().unwrap() = block_hash;
3526+
*self.best_block.write().unwrap() = BestBlock::new(block_hash, height);
35083527

35093528
self.do_chain_event(height, |channel| channel.update_best_block(height, header.time));
35103529

@@ -4082,8 +4101,11 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> Writeable f
40824101
writer.write_all(&[MIN_SERIALIZATION_VERSION; 1])?;
40834102

40844103
self.genesis_hash.write(writer)?;
4085-
(self.latest_block_height.load(Ordering::Acquire) as u32).write(writer)?;
4086-
self.last_block_hash.read().unwrap().write(writer)?;
4104+
{
4105+
let best_block = self.best_block.read().unwrap();
4106+
best_block.height().write(writer)?;
4107+
best_block.block_hash().write(writer)?;
4108+
}
40874109

40884110
let channel_state = self.channel_state.lock().unwrap();
40894111
let mut unfunded_channels = 0;
@@ -4275,8 +4297,8 @@ impl<'a, Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
42754297
}
42764298

42774299
let genesis_hash: BlockHash = Readable::read(reader)?;
4278-
let latest_block_height: u32 = Readable::read(reader)?;
4279-
let last_block_hash: BlockHash = Readable::read(reader)?;
4300+
let best_block_height: u32 = Readable::read(reader)?;
4301+
let best_block_hash: BlockHash = Readable::read(reader)?;
42804302

42814303
let mut failed_htlcs = Vec::new();
42824304

@@ -4384,8 +4406,7 @@ impl<'a, Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
43844406
chain_monitor: args.chain_monitor,
43854407
tx_broadcaster: args.tx_broadcaster,
43864408

4387-
latest_block_height: AtomicUsize::new(latest_block_height as usize),
4388-
last_block_hash: RwLock::new(last_block_hash),
4409+
best_block: RwLock::new(BestBlock::new(best_block_hash, best_block_height)),
43894410

43904411
channel_state: Mutex::new(ChannelHolder {
43914412
by_id,
@@ -4419,7 +4440,7 @@ impl<'a, Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
44194440
//TODO: Broadcast channel update for closed channels, but only after we've made a
44204441
//connection or two.
44214442

4422-
Ok((last_block_hash.clone(), channel_manager))
4443+
Ok((best_block_hash.clone(), channel_manager))
44234444
}
44244445
}
44254446

@@ -4481,7 +4502,7 @@ pub mod bench {
44814502
use chain::channelmonitor::Persist;
44824503
use chain::keysinterface::{KeysManager, InMemorySigner};
44834504
use chain::transaction::OutPoint;
4484-
use ln::channelmanager::{ChainParameters, ChannelManager, PaymentHash, PaymentPreimage};
4505+
use ln::channelmanager::{BestBlock, ChainParameters, ChannelManager, PaymentHash, PaymentPreimage};
44854506
use ln::features::InitFeatures;
44864507
use ln::functional_test_utils::*;
44874508
use ln::msgs::ChannelMessageHandler;
@@ -4533,8 +4554,7 @@ pub mod bench {
45334554
let keys_manager_a = KeysManager::new(&seed_a, 42, 42);
45344555
let node_a = ChannelManager::new(&fee_estimator, &chain_monitor_a, &tx_broadcaster, &logger_a, &keys_manager_a, config.clone(), ChainParameters {
45354556
network,
4536-
latest_hash: genesis_hash,
4537-
latest_height: 0,
4557+
best_block: BestBlock::from_genesis(network),
45384558
});
45394559
let node_a_holder = NodeHolder { node: &node_a };
45404560

@@ -4544,8 +4564,7 @@ pub mod bench {
45444564
let keys_manager_b = KeysManager::new(&seed_b, 42, 42);
45454565
let node_b = ChannelManager::new(&fee_estimator, &chain_monitor_b, &tx_broadcaster, &logger_b, &keys_manager_b, config.clone(), ChainParameters {
45464566
network,
4547-
latest_hash: genesis_hash,
4548-
latest_height: 0,
4567+
best_block: BestBlock::from_genesis(network),
45494568
});
45504569
let node_b_holder = NodeHolder { node: &node_b };
45514570

lightning/src/ln/functional_test_utils.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
use chain::{Listen, Watch};
1414
use chain::channelmonitor::ChannelMonitor;
1515
use chain::transaction::OutPoint;
16-
use ln::channelmanager::{ChainParameters, ChannelManager, ChannelManagerReadArgs, RAACommitmentOrder, PaymentPreimage, PaymentHash, PaymentSecret, PaymentSendFailure};
16+
use ln::channelmanager::{BestBlock, ChainParameters, ChannelManager, ChannelManagerReadArgs, RAACommitmentOrder, PaymentPreimage, PaymentHash, PaymentSecret, PaymentSendFailure};
1717
use routing::router::{Route, get_route};
1818
use routing::network_graph::{NetGraphMsgHandler, NetworkGraph};
1919
use ln::features::InitFeatures;
@@ -1278,8 +1278,7 @@ pub fn create_node_chanmgrs<'a, 'b>(node_count: usize, cfgs: &'a Vec<NodeCfg<'b>
12781278
let network = Network::Testnet;
12791279
let params = ChainParameters {
12801280
network,
1281-
latest_hash: genesis_block(network).header.block_hash(),
1282-
latest_height: 0,
1281+
best_block: BestBlock::from_genesis(network),
12831282
};
12841283
let node = ChannelManager::new(cfgs[i].fee_estimator, &cfgs[i].chain_monitor, cfgs[i].tx_broadcaster, cfgs[i].logger, cfgs[i].keys_manager, if node_config[i].is_some() { node_config[i].clone().unwrap() } else { default_config }, params);
12851284
chanmgrs.push(node);

0 commit comments

Comments
 (0)