diff --git a/src/checkpoints.cpp b/src/checkpoints.cpp index 078a4ff93f256..d4b378e60b9a1 100644 --- a/src/checkpoints.cpp +++ b/src/checkpoints.cpp @@ -81,4 +81,18 @@ namespace Checkpoints } return NULL; } + + bool HaveCheckpoint(int nHeight) + { + assert(nHeight >= 0); + + if (!fTestNet && (unsigned int)nHeight < sizeof(LSBCheckpoints)/sizeof(int)) + return true; + + MapCheckpoints& checkpoints = (fTestNet ? mapCheckpointsTestnet : mapCheckpoints); + + MapCheckpoints::const_iterator i = checkpoints.find(nHeight); + if (i == checkpoints.end()) return false; + return true; + } } diff --git a/src/checkpoints.h b/src/checkpoints.h index 70e936564c4a5..b8dab3a05f1a8 100644 --- a/src/checkpoints.h +++ b/src/checkpoints.h @@ -22,6 +22,9 @@ namespace Checkpoints // Returns last CBlockIndex* in mapBlockIndex that is a checkpoint CBlockIndex* GetLastCheckpoint(const std::map& mapBlockIndex); + + // Returns true if we have a checkpoint lock-in for the given height + bool HaveCheckpoint(int nHeight); } #endif diff --git a/src/main.cpp b/src/main.cpp index 3052cfb8c4083..9f4307cdee0bf 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1322,18 +1322,6 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex) if (!CheckBlock()) return false; - // Do not allow blocks that contain transactions which 'overwrite' older transactions, - // unless those are already completely spent. - // If such overwrites are allowed, coinbases and transactions depending upon those - // can be duplicated to remove the ability to spend the first instance -- even after - // being sent to another address. - // See BIP30 and http://r6.ca/blog/20120206T005236Z.html for more information. - // This logic is not necessary for memory pool transactions, as AcceptToMemoryPool - // already refuses previously-known transaction id's entirely. - // This rule applies to all blocks whose timestamp is after March 15, 2012, 0:00 UTC. - int64 nBIP30SwitchTime = 1331769600; - bool fEnforceBIP30 = (pindex->nTime > nBIP30SwitchTime); - // BIP16 didn't become active until Apr 1 2012 int64 nBIP16SwitchTime = 1333238400; bool fStrictPayToScriptHash = (pindex->nTime >= nBIP16SwitchTime); @@ -1348,7 +1336,16 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex) { uint256 hashTx = tx.GetHash(); - if (fEnforceBIP30) { + // Do not allow blocks that contain transactions which 'overwrite' older transactions, + // unless those are already completely spent. + // If such overwrites are allowed, coinbases and transactions depending upon those + // can be duplicated to remove the ability to spend the first instance -- even after + // being sent to another address. + // See BIP30 and http://r6.ca/blog/20120206T005236Z.html for more information. + // This logic is not necessary for memory pool transactions, as AcceptToMemoryPool + // already refuses previously-known transaction id's entirely. + // This rule applies to all blocks whose timestamp is after March 15, 2012, 0:00 UTC. + if (!Checkpoints::HaveCheckpoint(pindex->nHeight)) { CTxIndex txindexOld; if (txdb.ReadTxIndex(hashTx, txindexOld)) { BOOST_FOREACH(CDiskTxPos &pos, txindexOld.vSpent)