mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-01-10 03:47:29 -03:00
validation: add CChainState::m_disabled and ChainMan::isUsable
and remove m_snapshot_validated. This state can now be inferred by the number of isUsable chainstates. m_disabled is used to signal that a chainstate should no longer be used by validation logic; it is used as a sentinel when background validation completes or if the snapshot chainstate is found to be invalid. isUsable is a convenience method that incorporates m_disabled.
This commit is contained in:
parent
5ee22cdafd
commit
c29f26b47b
3 changed files with 39 additions and 17 deletions
|
@ -107,7 +107,7 @@ sequentially.
|
||||||
### Background chainstate hits snapshot base block
|
### Background chainstate hits snapshot base block
|
||||||
|
|
||||||
Once the tip of the background chainstate hits the base block of the snapshot
|
Once the tip of the background chainstate hits the base block of the snapshot
|
||||||
chainstate, we stop use of the background chainstate by setting `m_stop_use` (not yet
|
chainstate, we stop use of the background chainstate by setting `m_disabled` (not yet
|
||||||
committed - see #15606), in `CompleteSnapshotValidation()`, which is checked in
|
committed - see #15606), in `CompleteSnapshotValidation()`, which is checked in
|
||||||
`ActivateBestChain()`). We hash the background chainstate's UTXO set contents and
|
`ActivateBestChain()`). We hash the background chainstate's UTXO set contents and
|
||||||
ensure it matches the compiled value in `CMainParams::m_assumeutxo_data`.
|
ensure it matches the compiled value in `CMainParams::m_assumeutxo_data`.
|
||||||
|
@ -119,10 +119,10 @@ The background chainstate data lingers on disk until shutdown, when in
|
||||||
|
|
||||||
| | |
|
| | |
|
||||||
| ---------- | ----------- |
|
| ---------- | ----------- |
|
||||||
| number of chainstates | 2 (ibd has `m_stop_use=true`) |
|
| number of chainstates | 2 (ibd has `m_disabled=true`) |
|
||||||
| active chainstate | snapshot |
|
| active chainstate | snapshot |
|
||||||
|
|
||||||
**Failure consideration:** if bitcoind unexpectedly halts after `m_stop_use` is set on
|
**Failure consideration:** if bitcoind unexpectedly halts after `m_disabled` is set on
|
||||||
the background chainstate but before `CompleteSnapshotValidation()` can finish, the
|
the background chainstate but before `CompleteSnapshotValidation()` can finish, the
|
||||||
need to complete snapshot validation will be detected on subsequent init by
|
need to complete snapshot validation will be detected on subsequent init by
|
||||||
`ChainstateManager::CheckForUncleanShutdown()`.
|
`ChainstateManager::CheckForUncleanShutdown()`.
|
||||||
|
|
|
@ -4859,12 +4859,8 @@ std::vector<Chainstate*> ChainstateManager::GetAll()
|
||||||
LOCK(::cs_main);
|
LOCK(::cs_main);
|
||||||
std::vector<Chainstate*> out;
|
std::vector<Chainstate*> out;
|
||||||
|
|
||||||
if (!IsSnapshotValidated() && m_ibd_chainstate) {
|
for (Chainstate* cs : {m_ibd_chainstate.get(), m_snapshot_chainstate.get()}) {
|
||||||
out.push_back(m_ibd_chainstate.get());
|
if (this->IsUsable(cs)) out.push_back(cs);
|
||||||
}
|
|
||||||
|
|
||||||
if (m_snapshot_chainstate) {
|
|
||||||
out.push_back(m_snapshot_chainstate.get());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
|
@ -5263,17 +5259,22 @@ bool ChainstateManager::IsSnapshotActive() const
|
||||||
void ChainstateManager::MaybeRebalanceCaches()
|
void ChainstateManager::MaybeRebalanceCaches()
|
||||||
{
|
{
|
||||||
AssertLockHeld(::cs_main);
|
AssertLockHeld(::cs_main);
|
||||||
if (m_ibd_chainstate && !m_snapshot_chainstate) {
|
bool ibd_usable = this->IsUsable(m_ibd_chainstate.get());
|
||||||
|
bool snapshot_usable = this->IsUsable(m_snapshot_chainstate.get());
|
||||||
|
assert(ibd_usable || snapshot_usable);
|
||||||
|
|
||||||
|
if (ibd_usable && !snapshot_usable) {
|
||||||
LogPrintf("[snapshot] allocating all cache to the IBD chainstate\n");
|
LogPrintf("[snapshot] allocating all cache to the IBD chainstate\n");
|
||||||
// Allocate everything to the IBD chainstate.
|
// Allocate everything to the IBD chainstate.
|
||||||
m_ibd_chainstate->ResizeCoinsCaches(m_total_coinstip_cache, m_total_coinsdb_cache);
|
m_ibd_chainstate->ResizeCoinsCaches(m_total_coinstip_cache, m_total_coinsdb_cache);
|
||||||
}
|
}
|
||||||
else if (m_snapshot_chainstate && !m_ibd_chainstate) {
|
else if (snapshot_usable && !ibd_usable) {
|
||||||
|
// If background validation has completed and snapshot is our active chain...
|
||||||
LogPrintf("[snapshot] allocating all cache to the snapshot chainstate\n");
|
LogPrintf("[snapshot] allocating all cache to the snapshot chainstate\n");
|
||||||
// Allocate everything to the snapshot chainstate.
|
// Allocate everything to the snapshot chainstate.
|
||||||
m_snapshot_chainstate->ResizeCoinsCaches(m_total_coinstip_cache, m_total_coinsdb_cache);
|
m_snapshot_chainstate->ResizeCoinsCaches(m_total_coinstip_cache, m_total_coinsdb_cache);
|
||||||
}
|
}
|
||||||
else if (m_ibd_chainstate && m_snapshot_chainstate) {
|
else if (ibd_usable && snapshot_usable) {
|
||||||
// If both chainstates exist, determine who needs more cache based on IBD status.
|
// If both chainstates exist, determine who needs more cache based on IBD status.
|
||||||
//
|
//
|
||||||
// Note: shrink caches first so that we don't inadvertently overwhelm available memory.
|
// Note: shrink caches first so that we don't inadvertently overwhelm available memory.
|
||||||
|
|
|
@ -473,6 +473,19 @@ protected:
|
||||||
//! Manages the UTXO set, which is a reflection of the contents of `m_chain`.
|
//! Manages the UTXO set, which is a reflection of the contents of `m_chain`.
|
||||||
std::unique_ptr<CoinsViews> m_coins_views;
|
std::unique_ptr<CoinsViews> m_coins_views;
|
||||||
|
|
||||||
|
//! This toggle exists for use when doing background validation for UTXO
|
||||||
|
//! snapshots.
|
||||||
|
//!
|
||||||
|
//! In the expected case, it is set once the background validation chain reaches the
|
||||||
|
//! same height as the base of the snapshot and its UTXO set is found to hash to
|
||||||
|
//! the expected assumeutxo value. It signals that we should no longer connect
|
||||||
|
//! blocks to the background chainstate. When set on the background validation
|
||||||
|
//! chainstate, it signifies that we have fully validated the snapshot chainstate.
|
||||||
|
//!
|
||||||
|
//! In the unlikely case that the snapshot chainstate is found to be invalid, this
|
||||||
|
//! is set to true on the snapshot chainstate.
|
||||||
|
bool m_disabled GUARDED_BY(::cs_main) {false};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//! Reference to a BlockManager instance which itself is shared across all
|
//! Reference to a BlockManager instance which itself is shared across all
|
||||||
//! Chainstate instances.
|
//! Chainstate instances.
|
||||||
|
@ -840,10 +853,6 @@ private:
|
||||||
//! that call.
|
//! that call.
|
||||||
Chainstate* m_active_chainstate GUARDED_BY(::cs_main) {nullptr};
|
Chainstate* m_active_chainstate GUARDED_BY(::cs_main) {nullptr};
|
||||||
|
|
||||||
//! If true, the assumed-valid chainstate has been fully validated
|
|
||||||
//! by the background validation chainstate.
|
|
||||||
bool m_snapshot_validated GUARDED_BY(::cs_main){false};
|
|
||||||
|
|
||||||
CBlockIndex* m_best_invalid GUARDED_BY(::cs_main){nullptr};
|
CBlockIndex* m_best_invalid GUARDED_BY(::cs_main){nullptr};
|
||||||
|
|
||||||
//! Internal helper for ActivateSnapshot().
|
//! Internal helper for ActivateSnapshot().
|
||||||
|
@ -876,6 +885,15 @@ private:
|
||||||
//! nullopt.
|
//! nullopt.
|
||||||
std::optional<int> GetSnapshotBaseHeight() const EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
|
std::optional<int> GetSnapshotBaseHeight() const EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
|
||||||
|
|
||||||
|
//! Return true if a chainstate is considered usable.
|
||||||
|
//!
|
||||||
|
//! This is false when a background validation chainstate has completed its
|
||||||
|
//! validation of an assumed-valid chainstate, or when a snapshot
|
||||||
|
//! chainstate has been found to be invalid.
|
||||||
|
bool IsUsable(const Chainstate* const cs) const EXCLUSIVE_LOCKS_REQUIRED(::cs_main) {
|
||||||
|
return cs && !cs->m_disabled;
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using Options = kernel::ChainstateManagerOpts;
|
using Options = kernel::ChainstateManagerOpts;
|
||||||
|
|
||||||
|
@ -987,7 +1005,10 @@ public:
|
||||||
std::optional<uint256> SnapshotBlockhash() const;
|
std::optional<uint256> SnapshotBlockhash() const;
|
||||||
|
|
||||||
//! Is there a snapshot in use and has it been fully validated?
|
//! Is there a snapshot in use and has it been fully validated?
|
||||||
bool IsSnapshotValidated() const EXCLUSIVE_LOCKS_REQUIRED(::cs_main) { return m_snapshot_validated; }
|
bool IsSnapshotValidated() const EXCLUSIVE_LOCKS_REQUIRED(::cs_main)
|
||||||
|
{
|
||||||
|
return m_snapshot_chainstate && m_ibd_chainstate && m_ibd_chainstate->m_disabled;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process an incoming block. This only returns after the best known valid
|
* Process an incoming block. This only returns after the best known valid
|
||||||
|
|
Loading…
Reference in a new issue