chore(esplora): Clarify consistency guarantees
This commit is contained in:
parent
63fa710319
commit
216648bcfd
@ -26,6 +26,12 @@ pub trait EsploraAsyncExt {
|
|||||||
///
|
///
|
||||||
/// The result of this method can be applied to [`LocalChain::apply_update`].
|
/// The result of this method can be applied to [`LocalChain::apply_update`].
|
||||||
///
|
///
|
||||||
|
/// ## Consistency
|
||||||
|
///
|
||||||
|
/// The chain update returned is guaranteed to be consistent as long as there is not a *large* re-org
|
||||||
|
/// during the call. The size of re-org we can tollerate is server dependent but will be at
|
||||||
|
/// least 10.
|
||||||
|
///
|
||||||
/// [`LocalChain`]: bdk_chain::local_chain::LocalChain
|
/// [`LocalChain`]: bdk_chain::local_chain::LocalChain
|
||||||
/// [`LocalChain::tip`]: bdk_chain::local_chain::LocalChain::tip
|
/// [`LocalChain::tip`]: bdk_chain::local_chain::LocalChain::tip
|
||||||
/// [`LocalChain::apply_update`]: bdk_chain::local_chain::LocalChain::apply_update
|
/// [`LocalChain::apply_update`]: bdk_chain::local_chain::LocalChain::apply_update
|
||||||
@ -85,9 +91,8 @@ impl EsploraAsyncExt for esplora_client::AsyncClient {
|
|||||||
local_tip: CheckPoint,
|
local_tip: CheckPoint,
|
||||||
request_heights: impl IntoIterator<IntoIter = impl Iterator<Item = u32> + Send> + Send,
|
request_heights: impl IntoIterator<IntoIter = impl Iterator<Item = u32> + Send> + Send,
|
||||||
) -> Result<local_chain::Update, Error> {
|
) -> Result<local_chain::Update, Error> {
|
||||||
// Atomically fetch latest blocks from Esplora. This way, we avoid creating an update with
|
// Fetch latest N (server dependent) blocks from Esplora. The server guarantees these are
|
||||||
// an inconsistent set of blocks (assuming that a reorg depth cannot be greater than the
|
// consistent.
|
||||||
// latest blocks fetched).
|
|
||||||
let mut fetched_blocks = self
|
let mut fetched_blocks = self
|
||||||
.get_blocks(None)
|
.get_blocks(None)
|
||||||
.await?
|
.await?
|
||||||
@ -109,6 +114,10 @@ impl EsploraAsyncExt for esplora_client::AsyncClient {
|
|||||||
}
|
}
|
||||||
// only fetch what is missing
|
// only fetch what is missing
|
||||||
if let btree_map::Entry::Vacant(entry) = fetched_blocks.entry(height) {
|
if let btree_map::Entry::Vacant(entry) = fetched_blocks.entry(height) {
|
||||||
|
// ❗The return value of `get_block_hash` is not strictly guaranteed to be consistent
|
||||||
|
// with the chain at the time of `get_blocks` above (there could have been a deep
|
||||||
|
// re-org). Since `get_blocks` returns 10 (or so) blocks we are assuming that it's
|
||||||
|
// not possible to have a re-org deeper than that.
|
||||||
entry.insert(self.get_block_hash(height).await?);
|
entry.insert(self.get_block_hash(height).await?);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,12 @@ pub trait EsploraExt {
|
|||||||
///
|
///
|
||||||
/// The result of this method can be applied to [`LocalChain::apply_update`].
|
/// The result of this method can be applied to [`LocalChain::apply_update`].
|
||||||
///
|
///
|
||||||
|
/// ## Consistency
|
||||||
|
///
|
||||||
|
/// The chain update returned is guaranteed to be consistent as long as there is not a *large* re-org
|
||||||
|
/// during the call. The size of re-org we can tollerate is server dependent but will be at
|
||||||
|
/// least 10.
|
||||||
|
///
|
||||||
/// [`LocalChain`]: bdk_chain::local_chain::LocalChain
|
/// [`LocalChain`]: bdk_chain::local_chain::LocalChain
|
||||||
/// [`LocalChain::tip`]: bdk_chain::local_chain::LocalChain::tip
|
/// [`LocalChain::tip`]: bdk_chain::local_chain::LocalChain::tip
|
||||||
/// [`LocalChain::apply_update`]: bdk_chain::local_chain::LocalChain::apply_update
|
/// [`LocalChain::apply_update`]: bdk_chain::local_chain::LocalChain::apply_update
|
||||||
@ -78,9 +84,8 @@ impl EsploraExt for esplora_client::BlockingClient {
|
|||||||
local_tip: CheckPoint,
|
local_tip: CheckPoint,
|
||||||
request_heights: impl IntoIterator<Item = u32>,
|
request_heights: impl IntoIterator<Item = u32>,
|
||||||
) -> Result<local_chain::Update, Error> {
|
) -> Result<local_chain::Update, Error> {
|
||||||
// Atomically fetch latest blocks from Esplora. This way, we avoid creating an update with
|
// Fetch latest N (server dependent) blocks from Esplora. The server guarantees these are
|
||||||
// an inconsistent set of blocks (assuming that a reorg depth cannot be greater than the
|
// consistent.
|
||||||
// latest blocks fetched).
|
|
||||||
let mut fetched_blocks = self
|
let mut fetched_blocks = self
|
||||||
.get_blocks(None)?
|
.get_blocks(None)?
|
||||||
.into_iter()
|
.into_iter()
|
||||||
@ -101,6 +106,10 @@ impl EsploraExt for esplora_client::BlockingClient {
|
|||||||
}
|
}
|
||||||
// only fetch what is missing
|
// only fetch what is missing
|
||||||
if let btree_map::Entry::Vacant(entry) = fetched_blocks.entry(height) {
|
if let btree_map::Entry::Vacant(entry) = fetched_blocks.entry(height) {
|
||||||
|
// ❗The return value of `get_block_hash` is not strictly guaranteed to be consistent
|
||||||
|
// with the chain at the time of `get_blocks` above (there could have been a deep
|
||||||
|
// re-org). Since `get_blocks` returns 10 (or so) blocks we are assuming that it's
|
||||||
|
// not possible to have a re-org deeper than that.
|
||||||
entry.insert(self.get_block_hash(height)?);
|
entry.insert(self.get_block_hash(height)?);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user