Skip to content

Commit

Permalink
Merge pull request #1584 from evoskuil/master
Browse files Browse the repository at this point in the history
Check version before internal lock.
  • Loading branch information
evoskuil authored Jan 13, 2025
2 parents 1cc7c18 + e980a01 commit 6aef84a
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 7 deletions.
7 changes: 4 additions & 3 deletions include/bitcoin/system/chain/input.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,14 +118,15 @@ class BC_API input
/// Requires metadata.height and median_time_past (otherwise returns true).
bool is_locked(size_t height, uint32_t median_time_past) const NOEXCEPT;

/// Any non-zero relative locktime value locks internally-spent input.
bool is_internally_locked() const NOEXCEPT;

protected:
input(const chain::point::cptr& point, const chain::script::cptr& script,
const chain::witness::cptr& witness, uint32_t sequence,
bool valid) NOEXCEPT;

/// Any non-zero relative locktime value locks internally-spent input.
friend class transaction;
bool is_internal_lock() const NOEXCEPT;

private:
typedef struct { size_t nominal; size_t witnessed; } sizes;

Expand Down
3 changes: 3 additions & 0 deletions include/bitcoin/system/chain/transaction.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,9 @@ class BC_API transaction
bool is_empty() const NOEXCEPT;
bool is_dusty(uint64_t minimum_output_value) const NOEXCEPT;

/// Requires no metadata, true if spend in own block would be locked.
bool is_internal_lock(const input& in) const NOEXCEPT;

/// Assumes coinbase if prevout not populated (returns only legacy sigops).
size_t signature_operations(bool bip16, bool bip141) const NOEXCEPT;

Expand Down
2 changes: 1 addition & 1 deletion src/chain/block.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -730,7 +730,7 @@ bool block::populate(const chain::context& ctx) const NOEXCEPT
if (point != points.end())
{
in->prevout = point->second;
in->metadata.locked = bip68 && in->is_internally_locked();
in->metadata.locked = bip68 && (*tx)->is_internal_lock(*in);
locked |= in->metadata.locked;
}
}
Expand Down
7 changes: 4 additions & 3 deletions src/chain/input.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -416,10 +416,11 @@ bool input::is_locked(size_t height, uint32_t median_time_past) const NOEXCEPT
metadata.median_time_past);
}

bool input::is_internally_locked() const NOEXCEPT
// protected (tx friend)
bool input::is_internal_lock() const NOEXCEPT
{
// Internal spends have zero relative height/mtp.
return is_locked(sequence_, {}, {}, {}, {});
// Internal spends have no relative height/mtp (any metadata values work).
return is_locked(metadata.height, metadata.median_time_past);
}

bool input::reserved_hash(hash_digest& out) const NOEXCEPT
Expand Down
12 changes: 12 additions & 0 deletions src/chain/transaction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1151,6 +1151,18 @@ bool transaction::is_immature(size_t height) const NOEXCEPT
return !std::all_of(inputs_->begin(), inputs_->end(), mature);
}

bool transaction::is_internal_lock(const input& in) const NOEXCEPT
{
// BIP68: not applied to the sequence of the input of a coinbase.
BC_ASSERT(!is_coinbase());

// BIP68: applied to txs with a version greater than or equal to two.
if (version_ < relative_locktime_min_version)
return false;

return in.is_internal_lock();
}

bool transaction::is_locked(size_t height,
uint32_t median_time_past) const NOEXCEPT
{
Expand Down

0 comments on commit 6aef84a

Please sign in to comment.