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

Add malleated64 check based on coinbase invalidity. #1481

Merged
merged 1 commit into from
Jun 18, 2024
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
4 changes: 3 additions & 1 deletion include/bitcoin/system/chain/block.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,11 @@ class BC_API block

/// Computed malleation properties.
bool is_malleable() const NOEXCEPT;
bool is_malleable64() const NOEXCEPT;
bool is_malleated() const NOEXCEPT;
bool is_malleable32() const NOEXCEPT;
bool is_malleated32() const NOEXCEPT;
bool is_malleable64() const NOEXCEPT;
bool is_malleated64() const NOEXCEPT;

/// Validation.
/// -----------------------------------------------------------------------
Expand Down
2 changes: 1 addition & 1 deletion include/bitcoin/system/error/block_error_t.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ enum block_error_t : uint8_t
forward_reference,
invalid_transaction_commitment,
block_legacy_sigop_limit,
type32_malleated,
block_malleated,

// accept block
block_non_final,
Expand Down
20 changes: 17 additions & 3 deletions src/chain/block.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,11 @@ bool block::is_malleable() const NOEXCEPT
return is_malleable64() || is_malleable32();
}

bool block::is_malleated() const NOEXCEPT
{
return is_malleated32() || is_malleated64();
}

bool block::is_malleable32() const NOEXCEPT
{
const auto unmalleated = txs_->size();
Expand Down Expand Up @@ -514,6 +519,14 @@ bool block::is_malleable64(const transaction_cptrs& txs) NOEXCEPT
return !txs.empty() && std::all_of(txs.begin(), txs.end(), two_leaves);
}

// A mallaeable64 block is considered malleated if the first tx is not a valid
// coinbase. It is possible but computationally infeasible to grind a valid
// coinbase and therefore treated similarly to sha256 hash collision.
bool block::is_malleated64() const NOEXCEPT
{
return is_malleable64(*txs_) && !txs_->front()->is_coinbase();
}

bool block::is_segregated() const NOEXCEPT
{
const auto segregated = [](const auto& tx) NOEXCEPT
Expand Down Expand Up @@ -736,9 +749,10 @@ code block::check(bool bypass) const NOEXCEPT
if (is_invalid_merkle_root())
return error::invalid_transaction_commitment;

// type32_malleated is subset of is_internal_double_spend
if (bypass && is_malleated32())
return error::type32_malleated;
// type32 malleated is a subset of is_internal_double_spend
// type64 malleated is a subset of first_not_coinbase
if (bypass && is_malleated())
return error::block_malleated;
if (bypass)
return error::block_success;

Expand Down
2 changes: 1 addition & 1 deletion src/error/block_error_t.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ DEFINE_ERROR_T_MESSAGE_MAP(block_error)
{ forward_reference, "transactions out of order" },
{ invalid_transaction_commitment, "invalid transaction commitment" },
{ block_legacy_sigop_limit, "too many block legacy signature operations" },
{ type32_malleated, "block is type32 malleated" },
{ block_malleated, "block is malleated" },

// accept block
{ block_non_final, "block contains a non-final transaction" },
Expand Down
6 changes: 3 additions & 3 deletions test/error/block_error_t.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -183,13 +183,13 @@ BOOST_AUTO_TEST_CASE(block_error_t__code__block_legacy_sigop_limit__true_exected
BOOST_REQUIRE_EQUAL(ec.message(), "too many block legacy signature operations");
}

BOOST_AUTO_TEST_CASE(block_error_t__code__type32_malleated__true_exected_message)
BOOST_AUTO_TEST_CASE(block_error_t__code__block_malleated__true_exected_message)
{
constexpr auto value = error::type32_malleated;
constexpr auto value = error::block_malleated;
const auto ec = code(value);
BOOST_REQUIRE(ec);
BOOST_REQUIRE(ec == value);
BOOST_REQUIRE_EQUAL(ec.message(), "block is type32 malleated");
BOOST_REQUIRE_EQUAL(ec.message(), "block is malleated");
}

// accept block
Expand Down
Loading