|
60 | 60 | #define MICRO 0.000001
|
61 | 61 | #define MILLI 0.001
|
62 | 62 |
|
63 |
| -/** |
64 |
| - * Global state |
65 |
| - */ |
66 |
| -namespace { |
67 |
| - struct CBlockIndexWorkComparator |
68 |
| - { |
69 |
| - bool operator()(const CBlockIndex *pa, const CBlockIndex *pb) const { |
70 |
| - // First sort by most total work, ... |
71 |
| - if (pa->nChainWork > pb->nChainWork) return false; |
72 |
| - if (pa->nChainWork < pb->nChainWork) return true; |
73 |
| - |
74 |
| - // ... then by earliest time received, ... |
75 |
| - if (pa->nSequenceId < pb->nSequenceId) return false; |
76 |
| - if (pa->nSequenceId > pb->nSequenceId) return true; |
77 |
| - |
78 |
| - // Use pointer address as tie breaker (should only happen with blocks |
79 |
| - // loaded from disk, as those all have id 0). |
80 |
| - if (pa < pb) return false; |
81 |
| - if (pa > pb) return true; |
82 |
| - |
83 |
| - // Identical blocks. |
84 |
| - return false; |
85 |
| - } |
86 |
| - }; |
87 |
| -} // anon namespace |
88 |
| - |
89 |
| -enum DisconnectResult |
90 |
| -{ |
91 |
| - DISCONNECT_OK, // All good. |
92 |
| - DISCONNECT_UNCLEAN, // Rolled back, but UTXO set was inconsistent with block. |
93 |
| - DISCONNECT_FAILED // Something else went wrong. |
94 |
| -}; |
95 |
| - |
96 |
| -class ConnectTrace; |
97 |
| - |
98 |
| -/** |
99 |
| - * CChainState stores and provides an API to update our local knowledge of the |
100 |
| - * current best chain and header tree. |
101 |
| - * |
102 |
| - * It generally provides access to the current block tree, as well as functions |
103 |
| - * to provide new data, which it will appropriately validate and incorporate in |
104 |
| - * its state as necessary. |
105 |
| - * |
106 |
| - * Eventually, the API here is targeted at being exposed externally as a |
107 |
| - * consumable libconsensus library, so any functions added must only call |
108 |
| - * other class member functions, pure functions in other parts of the consensus |
109 |
| - * library, callbacks via the validation interface, or read/write-to-disk |
110 |
| - * functions (eventually this will also be via callbacks). |
111 |
| - */ |
112 |
| -class CChainState { |
113 |
| -private: |
114 |
| - /** |
115 |
| - * The set of all CBlockIndex entries with BLOCK_VALID_TRANSACTIONS (for itself and all ancestors) and |
116 |
| - * as good as our current tip or better. Entries may be failed, though, and pruning nodes may be |
117 |
| - * missing the data for the block. |
118 |
| - */ |
119 |
| - std::set<CBlockIndex*, CBlockIndexWorkComparator> setBlockIndexCandidates; |
120 |
| - |
121 |
| - /** |
122 |
| - * Every received block is assigned a unique and increasing identifier, so we |
123 |
| - * know which one to give priority in case of a fork. |
124 |
| - */ |
125 |
| - CCriticalSection cs_nBlockSequenceId; |
126 |
| - /** Blocks loaded from disk are assigned id 0, so start the counter at 1. */ |
127 |
| - int32_t nBlockSequenceId = 1; |
128 |
| - /** Decreasing counter (used by subsequent preciousblock calls). */ |
129 |
| - int32_t nBlockReverseSequenceId = -1; |
130 |
| - /** chainwork for the last block that preciousblock has been applied to. */ |
131 |
| - arith_uint256 nLastPreciousChainwork = 0; |
132 |
| - |
133 |
| - /** In order to efficiently track invalidity of headers, we keep the set of |
134 |
| - * blocks which we tried to connect and found to be invalid here (ie which |
135 |
| - * were set to BLOCK_FAILED_VALID since the last restart). We can then |
136 |
| - * walk this set and check if a new header is a descendant of something in |
137 |
| - * this set, preventing us from having to walk mapBlockIndex when we try |
138 |
| - * to connect a bad block and fail. |
139 |
| - * |
140 |
| - * While this is more complicated than marking everything which descends |
141 |
| - * from an invalid block as invalid at the time we discover it to be |
142 |
| - * invalid, doing so would require walking all of mapBlockIndex to find all |
143 |
| - * descendants. Since this case should be very rare, keeping track of all |
144 |
| - * BLOCK_FAILED_VALID blocks in a set should be just fine and work just as |
145 |
| - * well. |
146 |
| - * |
147 |
| - * Because we already walk mapBlockIndex in height-order at startup, we go |
148 |
| - * ahead and mark descendants of invalid blocks as FAILED_CHILD at that time, |
149 |
| - * instead of putting things in this set. |
150 |
| - */ |
151 |
| - std::set<CBlockIndex*> m_failed_blocks; |
152 |
| - |
153 |
| - /** |
154 |
| - * the ChainState CriticalSection |
155 |
| - * A lock that must be held when modifying this ChainState - held in ActivateBestChain() |
156 |
| - */ |
157 |
| - CCriticalSection m_cs_chainstate; |
158 |
| - |
159 |
| -public: |
160 |
| - //! The current chain of blockheaders we consult and build on. |
161 |
| - //! @see CChain, CBlockIndex. |
162 |
| - CChain m_chain; |
163 |
| - BlockMap mapBlockIndex GUARDED_BY(cs_main); |
164 |
| - std::multimap<CBlockIndex*, CBlockIndex*> mapBlocksUnlinked; |
165 |
| - CBlockIndex *pindexBestInvalid = nullptr; |
166 |
| - |
167 |
| - bool LoadBlockIndex(const Consensus::Params& consensus_params, CBlockTreeDB& blocktree) EXCLUSIVE_LOCKS_REQUIRED(cs_main); |
168 |
| - |
169 |
| - bool ActivateBestChain(CValidationState &state, const CChainParams& chainparams, std::shared_ptr<const CBlock> pblock) LOCKS_EXCLUDED(cs_main); |
170 |
| - |
171 |
| - /** |
172 |
| - * If a block header hasn't already been seen, call CheckBlockHeader on it, ensure |
173 |
| - * that it doesn't descend from an invalid block, and then add it to mapBlockIndex. |
174 |
| - */ |
175 |
| - bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state, const CChainParams& chainparams, CBlockIndex** ppindex) EXCLUSIVE_LOCKS_REQUIRED(cs_main); |
176 |
| - bool AcceptBlock(const std::shared_ptr<const CBlock>& pblock, CValidationState& state, const CChainParams& chainparams, CBlockIndex** ppindex, bool fRequested, const FlatFilePos* dbp, bool* fNewBlock) EXCLUSIVE_LOCKS_REQUIRED(cs_main); |
| 63 | +bool CBlockIndexWorkComparator::operator()(const CBlockIndex *pa, const CBlockIndex *pb) const { |
| 64 | + // First sort by most total work, ... |
| 65 | + if (pa->nChainWork > pb->nChainWork) return false; |
| 66 | + if (pa->nChainWork < pb->nChainWork) return true; |
177 | 67 |
|
178 |
| - // Block (dis)connection on a given view: |
179 |
| - DisconnectResult DisconnectBlock(const CBlock& block, const CBlockIndex* pindex, CCoinsViewCache& view); |
180 |
| - bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pindex, |
181 |
| - CCoinsViewCache& view, const CChainParams& chainparams, bool fJustCheck = false) EXCLUSIVE_LOCKS_REQUIRED(cs_main); |
| 68 | + // ... then by earliest time received, ... |
| 69 | + if (pa->nSequenceId < pb->nSequenceId) return false; |
| 70 | + if (pa->nSequenceId > pb->nSequenceId) return true; |
182 | 71 |
|
183 |
| - // Block disconnection on our pcoinsTip: |
184 |
| - bool DisconnectTip(CValidationState& state, const CChainParams& chainparams, DisconnectedBlockTransactions* disconnectpool) EXCLUSIVE_LOCKS_REQUIRED(cs_main); |
| 72 | + // Use pointer address as tie breaker (should only happen with blocks |
| 73 | + // loaded from disk, as those all have id 0). |
| 74 | + if (pa < pb) return false; |
| 75 | + if (pa > pb) return true; |
185 | 76 |
|
186 |
| - // Manual block validity manipulation: |
187 |
| - bool PreciousBlock(CValidationState& state, const CChainParams& params, CBlockIndex* pindex) LOCKS_EXCLUDED(cs_main); |
188 |
| - bool InvalidateBlock(CValidationState& state, const CChainParams& chainparams, CBlockIndex* pindex) LOCKS_EXCLUDED(cs_main); |
189 |
| - void ResetBlockFailureFlags(CBlockIndex* pindex) EXCLUSIVE_LOCKS_REQUIRED(cs_main); |
190 |
| - |
191 |
| - bool ReplayBlocks(const CChainParams& params, CCoinsView* view); |
192 |
| - bool RewindBlockIndex(const CChainParams& params) LOCKS_EXCLUDED(cs_main); |
193 |
| - bool LoadGenesisBlock(const CChainParams& chainparams); |
194 |
| - |
195 |
| - void PruneBlockIndexCandidates(); |
196 |
| - |
197 |
| - void UnloadBlockIndex(); |
198 |
| - |
199 |
| -private: |
200 |
| - bool ActivateBestChainStep(CValidationState& state, const CChainParams& chainparams, CBlockIndex* pindexMostWork, const std::shared_ptr<const CBlock>& pblock, bool& fInvalidFound, ConnectTrace& connectTrace) EXCLUSIVE_LOCKS_REQUIRED(cs_main); |
201 |
| - bool ConnectTip(CValidationState& state, const CChainParams& chainparams, CBlockIndex* pindexNew, const std::shared_ptr<const CBlock>& pblock, ConnectTrace& connectTrace, DisconnectedBlockTransactions &disconnectpool) EXCLUSIVE_LOCKS_REQUIRED(cs_main); |
202 |
| - |
203 |
| - CBlockIndex* AddToBlockIndex(const CBlockHeader& block) EXCLUSIVE_LOCKS_REQUIRED(cs_main); |
204 |
| - /** Create a new block index entry for a given block hash */ |
205 |
| - CBlockIndex* InsertBlockIndex(const uint256& hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main); |
206 |
| - /** |
207 |
| - * Make various assertions about the state of the block index. |
208 |
| - * |
209 |
| - * By default this only executes fully when using the Regtest chain; see: fCheckBlockIndex. |
210 |
| - */ |
211 |
| - void CheckBlockIndex(const Consensus::Params& consensusParams); |
212 |
| - |
213 |
| - void InvalidBlockFound(CBlockIndex *pindex, const CValidationState &state) EXCLUSIVE_LOCKS_REQUIRED(cs_main); |
214 |
| - CBlockIndex* FindMostWorkChain() EXCLUSIVE_LOCKS_REQUIRED(cs_main); |
215 |
| - void ReceivedBlockTransactions(const CBlock& block, CBlockIndex* pindexNew, const FlatFilePos& pos, const Consensus::Params& consensusParams) EXCLUSIVE_LOCKS_REQUIRED(cs_main); |
216 |
| - |
217 |
| - bool RollforwardBlock(const CBlockIndex* pindex, CCoinsViewCache& inputs, const CChainParams& params) EXCLUSIVE_LOCKS_REQUIRED(cs_main); |
| 77 | + // Identical blocks. |
| 78 | + return false; |
| 79 | +} |
218 | 80 |
|
219 |
| - //! Mark a block as not having block data |
220 |
| - void EraseBlockData(CBlockIndex* index) EXCLUSIVE_LOCKS_REQUIRED(cs_main); |
221 |
| -} g_chainstate; |
| 81 | +CChainState g_chainstate; |
222 | 82 |
|
223 | 83 | CChain& ChainActive() { return g_chainstate.m_chain; }
|
224 | 84 |
|
|
0 commit comments