Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Fix sequence lock time mask in TransactionSignatureChecker::CheckSequence #1645

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 6 additions & 11 deletions src/script/interpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1213,23 +1213,18 @@ bool TransactionSignatureChecker::CheckSequence(const CScriptNum& nSequence) con

// Mask off any bits that do not have consensus-enforced meaning
// before doing the integer comparisons
const uint32_t nLockTimeMask = CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG | CTxIn::LEGACY_SEQUENCE_LOCKTIME_MASK;
const int64_t txToSequenceMasked = txToSequence & nLockTimeMask;
const CScriptNum nSequenceMasked = nSequence & nLockTimeMask;
const int64_t txToSequenceMasked = txToSequence & CTxIn::DIP0001_SEQUENCE_LOCKTIME_MASK;
const CScriptNum nSequenceMasked = nSequence & CTxIn::DIP0001_SEQUENCE_LOCKTIME_MASK;

// There are two kinds of nSequence: lock-by-blockheight
// and lock-by-blocktime, distinguished by whether
// nSequenceMasked < CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG.
// CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG is set.
//
// 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)
)) {
// unless the type of nSequence being tested is the same as
// the nSequence in the transaction.
if (((nSequence ^ txToSequence) & CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG) != 0)
return false;
}

// Now that we know we're comparing apples-to-apples, the
// comparison is a simple numeric one.
Expand Down
11 changes: 11 additions & 0 deletions src/script/script.h
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,11 @@ class CScriptNum

inline CScriptNum& operator&=( const CScriptNum& rhs) { return operator&=(rhs.m_value); }

inline CScriptNum operator^( const int64_t& rhs) const { return CScriptNum(m_value ^ rhs);}
inline CScriptNum operator^( const CScriptNum& rhs) const { return operator^(rhs.m_value); }

inline CScriptNum& operator^=( const CScriptNum& rhs) { return operator^=(rhs.m_value); }

inline CScriptNum operator-() const
{
assert(m_value != std::numeric_limits<int64_t>::min());
Expand Down Expand Up @@ -299,6 +304,12 @@ class CScriptNum
return *this;
}

inline CScriptNum& operator^=( const int64_t& rhs)
{
m_value ^= rhs;
return *this;
}

int getint() const
{
if (m_value > std::numeric_limits<int>::max())
Expand Down