]>
Commit | Line | Data |
---|---|---|
0a61b0df | 1 | // Copyright (c) 2009-2010 Satoshi Nakamoto |
f914f1a7 | 2 | // Copyright (c) 2009-2014 The Bitcoin Core developers |
c5b390b6 | 3 | // Distributed under the MIT software license, see the accompanying |
3a25a2b9 | 4 | // file COPYING or http://www.opensource.org/licenses/mit-license.php. |
51ed9ec9 | 5 | |
223b6f1b WL |
6 | #ifndef BITCOIN_MAIN_H |
7 | #define BITCOIN_MAIN_H | |
8 | ||
35b8af92 | 9 | #if defined(HAVE_CONFIG_H) |
f3967bcc | 10 | #include "config/bitcoin-config.h" |
35b8af92 CF |
11 | #endif |
12 | ||
eda37330 | 13 | #include "amount.h" |
e8b5f0d5 | 14 | #include "chain.h" |
51ed9ec9 | 15 | #include "chainparams.h" |
a0fa20a1 | 16 | #include "coins.h" |
691161d4 | 17 | #include "consensus/consensus.h" |
072099d7 | 18 | #include "consensus/upgrades.h" |
691161d4 | 19 | #include "net.h" |
d2270111 LD |
20 | #include "primitives/block.h" |
21 | #include "primitives/transaction.h" | |
c4408a6c | 22 | #include "script/script.h" |
2c8d8268 | 23 | #include "script/serverchecker.h" |
c4408a6c | 24 | #include "script/standard.h" |
8b78a819 | 25 | #include "spentindex.h" |
51ed9ec9 | 26 | #include "sync.h" |
85c579e3 | 27 | #include "tinyformat.h" |
51ed9ec9 BD |
28 | #include "txmempool.h" |
29 | #include "uint256.h" | |
223b6f1b | 30 | |
51ed9ec9 BD |
31 | #include <algorithm> |
32 | #include <exception> | |
33 | #include <map> | |
34 | #include <set> | |
35 | #include <stdint.h> | |
36 | #include <string> | |
37 | #include <utility> | |
38 | #include <vector> | |
0a61b0df | 39 | |
8a41e1ed PW |
40 | #include <boost/unordered_map.hpp> |
41 | ||
0a61b0df | 42 | class CBlockIndex; |
771d5002 | 43 | class CBlockTreeDB; |
51ed9ec9 | 44 | class CBloomFilter; |
40c2614e | 45 | class CInv; |
771d5002 PK |
46 | class CScriptCheck; |
47 | class CValidationInterface; | |
48 | class CValidationState; | |
6514771a | 49 | class PrecomputedTransactionData; |
771d5002 | 50 | |
771d5002 | 51 | struct CNodeStateStats; |
14aa6cc0 | 52 | #define DEFAULT_MEMPOOL_EXPIRY 1 |
96ac2045 | 53 | #define _COINBASE_MATURITY 100 |
40c2614e | 54 | |
037b4f14 | 55 | /** Default for -blockmaxsize and -blockminsize, which control the range of sizes the mining code will create **/ |
e2a6161f | 56 | static const unsigned int DEFAULT_BLOCK_MAX_SIZE = MAX_BLOCK_SIZE; |
037b4f14 | 57 | static const unsigned int DEFAULT_BLOCK_MIN_SIZE = 0; |
ad898b40 | 58 | /** Default for -blockprioritysize, maximum space for zero/low-fee transactions **/ |
e2a6161f | 59 | static const unsigned int DEFAULT_BLOCK_PRIORITY_SIZE = DEFAULT_BLOCK_MAX_SIZE / 2; |
4d9c7fe6 WL |
60 | /** Default for accepting alerts from the P2P network. */ |
61 | static const bool DEFAULT_ALERTS = true; | |
a40034f7 JG |
62 | /** Minimum alert priority for enabling safe mode. */ |
63 | static const int ALERT_PRIORITY_SAFE_MODE = 4000; | |
57e6ecda | 64 | /** Maximum reorg length we will accept before we shut down and alert the user. */ |
269342f8 | 65 | static const unsigned int MAX_REORG_LENGTH = _COINBASE_MATURITY - 1; |
c5b390b6 | 66 | /** Maximum number of signature check operations in an IsStandard() P2SH script */ |
7f3b4e95 | 67 | static const unsigned int MAX_P2SH_SIGOPS = 15; |
9ee09dc6 | 68 | /** The maximum number of sigops we're willing to relay/mine in a single tx */ |
23f34359 | 69 | static const unsigned int MAX_STANDARD_TX_SIGOPS = MAX_BLOCK_SIGOPS/5; |
ba0625f2 | 70 | /** Default for -minrelaytxfee, minimum relay fee for transactions */ |
0f724e71 | 71 | static const unsigned int DEFAULT_MIN_RELAY_TX_FEE = 100; |
aa3c697e GA |
72 | /** Default for -maxorphantx, maximum number of orphan transactions kept in memory */ |
73 | static const unsigned int DEFAULT_MAX_ORPHAN_TRANSACTIONS = 100; | |
9bb37bf0 JG |
74 | /** Default for -txexpirydelta, in number of blocks */ |
75 | static const unsigned int DEFAULT_TX_EXPIRY_DELTA = 20; | |
9d6633ac | 76 | /** The maximum size of a blk?????.dat file (since 0.8) */ |
5382bcf8 | 77 | static const unsigned int MAX_BLOCKFILE_SIZE = 0x8000000; // 128 MiB |
9d6633ac | 78 | /** The pre-allocation chunk size for blk?????.dat files (since 0.8) */ |
bba89aa8 | 79 | static const unsigned int BLOCKFILE_CHUNK_SIZE = 0x1000000; // 16 MiB |
9d6633ac | 80 | /** The pre-allocation chunk size for rev?????.dat files (since 0.8) */ |
bba89aa8 | 81 | static const unsigned int UNDOFILE_CHUNK_SIZE = 0x100000; // 1 MiB |
f9cae832 PW |
82 | /** Maximum number of script-checking threads allowed */ |
83 | static const int MAX_SCRIPTCHECK_THREADS = 16; | |
5409404d PK |
84 | /** -par default (number of script-checking threads, 0 = auto) */ |
85 | static const int DEFAULT_SCRIPTCHECK_THREADS = 0; | |
f59d8f0b | 86 | /** Number of blocks that can be requested at any given time from a single peer. */ |
341735eb PW |
87 | static const int MAX_BLOCKS_IN_TRANSIT_PER_PEER = 16; |
88 | /** Timeout in seconds during which a peer must stall block download progress before being disconnected. */ | |
89 | static const unsigned int BLOCK_STALLING_TIMEOUT = 2; | |
90 | /** Number of headers sent in one getheaders result. We rely on the assumption that if a peer sends | |
7e6d23b1 | 91 | * less than this number, we reached its tip. Changing this value is a protocol upgrade. */ |
b93c8139 | 92 | static const unsigned int MAX_HEADERS_RESULTS = 160; |
341735eb PW |
93 | /** Size of the "block download window": how far ahead of our current height do we fetch? |
94 | * Larger windows tolerate larger download speed differences between peer, but increase the potential | |
95 | * degree of disordering of blocks on disk (which make reindexing and in the future perhaps pruning | |
96 | * harder). We'll probably want to make this a per-peer adaptive value at some point. */ | |
b3e591ac | 97 | static const unsigned int BLOCK_DOWNLOAD_WINDOW = 1024; |
67708acf PW |
98 | /** Time to wait (in seconds) between writing blocks/block index to disk. */ |
99 | static const unsigned int DATABASE_WRITE_INTERVAL = 60 * 60; | |
100 | /** Time to wait (in seconds) between flushing chainstate to disk. */ | |
101 | static const unsigned int DATABASE_FLUSH_INTERVAL = 24 * 60 * 60; | |
307f7d48 PW |
102 | /** Maximum length of reject messages. */ |
103 | static const unsigned int MAX_REJECT_MESSAGE_LENGTH = 111; | |
f59d8f0b | 104 | |
96fc3db2 | 105 | //static const bool DEFAULT_ADDRESSINDEX = false; |
106 | #define DEFAULT_ADDRESSINDEX (GetArg("-ac_cc",0) != 0) | |
8b78a819 T |
107 | static const bool DEFAULT_TIMESTAMPINDEX = false; |
108 | static const bool DEFAULT_SPENTINDEX = false; | |
109 | static const unsigned int DEFAULT_DB_MAX_OPEN_FILES = 1000; | |
110 | static const bool DEFAULT_DB_COMPRESSION = true; | |
111 | ||
e2a6161f S |
112 | // Sanity check the magic numbers when we change them |
113 | BOOST_STATIC_ASSERT(DEFAULT_BLOCK_MAX_SIZE <= MAX_BLOCK_SIZE); | |
114 | BOOST_STATIC_ASSERT(DEFAULT_BLOCK_PRIORITY_SIZE <= DEFAULT_BLOCK_MAX_SIZE); | |
115 | ||
c6a7e897 DH |
116 | #define equihash_parameters_acceptable(N, K) \ |
117 | ((CBlockHeader::HEADER_SIZE + equihash_solution_size(N, K))*MAX_HEADERS_RESULTS < \ | |
118 | MAX_PROTOCOL_MESSAGE_LENGTH-1000) | |
119 | ||
8a41e1ed PW |
120 | struct BlockHasher |
121 | { | |
80765854 | 122 | size_t operator()(const uint256& hash) const { return hash.GetCheapHash(); } |
8a41e1ed | 123 | }; |
0a61b0df | 124 | |
9bb37bf0 | 125 | extern unsigned int expiryDelta; |
7bf8b7c2 | 126 | extern CScript COINBASE_FLAGS; |
0a61b0df | 127 | extern CCriticalSection cs_main; |
319b1160 | 128 | extern CTxMemPool mempool; |
8a41e1ed | 129 | typedef boost::unordered_map<uint256, CBlockIndex*, BlockHasher> BlockMap; |
145d5be8 | 130 | extern BlockMap mapBlockIndex; |
51ed9ec9 BD |
131 | extern uint64_t nLastBlockTx; |
132 | extern uint64_t nLastBlockSize; | |
2bc4fd60 | 133 | extern const std::string strMessageMagic; |
ff6a7af1 LD |
134 | extern CWaitableCriticalSection csBestBlock; |
135 | extern CConditionVariable cvBlockChange; | |
1f015f6a | 136 | extern bool fExperimentalMode; |
66b02c93 | 137 | extern bool fImporting; |
7fea4846 | 138 | extern bool fReindex; |
f9cae832 | 139 | extern int nScriptCheckThreads; |
2d1fa42e | 140 | extern bool fTxIndex; |
3da434a2 | 141 | extern bool fIsBareMultisigStd; |
3fcfbc8a | 142 | extern bool fCheckBlockIndex; |
a8cdaf5c | 143 | extern bool fCheckpointsEnabled; |
d212ba32 SB |
144 | // TODO: remove this flag by structuring our code such that |
145 | // it is unneeded for testing | |
146 | extern bool fCoinbaseEnforcedProtectionEnabled; | |
fc684ad8 | 147 | extern size_t nCoinCacheUsage; |
13fc83c7 | 148 | extern CFeeRate minRelayTxFee; |
4d9c7fe6 | 149 | extern bool fAlerts; |
0a61b0df | 150 | |
c5b390b6 | 151 | /** Best header we've seen so far (used for getheaders queries' starting points). */ |
ad6e6017 PW |
152 | extern CBlockIndex *pindexBestHeader; |
153 | ||
c5b390b6 | 154 | /** Minimum disk space required - used in CheckDiskSpace() */ |
51ed9ec9 | 155 | static const uint64_t nMinDiskSpace = 52428800; |
0a61b0df | 156 | |
f9ec3f0f | 157 | /** Pruning-related variables and constants */ |
158 | /** True if any block files have ever been pruned. */ | |
159 | extern bool fHavePruned; | |
160 | /** True if we're running in -prune mode. */ | |
161 | extern bool fPruneMode; | |
162 | /** Number of MiB of block files that we're trying to stay below. */ | |
163 | extern uint64_t nPruneTarget; | |
164 | /** Block files containing a block-height within MIN_BLOCKS_TO_KEEP of chainActive.Tip() will not be pruned. */ | |
a79c8e24 | 165 | static const unsigned int MIN_BLOCKS_TO_KEEP = 288; |
f9ec3f0f | 166 | |
167 | // Require that user allocate at least 550MB for block & undo files (blk???.dat and rev???.dat) | |
168 | // At 1MB per block, 288 blocks = 288MB. | |
169 | // Add 15% for Undo data = 331MB | |
170 | // Add 20% for Orphan block rate = 397MB | |
171 | // We want the low water mark after pruning to be at least 397 MB and since we prune in | |
172 | // full block file chunks, we need the high water mark which triggers the prune to be | |
173 | // one 128MB block file + added 15% undo data = 147MB greater for a total of 545MB | |
174 | // Setting the target to > than 550MB will make it likely we can respect the target. | |
a79c8e24 | 175 | static const uint64_t MIN_DISK_SPACE_FOR_BLOCK_FILES = 550 * 1024 * 1024; |
f9ec3f0f | 176 | |
501da250 EL |
177 | /** Register with a network node to receive its signals */ |
178 | void RegisterNodeSignals(CNodeSignals& nodeSignals); | |
179 | /** Unregister a network node */ | |
180 | void UnregisterNodeSignals(CNodeSignals& nodeSignals); | |
181 | ||
c5b390b6 MF |
182 | /** |
183 | * Process an incoming block. This only returns after the best known valid | |
184 | * block is made active. Note that it does not, however, guarantee that the | |
185 | * specific block passed to it has been checked for validity! | |
186 | * | |
26c16d9d | 187 | * @param[out] state This may be set to an Error state if any error occurred processing it, including during validation/connection/etc of otherwise unrelated blocks during reorganisation; or it may be set to an Invalid state if pblock is itself invalid (but this is not guaranteed even when the block is checked). If you want to *possibly* get feedback on whether pblock is valid, you must also install a CValidationInterface (see validationinterface.h) - this will have its BlockChecked method called whenever *any* block completes validation. |
c5b390b6 MF |
188 | * @param[in] pfrom The node which we are receiving the block from; it is added to mapBlockSource and may be penalised if the block is invalid. |
189 | * @param[in] pblock The block we want to process. | |
304892fc | 190 | * @param[in] fForceProcessing Process this block even if unrequested; used for non-network block sources and whitelisted peers. |
c5b390b6 MF |
191 | * @param[out] dbp If pblock is stored to disk (or already there), this will be set to its location. |
192 | * @return True if state.IsValid() | |
193 | */ | |
7bb789bb | 194 | bool ProcessNewBlock(bool from_miner,int32_t height,CValidationState &state, CNode* pfrom, CBlock* pblock, bool fForceProcessing, CDiskBlockPos *dbp); |
160b028b | 195 | /** Check whether enough disk space is available for an incoming block */ |
51ed9ec9 | 196 | bool CheckDiskSpace(uint64_t nAdditionalBytes = 0); |
160b028b | 197 | /** Open a block file (blk?????.dat) */ |
5382bcf8 | 198 | FILE* OpenBlockFile(const CDiskBlockPos &pos, bool fReadOnly = false); |
160b028b | 199 | /** Open an undo file (rev?????.dat) */ |
5382bcf8 | 200 | FILE* OpenUndoFile(const CDiskBlockPos &pos, bool fReadOnly = false); |
ec7eb0fa SD |
201 | /** Translation to a filesystem path */ |
202 | boost::filesystem::path GetBlockPosFilename(const CDiskBlockPos &pos, const char *prefix); | |
160b028b | 203 | /** Import blocks from an external file */ |
7fea4846 | 204 | bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp = NULL); |
38603761 PW |
205 | /** Initialize a new block tree database + block data on disk */ |
206 | bool InitBlockIndex(); | |
160b028b | 207 | /** Load the block tree and coins database from disk */ |
7fea4846 | 208 | bool LoadBlockIndex(); |
f7f3a96b PW |
209 | /** Unload database information */ |
210 | void UnloadBlockIndex(); | |
160b028b | 211 | /** Process protocol messages received from a given node */ |
0a61b0df | 212 | bool ProcessMessages(CNode* pfrom); |
fc720207 RV |
213 | /** |
214 | * Send queued protocol messages to be sent to a give node. | |
215 | * | |
216 | * @param[in] pto The node which we are sending messages to. | |
217 | * @param[in] fSendTrickle When true send the trickled data, otherwise trickle the data until true. | |
218 | */ | |
0a61b0df | 219 | bool SendMessages(CNode* pto, bool fSendTrickle); |
f9cae832 | 220 | /** Run an instance of the script checking thread */ |
21eb5ada | 221 | void ThreadScriptCheck(); |
36cba8f1 | 222 | /** Try to detect Partition (network isolation) attacks against us */ |
fce474c9 | 223 | void PartitionCheck(bool (*initialDownloadCheck)(), CCriticalSection& cs, const CBlockIndex *const &bestHeader, int64_t nPowTargetSpacing); |
f0bf5fb2 | 224 | /** Check whether we are doing an initial block download (synchronizing from disk or network) */ |
0a61b0df | 225 | bool IsInitialBlockDownload(); |
160b028b | 226 | /** Format a string that describes several potential problems detected by the core */ |
db954a65 | 227 | std::string GetWarnings(const std::string& strFor); |
160b028b | 228 | /** Retrieve a transaction (from memory pool, or from disk, if possible) */ |
450cbb09 | 229 | bool GetTransaction(const uint256 &hash, CTransaction &tx, uint256 &hashBlock, bool fAllowSlow = false); |
160b028b | 230 | /** Find the best known block, and make it the tip of the block chain */ |
92bb6f2f | 231 | bool ActivateBestChain(CValidationState &state, CBlock *pblock = NULL); |
935bd0a4 | 232 | CAmount GetBlockSubsidy(int nHeight, const Consensus::Params& consensusParams); |
aabdf9e8 | 233 | |
f9ec3f0f | 234 | /** |
235 | * Prune block and undo files (blk???.dat and undo???.dat) so that the disk space used is less than a user-defined target. | |
236 | * The user sets the target (in MB) on the command line or in config file. This will be run on startup and whenever new | |
237 | * space is allocated in a block or undo file, staying below the target. Changing back to unpruned requires a reindex | |
238 | * (which in this case means the blockchain must be re-downloaded.) | |
239 | * | |
240 | * Pruning functions are called from FlushStateToDisk when the global fCheckForPruning flag has been set. | |
241 | * Block and undo files are deleted in lock-step (when blk00003.dat is deleted, so is rev00003.dat.) | |
242 | * Pruning cannot take place until the longest chain is at least a certain length (100000 on mainnet, 1000 on testnet, 10 on regtest). | |
243 | * Pruning will never delete a block within a defined distance (currently 288) from the active chain's tip. | |
244 | * The block index is updated by unsetting HAVE_DATA and HAVE_UNDO for any blocks that were stored in the deleted files. | |
245 | * A db flag records the fact that at least some block files have been pruned. | |
246 | * | |
247 | * @param[out] setFilesToPrune The set of file indices that can be unlinked will be returned | |
248 | */ | |
249 | void FindFilesToPrune(std::set<int>& setFilesToPrune); | |
250 | ||
251 | /** | |
252 | * Actually unlink the specified files | |
253 | */ | |
254 | void UnlinkPrunedFiles(std::set<int>& setFilesToPrune); | |
255 | ||
160b028b | 256 | /** Create a new block index entry for a given block hash */ |
2d8a4829 | 257 | CBlockIndex * InsertBlockIndex(uint256 hash); |
b2864d2f PW |
258 | /** Get statistics from node state */ |
259 | bool GetNodeStateStats(NodeId nodeid, CNodeStateStats &stats); | |
f59d8f0b PW |
260 | /** Increase a node's misbehavior score. */ |
261 | void Misbehaving(NodeId nodeid, int howmuch); | |
51ce901a PW |
262 | /** Flush all state, indexes and buffers to disk. */ |
263 | void FlushStateToDisk(); | |
f9ec3f0f | 264 | /** Prune block files and flush state to disk. */ |
265 | void PruneAndFlush(); | |
857c61df | 266 | |
319b1160 GA |
267 | /** (try to) add transaction to memory pool **/ |
268 | bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree, | |
1371e6f5 | 269 | bool* pfMissingInputs, bool fRejectAbsurdFee=false); |
0a61b0df | 270 | |
271 | ||
b2864d2f PW |
272 | struct CNodeStateStats { |
273 | int nMisbehavior; | |
aa815647 | 274 | int nSyncHeight; |
ad6e6017 PW |
275 | int nCommonHeight; |
276 | std::vector<int> vHeightInFlight; | |
b2864d2f PW |
277 | }; |
278 | ||
8b78a819 T |
279 | struct CTimestampIndexIteratorKey { |
280 | unsigned int timestamp; | |
281 | ||
282 | size_t GetSerializeSize(int nType, int nVersion) const { | |
283 | return 4; | |
284 | } | |
285 | template<typename Stream> | |
286 | void Serialize(Stream& s, int nType, int nVersion) const { | |
287 | ser_writedata32be(s, timestamp); | |
288 | } | |
289 | template<typename Stream> | |
290 | void Unserialize(Stream& s, int nType, int nVersion) { | |
291 | timestamp = ser_readdata32be(s); | |
292 | } | |
293 | ||
294 | CTimestampIndexIteratorKey(unsigned int time) { | |
295 | timestamp = time; | |
296 | } | |
297 | ||
298 | CTimestampIndexIteratorKey() { | |
299 | SetNull(); | |
300 | } | |
301 | ||
302 | void SetNull() { | |
303 | timestamp = 0; | |
304 | } | |
305 | }; | |
306 | ||
307 | struct CTimestampIndexKey { | |
308 | unsigned int timestamp; | |
309 | uint256 blockHash; | |
310 | ||
311 | size_t GetSerializeSize(int nType, int nVersion) const { | |
312 | return 36; | |
313 | } | |
314 | template<typename Stream> | |
315 | void Serialize(Stream& s, int nType, int nVersion) const { | |
316 | ser_writedata32be(s, timestamp); | |
317 | blockHash.Serialize(s, nType, nVersion); | |
318 | } | |
319 | template<typename Stream> | |
320 | void Unserialize(Stream& s, int nType, int nVersion) { | |
321 | timestamp = ser_readdata32be(s); | |
322 | blockHash.Unserialize(s, nType, nVersion); | |
323 | } | |
324 | ||
325 | CTimestampIndexKey(unsigned int time, uint256 hash) { | |
326 | timestamp = time; | |
327 | blockHash = hash; | |
328 | } | |
329 | ||
330 | CTimestampIndexKey() { | |
331 | SetNull(); | |
332 | } | |
333 | ||
334 | void SetNull() { | |
335 | timestamp = 0; | |
336 | blockHash.SetNull(); | |
337 | } | |
338 | }; | |
339 | ||
340 | struct CTimestampBlockIndexKey { | |
341 | uint256 blockHash; | |
342 | ||
343 | size_t GetSerializeSize(int nType, int nVersion) const { | |
344 | return 32; | |
345 | } | |
346 | ||
347 | template<typename Stream> | |
348 | void Serialize(Stream& s, int nType, int nVersion) const { | |
349 | blockHash.Serialize(s, nType, nVersion); | |
350 | } | |
351 | ||
352 | template<typename Stream> | |
353 | void Unserialize(Stream& s, int nType, int nVersion) { | |
354 | blockHash.Unserialize(s, nType, nVersion); | |
355 | } | |
356 | ||
357 | CTimestampBlockIndexKey(uint256 hash) { | |
358 | blockHash = hash; | |
359 | } | |
360 | ||
361 | CTimestampBlockIndexKey() { | |
362 | SetNull(); | |
363 | } | |
364 | ||
365 | void SetNull() { | |
366 | blockHash.SetNull(); | |
367 | } | |
368 | }; | |
369 | ||
370 | struct CTimestampBlockIndexValue { | |
371 | unsigned int ltimestamp; | |
372 | size_t GetSerializeSize(int nType, int nVersion) const { | |
373 | return 4; | |
374 | } | |
375 | ||
376 | template<typename Stream> | |
377 | void Serialize(Stream& s, int nType, int nVersion) const { | |
378 | ser_writedata32be(s, ltimestamp); | |
379 | } | |
380 | ||
381 | template<typename Stream> | |
382 | void Unserialize(Stream& s, int nType, int nVersion) { | |
383 | ltimestamp = ser_readdata32be(s); | |
384 | } | |
385 | ||
386 | CTimestampBlockIndexValue (unsigned int time) { | |
387 | ltimestamp = time; | |
388 | } | |
389 | ||
390 | CTimestampBlockIndexValue() { | |
391 | SetNull(); | |
392 | } | |
393 | ||
394 | void SetNull() { | |
395 | ltimestamp = 0; | |
396 | } | |
397 | }; | |
398 | ||
399 | struct CAddressUnspentKey { | |
400 | unsigned int type; | |
401 | uint160 hashBytes; | |
402 | uint256 txhash; | |
403 | size_t index; | |
404 | ||
405 | size_t GetSerializeSize(int nType, int nVersion) const { | |
406 | return 57; | |
407 | } | |
408 | template<typename Stream> | |
409 | void Serialize(Stream& s, int nType, int nVersion) const { | |
410 | ser_writedata8(s, type); | |
411 | hashBytes.Serialize(s, nType, nVersion); | |
412 | txhash.Serialize(s, nType, nVersion); | |
413 | ser_writedata32(s, index); | |
414 | } | |
415 | template<typename Stream> | |
416 | void Unserialize(Stream& s, int nType, int nVersion) { | |
417 | type = ser_readdata8(s); | |
418 | hashBytes.Unserialize(s, nType, nVersion); | |
419 | txhash.Unserialize(s, nType, nVersion); | |
420 | index = ser_readdata32(s); | |
421 | } | |
422 | ||
423 | CAddressUnspentKey(unsigned int addressType, uint160 addressHash, uint256 txid, size_t indexValue) { | |
424 | type = addressType; | |
425 | hashBytes = addressHash; | |
426 | txhash = txid; | |
427 | index = indexValue; | |
428 | } | |
429 | ||
430 | CAddressUnspentKey() { | |
431 | SetNull(); | |
432 | } | |
433 | ||
434 | void SetNull() { | |
435 | type = 0; | |
436 | hashBytes.SetNull(); | |
437 | txhash.SetNull(); | |
438 | index = 0; | |
439 | } | |
440 | }; | |
441 | ||
442 | struct CAddressUnspentValue { | |
443 | CAmount satoshis; | |
444 | CScript script; | |
445 | int blockHeight; | |
446 | ||
447 | ADD_SERIALIZE_METHODS; | |
448 | ||
449 | template <typename Stream, typename Operation> | |
450 | inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { | |
451 | READWRITE(satoshis); | |
452 | READWRITE(script); | |
453 | READWRITE(blockHeight); | |
454 | } | |
455 | ||
456 | CAddressUnspentValue(CAmount sats, CScript scriptPubKey, int height) { | |
457 | satoshis = sats; | |
458 | script = scriptPubKey; | |
459 | blockHeight = height; | |
460 | } | |
461 | ||
462 | CAddressUnspentValue() { | |
463 | SetNull(); | |
464 | } | |
465 | ||
466 | void SetNull() { | |
467 | satoshis = -1; | |
468 | script.clear(); | |
469 | blockHeight = 0; | |
470 | } | |
471 | ||
472 | bool IsNull() const { | |
473 | return (satoshis == -1); | |
474 | } | |
475 | }; | |
476 | ||
477 | struct CAddressIndexKey { | |
478 | unsigned int type; | |
479 | uint160 hashBytes; | |
480 | int blockHeight; | |
481 | unsigned int txindex; | |
482 | uint256 txhash; | |
483 | size_t index; | |
484 | bool spending; | |
485 | ||
486 | size_t GetSerializeSize(int nType, int nVersion) const { | |
487 | return 66; | |
488 | } | |
489 | template<typename Stream> | |
490 | void Serialize(Stream& s, int nType, int nVersion) const { | |
491 | ser_writedata8(s, type); | |
492 | hashBytes.Serialize(s, nType, nVersion); | |
493 | // Heights are stored big-endian for key sorting in LevelDB | |
494 | ser_writedata32be(s, blockHeight); | |
495 | ser_writedata32be(s, txindex); | |
496 | txhash.Serialize(s, nType, nVersion); | |
497 | ser_writedata32(s, index); | |
498 | char f = spending; | |
499 | ser_writedata8(s, f); | |
500 | } | |
501 | template<typename Stream> | |
502 | void Unserialize(Stream& s, int nType, int nVersion) { | |
503 | type = ser_readdata8(s); | |
504 | hashBytes.Unserialize(s, nType, nVersion); | |
505 | blockHeight = ser_readdata32be(s); | |
506 | txindex = ser_readdata32be(s); | |
507 | txhash.Unserialize(s, nType, nVersion); | |
508 | index = ser_readdata32(s); | |
509 | char f = ser_readdata8(s); | |
510 | spending = f; | |
511 | } | |
512 | ||
513 | CAddressIndexKey(unsigned int addressType, uint160 addressHash, int height, int blockindex, | |
514 | uint256 txid, size_t indexValue, bool isSpending) { | |
515 | type = addressType; | |
516 | hashBytes = addressHash; | |
517 | blockHeight = height; | |
518 | txindex = blockindex; | |
519 | txhash = txid; | |
520 | index = indexValue; | |
521 | spending = isSpending; | |
522 | } | |
523 | ||
524 | CAddressIndexKey() { | |
525 | SetNull(); | |
526 | } | |
527 | ||
528 | void SetNull() { | |
529 | type = 0; | |
530 | hashBytes.SetNull(); | |
531 | blockHeight = 0; | |
532 | txindex = 0; | |
533 | txhash.SetNull(); | |
534 | index = 0; | |
535 | spending = false; | |
536 | } | |
537 | ||
538 | }; | |
539 | ||
540 | struct CAddressIndexIteratorKey { | |
541 | unsigned int type; | |
542 | uint160 hashBytes; | |
543 | ||
544 | size_t GetSerializeSize(int nType, int nVersion) const { | |
545 | return 21; | |
546 | } | |
547 | template<typename Stream> | |
548 | void Serialize(Stream& s, int nType, int nVersion) const { | |
549 | ser_writedata8(s, type); | |
550 | hashBytes.Serialize(s, nType, nVersion); | |
551 | } | |
552 | template<typename Stream> | |
553 | void Unserialize(Stream& s, int nType, int nVersion) { | |
554 | type = ser_readdata8(s); | |
555 | hashBytes.Unserialize(s, nType, nVersion); | |
556 | } | |
557 | ||
558 | CAddressIndexIteratorKey(unsigned int addressType, uint160 addressHash) { | |
559 | type = addressType; | |
560 | hashBytes = addressHash; | |
561 | } | |
562 | ||
563 | CAddressIndexIteratorKey() { | |
564 | SetNull(); | |
565 | } | |
566 | ||
567 | void SetNull() { | |
568 | type = 0; | |
569 | hashBytes.SetNull(); | |
570 | } | |
571 | }; | |
572 | ||
573 | struct CAddressIndexIteratorHeightKey { | |
574 | unsigned int type; | |
575 | uint160 hashBytes; | |
576 | int blockHeight; | |
577 | ||
578 | size_t GetSerializeSize(int nType, int nVersion) const { | |
579 | return 25; | |
580 | } | |
581 | template<typename Stream> | |
582 | void Serialize(Stream& s, int nType, int nVersion) const { | |
583 | ser_writedata8(s, type); | |
584 | hashBytes.Serialize(s, nType, nVersion); | |
585 | ser_writedata32be(s, blockHeight); | |
586 | } | |
587 | template<typename Stream> | |
588 | void Unserialize(Stream& s, int nType, int nVersion) { | |
589 | type = ser_readdata8(s); | |
590 | hashBytes.Unserialize(s, nType, nVersion); | |
591 | blockHeight = ser_readdata32be(s); | |
592 | } | |
593 | ||
594 | CAddressIndexIteratorHeightKey(unsigned int addressType, uint160 addressHash, int height) { | |
595 | type = addressType; | |
596 | hashBytes = addressHash; | |
597 | blockHeight = height; | |
598 | } | |
599 | ||
600 | CAddressIndexIteratorHeightKey() { | |
601 | SetNull(); | |
602 | } | |
603 | ||
604 | void SetNull() { | |
605 | type = 0; | |
606 | hashBytes.SetNull(); | |
607 | blockHeight = 0; | |
608 | } | |
609 | }; | |
610 | ||
2d1fa42e PW |
611 | struct CDiskTxPos : public CDiskBlockPos |
612 | { | |
613 | unsigned int nTxOffset; // after header | |
614 | ||
3f6540ad | 615 | ADD_SERIALIZE_METHODS; |
3d796f89 | 616 | |
84881f8c | 617 | template <typename Stream, typename Operation> |
31e9a838 | 618 | inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { |
2d1fa42e PW |
619 | READWRITE(*(CDiskBlockPos*)this); |
620 | READWRITE(VARINT(nTxOffset)); | |
3d796f89 | 621 | } |
2d1fa42e PW |
622 | |
623 | CDiskTxPos(const CDiskBlockPos &blockIn, unsigned int nTxOffsetIn) : CDiskBlockPos(blockIn.nFile, blockIn.nPos), nTxOffset(nTxOffsetIn) { | |
624 | } | |
625 | ||
626 | CDiskTxPos() { | |
627 | SetNull(); | |
628 | } | |
0a61b0df | 629 | |
2d1fa42e PW |
630 | void SetNull() { |
631 | CDiskBlockPos::SetNull(); | |
632 | nTxOffset = 0; | |
633 | } | |
634 | }; | |
0a61b0df | 635 | |
636 | ||
a372168e | 637 | CAmount GetMinRelayFee(const CTransaction& tx, unsigned int nBytes, bool fAllowFree); |
788536f1 | 638 | |
c5b390b6 MF |
639 | /** |
640 | * Check transaction inputs, and make sure any | |
641 | * pay-to-script-hash transactions are evaluating IsStandard scripts | |
642 | * | |
643 | * Why bother? To avoid denial-of-service attacks; an attacker | |
644 | * can submit a standard HASH... OP_EQUAL transaction, | |
645 | * which will get accepted into blocks. The redemption | |
646 | * script can be anything; an attacker could use a very | |
647 | * expensive-to-check-upon-redemption script like: | |
648 | * DUP CHECKSIG DROP ... repeated 100 times... OP_1 | |
649 | */ | |
922e8e29 | 650 | |
c5b390b6 MF |
651 | /** |
652 | * Check for standard transaction types | |
653 | * @param[in] mapInputs Map of previous transactions that have outputs we're spending | |
654 | * @return True if all inputs (scriptSigs) use only standard transaction forms | |
655 | */ | |
be126699 | 656 | bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs, uint32_t consensusBranchId); |
8d7849b6 | 657 | |
c5b390b6 MF |
658 | /** |
659 | * Count ECDSA signature operations the old-fashioned (pre-0.6) way | |
660 | * @return number of sigops this transaction's outputs will produce when spent | |
661 | * @see CTransaction::FetchInputs | |
662 | */ | |
05df3fc6 | 663 | unsigned int GetLegacySigOpCount(const CTransaction& tx); |
a206a239 | 664 | |
c5b390b6 MF |
665 | /** |
666 | * Count ECDSA signature operations in pay-to-script-hash inputs. | |
667 | * | |
668 | * @param[in] mapInputs Map of previous transactions that have outputs we're spending | |
669 | * @return maximum number of sigops required to validate this transaction's inputs | |
670 | * @see CTransaction::FetchInputs | |
05df3fc6 | 671 | */ |
d0867acb | 672 | unsigned int GetP2SHSigOpCount(const CTransaction& tx, const CCoinsViewCache& mapInputs); |
0a61b0df | 673 | |
0a61b0df | 674 | |
c5b390b6 MF |
675 | /** |
676 | * Check whether all inputs of this transaction are valid (no double spends, scripts & sigs, amounts) | |
677 | * This does not modify the UTXO set. If pvChecks is not NULL, script checks are pushed onto it | |
678 | * instead of being performed inline. | |
679 | */ | |
10df6fb3 | 680 | bool ContextualCheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsViewCache &view, bool fScriptChecks, |
be126699 JG |
681 | unsigned int flags, bool cacheStore, PrecomputedTransactionData& txdata, |
682 | const Consensus::Params& consensusParams, uint32_t consensusBranchId, | |
c0dde76d | 683 | std::vector<CScriptCheck> *pvChecks = NULL); |
0a61b0df | 684 | |
072099d7 S |
685 | /** Check a transaction contextually against a set of consensus rules */ |
686 | bool ContextualCheckTransaction(const CTransaction& tx, CValidationState &state, int nHeight, int dosLevel); | |
687 | ||
c5b390b6 | 688 | /** Apply the effects of this transaction on the UTXO set represented by view */ |
8cb98d91 | 689 | void UpdateCoins(const CTransaction& tx, CCoinsViewCache& inputs, int nHeight); |
8d7849b6 | 690 | |
722d811f | 691 | /** Transaction validation functions */ |
8d7849b6 | 692 | |
c5b390b6 | 693 | /** Context-independent validity checks */ |
6fb8d0c2 | 694 | bool CheckTransaction(const CTransaction& tx, CValidationState& state, libzcash::ProofVerifier& verifier); |
948d4e6c | 695 | bool CheckTransactionWithoutProofVerification(const CTransaction& tx, CValidationState &state); |
450cbb09 | 696 | |
05df3fc6 | 697 | /** Check for standard transaction types |
c5b390b6 MF |
698 | * @return True if all outputs (scriptPubKeys) use only standard transaction forms |
699 | */ | |
072099d7 | 700 | bool IsStandardTx(const CTransaction& tx, std::string& reason, int nHeight = 0); |
450cbb09 | 701 | |
722d811f JT |
702 | namespace Consensus { |
703 | ||
704 | /** | |
705 | * Check whether all inputs of this transaction are valid (no double spends and amounts) | |
706 | * This does not modify the UTXO set. This does not check scripts and sigs. | |
707 | * Preconditions: tx.IsCoinBase() is false. | |
708 | */ | |
709 | bool CheckTxInputs(const CTransaction& tx, CValidationState& state, const CCoinsViewCache& inputs, int nSpendHeight, const Consensus::Params& consensusParams); | |
710 | ||
711 | } // namespace Consensus | |
450cbb09 | 712 | |
75a4d512 PT |
713 | /** |
714 | * Check if transaction is final and can be included in a block with the | |
715 | * specified height and time. Consensus critical. | |
716 | */ | |
14aa6cc0 | 717 | bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime); |
75a4d512 | 718 | |
9bb37bf0 JG |
719 | /** |
720 | * Check if transaction is expired and can be included in a block with the | |
721 | * specified height. Consensus critical. | |
722 | */ | |
723 | bool IsExpiredTx(const CTransaction &tx, int nBlockHeight); | |
724 | ||
75a4d512 PT |
725 | /** |
726 | * Check if transaction will be final in the next block to be created. | |
727 | * | |
728 | * Calls IsFinalTx() with current block height and appropriate block time. | |
a1d3c6fb MF |
729 | * |
730 | * See consensus/consensus.h for flag definitions. | |
75a4d512 | 731 | */ |
a1d3c6fb | 732 | bool CheckFinalTx(const CTransaction &tx, int flags = -1); |
450cbb09 | 733 | |
c5b390b6 MF |
734 | /** |
735 | * Closure representing one script verification | |
736 | * Note that this stores references to the spending transaction | |
737 | */ | |
2800ce73 PW |
738 | class CScriptCheck |
739 | { | |
740 | private: | |
741 | CScript scriptPubKey; | |
2d42e1a9 | 742 | CAmount amount; |
2800ce73 PW |
743 | const CTransaction *ptxTo; |
744 | unsigned int nIn; | |
745 | unsigned int nFlags; | |
e790c370 | 746 | bool cacheStore; |
be126699 | 747 | uint32_t consensusBranchId; |
307f7d48 | 748 | ScriptError error; |
6514771a | 749 | PrecomputedTransactionData *txdata; |
0a61b0df | 750 | |
2800ce73 | 751 | public: |
be126699 JG |
752 | CScriptCheck(): amount(0), ptxTo(0), nIn(0), nFlags(0), cacheStore(false), consensusBranchId(0), error(SCRIPT_ERR_UNKNOWN_ERROR) {} |
753 | CScriptCheck(const CCoins& txFromIn, const CTransaction& txToIn, unsigned int nInIn, unsigned int nFlagsIn, bool cacheIn, uint32_t consensusBranchIdIn, PrecomputedTransactionData* txdataIn) : | |
2d42e1a9 | 754 | scriptPubKey(txFromIn.vout[txToIn.vin[nInIn].prevout.n].scriptPubKey), amount(txFromIn.vout[txToIn.vin[nInIn].prevout.n].nValue), |
be126699 | 755 | ptxTo(&txToIn), nIn(nInIn), nFlags(nFlagsIn), cacheStore(cacheIn), consensusBranchId(consensusBranchIdIn), error(SCRIPT_ERR_UNKNOWN_ERROR), txdata(txdataIn) { } |
2800ce73 | 756 | |
307f7d48 | 757 | bool operator()(); |
2800ce73 PW |
758 | |
759 | void swap(CScriptCheck &check) { | |
760 | scriptPubKey.swap(check.scriptPubKey); | |
761 | std::swap(ptxTo, check.ptxTo); | |
2d42e1a9 | 762 | std::swap(amount, check.amount); |
2800ce73 PW |
763 | std::swap(nIn, check.nIn); |
764 | std::swap(nFlags, check.nFlags); | |
e790c370 | 765 | std::swap(cacheStore, check.cacheStore); |
be126699 | 766 | std::swap(consensusBranchId, check.consensusBranchId); |
307f7d48 | 767 | std::swap(error, check.error); |
6514771a | 768 | std::swap(txdata, check.txdata); |
2800ce73 | 769 | } |
307f7d48 PW |
770 | |
771 | ScriptError GetScriptError() const { return error; } | |
2800ce73 | 772 | }; |
0a61b0df | 773 | |
8b78a819 T |
774 | bool GetTimestampIndex(const unsigned int &high, const unsigned int &low, const bool fActiveOnly, std::vector<std::pair<uint256, unsigned int> > &hashes); |
775 | bool GetSpentIndex(CSpentIndexKey &key, CSpentIndexValue &value); | |
776 | bool GetAddressIndex(uint160 addressHash, int type, | |
777 | std::vector<std::pair<CAddressIndexKey, CAmount> > &addressIndex, | |
778 | int start = 0, int end = 0); | |
779 | bool GetAddressUnspent(uint160 addressHash, int type, | |
780 | std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > &unspentOutputs); | |
0a61b0df | 781 | |
a6dba0fd | 782 | /** Functions for disk access for blocks */ |
e6973430 | 783 | bool WriteBlockToDisk(CBlock& block, CDiskBlockPos& pos, const CMessageHeader::MessageStartChars& messageStart); |
b8add6a4 | 784 | bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos,bool checkPOW); |
785 | bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex,bool checkPOW); | |
0a61b0df | 786 | |
787 | ||
5c363ed6 EL |
788 | /** Functions for validating blocks and updating the block tree */ |
789 | ||
790 | /** Undo the effects of this block (with given index) on the UTXO set represented by coins. | |
791 | * In case pfClean is provided, operation will try to be tolerant about errors, and *pfClean | |
792 | * will be true if no problems were found. Otherwise, the return value will be false in case | |
793 | * of problems. Note that in any case, coins may be modified. */ | |
794 | bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& coins, bool* pfClean = NULL); | |
795 | ||
c5b390b6 | 796 | /** Apply the effects of this block (with given index) on the UTXO set represented by coins */ |
96f9009e | 797 | bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& coins, bool fJustCheck = false,bool fCheckPOW = false); |
f3ae51dc | 798 | |
c5b390b6 | 799 | /** Context-independent validity checks */ |
531b9293 | 800 | bool CheckBlockHeader(int32_t *futureblockp,int32_t height,CBlockIndex *pindex,const CBlockHeader& block, CValidationState& state, bool fCheckPOW = true); |
9f6cb8f0 | 801 | bool CheckBlock(int32_t *futureblockp,int32_t height,CBlockIndex *pindex,const CBlock& block, CValidationState& state, |
6fb8d0c2 JG |
802 | libzcash::ProofVerifier& verifier, |
803 | bool fCheckPOW = true, bool fCheckMerkleRoot = true); | |
38991ffa | 804 | |
c5b390b6 | 805 | /** Context-dependent validity checks */ |
a48f2d6d LD |
806 | bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex *pindexPrev); |
807 | bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIndex *pindexPrev); | |
808 | ||
c5b390b6 | 809 | /** Check a block is completely valid from start to finish (only works on top of our current best block, with cs_main held) */ |
df08a626 LD |
810 | bool TestBlockValidity(CValidationState &state, const CBlock& block, CBlockIndex *pindexPrev, bool fCheckPOW = true, bool fCheckMerkleRoot = true); |
811 | ||
6fb8d0c2 JG |
812 | /** |
813 | * Store block on disk. | |
814 | * JoinSplit proofs are never verified, because: | |
815 | * - AcceptBlock doesn't perform script checks either. | |
816 | * - The only caller of AcceptBlock verifies JoinSplit proofs elsewhere. | |
817 | * If dbp is non-NULL, the file is known to already reside on disk | |
818 | */ | |
531b9293 | 819 | bool AcceptBlock(int32_t *futureblockp,CBlock& block, CValidationState& state, CBlockIndex **pindex, bool fRequested, CDiskBlockPos* dbp); |
820 | bool AcceptBlockHeader(int32_t *futureblockp,const CBlockHeader& block, CValidationState& state, CBlockIndex **ppindex= NULL); | |
2a4d3464 | 821 | |
5c363ed6 EL |
822 | |
823 | ||
9e851450 JG |
824 | /** |
825 | * When there are blocks in the active chain with missing data (e.g. if the | |
826 | * activation height and branch ID of a particular upgrade have been altered), | |
827 | * rewind the chainstate and remove them from the block index. | |
828 | */ | |
89f20450 PW |
829 | bool RewindBlockIndex(const CChainParams& params); |
830 | ||
5382bcf8 PW |
831 | class CBlockFileInfo |
832 | { | |
833 | public: | |
c5b390b6 MF |
834 | unsigned int nBlocks; //! number of blocks stored in file |
835 | unsigned int nSize; //! number of used bytes of block file | |
836 | unsigned int nUndoSize; //! number of used bytes in the undo file | |
837 | unsigned int nHeightFirst; //! lowest height of block in file | |
838 | unsigned int nHeightLast; //! highest height of block in file | |
839 | uint64_t nTimeFirst; //! earliest time of block in file | |
840 | uint64_t nTimeLast; //! latest time of block in file | |
5382bcf8 | 841 | |
3f6540ad | 842 | ADD_SERIALIZE_METHODS; |
3d796f89 | 843 | |
84881f8c | 844 | template <typename Stream, typename Operation> |
31e9a838 | 845 | inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { |
5382bcf8 PW |
846 | READWRITE(VARINT(nBlocks)); |
847 | READWRITE(VARINT(nSize)); | |
848 | READWRITE(VARINT(nUndoSize)); | |
849 | READWRITE(VARINT(nHeightFirst)); | |
850 | READWRITE(VARINT(nHeightLast)); | |
851 | READWRITE(VARINT(nTimeFirst)); | |
852 | READWRITE(VARINT(nTimeLast)); | |
3d796f89 | 853 | } |
5382bcf8 PW |
854 | |
855 | void SetNull() { | |
856 | nBlocks = 0; | |
857 | nSize = 0; | |
858 | nUndoSize = 0; | |
859 | nHeightFirst = 0; | |
860 | nHeightLast = 0; | |
861 | nTimeFirst = 0; | |
862 | nTimeLast = 0; | |
863 | } | |
864 | ||
865 | CBlockFileInfo() { | |
866 | SetNull(); | |
867 | } | |
868 | ||
651480c8 | 869 | std::string ToString() const; |
5382bcf8 | 870 | |
c5b390b6 | 871 | /** update statistics (does not update nSize) */ |
51ed9ec9 | 872 | void AddBlock(unsigned int nHeightIn, uint64_t nTimeIn) { |
5382bcf8 PW |
873 | if (nBlocks==0 || nHeightFirst > nHeightIn) |
874 | nHeightFirst = nHeightIn; | |
875 | if (nBlocks==0 || nTimeFirst > nTimeIn) | |
876 | nTimeFirst = nTimeIn; | |
877 | nBlocks++; | |
367c29d6 | 878 | if (nHeightIn > nHeightLast) |
5382bcf8 PW |
879 | nHeightLast = nHeightIn; |
880 | if (nTimeIn > nTimeLast) | |
881 | nTimeLast = nTimeIn; | |
882 | } | |
883 | }; | |
884 | ||
06a91d96 CL |
885 | /** RAII wrapper for VerifyDB: Verify consistency of the block and coin databases */ |
886 | class CVerifyDB { | |
887 | public: | |
06a91d96 CL |
888 | CVerifyDB(); |
889 | ~CVerifyDB(); | |
2e280311 | 890 | bool VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth); |
06a91d96 CL |
891 | }; |
892 | ||
6db83db3 | 893 | /** Find the last common block between the parameter chain and a locator. */ |
894 | CBlockIndex* FindForkInGlobalIndex(const CChain& chain, const CBlockLocator& locator); | |
0a61b0df | 895 | |
9b0a8d31 PW |
896 | /** Mark a block as invalid. */ |
897 | bool InvalidateBlock(CValidationState& state, CBlockIndex *pindex); | |
898 | ||
899 | /** Remove invalidity status from a block and its descendants. */ | |
900 | bool ReconsiderBlock(CValidationState& state, CBlockIndex *pindex); | |
901 | ||
fe5cef05 | 902 | /** The currently-connected chain of blocks (protected by cs_main). */ |
4c6d41b8 | 903 | extern CChain chainActive; |
0a61b0df | 904 | |
d979e6e3 | 905 | /** Global variable that points to the active CCoinsView (protected by cs_main) */ |
ae8bfd12 PW |
906 | extern CCoinsViewCache *pcoinsTip; |
907 | ||
d979e6e3 PW |
908 | /** Global variable that points to the active block tree (protected by cs_main) */ |
909 | extern CBlockTreeDB *pblocktree; | |
910 | ||
e079f010 JT |
911 | /** |
912 | * Return the spend height, which is one more than the inputs.GetBestBlock(). | |
913 | * While checking, GetBestBlock() refers to the parent block. (protected by cs_main) | |
914 | * This is also true for mempool checks. | |
915 | */ | |
916 | int GetSpendHeight(const CCoinsViewCache& inputs); | |
917 | ||
072099d7 S |
918 | /** Return a CMutableTransaction with contextual default values based on set of consensus rules at height */ |
919 | CMutableTransaction CreateNewContextualCMutableTransaction(const Consensus::Params& consensusParams, int nHeight); | |
e079f010 | 920 | |
093303a8 | 921 | #endif // BITCOIN_MAIN_H |