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
9 changes: 8 additions & 1 deletion include/bitcoin/node/chasers/chaser_validate.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,13 @@ class BCN_API chaser_validate
virtual void do_checked(height_t height) NOEXCEPT;
virtual void do_bump(height_t height) NOEXCEPT;

virtual void validate_block(const database::header_link& link) NOEXCEPT;
virtual void validate_block(const database::header_link& link,
bool bypass) NOEXCEPT;
virtual code validate(bool bypass, const system::chain::block& block,
const database::header_link& link,
const system::chain::context& ctx) NOEXCEPT;
virtual code populate(bool bypass, const system::chain::block& block,
const system::chain::context& ctx) NOEXCEPT;
virtual void complete_block(const code& ec,
const database::header_link& link, size_t height) NOEXCEPT;

Expand All @@ -77,6 +83,7 @@ class BCN_API chaser_validate
const uint64_t initial_subsidy_;
const size_t maximum_backlog_;
const bool concurrent_;
const bool filter_;
};

} // namespace node
Expand Down
84 changes: 60 additions & 24 deletions src/chasers/chaser_validate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ chaser_validate::chaser_validate(full_node& node) NOEXCEPT
subsidy_interval_(node.config().bitcoin.subsidy_interval_blocks),
initial_subsidy_(node.config().bitcoin.initial_subsidy()),
maximum_backlog_(node.config().node.maximum_concurrency_()),
concurrent_(node.config().node.concurrent_validation)
concurrent_(node.config().node.concurrent_validation),
filter_(node.archive().neutrino_enabled())
{
}

Expand Down Expand Up @@ -187,20 +188,24 @@ void chaser_validate::do_bump(height_t) NOEXCEPT

set_position(height);

if ((ec == database::error::block_valid) ||
const auto bypass =
(ec == database::error::block_valid) ||
(ec == database::error::block_confirmable) ||
is_under_checkpoint(height) || query.is_milestone(link))
is_under_checkpoint(height) || query.is_milestone(link);

if (bypass && !filter_)
{
complete_block(error::success, link, height);
continue;
}

PARALLEL(validate_block, link);
PARALLEL(validate_block, link, bypass);
}
}

// Unstranded (concurrent by block).
void chaser_validate::validate_block(const header_link& link) NOEXCEPT
void chaser_validate::validate_block(const header_link& link,
bool bypass) NOEXCEPT
{
if (closed())
return;
Expand All @@ -218,44 +223,75 @@ void chaser_validate::validate_block(const header_link& link) NOEXCEPT
{
ec = error::validate2;
}
else if (!block->populate(ctx))
{
ec = system::error::relative_time_locked;
}
else if (!query.populate(*block))
{
ec = system::error::missing_previous_output;
}
else if ((ec = block->accept(ctx, subsidy_interval_, initial_subsidy_)))
else if ((ec = populate(bypass, *block, ctx)))
{
if (!query.set_block_unconfirmable(link))
ec = error::validate3;
}
else if ((ec = block->connect(ctx)))
else if ((ec = validate(bypass, *block, link, ctx)))
{
if (!query.set_block_unconfirmable(link))
ec = error::validate4;
}
else if (!query.set_block_valid(link, block->fees()))
else if (!query.set_filter_body(link, *block))
{
ec = error::validate5;
}
else if (!query.set_prevouts(link, *block))
else
{
ec = error::validate6;
fire(events::block_validated, ctx.height);
}
else if (!query.set_filter_body(link, *block))

// Return to strand to handle result.
POST(complete_block, ec, link, ctx.height);
}

code chaser_validate::populate(bool bypass, const system::chain::block& block,
const system::chain::context& ctx) NOEXCEPT
{
const auto& query = archive();

// Relative locktime check is unnecessary under bypass, but cheap.
if (!block.populate(ctx))
return system::error::relative_time_locked;

if (bypass)
{
// TODO: this should not bypass checkpoint/milestone if enabled.
ec = error::validate7;
if (!query.populate_without_metadata(block))
return system::error::missing_previous_output;
}
else
{
fire(events::block_validated, ctx.height);
if (!query.populate(block))
return system::error::missing_previous_output;
}

return error::success;
}

// Return to strand to handle result.
POST(complete_block, ec, link, ctx.height);
code chaser_validate::validate(bool bypass, const system::chain::block& block,
const database::header_link& link,
const system::chain::context& ctx) NOEXCEPT
{
code ec{};
if (bypass)
return ec;

auto& query = archive();

if ((ec = block.accept(ctx, subsidy_interval_, initial_subsidy_)))
return ec;

if ((ec = block.connect(ctx)))
return ec;

if (!query.set_block_valid(link, block.fees()))
return error::validate6;

if (!query.set_prevouts(link, block))
return error::validate7;

return ec;
}

void chaser_validate::complete_block(const code& ec, const header_link& link,
Expand Down
Loading