Max-Reorg-Depth
This commit is contained in:
parent
d34c2ce7f7
commit
1ff115d7de
@ -203,7 +203,9 @@ public:
|
||||
// (the tx=... number in the SetBestChain debug.log lines)
|
||||
0.03 // * estimated number of transactions per second after that timestamp
|
||||
};
|
||||
|
||||
// Max-Reorg (51% attack prevention)
|
||||
nMaxReorganizationDepth = 55; // 55 at 1 minute block timespan is +/- 55 minutes.
|
||||
nMinReorganizationPeers = 3;
|
||||
}
|
||||
};
|
||||
|
||||
@ -411,7 +413,7 @@ public:
|
||||
|
||||
fDefaultConsistencyChecks = true;
|
||||
fRequireStandard = false;
|
||||
fMineBlocksOnDemand = true;
|
||||
fMineBlocksOnDemand = true;
|
||||
|
||||
// checkpointData = (CCheckpointData) {
|
||||
// {
|
||||
|
||||
@ -81,6 +81,9 @@ public:
|
||||
const CCheckpointData& Checkpoints() const { return checkpointData; }
|
||||
const ChainTxData& TxData() const { return chainTxData; }
|
||||
void UpdateVersionBitsParameters(Consensus::DeploymentPos d, int64_t nStartTime, int64_t nTimeout);
|
||||
// Max-Reorg (51% attack prevention)
|
||||
int MaxReorganizationDepth() const { return nMaxReorganizationDepth; }
|
||||
int MinReorganizationPeers() const { return nMinReorganizationPeers; }
|
||||
protected:
|
||||
CChainParams() {}
|
||||
|
||||
@ -99,6 +102,9 @@ protected:
|
||||
bool fMineBlocksOnDemand;
|
||||
CCheckpointData checkpointData;
|
||||
ChainTxData chainTxData;
|
||||
// Max-Reorg (51% attack prevention)
|
||||
int nMaxReorganizationDepth;
|
||||
int nMinReorganizationPeers;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@ -22,6 +22,8 @@ static const unsigned char REJECT_NONSTANDARD = 0x40;
|
||||
// static const unsigned char REJECT_DUST = 0x41; // part of BIP 61
|
||||
static const unsigned char REJECT_INSUFFICIENTFEE = 0x42;
|
||||
static const unsigned char REJECT_CHECKPOINT = 0x43;
|
||||
// Max-Reorg (51% attack prevention)
|
||||
static const unsigned char REJECT_MAXREORGDEPTH = 0x44;
|
||||
|
||||
/** Capture information about block/transaction validation */
|
||||
class CValidationState {
|
||||
|
||||
@ -364,6 +364,8 @@ std::string HelpMessage(HelpMessageMode mode)
|
||||
if (showDebug)
|
||||
strUsage += HelpMessageOpt("-feefilter", strprintf("Tell other nodes to filter invs to us by our mempool min fee (default: %u)", DEFAULT_FEEFILTER));
|
||||
strUsage += HelpMessageOpt("-loadblock=<file>", _("Imports blocks from external blk000??.dat file on startup"));
|
||||
strUsage += HelpMessageOpt("-maxreorg=<n>", strprintf(_("Set the Maximum reorg depth (default: %u)"), defaultChainParams->MaxReorganizationDepth())); //#51-Attk-prevention
|
||||
strUsage += HelpMessageOpt("-minreorgpeers=<n>", strprintf(_("Set the Minimum amount of peers required to not allow reorgs. Peers must be greater than. (default: %u)"), defaultChainParams->MinReorganizationPeers())); //#51-Attk-prevention
|
||||
strUsage += HelpMessageOpt("-maxorphantx=<n>", strprintf(_("Keep at most <n> unconnectable transactions in memory (default: %u)"), DEFAULT_MAX_ORPHAN_TRANSACTIONS));
|
||||
strUsage += HelpMessageOpt("-maxmempool=<n>", strprintf(_("Keep the transaction memory pool below <n> megabytes (default: %u)"), DEFAULT_MAX_MEMPOOL_SIZE));
|
||||
strUsage += HelpMessageOpt("-mempoolexpiry=<n>", strprintf(_("Do not keep transactions in the mempool longer than <n> hours (default: %u)"), DEFAULT_MEMPOOL_EXPIRY));
|
||||
|
||||
@ -1009,6 +1009,7 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
|
||||
// best equivalent proof of work) than the best header chain we know about.
|
||||
send = mi->second->IsValid(BLOCK_VALID_SCRIPTS) && (pindexBestHeader != nullptr) &&
|
||||
(pindexBestHeader->GetBlockTime() - mi->second->GetBlockTime() < nOneMonth) &&
|
||||
(chainActive.Height() - mi->second->nHeight < Params().MaxReorganizationDepth()) && //(51% attk prevention)
|
||||
(GetBlockProofEquivalentTime(*pindexBestHeader, *mi->second, *pindexBestHeader, consensusParams) < nOneMonth);
|
||||
if (!send) {
|
||||
LogPrintf("%s: ignoring request from peer=%i for old block that isn't in the main chain\n", __func__, pfrom->GetId());
|
||||
|
||||
@ -42,6 +42,7 @@
|
||||
#include "validationinterface.h"
|
||||
#include "versionbits.h"
|
||||
#include "warnings.h"
|
||||
#include "net.h"
|
||||
|
||||
#include <atomic>
|
||||
#include <sstream>
|
||||
@ -2942,6 +2943,13 @@ static bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationSta
|
||||
assert(pindexPrev != nullptr);
|
||||
const int nHeight = pindexPrev->nHeight + 1;
|
||||
|
||||
//If this is a reorg, check that it is not too deep (51% attack prevention)
|
||||
int nMaxReorgDepth = gArgs.GetArg("-maxreorg", Params().MaxReorganizationDepth());
|
||||
int nMinReorgPeers = gArgs.GetArg("-minreorgpeers", Params().MinReorganizationPeers());
|
||||
bool fGreaterThanMaxReorg = chainActive.Height() - nHeight >= nMaxReorgDepth;
|
||||
if (fGreaterThanMaxReorg && g_connman && (int)g_connman->GetNodeCount(CConnman::CONNECTIONS_ALL) > nMinReorgPeers && !IsInitialBlockDownload())
|
||||
return state.DoS(1, error("%s: forked chain older than max reorganization depth (height %d), with connections (count %d), and (initial download %s)", __func__, nHeight, g_connman ? g_connman->GetNodeCount(CConnman::CONNECTIONS_ALL) : -1, IsInitialBlockDownload() ? "true" : "false"), REJECT_MAXREORGDEPTH, "bad-fork-prior-to-maxreorgdepth");
|
||||
|
||||
// Check proof of work
|
||||
const Consensus::Params& consensusParams = params.GetConsensus();
|
||||
if (block.nBits != GetNextWorkRequired(pindexPrev, &block, consensusParams))
|
||||
|
||||
Loading…
Reference in New Issue
Block a user