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

Clean up codes, weak ptr fixes, add organizer::duplicate(). #653

Merged
merged 1 commit into from
Jun 24, 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: 2 additions & 2 deletions console/executor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@ void executor::scan_flags() const
{
const auto start = logger::now();
constexpr auto flag_bits = to_bits(sizeof(chain::flags));
const auto error = code{ error::store_integrity }.message();
const auto error = code{ database::error::integrity }.message();
const auto top = query_.get_top_candidate();
uint32_t flags{};

Expand Down Expand Up @@ -2660,7 +2660,7 @@ bool executor::do_run()
{
ec = error::success;
if (!restore_store(true))
ec = error::store_integrity;
ec = database::error::integrity;
}

if (ec)
Expand Down
4 changes: 4 additions & 0 deletions include/bitcoin/node/chasers/chaser_block.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ class BCN_API chaser_block
virtual bool get_block(system::chain::block::cptr& out,
size_t height) const NOEXCEPT;

/// Determine if Block is a duplicate (success for not duplicate).
virtual code duplicate(size_t& height,
const system::hash_digest& hash) const NOEXCEPT;

/// Determine if Block is valid.
virtual code validate(const system::chain::block& block,
const chain_state& state) const NOEXCEPT;
Expand Down
4 changes: 4 additions & 0 deletions include/bitcoin/node/chasers/chaser_header.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ class BCN_API chaser_header
virtual bool get_block(system::chain::header::cptr& out,
size_t height) const NOEXCEPT;

/// Determine if Block is a duplicate (success for not duplicate).
virtual code duplicate(size_t& height,
const system::hash_digest& hash) const NOEXCEPT;

/// Determine if Block is valid.
virtual code validate(const system::chain::header& header,
const chain_state& state) const NOEXCEPT;
Expand Down
6 changes: 5 additions & 1 deletion include/bitcoin/node/chasers/chaser_organize.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ class chaser_organize
virtual bool get_block(typename Block::cptr& out,
size_t height) const NOEXCEPT = 0;

/// Determine if Block is a duplicate (success for not duplicate).
virtual code duplicate(size_t& height,
const system::hash_digest& hash) const NOEXCEPT = 0;

/// Determine if Block is valid.
virtual code validate(const Block& block,
const chain_state& state) const NOEXCEPT = 0;
Expand All @@ -95,7 +99,7 @@ class chaser_organize
event_value value) NOEXCEPT;

/// Organize a discovered Block.
virtual void do_organize(typename Block::cptr& block_ptr,
virtual void do_organize(typename Block::cptr block_ptr,
const organize_handler& handler) NOEXCEPT;

/// Reorganize following Block unconfirmability.
Expand Down
27 changes: 10 additions & 17 deletions include/bitcoin/node/error.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,8 @@ enum error_t : uint8_t
{
/// general
success,
internal_error,
unexpected_event,

/// database
store_integrity,
store_uninitialized,
store_reload,
store_snapshot,
Expand All @@ -56,40 +53,36 @@ enum error_t : uint8_t
suspended_service,

/// blockchain
branch_error,
orphan_block,
orphan_header,
duplicate_block,
duplicate_header,
malleated_block,
insufficient_work,
validation_bypass,
confirmation_bypass,
////validation_bypass,
////confirmation_bypass,

/// query
/// chasers
set_block_unconfirmable,
////set_block_link,
get_height,
get_branch_work,
get_is_strong,
invalid_branch_point,
pop_candidate,
push_candidate,
set_header_link,
invalid_fork_point,
get_candidate_chain_state,
get_block,
set_dissasociated,
get_unassociated,
get_fork_work,
to_confirmed,
pop_confirmed,
set_confirmed,
block_confirmable,
set_txs_connected,
get_block_confirmable,
get_block_state,
set_strong,
set_unstrong,
set_organized,
set_block_confirmable,
set_block_valid,

/// query composite
node_push,
node_confirm,
node_validate,
node_roll_back
Expand Down
54 changes: 10 additions & 44 deletions include/bitcoin/node/impl/chasers/chaser_organize.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -119,13 +119,12 @@ bool CLASS::handle_event(const code&, chase event_, event_value value) NOEXCEPT
}

TEMPLATE
void CLASS::do_organize(typename Block::cptr& block_ptr,
void CLASS::do_organize(typename Block::cptr block_ptr,
const organize_handler& handler) NOEXCEPT
{
using namespace system;
BC_ASSERT(stranded());

// block_ptr is
const auto& hash = block_ptr->get_hash();
const auto& header = get_header(*block_ptr);
auto& query = archive();
Expand All @@ -146,45 +145,12 @@ void CLASS::do_organize(typename Block::cptr& block_ptr,
return;
}

const auto id = query.to_header(hash);
if (!id.is_terminal())
code ec{};
size_t height{};
if ((ec = duplicate(height, hash)))
{
size_t height{};
if (!query.get_height(height, id))
{
handler(fault(error::get_height), {});
return;
}

// block_unconfirmable is not set when merkle tree is malleable, in
// which case the header may be archived in an undetermined state. Not
// setting block_unconfirmable only delays ineviable invalidity
// discovery and consequential deorganization at that block. Though
// this may cycle until a strong candidate chain is located.
const auto ec = query.get_header_state(id);
if (ec == database::error::block_unconfirmable)
{
// This eventually stops the peer, but the full set of headers may
// still cycle through to become strong, despite this being stored
// as block_unconfirmable from a block validate or confirm failure.
// Block validation will then fail and this cycle will continue
// until a strong candidate chain is located. The cycle occurs
// because peers continue to send the same headers, which may
// indicate a local failure or peer failures.
handler(ec, height);
return;
}

// With a candidate reorg that drops strong below a valid header chain,
// this will cause a sequence of headers to be bypassed, such that a
// parent of a block that doesn't exist will not be a candidate, which
// result in a failure of get_chain_state below, because it depends on
// candidate state. So get_chain_state needs to be chain independent.
if (!is_block() || ec != database::error::unassociated)
{
handler(error_duplicate(), height);
return;
}
handler(ec, height);
return;
}

// Obtain header chain state.
Expand All @@ -200,11 +166,11 @@ void CLASS::do_organize(typename Block::cptr& block_ptr,

// Roll chain state forward from archived parent to current header.
const auto state = std::make_shared<chain_state>(*parent, header, settings_);
height = state->height();

// Validation and currency.
// ........................................................................

const auto height = state->height();
if (chain::checkpoint::is_conflict(checkpoints_, hash, height))
{
handler(system::error::checkpoint_conflict, height);
Expand All @@ -214,7 +180,7 @@ void CLASS::do_organize(typename Block::cptr& block_ptr,
// blocks-first may return malleation error, in which case another peer may
// return the good block of the same hash. headers-first cannot detect
// malleation here, so the block_in protocol sends chase::malleated.
if (const auto ec = validate(*block_ptr, *state))
if ((ec = validate(*block_ptr, *state)))
{
handler(ec, height);
return;
Expand Down Expand Up @@ -244,6 +210,7 @@ void CLASS::do_organize(typename Block::cptr& block_ptr,
return;
}

// branch_point is the highest tree-candidate common block.
if (!get_is_strong(strong, work, branch_point))
{
handler(fault(error::get_is_strong), height);
Expand All @@ -265,7 +232,6 @@ void CLASS::do_organize(typename Block::cptr& block_ptr,
// A milestone can only be set within a to-be-archived chain of candidate
// headers/blocks. Once the milestone block is archived it is not useful.
update_milestone(header, height, branch_point);
code ec{};

const auto top_candidate = state_->height();
if (branch_point > top_candidate)
Expand Down Expand Up @@ -596,7 +562,7 @@ code CLASS::push_block(const system::hash_digest& key) NOEXCEPT
{
const auto handle = tree_.extract(key);
if (!handle)
return error::internal_error;
return error::branch_error;

const auto& value = handle.mapped();
return push_block(*value.block, value.state->context());
Expand Down
2 changes: 1 addition & 1 deletion include/bitcoin/node/protocols/protocol_block_in_31800.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ class BCN_API protocol_block_in_31800

/// Check incoming block message.
virtual bool handle_receive_block(const code& ec,
const network::messages::block::cptr& message) NOEXCEPT;
const network::messages::block::cptr message) NOEXCEPT;

private:
using type_id = network::messages::inventory::type_id;
Expand Down
34 changes: 34 additions & 0 deletions src/chasers/chaser_block.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,40 @@ bool chaser_block::get_block(block::cptr& out, size_t height) const NOEXCEPT
return !is_null(out);
}

code chaser_block::duplicate(size_t& height,
const system::hash_digest& hash) const NOEXCEPT
{
height = max_size_t;
const auto& query = archive();
const auto id = query.to_header(hash);
if (!id.is_terminal())
{
// database::error::unassociated
// database::error::block_unconfirmable
// database::error::block_confirmable
// database::error::block_valid
// database::error::unknown_state
// database::error::unvalidated
const auto ec = query.get_block_state(id);

// Most header states are duplicates, one implies fail.
if (ec == database::error::block_unconfirmable)
{
height = query.get_height(id);
return ec;
}

// unassociated is only non-duplicate.
if (ec != database::error::unassociated)
{
height = query.get_height(id);
return error::duplicate_block;
}
}

return error::success;
}

code chaser_block::validate(const block& block,
const chain_state& state) const NOEXCEPT
{
Expand Down
Loading
Loading