return DoS(10, error("CTransaction::CheckTransaction() : vin empty"));
if (vout.empty())
return DoS(10, error("CTransaction::CheckTransaction() : vout empty"));
+ // Time (prevent mempool memory exhaustion attack)
+ // Comes into force since 20 December 2015.
+ if (nTime > 1450569600 && nTime > FutureDrift(GetAdjustedTime()))
+ return DoS(10, error("CTransaction::CheckTransaction() : timestamp is too far into the future"));
// Size limits
if (::GetSerializeSize(*this, SER_NETWORK, PROTOCOL_VERSION) > MAX_BLOCK_SIZE)
return DoS(100, error("CTransaction::CheckTransaction() : size limits failed"));
if (nBits != GetNextTargetRequired(pindexPrev, IsProofOfStake()))
return DoS(100, error("AcceptBlock() : incorrect %s", IsProofOfWork() ? "proof-of-work" : "proof-of-stake"));
+ int64_t nMedianTimePast = pindexPrev->GetMedianTimePast();
+ int nMaxOffset = 12 * 3600; // 12 hours
+ if (pindexPrev->nTime < 1450569600)
+ nMaxOffset = 7 * 86400; // One week until 20 Dec, 2015
+
// Check timestamp against prev
- if (GetBlockTime() <= pindexPrev->GetMedianTimePast() || FutureDrift(GetBlockTime()) < pindexPrev->GetBlockTime())
+ if (GetBlockTime() <= nMedianTimePast || FutureDrift(GetBlockTime()) < pindexPrev->GetBlockTime())
return error("AcceptBlock() : block's timestamp is too early");
+ // Don't accept blocks with future timestamps
+ if (pindexPrev->nHeight > 1 && nMedianTimePast + nMaxOffset < GetBlockTime())
+ return error("AcceptBlock() : block's timestamp is too far in the future");
+
// Check that all transactions are finalized
BOOST_FOREACH(const CTransaction& tx, vtx)
if (!tx.IsFinal(nHeight, GetBlockTime()))
// orphan transactions
}
-} instance_of_cmaincleanup;
\ No newline at end of file
+} instance_of_cmaincleanup;