Skip to content

Commit

Permalink
Port net processing
Browse files Browse the repository at this point in the history
  • Loading branch information
timemarkovqtum committed Jun 14, 2024
1 parent b2bad08 commit 2d1d436
Show file tree
Hide file tree
Showing 11 changed files with 727 additions and 33 deletions.
5 changes: 4 additions & 1 deletion src/blockencodings.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ class BlockValidationState;
namespace Consensus {
struct Params;
};
class ChainstateManager;
class Chainstate;

// Transaction compression schemes for compact block relay can be introduced by writing
// an actual formatter here.
Expand Down Expand Up @@ -132,14 +134,15 @@ class PartiallyDownloadedBlock {
std::vector<CTransactionRef> txn_available;
size_t prefilled_count = 0, mempool_count = 0, extra_count = 0;
const CTxMemPool* pool;
const ChainstateManager* chainman;
public:
CBlockHeader header;

// Can be overridden for testing
using CheckBlockFn = std::function<bool(const CBlock&, BlockValidationState&, const Consensus::Params&, bool, bool)>;
CheckBlockFn m_check_block_mock{nullptr};

explicit PartiallyDownloadedBlock(CTxMemPool* poolIn) : pool(poolIn) {}
explicit PartiallyDownloadedBlock(CTxMemPool* poolIn, ChainstateManager* _chainman) : pool(poolIn), chainman(_chainman) {}

// extra_txn is a list of extra transactions to look at, in <witness hash, reference> form
ReadStatus InitData(const CBlockHeaderAndShortTxIDs& cmpctblock, const std::vector<std::pair<uint256, CTransactionRef>>& extra_txn);
Expand Down
10 changes: 8 additions & 2 deletions src/consensus/validation.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ enum class TxValidationResult {
TX_NO_MEMPOOL, //!< this node does not have a mempool so can't validate the transaction
TX_RECONSIDERABLE, //!< fails some policy, but might be acceptable if submitted in a (different) package
TX_UNKNOWN, //!< transaction was not validated because package failed
TX_INVALID_SENDER_SCRIPT, //!< invalid contract sender script, used in the mempool
TX_GAS_EXCEEDS_LIMIT, //!< transaction gas exceeds block gas limit
};

/** A "reason" why a block was invalid, suitable for determining whether the
Expand All @@ -74,13 +76,17 @@ enum class BlockValidationResult {
*/
BLOCK_RECENT_CONSENSUS_CHANGE,
BLOCK_CACHED_INVALID, //!< this block was cached as being invalid and we didn't store the reason why
BLOCK_INVALID_HEADER, //!< invalid proof of work or time too old
BLOCK_INVALID_HEADER, //!< invalid proof of work, proof of stake or time too old
BLOCK_MUTATED, //!< the block's data didn't match the data committed to by the PoW
BLOCK_MISSING_PREV, //!< We don't have the previous block the checked one is built on
BLOCK_INVALID_PREV, //!< A block this one builds on is invalid
BLOCK_TIME_FUTURE, //!< block timestamp was > 2 hours in the future (or our clock is bad)
BLOCK_CHECKPOINT, //!< the block failed to meet one of our checkpoints
BLOCK_HEADER_LOW_WORK //!< the block header may be on a too-little-work chain
BLOCK_HEADER_LOW_WORK, //!< the block header may be on a too-little-work chain
BLOCK_HEADER_SPAM, //!< reject block header from the spam filter
BLOCK_HEADER_REJECT, //!< reject only the block header, but not ban the node
BLOCK_HEADER_SYNC, //!< reject the block header due to synchronization problems, used to punish the node less
BLOCK_GAS_EXCEEDS_LIMIT, //!< transaction gas exceeds block gas limit
};


Expand Down
638 changes: 618 additions & 20 deletions src/net_processing.cpp

Large diffs are not rendered by default.

9 changes: 9 additions & 0 deletions src/net_processing.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,15 @@ class PeerManager : public CValidationInterface, public NetEventsInterface
* we do not have a confirmed set of service flags.
*/
virtual ServiceFlags GetDesirableServiceFlags(ServiceFlags services) const = 0;

/** Initialize clean block index */
virtual void InitCleanBlockIndex() = 0;

/** Stop clean block index thread */
virtual void StopCleanBlockIndex() = 0;
};

/** Default for -headerspamfiltermaxsize, maximum size of the list of indexes in the header spam filter */
unsigned int GefaultHeaderSpamFilterMaxSize();

#endif // BITCOIN_NET_PROCESSING_H
36 changes: 36 additions & 0 deletions src/node/blockstorage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,10 @@ bool BlockTreeDB::LoadBlockIndexGuts(const Consensus::Params& consensusParams, s

return true;
}
bool BlockTreeDB::EraseBlockIndex(const std::vector<uint256> &vect)
{
return {};
}
} // namespace kernel

namespace node {
Expand Down Expand Up @@ -617,6 +621,38 @@ bool BlockManager::CheckBlockDataAvailability(const CBlockIndex& upper_block, co
return GetFirstStoredBlock(upper_block, &lower_block) == &lower_block;
}

bool BlockManager::CheckHardened(int nHeight, const uint256& hash, const CCheckpointData& data)
{
const MapCheckpoints& checkpoints = data.mapCheckpoints;

MapCheckpoints::const_iterator i = checkpoints.find(nHeight);
if (i == checkpoints.end()) return true;
return hash == i->second;
}

// Automatically select a suitable sync-checkpoint
const CBlockIndex* BlockManager::AutoSelectSyncCheckpoint(const CBlockIndex *pindexBest)
{
const CBlockIndex *pindex = pindexBest;
// Search backward for a block within max span and maturity window
int checkpointSpan = GetConsensus().CheckpointSpan(pindexBest->nHeight);
while (pindex->pprev && pindex->nHeight + checkpointSpan > pindexBest->nHeight)
pindex = pindex->pprev;
return pindex;
}

// Check against synchronized checkpoint
bool BlockManager::CheckSync(int nHeight, const CBlockIndex *pindexBest)
{
const CBlockIndex* pindexSync = nullptr;
if(nHeight)
pindexSync = AutoSelectSyncCheckpoint(pindexBest);

if(nHeight && nHeight <= pindexSync->nHeight)
return false;
return true;
}

// If we're using -prune with -reindex, then delete block files that will be ignored by the
// reindex. Since reindexing works by starting at block file 0 and looping until a blockfile
// is missing, do the same here to delete any later block files after a gap. Also delete all
Expand Down
11 changes: 11 additions & 0 deletions src/node/blockstorage.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ class BlockTreeDB : public CDBWrapper
bool ReadFlag(const std::string& name, bool& fValue);
bool LoadBlockIndexGuts(const Consensus::Params& consensusParams, std::function<CBlockIndex*(const uint256&)> insertBlockIndex, const util::SignalInterrupt& interrupt)
EXCLUSIVE_LOCKS_REQUIRED(::cs_main);

bool EraseBlockIndex(const std::vector<uint256>&vect);
};
} // namespace kernel

Expand Down Expand Up @@ -360,6 +362,15 @@ class BlockManager
*/
void UnlinkPrunedFiles(const std::set<int>& setFilesToPrune) const;

//! Checks that the block hash at height nHeight matches the expected hardened checkpoint
bool CheckHardened(int nHeight, const uint256& hash, const CCheckpointData& data) EXCLUSIVE_LOCKS_REQUIRED(cs_main);

//! Returns last CBlockIndex* from the auto selected checkpoint
const CBlockIndex* AutoSelectSyncCheckpoint(const CBlockIndex *pindexBest) EXCLUSIVE_LOCKS_REQUIRED(cs_main);

//! Check against automatically selected checkpoint
bool CheckSync(int nHeight, const CBlockIndex *pindexBest) EXCLUSIVE_LOCKS_REQUIRED(cs_main);

/** Functions for disk access for blocks */
bool ReadBlockFromDisk(CBlock& block, const FlatFilePos& pos) const;
bool ReadBlockFromDisk(CBlock& block, const CBlockIndex& index) const;
Expand Down
9 changes: 6 additions & 3 deletions src/node/protocol_version.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,16 @@
* network protocol versioning
*/

static const int PROTOCOL_VERSION = 70016;
static const int PROTOCOL_VERSION = 70021;

//! initial proto version, to be increased after version/verack negotiation
static const int INIT_PROTO_VERSION = 209;

//! disconnect from peers older than this proto version
static const int MIN_PEER_PROTO_VERSION = 31800;
static const int MIN_PEER_PROTO_VERSION = 70020;

//! disconnect from peers older than this proto version after evm Shanghai
static const int MIN_PEER_PROTO_VERSION_AFTER_EVMSHANGHAI = 70021;

//! BIP 0031, pong message, is enabled for all versions AFTER this one
static const int BIP0031_VERSION = 60000;
Expand All @@ -33,6 +36,6 @@ static const int SHORT_IDS_BLOCKS_VERSION = 70014;
static const int INVALID_CB_NO_BAN_VERSION = 70015;

//! "wtxidrelay" command for wtxid-based relay starts with this version
static const int WTXID_RELAY_VERSION = 70016;
static const int WTXID_RELAY_VERSION = 70019;

#endif // BITCOIN_NODE_PROTOCOL_VERSION_H
8 changes: 4 additions & 4 deletions src/test/blockencodings_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ BOOST_AUTO_TEST_CASE(SimpleRoundTripTest)
CBlockHeaderAndShortTxIDs shortIDs2;
stream >> shortIDs2;

PartiallyDownloadedBlock partialBlock(&pool);
PartiallyDownloadedBlock partialBlock(&pool, m_node.chainman.get());
BOOST_CHECK(partialBlock.InitData(shortIDs2, extra_txn) == READ_STATUS_OK);
BOOST_CHECK( partialBlock.IsTxAvailable(0));
BOOST_CHECK(!partialBlock.IsTxAvailable(1));
Expand Down Expand Up @@ -164,7 +164,7 @@ BOOST_AUTO_TEST_CASE(NonCoinbasePreforwardRTTest)
CBlockHeaderAndShortTxIDs shortIDs2;
stream >> shortIDs2;

PartiallyDownloadedBlock partialBlock(&pool);
PartiallyDownloadedBlock partialBlock(&pool, m_node.chainman.get());
BOOST_CHECK(partialBlock.InitData(shortIDs2, extra_txn) == READ_STATUS_OK);
BOOST_CHECK(!partialBlock.IsTxAvailable(0));
BOOST_CHECK( partialBlock.IsTxAvailable(1));
Expand Down Expand Up @@ -234,7 +234,7 @@ BOOST_AUTO_TEST_CASE(SufficientPreforwardRTTest)
CBlockHeaderAndShortTxIDs shortIDs2;
stream >> shortIDs2;

PartiallyDownloadedBlock partialBlock(&pool);
PartiallyDownloadedBlock partialBlock(&pool, m_node.chainman.get());
BOOST_CHECK(partialBlock.InitData(shortIDs2, extra_txn) == READ_STATUS_OK);
BOOST_CHECK( partialBlock.IsTxAvailable(0));
BOOST_CHECK( partialBlock.IsTxAvailable(1));
Expand Down Expand Up @@ -289,7 +289,7 @@ BOOST_AUTO_TEST_CASE(EmptyBlockRoundTripTest)
CBlockHeaderAndShortTxIDs shortIDs2;
stream >> shortIDs2;

PartiallyDownloadedBlock partialBlock(&pool);
PartiallyDownloadedBlock partialBlock(&pool, m_node.chainman.get());
BOOST_CHECK(partialBlock.InitData(shortIDs2, extra_txn) == READ_STATUS_OK);
BOOST_CHECK(partialBlock.IsTxAvailable(0));

Expand Down
2 changes: 1 addition & 1 deletion src/test/fuzz/partially_downloaded_block.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ FUZZ_TARGET(partially_downloaded_block, .init = initialize_pdb)
CBlockHeaderAndShortTxIDs cmpctblock{*block};

CTxMemPool pool{MemPoolOptionsForTest(g_setup->m_node)};
PartiallyDownloadedBlock pdb{&pool};
PartiallyDownloadedBlock pdb{&pool, g_setup->m_node.chainman.get()};

// Set of available transactions (mempool or extra_txn)
std::set<uint16_t> available;
Expand Down
22 changes: 21 additions & 1 deletion src/validation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,11 @@ const std::vector<std::string> CHECKLEVEL_DOC {
* */
static constexpr int PRUNE_LOCK_BUFFER{10};

bool fRecordLogOpcodes = false;
bool fIsVMlogFile = false;
bool fGettingValuesDGP = false;
std::set<std::pair<COutPoint, unsigned int>> setStakeSeen;

GlobalMutex g_best_block_mutex;
std::condition_variable g_best_block_cv;
uint256 g_best_block;
Expand Down Expand Up @@ -141,6 +146,11 @@ bool CheckInputScripts(const CTransaction& tx, TxValidationState& state,
std::vector<CScriptCheck>* pvChecks = nullptr)
EXCLUSIVE_LOCKS_REQUIRED(cs_main);

int64_t FutureDrift(uint32_t nTime, int nHeight, const Consensus::Params& consensusParams)
{
return nTime + consensusParams.StakeTimestampMask(nHeight);
}

bool CheckFinalTxAtTip(const CBlockIndex& active_chain_tip, const CTransaction& tx)
{
AssertLockHeld(cs_main);
Expand Down Expand Up @@ -4122,7 +4132,7 @@ bool ChainstateManager::AcceptBlockHeader(const CBlockHeader& block, BlockValida
}

// Exposed wrapper for AcceptBlockHeader
bool ChainstateManager::ProcessNewBlockHeaders(const std::vector<CBlockHeader>& headers, bool min_pow_checked, BlockValidationState& state, const CBlockIndex** ppindex)
bool ChainstateManager::ProcessNewBlockHeaders(const std::vector<CBlockHeader>& headers, bool min_pow_checked, BlockValidationState& state, const CBlockIndex** ppindex, const CBlockIndex** pindexFirst)
{
AssertLockNotHeld(cs_main);
{
Expand Down Expand Up @@ -4269,6 +4279,11 @@ bool ChainstateManager::AcceptBlock(const std::shared_ptr<const CBlock>& pblock,
return true;
}

bool CheckCanonicalBlockSignature(const CBlockHeader* pblock)
{
return {};
}

bool ChainstateManager::ProcessNewBlock(const std::shared_ptr<const CBlock>& block, bool force_processing, bool min_pow_checked, bool* new_block)
{
AssertLockNotHeld(cs_main);
Expand Down Expand Up @@ -5212,6 +5227,11 @@ bool Chainstate::ResizeCoinsCaches(size_t coinstip_size, size_t coinsdb_size)
return ret;
}

bool Chainstate::RemoveBlockIndex(CBlockIndex *pindex)
{
return {};
}

//! Guess how far we are in the verification process at the given block index
//! require cs_main if pindex has not been validated yet (because nChainTx might be unset)
double GuessVerificationProgress(const ChainTxData& data, const CBlockIndex *pindex) {
Expand Down
10 changes: 9 additions & 1 deletion src/validation.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,11 @@ extern bool fLogEvents;
/** Documentation for argument 'checklevel'. */
extern const std::vector<std::string> CHECKLEVEL_DOC;

/** The set of all seen COutPoint entries for proof of stake. */
extern std::set<std::pair<COutPoint, unsigned int>> setStakeSeen;

int64_t FutureDrift(uint32_t nTime, int nHeight, const Consensus::Params& consensusParams);

CAmount GetBlockSubsidy(int nHeight, const Consensus::Params& consensusParams);

bool FatalError(kernel::Notifications& notifications, BlockValidationState& state, const std::string& strMessage, const bilingual_str& userMessage = {});
Expand Down Expand Up @@ -390,6 +395,7 @@ static_assert(std::is_nothrow_destructible_v<CScriptCheck>);

/** Context-independent validity checks */
bool CheckBlock(const CBlock& block, BlockValidationState& state, const Consensus::Params& consensusParams, bool fCheckPOW = true, bool fCheckMerkleRoot = true);
bool CheckCanonicalBlockSignature(const CBlockHeader* pblock);

/** Check a block is completely valid from start to finish (only works on top of our current best block) */
bool TestBlockValidity(BlockValidationState& state,
Expand Down Expand Up @@ -750,6 +756,8 @@ class Chainstate

void ClearBlockIndexCandidates() EXCLUSIVE_LOCKS_REQUIRED(::cs_main);

bool RemoveBlockIndex(CBlockIndex *pindex) EXCLUSIVE_LOCKS_REQUIRED(cs_main);

/** Find the last common block of this chain and a locator. */
const CBlockIndex* FindForkInGlobalIndex(const CBlockLocator& locator) const EXCLUSIVE_LOCKS_REQUIRED(cs_main);

Expand Down Expand Up @@ -1195,7 +1203,7 @@ class ChainstateManager
* @param[out] state This may be set to an Error state if any error occurred processing them
* @param[out] ppindex If set, the pointer will be set to point to the last new block index object for the given headers
*/
bool ProcessNewBlockHeaders(const std::vector<CBlockHeader>& block, bool min_pow_checked, BlockValidationState& state, const CBlockIndex** ppindex = nullptr) LOCKS_EXCLUDED(cs_main);
bool ProcessNewBlockHeaders(const std::vector<CBlockHeader>& block, bool min_pow_checked, BlockValidationState& state, const CBlockIndex** ppindex = nullptr, const CBlockIndex** pindexFirst=nullptr) LOCKS_EXCLUDED(cs_main);

/**
* Sufficiently validate a block for disk storage (and store on disk).
Expand Down

0 comments on commit 2d1d436

Please sign in to comment.