Skip to content

Commit 43c6c0f

Browse files
authored
Merge pull request #1595 from evoskuil/master
Don't compute optional witness commitment (optimization).
2 parents 79c40fd + 7d4a517 commit 43c6c0f

5 files changed

Lines changed: 33 additions & 5 deletions

File tree

include/bitcoin/system/chain/block.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ class BC_API block
9898
bool is_segregated() const NOEXCEPT;
9999
size_t serialized_size(bool witness) const NOEXCEPT;
100100
size_t signature_operations(bool bip16, bool bip141) const NOEXCEPT;
101+
size_t segregated() const NOEXCEPT;
101102

102103
/// Computed malleation properties.
103104
bool is_malleable() const NOEXCEPT;

include/bitcoin/system/error/macros.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ class BC_API cat##_category \
5757
static const message_map<cat##_t> messages; \
5858
public: \
5959
static const cat##_category singleton; \
60+
static bool contains(const std::error_code& ec) noexcept; \
6061
virtual const char* name() const noexcept; \
6162
virtual std::string message(int condition) const noexcept; \
6263
virtual std::error_condition default_error_condition(int value) const noexcept; \
@@ -74,6 +75,7 @@ class BC_API cat##_category \
7475
static const message_map<cat##_t> messages; \
7576
public: \
7677
static const cat##_category singleton; \
78+
static bool contains(const std::error_code& ec) noexcept; \
7779
virtual const char* name() const noexcept; \
7880
virtual std::string message(int condition) const noexcept; \
7981
virtual std::error_condition default_error_condition(int value) const noexcept; \
@@ -84,6 +86,10 @@ std::error_condition make_error_condition(cat##_t value) noexcept
8486

8587
#define DEFINE_ERROR_T_CATEGORY(cat, category_name, unmapped) \
8688
const cat##_category cat##_category::singleton; \
89+
bool cat##_category::contains(const std::error_code& ec) noexcept \
90+
{ \
91+
return is_zero(std::strcmp(ec.category().name(), category_name)); \
92+
} \
8793
const char* cat##_category::name() const noexcept \
8894
{ \
8995
return category_name; \

src/chain/block.cpp

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -587,6 +587,16 @@ bool block::is_segregated() const NOEXCEPT
587587
return std::any_of(txs_->begin(), txs_->end(), segregated);
588588
}
589589

590+
size_t block::segregated() const NOEXCEPT
591+
{
592+
const auto count_segregated = [](const auto& tx) NOEXCEPT
593+
{
594+
return tx->is_segregated();
595+
};
596+
597+
return std::count_if(txs_->begin(), txs_->end(), count_segregated);
598+
}
599+
590600
// The witness merkle root is obtained from wtxids, subject to malleation just
591601
// as the txs commitment. However, since tx duplicates are precluded by the
592602
// malleable32 (or complete) block check, there is no opportunity for this.
@@ -600,6 +610,10 @@ bool block::is_invalid_witness_commitment() const NOEXCEPT
600610
if (coinbase->inputs_ptr()->empty())
601611
return false;
602612

613+
// If no block tx has witness data the commitment is optional (bip141).
614+
if (!is_segregated())
615+
return false;
616+
603617
// If there is a valid commitment, return false (valid).
604618
// Coinbase input witness must be 32 byte witness reserved value (bip141).
605619
// Last output of commitment pattern holds the committed value (bip141).
@@ -610,10 +624,8 @@ bool block::is_invalid_witness_commitment() const NOEXCEPT
610624
if (committed == sha256::double_hash(
611625
generate_merkle_root(true), reserved))
612626
return false;
613-
614-
// If no valid commitment, return true (invalid) if segregated.
615-
// If no block tx has witness data the commitment is optional (bip141).
616-
return is_segregated();
627+
628+
return true;
617629
}
618630

619631
//*****************************************************************************

test/chain/block.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -460,6 +460,7 @@ BOOST_AUTO_TEST_CASE(block__hash__default__matches_header_hash)
460460
// is_malleable
461461
// is_segregated
462462
// serialized_size
463+
// segregated
463464

464465
// validation (public)
465466
// ----------------------------------------------------------------------------

test/error/error.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ BOOST_AUTO_TEST_CASE(error_t__code__message_overflow__default_message)
4040
// Overflows can be cast in, and value retained, and yield default message.
4141
BOOST_AUTO_TEST_CASE(error_t__code__value_overflow__default_message)
4242
{
43-
const auto overflow = static_cast<int>(error::error_last);
43+
constexpr auto overflow = static_cast<int>(error::error_last);
4444
const auto ec = code(static_cast<error::error_t>(overflow));
4545
BOOST_REQUIRE(ec);
4646
BOOST_REQUIRE_EQUAL(ec.message(), default_message);
@@ -108,6 +108,14 @@ BOOST_AUTO_TEST_CASE(error_t__code__category_name__expected)
108108
{
109109
BOOST_REQUIRE_EQUAL(code().category().name(), system_category_name);
110110
BOOST_REQUIRE_EQUAL(code(error::success).category().name(), bitcoin_category_name);
111+
BOOST_REQUIRE_NE(code(error::script_success).category().name(), code(error::success).category().name());
112+
}
113+
114+
BOOST_AUTO_TEST_CASE(error_t__code__category_contains__expected)
115+
{
116+
BOOST_REQUIRE(system::error::error_category::contains(system::error::success));
117+
BOOST_REQUIRE(!system::error::script_error_category::contains(system::error::success));
118+
BOOST_REQUIRE(system::error::script_error_category::contains(system::error::script_success));
111119
}
112120

113121
BOOST_AUTO_TEST_CASE(error_t__code__default_error_condition_category_name__expected)

0 commit comments

Comments
 (0)