#include "checkpoints.h"
#include "db.h"
#include "txdb.h"
-#include "net.h"
#include "init.h"
#include "ui_interface.h"
#include "checkqueue.h"
CTransaction::GetLegacySigOpCount() const
{
unsigned int nSigOps = 0;
- if (!IsCoinBase() || nTime < COINBASE_SIGOPS_SWITCH_TIME)
+ if (!IsCoinBase())
{
// Coinbase scriptsigs are never executed, so there is
// no sense in calculation of sigops.
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"));
unsigned int GetNextTargetRequired(const CBlockIndex* pindexLast, bool fProofOfStake)
{
- CBigNum bnTargetLimit = !fProofOfStake ? bnProofOfWorkLimit : GetProofOfStakeLimit(pindexLast->nHeight, pindexLast->nTime);
-
if (pindexLast == NULL)
- return bnTargetLimit.GetCompact(); // genesis block
+ return bnProofOfWorkLimit.GetCompact(); // genesis block
+
+ CBigNum bnTargetLimit = !fProofOfStake ? bnProofOfWorkLimit : GetProofOfStakeLimit(pindexLast->nHeight, pindexLast->nTime);
const CBlockIndex* pindexPrev = GetLastBlockIndex(pindexLast, fProofOfStake);
if (pindexPrev->pprev == NULL)
if (!tx.IsCoinStake())
nFees += nTxValueIn - nTxValueOut;
+ unsigned int nFlags = SCRIPT_VERIFY_NOCACHE | SCRIPT_VERIFY_P2SH;
+
+ if (tx.nTime >= CHECKLOCKTIMEVERIFY_SWITCH_TIME) {
+ nFlags |= SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY;
+ nFlags |= SCRIPT_VERIFY_CHECKSEQUENCEVERIFY;
+ }
+
std::vector<CScriptCheck> vChecks;
- if (!tx.ConnectInputs(txdb, mapInputs, mapQueuedChanges, posThisTx, pindex, true, false, fScriptChecks, SCRIPT_VERIFY_NOCACHE | SCRIPT_VERIFY_P2SH, nScriptCheckThreads ? &vChecks : NULL))
+ if (!tx.ConnectInputs(txdb, mapInputs, mapQueuedChanges, posThisTx, pindex, true, false, fScriptChecks, nFlags, nScriptCheckThreads ? &vChecks : NULL))
return false;
control.Add(vChecks);
}
return error("AddToBlockIndex() : %s already exists", hash.ToString().substr(0,20).c_str());
// Construct new block index object
- CBlockIndex* pindexNew = new CBlockIndex(nFile, nBlockPos, *this);
+ CBlockIndex* pindexNew = new(nothrow) CBlockIndex(nFile, nBlockPos, *this);
if (!pindexNew)
return error("AddToBlockIndex() : new CBlockIndex failed");
pindexNew->phashBlock = &hash;
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()))
if (!GetBoolArg("-allowreceivebyip"))
{
- pfrom->PushMessage("reply", hashReply, (int)2, string(""));
+ pfrom->PushMessage("reply", hashReply, 2, string(""));
return true;
}
// Send back approval of order and pubkey to use
CScript scriptPubKey;
scriptPubKey << mapReuseKey[pfrom->addr] << OP_CHECKSIG;
- pfrom->PushMessage("reply", hashReply, (int)0, scriptPubKey);
+ pfrom->PushMessage("reply", hashReply, 0, scriptPubKey);
}
// orphan transactions
}
-} instance_of_cmaincleanup;
\ No newline at end of file
+} instance_of_cmaincleanup;