commit
6ec6ee4b96
@ -203,7 +203,9 @@ public:
|
|||||||
// (the tx=... number in the SetBestChain debug.log lines)
|
// (the tx=... number in the SetBestChain debug.log lines)
|
||||||
0.03 // * estimated number of transactions per second after that timestamp
|
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;
|
fDefaultConsistencyChecks = true;
|
||||||
fRequireStandard = false;
|
fRequireStandard = false;
|
||||||
fMineBlocksOnDemand = true;
|
fMineBlocksOnDemand = true;
|
||||||
|
|
||||||
// checkpointData = (CCheckpointData) {
|
// checkpointData = (CCheckpointData) {
|
||||||
// {
|
// {
|
||||||
|
|||||||
@ -81,6 +81,9 @@ public:
|
|||||||
const CCheckpointData& Checkpoints() const { return checkpointData; }
|
const CCheckpointData& Checkpoints() const { return checkpointData; }
|
||||||
const ChainTxData& TxData() const { return chainTxData; }
|
const ChainTxData& TxData() const { return chainTxData; }
|
||||||
void UpdateVersionBitsParameters(Consensus::DeploymentPos d, int64_t nStartTime, int64_t nTimeout);
|
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:
|
protected:
|
||||||
CChainParams() {}
|
CChainParams() {}
|
||||||
|
|
||||||
@ -99,6 +102,9 @@ protected:
|
|||||||
bool fMineBlocksOnDemand;
|
bool fMineBlocksOnDemand;
|
||||||
CCheckpointData checkpointData;
|
CCheckpointData checkpointData;
|
||||||
ChainTxData chainTxData;
|
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_DUST = 0x41; // part of BIP 61
|
||||||
static const unsigned char REJECT_INSUFFICIENTFEE = 0x42;
|
static const unsigned char REJECT_INSUFFICIENTFEE = 0x42;
|
||||||
static const unsigned char REJECT_CHECKPOINT = 0x43;
|
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 */
|
/** Capture information about block/transaction validation */
|
||||||
class CValidationState {
|
class CValidationState {
|
||||||
|
|||||||
@ -364,6 +364,8 @@ std::string HelpMessage(HelpMessageMode mode)
|
|||||||
if (showDebug)
|
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("-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("-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("-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("-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));
|
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.
|
// best equivalent proof of work) than the best header chain we know about.
|
||||||
send = mi->second->IsValid(BLOCK_VALID_SCRIPTS) && (pindexBestHeader != nullptr) &&
|
send = mi->second->IsValid(BLOCK_VALID_SCRIPTS) && (pindexBestHeader != nullptr) &&
|
||||||
(pindexBestHeader->GetBlockTime() - mi->second->GetBlockTime() < nOneMonth) &&
|
(pindexBestHeader->GetBlockTime() - mi->second->GetBlockTime() < nOneMonth) &&
|
||||||
|
(chainActive.Height() - mi->second->nHeight < Params().MaxReorganizationDepth()) && //(51% attk prevention)
|
||||||
(GetBlockProofEquivalentTime(*pindexBestHeader, *mi->second, *pindexBestHeader, consensusParams) < nOneMonth);
|
(GetBlockProofEquivalentTime(*pindexBestHeader, *mi->second, *pindexBestHeader, consensusParams) < nOneMonth);
|
||||||
if (!send) {
|
if (!send) {
|
||||||
LogPrintf("%s: ignoring request from peer=%i for old block that isn't in the main chain\n", __func__, pfrom->GetId());
|
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 "validationinterface.h"
|
||||||
#include "versionbits.h"
|
#include "versionbits.h"
|
||||||
#include "warnings.h"
|
#include "warnings.h"
|
||||||
|
#include "net.h"
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
@ -2942,6 +2943,13 @@ static bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationSta
|
|||||||
assert(pindexPrev != nullptr);
|
assert(pindexPrev != nullptr);
|
||||||
const int nHeight = pindexPrev->nHeight + 1;
|
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
|
// Check proof of work
|
||||||
const Consensus::Params& consensusParams = params.GetConsensus();
|
const Consensus::Params& consensusParams = params.GetConsensus();
|
||||||
if (block.nBits != GetNextWorkRequired(pindexPrev, &block, consensusParams))
|
if (block.nBits != GetNextWorkRequired(pindexPrev, &block, consensusParams))
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user