2017-11-09 19:34:51 +01:00
/*
* This file is part of the Flowee project
* Copyright (C) 2009-2010 Satoshi Nakamoto
* Copyright (C) 2009-2015 The Bitcoin Core developers
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
2013-04-13 00:13:08 -05:00
2018-01-16 10:47:52 +00:00
# ifndef FLOWEE_MAIN_H
# define FLOWEE_MAIN_H
2011-05-15 09:11:04 +02:00
2013-05-27 19:55:01 -04:00
# if defined(HAVE_CONFIG_H)
2018-01-16 10:47:52 +00:00
# include "config/flowee-config.h"
2013-05-27 19:55:01 -04:00
# endif
2014-10-23 02:05:11 +02:00
# include "amount.h"
2014-09-03 02:20:09 +02:00
# include "chain.h"
2015-01-24 15:29:29 +01:00
# include "net.h"
2015-07-05 14:17:46 +02:00
# include "script/script_error.h"
2013-04-13 00:13:08 -05:00
# include "sync.h"
2011-05-15 09:11:04 +02:00
2013-04-13 00:13:08 -05:00
# include <algorithm>
# include <exception>
# include <map>
# include <set>
2017-08-17 20:53:23 -06:00
# include <cstdint>
2013-04-13 00:13:08 -05:00
# include <string>
# include <utility>
# include <vector>
2010-08-29 16:58:15 +00:00
2016-01-22 11:03:50 -05:00
# include <boost/atomic.hpp>
2014-09-04 02:03:17 +02:00
# include <boost/unordered_map.hpp>
2020-04-11 18:35:43 +02:00
# include <script/interpreter.h>
2010-08-29 16:58:15 +00:00
class CBlockIndex ;
2013-04-13 00:13:08 -05:00
class CBloomFilter ;
2015-04-20 00:17:11 +02:00
class CChainParams ;
2011-05-14 16:20:30 -05:00
class CInv ;
2014-10-31 09:36:30 +01:00
class CScriptCheck ;
2015-07-05 14:30:07 +02:00
class CTxMemPool ;
2018-02-15 18:06:38 +01:00
class ValidationInterface ;
2014-10-31 09:36:30 +01:00
class CValidationState ;
2020-02-27 13:35:56 +01:00
class UnspentOutputDatabase ;
2014-10-31 09:36:30 +01:00
struct CNodeStateStats ;
2015-12-04 15:01:22 -05:00
struct LockPoints ;
2021-11-02 09:59:13 +01:00
struct CBlockLocator ;
2011-05-14 16:20:30 -05:00
2014-01-10 13:23:26 +01:00
/** Number of blocks that can be requested at any given time from a single peer. */
2014-07-12 00:02:35 +02:00
static const int MAX_BLOCKS_IN_TRANSIT_PER_PEER = 16 ;
/** Timeout in seconds during which a peer must stall block download progress before being disconnected. */
2019-05-26 13:28:35 +02:00
static const unsigned int BLOCK_STALLING_TIMEOUT = 6 ;
2014-07-12 00:02:35 +02:00
/** Number of headers sent in one getheaders result. We rely on the assumption that if a peer sends
2015-04-28 14:48:28 +00:00
* less than this number, we reached its tip. Changing this value is a protocol upgrade. */
2014-07-12 00:02:35 +02:00
static const unsigned int MAX_HEADERS_RESULTS = 2000 ;
/** Size of the "block download window": how far ahead of our current height do we fetch?
* Larger windows tolerate larger download speed differences between peer, but increase the potential
* degree of disordering of blocks on disk (which make reindexing and in the future perhaps pruning
* harder). We'll probably want to make this a per-peer adaptive value at some point. */
static const unsigned int BLOCK_DOWNLOAD_WINDOW = 1024 ;
2015-05-04 22:00:19 +02:00
/** Time to wait (in seconds) between writing blocks/block index to disk. */
static const unsigned int DATABASE_WRITE_INTERVAL = 60 * 60 ;
/** Time to wait (in seconds) between flushing chainstate to disk. */
static const unsigned int DATABASE_FLUSH_INTERVAL = 24 * 60 * 60 ;
2014-11-29 16:01:37 +01:00
/** Maximum length of reject messages. */
static const unsigned int MAX_REJECT_MESSAGE_LENGTH = 111 ;
2015-04-08 11:20:00 -07:00
/** Average delay between local address broadcasts in seconds. */
static const unsigned int AVG_LOCAL_ADDRESS_BROADCAST_INTERVAL = 24 * 24 * 60 ;
/** Average delay between peer address broadcasts in seconds. */
static const unsigned int AVG_ADDRESS_BROADCAST_INTERVAL = 30 ;
/** Average delay between trickled inventory broadcasts in seconds.
* Blocks, whitelisted receivers, and a random 25% of transactions bypass this. */
static const unsigned int AVG_INVENTORY_BROADCAST_INTERVAL = 5 ;
2016-04-07 13:18:11 +02:00
/** Block download timeout base, expressed in millionths of the block interval (i.e. 10 min) */
static const int64_t BLOCK_DOWNLOAD_TIMEOUT_BASE = 1000000 ;
2016-04-03 15:24:09 +02:00
/** Additional block download timeout per parallel downloading peer (i.e. 5 min) */
static const int64_t BLOCK_DOWNLOAD_TIMEOUT_PER_PEER = 500000 ;
2015-04-08 11:20:00 -07:00
2014-11-18 22:16:32 +01:00
/** Maximum number of headers to announce when relaying blocks with headers message.*/
static const unsigned int MAX_BLOCKS_TO_ANNOUNCE = 8 ;
2010-08-29 16:58:15 +00:00
extern CCriticalSection cs_main ;
2013-08-27 15:51:57 +10:00
extern CTxMemPool mempool ;
2013-04-13 00:13:08 -05:00
extern uint64_t nLastBlockTx ;
extern uint64_t nLastBlockSize ;
2011-12-23 10:14:57 -05:00
extern const std : : string strMessageMagic ;
2012-05-13 04:43:24 +00:00
extern CWaitableCriticalSection csBestBlock ;
extern CConditionVariable cvBlockChange ;
2014-07-16 20:04:04 -04:00
extern bool fIsBareMultisigStd ;
2015-06-24 03:36:22 +00:00
extern bool fRequireStandard ;
2015-04-22 23:22:36 -04:00
extern bool fCheckpointsEnabled ;
2014-07-03 14:25:32 -04:00
extern CFeeRate minRelayTxFee ;
2010-08-29 16:58:15 +00:00
2016-01-15 21:37:25 -08:00
// Xpress Validation: begin section
/**
* Transactions that have already been accepted into the memory pool do not need to be
2016-04-25 14:36:03 +01:00
* re-verified and can avoid having to do a second and expensive CheckInputs() when
2016-01-15 21:37:25 -08:00
* processing a new block. (Protected by cs_main)
*/
static std : : set < uint256 > setPreVerifiedTxHash ;
2016-03-05 11:08:23 -08:00
/**
* Orphans that are added to the thinblock must be verifed since they have never been
* accepted into the memory pool.
*/
static std : : set < uint256 > setUnVerifiedOrphanTxHash ;
// BU - Xpress Validation: end section
2016-01-15 21:37:25 -08:00
2014-12-01 09:39:44 +08:00
/** Best header we've seen so far (used for getheaders queries' starting points). */
2014-07-12 00:03:10 +02:00
extern CBlockIndex * pindexBestHeader ;
2014-12-01 09:39:44 +08:00
/** Minimum disk space required - used in CheckDiskSpace() */
2013-04-13 00:13:08 -05:00
static const uint64_t nMinDiskSpace = 52428800 ;
2010-08-29 16:58:15 +00:00
2013-06-05 20:21:41 -07:00
/** Register with a network node to receive its signals */
void RegisterNodeSignals ( CNodeSignals & nodeSignals ) ;
/** Unregister a network node */
void UnregisterNodeSignals ( CNodeSignals & nodeSignals ) ;
2014-12-01 09:39:44 +08:00
/**
* Process an incoming block. This only returns after the best known valid
* block is made active. Note that it does not, however, guarantee that the
* specific block passed to it has been checked for validity!
*
2015-02-05 01:11:44 +01:00
* @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.
2014-12-01 09:39:44 +08:00
* @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.
* @param[in] pblock The block we want to process.
2015-04-09 13:21:11 -04:00
* @param[in] fForceProcessing Process this block even if unrequested; used for non-network block sources and whitelisted peers.
2014-12-01 09:39:44 +08:00
* @param[out] dbp If pblock is stored to disk (or already there), this will be set to its location.
* @return True if state.IsValid()
*/
2021-11-02 09:36:09 +01:00
bool ProcessNewBlock ( CValidationState & state , const CChainParams & chainparams , const CNode * pfrom , const MutableBlock * pblock , bool fForceProcessing , CDiskBlockPos * dbp ) ;
2012-11-04 13:18:04 +01:00
/** Check whether enough disk space is available for an incoming block */
2013-04-13 00:13:08 -05:00
bool CheckDiskSpace ( uint64_t nAdditionalBytes = 0 ) ;
2013-01-30 21:43:36 +01:00
/** Initialize a new block tree database + block data on disk */
2015-04-17 14:40:24 +02:00
bool InitBlockIndex ( const CChainParams & chainparams ) ;
2012-11-04 13:18:04 +01:00
/** Load the block tree and coins database from disk */
2020-02-27 13:35:56 +01:00
bool LoadBlockIndexDB ( const UnspentOutputDatabase * utxo ) ;
2013-02-16 17:58:45 +01:00
/** Unload database information */
void UnloadBlockIndex ( ) ;
2012-11-04 13:18:04 +01:00
/** Process protocol messages received from a given node */
2010-08-29 16:58:15 +00:00
bool ProcessMessages ( CNode * pfrom ) ;
2015-03-24 14:29:13 +01:00
/**
* Send queued protocol messages to be sent to a give node.
*
* @param[in] pto The node which we are sending messages to.
*/
2015-04-08 11:20:00 -07:00
bool SendMessages ( CNode * pto ) ;
2012-12-17 18:09:53 +08:00
/** Check whether we are doing an initial block download (synchronizing from disk or network) */
2010-08-29 16:58:15 +00:00
bool IsInitialBlockDownload ( ) ;
2015-12-01 09:47:13 +01:00
/** Format a string that describes several potential problems detected by the core.
* strFor can have three values:
* - "rpc": get critical warnings, which should put the client in safe mode if non-empty
* - "statusbar": get all warnings
* - "gui": get all warnings, translated (where possible) for GUI
* This function only returns the highest priority warning of the set selected by strFor.
*/
2015-05-31 15:36:44 +02:00
std : : string GetWarnings ( const std : : string & strFor ) ;
2012-11-04 13:18:04 +01:00
/** Find the best known block, and make it the tip of the block chain */
2021-01-20 19:21:53 +01:00
int64_t GetBlockSubsidy ( int nHeight , const Consensus : : Params & consensusParams ) ;
2013-01-08 14:58:06 -08:00
2018-01-15 15:26:12 +00:00
bool MarkBlockAsReceived ( const uint256 & hash ) ;
bool IsBlockInFlight ( const uint256 & hash ) ;
2013-11-18 01:25:17 +01:00
/** Get statistics from node state */
bool GetNodeStateStats ( NodeId nodeid , CNodeStateStats & stats ) ;
2014-01-10 13:23:26 +01:00
/** Increase a node's misbehavior score. */
void Misbehaving ( NodeId nodeid , int howmuch ) ;
2014-11-07 02:38:35 -08:00
/** Flush all state, indexes and buffers to disk. */
void FlushStateToDisk ( ) ;
2012-08-19 00:33:01 +02:00
2018-01-15 15:26:12 +00:00
void queueRejectMessage ( int peerId , const uint256 & blockHash , std : : uint8_t rejectCode , const std : : string & rejectReason ) ;
class CBlockUndo ;
bool UndoWriteToDisk ( const CBlockUndo & blockundo , CDiskBlockPos & pos , const uint256 & hashBlock , const CMessageHeader : : MessageStartChars & messageStart ) ;
2013-08-27 15:51:57 +10:00
/** (try to) add transaction to memory pool **/
bool AcceptToMemoryPool ( CTxMemPool & pool , CValidationState & state , const CTransaction & tx , bool fLimitFree ,
2015-10-02 14:20:38 -07:00
bool * pfMissingInputs , bool fOverrideMempoolLimit = false , bool fRejectAbsurdFee = false ) ;
2018-01-15 15:26:12 +00:00
void AlertNotify ( const std : : string & strMessage , bool fThread ) ;
2010-08-29 16:58:15 +00:00
2013-11-18 01:25:17 +01:00
struct CNodeStateStats {
int nMisbehavior ;
2014-06-23 00:00:26 +02:00
int nSyncHeight ;
2014-07-12 00:03:10 +02:00
int nCommonHeight ;
std : : vector < int > vHeightInFlight ;
2013-11-18 01:25:17 +01:00
} ;
2013-01-11 01:47:57 +01:00
struct CDiskTxPos : public CDiskBlockPos
{
unsigned int nTxOffset ; // after header
2010-08-29 16:58:15 +00:00
2017-01-19 21:40:34 +01:00
ADD_SERIALIZE_METHODS
2014-08-20 08:42:31 +02:00
2014-08-20 22:44:38 +02:00
template < typename Stream , typename Operation >
2014-08-21 00:49:32 +02:00
inline void SerializationOp ( Stream & s , Operation ser_action , int nType , int nVersion ) {
2013-01-11 01:47:57 +01:00
READWRITE ( * ( CDiskBlockPos * ) this ) ;
READWRITE ( VARINT ( nTxOffset ) ) ;
2014-08-20 08:42:31 +02:00
}
2013-01-11 01:47:57 +01:00
CDiskTxPos ( const CDiskBlockPos & blockIn , unsigned int nTxOffsetIn ) : CDiskBlockPos ( blockIn . nFile , blockIn . nPos ) , nTxOffset ( nTxOffsetIn ) {
}
CDiskTxPos ( ) {
SetNull ( ) ;
}
void SetNull ( ) {
CDiskBlockPos : : SetNull ( ) ;
nTxOffset = 0 ;
}
} ;
2010-08-29 16:58:15 +00:00
2015-05-25 00:48:33 -04:00
/**
* Check if transaction is final and can be included in a block with the
* specified height and time. Consensus critical.
*/
2026-04-15 21:35:08 +02:00
bool IsFinalTx ( const Tx & tx , int nBlockHeight , int64_t nBlockTime ) ;
2015-05-25 00:48:33 -04:00
/**
* Check if transaction will be final in the next block to be created.
*
* Calls IsFinalTx() with current block height and appropriate block time.
2015-11-03 17:12:36 +00:00
*
* See consensus/consensus.h for flag definitions.
2015-05-25 00:48:33 -04:00
*/
2026-04-15 21:35:08 +02:00
bool CheckFinalTx ( const Tx & tx , int flags = - 1 ) ;
2012-01-10 20:18:00 -05:00
2015-12-04 15:01:22 -05:00
/**
* Test whether the LockPoints height and time are still valid on the current chain
*/
bool TestLockPointValidity ( const LockPoints * lp ) ;
2015-12-07 15:44:16 -05:00
/**
* Check if transaction is final per BIP 68 sequence numbers and can be included in a block.
* Consensus critical. Takes as input a list of heights at which tx's inputs (in order) confirmed.
*/
bool SequenceLocks ( const CTransaction & tx , int flags , std : : vector < int > * prevHeights , const CBlockIndex & block ) ;
/**
* Check if transaction will be BIP 68 final in the next block to be created.
*
2016-02-11 15:34:04 -05:00
* Simulates calling SequenceLocks() with data from the tip of the current active chain.
2015-12-04 15:01:22 -05:00
* Optionally stores in LockPoints the resulting height and time calculated and the hash
* of the block needed for calculation or skips the calculation and uses the LockPoints
* passed in for evaluation.
* The LockPoints should not be considered valid if CheckSequenceLocks returns false.
2015-12-07 15:44:16 -05:00
*
* See consensus/consensus.h for flag definitions.
*/
2018-01-15 15:26:12 +00:00
bool CheckSequenceLocks ( CTxMemPool & mp , const CTransaction & tx , int flags , LockPoints * lp = nullptr , bool useExistingLockPoints = false , CBlockIndex * tip = nullptr ) ;
2015-12-07 15:44:16 -05:00
2010-08-29 16:58:15 +00:00
2013-06-23 17:35:01 -07:00
/** Functions for disk access for blocks */
2021-11-02 09:36:09 +01:00
bool ReadBlockFromDisk ( MutableBlock & block , const CDiskBlockPos & pos , const Consensus : : Params & consensusParams ) ;
bool ReadBlockFromDisk ( MutableBlock & block , const CBlockIndex * pindex , const Consensus : : Params & consensusParams ) ;
2010-08-29 16:58:15 +00:00
2013-06-23 18:32:58 -07:00
/** Functions for validating blocks and updating the block tree */
2014-12-01 09:39:44 +08:00
/** Context-independent validity checks */
2026-04-15 21:35:08 +02:00
bool CheckBlockHeader ( const BlockHeader & block , CValidationState & state , bool fCheckPOW = true ) ;
2013-06-23 19:14:11 -07:00
2014-12-01 09:39:44 +08:00
/** Check a block is completely valid from start to finish (only works on top of our current best block, with cs_main held) */
2021-11-02 09:36:09 +01:00
bool TestBlockValidity ( CValidationState & state , const CChainParams & chainparams , const MutableBlock & block , CBlockIndex * pindexPrev , bool fCheckPOW = true , bool fCheckMerkleRoot = true ) ;
2014-10-20 02:10:03 +00:00
2018-01-15 15:26:12 +00:00
/** Mark this index as 'dirty' to be saved to disk soon */
2018-01-29 17:35:19 +00:00
void MarkIndexUnsaved ( CBlockIndex * index ) ;
2013-06-23 18:32:58 -07:00
2017-09-03 21:17:27 +02:00
extern CCriticalSection cs_LastBlockFile ;
extern int nLastBlockFile ;
extern std : : set < int > setDirtyFileInfo ;
2014-09-03 02:52:01 +02:00
/** Find the last common block between the parameter chain and a locator. */
CBlockIndex * FindForkInGlobalIndex ( const CChain & chain , const CBlockLocator & locator ) ;
2013-10-10 23:07:44 +02:00
2014-11-19 09:39:42 +01:00
/** Mark a block as invalid. */
2018-01-15 15:26:12 +00:00
// bool InvalidateBlock(CValidationState& state, const Consensus::Params& consensusParams, CBlockIndex *pindex);
2014-11-19 09:39:42 +01:00
/** Remove invalidity status from a block and its descendants. */
2018-01-15 15:26:12 +00:00
// bool ReconsiderBlock(CBlockIndex *pindex);
2014-11-19 09:39:42 +01:00
2015-09-09 16:31:20 -07:00
/** The currently-connected chain of blocks (protected by cs_main). */
2013-10-10 23:07:44 +02:00
extern CChain chainActive ;
2010-08-29 16:58:15 +00:00
2018-07-23 18:05:43 +02:00
class UnspentOutputDatabase ;
extern UnspentOutputDatabase * g_utxo ;
2015-04-24 16:45:16 +02:00
2018-01-15 15:26:12 +00:00
void LimitMempoolSize ( CTxMemPool & pool , size_t limit , unsigned long age ) ;
2015-08-06 09:51:36 +02:00
/** Reject codes greater or equal to this can be returned by AcceptToMemPool
* for transactions, to signal internal conditions. They cannot and should not
* be sent over the P2P network.
*/
static const unsigned int REJECT_INTERNAL = 0x100 ;
/** Too high fee. Can not be triggered by P2P transactions */
2015-03-16 21:36:43 -04:00
static const unsigned int REJECT_HIGHFEE = 0x100 ;
2015-08-06 09:51:36 +02:00
/** Transaction is already known (either in mempool or blockchain) */
static const unsigned int REJECT_ALREADY_KNOWN = 0x101 ;
/** Transaction conflicts with a transaction already known */
static const unsigned int REJECT_CONFLICT = 0x102 ;
2015-03-16 21:36:43 -04:00
2018-01-15 15:26:12 +00:00
enum FlushStateMode {
FLUSH_STATE_NONE ,
FLUSH_STATE_IF_NEEDED ,
FLUSH_STATE_PERIODIC ,
FLUSH_STATE_ALWAYS
} ;
/**
* Update the on-disk chain state.
* The caches and indexes are flushed depending on the mode we're called with
* if they're too large, if it's been a while since the last write,
* or always and in all cases if we're in prune mode and are deleting files.
*/
bool FlushStateToDisk ( CValidationState & state , FlushStateMode mode ) ;
void CheckForkWarningConditions ( ) ;
void CheckForkWarningConditionsOnNewFork ( CBlockIndex * pindexNewForkTip ) ;
2018-01-16 10:47:52 +00:00
# endif