aboutsummaryrefslogtreecommitdiff
path: root/src/main.cpp
diff options
context:
space:
mode:
authorPatrick Lodder <[email protected]>2015-07-20 15:03:02 +0200
committerPatrick Lodder <[email protected]>2015-07-20 15:03:02 +0200
commit8cd835cddba565594f5cde2d91ee92e32bcbf2fd (patch)
tree049698b334daf7e65af268b0da64134fd9dbbfdc /src/main.cpp
parentMerge pull request #1200 from rnicoll/1.10-auxpow-clean (diff)
parentUpdate Python test address and key values to match Dogecoin format. (diff)
downloaddiscoin-8cd835cddba565594f5cde2d91ee92e32bcbf2fd.tar.xz
discoin-8cd835cddba565594f5cde2d91ee92e32bcbf2fd.zip
Merge pull request #1201 from rnicoll/1.10-sync
Consensus fixes
Diffstat (limited to 'src/main.cpp')
-rw-r--r--src/main.cpp57
1 files changed, 32 insertions, 25 deletions
diff --git a/src/main.cpp b/src/main.cpp
index 39b97d1d6..dfcd50310 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1182,7 +1182,7 @@ static bool ReadBlockOrHeader(T& block, const CDiskBlockPos& pos)
}
// Check the header
- if (!CheckAuxPowProofOfWork(block, Params().GetConsensus()))
+ if (!CheckAuxPowProofOfWork(block, Params().GetConsensus(0))) // FIXME: Can we get height at all?
return error("ReadBlockFromDisk: Errors in block header at %s", pos.ToString());
return true;
@@ -1444,7 +1444,11 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsVi
// If prev is coinbase, check that it's matured
if (coins->IsCoinBase()) {
- if (nSpendHeight - coins->nHeight < COINBASE_MATURITY)
+ // Dogecoin: Switch maturity at depth 145,000
+ int nCoinbaseMaturity = coins->nHeight < COINBASE_MATURITY_SWITCH
+ ? COINBASE_MATURITY_OLD
+ : COINBASE_MATURITY;
+ if (nSpendHeight - coins->nHeight < nCoinbaseMaturity)
return state.Invalid(
error("CheckInputs(): tried to spend coinbase at depth %d", nSpendHeight - coins->nHeight),
REJECT_INVALID, "bad-txns-premature-spend-of-coinbase");
@@ -1800,6 +1804,7 @@ static int64_t nTimeTotal = 0;
bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& view, bool fJustCheck)
{
const CChainParams& chainparams = Params();
+ const Consensus::Params consensus = chainparams.GetConsensus(pindex->nHeight);
AssertLockHeld(cs_main);
// Check it again in case a previous version let a bad block in
if (!CheckBlock(block, state, !fJustCheck, !fJustCheck))
@@ -1811,7 +1816,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
// Special case for the genesis block, skipping connection of its transactions
// (its coinbase is unspendable)
- if (block.GetHash() == chainparams.GetConsensus().hashGenesisBlock) {
+ if (block.GetHash() == consensus.hashGenesisBlock) {
if (!fJustCheck)
view.SetBestBlock(pindex->GetBlockHash());
return true;
@@ -1850,7 +1855,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
unsigned int flags = fStrictPayToScriptHash ? SCRIPT_VERIFY_P2SH : SCRIPT_VERIFY_NONE;
// Start enforcing the DERSIG (BIP66) rules, for block.nVersion=3 blocks, when 75% of the network has upgraded:
- if (block.nVersion >= 3 && IsSuperMajority(3, pindex->pprev, chainparams.GetConsensus().nMajorityEnforceBlockUpgrade, chainparams.GetConsensus())) {
+ if (block.nVersion >= 3 && IsSuperMajority(3, pindex->pprev, consensus.nMajorityEnforceBlockUpgrade, consensus)) {
flags |= SCRIPT_VERIFY_DERSIG;
}
@@ -1913,7 +1918,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
int64_t nTime1 = GetTimeMicros(); nTimeConnect += nTime1 - nTimeStart;
LogPrint("bench", " - Connect %u transactions: %.2fms (%.3fms/tx, %.3fms/txin) [%.2fs]\n", (unsigned)block.vtx.size(), 0.001 * (nTime1 - nTimeStart), 0.001 * (nTime1 - nTimeStart) / block.vtx.size(), nInputs <= 1 ? 0 : 0.001 * (nTime1 - nTimeStart) / (nInputs-1), nTimeConnect * 0.000001);
- CAmount blockReward = nFees + GetDogecoinBlockSubsidy(pindex->nHeight, chainparams.GetConsensus(), hashPrevBlock);
+ CAmount blockReward = nFees + GetDogecoinBlockSubsidy(pindex->nHeight, consensus, hashPrevBlock);
if (block.vtx[0].GetValueOut() > blockReward)
return state.DoS(100,
error("ConnectBlock(): coinbase pays too much (actual=%d vs limit=%d)",
@@ -2667,7 +2672,7 @@ bool FindUndoPos(CValidationState &state, int nFile, CDiskBlockPos &pos, unsigne
bool CheckBlockHeader(const CBlockHeader& block, CValidationState& state, bool fCheckPOW)
{
// Check proof of work matches claimed amount
- if (fCheckPOW && !CheckAuxPowProofOfWork(block, Params().GetConsensus()))
+ if (fCheckPOW && !CheckAuxPowProofOfWork(block, Params().GetConsensus(0))) // FIXME: Get actual height
return state.DoS(50, error("CheckBlockHeader(): proof of work failed"),
REJECT_INVALID, "high-hash");
@@ -2742,7 +2747,7 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo
bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex * const pindexPrev)
{
const CChainParams& chainParams = Params();
- const Consensus::Params& consensusParams = chainParams.GetConsensus();
+ const Consensus::Params& consensusParams = chainParams.GetConsensus(pindexPrev->nHeight + 1);
uint256 hash = block.GetHash();
if (hash == consensusParams.hashGenesisBlock)
return true;
@@ -2752,15 +2757,15 @@ bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& sta
int nHeight = pindexPrev->nHeight+1;
// Disallow legacy blocks after merge-mining start.
- if (!Params().GetConsensus().AllowLegacyBlocks(nHeight)
+ if (!consensusParams.fAllowLegacyBlocks
&& block.nVersion.IsLegacy())
- return state.DoS(100, error("%s : legacy block after auxpow start",
- __func__),
+ return state.DoS(100, error("%s : legacy block after auxpow start at height %d, parameters effective from %d",
+ __func__, pindexPrev->nHeight + 1, consensusParams.nHeightEffective),
REJECT_INVALID, "late-legacy-block");
// Check proof of work
if (block.nBits != GetNextWorkRequired(pindexPrev, &block, consensusParams))
- return state.DoS(100, error("%s: incorrect proof of work", __func__),
+ return state.DoS(100, error("%s: incorrect proof of work at height %d", __func__, nHeight),
REJECT_INVALID, "bad-diffbits");
// Check timestamp against prev
@@ -2782,9 +2787,10 @@ bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& sta
}
// Reject block.nVersion=1 blocks when 95% (75% on testnet) of the network has upgraded:
- if (block.nVersion < 2 && IsSuperMajority(2, pindexPrev, consensusParams.nMajorityRejectBlockOutdated, consensusParams))
- return state.Invalid(error("%s: rejected nVersion=1 block", __func__),
- REJECT_OBSOLETE, "bad-version");
+ // Dogecoin: Version 2 enforcement was never used
+ //if (block.nVersion < 2 && IsSuperMajority(2, pindexPrev, consensusParams.nMajorityRejectBlockOutdated, consensusParams))
+ // return state.Invalid(error("%s: rejected nVersion=1 block", __func__),
+ // REJECT_OBSOLETE, "bad-version");
// Reject block.nVersion=2 blocks when 95% (75% on testnet) of the network has upgraded:
if (block.nVersion < 3 && IsSuperMajority(3, pindexPrev, consensusParams.nMajorityRejectBlockOutdated, consensusParams))
@@ -2797,7 +2803,6 @@ bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& sta
bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIndex * const pindexPrev)
{
const int nHeight = pindexPrev == NULL ? 0 : pindexPrev->nHeight + 1;
- const Consensus::Params& consensusParams = Params().GetConsensus();
// Check that all transactions are finalized
BOOST_FOREACH(const CTransaction& tx, block.vtx)
@@ -2807,7 +2812,8 @@ bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIn
// Enforce block.nVersion=2 rule that the coinbase starts with serialized block height
// if 750 of the last 1,000 blocks are version 2 or greater (51/100 if testnet):
- if (block.nVersion >= 2 && IsSuperMajority(2, pindexPrev, consensusParams.nMajorityEnforceBlockUpgrade, consensusParams))
+ // Dogecoin: Block v2 was never enforced
+ if (block.nVersion >= 3)
{
CScript expect = CScript() << nHeight;
if (block.vtx[0].vin[0].scriptSig.size() < expect.size() ||
@@ -2842,7 +2848,7 @@ bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state, CBloc
// Get prev block index
CBlockIndex* pindexPrev = NULL;
- if (hash != chainparams.GetConsensus().hashGenesisBlock) {
+ if (hash != chainparams.GetConsensus(0).hashGenesisBlock) {
BlockMap::iterator mi = mapBlockIndex.find(block.hashPrevBlock);
if (mi == mapBlockIndex.end())
return state.DoS(10, error("%s: prev block not found", __func__), 0, "bad-prevblk");
@@ -3485,7 +3491,7 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp)
// detect out of order blocks, and store them for later
uint256 hash = block.GetHash();
- if (hash != chainparams.GetConsensus().hashGenesisBlock && mapBlockIndex.find(block.hashPrevBlock) == mapBlockIndex.end()) {
+ if (hash != chainparams.GetConsensus(0).hashGenesisBlock && mapBlockIndex.find(block.hashPrevBlock) == mapBlockIndex.end()) {
LogPrint("reindex", "%s: Out of order block %s, parent %s not known\n", __func__, hash.ToString(),
block.hashPrevBlock.ToString());
if (dbp)
@@ -3500,7 +3506,7 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp)
nLoaded++;
if (state.IsError())
break;
- } else if (hash != chainparams.GetConsensus().hashGenesisBlock && mapBlockIndex[hash]->nHeight % 1000 == 0) {
+ } else if (hash != chainparams.GetConsensus(0).hashGenesisBlock && mapBlockIndex[hash]->nHeight % 1000 == 0) {
LogPrintf("Block Import: already had block %s at height %d\n", hash.ToString(), mapBlockIndex[hash]->nHeight);
}
@@ -3542,7 +3548,6 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp)
void static CheckBlockIndex()
{
- const Consensus::Params& consensusParams = Params().GetConsensus();
if (!fCheckBlockIndex) {
return;
}
@@ -3557,6 +3562,7 @@ void static CheckBlockIndex()
return;
}
+
// Build forward-pointing map of the entire block tree.
std::multimap<CBlockIndex*,CBlockIndex*> forward;
for (BlockMap::iterator it = mapBlockIndex.begin(); it != mapBlockIndex.end(); it++) {
@@ -3583,6 +3589,7 @@ void static CheckBlockIndex()
CBlockIndex* pindexFirstNotChainValid = NULL; // Oldest ancestor of pindex which does not have BLOCK_VALID_CHAIN (regardless of being valid or not).
CBlockIndex* pindexFirstNotScriptsValid = NULL; // Oldest ancestor of pindex which does not have BLOCK_VALID_SCRIPTS (regardless of being valid or not).
while (pindex != NULL) {
+ const Consensus::Params& consensusParams = Params().GetConsensus(nHeight);
nNodes++;
if (pindexFirstInvalid == NULL && pindex->nStatus & BLOCK_FAILED_VALID) pindexFirstInvalid = pindex;
if (pindexFirstMissing == NULL && !(pindex->nStatus & BLOCK_HAVE_DATA)) pindexFirstMissing = pindex;
@@ -3816,8 +3823,8 @@ bool static AlreadyHave(const CInv& inv)
void static ProcessGetData(CNode* pfrom)
{
std::deque<CInv>::iterator it = pfrom->vRecvGetData.begin();
-
vector<CInv> vNotFound;
+ const Consensus::Params &consensus = Params().GetConsensus(chainActive.Height());
LOCK(cs_main);
@@ -3846,7 +3853,7 @@ void static ProcessGetData(CNode* pfrom)
// best equivalent proof of work) than the best header chain we know about.
send = mi->second->IsValid(BLOCK_VALID_SCRIPTS) && (pindexBestHeader != NULL) &&
(pindexBestHeader->GetBlockTime() - mi->second->GetBlockTime() < nOneMonth) &&
- (GetBlockProofEquivalentTime(*pindexBestHeader, *mi->second, *pindexBestHeader, Params().GetConsensus()) < nOneMonth);
+ (GetBlockProofEquivalentTime(*pindexBestHeader, *mi->second, *pindexBestHeader, consensus) < nOneMonth);
if (!send) {
LogPrintf("%s: ignoring request from peer=%i for old block that isn't in the main chain\n", __func__, pfrom->GetId());
}
@@ -4208,12 +4215,12 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
// not a direct successor.
pfrom->PushMessage("getheaders", chainActive.GetLocator(pindexBestHeader), inv.hash);
CNodeState *nodestate = State(pfrom->GetId());
- if (chainActive.Tip()->GetBlockTime() > GetAdjustedTime() - chainparams.GetConsensus().nPowTargetSpacing * 20 &&
+ if (chainActive.Tip()->GetBlockTime() > GetAdjustedTime() - chainparams.GetConsensus(chainActive.Height()).nPowTargetSpacing * 20 &&
nodestate->nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) {
vToFetch.push_back(inv);
// Mark block as in flight already, even though the actual "getdata" message only goes out
// later (within the same cs_main lock, though).
- MarkBlockAsInFlight(pfrom->GetId(), inv.hash, chainparams.GetConsensus());
+ MarkBlockAsInFlight(pfrom->GetId(), inv.hash, chainparams.GetConsensus(chainActive.Height()));
}
LogPrint("net", "getheaders (%d) %s to peer=%d\n", pindexBestHeader->nHeight, inv.hash.ToString(), pfrom->id);
}
@@ -4876,7 +4883,7 @@ bool ProcessMessages(CNode* pfrom)
bool SendMessages(CNode* pto, bool fSendTrickle)
{
- const Consensus::Params& consensusParams = Params().GetConsensus();
+ const Consensus::Params& consensusParams = Params().GetConsensus(chainActive.Height());
{
// Don't send anything until we get its version message
if (pto->nVersion == 0)