Skip to content

Commit

Permalink
Merge pull request #1595 from evoskuil/master
Browse files Browse the repository at this point in the history
Don't compute optional witness commitment (optimization).
  • Loading branch information
evoskuil authored Jan 28, 2025
2 parents 79c40fd + 7d4a517 commit 43c6c0f
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 5 deletions.
1 change: 1 addition & 0 deletions include/bitcoin/system/chain/block.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ class BC_API block
bool is_segregated() const NOEXCEPT;
size_t serialized_size(bool witness) const NOEXCEPT;
size_t signature_operations(bool bip16, bool bip141) const NOEXCEPT;
size_t segregated() const NOEXCEPT;

/// Computed malleation properties.
bool is_malleable() const NOEXCEPT;
Expand Down
6 changes: 6 additions & 0 deletions include/bitcoin/system/error/macros.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ class BC_API cat##_category \
static const message_map<cat##_t> messages; \
public: \
static const cat##_category singleton; \
static bool contains(const std::error_code& ec) noexcept; \
virtual const char* name() const noexcept; \
virtual std::string message(int condition) const noexcept; \
virtual std::error_condition default_error_condition(int value) const noexcept; \
Expand All @@ -74,6 +75,7 @@ class BC_API cat##_category \
static const message_map<cat##_t> messages; \
public: \
static const cat##_category singleton; \
static bool contains(const std::error_code& ec) noexcept; \
virtual const char* name() const noexcept; \
virtual std::string message(int condition) const noexcept; \
virtual std::error_condition default_error_condition(int value) const noexcept; \
Expand All @@ -84,6 +86,10 @@ std::error_condition make_error_condition(cat##_t value) noexcept

#define DEFINE_ERROR_T_CATEGORY(cat, category_name, unmapped) \
const cat##_category cat##_category::singleton; \
bool cat##_category::contains(const std::error_code& ec) noexcept \
{ \
return is_zero(std::strcmp(ec.category().name(), category_name)); \
} \
const char* cat##_category::name() const noexcept \
{ \
return category_name; \
Expand Down
20 changes: 16 additions & 4 deletions src/chain/block.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -587,6 +587,16 @@ bool block::is_segregated() const NOEXCEPT
return std::any_of(txs_->begin(), txs_->end(), segregated);
}

size_t block::segregated() const NOEXCEPT
{
const auto count_segregated = [](const auto& tx) NOEXCEPT
{
return tx->is_segregated();
};

return std::count_if(txs_->begin(), txs_->end(), count_segregated);
}

// The witness merkle root is obtained from wtxids, subject to malleation just
// as the txs commitment. However, since tx duplicates are precluded by the
// malleable32 (or complete) block check, there is no opportunity for this.
Expand All @@ -600,6 +610,10 @@ bool block::is_invalid_witness_commitment() const NOEXCEPT
if (coinbase->inputs_ptr()->empty())
return false;

// If no block tx has witness data the commitment is optional (bip141).
if (!is_segregated())
return false;

// If there is a valid commitment, return false (valid).
// Coinbase input witness must be 32 byte witness reserved value (bip141).
// Last output of commitment pattern holds the committed value (bip141).
Expand All @@ -610,10 +624,8 @@ bool block::is_invalid_witness_commitment() const NOEXCEPT
if (committed == sha256::double_hash(
generate_merkle_root(true), reserved))
return false;

// If no valid commitment, return true (invalid) if segregated.
// If no block tx has witness data the commitment is optional (bip141).
return is_segregated();

return true;
}

//*****************************************************************************
Expand Down
1 change: 1 addition & 0 deletions test/chain/block.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -460,6 +460,7 @@ BOOST_AUTO_TEST_CASE(block__hash__default__matches_header_hash)
// is_malleable
// is_segregated
// serialized_size
// segregated

// validation (public)
// ----------------------------------------------------------------------------
Expand Down
10 changes: 9 additions & 1 deletion test/error/error.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ BOOST_AUTO_TEST_CASE(error_t__code__message_overflow__default_message)
// Overflows can be cast in, and value retained, and yield default message.
BOOST_AUTO_TEST_CASE(error_t__code__value_overflow__default_message)
{
const auto overflow = static_cast<int>(error::error_last);
constexpr auto overflow = static_cast<int>(error::error_last);
const auto ec = code(static_cast<error::error_t>(overflow));
BOOST_REQUIRE(ec);
BOOST_REQUIRE_EQUAL(ec.message(), default_message);
Expand Down Expand Up @@ -108,6 +108,14 @@ BOOST_AUTO_TEST_CASE(error_t__code__category_name__expected)
{
BOOST_REQUIRE_EQUAL(code().category().name(), system_category_name);
BOOST_REQUIRE_EQUAL(code(error::success).category().name(), bitcoin_category_name);
BOOST_REQUIRE_NE(code(error::script_success).category().name(), code(error::success).category().name());
}

BOOST_AUTO_TEST_CASE(error_t__code__category_contains__expected)
{
BOOST_REQUIRE(system::error::error_category::contains(system::error::success));
BOOST_REQUIRE(!system::error::script_error_category::contains(system::error::success));
BOOST_REQUIRE(system::error::script_error_category::contains(system::error::script_success));
}

BOOST_AUTO_TEST_CASE(error_t__code__default_error_condition_category_name__expected)
Expand Down

0 comments on commit 43c6c0f

Please sign in to comment.