Skip to content

Commit 2cdf697

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 2d03c7b commit 2cdf697

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;
@@ -351,15 +351,13 @@ pub fn do_test(data: &[u8], logger: &Arc<dyn Logger>) {
351351
config.channel_options.announced_channel = get_slice!(1)[0] != 0;
352352
config.peer_channel_config_limits.min_dust_limit_satoshis = 0;
353353
let network = Network::Bitcoin;
354-
let genesis_hash = genesis_block(network).block_hash();
355354
let params = ChainParameters {
356355
network,
357-
latest_hash: genesis_hash,
358-
latest_height: 0,
356+
best_block: BestBlock::from_genesis(network),
359357
};
360358
let channelmanager = Arc::new(ChannelManager::new(fee_est.clone(), monitor.clone(), broadcast.clone(), Arc::clone(&logger), keys_manager.clone(), config, params));
361359
let our_id = PublicKey::from_secret_key(&Secp256k1::signing_only(), &keys_manager.get_node_secret());
362-
let net_graph_msg_handler = Arc::new(NetGraphMsgHandler::new(genesis_hash, None, Arc::clone(&logger)));
360+
let net_graph_msg_handler = Arc::new(NetGraphMsgHandler::new(genesis_block(network).block_hash(), None, Arc::clone(&logger)));
363361

364362
let peers = RefCell::new([false; 256]);
365363
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
@@ -351,9 +351,6 @@ struct PeerState {
351351
latest_features: InitFeatures,
352352
}
353353

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

425422
#[cfg(test)]
426-
pub(super) latest_block_height: AtomicUsize,
423+
pub(super) best_block: RwLock<BestBlock>,
427424
#[cfg(not(test))]
428-
latest_block_height: AtomicUsize,
429-
last_block_hash: RwLock<BlockHash>,
425+
best_block: RwLock<BestBlock>,
430426
secp_ctx: Secp256k1<secp256k1::All>,
431427

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

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

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

824-
latest_block_height: AtomicUsize::new(params.latest_height),
825-
last_block_hash: RwLock::new(params.latest_hash),
844+
best_block: RwLock::new(params.best_block),
826845

827846
channel_state: Mutex::new(ChannelHolder{
828847
by_id: HashMap::new(),
@@ -1169,7 +1188,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
11691188
// HTLC_FAIL_BACK_BUFFER blocks to go.
11701189
// Also, ensure that, in the case of an unknown payment hash, our payment logic has enough time to fail the HTLC backward
11711190
// before our onchain logic triggers a channel closure (see HTLC_FAIL_BACK_BUFFER rational).
1172-
if (msg.cltv_expiry as u64) <= self.latest_block_height.load(Ordering::Acquire) as u64 + HTLC_FAIL_BACK_BUFFER as u64 + 1 {
1191+
if (msg.cltv_expiry as u64) <= self.best_block.read().unwrap().height() as u64 + HTLC_FAIL_BACK_BUFFER as u64 + 1 {
11731192
return_err!("The final CLTV expiry is too soon to handle", 17, &[0;0]);
11741193
}
11751194
// final_incorrect_htlc_amount
@@ -1292,7 +1311,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
12921311
if (msg.cltv_expiry as u64) < (*outgoing_cltv_value) as u64 + chan.get_cltv_expiry_delta() as u64 { // incorrect_cltv_expiry
12931312
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())));
12941313
}
1295-
let cur_height = self.latest_block_height.load(Ordering::Acquire) as u32 + 1;
1314+
let cur_height = self.best_block.read().unwrap().height() + 1;
12961315
// Theoretically, channel counterparty shouldn't send us a HTLC expiring now, but we want to be robust wrt to counterparty
12971316
// packet sanitization (see HTLC_FAIL_BACK_BUFFER rational)
12981317
if msg.cltv_expiry <= cur_height + HTLC_FAIL_BACK_BUFFER as u32 { // expiry_too_soon
@@ -1509,7 +1528,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
15091528
return Err(PaymentSendFailure::PathParameterError(path_errs));
15101529
}
15111530

1512-
let cur_height = self.latest_block_height.load(Ordering::Acquire) as u32 + 1;
1531+
let cur_height = self.best_block.read().unwrap().height() + 1;
15131532
let mut results = Vec::new();
15141533
for path in route.paths.iter() {
15151534
results.push(self.send_payment_along_path(&path, &payment_hash, payment_secret, total_value, cur_height));
@@ -1859,10 +1878,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
18591878
for htlc in htlcs.iter() {
18601879
let mut htlc_msat_height_data = byte_utils::be64_to_array(htlc.value).to_vec();
18611880
htlc_msat_height_data.extend_from_slice(
1862-
&byte_utils::be32_to_array(
1863-
self.latest_block_height.load(Ordering::Acquire)
1864-
as u32,
1865-
),
1881+
&byte_utils::be32_to_array(self.best_block.read().unwrap().height()),
18661882
);
18671883
failed_forwards.push((HTLCSource::PreviousHopData(HTLCPreviousHopData {
18681884
short_channel_id: htlc.prev_hop.short_channel_id,
@@ -1982,8 +1998,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
19821998
if channel_state.is_none() { channel_state = Some(self.channel_state.lock().unwrap()); }
19831999
let mut htlc_msat_height_data = byte_utils::be64_to_array(htlc.value).to_vec();
19842000
htlc_msat_height_data.extend_from_slice(&byte_utils::be32_to_array(
1985-
self.latest_block_height.load(Ordering::Acquire) as u32,
1986-
));
2001+
self.best_block.read().unwrap().height()));
19872002
self.fail_htlc_backwards_internal(channel_state.take().unwrap(),
19882003
HTLCSource::PreviousHopData(htlc.prev_hop), payment_hash,
19892004
HTLCFailReason::Reason { failure_code: 0x4000 | 15, data: htlc_msat_height_data });
@@ -2197,8 +2212,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
21972212
if (is_mpp && !valid_mpp) || (!is_mpp && (htlc.value < expected_amount || htlc.value > expected_amount * 2)) {
21982213
let mut htlc_msat_height_data = byte_utils::be64_to_array(htlc.value).to_vec();
21992214
htlc_msat_height_data.extend_from_slice(&byte_utils::be32_to_array(
2200-
self.latest_block_height.load(Ordering::Acquire) as u32,
2201-
));
2215+
self.best_block.read().unwrap().height()));
22022216
self.fail_htlc_backwards_internal(channel_state.take().unwrap(),
22032217
HTLCSource::PreviousHopData(htlc.prev_hop), &payment_hash,
22042218
HTLCFailReason::Reason { failure_code: 0x4000|15, data: htlc_msat_height_data });
@@ -2486,7 +2500,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
24862500

24872501
fn internal_funding_created(&self, counterparty_node_id: &PublicKey, msg: &msgs::FundingCreated) -> Result<(), MsgHandleErrInternal> {
24882502
let ((funding_msg, monitor), mut chan) = {
2489-
let last_block_hash = *self.last_block_hash.read().unwrap();
2503+
let last_block_hash = self.best_block.read().unwrap().block_hash();
24902504
let mut channel_lock = self.channel_state.lock().unwrap();
24912505
let channel_state = &mut *channel_lock;
24922506
match channel_state.by_id.entry(msg.temporary_channel_id.clone()) {
@@ -2543,7 +2557,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
25432557

25442558
fn internal_funding_signed(&self, counterparty_node_id: &PublicKey, msg: &msgs::FundingSigned) -> Result<(), MsgHandleErrInternal> {
25452559
let (funding_txo, user_id) = {
2546-
let last_block_hash = *self.last_block_hash.read().unwrap();
2560+
let last_block_hash = self.best_block.read().unwrap().block_hash();
25472561
let mut channel_lock = self.channel_state.lock().unwrap();
25482562
let channel_state = &mut *channel_lock;
25492563
match channel_state.by_id.entry(msg.channel_id) {
@@ -3295,24 +3309,30 @@ where
32953309
L::Target: Logger,
32963310
{
32973311
fn block_connected(&self, block: &Block, height: u32) {
3298-
assert_eq!(*self.last_block_hash.read().unwrap(), block.header.prev_blockhash,
3299-
"Blocks must be connected in chain-order - the connected header must build on the last connected header");
3300-
assert_eq!(self.latest_block_height.load(Ordering::Acquire) as u64, height as u64 - 1,
3301-
"Blocks must be connected in chain-order - the connected block height must be one greater than the previous height");
3312+
{
3313+
let best_block = self.best_block.read().unwrap();
3314+
assert_eq!(best_block.block_hash(), block.header.prev_blockhash,
3315+
"Blocks must be connected in chain-order - the connected header must build on the last connected header");
3316+
assert_eq!(best_block.height(), height - 1,
3317+
"Blocks must be connected in chain-order - the connected block height must be one greater than the previous height");
3318+
}
3319+
33023320
let txdata: Vec<_> = block.txdata.iter().enumerate().collect();
33033321
self.transactions_confirmed(&block.header, height, &txdata);
33043322
self.update_best_block(&block.header, height);
33053323
}
33063324

33073325
fn block_disconnected(&self, header: &BlockHeader, height: u32) {
3308-
assert_eq!(*self.last_block_hash.read().unwrap(), header.block_hash(),
3309-
"Blocks must be disconnected in chain-order - the disconnected header must be the last connected header");
3310-
33113326
let _persistence_guard = PersistenceNotifierGuard::new(&self.total_consistency_lock, &self.persistence_notifier);
3312-
let new_height = self.latest_block_height.fetch_sub(1, Ordering::AcqRel) as u32 - 1;
3313-
assert_eq!(new_height, height - 1,
3314-
"Blocks must be disconnected in chain-order - the disconnected block must have the correct height");
3315-
*self.last_block_hash.write().unwrap() = header.prev_blockhash;
3327+
let new_height = height - 1;
3328+
{
3329+
let mut best_block = self.best_block.write().unwrap();
3330+
assert_eq!(best_block.block_hash(), header.block_hash(),
3331+
"Blocks must be disconnected in chain-order - the disconnected header must be the last connected header");
3332+
assert_eq!(best_block.height(), height,
3333+
"Blocks must be disconnected in chain-order - the disconnected block must have the correct height");
3334+
*best_block = BestBlock::new(header.prev_blockhash, new_height)
3335+
}
33163336

33173337
self.do_chain_event(new_height, |channel| channel.update_best_block(new_height, header.time));
33183338
}
@@ -3464,8 +3484,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
34643484

34653485
let _persistence_guard = PersistenceNotifierGuard::new(&self.total_consistency_lock, &self.persistence_notifier);
34663486

3467-
self.latest_block_height.store(height as usize, Ordering::Release);
3468-
*self.last_block_hash.write().unwrap() = block_hash;
3487+
*self.best_block.write().unwrap() = BestBlock::new(block_hash, height);
34693488

34703489
self.do_chain_event(height, |channel| channel.update_best_block(height, header.time));
34713490

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

40454064
self.genesis_hash.write(writer)?;
4046-
(self.latest_block_height.load(Ordering::Acquire) as u32).write(writer)?;
4047-
self.last_block_hash.read().unwrap().write(writer)?;
4065+
{
4066+
let best_block = self.best_block.read().unwrap();
4067+
best_block.height().write(writer)?;
4068+
best_block.block_hash().write(writer)?;
4069+
}
40484070

40494071
let channel_state = self.channel_state.lock().unwrap();
40504072
let mut unfunded_channels = 0;
@@ -4236,8 +4258,8 @@ impl<'a, Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
42364258
}
42374259

42384260
let genesis_hash: BlockHash = Readable::read(reader)?;
4239-
let latest_block_height: u32 = Readable::read(reader)?;
4240-
let last_block_hash: BlockHash = Readable::read(reader)?;
4261+
let best_block_height: u32 = Readable::read(reader)?;
4262+
let best_block_hash: BlockHash = Readable::read(reader)?;
42414263

42424264
let mut failed_htlcs = Vec::new();
42434265

@@ -4345,8 +4367,7 @@ impl<'a, Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
43454367
chain_monitor: args.chain_monitor,
43464368
tx_broadcaster: args.tx_broadcaster,
43474369

4348-
latest_block_height: AtomicUsize::new(latest_block_height as usize),
4349-
last_block_hash: RwLock::new(last_block_hash),
4370+
best_block: RwLock::new(BestBlock::new(best_block_hash, best_block_height)),
43504371

43514372
channel_state: Mutex::new(ChannelHolder {
43524373
by_id,
@@ -4380,7 +4401,7 @@ impl<'a, Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
43804401
//TODO: Broadcast channel update for closed channels, but only after we've made a
43814402
//connection or two.
43824403

4383-
Ok((last_block_hash.clone(), channel_manager))
4404+
Ok((best_block_hash.clone(), channel_manager))
43844405
}
43854406
}
43864407

@@ -4442,7 +4463,7 @@ pub mod bench {
44424463
use chain::channelmonitor::Persist;
44434464
use chain::keysinterface::{KeysManager, InMemorySigner};
44444465
use chain::transaction::OutPoint;
4445-
use ln::channelmanager::{ChainParameters, ChannelManager, PaymentHash, PaymentPreimage};
4466+
use ln::channelmanager::{BestBlock, ChainParameters, ChannelManager, PaymentHash, PaymentPreimage};
44464467
use ln::features::InitFeatures;
44474468
use ln::functional_test_utils::*;
44484469
use ln::msgs::ChannelMessageHandler;
@@ -4494,8 +4515,7 @@ pub mod bench {
44944515
let keys_manager_a = KeysManager::new(&seed_a, 42, 42);
44954516
let node_a = ChannelManager::new(&fee_estimator, &chain_monitor_a, &tx_broadcaster, &logger_a, &keys_manager_a, config.clone(), ChainParameters {
44964517
network,
4497-
latest_hash: genesis_hash,
4498-
latest_height: 0,
4518+
best_block: BestBlock::from_genesis(network),
44994519
});
45004520
let node_a_holder = NodeHolder { node: &node_a };
45014521

@@ -4505,8 +4525,7 @@ pub mod bench {
45054525
let keys_manager_b = KeysManager::new(&seed_b, 42, 42);
45064526
let node_b = ChannelManager::new(&fee_estimator, &chain_monitor_b, &tx_broadcaster, &logger_b, &keys_manager_b, config.clone(), ChainParameters {
45074527
network,
4508-
latest_hash: genesis_hash,
4509-
latest_height: 0,
4528+
best_block: BestBlock::from_genesis(network),
45104529
});
45114530
let node_b_holder = NodeHolder { node: &node_b };
45124531

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;
@@ -1281,8 +1281,7 @@ pub fn create_node_chanmgrs<'a, 'b>(node_count: usize, cfgs: &'a Vec<NodeCfg<'b>
12811281
let network = Network::Testnet;
12821282
let params = ChainParameters {
12831283
network,
1284-
latest_hash: genesis_block(network).header.block_hash(),
1285-
latest_height: 0,
1284+
best_block: BestBlock::from_genesis(network),
12861285
};
12871286
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);
12881287
chanmgrs.push(node);

0 commit comments

Comments
 (0)