Return `BestBlock` when deserializing chain-synced structs
What changed, and why it matters
This commit changes how Lightning Dev Kit (LDK) deserializes (reloads from disk) important chain-following objects like ChannelMonitor and ChannelManager. Previously, deserialization returned just a single latest block hash paired with the object. Now it returns a BestBlock structure that includes the latest block hash plus a short history of recent block hashes. This is a defensive, API-shaping change intended to make downstream developers handle initial chain sync more safely after a restart, especially if the Bitcoin chain source has lost blocks from a reorganization while the node was offline. It is not a patch for an active exploit; it is a hardening/refactoring change that improves resilience against reorgs during startup.
Treat this as a hardening/API improvement rather than an urgent vulnerability fix. Downstream projects using LDK should update their deserialization call sites from (BlockHash, ChannelMonitor/ChannelManager) to (BestBlock, ChannelMonitor/ChannelManager) and use BestBlock.block_hash (and any future BestBlock fields) when registering chain listeners. Review initial chain-sync logic to ensure it can disconnect/reconnect the recent blocks now exposed by BestBlock. No immediate patch deployment is required solely on the basis of this commit.
Security signals we found
API change pushes developers to use richer chain-sync state on startup
BestBlock carries recent block hashes to handle reorgs while offline
Deserialization target changed from (BlockHash, _) to (BestBlock, _) for ChannelMonitor, ChannelManager, OutputSweeper
Persistence helpers (read_channel_monitors, etc.) updated to return BestBlock
Documentation and examples updated to use .block_hash field of BestBlock
No new input validation, bounds checking, or memory-safety code visible in diff
Evidence from the diff
The commit refactors deserialization implementations for ChannelMonitor, ChannelManager, and OutputSweeper from returning (BlockHash, Object) to returning (BestBlock, Object). BestBlock already existed and, in a preceding commit, was extended to store additional recent block hashes. By returning BestBlock at deserialization time, LDK gives callers access to that recent-block history immediately, which is needed for safe initial chain synchronization after restart. The change is pervasive across tests, fuzz targets, persistence helpers, and documentation examples, but the core logic is a type substitution: where deserialization previously extracted best_block.block_hash, it now returns the full best_block. No new cryptographic or consensus logic is introduced in this commit; the security benefit comes from forcing callers to consume the richer chain-sync state.
Changed components
lightning/src/chain/channelmonitor.rslightning/src/ln/channelmanager.rslightning/src/util/persist.rslightning-block-sync/src/init.rsfuzz/src/chanmon_consistency.rsfuzz/src/chanmon_deser.rslightning/src/ln/functional_test_utils.rslightning/src/ln/functional_tests.rslightning/src/ln/reload_tests.rslightning/src/ln/chanmon_update_fail_tests.rslightning/src/util/test_utils.rsInspect captured patch +74 / −77
diff --git a/fuzz/src/chanmon_consistency.rs b/fuzz/src/chanmon_consistency.rs
index e4fd347..98725bd 100644
--- a/fuzz/src/chanmon_consistency.rs
+++ b/fuzz/src/chanmon_consistency.rs
@@ -29,7 +29,7 @@ use bitcoin::transaction::{Transaction, TxOut};
use bitcoin::FeeRate;
use bitcoin::block::Header;
-use bitcoin::hash_types::{BlockHash, Txid};
+use bitcoin::hash_types::Txid;
use bitcoin::hashes::sha256::Hash as Sha256;
use bitcoin::hashes::sha256d::Hash as Sha256dHash;
use bitcoin::hashes::Hash as TraitImport;
@@ -331,7 +331,7 @@ impl chain::Watch<TestChannelSigner> for TestChainMonitor {
.map(|(_, data)| data)
.unwrap_or(&map_entry.persisted_monitor);
let deserialized_monitor =
- <(BlockHash, channelmonitor::ChannelMonitor<TestChannelSigner>)>::read(
+ <(BestBlock, channelmonitor::ChannelMonitor<TestChannelSigner>)>::read(
&mut &latest_monitor_data[..],
(&*self.keys, &*self.keys),
)
@@ -1000,7 +1000,7 @@ pub fn do_test<Out: Output + MaybeSend + MaybeSync>(
// Use a different value of `use_old_mons` if we have another monitor (only for node B)
// by shifting `use_old_mons` one in base-3.
use_old_mons /= 3;
- let mon = <(BlockHash, ChannelMonitor<TestChannelSigner>)>::read(
+ let mon = <(BestBlock, ChannelMonitor<TestChannelSigner>)>::read(
&mut &serialized_mon[..],
(&**keys, &**keys),
)
@@ -1035,7 +1035,7 @@ pub fn do_test<Out: Output + MaybeSend + MaybeSync>(
};
let manager =
- <(BlockHash, ChanMan)>::read(&mut &ser[..], read_args).expect("Failed to read manager");
+ <(BestBlock, ChanMan)>::read(&mut &ser[..], read_args).expect("Failed to read manager");
let res = (manager.1, chain_monitor.clone());
for (channel_id, mon) in monitors.drain() {
assert_eq!(
diff --git a/fuzz/src/chanmon_deser.rs b/fuzz/src/chanmon_deser.rs
index 4a4e79c..be9ffe8 100644
--- a/fuzz/src/chanmon_deser.rs
+++ b/fuzz/src/chanmon_deser.rs
@@ -1,9 +1,7 @@
// This file is auto-generated by gen_target.sh based on msg_target_template.txt
// To modify it, modify msg_target_template.txt and run gen_target.sh instead.
-use bitcoin::hash_types::BlockHash;
-
-use lightning::chain::channelmonitor;
+use lightning::chain::{channelmonitor, BestBlock};
use lightning::util::ser::{ReadableArgs, Writeable, Writer};
use lightning::util::test_channel_signer::TestChannelSigner;
use lightning::util::test_utils::OnlyReadsKeysInterface;
@@ -23,14 +21,14 @@ impl Writer for VecWriter {
#[inline]
pub fn do_test<Out: test_logger::Output>(data: &[u8], _out: Out) {
if let Ok((latest_block_hash, monitor)) =
- <(BlockHash, channelmonitor::ChannelMonitor<TestChannelSigner>)>::read(
+ <(BestBlock, channelmonitor::ChannelMonitor<TestChannelSigner>)>::read(
&mut Cursor::new(data),
(&OnlyReadsKeysInterface {}, &OnlyReadsKeysInterface {}),
) {
let mut w = VecWriter(Vec::new());
monitor.write(&mut w).unwrap();
let deserialized_copy =
- <(BlockHash, channelmonitor::ChannelMonitor<TestChannelSigner>)>::read(
+ <(BestBlock, channelmonitor::ChannelMonitor<TestChannelSigner>)>::read(
&mut Cursor::new(&w.0),
(&OnlyReadsKeysInterface {}, &OnlyReadsKeysInterface {}),
)
diff --git a/lightning-block-sync/src/init.rs b/lightning-block-sync/src/init.rs
index a870f8c..61f44c6 100644
--- a/lightning-block-sync/src/init.rs
+++ b/lightning-block-sync/src/init.rs
@@ -40,11 +40,10 @@ where
/// switching to [`SpvClient`]. For example:
///
/// ```
-/// use bitcoin::hash_types::BlockHash;
/// use bitcoin::network::Network;
///
/// use lightning::chain;
-/// use lightning::chain::Watch;
+/// use lightning::chain::{BestBlock, Watch};
/// use lightning::chain::chainmonitor;
/// use lightning::chain::chainmonitor::ChainMonitor;
/// use lightning::chain::channelmonitor::ChannelMonitor;
@@ -89,14 +88,14 @@ where
/// logger: &L,
/// persister: &P,
/// ) {
-/// // Read a serialized channel monitor paired with the block hash when it was persisted.
+/// // Read a serialized channel monitor paired with the best block when it was persisted.
/// let serialized_monitor = "...";
-/// let (monitor_block_hash, mut monitor) = <(BlockHash, ChannelMonitor<SP::EcdsaSigner>)>::read(
+/// let (monitor_best_block, mut monitor) = <(BestBlock, ChannelMonitor<SP::EcdsaSigner>)>::read(
/// &mut Cursor::new(&serialized_monitor), (entropy_source, signer_provider)).unwrap();
///
-/// // Read the channel manager paired with the block hash when it was persisted.
+/// // Read the channel manager paired with the best block when it was persisted.
/// let serialized_manager = "...";
-/// let (manager_block_hash, mut manager) = {
+/// let (manager_best_block, mut manager) = {
/// let read_args = ChannelManagerReadArgs::new(
/// entropy_source,
/// node_signer,
@@ -110,7 +109,7 @@ where
/// config,
/// vec![&mut monitor],
/// );
-/// <(BlockHash, ChannelManager<&ChainMonitor<SP::EcdsaSigner, &C, &T, &F, &L, &P, &ES>, &T, &ES, &NS, &SP, &F, &R, &MR, &L>)>::read(
+/// <(BestBlock, ChannelManager<&ChainMonitor<SP::EcdsaSigner, &C, &T, &F, &L, &P, &ES>, &T, &ES, &NS, &SP, &F, &R, &MR, &L>)>::read(
/// &mut Cursor::new(&serialized_manager), read_args).unwrap()
/// };
///
@@ -118,8 +117,8 @@ where
/// let mut cache = UnboundedCache::new();
/// let mut monitor_listener = (monitor, &*tx_broadcaster, &*fee_estimator, &*logger);
/// let listeners = vec![
-/// (monitor_block_hash, &monitor_listener as &dyn chain::Listen),
-/// (manager_block_hash, &manager as &dyn chain::Listen),
+/// (monitor_best_block.block_hash, &monitor_listener as &dyn chain::Listen),
+/// (manager_best_block.block_hash, &manager as &dyn chain::Listen),
/// ];
/// let chain_tip = init::synchronize_listeners(
/// block_source, Network::Bitcoin, &mut cache, listeners).await.unwrap();
diff --git a/lightning/src/chain/channelmonitor.rs b/lightning/src/chain/channelmonitor.rs
index 5a49c39..0173e98 100644
--- a/lightning/src/chain/channelmonitor.rs
+++ b/lightning/src/chain/channelmonitor.rs
@@ -1058,7 +1058,7 @@ impl Readable for IrrevocablyResolvedHTLC {
/// You MUST ensure that no ChannelMonitors for a given channel anywhere contain out-of-date
/// information and are actively monitoring the chain.
///
-/// Like the [`ChannelManager`], deserialization is implemented for `(BlockHash, ChannelMonitor)`,
+/// Like the [`ChannelManager`], deserialization is implemented for `(BestBlock, ChannelMonitor)`,
/// providing you with the last block hash which was connected before shutting down. You must begin
/// syncing the chain from that point, disconnecting and connecting blocks as required to get to
/// the best chain on startup. Note that all [`ChannelMonitor`]s passed to a [`ChainMonitor`] must
@@ -1066,7 +1066,7 @@ impl Readable for IrrevocablyResolvedHTLC {
/// initialization.
///
/// For those loading potentially-ancient [`ChannelMonitor`]s, deserialization is also implemented
-/// for `Option<(BlockHash, ChannelMonitor)>`. LDK can no longer deserialize a [`ChannelMonitor`]
+/// for `Option<(BestBlock, ChannelMonitor)>`. LDK can no longer deserialize a [`ChannelMonitor`]
/// that was first created in LDK prior to 0.0.110 and last updated prior to LDK 0.0.119. In such
/// cases, the `Option<(..)>` deserialization option may return `Ok(None)` rather than failing to
/// deserialize, allowing you to differentiate between the two cases.
@@ -6467,7 +6467,7 @@ where
const MAX_ALLOC_SIZE: usize = 64 * 1024;
impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP)>
- for (BlockHash, ChannelMonitor<SP::EcdsaSigner>)
+ for (BestBlock, ChannelMonitor<SP::EcdsaSigner>)
{
fn read<R: io::Read>(reader: &mut R, args: (&'a ES, &'b SP)) -> Result<Self, DecodeError> {
match <Option<Self>>::read(reader, args) {
@@ -6479,7 +6479,7 @@ impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP
}
impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP)>
- for Option<(BlockHash, ChannelMonitor<SP::EcdsaSigner>)>
+ for Option<(BestBlock, ChannelMonitor<SP::EcdsaSigner>)>
{
#[rustfmt::skip]
fn read<R: io::Read>(reader: &mut R, args: (&'a ES, &'b SP)) -> Result<Self, DecodeError> {
@@ -6913,7 +6913,7 @@ impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP
To continue, run a v0.1 release, send/route a payment over the channel or close it.");
}
}
- Ok(Some((best_block.block_hash, monitor)))
+ Ok(Some((best_block, monitor)))
}
}
@@ -6985,7 +6985,7 @@ pub(super) fn dummy_monitor<S: EcdsaChannelSigner + 'static>(
#[cfg(test)]
mod tests {
use bitcoin::amount::Amount;
- use bitcoin::hash_types::{BlockHash, Txid};
+ use bitcoin::hash_types::Txid;
use bitcoin::hashes::sha256::Hash as Sha256;
use bitcoin::hashes::Hash;
use bitcoin::hex::FromHex;
@@ -7011,7 +7011,7 @@ mod tests {
weight_revoked_received_htlc, WEIGHT_REVOKED_OUTPUT,
};
use crate::chain::transaction::OutPoint;
- use crate::chain::Confirm;
+ use crate::chain::{BestBlock, Confirm};
use crate::io;
use crate::ln::chan_utils::{self, HTLCOutputInCommitment, HolderCommitmentTransaction};
use crate::ln::channel_keys::{
@@ -7078,7 +7078,7 @@ mod tests {
nodes[1].chain_monitor.chain_monitor.transactions_confirmed(&new_header,
&[(0, broadcast_tx)], conf_height);
- let (_, pre_update_monitor) = <(BlockHash, ChannelMonitor<_>)>::read(
+ let (_, pre_update_monitor) = <(BestBlock, ChannelMonitor<_>)>::read(
&mut io::Cursor::new(&get_monitor!(nodes[1], channel.2).encode()),
(&nodes[1].keys_manager.backing, &nodes[1].keys_manager.backing)).unwrap();
diff --git a/lightning/src/ln/chanmon_update_fail_tests.rs b/lightning/src/ln/chanmon_update_fail_tests.rs
index 0d8a4a0..0409ce7 100644
--- a/lightning/src/ln/chanmon_update_fail_tests.rs
+++ b/lightning/src/ln/chanmon_update_fail_tests.rs
@@ -16,7 +16,7 @@ use crate::chain::chaininterface::LowerBoundedFeeEstimator;
use crate::chain::chainmonitor::ChainMonitor;
use crate::chain::channelmonitor::{ChannelMonitor, MonitorEvent, ANTI_REORG_DELAY};
use crate::chain::transaction::OutPoint;
-use crate::chain::{ChannelMonitorUpdateStatus, Confirm, Listen, Watch};
+use crate::chain::{BestBlock, ChannelMonitorUpdateStatus, Confirm, Listen, Watch};
use crate::events::{ClosureReason, Event, HTLCHandlingFailureType, PaymentPurpose};
use crate::ln::channel::AnnouncementSigsState;
use crate::ln::channelmanager::{PaymentId, RAACommitmentOrder};
@@ -90,7 +90,7 @@ fn test_monitor_and_persister_update_fail() {
let chain_mon = {
let new_monitor = {
let monitor = nodes[0].chain_monitor.chain_monitor.get_monitor(chan.2).unwrap();
- let (_, new_monitor) = <(BlockHash, ChannelMonitor<TestChannelSigner>)>::read(
+ let (_, new_monitor) = <(BestBlock, ChannelMonitor<TestChannelSigner>)>::read(
&mut &monitor.encode()[..],
(nodes[0].keys_manager, nodes[0].keys_manager),
)
diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs
index d63ccca..cba2f73 100644
--- a/lightning/src/ln/channelmanager.rs
+++ b/lightning/src/ln/channelmanager.rs
@@ -2048,7 +2048,6 @@ impl<
/// detailed in the [`ChannelManagerReadArgs`] documentation.
///
/// ```
-/// use bitcoin::BlockHash;
/// use bitcoin::network::Network;
/// use lightning::chain::BestBlock;
/// # use lightning::chain::channelmonitor::ChannelMonitor;
@@ -2097,8 +2096,8 @@ impl<
/// entropy_source, node_signer, signer_provider, fee_estimator, chain_monitor, tx_broadcaster,
/// router, message_router, logger, config, channel_monitors.iter().collect(),
/// );
-/// let (block_hash, channel_manager) =
-/// <(BlockHash, ChannelManager<_, _, _, _, _, _, _, _, _>)>::read(&mut reader, args)?;
+/// let (best_block, channel_manager) =
+/// <(BestBlock, ChannelManager<_, _, _, _, _, _, _, _, _>)>::read(&mut reader, args)?;
///
/// // Update the ChannelManager and ChannelMonitors with the latest chain data
/// // ...
@@ -2665,7 +2664,7 @@ impl<
/// [`read`], those channels will be force-closed based on the `ChannelMonitor` state and no funds
/// will be lost (modulo on-chain transaction fees).
///
-/// Note that the deserializer is only implemented for `(`[`BlockHash`]`, `[`ChannelManager`]`)`, which
+/// Note that the deserializer is only implemented for `(`[`BestBlock`]`, `[`ChannelManager`]`)`, which
/// tells you the last block hash which was connected. You should get the best block tip before using the manager.
/// See [`chain::Listen`] and [`chain::Confirm`] for more details.
///
@@ -2732,7 +2731,6 @@ impl<
/// [`peer_disconnected`]: msgs::BaseMessageHandler::peer_disconnected
/// [`funding_created`]: msgs::FundingCreated
/// [`funding_transaction_generated`]: Self::funding_transaction_generated
-/// [`BlockHash`]: bitcoin::hash_types::BlockHash
/// [`update_channel`]: chain::Watch::update_channel
/// [`ChannelUpdate`]: msgs::ChannelUpdate
/// [`read`]: ReadableArgs::read
@@ -18644,7 +18642,7 @@ impl<'a, ES: EntropySource, SP: SignerProvider, L: Logger>
/// is:
/// 1) Deserialize all stored [`ChannelMonitor`]s.
/// 2) Deserialize the [`ChannelManager`] by filling in this struct and calling:
-/// `<(BlockHash, ChannelManager)>::read(reader, args)`
+/// `<(BestBlock, ChannelManager)>::read(reader, args)`
/// This may result in closing some channels if the [`ChannelMonitor`] is newer than the stored
/// [`ChannelManager`] state to ensure no loss of funds. Thus, transactions may be broadcasted.
/// 3) If you are not fetching full blocks, register all relevant [`ChannelMonitor`] outpoints the
@@ -18845,14 +18843,14 @@ impl<
MR: MessageRouter,
L: Logger + Clone,
> ReadableArgs<ChannelManagerReadArgs<'a, M, T, ES, NS, SP, F, R, MR, L>>
- for (BlockHash, Arc<ChannelManager<M, T, ES, NS, SP, F, R, MR, L>>)
+ for (BestBlock, Arc<ChannelManager<M, T, ES, NS, SP, F, R, MR, L>>)
{
fn read<Reader: io::Read>(
reader: &mut Reader, args: ChannelManagerReadArgs<'a, M, T, ES, NS, SP, F, R, MR, L>,
) -> Result<Self, DecodeError> {
- let (blockhash, chan_manager) =
- <(BlockHash, ChannelManager<M, T, ES, NS, SP, F, R, MR, L>)>::read(reader, args)?;
- Ok((blockhash, Arc::new(chan_manager)))
+ let (best_block, chan_manager) =
+ <(BestBlock, ChannelManager<M, T, ES, NS, SP, F, R, MR, L>)>::read(reader, args)?;
+ Ok((best_block, Arc::new(chan_manager)))
}
}
@@ -18868,7 +18866,7 @@ impl<
MR: MessageRouter,
L: Logger + Clone,
> ReadableArgs<ChannelManagerReadArgs<'a, M, T, ES, NS, SP, F, R, MR, L>>
- for (BlockHash, ChannelManager<M, T, ES, NS, SP, F, R, MR, L>)
+ for (BestBlock, ChannelManager<M, T, ES, NS, SP, F, R, MR, L>)
{
fn read<Reader: io::Read>(
reader: &mut Reader, args: ChannelManagerReadArgs<'a, M, T, ES, NS, SP, F, R, MR, L>,
@@ -18912,7 +18910,7 @@ impl<
pub(super) fn from_channel_manager_data(
data: ChannelManagerData<SP>,
mut args: ChannelManagerReadArgs<'_, M, T, ES, NS, SP, F, R, MR, L>,
- ) -> Result<(BlockHash, Self), DecodeError> {
+ ) -> Result<(BestBlock, Self), DecodeError> {
let ChannelManagerData {
chain_hash,
best_block,
@@ -20534,7 +20532,7 @@ impl<
//TODO: Broadcast channel update for closed channels, but only after we've made a
//connection or two.
- Ok((best_block.block_hash, channel_manager))
+ Ok((best_block, channel_manager))
}
}
diff --git a/lightning/src/ln/functional_test_utils.rs b/lightning/src/ln/functional_test_utils.rs
index 80274d1..0dcac34 100644
--- a/lightning/src/ln/functional_test_utils.rs
+++ b/lightning/src/ln/functional_test_utils.rs
@@ -859,7 +859,7 @@ impl<'a, 'b, 'c> Drop for Node<'a, 'b, 'c> {
let mon = self.chain_monitor.chain_monitor.get_monitor(channel_id).unwrap();
mon.write(&mut w).unwrap();
let (_, deserialized_monitor) =
- <(BlockHash, ChannelMonitor<TestChannelSigner>)>::read(
+ <(BestBlock, ChannelMonitor<TestChannelSigner>)>::read(
&mut io::Cursor::new(&w.0),
(self.keys_manager, self.keys_manager),
)
@@ -888,7 +888,7 @@ impl<'a, 'b, 'c> Drop for Node<'a, 'b, 'c> {
let mut w = test_utils::TestVecWriter(Vec::new());
self.node.write(&mut w).unwrap();
<(
- BlockHash,
+ BestBlock,
ChannelManager<
&test_utils::TestChainMonitor,
&test_utils::TestBroadcaster,
@@ -1327,7 +1327,7 @@ pub fn _reload_node<'a, 'b, 'c>(
let mut monitors_read = Vec::with_capacity(monitors_encoded.len());
for encoded in monitors_encoded {
let mut monitor_read = &encoded[..];
- let (_, monitor) = <(BlockHash, ChannelMonitor<TestChannelSigner>)>::read(
+ let (_, monitor) = <(BestBlock, ChannelMonitor<TestChannelSigner>)>::read(
&mut monitor_read,
(node.keys_manager, node.keys_manager),
)
@@ -1342,7 +1342,7 @@ pub fn _reload_node<'a, 'b, 'c>(
for monitor in monitors_read.iter() {
assert!(channel_monitors.insert(monitor.channel_id(), monitor).is_none());
}
- <(BlockHash, TestChannelManager<'b, 'c>)>::read(
+ <(BestBlock, TestChannelManager<'b, 'c>)>::read(
&mut node_read,
ChannelManagerReadArgs {
config,
diff --git a/lightning/src/ln/functional_tests.rs b/lightning/src/ln/functional_tests.rs
index a325247..6b1b0f6 100644
--- a/lightning/src/ln/functional_tests.rs
+++ b/lightning/src/ln/functional_tests.rs
@@ -19,6 +19,7 @@ use crate::chain::channelmonitor::{
LATENCY_GRACE_PERIOD_BLOCKS,
};
use crate::chain::transaction::OutPoint;
+use crate::chain::BestBlock;
use crate::chain::{ChannelMonitorUpdateStatus, Confirm, Listen, Watch};
use crate::events::{
ClosureReason, Event, HTLCHandlingFailureType, PathFailure, PaymentFailureReason,
@@ -7377,7 +7378,7 @@ pub fn test_update_err_monitor_lockdown() {
let new_monitor = {
let monitor = nodes[0].chain_monitor.chain_monitor.get_monitor(chan_1.2).unwrap();
let new_monitor =
- <(BlockHash, channelmonitor::ChannelMonitor<TestChannelSigner>)>::read(
+ <(BestBlock, channelmonitor::ChannelMonitor<TestChannelSigner>)>::read(
&mut io::Cursor::new(&monitor.encode()),
(nodes[0].keys_manager, nodes[0].keys_manager),
)
@@ -7485,7 +7486,7 @@ pub fn test_concurrent_monitor_claim() {
let new_monitor = {
let monitor = nodes[0].chain_monitor.chain_monitor.get_monitor(chan_1.2).unwrap();
let new_monitor =
- <(BlockHash, channelmonitor::ChannelMonitor<TestChannelSigner>)>::read(
+ <(BestBlock, channelmonitor::ChannelMonitor<TestChannelSigner>)>::read(
&mut io::Cursor::new(&monitor.encode()),
(nodes[0].keys_manager, nodes[0].keys_manager),
)
@@ -7535,7 +7536,7 @@ pub fn test_concurrent_monitor_claim() {
let new_monitor = {
let monitor = nodes[0].chain_monitor.chain_monitor.get_monitor(chan_1.2).unwrap();
let new_monitor =
- <(BlockHash, channelmonitor::ChannelMonitor<TestChannelSigner>)>::read(
+ <(BestBlock, channelmonitor::ChannelMonitor<TestChannelSigner>)>::read(
&mut io::Cursor::new(&monitor.encode()),
(nodes[0].keys_manager, nodes[0].keys_manager),
)
diff --git a/lightning/src/ln/reload_tests.rs b/lightning/src/ln/reload_tests.rs
index 8d9eac5..892a6c6 100644
--- a/lightning/src/ln/reload_tests.rs
+++ b/lightning/src/ln/reload_tests.rs
@@ -11,7 +11,7 @@
//! Functional tests which test for correct behavior across node restarts.
-use crate::chain::{ChannelMonitorUpdateStatus, Watch};
+use crate::chain::{BestBlock, ChannelMonitorUpdateStatus, Watch};
use crate::chain::chaininterface::LowerBoundedFeeEstimator;
use crate::chain::channelmonitor::{ChannelMonitor, ChannelMonitorUpdateStep};
use crate::routing::router::{PaymentParameters, RouteParameters};
@@ -30,7 +30,6 @@ use crate::util::ser::{Writeable, ReadableArgs};
use crate::util::config::{HTLCInterceptionFlags, UserConfig};
use bitcoin::hashes::Hash;
-use bitcoin::hash_types::BlockHash;
use types::payment::{PaymentHash, PaymentPreimage};
use crate::prelude::*;
@@ -412,7 +411,7 @@ fn test_manager_serialize_deserialize_inconsistent_monitor() {
let mut node_0_stale_monitors = Vec::new();
for serialized in node_0_stale_monitors_serialized.iter() {
let mut read = &serialized[..];
- let (_, monitor) = <(BlockHash, ChannelMonitor<TestChannelSigner>)>::read(&mut read, (keys_manager, keys_manager)).unwrap();
+ let (_, monitor) = <(BestBlock, ChannelMonitor<TestChannelSigner>)>::read(&mut read, (keys_manager, keys_manager)).unwrap();
assert!(read.is_empty());
node_0_stale_monitors.push(monitor);
}
@@ -420,14 +419,14 @@ fn test_manager_serialize_deserialize_inconsistent_monitor() {
let mut node_0_monitors = Vec::new();
for serialized in node_0_monitors_serialized.iter() {
let mut read = &serialized[..];
- let (_, monitor) = <(BlockHash, ChannelMonitor<TestChannelSigner>)>::read(&mut read, (keys_manager, keys_manager)).unwrap();
+ let (_, monitor) = <(BestBlock, ChannelMonitor<TestChannelSigner>)>::read(&mut read, (keys_manager, keys_manager)).unwrap();
assert!(read.is_empty());
node_0_monitors.push(monitor);
}
let mut nodes_0_read = &nodes_0_serialized[..];
if let Err(msgs::DecodeError::DangerousValue) =
- <(BlockHash, ChannelManager<&test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestKeysInterface, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestRouter, &test_utils::TestMessageRouter, &test_utils::TestLogger>)>::read(&mut nodes_0_read, ChannelManagerReadArgs {
+ <(BestBlock, ChannelManager<&test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestKeysInterface, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestRouter, &test_utils::TestMessageRouter, &test_utils::TestLogger>)>::read(&mut nodes_0_read, ChannelManagerReadArgs {
config: UserConfig::default(),
entropy_source: keys_manager,
node_signer: keys_manager,
@@ -446,7 +445,7 @@ fn test_manager_serialize_deserialize_inconsistent_monitor() {
let mut nodes_0_read = &nodes_0_serialized[..];
let (_, nodes_0_deserialized_tmp) =
- <(BlockHash, ChannelManager<&test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestKeysInterface, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestRouter, &test_utils::TestMessageRouter, &test_utils::TestLogger>)>::read(&mut nodes_0_read, ChannelManagerReadArgs {
+ <(BestBlock, ChannelManager<&test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestKeysInterface, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestRouter, &test_utils::TestMessageRouter, &test_utils::TestLogger>)>::read(&mut nodes_0_read, ChannelManagerReadArgs {
config: UserConfig::default(),
entropy_source: keys_manager,
node_signer: keys_manager,
diff --git a/lightning/src/util/persist.rs b/lightning/src/util/persist.rs
index f27ccc1..7df63aa 100644
--- a/lightning/src/util/persist.rs
+++ b/lightning/src/util/persist.rs
@@ -14,7 +14,7 @@
use alloc::sync::Arc;
use bitcoin::hashes::hex::FromHex;
-use bitcoin::{BlockHash, Txid};
+use bitcoin::Txid;
use core::convert::Infallible;
use core::fmt;
@@ -33,6 +33,7 @@ use crate::chain::chaininterface::{BroadcasterInterface, FeeEstimator};
use crate::chain::chainmonitor::Persist;
use crate::chain::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate};
use crate::chain::transaction::OutPoint;
+use crate::chain::BestBlock;
use crate::ln::types::ChannelId;
use crate::sign::{ecdsa::EcdsaChannelSigner, EntropySource, SignerProvider};
use crate::sync::Mutex;
@@ -653,7 +654,7 @@ impl<ChannelSigner: EcdsaChannelSigner, K: KVStoreSync + ?Sized> Persist<Channel
/// Read previously persisted [`ChannelMonitor`]s from the store.
pub fn read_channel_monitors<K: Deref, ES: EntropySource, SP: SignerProvider>(
kv_store: K, entropy_source: ES, signer_provider: SP,
-) -> Result<Vec<(BlockHash, ChannelMonitor<SP::EcdsaSigner>)>, io::Error>
+) -> Result<Vec<(BestBlock, ChannelMonitor<SP::EcdsaSigner>)>, io::Error>
where
K::Target: KVStoreSync,
{
@@ -663,7 +664,7 @@ where
CHANNEL_MONITOR_PERSISTENCE_PRIMARY_NAMESPACE,
CHANNEL_MONITOR_PERSISTENCE_SECONDARY_NAMESPACE,
)? {
- match <Option<(BlockHash, ChannelMonitor<SP::EcdsaSigner>)>>::read(
+ match <Option<(BestBlock, ChannelMonitor<SP::EcdsaSigner>)>>::read(
&mut io::Cursor::new(kv_store.read(
CHANNEL_MONITOR_PERSISTENCE_PRIMARY_NAMESPACE,
CHANNEL_MONITOR_PERSISTENCE_SECONDARY_NAMESPACE,
@@ -671,7 +672,7 @@ where
)?),
(&entropy_source, &signer_provider),
) {
- Ok(Some((block_hash, channel_monitor))) => {
+ Ok(Some((best_block, channel_monitor))) => {
let monitor_name = MonitorName::from_str(&stored_key)?;
if channel_monitor.persistence_key() != monitor_name {
return Err(io::Error::new(
@@ -680,7 +681,7 @@ where
));
}
- res.push((block_hash, channel_monitor));
+ res.push((best_block, channel_monitor));
},
Ok(None) => {},
Err(_) => {
@@ -856,7 +857,7 @@ where
/// Reads all stored channel monitors, along with any stored updates for them.
pub fn read_all_channel_monitors_with_updates(
&self,
- ) -> Result<Vec<(BlockHash, ChannelMonitor<SP::EcdsaSigner>)>, io::Error> {
+ ) -> Result<Vec<(BestBlock, ChannelMonitor<SP::EcdsaSigner>)>, io::Error> {
poll_sync_future(self.0.read_all_channel_monitors_with_updates())
}
@@ -877,7 +878,7 @@ where
/// function to accomplish this. Take care to limit the number of parallel readers.
pub fn read_channel_monitor_with_updates(
&self, monitor_key: &str,
- ) -> Result<(BlockHash, ChannelMonitor<SP::EcdsaSigner>), io::Error> {
+ ) -> Result<(BestBlock, ChannelMonitor<SP::EcdsaSigner>), io::Error> {
poll_sync_future(self.0.read_channel_monitor_with_updates(monitor_key))
}
@@ -1044,7 +1045,7 @@ impl<
/// deserialization as well.
pub async fn read_all_channel_monitors_with_updates(
&self,
- ) -> Result<Vec<(BlockHash, ChannelMonitor<SP::EcdsaSigner>)>, io::Error> {
+ ) -> Result<Vec<(BestBlock, ChannelMonitor<SP::EcdsaSigner>)>, io::Error> {
let primary = CHANNEL_MONITOR_PERSISTENCE_PRIMARY_NAMESPACE;
let secondary = CHANNEL_MONITOR_PERSISTENCE_SECONDARY_NAMESPACE;
let monitor_list = self.0.kv_store.list(primary, secondary).await?;
@@ -1075,7 +1076,7 @@ impl<
/// `Arc` that can live for `'static` and be sent and accessed across threads.
pub async fn read_all_channel_monitors_with_updates_parallel(
self: &Arc<Self>,
- ) -> Result<Vec<(BlockHash, ChannelMonitor<SP::EcdsaSigner>)>, io::Error>
+ ) -> Result<Vec<(BestBlock, ChannelMonitor<SP::EcdsaSigner>)>, io::Error>
where
K: MaybeSend + MaybeSync + 'static,
L: MaybeSend + MaybeSync + 'static,
@@ -1125,7 +1126,7 @@ impl<
/// function to accomplish this. Take care to limit the number of parallel readers.
pub async fn read_channel_monitor_with_updates(
&self, monitor_key: &str,
- ) -> Result<(BlockHash, ChannelMonitor<SP::EcdsaSigner>), io::Error> {
+ ) -> Result<(BestBlock, ChannelMonitor<SP::EcdsaSigner>), io::Error> {
self.0.read_channel_monitor_with_updates(monitor_key).await
}
@@ -1236,7 +1237,7 @@ impl<
{
pub async fn read_channel_monitor_with_updates(
&self, monitor_key: &str,
- ) -> Result<(BlockHash, ChannelMonitor<SP::EcdsaSigner>), io::Error> {
+ ) -> Result<(BestBlock, ChannelMonitor<SP::EcdsaSigner>), io::Error> {
match self.maybe_read_channel_monitor_with_updates(monitor_key).await? {
Some(res) => Ok(res),
None => Err(io::Error::new(
@@ -1253,14 +1254,14 @@ impl<
async fn maybe_read_channel_monitor_with_updates(
&self, monitor_key: &str,
- ) -> Result<Option<(BlockHash, ChannelMonitor<SP::EcdsaSigner>)>, io::Error> {
+ ) -> Result<Option<(BestBlock, ChannelMonitor<SP::EcdsaSigner>)>, io::Error> {
let monitor_name = MonitorName::from_str(monitor_key)?;
let read_future = pin!(self.maybe_read_monitor(&monitor_name, monitor_key));
let list_future = pin!(self
.kv_store
.list(CHANNEL_MONITOR_UPDATE_PERSISTENCE_PRIMARY_NAMESPACE, monitor_key));
let (read_res, list_res) = TwoFutureJoiner::new(read_future, list_future).await;
- let (block_hash, monitor) = match read_res? {
+ let (best_block, monitor) = match read_res? {
Some(res) => res,
None => return Ok(None),
};
@@ -1291,13 +1292,13 @@ impl<
io::Error::new(io::ErrorKind::Other, "Monitor update failed")
})?;
}
- Ok(Some((block_hash, monitor)))
+ Ok(Some((best_block, monitor)))
}
/// Read a channel monitor.
async fn maybe_read_monitor(
&self, monitor_name: &MonitorName, monitor_key: &str,
- ) -> Result<Option<(BlockHash, ChannelMonitor<SP::EcdsaSigner>)>, io::Error> {
+ ) -> Result<Option<(BestBlock, ChannelMonitor<SP::EcdsaSigner>)>, io::Error> {
let primary = CHANNEL_MONITOR_PERSISTENCE_PRIMARY_NAMESPACE;
let secondary = CHANNEL_MONITOR_PERSISTENCE_SECONDARY_NAMESPACE;
let monitor_bytes = self.kv_store.read(primary, secondary, monitor_key).await?;
@@ -1306,12 +1307,12 @@ impl<
if monitor_cursor.get_ref().starts_with(MONITOR_UPDATING_PERSISTER_PREPEND_SENTINEL) {
monitor_cursor.set_position(MONITOR_UPDATING_PERSISTER_PREPEND_SENTINEL.len() as u64);
}
- match <Option<(BlockHash, ChannelMonitor<SP::EcdsaSigner>)>>::read(
+ match <Option<(BestBlock, ChannelMonitor<SP::EcdsaSigner>)>>::read(
&mut monitor_cursor,
(&self.entropy_source, &self.signer_provider),
) {
Ok(None) => Ok(None),
- Ok(Some((blockhash, channel_monitor))) => {
+ Ok(Some((best_block, channel_monitor))) => {
if channel_monitor.persistence_key() != *monitor_name {
log_error!(
self.logger,
@@ -1323,7 +1324,7 @@ impl<
"ChannelMonitor was stored under the wrong key",
))
} else {
- Ok(Some((blockhash, channel_monitor)))
+ Ok(Some((best_block, channel_monitor)))
}
},
Err(e) => {
@@ -1502,7 +1503,7 @@ impl<
async fn archive_persisted_channel(&self, monitor_name: MonitorName) {
let monitor_key = monitor_name.to_string();
let monitor = match self.read_channel_monitor_with_updates(&monitor_key).await {
- Ok((_block_hash, monitor)) => monitor,
+ Ok((_best_block, monitor)) => monitor,
Err(_) => return,
};
let primary = ARCHIVED_CHANNEL_MONITOR_PERSISTENCE_PRIMARY_NAMESPACE;
diff --git a/lightning/src/util/test_utils.rs b/lightning/src/util/test_utils.rs
index abcc24a..4b037cd 100644
--- a/lightning/src/util/test_utils.rs
+++ b/lightning/src/util/test_utils.rs
@@ -20,6 +20,7 @@ use crate::chain::channelmonitor::{
ChannelMonitor, ChannelMonitorUpdate, ChannelMonitorUpdateStep, MonitorEvent,
};
use crate::chain::transaction::OutPoint;
+use crate::chain::BestBlock;
use crate::chain::WatchedOutput;
#[cfg(any(test, feature = "_externalize_tests"))]
use crate::ln::chan_utils::CommitmentTransaction;
@@ -66,7 +67,7 @@ use bitcoin::amount::Amount;
use bitcoin::block::Block;
use bitcoin::constants::genesis_block;
use bitcoin::constants::ChainHash;
-use bitcoin::hash_types::{BlockHash, Txid};
+use bitcoin::hash_types::Txid;
use bitcoin::hashes::{hex::FromHex, Hash};
use bitcoin::network::Network;
use bitcoin::script::{Builder, Script, ScriptBuf};
@@ -605,7 +606,7 @@ impl<'a> TestChainMonitor<'a> {
// underlying `ChainMonitor`.
let mut w = TestVecWriter(Vec::new());
monitor.write(&mut w).unwrap();
- let new_monitor = <(BlockHash, ChannelMonitor<TestChannelSigner>)>::read(
+ let new_monitor = <(BestBlock, ChannelMonitor<TestChannelSigner>)>::read(
&mut io::Cursor::new(&w.0),
(self.keys_manager, self.keys_manager),
)
@@ -642,7 +643,7 @@ impl<'a> chain::Watch<TestChannelSigner> for TestChainMonitor<'a> {
// monitor to a serialized copy and get he same one back.
let mut w = TestVecWriter(Vec::new());
monitor.write(&mut w).unwrap();
- let new_monitor = <(BlockHash, ChannelMonitor<TestChannelSigner>)>::read(
+ let new_monitor = <(BestBlock, ChannelMonitor<TestChannelSigner>)>::read(
&mut io::Cursor::new(&w.0),
(self.keys_manager, self.keys_manager),
)
@@ -698,7 +699,7 @@ impl<'a> chain::Watch<TestChannelSigner> for TestChainMonitor<'a> {
let monitor = self.chain_monitor.get_monitor(channel_id).unwrap();
w.0.clear();
monitor.write(&mut w).unwrap();
- let new_monitor = <(BlockHash, ChannelMonitor<TestChannelSigner>)>::read(
+ let new_monitor = <(BestBlock, ChannelMonitor<TestChannelSigner>)>::read(
&mut io::Cursor::new(&w.0),
(self.keys_manager, self.keys_manager),
)
Why this scored 29/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.