Line data Source code
1 : // Copyright (c) 2009-2010 Satoshi Nakamoto
2 : // Copyright (c) 2009-2014 The Bitcoin Core developers
3 : // Distributed under the MIT software license, see the accompanying
4 : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 :
6 : #ifndef BITCOIN_MAIN_H
7 : #define BITCOIN_MAIN_H
8 :
9 : #if defined(HAVE_CONFIG_H)
10 : #include "config/bitcoin-config.h"
11 : #endif
12 :
13 : #include "amount.h"
14 : #include "chain.h"
15 : #include "coins.h"
16 : #include "net.h"
17 : #include "script/script_error.h"
18 : #include "sync.h"
19 :
20 : #include <algorithm>
21 : #include <exception>
22 : #include <map>
23 : #include <set>
24 : #include <stdint.h>
25 : #include <string>
26 : #include <utility>
27 : #include <vector>
28 :
29 : #include <boost/unordered_map.hpp>
30 :
31 : class CBlockIndex;
32 : class CBlockTreeDB;
33 : class CBloomFilter;
34 : class CInv;
35 : class CScriptCheck;
36 : class CTxMemPool;
37 : class CValidationInterface;
38 : class CValidationState;
39 :
40 : struct CNodeStateStats;
41 :
42 : /** Default for accepting alerts from the P2P network. */
43 : static const bool DEFAULT_ALERTS = true;
44 : /** Default for -maxorphantx, maximum number of orphan transactions kept in memory */
45 : static const unsigned int DEFAULT_MAX_ORPHAN_TRANSACTIONS = 100;
46 : /** Default for -limitancestorcount, max number of in-mempool ancestors */
47 : static const unsigned int DEFAULT_ANCESTOR_LIMIT = 100;
48 : /** Default for -limitancestorsize, maximum kilobytes of tx + all in-mempool ancestors */
49 : static const unsigned int DEFAULT_ANCESTOR_SIZE_LIMIT = 900;
50 : /** Default for -limitdescendantcount, max number of in-mempool descendants */
51 : static const unsigned int DEFAULT_DESCENDANT_LIMIT = 1000;
52 : /** Default for -limitdescendantsize, maximum kilobytes of in-mempool descendants */
53 : static const unsigned int DEFAULT_DESCENDANT_SIZE_LIMIT = 2500;
54 : /** The maximum size of a blk?????.dat file (since 0.8) */
55 : static const unsigned int MAX_BLOCKFILE_SIZE = 0x8000000; // 128 MiB
56 : /** The pre-allocation chunk size for blk?????.dat files (since 0.8) */
57 : static const unsigned int BLOCKFILE_CHUNK_SIZE = 0x1000000; // 16 MiB
58 : /** The pre-allocation chunk size for rev?????.dat files (since 0.8) */
59 : static const unsigned int UNDOFILE_CHUNK_SIZE = 0x100000; // 1 MiB
60 : /** Maximum number of script-checking threads allowed */
61 : static const int MAX_SCRIPTCHECK_THREADS = 16;
62 : /** -par default (number of script-checking threads, 0 = auto) */
63 : static const int DEFAULT_SCRIPTCHECK_THREADS = 0;
64 : /** Number of blocks that can be requested at any given time from a single peer. */
65 : static const int MAX_BLOCKS_IN_TRANSIT_PER_PEER = 16;
66 : /** Timeout in seconds during which a peer must stall block download progress before being disconnected. */
67 : static const unsigned int BLOCK_STALLING_TIMEOUT = 2;
68 : /** Number of headers sent in one getheaders result. We rely on the assumption that if a peer sends
69 : * less than this number, we reached its tip. Changing this value is a protocol upgrade. */
70 : static const unsigned int MAX_HEADERS_RESULTS = 2000;
71 : /** Size of the "block download window": how far ahead of our current height do we fetch?
72 : * Larger windows tolerate larger download speed differences between peer, but increase the potential
73 : * degree of disordering of blocks on disk (which make reindexing and in the future perhaps pruning
74 : * harder). We'll probably want to make this a per-peer adaptive value at some point. */
75 : static const unsigned int BLOCK_DOWNLOAD_WINDOW = 1024;
76 : /** Time to wait (in seconds) between writing blocks/block index to disk. */
77 : static const unsigned int DATABASE_WRITE_INTERVAL = 60 * 60;
78 : /** Time to wait (in seconds) between flushing chainstate to disk. */
79 : static const unsigned int DATABASE_FLUSH_INTERVAL = 24 * 60 * 60;
80 : /** Maximum length of reject messages. */
81 : static const unsigned int MAX_REJECT_MESSAGE_LENGTH = 111;
82 :
83 : struct BlockHasher
84 : {
85 0 : size_t operator()(const uint256& hash) const { return hash.GetCheapHash(); }
86 : };
87 :
88 : extern CScript COINBASE_FLAGS;
89 : extern CCriticalSection cs_main;
90 : extern CTxMemPool mempool;
91 : typedef boost::unordered_map<uint256, CBlockIndex*, BlockHasher> BlockMap;
92 : extern BlockMap mapBlockIndex;
93 : extern uint64_t nLastBlockTx;
94 : extern uint64_t nLastBlockSize;
95 : extern const std::string strMessageMagic;
96 : extern CWaitableCriticalSection csBestBlock;
97 : extern CConditionVariable cvBlockChange;
98 : extern bool fImporting;
99 : extern bool fReindex;
100 : extern int nScriptCheckThreads;
101 : extern bool fTxIndex;
102 : extern bool fIsBareMultisigStd;
103 : extern bool fRequireStandard;
104 : extern bool fCheckBlockIndex;
105 : extern bool fCheckpointsEnabled;
106 : extern size_t nCoinCacheUsage;
107 : extern CFeeRate minRelayTxFee;
108 : extern bool fAlerts;
109 :
110 : /** Best header we've seen so far (used for getheaders queries' starting points). */
111 : extern CBlockIndex *pindexBestHeader;
112 :
113 : /** Minimum disk space required - used in CheckDiskSpace() */
114 : static const uint64_t nMinDiskSpace = 52428800;
115 :
116 : /** Pruning-related variables and constants */
117 : /** True if any block files have ever been pruned. */
118 : extern bool fHavePruned;
119 : /** True if we're running in -prune mode. */
120 : extern bool fPruneMode;
121 : /** Number of MiB of block files that we're trying to stay below. */
122 : extern uint64_t nPruneTarget;
123 : /** Block files containing a block-height within MIN_BLOCKS_TO_KEEP of chainActive.Tip() will not be pruned. */
124 : static const unsigned int MIN_BLOCKS_TO_KEEP = 288;
125 :
126 : // Require that user allocate at least 550MB for block & undo files (blk???.dat and rev???.dat)
127 : // At 1MB per block, 288 blocks = 288MB.
128 : // Add 15% for Undo data = 331MB
129 : // Add 20% for Orphan block rate = 397MB
130 : // We want the low water mark after pruning to be at least 397 MB and since we prune in
131 : // full block file chunks, we need the high water mark which triggers the prune to be
132 : // one 128MB block file + added 15% undo data = 147MB greater for a total of 545MB
133 : // Setting the target to > than 550MB will make it likely we can respect the target.
134 : static const uint64_t MIN_DISK_SPACE_FOR_BLOCK_FILES = 550 * 1024 * 1024;
135 :
136 : /** Register with a network node to receive its signals */
137 : void RegisterNodeSignals(CNodeSignals& nodeSignals);
138 : /** Unregister a network node */
139 : void UnregisterNodeSignals(CNodeSignals& nodeSignals);
140 :
141 : /**
142 : * Process an incoming block. This only returns after the best known valid
143 : * block is made active. Note that it does not, however, guarantee that the
144 : * specific block passed to it has been checked for validity!
145 : *
146 : * @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.
147 : * @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.
148 : * @param[in] pblock The block we want to process.
149 : * @param[in] fForceProcessing Process this block even if unrequested; used for non-network block sources and whitelisted peers.
150 : * @param[out] dbp If pblock is stored to disk (or already there), this will be set to its location.
151 : * @return True if state.IsValid()
152 : */
153 : bool ProcessNewBlock(CValidationState &state, const CNode* pfrom, const CBlock* pblock, bool fForceProcessing, CDiskBlockPos *dbp);
154 : /** Check whether enough disk space is available for an incoming block */
155 : bool CheckDiskSpace(uint64_t nAdditionalBytes = 0);
156 : /** Open a block file (blk?????.dat) */
157 : FILE* OpenBlockFile(const CDiskBlockPos &pos, bool fReadOnly = false);
158 : /** Open an undo file (rev?????.dat) */
159 : FILE* OpenUndoFile(const CDiskBlockPos &pos, bool fReadOnly = false);
160 : /** Translation to a filesystem path */
161 : boost::filesystem::path GetBlockPosFilename(const CDiskBlockPos &pos, const char *prefix);
162 : /** Import blocks from an external file */
163 : bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp = NULL);
164 : /** Initialize a new block tree database + block data on disk */
165 : bool InitBlockIndex();
166 : /** Load the block tree and coins database from disk */
167 : bool LoadBlockIndex();
168 : /** Unload database information */
169 : void UnloadBlockIndex();
170 : /** Process protocol messages received from a given node */
171 : bool ProcessMessages(CNode* pfrom);
172 : /**
173 : * Send queued protocol messages to be sent to a give node.
174 : *
175 : * @param[in] pto The node which we are sending messages to.
176 : * @param[in] fSendTrickle When true send the trickled data, otherwise trickle the data until true.
177 : */
178 : bool SendMessages(CNode* pto, bool fSendTrickle);
179 : /** Run an instance of the script checking thread */
180 : void ThreadScriptCheck();
181 : /** Try to detect Partition (network isolation) attacks against us */
182 : void PartitionCheck(bool (*initialDownloadCheck)(), CCriticalSection& cs, const CBlockIndex *const &bestHeader, int64_t nPowTargetSpacing);
183 : /** Check whether we are doing an initial block download (synchronizing from disk or network) */
184 : bool IsInitialBlockDownload();
185 : /** Format a string that describes several potential problems detected by the core */
186 : std::string GetWarnings(const std::string& strFor);
187 : /** Retrieve a transaction (from memory pool, or from disk, if possible) */
188 : bool GetTransaction(const uint256 &hash, CTransaction &tx, uint256 &hashBlock, bool fAllowSlow = false);
189 : /** Find the best known block, and make it the tip of the block chain */
190 : bool ActivateBestChain(CValidationState &state, const CBlock *pblock = NULL);
191 : CAmount GetBlockSubsidy(int nHeight, const Consensus::Params& consensusParams);
192 :
193 : /**
194 : * Prune block and undo files (blk???.dat and undo???.dat) so that the disk space used is less than a user-defined target.
195 : * The user sets the target (in MB) on the command line or in config file. This will be run on startup and whenever new
196 : * space is allocated in a block or undo file, staying below the target. Changing back to unpruned requires a reindex
197 : * (which in this case means the blockchain must be re-downloaded.)
198 : *
199 : * Pruning functions are called from FlushStateToDisk when the global fCheckForPruning flag has been set.
200 : * Block and undo files are deleted in lock-step (when blk00003.dat is deleted, so is rev00003.dat.)
201 : * Pruning cannot take place until the longest chain is at least a certain length (100000 on mainnet, 1000 on testnet, 10 on regtest).
202 : * Pruning will never delete a block within a defined distance (currently 288) from the active chain's tip.
203 : * The block index is updated by unsetting HAVE_DATA and HAVE_UNDO for any blocks that were stored in the deleted files.
204 : * A db flag records the fact that at least some block files have been pruned.
205 : *
206 : * @param[out] setFilesToPrune The set of file indices that can be unlinked will be returned
207 : */
208 : void FindFilesToPrune(std::set<int>& setFilesToPrune);
209 :
210 : /**
211 : * Actually unlink the specified files
212 : */
213 : void UnlinkPrunedFiles(std::set<int>& setFilesToPrune);
214 :
215 : /** Create a new block index entry for a given block hash */
216 : CBlockIndex * InsertBlockIndex(uint256 hash);
217 : /** Get statistics from node state */
218 : bool GetNodeStateStats(NodeId nodeid, CNodeStateStats &stats);
219 : /** Increase a node's misbehavior score. */
220 : void Misbehaving(NodeId nodeid, int howmuch);
221 : /** Flush all state, indexes and buffers to disk. */
222 : void FlushStateToDisk();
223 : /** Prune block files and flush state to disk. */
224 : void PruneAndFlush();
225 :
226 : /** (try to) add transaction to memory pool **/
227 : bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree,
228 : bool* pfMissingInputs, bool fRejectAbsurdFee=false);
229 :
230 :
231 1614 : struct CNodeStateStats {
232 : int nMisbehavior;
233 : int nSyncHeight;
234 : int nCommonHeight;
235 : std::vector<int> vHeightInFlight;
236 : };
237 :
238 : struct CDiskTxPos : public CDiskBlockPos
239 : {
240 : unsigned int nTxOffset; // after header
241 :
242 221 : ADD_SERIALIZE_METHODS;
243 :
244 : template <typename Stream, typename Operation>
245 221 : inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
246 221 : READWRITE(*(CDiskBlockPos*)this);
247 221 : READWRITE(VARINT(nTxOffset));
248 221 : }
249 :
250 13618 : CDiskTxPos(const CDiskBlockPos &blockIn, unsigned int nTxOffsetIn) : CDiskBlockPos(blockIn.nFile, blockIn.nPos), nTxOffset(nTxOffsetIn) {
251 0 : }
252 :
253 1 : CDiskTxPos() {
254 : SetNull();
255 0 : }
256 :
257 : void SetNull() {
258 1 : CDiskBlockPos::SetNull();
259 1 : nTxOffset = 0;
260 : }
261 : };
262 :
263 :
264 : CAmount GetMinRelayFee(const CTransaction& tx, unsigned int nBytes, bool fAllowFree);
265 :
266 : /**
267 : * Count ECDSA signature operations the old-fashioned (pre-0.6) way
268 : * @return number of sigops this transaction's outputs will produce when spent
269 : * @see CTransaction::FetchInputs
270 : */
271 : unsigned int GetLegacySigOpCount(const CTransaction& tx);
272 :
273 : /**
274 : * Count ECDSA signature operations in pay-to-script-hash inputs.
275 : *
276 : * @param[in] mapInputs Map of previous transactions that have outputs we're spending
277 : * @return maximum number of sigops required to validate this transaction's inputs
278 : * @see CTransaction::FetchInputs
279 : */
280 : unsigned int GetP2SHSigOpCount(const CTransaction& tx, const CCoinsViewCache& mapInputs);
281 :
282 :
283 : /**
284 : * Check whether all inputs of this transaction are valid (no double spends, scripts & sigs, amounts)
285 : * This does not modify the UTXO set. If pvChecks is not NULL, script checks are pushed onto it
286 : * instead of being performed inline.
287 : */
288 : bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsViewCache &view, bool fScriptChecks,
289 : unsigned int flags, bool cacheStore, std::vector<CScriptCheck> *pvChecks = NULL);
290 :
291 : /** Apply the effects of this transaction on the UTXO set represented by view */
292 : void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCache &inputs, int nHeight);
293 :
294 : /** Context-independent validity checks */
295 : bool CheckTransaction(const CTransaction& tx, CValidationState& state);
296 :
297 : /**
298 : * Check if transaction is final and can be included in a block with the
299 : * specified height and time. Consensus critical.
300 : */
301 : bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime);
302 :
303 : /**
304 : * Check if transaction will be final in the next block to be created.
305 : *
306 : * Calls IsFinalTx() with current block height and appropriate block time.
307 : */
308 : bool CheckFinalTx(const CTransaction &tx);
309 :
310 : /**
311 : * Closure representing one script verification
312 : * Note that this stores references to the spending transaction
313 : */
314 67251 : class CScriptCheck
315 : {
316 : private:
317 : CScript scriptPubKey;
318 : const CTransaction *ptxTo;
319 : unsigned int nIn;
320 : unsigned int nFlags;
321 : bool cacheStore;
322 : ScriptError error;
323 :
324 : public:
325 13112 : CScriptCheck(): ptxTo(0), nIn(0), nFlags(0), cacheStore(false), error(SCRIPT_ERR_UNKNOWN_ERROR) {}
326 5916 : CScriptCheck(const CCoins& txFromIn, const CTransaction& txToIn, unsigned int nInIn, unsigned int nFlagsIn, bool cacheIn) :
327 11832 : scriptPubKey(txFromIn.vout[txToIn.vin[nInIn].prevout.n].scriptPubKey),
328 11832 : ptxTo(&txToIn), nIn(nInIn), nFlags(nFlagsIn), cacheStore(cacheIn), error(SCRIPT_ERR_UNKNOWN_ERROR) { }
329 :
330 : bool operator()();
331 :
332 7451 : void swap(CScriptCheck &check) {
333 7451 : scriptPubKey.swap(check.scriptPubKey);
334 7451 : std::swap(ptxTo, check.ptxTo);
335 7451 : std::swap(nIn, check.nIn);
336 7451 : std::swap(nFlags, check.nFlags);
337 7451 : std::swap(cacheStore, check.cacheStore);
338 7451 : std::swap(error, check.error);
339 7451 : }
340 :
341 0 : ScriptError GetScriptError() const { return error; }
342 : };
343 :
344 :
345 : /** Functions for disk access for blocks */
346 : bool WriteBlockToDisk(const CBlock& block, CDiskBlockPos& pos, const CMessageHeader::MessageStartChars& messageStart);
347 : bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos);
348 : bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex);
349 :
350 :
351 : /** Functions for validating blocks and updating the block tree */
352 :
353 : /** Undo the effects of this block (with given index) on the UTXO set represented by coins.
354 : * In case pfClean is provided, operation will try to be tolerant about errors, and *pfClean
355 : * will be true if no problems were found. Otherwise, the return value will be false in case
356 : * of problems. Note that in any case, coins may be modified. */
357 : bool DisconnectBlock(const CBlock& block, CValidationState& state, const CBlockIndex* pindex, CCoinsViewCache& coins, bool* pfClean = NULL);
358 :
359 : /** Apply the effects of this block (with given index) on the UTXO set represented by coins */
360 : bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& coins, bool fJustCheck = false);
361 :
362 : /** Context-independent validity checks */
363 : bool CheckBlockHeader(const CBlockHeader& block, CValidationState& state, bool fCheckPOW = true);
364 : bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW = true, bool fCheckMerkleRoot = true);
365 :
366 : /** Context-dependent validity checks */
367 : bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex *pindexPrev);
368 : bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIndex *pindexPrev);
369 :
370 : /** Check a block is completely valid from start to finish (only works on top of our current best block, with cs_main held) */
371 : bool TestBlockValidity(CValidationState &state, const CBlock& block, CBlockIndex *pindexPrev, bool fCheckPOW = true, bool fCheckMerkleRoot = true);
372 :
373 : /** Store block on disk. If dbp is non-NULL, the file is known to already reside on disk */
374 : bool AcceptBlock(const CBlock& block, CValidationState& state, CBlockIndex **pindex, bool fRequested, CDiskBlockPos* dbp);
375 : bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex **ppindex= NULL);
376 :
377 :
378 :
379 : class CBlockFileInfo
380 : {
381 : public:
382 : unsigned int nBlocks; //! number of blocks stored in file
383 : unsigned int nSize; //! number of used bytes of block file
384 : unsigned int nUndoSize; //! number of used bytes in the undo file
385 : unsigned int nHeightFirst; //! lowest height of block in file
386 : unsigned int nHeightLast; //! highest height of block in file
387 : uint64_t nTimeFirst; //! earliest time of block in file
388 : uint64_t nTimeLast; //! latest time of block in file
389 :
390 313 : ADD_SERIALIZE_METHODS;
391 :
392 : template <typename Stream, typename Operation>
393 313 : inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
394 313 : READWRITE(VARINT(nBlocks));
395 313 : READWRITE(VARINT(nSize));
396 313 : READWRITE(VARINT(nUndoSize));
397 313 : READWRITE(VARINT(nHeightFirst));
398 313 : READWRITE(VARINT(nHeightLast));
399 313 : READWRITE(VARINT(nTimeFirst));
400 313 : READWRITE(VARINT(nTimeLast));
401 313 : }
402 :
403 : void SetNull() {
404 212 : nBlocks = 0;
405 212 : nSize = 0;
406 212 : nUndoSize = 0;
407 212 : nHeightFirst = 0;
408 212 : nHeightLast = 0;
409 212 : nTimeFirst = 0;
410 212 : nTimeLast = 0;
411 : }
412 :
413 0 : CBlockFileInfo() {
414 : SetNull();
415 0 : }
416 :
417 : std::string ToString() const;
418 :
419 : /** update statistics (does not update nSize) */
420 5518 : void AddBlock(unsigned int nHeightIn, uint64_t nTimeIn) {
421 5518 : if (nBlocks==0 || nHeightFirst > nHeightIn)
422 62 : nHeightFirst = nHeightIn;
423 5518 : if (nBlocks==0 || nTimeFirst > nTimeIn)
424 62 : nTimeFirst = nTimeIn;
425 5518 : nBlocks++;
426 5518 : if (nHeightIn > nHeightLast)
427 4703 : nHeightLast = nHeightIn;
428 5518 : if (nTimeIn > nTimeLast)
429 1880 : nTimeLast = nTimeIn;
430 5518 : }
431 : };
432 :
433 : /** RAII wrapper for VerifyDB: Verify consistency of the block and coin databases */
434 : class CVerifyDB {
435 : public:
436 : CVerifyDB();
437 : ~CVerifyDB();
438 : bool VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth);
439 : };
440 :
441 : /** Find the last common block between the parameter chain and a locator. */
442 : CBlockIndex* FindForkInGlobalIndex(const CChain& chain, const CBlockLocator& locator);
443 :
444 : /** Mark a block as invalid. */
445 : bool InvalidateBlock(CValidationState& state, CBlockIndex *pindex);
446 :
447 : /** Remove invalidity status from a block and its descendants. */
448 : bool ReconsiderBlock(CValidationState& state, CBlockIndex *pindex);
449 :
450 : /** The currently-connected chain of blocks. */
451 : extern CChain chainActive;
452 :
453 : /** Global variable that points to the active CCoinsView (protected by cs_main) */
454 : extern CCoinsViewCache *pcoinsTip;
455 :
456 : /** Global variable that points to the active block tree (protected by cs_main) */
457 : extern CBlockTreeDB *pblocktree;
458 :
459 : /**
460 : * Return the spend height, which is one more than the inputs.GetBestBlock().
461 : * While checking, GetBestBlock() refers to the parent block. (protected by cs_main)
462 : * This is also true for mempool checks.
463 : */
464 : int GetSpendHeight(const CCoinsViewCache& inputs);
465 :
466 : /** Reject codes greater or equal to this can be returned by AcceptToMemPool
467 : * for transactions, to signal internal conditions. They cannot and should not
468 : * be sent over the P2P network.
469 : */
470 : static const unsigned int REJECT_INTERNAL = 0x100;
471 : /** Too high fee. Can not be triggered by P2P transactions */
472 : static const unsigned int REJECT_HIGHFEE = 0x100;
473 : /** Transaction is already known (either in mempool or blockchain) */
474 : static const unsigned int REJECT_ALREADY_KNOWN = 0x101;
475 : /** Transaction conflicts with a transaction already known */
476 : static const unsigned int REJECT_CONFLICT = 0x102;
477 :
478 : #endif // BITCOIN_MAIN_H
|