nBlocks = nMaxLocks / 48768;
nDeepReorg = (nBlocks - 1) / 2;
- printf("Final lk_max_locks is %lu, sufficient for (worst case) %d block%s in a single transaction (up to a %d-deep reorganization)\n", (unsigned long)nMaxLocks, nBlocks, (nBlocks == 1) ? "" : "s", nDeepReorg);
+ printf("Final lk_max_locks is %u, sufficient for (worst case) %d block%s in a single transaction (up to a %d-deep reorganization)\n", nMaxLocks, nBlocks, (nBlocks == 1) ? "" : "s", nDeepReorg);
if (nDeepReorg < 3)
{
if (nBlocks < 1)
- strMessage = strprintf(_("Warning: DB_CONFIG has set_lk_max_locks %lu, which may be too low for a single block. If this limit is reached, NovaCoin may stop working."), (unsigned long)nMaxLocks);
+ strMessage = strprintf(_("Warning: DB_CONFIG has set_lk_max_locks %u, which may be too low for a single block. If this limit is reached, NovaCoin may stop working."), nMaxLocks);
else
- strMessage = strprintf(_("Warning: DB_CONFIG has set_lk_max_locks %lu, which may be too low for a common blockchain reorganization. If this limit is reached, NovaCoin may stop working."), (unsigned long)nMaxLocks);
+ strMessage = strprintf(_("Warning: DB_CONFIG has set_lk_max_locks %u, which may be too low for a common blockchain reorganization. If this limit is reached, NovaCoin may stop working."), nMaxLocks);
strMiscWarning = strMessage;
printf("*** %s\n", strMessage.c_str());
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;
+ }
+
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);
}
if (nHeight >= 9689 || fTestNet)
{
// Take last bit of block hash as entropy bit
- unsigned int nEntropyBit = ((GetHash().Get64()) & 1ULL);
+ unsigned int nEntropyBit = (GetHash().Get64()) & (uint64_t)1;
if (fDebug && GetBoolArg("-printstakemodifier"))
printf("GetStakeEntropyBit: nTime=%u hashBlock=%s nEntropyBit=%u\n", nTime, GetHash().ToString().c_str(), nEntropyBit);
return nEntropyBit;
"getmininginfo\n"
"Returns an object containing mining-related information.");
- Object obj, diff, weight;
+ Object obj, diff;
obj.push_back(Pair("blocks", (int)nBestHeight));
obj.push_back(Pair("currentblocksize",(uint64_t)nLastBlockSize));
obj.push_back(Pair("currentblocktx",(uint64_t)nLastBlockTx));
int nRequired = params[0].get_int();
const Array& keys = params[1].get_array();
- string strAccount;
// Gather public keys
if (nRequired < 1)
case OP_ENDIF : return "OP_ENDIF";
case OP_VERIFY : return "OP_VERIFY";
case OP_RETURN : return "OP_RETURN";
+ case OP_CHECKLOCKTIMEVERIFY : return "OP_CHECKLOCKTIMEVERIFY";
// stack ops
case OP_TOALTSTACK : return "OP_TOALTSTACK";
// expanson
case OP_NOP1 : return "OP_NOP1";
- case OP_NOP2 : return "OP_NOP2";
case OP_NOP3 : return "OP_NOP3";
case OP_NOP4 : return "OP_NOP4";
case OP_NOP5 : return "OP_NOP5";
if (5 + nLenR >= vchSig.size())
return error("Non-canonical signature: S length misplaced");
unsigned int nLenS = vchSig[5+nLenR];
- if ((unsigned long)(nLenR + nLenS + (fWithHashType ? 7 : 6)) != vchSig.size())
+ if ((nLenR + nLenS + (fWithHashType ? 7 : 6)) != vchSig.size())
return error("Non-canonical signature: R+S length mismatch");
const unsigned char *R = &vchSig[4];
// Control
//
case OP_NOP:
- case OP_NOP1: case OP_NOP2: case OP_NOP3: case OP_NOP4: case OP_NOP5:
+ case OP_NOP1: case OP_NOP3: case OP_NOP4: case OP_NOP5:
case OP_NOP6: case OP_NOP7: case OP_NOP8: case OP_NOP9: case OP_NOP10:
break;
}
break;
+ case OP_CHECKLOCKTIMEVERIFY:
+ {
+ // CHECKLOCKTIMEVERIFY
+ //
+ // (nLockTime -- nLockTime)
+ if (!(flags & SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY))
+ break; // treat as a NOP is not enabled
+ if (stack.size() < 1)
+ return false;
+ const CBigNum nLockTime = CastToBigNum(stacktop(-1));
+ if (nLockTime < 0)
+ return false; // Negative argument is senseless.
+
+ if (!( // We can have either lock-by-blockheight or lock-by-blocktime.
+ (txTo.nLockTime < LOCKTIME_THRESHOLD && nLockTime < LOCKTIME_THRESHOLD) ||
+ (txTo.nLockTime >= LOCKTIME_THRESHOLD && nLockTime >= LOCKTIME_THRESHOLD)
+ ))
+ return false;
+
+ // Now we can perform a simple numerical comparison
+ if (nLockTime > (int64_t)txTo.nLockTime)
+ return false;
+
+ // Finally the nLockTime feature can be disabled and thus
+ // CHECKLOCKTIMEVERIFY bypassed if every txin has been
+ // finalized by setting nSequence to maxint. The
+ // transaction would be allowed into the blockchain, making
+ // the opcode ineffective.
+ //
+ // Testing if this vin is not final is sufficient to
+ // prevent this condition. Alternatively we could test all
+ // inputs, but testing just this input minimizes the data
+ // required to prove correct CHECKLOCKTIMEVERIFY execution.
+ if (txTo.vin[nIn].IsFinal())
+ return false;
+ break;
+ }
//
// Stack ops
mTemplates.insert(make_pair(TX_NULL_DATA, CScript() << OP_RETURN << OP_SMALLDATA));
}
+ vSolutionsRet.clear();
+
// Shortcut for pay-to-script-hash, which are more constrained than the other types:
// it is always OP_HASH160 20 [20 byte hash] OP_EQUAL
if (scriptPubKey.IsPayToScriptHash())
return true;
}
+ // Provably prunable, data-carrying output
+ //
+ // So long as script passes the IsUnspendable() test and all but the first
+ // byte passes the IsPushOnly() test we don't care what exactly is in the
+ // script.
+ if (scriptPubKey.size() >= 1 && scriptPubKey[0] == OP_RETURN && scriptPubKey.IsPushOnly(scriptPubKey.begin()+1)) {
+ typeRet = TX_NULL_DATA;
+ return true;
+ }
+
// Scan templates
const CScript& script1 = scriptPubKey;
BOOST_FOREACH(const PAIRTYPE(txnouttype, CScript)& tplate, mTemplates)
SCRIPT_VERIFY_STRICTENC = (1U << 1), // enforce strict conformance to DER and SEC2 for signatures and pubkeys
SCRIPT_VERIFY_LOW_S = (1U << 2), // enforce low S values in signatures (depends on STRICTENC)
SCRIPT_VERIFY_NOCACHE = (1U << 3), // do not store results in signature cache (but do query it)
- SCRIPT_VERIFY_NULLDUMMY = (1U << 4) // verify dummy stack item consumed by CHECKMULTISIG is of zero-length
+ SCRIPT_VERIFY_NULLDUMMY = (1U << 4), // verify dummy stack item consumed by CHECKMULTISIG is of zero-length
+ SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY = (1U << 9)
+
};
// Strict verification:
OP_ENDIF = 0x68,
OP_VERIFY = 0x69,
OP_RETURN = 0x6a,
+ OP_CHECKLOCKTIMEVERIFY = 0xb1,
// stack ops
OP_TOALTSTACK = 0x6b,
// expansion
OP_NOP1 = 0xb0,
- OP_NOP2 = 0xb1,
OP_NOP3 = 0xb2,
OP_NOP4 = 0xb3,
OP_NOP5 = 0xb4,
bool IsPayToScriptHash() const;
- // Called by CTransaction::IsStandard and P2SH VerifyScript (which makes it consensus-critical).
- bool IsPushOnly() const
+ bool IsPushOnly(const_iterator pc) const
{
- const_iterator pc = begin();
while (pc < end())
{
opcodetype opcode;
return true;
}
+ // Called by CTransaction::IsStandard and P2SH VerifyScript (which makes it consensus-critical).
+ bool IsPushOnly() const
+ {
+ return this->IsPushOnly(begin());
+ }
+
// Called by CTransaction::IsStandard.
bool HasCanonicalPushes() const;
static const unsigned int TARGETS_SWITCH_TIME = 1374278400; // Saturday, 20-Jul-2013 00:00:00 UTC
static const unsigned int COINBASE_SIGOPS_SWITCH_TIME = 1447977600; // Friday, 20-Nov-15 00:00:00 UTC
static const unsigned int SMALLDATA_SWITCH_TIME = 1458432000; // Sunday, 20-Mar-16 00:00:00 UTC
-
+static const unsigned int CHECKLOCKTIMEVERIFY_SWITCH_TIME = 1461110400; // Wednesday, 20-Apr-16 00:00:00 UTC
#endif