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

Check version before internal lock. #1584

Merged
merged 1 commit into from
Jan 13, 2025
Merged
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
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
Loading