|
|
@ -1157,33 +1157,27 @@ bool TransactionSignatureChecker::CheckSig(const vector<unsigned char>& vchSigIn |
|
|
|
return true; |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static bool VerifyLockTime(int64_t txToLockTime, int64_t nThreshold, const CScriptNum& nLockTime) |
|
|
|
bool TransactionSignatureChecker::CheckLockTime(const CScriptNum& nLockTime) const |
|
|
|
{ |
|
|
|
{ |
|
|
|
// There are two kinds of nLockTime: lock-by-blockheight
|
|
|
|
// There are two kinds of nLockTime: lock-by-blockheight
|
|
|
|
// and lock-by-blocktime, distinguished by whether
|
|
|
|
// and lock-by-blocktime, distinguished by whether
|
|
|
|
// nLockTime < nThreshold (either LOCKTIME_THRESHOLD or
|
|
|
|
// nLockTime < LOCKTIME_THRESHOLD.
|
|
|
|
// CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG).
|
|
|
|
|
|
|
|
//
|
|
|
|
//
|
|
|
|
// We want to compare apples to apples, so fail the script
|
|
|
|
// We want to compare apples to apples, so fail the script
|
|
|
|
// unless the type of nLockTime being tested is the same as
|
|
|
|
// unless the type of nLockTime being tested is the same as
|
|
|
|
// the nLockTime in the transaction.
|
|
|
|
// the nLockTime in the transaction.
|
|
|
|
if (!( |
|
|
|
if (!( |
|
|
|
(txToLockTime < nThreshold && nLockTime < nThreshold) || |
|
|
|
(txTo->nLockTime < LOCKTIME_THRESHOLD && nLockTime < LOCKTIME_THRESHOLD) || |
|
|
|
(txToLockTime >= nThreshold && nLockTime >= nThreshold) |
|
|
|
(txTo->nLockTime >= LOCKTIME_THRESHOLD && nLockTime >= LOCKTIME_THRESHOLD) |
|
|
|
)) |
|
|
|
)) |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
|
|
// Now that we know we're comparing apples-to-apples, the
|
|
|
|
// Now that we know we're comparing apples-to-apples, the
|
|
|
|
// comparison is a simple numeric one.
|
|
|
|
// comparison is a simple numeric one.
|
|
|
|
if (nLockTime > txToLockTime) |
|
|
|
if (nLockTime > (int64_t)txTo->nLockTime) |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
|
|
return true; |
|
|
|
// Finally the nLockTime feature can be disabled and thus
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool TransactionSignatureChecker::CheckLockTime(const CScriptNum& nLockTime) const |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
// The nLockTime feature can be disabled and thus
|
|
|
|
|
|
|
|
// CHECKLOCKTIMEVERIFY bypassed if every txin has been
|
|
|
|
// CHECKLOCKTIMEVERIFY bypassed if every txin has been
|
|
|
|
// finalized by setting nSequence to maxint. The
|
|
|
|
// finalized by setting nSequence to maxint. The
|
|
|
|
// transaction would be allowed into the blockchain, making
|
|
|
|
// transaction would be allowed into the blockchain, making
|
|
|
@ -1196,9 +1190,6 @@ bool TransactionSignatureChecker::CheckLockTime(const CScriptNum& nLockTime) con |
|
|
|
if (CTxIn::SEQUENCE_FINAL == txTo->vin[nIn].nSequence) |
|
|
|
if (CTxIn::SEQUENCE_FINAL == txTo->vin[nIn].nSequence) |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
|
|
if (!::VerifyLockTime((int64_t)txTo->nLockTime, LOCKTIME_THRESHOLD, nLockTime)) |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return true; |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -1221,17 +1212,32 @@ bool TransactionSignatureChecker::CheckSequence(const CScriptNum& nSequence) con |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
|
|
// Mask off any bits that do not have consensus-enforced meaning
|
|
|
|
// Mask off any bits that do not have consensus-enforced meaning
|
|
|
|
// before doing the integer comparisons of ::VerifyLockTime.
|
|
|
|
// before doing the integer comparisons
|
|
|
|
const uint32_t nLockTimeMask = CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG |
|
|
|
const uint32_t nLockTimeMask = CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG | CTxIn::SEQUENCE_LOCKTIME_MASK; |
|
|
|
| CTxIn::SEQUENCE_LOCKTIME_MASK; |
|
|
|
const int64_t txToSequenceMasked = txToSequence & nLockTimeMask; |
|
|
|
|
|
|
|
const CScriptNum nSequenceMasked = nSequence & nLockTimeMask; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// There are two kinds of nSequence: lock-by-blockheight
|
|
|
|
|
|
|
|
// and lock-by-blocktime, distinguished by whether
|
|
|
|
|
|
|
|
// nSequenceMasked < CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG.
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// We want to compare apples to apples, so fail the script
|
|
|
|
|
|
|
|
// unless the type of nSequenceMasked being tested is the same as
|
|
|
|
|
|
|
|
// the nSequenceMasked in the transaction.
|
|
|
|
|
|
|
|
if (!( |
|
|
|
|
|
|
|
(txToSequenceMasked < CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG && nSequenceMasked < CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG) || |
|
|
|
|
|
|
|
(txToSequenceMasked >= CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG && nSequenceMasked >= CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG) |
|
|
|
|
|
|
|
)) |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
|
|
if (!::VerifyLockTime(txToSequence & nLockTimeMask, CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG, nSequence & nLockTimeMask)) |
|
|
|
// Now that we know we're comparing apples-to-apples, the
|
|
|
|
|
|
|
|
// comparison is a simple numeric one.
|
|
|
|
|
|
|
|
if (nSequenceMasked > txToSequenceMasked) |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
|
|
return true; |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* serror) |
|
|
|
bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* serror) |
|
|
|
{ |
|
|
|
{ |
|
|
|
set_error(serror, SCRIPT_ERR_UNKNOWN_ERROR); |
|
|
|
set_error(serror, SCRIPT_ERR_UNKNOWN_ERROR); |
|
|
|