Skip to content

Commit

Permalink
Merge pull request #539 from evoskuil/master
Browse files Browse the repository at this point in the history
Move sequential block/header validation to chasers.
  • Loading branch information
evoskuil authored Feb 20, 2024
2 parents 7d4e1a4 + 79878dc commit 2c3d7a3
Show file tree
Hide file tree
Showing 41 changed files with 994 additions and 374 deletions.
3 changes: 3 additions & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ src_libbitcoin_node_la_SOURCES = \
src/parser.cpp \
src/settings.cpp \
src/chasers/chaser.cpp \
src/chasers/chaser_block.cpp \
src/chasers/chaser_candidate.cpp \
src/chasers/chaser_check.cpp \
src/chasers/chaser_confirm.cpp \
Expand Down Expand Up @@ -79,6 +80,7 @@ test_libbitcoin_node_test_SOURCES = \
test/test.cpp \
test/test.hpp \
test/chasers/chaser.cpp \
test/chasers/chaser_block.cpp \
test/chasers/chaser_candidate.cpp \
test/chasers/chaser_check.cpp \
test/chasers/chaser_confirm.cpp \
Expand Down Expand Up @@ -126,6 +128,7 @@ include_bitcoin_node_HEADERS = \
include_bitcoin_node_chasersdir = ${includedir}/bitcoin/node/chasers
include_bitcoin_node_chasers_HEADERS = \
include/bitcoin/node/chasers/chaser.hpp \
include/bitcoin/node/chasers/chaser_block.hpp \
include/bitcoin/node/chasers/chaser_candidate.hpp \
include/bitcoin/node/chasers/chaser_check.hpp \
include/bitcoin/node/chasers/chaser_confirm.hpp \
Expand Down
2 changes: 2 additions & 0 deletions builds/cmake/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,7 @@ add_library( ${CANONICAL_LIB_NAME}
"../../src/parser.cpp"
"../../src/settings.cpp"
"../../src/chasers/chaser.cpp"
"../../src/chasers/chaser_block.cpp"
"../../src/chasers/chaser_candidate.cpp"
"../../src/chasers/chaser_check.cpp"
"../../src/chasers/chaser_confirm.cpp"
Expand Down Expand Up @@ -348,6 +349,7 @@ if (with-tests)
"../../test/test.cpp"
"../../test/test.hpp"
"../../test/chasers/chaser.cpp"
"../../test/chasers/chaser_block.cpp"
"../../test/chasers/chaser_candidate.cpp"
"../../test/chasers/chaser_check.cpp"
"../../test/chasers/chaser_confirm.cpp"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
</ImportGroup>
<ItemGroup>
<ClCompile Include="..\..\..\..\test\chasers\chaser.cpp" />
<ClCompile Include="..\..\..\..\test\chasers\chaser_block.cpp" />
<ClCompile Include="..\..\..\..\test\chasers\chaser_candidate.cpp" />
<ClCompile Include="..\..\..\..\test\chasers\chaser_check.cpp" />
<ClCompile Include="..\..\..\..\test\chasers\chaser_confirm.cpp" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@
<ClCompile Include="..\..\..\..\test\chasers\chaser.cpp">
<Filter>src\chasers</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\test\chasers\chaser_block.cpp">
<Filter>src\chasers</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\test\chasers\chaser_candidate.cpp">
<Filter>src\chasers</Filter>
</ClCompile>
Expand Down
2 changes: 2 additions & 0 deletions builds/msvc/vs2022/libbitcoin-node/libbitcoin-node.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@
</ImportGroup>
<ItemGroup>
<ClCompile Include="..\..\..\..\src\chasers\chaser.cpp" />
<ClCompile Include="..\..\..\..\src\chasers\chaser_block.cpp" />
<ClCompile Include="..\..\..\..\src\chasers\chaser_candidate.cpp" />
<ClCompile Include="..\..\..\..\src\chasers\chaser_check.cpp" />
<ClCompile Include="..\..\..\..\src\chasers\chaser_confirm.cpp" />
Expand Down Expand Up @@ -102,6 +103,7 @@
<ItemGroup>
<ClInclude Include="..\..\..\..\include\bitcoin\node.hpp" />
<ClInclude Include="..\..\..\..\include\bitcoin\node\chasers\chaser.hpp" />
<ClInclude Include="..\..\..\..\include\bitcoin\node\chasers\chaser_block.hpp" />
<ClInclude Include="..\..\..\..\include\bitcoin\node\chasers\chaser_candidate.hpp" />
<ClInclude Include="..\..\..\..\include\bitcoin\node\chasers\chaser_check.hpp" />
<ClInclude Include="..\..\..\..\include\bitcoin\node\chasers\chaser_confirm.hpp" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@
<ClCompile Include="..\..\..\..\src\chasers\chaser.cpp">
<Filter>src\chasers</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\src\chasers\chaser_block.cpp">
<Filter>src\chasers</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\src\chasers\chaser_candidate.cpp">
<Filter>src\chasers</Filter>
</ClCompile>
Expand Down Expand Up @@ -125,6 +128,9 @@
<ClInclude Include="..\..\..\..\include\bitcoin\node\chasers\chaser.hpp">
<Filter>include\bitcoin\node\chasers</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\include\bitcoin\node\chasers\chaser_block.hpp">
<Filter>include\bitcoin\node\chasers</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\include\bitcoin\node\chasers\chaser_candidate.hpp">
<Filter>include\bitcoin\node\chasers</Filter>
</ClInclude>
Expand Down
1 change: 1 addition & 0 deletions include/bitcoin/node.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include <bitcoin/node/settings.hpp>
#include <bitcoin/node/version.hpp>
#include <bitcoin/node/chasers/chaser.hpp>
#include <bitcoin/node/chasers/chaser_block.hpp>
#include <bitcoin/node/chasers/chaser_candidate.hpp>
#include <bitcoin/node/chasers/chaser_check.hpp>
#include <bitcoin/node/chasers/chaser_confirm.hpp>
Expand Down
12 changes: 12 additions & 0 deletions include/bitcoin/node/chasers/chaser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include <variant>
#include <bitcoin/database.hpp>
#include <bitcoin/network.hpp>
#include <bitcoin/node/configuration.hpp>
#include <bitcoin/node/define.hpp>

namespace libbitcoin {
Expand All @@ -43,8 +44,15 @@ class BCN_API chaser
public:
enum class chase
{
/// A new strong branch exists (strong height_t).
/// Issued by 'block' and handled by 'confirm'.
/// The block chaser works with the blocks-first protocol.
/// Bocks first performs header/checked/connected stages.
block,

/// A new strong branch exists (strong height_t).
/// Issued by 'header' and handled by 'check'.
/// The block chaser works with the header-first protocol.
header,

/// A block has been downloaded, checked and stored (header_t).
Expand Down Expand Up @@ -91,6 +99,9 @@ class BCN_API chaser
chaser(full_node& node) NOEXCEPT;
~chaser() NOEXCEPT;

/// Node configuration settings.
const node::configuration& config() const NOEXCEPT;

/// Thread safe synchronous archival interface.
query& archive() const NOEXCEPT;

Expand All @@ -117,6 +128,7 @@ class BCN_API chaser

// These are thread safe (mostly).
full_node& node_;
const node::configuration& config_;
network::asio::strand strand_;

// This is protected by the network strand.
Expand Down
113 changes: 113 additions & 0 deletions include/bitcoin/node/chasers/chaser_block.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
/**
* Copyright (c) 2011-2023 libbitcoin developers (see AUTHORS)
*
* This file is part of libbitcoin.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef LIBBITCOIN_NODE_CHASERS_CHASER_BLOCK_HPP
#define LIBBITCOIN_NODE_CHASERS_CHASER_BLOCK_HPP

#include <unordered_map>
#include <bitcoin/database.hpp>
#include <bitcoin/network.hpp>
#include <bitcoin/node/define.hpp>
#include <bitcoin/node/chasers/chaser.hpp>

namespace libbitcoin {
namespace node {

class full_node;

/// Chase down stronger block branches for the confirmed chain.
/// Weak branches are retained in a hash table if not store populated.
/// Strong branches reorganize the candidate chain and fire the 'connect' event.
class BCN_API chaser_block
: public chaser
{
public:
DELETE_COPY_MOVE(chaser_block);

chaser_block(full_node& node) NOEXCEPT;
virtual ~chaser_block() NOEXCEPT;

virtual code start() NOEXCEPT;

/// Validate and organize next block in sequence relative to caller peer.
/// Causes a fault/stop if preceding blocks have not been stored.
virtual void organize(
const system::chain::block::cptr& block_ptr) NOEXCEPT;

protected:
struct validated_block
{
database::context context;
system::chain::block::cptr item;
};
typedef std::vector<database::header_link> header_links;

// This is protected by strand.
system::chain::chain_state::ptr state_{};
std::unordered_map<system::hash_digest, validated_block> tree_{};

/// Handlers.
virtual void handle_event(const code& ec, chase event_,
link value) NOEXCEPT;

/// Sum of work from header to fork point (excluded).
virtual bool get_branch_work(uint256_t& work, size_t& point,
system::hashes& tree_branch, header_links& store_branch,
const system::chain::header& header) const NOEXCEPT;

/// Strong if new branch work exceeds confirmed work.
/// Also obtains fork point for work summation termination.
/// Also obtains ordered branch identifiers for subsequent reorg.
virtual bool get_is_strong(bool& strong, const uint256_t& work,
size_t point) const NOEXCEPT;

/// Header timestamp is within configured span from current time.
virtual bool is_current(const system::chain::header& header,
size_t height) const NOEXCEPT;

/// Save block to tree with validation context.
virtual void save(const system::chain::block::cptr& block,
const system::chain::context& context) NOEXCEPT;

/// Store block to database and push to top of candidate chain.
virtual database::header_link push(
const system::chain::block::cptr& block,
const system::chain::context& context) const NOEXCEPT;

/// Move tree header to database and push to top of candidate chain.
virtual bool push(const system::hash_digest& key) NOEXCEPT;

/// Properties.
/// Given non-current blocks cached in memory, should always be zero/false.
virtual const network::wall_clock::duration& currency_window() const NOEXCEPT;
virtual bool use_currency_window() const NOEXCEPT;

private:
void do_handle_event(const code& ec, chase event_, link value) NOEXCEPT;
void do_organize(const system::chain::block::cptr& block) NOEXCEPT;

// These are thread safe.
const system::chain::checkpoints& checkpoints_;
const network::wall_clock::duration currency_window_;
const bool use_currency_window_;
};

} // namespace node
} // namespace libbitcoin

#endif
3 changes: 3 additions & 0 deletions include/bitcoin/node/chasers/chaser_candidate.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,10 @@ class BCN_API chaser_candidate
: public chaser
{
public:
DELETE_COPY_MOVE(chaser_candidate);

chaser_candidate(full_node& node) NOEXCEPT;
virtual ~chaser_candidate() NOEXCEPT;

virtual code start() NOEXCEPT;

Expand Down
3 changes: 3 additions & 0 deletions include/bitcoin/node/chasers/chaser_check.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,10 @@ class BCN_API chaser_check
: public chaser
{
public:
DELETE_COPY_MOVE(chaser_check);

chaser_check(full_node& node) NOEXCEPT;
virtual ~chaser_check() NOEXCEPT;

virtual code start() NOEXCEPT;
virtual void checked(const system::chain::block::cptr& block) NOEXCEPT;
Expand Down
3 changes: 3 additions & 0 deletions include/bitcoin/node/chasers/chaser_confirm.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,10 @@ class BCN_API chaser_confirm
: public chaser
{
public:
DELETE_COPY_MOVE(chaser_confirm);

chaser_confirm(full_node& node) NOEXCEPT;
virtual ~chaser_confirm() NOEXCEPT;

virtual code start() NOEXCEPT;

Expand Down
3 changes: 3 additions & 0 deletions include/bitcoin/node/chasers/chaser_connect.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,10 @@ class BCN_API chaser_connect
: public chaser
{
public:
DELETE_COPY_MOVE(chaser_connect);

chaser_connect(full_node& node) NOEXCEPT;
virtual ~chaser_connect() NOEXCEPT;

virtual code start() NOEXCEPT;

Expand Down
23 changes: 14 additions & 9 deletions include/bitcoin/node/chasers/chaser_header.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include <unordered_map>
#include <bitcoin/database.hpp>
#include <bitcoin/network.hpp>
#include <bitcoin/node/configuration.hpp>
#include <bitcoin/node/define.hpp>
#include <bitcoin/node/chasers/chaser.hpp>

Expand All @@ -37,25 +38,28 @@ class BCN_API chaser_header
: public chaser
{
public:
DELETE_COPY_MOVE(chaser_header);

chaser_header(full_node& node) NOEXCEPT;
virtual ~chaser_header() NOEXCEPT;

virtual code start() NOEXCEPT;

/// Organize the next header in sequence, relative to caller's peer.
/// Validate and organize next header in sequence relative to caller peer.
/// Causes a fault/stop if preceding headers have not been stored.
/// Caller must validate the header and provide context.
virtual void organize(const system::chain::header::cptr& header,
system::chain::context&& context) NOEXCEPT;
virtual void organize(
const system::chain::header::cptr& header_ptr) NOEXCEPT;

protected:
struct proposed_header
{
database::context context;
system::chain::header::cptr header;
system::chain::header::cptr item;
};
typedef std::vector<database::header_link> header_links;

// This is protected by strand.
// These are protected by strand.
system::chain::chain_state::ptr state_{};
std::unordered_map<system::hash_digest, proposed_header> tree_{};

/// Handlers.
Expand All @@ -74,7 +78,8 @@ class BCN_API chaser_header
size_t point) const NOEXCEPT;

/// Header timestamp is within configured span from current time.
virtual bool is_current(const system::chain::header& header) const NOEXCEPT;
virtual bool is_current(const system::chain::header& header,
size_t height) const NOEXCEPT;

/// Save header to tree with validation context.
virtual void save(const system::chain::header::cptr& header,
Expand All @@ -94,10 +99,10 @@ class BCN_API chaser_header

private:
void do_handle_event(const code& ec, chase event_, link value) NOEXCEPT;
void do_organize(const system::chain::header::cptr& header,
const system::chain::context& context) NOEXCEPT;
void do_organize(const system::chain::header::cptr& header) NOEXCEPT;

// These are thread safe.
const system::chain::checkpoints& checkpoints_;
const network::wall_clock::duration currency_window_;
const bool use_currency_window_;
};
Expand Down
3 changes: 3 additions & 0 deletions include/bitcoin/node/chasers/chaser_transaction.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,10 @@ class BCN_API chaser_transaction
: public chaser
{
public:
DELETE_COPY_MOVE(chaser_transaction);

chaser_transaction(full_node& node) NOEXCEPT;
virtual ~chaser_transaction() NOEXCEPT;

code start() NOEXCEPT override;
virtual void store(const system::chain::transaction::cptr& block) NOEXCEPT;
Expand Down
1 change: 1 addition & 0 deletions include/bitcoin/node/chasers/chasers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#define LIBBITCOIN_NODE_CHASERS_CHASERS_HPP

#include <bitcoin/node/chasers/chaser.hpp>
#include <bitcoin/node/chasers/chaser_block.hpp>
#include <bitcoin/node/chasers/chaser_candidate.hpp>
#include <bitcoin/node/chasers/chaser_check.hpp>
#include <bitcoin/node/chasers/chaser_confirm.hpp>
Expand Down
1 change: 1 addition & 0 deletions include/bitcoin/node/error.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ enum error_t : uint8_t
stalled_channel,

// blockchain
orphan_block,
orphan_header,
insufficient_work,
duplicate_block
Expand Down
Loading

0 comments on commit 2c3d7a3

Please sign in to comment.