Files

201 lines
7.0 KiB
C++
Raw Permalink Normal View History

2018-01-15 15:26:12 +00:00
/*
* This file is part of the flowee project
2021-06-20 22:44:44 +02:00
* Copyright (C) 2017-2019 Tom Zander <tom@flowee.org>
2018-01-15 15:26:12 +00:00
*
* 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/>.
*/
#ifndef VALIDATIONENGINE_H
#define VALIDATIONENGINE_H
#include "ValidationSettings.h"
class CNode;
struct CDiskBlockPos;
class ValidationEnginePrivate;
class CChain;
2021-11-02 10:18:24 +01:00
class Block;
2018-01-15 15:26:12 +00:00
class CTxMemPool;
class CTransaction;
class Tx;
namespace Blocks {
class DB;
}
#include <memory>
#include <future>
#include <uint256.h>
namespace Validation {
/**
* @brief The ResultHandlingFlags enum explains what to do after a block finished validation.
*/
enum ResultHandlingFlags {
SaveGoodToDisk = 1, ///< Successful blocks get saved to disk.
ForwardGoodToPeers = 2,///< A successful block will get forwarded to peers.
PunishBadNode = 4, ///< Ban a bad node that gave us this block.
RateLimitFreeTx = 8,
2021-03-04 15:48:56 +01:00
RejectAbsurdFeeTx = 0x10,
TxValidateOnly = 0x20
2018-01-15 15:26:12 +00:00
};
/// throws exception if transaction is malformed.
2026-04-14 23:43:29 +02:00
void checkTransaction(const Tx &tx);
2018-01-15 15:26:12 +00:00
enum EngineType {
FullEngine,
/**
* In the case of VerifyDB we need an engine that allows going backwards in time.
* Removing items *against* the blocks-db. For this unique usecase we need to skip
* automatically loading and processing blocks that have previously been added to the
* header-chain.
*/
SkipAutoBlockProcessing
};
/**
* @brief The Engine class does all block & transaction validation and processing.
* This class is an abstraction to simplify the validation process of foreign data being shared
* with this node and validating its correctness before accepting it into the node.
*
* This class is multi-threaded for parallel validation, both of block headers and all other parts where possible.
* The actual multi-threading is done in a way that is lock-free.
*
* Should there be a large backlog of blocks the headers will be validated first at a much higher pace than the actual
* block content and based on validated blocks we choose which full blocks to start validation on.
* An additional feature that this allows us is that blocks that have half a difficulty-adjustment period of
* validated headers (1008) build already on top of them, they skip validation of script signatures to allow
* catching up of a node to be as fast as possible, without sacrificing security.
*
* @see Application::validation()
*/
class Engine
{
public:
Engine(EngineType type = FullEngine);
~Engine();
/**
* Disable most validation of transactions and content.
*/
void setSpvValidationMode(bool spv);
2018-01-15 15:26:12 +00:00
/**
* @brief add a block to the validation queue.
* This takes a block schedules the validation on all the threads available. This method returns immediately.
* @param block the block you want to validate.
* @param onResultFlags indicates what should happen after validation completes.
* @param pFrom the originating node that send us this. Needed if its a bad block and we want to punish it.
* @see waitForSpace
*/
2021-11-02 10:18:24 +01:00
Settings addBlock(const Block &block, std::uint32_t onResultFlags, CNode *pFrom = nullptr);
2018-01-15 15:26:12 +00:00
Settings addBlock(const CDiskBlockPos &pos, std::uint32_t onResultFlags = 0);
/*
* Schedule the transaction validation for correctness and addition to the mempool.
*/
std::future<std::string> addTransaction(const Tx &tx, std::uint32_t onResultFlags = 0, CNode *pFrom = nullptr);
/**
* @brief waitForSpace is a potentially blocking method that waits until the job count drops to an acceptable level.
* Due to addBlock() starting an async process it returns immediately and as such a user that expects to add
* a large number of blocks should avoid overloading the system by waiting in between calls to addBlock for space to
* free up from blocks that finished validation.
*/
void waitForSpace();
/**
* This method blocks until all validation tasks are done.
*/
void waitValidationFinished();
/**
* Set the block chain we should operate on. This is mandatory data.
*/
void setBlockchain(CChain *chain);
bool isRecentlyRejectedTransaction(const uint256 &txHash) const;
/**
* @brief get the block chain that was set using setBlockchain()
*/
CChain* blockchain() const;
void setMempool(CTxMemPool *mempool);
CTxMemPool *mempool() const;
void invalidateBlock(CBlockIndex *index);
2021-03-09 16:45:16 +01:00
/**
* The BlockMetaData collects details like 'fees' per transaction and
* similar which speed up variouss API operations quite considerably.
* Turning it on does have a negative side-effect of causing much more
* disk-IO during validation of non-recent blocks. Mostly noticed during IBD.
*/
void enableFeeResolveForMetaData(bool on);
2018-01-15 15:26:12 +00:00
/**
* Undo the effects of this block (with given index) on the UTXO set represented by view.
* @param index the blockindex representing the block that we should undo.
* @param the UTXO view we should undo the changes on.
* @param clean is an optional bool that is set based on non-fatal issues in disconnecting,
* essentially it is set to false if the reverse-apply of the block was non-clean.
* Notice that passing in a non-null value adjusts the return value!.
*
* @return true if all went well. If \a clean was null and the application was not clean, then we also return false.
*
* Note that in any case, coins may be modified.
*/
2020-11-18 22:08:00 +01:00
bool disconnectTip(CBlockIndex *index, bool *clean = nullptr);
2018-01-15 15:26:12 +00:00
/**
* Request the validation engine to stop validating.
* This call blocks until many parts are stopped.
*
* Notice that this method is also called from the destructor.
*/
void shutdown();
2018-09-15 22:12:16 +02:00
/**
* A fully initialized validation engine is idling until something
* is added.
* If a backlog of blocks to check was left last shutdown, calling start
* will start processing those.
*/
void start();
/**
* Return the validation flags we determined based on current chain-tip.
*/
uint32_t tipValidationFlags(bool requireStandard = false) const;
2026-05-18 11:55:31 +02:00
/**
* Notify the validation process that all data from the originating
* node is suspect and may be ignored.
*/
void nodeBanned(int nodeId);
2018-01-15 15:26:12 +00:00
/// \internal
2019-07-29 17:07:19 +02:00
std::weak_ptr<ValidationEnginePrivate> priv() const;
2018-01-15 15:26:12 +00:00
private:
std::shared_ptr<ValidationEnginePrivate> d;
};
}
#endif