Skip to content
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
3 changes: 2 additions & 1 deletion include/bitcoin/node/error.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,8 @@ enum error_t : uint8_t
estimates_push1,
estimates_push2,
estimates_pop1,
estimates_pop2
estimates_pop2,
capture_fault
};

// No current need for error_code equivalence mapping.
Expand Down
35 changes: 23 additions & 12 deletions src/chasers/chaser_validate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,7 @@ code chaser_validate::validate(bool bypass, const chain::block& block,
{
using namespace chain;
std::atomic<size_t> set{};
code capture_ec{};

const auto to_events = [](opcode op) NOEXCEPT
{
Expand Down Expand Up @@ -361,19 +362,19 @@ code chaser_validate::validate(bool bypass, const chain::block& block,
{
case signatures::miss::ecdsa:
++missed_ecdsa_;
fire(events::missed_ecdsa, ctx.height);
////fire(events::missed_ecdsa, ctx.height);
break;
case signatures::miss::multisig:
++missed_multisig_;
fire(events::missed_multisig, ctx.height);
////fire(events::missed_multisig, ctx.height);
break;
case signatures::miss::schnorr:
++missed_schnorr_;
fire(events::missed_schnorr, ctx.height);
////fire(events::missed_schnorr, ctx.height);
break;
case signatures::miss::overflow:
++missed_threshold_;
fire(events::missed_overflow, ctx.height);
////fire(events::missed_overflow, ctx.height);
break;

// should be no path to this.
Expand All @@ -386,14 +387,14 @@ code chaser_validate::validate(bool bypass, const chain::block& block,
const ec_signature& sign) NOEXCEPT
{
++ecdsa_;
fire(to_events(opcode::checksigverify), ctx.height);
////fire(to_events(opcode::checksigverify), ctx.height);
return query.set_signature(digest, point, sign, link);
},
.schnorr = [&](const hash_digest& digest, const ec_xonly& point,
const ec_signature& sign) NOEXCEPT
{
++schnorr_;
fire(to_events(opcode::checksigadd), ctx.height);
////fire(to_events(opcode::checksigadd), ctx.height);
return query.set_signature(digest, point, sign, link);
},
.multisig = [&](const hash_digest& digest,
Expand All @@ -402,28 +403,37 @@ code chaser_validate::validate(bool bypass, const chain::block& block,
{
BC_ASSERT(points.size() == signs.size());
multisig_ += points.size();
fire(to_events(opcode::checkmultisigverify), ctx.height);
////fire(to_events(opcode::checkmultisigverify), ctx.height);
return query.set_signatures(digest, points, signs, set, link);
},
.threshold = [&](
const signatures::threshold_entries& group) NOEXCEPT
{
// Sets condition to opcode::checksig for all required.
threshold_ += group.entries.size();
fire(to_events(group.condition), ctx.height);
return query.set_signatures(group, set, link);
////fire(to_events(group.condition), ctx.height);

// Script always processing proceeds as if batch succeeded.
if (!query.set_signatures(group, set, link))
capture_ec = fault(error::capture_fault);
}
};

// Prioritize validation failure over capture failure.
if ((ec = block.connect(ctx, capture)))
return ec;

const auto log_capture = [&](std::string_view name, size_t captured,
size_t missed) NOEXCEPT
// TODO: repost block (link) to work queue in complete_block
// TODO: based on error::capture_fault.
if (capture_ec)
return capture_ec;

const auto log_capture = [&](std::string_view name,
size_t captured, size_t missed) NOEXCEPT
{
if (!to_bool(captured) && !to_bool(missed)) return;
const auto ratio = (100.0f * captured) / (captured + missed);
const auto rate = (boost_format("%.2f") % ratio).str();
const auto rate = (boost_format("%.4f") % ratio).str();
LOGA("Efficiency " << name << rate << "% = " << captured
<< "/(" << captured << "+" << missed << ")");
};
Expand Down Expand Up @@ -463,6 +473,7 @@ void chaser_validate::complete_block(const code& ec, const header_link& link,
// Node errors are fatal.
if (node::error::error_category::contains(ec))
{
// fault(ec) initiates recovery if caused by disk full condition.
LOGF("Fault validating [" << height << "] " << ec.message());
fault(ec);
return;
Expand Down
3 changes: 2 additions & 1 deletion src/error.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,8 @@ DEFINE_ERROR_T_MESSAGE_MAP(error)
{ estimates_push1, "estimates_push1" },
{ estimates_push2, "estimates_push2" },
{ estimates_pop1, "estimates_pop1" },
{ estimates_pop2, "estimates_pop2" }
{ estimates_pop2, "estimates_pop2" },
{ capture_fault, "capture_fault" }
};

DEFINE_ERROR_T_CATEGORY(error, "node", "node code")
Expand Down
2 changes: 1 addition & 1 deletion src/full_node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ void full_node::fault(const code& ec) NOEXCEPT
}
else if (query_.is_fault())
{
LOGF("Store faulted '" << query_.get_fault().message()
LOGF("Store fault (unrecoverable) '" << query_.get_fault().message()
<< "' following, " << ec.message());
}
else if (ec)
Expand Down
9 changes: 9 additions & 0 deletions test/error.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -297,4 +297,13 @@ BOOST_AUTO_TEST_CASE(error_t__code__estimates_pop2__true_expected_message)
BOOST_REQUIRE_EQUAL(ec.message(), "estimates_pop2");
}

BOOST_AUTO_TEST_CASE(error_t__code__capture_fault__true_expected_message)
{
constexpr auto value = error::capture_fault;
const auto ec = code(value);
BOOST_REQUIRE(ec);
BOOST_REQUIRE(ec == value);
BOOST_REQUIRE_EQUAL(ec.message(), "capture_fault");
}

BOOST_AUTO_TEST_SUITE_END()
Loading