14
14
#include < coins.h>
15
15
#include < crypto/common.h> // for ReadLE64
16
16
#include < fs.h>
17
+ #include < optional.h>
17
18
#include < policy/feerate.h>
18
19
#include < protocol.h> // For CMessageHeader::MessageStartChars
19
20
#include < script/script_error.h>
@@ -539,6 +540,9 @@ enum class CoinsCacheSizeState
539
540
OK = 0
540
541
};
541
542
543
+ // Defined below, but needed for `friend` usage in CChainState.
544
+ class ChainstateManager ;
545
+
542
546
/* *
543
547
* CChainState stores and provides an API to update our local knowledge of the
544
548
* current best chain.
@@ -748,6 +752,8 @@ class CChainState {
748
752
size_t max_coins_cache_size_bytes,
749
753
size_t max_mempool_size_bytes) EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
750
754
755
+ std::string ToString () EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
756
+
751
757
private:
752
758
bool ActivateBestChainStep (BlockValidationState& state, const CChainParams& chainparams, CBlockIndex* pindexMostWork, const std::shared_ptr<const CBlock>& pblock, bool & fInvalidFound , ConnectTrace& connectTrace) EXCLUSIVE_LOCKS_REQUIRED(cs_main, ::mempool.cs);
753
759
bool ConnectTip (BlockValidationState& state, const CChainParams& chainparams, CBlockIndex* pindexNew, const std::shared_ptr<const CBlock>& pblock, ConnectTrace& connectTrace, DisconnectedBlockTransactions& disconnectpool) EXCLUSIVE_LOCKS_REQUIRED(cs_main, ::mempool.cs);
@@ -760,6 +766,8 @@ class CChainState {
760
766
761
767
// ! Mark a block as not having block data
762
768
void EraseBlockData (CBlockIndex* index) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
769
+
770
+ friend ChainstateManager;
763
771
};
764
772
765
773
/* * Mark a block as precious and reorganize.
@@ -775,6 +783,111 @@ bool InvalidateBlock(BlockValidationState& state, const CChainParams& chainparam
775
783
/* * Remove invalidity status from a block and its descendants. */
776
784
void ResetBlockFailureFlags (CBlockIndex* pindex) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
777
785
786
+ /* *
787
+ * Provides an interface for creating and interacting with one or two
788
+ * chainstates: an IBD chainstate generated by downloading blocks, and
789
+ * an optional snapshot chainstate loaded from a UTXO snapshot. Managed
790
+ * chainstates can be maintained at different heights simultaneously.
791
+ *
792
+ * This class provides abstractions that allow the retrieval of the current
793
+ * most-work chainstate ("Active") as well as chainstates which may be in
794
+ * background use to validate UTXO snapshots.
795
+ *
796
+ * Definitions:
797
+ *
798
+ * *IBD chainstate*: a chainstate whose current state has been "fully"
799
+ * validated by the initial block download process.
800
+ *
801
+ * *Snapshot chainstate*: a chainstate populated by loading in an
802
+ * assumeutxo UTXO snapshot.
803
+ *
804
+ * *Active chainstate*: the chainstate containing the current most-work
805
+ * chain. Consulted by most parts of the system (net_processing,
806
+ * wallet) as a reflection of the current chain and UTXO set.
807
+ * This may either be an IBD chainstate or a snapshot chainstate.
808
+ *
809
+ * *Background IBD chainstate*: an IBD chainstate for which the
810
+ * IBD process is happening in the background while use of the
811
+ * active (snapshot) chainstate allows the rest of the system to function.
812
+ *
813
+ * *Validated chainstate*: the most-work chainstate which has been validated
814
+ * locally via initial block download. This will be the snapshot chainstate
815
+ * if a snapshot was loaded and all blocks up to the snapshot starting point
816
+ * have been downloaded and validated (via background validation), otherwise
817
+ * it will be the IBD chainstate.
818
+ */
819
+ class ChainstateManager
820
+ {
821
+ private:
822
+ // ! The chainstate used under normal operation (i.e. "regular" IBD) or, if
823
+ // ! a snapshot is in use, for background validation.
824
+ // !
825
+ // ! Its contents (including on-disk data) will be deleted *upon shutdown*
826
+ // ! after background validation of the snapshot has completed. We do not
827
+ // ! free the chainstate contents immediately after it finishes validation
828
+ // ! to cautiously avoid a case where some other part of the system is still
829
+ // ! using this pointer (e.g. net_processing).
830
+ std::unique_ptr<CChainState> m_ibd_chainstate;
831
+
832
+ // ! A chainstate initialized on the basis of a UTXO snapshot. If this is
833
+ // ! non-null, it is always our active chainstate.
834
+ std::unique_ptr<CChainState> m_snapshot_chainstate;
835
+
836
+ // ! Points to either the ibd or snapshot chainstate; indicates our
837
+ // ! most-work chain.
838
+ CChainState* m_active_chainstate{nullptr };
839
+
840
+ // ! If true, the assumed-valid chainstate has been fully validated
841
+ // ! by the background validation chainstate.
842
+ bool m_snapshot_validated{false };
843
+
844
+ // For access to m_active_chainstate.
845
+ friend CChain& ChainActive ();
846
+
847
+ public:
848
+ // ! Instantiate a new chainstate and assign it based upon whether it is
849
+ // ! from a snapshot.
850
+ // !
851
+ // ! @param[in] snapshot_blockhash If given, signify that this chainstate
852
+ // ! is based on a snapshot.
853
+ CChainState& InitializeChainstate (const uint256& snapshot_blockhash = uint256())
854
+ EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
855
+
856
+ // ! Get all chainstates currently being used.
857
+ std::vector<CChainState*> GetAll ();
858
+
859
+ // ! The most-work chain.
860
+ CChain& ActiveChain () const ;
861
+ int ActiveHeight () const { return ActiveChain ().Height (); }
862
+ CBlockIndex* ActiveTip () const { return ActiveChain ().Tip (); }
863
+
864
+ bool IsSnapshotActive () const ;
865
+
866
+ Optional<uint256> SnapshotBlockhash () const ;
867
+
868
+ // ! Is there a snapshot in use and has it been fully validated?
869
+ bool IsSnapshotValidated () const { return m_snapshot_validated; }
870
+
871
+ // ! @returns true if this chainstate is being used to validate an active
872
+ // ! snapshot in the background.
873
+ bool IsBackgroundIBD (CChainState* chainstate) const ;
874
+
875
+ // ! Return the most-work chainstate that has been fully validated.
876
+ // !
877
+ // ! During background validation of a snapshot, this is the IBD chain. After
878
+ // ! background validation has completed, this is the snapshot chain.
879
+ CChainState& ValidatedChainstate () const ;
880
+
881
+ CChain& ValidatedChain () const { return ValidatedChainstate ().m_chain ; }
882
+ CBlockIndex* ValidatedTip () const { return ValidatedChain ().Tip (); }
883
+
884
+ // ! Unload block index and chain data before shutdown.
885
+ void Unload () EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
886
+
887
+ // ! Clear (deconstruct) chainstate data.
888
+ void Reset ();
889
+ };
890
+
778
891
/* * @returns the most-work valid chainstate. */
779
892
CChainState& ChainstateActive ();
780
893
0 commit comments