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

Block pipeline #3727

Draft
wants to merge 21 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
66de849
This is a refactor of the block processor which breaks the block proc…
clemahieu Dec 7, 2022
ba1eea8
Merge branch 'develop' into block_pipeline
clemahieu Jan 25, 2023
3c30cf5
Formatting string before sending to cerr.
clemahieu Jan 25, 2023
056229b
Fix race condition where block being inserted in to the unchecked_map…
clemahieu Jan 25, 2023
86bc577
Fixing tests that assume synchronous block insertion.
clemahieu Jan 25, 2023
614edd6
Update block_processor_full tests to use fork blocks instead of a blo…
clemahieu Jan 26, 2023
6a78420
Replace flush with ASSERT_TIMELY.
clemahieu Jan 26, 2023
32dea05
Address compiler complaint.
clemahieu Jan 26, 2023
2ce59d2
Directly checking test conditions with ASSERT_TIMELY rather than impl…
clemahieu Jan 26, 2023
6f4ba33
Merge branch 'develop' into block_pipeline
clemahieu Jan 26, 2023
78f9e8d
Merge branch 'develop' into block_pipeline
clemahieu Jan 27, 2023
6662138
Merge branch 'develop' into block_pipeline
clemahieu Jan 28, 2023
065845e
Merge branch 'develop' into block_pipeline
clemahieu Feb 1, 2023
3621d2d
Enabling epoch restrictions filter.
clemahieu Feb 5, 2023
6441f5d
Hooking up signature verification.
clemahieu Feb 5, 2023
2c8c34b
Formatting.
clemahieu Feb 5, 2023
80205a0
Removing logging.
clemahieu Feb 5, 2023
2d5ba7a
Remove unused static.
clemahieu Feb 5, 2023
35e81c8
Merge branch 'develop' into block_pipeline2
clemahieu Feb 5, 2023
d374ccf
Changing how forced blocks are handled so it doesn't require a separa…
clemahieu Feb 6, 2023
6299819
Move any_pending query in to the account_state_filter rather than doi…
clemahieu Feb 8, 2023
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
8 changes: 8 additions & 0 deletions nano/core_test/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
add_executable(
core_test
account_state_filter.cpp
core_test_main.cc
fakes/websocket_client.hpp
fakes/work_peer.hpp
active_transactions.cpp
backlog.cpp
block.cpp
block_position_filter.cpp
block_store.cpp
blockprocessor.cpp
bootstrap.cpp
Expand All @@ -19,12 +21,15 @@ add_executable(
election.cpp
election_scheduler.cpp
enums.cpp
epoch_restrictions_filter.cpp
epochs.cpp
metastable_filter.cpp
frontiers_confirmation.cpp
gap_cache.cpp
ipc.cpp
ledger.cpp
ledger_walker.cpp
link_filter.cpp
locks.cpp
logger.cpp
message.cpp
Expand All @@ -37,7 +42,10 @@ add_executable(
processor_service.cpp
peer_container.cpp
prioritization.cpp
receive_restrictions_filter.cpp
request_aggregator.cpp
reserved_account_filter.cpp
send_restrictions_filter.cpp
signal_manager.cpp
signing.cpp
socket.cpp
Expand Down
179 changes: 179 additions & 0 deletions nano/core_test/account_state_filter.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
#include <nano/lib/blockbuilders.hpp>
#include <nano/lib/stats.hpp>
#include <nano/node/block_pipeline/account_state_filter.hpp>
#include <nano/node/block_pipeline/context.hpp>
#include <nano/secure/common.hpp>
#include <nano/secure/ledger.hpp>
#include <nano/secure/store.hpp>
#include <nano/secure/utility.hpp>

#include <gtest/gtest.h>

namespace
{
class context
{
public:
context () :
store{ nano::make_store (logger, nano::unique_path (), nano::dev::constants) },
ledger{ *store, stats, nano::dev::constants }
{
store->initialize (store->tx_begin_write (), ledger.cache, nano::dev::constants);
debug_assert (!store->init_error ());
filter.pass = [this] (nano::block_pipeline::context & context) {
pass.push_back (context);
};
filter.reject_gap = [this] (nano::block_pipeline::context & context) {
reject_gap.push_back (context);
};
filter.reject_existing = [this] (nano::block_pipeline::context & context) {
reject_existing.push_back (context);
};
}
nano::stats stats;
nano::logger_mt logger;
std::shared_ptr<nano::store> store;
nano::ledger ledger;
nano::block_pipeline::account_state_filter filter{ ledger };
nano::keypair signer;
std::vector<nano::block_pipeline::context> pass;
std::vector<nano::block_pipeline::context> reject_gap;
std::vector<nano::block_pipeline::context> reject_existing;
};
nano::work_pool pool{ nano::dev::network_params.network, 1 };
nano::block_pipeline::context previous_open_block ()
{
nano::block_builder builder;
nano::block_pipeline::context result;
result.block = builder.state ()
.account (nano::dev::genesis_key.pub)
.previous (nano::dev::genesis->hash ())
.representative (nano::dev::genesis_key.pub)
.balance (nano::dev::constants.genesis_amount - 1)
.link (0)
.sign (nano::dev::genesis_key.prv, nano::dev::genesis_key.pub)
.work (0)
.build_shared ();
result.previous = nano::dev::genesis;
return result;
}
nano::block_pipeline::context previous_send_block ()
{
nano::block_builder builder;
nano::block_pipeline::context result;
result.previous = builder.send ()
.previous (nano::dev::genesis->hash ())
.destination (nano::dev::genesis_key.pub)
.balance (nano::dev::constants.genesis_amount - 1)
.sign (nano::dev::genesis_key.prv, nano::dev::genesis_key.pub)
.work (*pool.generate (nano::dev::genesis->hash ()))
.build_shared ();
result.block = builder.state ()
.account (nano::dev::genesis_key.pub)
.previous (result.previous->hash ())
.representative (nano::dev::genesis_key.pub)
.balance (nano::dev::constants.genesis_amount - 1)
.link (0)
.sign (nano::dev::genesis_key.prv, nano::dev::genesis_key.pub)
.work (0)
.build_shared ();
return result;
}
nano::block_pipeline::context previous_state_block ()
{
nano::block_builder builder;
nano::block_pipeline::context result;
result.previous = builder.state ()
.account (nano::dev::genesis_key.pub)
.previous (nano::dev::genesis->hash ())
.representative (nano::dev::genesis_key.pub)
.balance (nano::dev::constants.genesis_amount - 1)
.link (nano::dev::genesis_key.pub)
.sign (nano::dev::genesis_key.prv, nano::dev::genesis_key.pub)
.work (*pool.generate (nano::dev::genesis->hash ()))
.build_shared ();
result.block = builder.state ()
.account (nano::dev::genesis_key.pub)
.previous (result.previous->hash ())
.representative (nano::dev::genesis_key.pub)
.balance (nano::dev::constants.genesis_amount - 1)
.link (0)
.sign (nano::dev::genesis_key.prv, nano::dev::genesis_key.pub)
.work (0)
.build_shared ();
return result;
}
nano::block_pipeline::context reject_gap_block ()
{
nano::block_builder builder;
nano::block_pipeline::context result;
auto dummy = builder.state ()
.account (nano::dev::genesis_key.pub)
.previous (nano::dev::genesis->hash ())
.representative (nano::dev::genesis_key.pub)
.balance (nano::dev::constants.genesis_amount)
.link (0)
.sign (nano::dev::genesis_key.prv, nano::dev::genesis_key.pub)
.work (0)
.build_shared ();
result.block = builder.state ()
.account (nano::dev::genesis_key.pub)
.previous (dummy->hash ()) // Previous block is not in ledger
.representative (nano::dev::genesis_key.pub)
.balance (nano::dev::constants.genesis_amount - 1)
.link (0)
.sign (nano::dev::genesis_key.prv, nano::dev::genesis_key.pub)
.work (0)
.build_shared ();
return result;
}
nano::block_pipeline::context reject_existing_block ()
{
nano::block_builder builder;
nano::block_pipeline::context result;
result.block = nano::dev::genesis;
return result;
}
}

TEST (account_state_filter, previous_open)
{
context context;
auto block = previous_open_block ();
context.filter.sink (block);
ASSERT_EQ (1, context.pass.size ());
}

TEST (account_state_filter, previous_send)
{
context context;
auto block = previous_send_block ();
ASSERT_EQ (nano::process_result::progress, context.ledger.process (context.store->tx_begin_write (), *block.previous).code);
context.filter.sink (block);
ASSERT_EQ (1, context.pass.size ());
}

TEST (account_state_filter, previous_state)
{
context context;
auto block = previous_send_block ();
ASSERT_EQ (nano::process_result::progress, context.ledger.process (context.store->tx_begin_write (), *block.previous).code);
context.filter.sink (block);
ASSERT_EQ (1, context.pass.size ());
}

TEST (account_state_filter, reject_gap)
{
context context;
auto block = reject_gap_block ();
context.filter.sink (block);
ASSERT_EQ (1, context.reject_gap.size ());
}

TEST (account_state_filter, reject_existing)
{
context context;
auto block = reject_existing_block ();
context.filter.sink (block);
ASSERT_EQ (1, context.reject_existing.size ());
}
2 changes: 2 additions & 0 deletions nano/core_test/active_transactions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,7 @@ TEST (active_transactions, inactive_votes_cache_existing_vote)
.work (*system.work.generate (key.pub))
.build_shared ();
node.process_active (send);
ASSERT_TIMELY (5s, node.block (send->hash ()) != nullptr);
node.block_processor.add (open);
node.block_processor.flush ();
ASSERT_TIMELY (5s, node.active.size () == 1);
Expand Down Expand Up @@ -555,6 +556,7 @@ TEST (active_transactions, vote_replays)
.build_shared ();
ASSERT_NE (nullptr, open1);
node.process_active (send1);
ASSERT_TIMELY (5s, node.block (send1->hash ()) != nullptr);
node.process_active (open1);
nano::test::blocks_confirm (node, { send1, open1 });
ASSERT_EQ (2, node.active.size ());
Expand Down
89 changes: 89 additions & 0 deletions nano/core_test/block_position_filter.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
#include <nano/lib/blockbuilders.hpp>
#include <nano/lib/stats.hpp>
#include <nano/node/block_pipeline/block_position_filter.hpp>
#include <nano/node/block_pipeline/context.hpp>
#include <nano/secure/common.hpp>
#include <nano/secure/ledger.hpp>
#include <nano/secure/store.hpp>
#include <nano/secure/utility.hpp>

#include <gtest/gtest.h>

namespace
{
class context
{
public:
context ()
{
filter.pass = [this] (nano::block_pipeline::context & context) {
pass.push_back (std::make_pair (context.block, context.previous));
};
filter.reject = [this] (nano::block_pipeline::context & context) {
reject.push_back (context.block);
};
}
nano::block_pipeline::block_position_filter filter;
std::vector<std::pair<std::shared_ptr<nano::block>, std::shared_ptr<nano::block>>> pass;
std::vector<std::shared_ptr<nano::block>> reject;
};
nano::work_pool pool{ nano::dev::network_params.network, 1 };
nano::block_pipeline::context pass_block ()
{
nano::block_builder builder;
nano::block_pipeline::context result;
result.block = builder.state ()
.account (nano::dev::genesis_key.pub)
.previous (nano::dev::genesis->hash ())
.representative (nano::dev::genesis_key.pub)
.balance (nano::dev::constants.genesis_amount - 1)
.link (nano::dev::genesis_key.pub)
.sign (nano::dev::genesis_key.prv, nano::dev::genesis_key.pub)
.work (0)
.build_shared ();
result.previous = nano::dev::genesis;
return result;
}
nano::block_pipeline::context reject_block ()
{
nano::block_builder builder;
nano::block_pipeline::context result;
result.previous = builder.state ()
.account (nano::dev::genesis_key.pub)
.previous (nano::dev::genesis->hash ())
.representative (nano::dev::genesis_key.pub)
.balance (nano::dev::constants.genesis_amount - 1)
.link (nano::dev::genesis_key.pub)
.sign (nano::dev::genesis_key.prv, nano::dev::genesis_key.pub)
.work (*pool.generate (nano::dev::genesis->hash ()))
.build_shared ();
result.block = builder.change ()
.previous (result.previous->hash ())
.representative (nano::dev::genesis_key.pub)
.sign (nano::dev::genesis_key.prv, nano::dev::genesis_key.pub)
.work (0)
.build_shared ();

return result;
}
}

TEST (block_position_filter, pass)
{
context context;
auto pass = pass_block ();
context.filter.sink (pass);
ASSERT_EQ (0, context.reject.size ());
ASSERT_EQ (1, context.pass.size ());
ASSERT_EQ (pass.block, context.pass[0].first);
}

TEST (block_position_filter, reject)
{
context context;
auto reject = reject_block ();
context.filter.sink (reject);
ASSERT_EQ (1, context.reject.size ());
ASSERT_EQ (0, context.pass.size ());
ASSERT_EQ (reject.block, context.reject[0]);
}
1 change: 1 addition & 0 deletions nano/core_test/confirmation_height.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,7 @@ TEST (confirmation_height, multiple_accounts)
ASSERT_EQ (nano::block_hash (0), confirmation_height_info.frontier);
}

node->block_processor.flush ();
// The nodes process a live receive which propagates across to all accounts
auto receive3 = builder
.receive ()
Expand Down
Loading