Merge branch 'develop' into repcrawler-overhaul-2

# Conflicts:
#	nano/lib/stats_enums.hpp
#	nano/lib/thread_roles.cpp
#	nano/lib/thread_roles.hpp
This commit is contained in:
Dimitrios Siganos 2024-03-08 15:42:12 +00:00
commit 1f0fd2e816
131 changed files with 1148 additions and 866 deletions

View file

@ -3571,19 +3571,19 @@ cl::pointer<T, detail::Deleter<SVMAllocator<T, SVMTrait>>> allocate_svm(const cl
}
#endif // #if !defined(CL_HPP_NO_STD_UNIQUE_PTR)
/*! \brief Vector alias to simplify contruction of coarse-grained SVM containers.
/*! \brief Vector alias to simplify construction of coarse-grained SVM containers.
*
*/
template < class T >
using coarse_svm_vector = vector<T, cl::SVMAllocator<int, cl::SVMTraitCoarse<>>>;
/*! \brief Vector alias to simplify contruction of fine-grained SVM containers.
/*! \brief Vector alias to simplify construction of fine-grained SVM containers.
*
*/
template < class T >
using fine_svm_vector = vector<T, cl::SVMAllocator<int, cl::SVMTraitFine<>>>;
/*! \brief Vector alias to simplify contruction of fine-grained SVM containers that support platform atomics.
/*! \brief Vector alias to simplify construction of fine-grained SVM containers that support platform atomics.
*
*/
template < class T >

View file

@ -11,7 +11,7 @@ endif()
# OSX compatibility needs to be set before project is declared
set(CMAKE_OSX_DEPLOYMENT_TARGET
12
13.3
CACHE STRING "")
project(nano-node)

View file

@ -9,11 +9,11 @@ git submodule init boost
cd boost
# deactivate all boost submodules
git submodule foreach 'git config submodule.$sm_path.active false'
# selectivly activate required dependencies
# selectively activate required dependencies
for i in ${dependencies[@]}
do
git config submodule.$i.active true
done
cd ..
# Update all submodules recursivly. Deactivated modules will be skipped by --recursive
# Update all submodules recursively. Deactivated modules will be skipped by --recursive
git submodule update --jobs 16 --recursive --recommend-shallow --single-branch

View file

@ -1,3 +1,4 @@
#include <nano/lib/blocks.hpp>
#include <nano/lib/jsonconfig.hpp>
#include <nano/node/election.hpp>
#include <nano/node/scheduler/component.hpp>

View file

@ -1,3 +1,4 @@
#include <nano/lib/blocks.hpp>
#include <nano/node/active_transactions.hpp>
#include <nano/test_common/chains.hpp>
#include <nano/test_common/system.hpp>

View file

@ -1,3 +1,4 @@
#include <nano/lib/blocks.hpp>
#include <nano/lib/stream.hpp>
#include <nano/node/common.hpp>
#include <nano/test_common/testutil.hpp>

View file

@ -1,4 +1,5 @@
#include <nano/crypto_lib/random_pool.hpp>
#include <nano/lib/blocks.hpp>
#include <nano/lib/lmdbconfig.hpp>
#include <nano/lib/logging.hpp>
#include <nano/lib/stats.hpp>
@ -1126,29 +1127,29 @@ TEST (mdb_block_store, sideband_height)
.work (*pool.generate (key3.pub))
.build ();
ASSERT_EQ (nano::block_status::progress, ledger.process (transaction, open));
auto block1 (store.block.get (transaction, nano::dev::genesis->hash ()));
auto block1 = ledger.block (transaction, nano::dev::genesis->hash ());
ASSERT_EQ (block1->sideband ().height, 1);
auto block2 (store.block.get (transaction, send->hash ()));
auto block2 = ledger.block (transaction, send->hash ());
ASSERT_EQ (block2->sideband ().height, 2);
auto block3 (store.block.get (transaction, receive->hash ()));
auto block3 = ledger.block (transaction, receive->hash ());
ASSERT_EQ (block3->sideband ().height, 3);
auto block4 (store.block.get (transaction, change->hash ()));
auto block4 = ledger.block (transaction, change->hash ());
ASSERT_EQ (block4->sideband ().height, 4);
auto block5 (store.block.get (transaction, state_send1->hash ()));
auto block5 = ledger.block (transaction, state_send1->hash ());
ASSERT_EQ (block5->sideband ().height, 5);
auto block6 (store.block.get (transaction, state_send2->hash ()));
auto block6 = ledger.block (transaction, state_send2->hash ());
ASSERT_EQ (block6->sideband ().height, 6);
auto block7 (store.block.get (transaction, state_send3->hash ()));
auto block7 = ledger.block (transaction, state_send3->hash ());
ASSERT_EQ (block7->sideband ().height, 7);
auto block8 (store.block.get (transaction, state_open->hash ()));
auto block8 = ledger.block (transaction, state_open->hash ());
ASSERT_EQ (block8->sideband ().height, 1);
auto block9 (store.block.get (transaction, epoch->hash ()));
auto block9 = ledger.block (transaction, epoch->hash ());
ASSERT_EQ (block9->sideband ().height, 2);
auto block10 (store.block.get (transaction, epoch_open->hash ()));
auto block10 = ledger.block (transaction, epoch_open->hash ());
ASSERT_EQ (block10->sideband ().height, 1);
auto block11 (store.block.get (transaction, state_receive->hash ()));
auto block11 = ledger.block (transaction, state_receive->hash ());
ASSERT_EQ (block11->sideband ().height, 2);
auto block12 (store.block.get (transaction, open->hash ()));
auto block12 = ledger.block (transaction, open->hash ());
ASSERT_EQ (block12->sideband ().height, 1);
}

View file

@ -1,4 +1,5 @@
#include <nano/lib/blockbuilders.hpp>
#include <nano/lib/blocks.hpp>
#include <nano/node/node.hpp>
#include <nano/node/nodeconfig.hpp>
#include <nano/secure/common.hpp>

View file

@ -1,3 +1,4 @@
#include <nano/lib/blocks.hpp>
#include <nano/node/bootstrap/block_deserializer.hpp>
#include <nano/node/bootstrap/bootstrap_frontier.hpp>
#include <nano/node/bootstrap/bootstrap_lazy.hpp>
@ -659,13 +660,13 @@ TEST (bootstrap_processor, push_diamond_pruning)
auto transaction (node1->store.tx_begin_write ());
ASSERT_EQ (1, node1->ledger.pruning_action (transaction, send1->hash (), 2));
ASSERT_EQ (1, node1->ledger.pruning_action (transaction, open->hash (), 1));
ASSERT_TRUE (node1->store.block.exists (transaction, nano::dev::genesis->hash ()));
ASSERT_FALSE (node1->store.block.exists (transaction, send1->hash ()));
ASSERT_TRUE (node1->ledger.block_exists (transaction, nano::dev::genesis->hash ()));
ASSERT_FALSE (node1->ledger.block_exists (transaction, send1->hash ()));
ASSERT_TRUE (node1->store.pruned.exists (transaction, send1->hash ()));
ASSERT_FALSE (node1->store.block.exists (transaction, open->hash ()));
ASSERT_FALSE (node1->ledger.block_exists (transaction, open->hash ()));
ASSERT_TRUE (node1->store.pruned.exists (transaction, open->hash ()));
ASSERT_TRUE (node1->store.block.exists (transaction, send2->hash ()));
ASSERT_TRUE (node1->store.block.exists (transaction, receive->hash ()));
ASSERT_TRUE (node1->ledger.block_exists (transaction, send2->hash ()));
ASSERT_TRUE (node1->ledger.block_exists (transaction, receive->hash ()));
ASSERT_EQ (2, node1->ledger.cache.pruned_count);
ASSERT_EQ (5, node1->ledger.cache.block_count);
}

View file

@ -1,3 +1,4 @@
#include <nano/lib/blocks.hpp>
#include <nano/lib/logging.hpp>
#include <nano/lib/stats.hpp>
#include <nano/lib/tomlconfig.hpp>

View file

@ -1,3 +1,4 @@
#include <nano/lib/blocks.hpp>
#include <nano/test_common/chains.hpp>
#include <nano/test_common/system.hpp>
#include <nano/test_common/testutil.hpp>

View file

@ -1,3 +1,4 @@
#include <nano/lib/blocks.hpp>
#include <nano/lib/logging.hpp>
#include <nano/node/election.hpp>
#include <nano/node/make_store.hpp>
@ -1278,7 +1279,7 @@ TEST (confirmation_heightDeathTest, modified_chain)
ledger, write_database_queue, 10ms, logger, stopped, batch_write_size, [] (auto const &) {}, [] (auto const &) {}, [] () { return 0; });
{
// This reads the blocks in the account, but prevents any writes from occuring yet
// This reads the blocks in the account, but prevents any writes from occurring yet
auto scoped_write_guard = write_database_queue.wait (nano::writer::testing);
bounded_processor.process (send);
}
@ -1297,7 +1298,7 @@ TEST (confirmation_heightDeathTest, modified_chain)
ledger, write_database_queue, 10ms, logger, stopped, batch_write_size, [] (auto const &) {}, [] (auto const &) {}, [] () { return 0; });
{
// This reads the blocks in the account, but prevents any writes from occuring yet
// This reads the blocks in the account, but prevents any writes from occurring yet
auto scoped_write_guard = write_database_queue.wait (nano::writer::testing);
unbounded_processor.process (send);
}
@ -1366,7 +1367,7 @@ TEST (confirmation_heightDeathTest, modified_chain_account_removed)
ledger, write_database_queue, 10ms, logger, stopped, batch_write_size, [] (auto const &) {}, [] (auto const &) {}, [] () { return 0; });
{
// This reads the blocks in the account, but prevents any writes from occuring yet
// This reads the blocks in the account, but prevents any writes from occurring yet
auto scoped_write_guard = write_database_queue.wait (nano::writer::testing);
unbounded_processor.process (open);
}
@ -1386,7 +1387,7 @@ TEST (confirmation_heightDeathTest, modified_chain_account_removed)
ledger, write_database_queue, 10ms, logger, stopped, batch_write_size, [] (auto const &) {}, [] (auto const &) {}, [] () { return 0; });
{
// This reads the blocks in the account, but prevents any writes from occuring yet
// This reads the blocks in the account, but prevents any writes from occurring yet
auto scoped_write_guard = write_database_queue.wait (nano::writer::testing);
bounded_processor.process (open);
}

View file

@ -1,3 +1,4 @@
#include <nano/lib/blocks.hpp>
#include <nano/lib/jsonconfig.hpp>
#include <nano/node/confirmation_solicitor.hpp>
#include <nano/node/transport/inproc.hpp>

View file

@ -1,4 +1,4 @@
#include <nano/lib/blocks.hpp>
#include <nano/node/election.hpp>
#include <nano/node/scheduler/component.hpp>
#include <nano/node/scheduler/priority.hpp>

View file

@ -1,3 +1,4 @@
#include <nano/lib/blocks.hpp>
#include <nano/node/election.hpp>
#include <nano/node/scheduler/component.hpp>
#include <nano/node/scheduler/priority.hpp>

View file

@ -1,3 +1,4 @@
#include <nano/lib/blocks.hpp>
#include <nano/node/scheduler/component.hpp>
#include <nano/node/scheduler/priority.hpp>
#include <nano/test_common/system.hpp>

View file

@ -1,3 +1,4 @@
#include <nano/lib/blocks.hpp>
#include <nano/node/active_transactions.hpp>
#include <nano/test_common/system.hpp>
#include <nano/test_common/testutil.hpp>

View file

@ -1,3 +1,4 @@
#include <nano/lib/blocks.hpp>
#include <nano/lib/logging.hpp>
#include <nano/lib/stats.hpp>
#include <nano/lib/threading.hpp>
@ -78,7 +79,7 @@ TEST (ledger, process_modifies_sideband)
.work (*pool.generate (nano::dev::genesis->hash ()))
.build ();
ASSERT_EQ (nano::block_status::progress, ledger.process (store.tx_begin_write (), send1));
ASSERT_EQ (send1->sideband ().timestamp, store.block.get (store.tx_begin_read (), send1->hash ())->sideband ().timestamp);
ASSERT_EQ (send1->sideband ().timestamp, ledger.block (store.tx_begin_read (), send1->hash ())->sideband ().timestamp);
}
// Create a send block and publish it.
@ -118,7 +119,7 @@ TEST (ledger, process_send)
auto info2 = ledger.account_info (transaction, nano::dev::genesis_key.pub);
ASSERT_TRUE (info2);
ASSERT_EQ (2, info2->block_count);
auto latest6 = store.block.get (transaction, info2->head);
auto latest6 = ledger.block (transaction, info2->head);
ASSERT_NE (nullptr, latest6);
auto latest7 = dynamic_cast<nano::send_block *> (latest6.get ());
ASSERT_NE (nullptr, latest7);
@ -150,14 +151,14 @@ TEST (ledger, process_send)
ASSERT_EQ (nano::dev::constants.genesis_amount - 50, ledger.weight (key2.pub));
auto info3 = ledger.account_info (transaction, nano::dev::genesis_key.pub);
ASSERT_TRUE (info3);
auto latest2 = store.block.get (transaction, info3->head);
auto latest2 = ledger.block (transaction, info3->head);
ASSERT_NE (nullptr, latest2);
auto latest3 = dynamic_cast<nano::send_block *> (latest2.get ());
ASSERT_NE (nullptr, latest3);
ASSERT_EQ (*send, *latest3);
auto info4 = ledger.account_info (transaction, key2.pub);
ASSERT_TRUE (info4);
auto latest4 = store.block.get (transaction, info4->head);
auto latest4 = ledger.block (transaction, info4->head);
ASSERT_NE (nullptr, latest4);
auto latest5 = dynamic_cast<nano::open_block *> (latest4.get ());
ASSERT_NE (nullptr, latest5);
@ -2382,8 +2383,8 @@ TEST (ledger, state_send_receive)
.work (*pool.generate (nano::dev::genesis->hash ()))
.build ();
ASSERT_EQ (nano::block_status::progress, ledger.process (transaction, send1));
ASSERT_TRUE (store.block.exists (transaction, send1->hash ()));
auto send2 = store.block.get (transaction, send1->hash ());
ASSERT_TRUE (ledger.block_exists (transaction, send1->hash ()));
auto send2 = ledger.block (transaction, send1->hash ());
ASSERT_NE (nullptr, send2);
ASSERT_EQ (*send1, *send2);
ASSERT_EQ (nano::dev::constants.genesis_amount - nano::Gxrb_ratio, ledger.balance (transaction, send1->hash ()));
@ -2405,8 +2406,8 @@ TEST (ledger, state_send_receive)
.work (*pool.generate (send1->hash ()))
.build ();
ASSERT_EQ (nano::block_status::progress, ledger.process (transaction, receive1));
ASSERT_TRUE (store.block.exists (transaction, receive1->hash ()));
auto receive2 = store.block.get (transaction, receive1->hash ());
ASSERT_TRUE (ledger.block_exists (transaction, receive1->hash ()));
auto receive2 = ledger.block (transaction, receive1->hash ());
ASSERT_NE (nullptr, receive2);
ASSERT_EQ (*receive1, *receive2);
ASSERT_EQ (nano::dev::constants.genesis_amount, ledger.balance (transaction, receive1->hash ()));
@ -2437,8 +2438,8 @@ TEST (ledger, state_receive)
.work (*pool.generate (nano::dev::genesis->hash ()))
.build ();
ASSERT_EQ (nano::block_status::progress, ledger.process (transaction, send1));
ASSERT_TRUE (store.block.exists (transaction, send1->hash ()));
auto send2 = store.block.get (transaction, send1->hash ());
ASSERT_TRUE (ledger.block_exists (transaction, send1->hash ()));
auto send2 = ledger.block (transaction, send1->hash ());
ASSERT_NE (nullptr, send2);
ASSERT_EQ (*send1, *send2);
ASSERT_EQ (nano::dev::constants.genesis_amount - nano::Gxrb_ratio, ledger.balance (transaction, send1->hash ()));
@ -2455,8 +2456,8 @@ TEST (ledger, state_receive)
.work (*pool.generate (send1->hash ()))
.build ();
ASSERT_EQ (nano::block_status::progress, ledger.process (transaction, receive1));
ASSERT_TRUE (store.block.exists (transaction, receive1->hash ()));
auto receive2 = store.block.get (transaction, receive1->hash ());
ASSERT_TRUE (ledger.block_exists (transaction, receive1->hash ()));
auto receive2 = ledger.block (transaction, receive1->hash ());
ASSERT_NE (nullptr, receive2);
ASSERT_EQ (*receive1, *receive2);
ASSERT_EQ (nano::dev::constants.genesis_amount, ledger.balance (transaction, receive1->hash ()));
@ -2488,8 +2489,8 @@ TEST (ledger, state_rep_change)
.work (*pool.generate (nano::dev::genesis->hash ()))
.build ();
ASSERT_EQ (nano::block_status::progress, ledger.process (transaction, change1));
ASSERT_TRUE (store.block.exists (transaction, change1->hash ()));
auto change2 = store.block.get (transaction, change1->hash ());
ASSERT_TRUE (ledger.block_exists (transaction, change1->hash ()));
auto change2 = ledger.block (transaction, change1->hash ());
ASSERT_NE (nullptr, change2);
ASSERT_EQ (*change1, *change2);
ASSERT_EQ (nano::dev::constants.genesis_amount, ledger.balance (transaction, change1->hash ()));
@ -2522,8 +2523,8 @@ TEST (ledger, state_open)
.work (*pool.generate (nano::dev::genesis->hash ()))
.build ();
ASSERT_EQ (nano::block_status::progress, ledger.process (transaction, send1));
ASSERT_TRUE (store.block.exists (transaction, send1->hash ()));
auto send2 = store.block.get (transaction, send1->hash ());
ASSERT_TRUE (ledger.block_exists (transaction, send1->hash ()));
auto send2 = ledger.block (transaction, send1->hash ());
ASSERT_NE (nullptr, send2);
ASSERT_EQ (*send1, *send2);
ASSERT_EQ (nano::dev::constants.genesis_amount - nano::Gxrb_ratio, ledger.balance (transaction, send1->hash ()));
@ -2542,8 +2543,8 @@ TEST (ledger, state_open)
.build ();
ASSERT_EQ (nano::block_status::progress, ledger.process (transaction, open1));
ASSERT_FALSE (store.pending.exists (transaction, nano::pending_key (destination.pub, send1->hash ())));
ASSERT_TRUE (store.block.exists (transaction, open1->hash ()));
auto open2 = store.block.get (transaction, open1->hash ());
ASSERT_TRUE (ledger.block_exists (transaction, open1->hash ()));
auto open2 = ledger.block (transaction, open1->hash ());
ASSERT_NE (nullptr, open2);
ASSERT_EQ (*open1, *open2);
ASSERT_EQ (nano::Gxrb_ratio, ledger.balance (transaction, open1->hash ()));
@ -2665,8 +2666,8 @@ TEST (ledger, state_unreceivable_fail)
.work (*pool.generate (nano::dev::genesis->hash ()))
.build ();
ASSERT_EQ (nano::block_status::progress, ledger.process (transaction, send1));
ASSERT_TRUE (store.block.exists (transaction, send1->hash ()));
auto send2 = store.block.get (transaction, send1->hash ());
ASSERT_TRUE (ledger.block_exists (transaction, send1->hash ()));
auto send2 = ledger.block (transaction, send1->hash ());
ASSERT_NE (nullptr, send2);
ASSERT_EQ (*send1, *send2);
ASSERT_EQ (nano::dev::constants.genesis_amount - nano::Gxrb_ratio, ledger.balance (transaction, send1->hash ()));
@ -2702,8 +2703,8 @@ TEST (ledger, state_receive_bad_amount_fail)
.work (*pool.generate (nano::dev::genesis->hash ()))
.build ();
ASSERT_EQ (nano::block_status::progress, ledger.process (transaction, send1));
ASSERT_TRUE (store.block.exists (transaction, send1->hash ()));
auto send2 = store.block.get (transaction, send1->hash ());
ASSERT_TRUE (ledger.block_exists (transaction, send1->hash ()));
auto send2 = ledger.block (transaction, send1->hash ());
ASSERT_NE (nullptr, send2);
ASSERT_EQ (*send1, *send2);
ASSERT_EQ (nano::dev::constants.genesis_amount - nano::Gxrb_ratio, ledger.balance (transaction, send1->hash ()));
@ -2774,8 +2775,8 @@ TEST (ledger, state_receive_wrong_account_fail)
.work (*pool.generate (nano::dev::genesis->hash ()))
.build ();
ASSERT_EQ (nano::block_status::progress, ledger.process (transaction, send1));
ASSERT_TRUE (store.block.exists (transaction, send1->hash ()));
auto send2 = store.block.get (transaction, send1->hash ());
ASSERT_TRUE (ledger.block_exists (transaction, send1->hash ()));
auto send2 = ledger.block (transaction, send1->hash ());
ASSERT_NE (nullptr, send2);
ASSERT_EQ (*send1, *send2);
ASSERT_EQ (nano::dev::constants.genesis_amount - nano::Gxrb_ratio, ledger.balance (transaction, send1->hash ()));
@ -2968,8 +2969,8 @@ TEST (ledger, state_send_change)
.work (*pool.generate (nano::dev::genesis->hash ()))
.build ();
ASSERT_EQ (nano::block_status::progress, ledger.process (transaction, send1));
ASSERT_TRUE (store.block.exists (transaction, send1->hash ()));
auto send2 = store.block.get (transaction, send1->hash ());
ASSERT_TRUE (ledger.block_exists (transaction, send1->hash ()));
auto send2 = ledger.block (transaction, send1->hash ());
ASSERT_NE (nullptr, send2);
ASSERT_EQ (*send1, *send2);
ASSERT_EQ (nano::dev::constants.genesis_amount - nano::Gxrb_ratio, ledger.balance (transaction, send1->hash ()));
@ -3001,8 +3002,8 @@ TEST (ledger, state_receive_change)
.work (*pool.generate (nano::dev::genesis->hash ()))
.build ();
ASSERT_EQ (nano::block_status::progress, ledger.process (transaction, send1));
ASSERT_TRUE (store.block.exists (transaction, send1->hash ()));
auto send2 = store.block.get (transaction, send1->hash ());
ASSERT_TRUE (ledger.block_exists (transaction, send1->hash ()));
auto send2 = ledger.block (transaction, send1->hash ());
ASSERT_NE (nullptr, send2);
ASSERT_EQ (*send1, *send2);
ASSERT_EQ (nano::dev::constants.genesis_amount - nano::Gxrb_ratio, ledger.balance (transaction, send1->hash ()));
@ -3020,8 +3021,8 @@ TEST (ledger, state_receive_change)
.work (*pool.generate (send1->hash ()))
.build ();
ASSERT_EQ (nano::block_status::progress, ledger.process (transaction, receive1));
ASSERT_TRUE (store.block.exists (transaction, receive1->hash ()));
auto receive2 = store.block.get (transaction, receive1->hash ());
ASSERT_TRUE (ledger.block_exists (transaction, receive1->hash ()));
auto receive2 = ledger.block (transaction, receive1->hash ());
ASSERT_NE (nullptr, receive2);
ASSERT_EQ (*receive1, *receive2);
ASSERT_EQ (nano::dev::constants.genesis_amount, ledger.balance (transaction, receive1->hash ()));
@ -3140,8 +3141,8 @@ TEST (ledger, state_rollback_send)
.work (*pool.generate (nano::dev::genesis->hash ()))
.build ();
ASSERT_EQ (nano::block_status::progress, ledger.process (transaction, send1));
ASSERT_TRUE (store.block.exists (transaction, send1->hash ()));
auto send2 = store.block.get (transaction, send1->hash ());
ASSERT_TRUE (ledger.block_exists (transaction, send1->hash ()));
auto send2 = ledger.block (transaction, send1->hash ());
ASSERT_NE (nullptr, send2);
ASSERT_EQ (*send1, *send2);
ASSERT_EQ (nano::dev::constants.genesis_amount - nano::Gxrb_ratio, ledger.account_balance (transaction, nano::dev::genesis->account ()));
@ -3151,7 +3152,7 @@ TEST (ledger, state_rollback_send)
ASSERT_EQ (nano::dev::genesis->account (), info->source);
ASSERT_EQ (nano::Gxrb_ratio, info->amount.number ());
ASSERT_FALSE (ledger.rollback (transaction, send1->hash ()));
ASSERT_FALSE (store.block.exists (transaction, send1->hash ()));
ASSERT_FALSE (ledger.block_exists (transaction, send1->hash ()));
ASSERT_EQ (nano::dev::constants.genesis_amount, ledger.account_balance (transaction, nano::dev::genesis->account ()));
ASSERT_EQ (nano::dev::constants.genesis_amount, ledger.weight (nano::dev::genesis->account ()));
ASSERT_FALSE (store.pending.exists (transaction, nano::pending_key (nano::dev::genesis->account (), send1->hash ())));
@ -3195,7 +3196,7 @@ TEST (ledger, state_rollback_receive)
ASSERT_TRUE (info);
ASSERT_EQ (nano::dev::genesis->account (), info->source);
ASSERT_EQ (nano::Gxrb_ratio, info->amount.number ());
ASSERT_FALSE (store.block.exists (transaction, receive1->hash ()));
ASSERT_FALSE (ledger.block_exists (transaction, receive1->hash ()));
ASSERT_EQ (nano::dev::constants.genesis_amount - nano::Gxrb_ratio, ledger.account_balance (transaction, nano::dev::genesis->account ()));
ASSERT_EQ (nano::dev::constants.genesis_amount - nano::Gxrb_ratio, ledger.weight (nano::dev::genesis->account ()));
ASSERT_EQ (store.account.count (transaction), ledger.cache.account_count);
@ -3235,8 +3236,8 @@ TEST (ledger, state_rollback_received_send)
ASSERT_FALSE (store.pending.exists (transaction, nano::pending_key (nano::dev::genesis->account (), receive1->hash ())));
ASSERT_FALSE (ledger.rollback (transaction, send1->hash ()));
ASSERT_FALSE (store.pending.exists (transaction, nano::pending_key (nano::dev::genesis->account (), send1->hash ())));
ASSERT_FALSE (store.block.exists (transaction, send1->hash ()));
ASSERT_FALSE (store.block.exists (transaction, receive1->hash ()));
ASSERT_FALSE (ledger.block_exists (transaction, send1->hash ()));
ASSERT_FALSE (ledger.block_exists (transaction, receive1->hash ()));
ASSERT_EQ (nano::dev::constants.genesis_amount, ledger.account_balance (transaction, nano::dev::genesis->account ()));
ASSERT_EQ (nano::dev::constants.genesis_amount, ledger.weight (nano::dev::genesis->account ()));
ASSERT_EQ (0, ledger.account_balance (transaction, key.pub));
@ -3265,7 +3266,7 @@ TEST (ledger, state_rep_change_rollback)
.build ();
ASSERT_EQ (nano::block_status::progress, ledger.process (transaction, change1));
ASSERT_FALSE (ledger.rollback (transaction, change1->hash ()));
ASSERT_FALSE (store.block.exists (transaction, change1->hash ()));
ASSERT_FALSE (ledger.block_exists (transaction, change1->hash ()));
ASSERT_EQ (nano::dev::constants.genesis_amount, ledger.account_balance (transaction, nano::dev::genesis->account ()));
ASSERT_EQ (nano::dev::constants.genesis_amount, ledger.weight (nano::dev::genesis->account ()));
ASSERT_EQ (0, ledger.weight (rep.pub));
@ -3303,7 +3304,7 @@ TEST (ledger, state_open_rollback)
.build ();
ASSERT_EQ (nano::block_status::progress, ledger.process (transaction, open1));
ASSERT_FALSE (ledger.rollback (transaction, open1->hash ()));
ASSERT_FALSE (store.block.exists (transaction, open1->hash ()));
ASSERT_FALSE (ledger.block_exists (transaction, open1->hash ()));
ASSERT_EQ (0, ledger.account_balance (transaction, destination.pub));
ASSERT_EQ (nano::dev::constants.genesis_amount - nano::Gxrb_ratio, ledger.weight (nano::dev::genesis->account ()));
auto info = ledger.pending_info (transaction, nano::pending_key (destination.pub, send1->hash ()));
@ -3334,7 +3335,7 @@ TEST (ledger, state_send_change_rollback)
.build ();
ASSERT_EQ (nano::block_status::progress, ledger.process (transaction, send1));
ASSERT_FALSE (ledger.rollback (transaction, send1->hash ()));
ASSERT_FALSE (store.block.exists (transaction, send1->hash ()));
ASSERT_FALSE (ledger.block_exists (transaction, send1->hash ()));
ASSERT_EQ (nano::dev::constants.genesis_amount, ledger.account_balance (transaction, nano::dev::genesis->account ()));
ASSERT_EQ (nano::dev::constants.genesis_amount, ledger.weight (nano::dev::genesis->account ()));
ASSERT_EQ (0, ledger.weight (rep.pub));
@ -3373,7 +3374,7 @@ TEST (ledger, state_receive_change_rollback)
.build ();
ASSERT_EQ (nano::block_status::progress, ledger.process (transaction, receive1));
ASSERT_FALSE (ledger.rollback (transaction, receive1->hash ()));
ASSERT_FALSE (store.block.exists (transaction, receive1->hash ()));
ASSERT_FALSE (ledger.block_exists (transaction, receive1->hash ()));
ASSERT_EQ (nano::dev::constants.genesis_amount - nano::Gxrb_ratio, ledger.account_balance (transaction, nano::dev::genesis->account ()));
ASSERT_EQ (nano::dev::constants.genesis_amount - nano::Gxrb_ratio, ledger.weight (nano::dev::genesis->account ()));
ASSERT_EQ (0, ledger.weight (rep.pub));
@ -4158,148 +4159,6 @@ TEST (ledger, block_hash_account_conflict)
ASSERT_EQ (*open_epoch1, *winner4);
}
TEST (ledger, could_fit)
{
nano::logger logger;
auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants);
ASSERT_TRUE (!store->init_error ());
nano::stats stats;
nano::ledger ledger (*store, stats, nano::dev::constants);
auto transaction (store->tx_begin_write ());
store->initialize (transaction, ledger.cache, ledger.constants);
nano::work_pool pool{ nano::dev::network_params.network, std::numeric_limits<unsigned>::max () };
nano::keypair destination;
// Test legacy and state change blocks could_fit
nano::block_builder builder;
auto change1 = builder
.change ()
.previous (nano::dev::genesis->hash ())
.representative (nano::dev::genesis->account ())
.sign (nano::dev::genesis_key.prv, nano::dev::genesis_key.pub)
.work (*pool.generate (nano::dev::genesis->hash ()))
.build ();
auto change2 = builder
.state ()
.account (nano::dev::genesis->account ())
.previous (nano::dev::genesis->hash ())
.representative (nano::dev::genesis->account ())
.balance (nano::dev::constants.genesis_amount)
.link (0)
.sign (nano::dev::genesis_key.prv, nano::dev::genesis_key.pub)
.work (*pool.generate (nano::dev::genesis->hash ()))
.build ();
ASSERT_TRUE (ledger.could_fit (transaction, *change1));
ASSERT_TRUE (ledger.could_fit (transaction, *change2));
// Test legacy and state send
nano::keypair key1;
auto send1 = builder
.send ()
.previous (change1->hash ())
.destination (key1.pub)
.balance (nano::dev::constants.genesis_amount - 1)
.sign (nano::dev::genesis_key.prv, nano::dev::genesis_key.pub)
.work (*pool.generate (change1->hash ()))
.build ();
auto send2 = builder
.state ()
.account (nano::dev::genesis->account ())
.previous (change1->hash ())
.representative (nano::dev::genesis->account ())
.balance (nano::dev::constants.genesis_amount - 1)
.link (key1.pub)
.sign (nano::dev::genesis_key.prv, nano::dev::genesis_key.pub)
.work (*pool.generate (change1->hash ()))
.build ();
ASSERT_FALSE (ledger.could_fit (transaction, *send1));
ASSERT_FALSE (ledger.could_fit (transaction, *send2));
ASSERT_EQ (nano::block_status::progress, ledger.process (transaction, change1));
ASSERT_TRUE (ledger.could_fit (transaction, *change1));
ASSERT_TRUE (ledger.could_fit (transaction, *change2));
ASSERT_TRUE (ledger.could_fit (transaction, *send1));
ASSERT_TRUE (ledger.could_fit (transaction, *send2));
// Test legacy and state open
auto open1 = builder
.open ()
.source (send2->hash ())
.representative (nano::dev::genesis->account ())
.account (key1.pub)
.sign (key1.prv, key1.pub)
.work (*pool.generate (key1.pub))
.build ();
auto open2 = builder
.state ()
.account (key1.pub)
.previous (0)
.representative (nano::dev::genesis->account ())
.balance (1)
.link (send2->hash ())
.sign (key1.prv, key1.pub)
.work (*pool.generate (key1.pub))
.build ();
ASSERT_FALSE (ledger.could_fit (transaction, *open1));
ASSERT_FALSE (ledger.could_fit (transaction, *open2));
ASSERT_EQ (nano::block_status::progress, ledger.process (transaction, send2));
ASSERT_TRUE (ledger.could_fit (transaction, *send1));
ASSERT_TRUE (ledger.could_fit (transaction, *send2));
ASSERT_TRUE (ledger.could_fit (transaction, *open1));
ASSERT_TRUE (ledger.could_fit (transaction, *open2));
ASSERT_EQ (nano::block_status::progress, ledger.process (transaction, open1));
ASSERT_TRUE (ledger.could_fit (transaction, *open1));
ASSERT_TRUE (ledger.could_fit (transaction, *open2));
// Create another send to receive
auto send3 = builder
.state ()
.account (nano::dev::genesis->account ())
.previous (send2->hash ())
.representative (nano::dev::genesis->account ())
.balance (nano::dev::constants.genesis_amount - 2)
.link (key1.pub)
.sign (nano::dev::genesis_key.prv, nano::dev::genesis_key.pub)
.work (*pool.generate (send2->hash ()))
.build ();
// Test legacy and state receive
auto receive1 = builder
.receive ()
.previous (open1->hash ())
.source (send3->hash ())
.sign (key1.prv, key1.pub)
.work (*pool.generate (open1->hash ()))
.build ();
auto receive2 = builder
.state ()
.account (key1.pub)
.previous (open1->hash ())
.representative (nano::dev::genesis->account ())
.balance (2)
.link (send3->hash ())
.sign (key1.prv, key1.pub)
.work (*pool.generate (open1->hash ()))
.build ();
ASSERT_FALSE (ledger.could_fit (transaction, *receive1));
ASSERT_FALSE (ledger.could_fit (transaction, *receive2));
ASSERT_EQ (nano::block_status::progress, ledger.process (transaction, send3));
ASSERT_TRUE (ledger.could_fit (transaction, *receive1));
ASSERT_TRUE (ledger.could_fit (transaction, *receive2));
// Test epoch (state)
auto epoch1 = builder
.state ()
.account (key1.pub)
.previous (receive1->hash ())
.representative (nano::dev::genesis->account ())
.balance (2)
.link (ledger.epoch_link (nano::epoch::epoch_1))
.sign (nano::dev::genesis_key.prv, nano::dev::genesis_key.pub)
.work (*pool.generate (receive1->hash ()))
.build ();
ASSERT_FALSE (ledger.could_fit (transaction, *epoch1));
ASSERT_EQ (nano::block_status::progress, ledger.process (transaction, receive1));
ASSERT_TRUE (ledger.could_fit (transaction, *receive1));
ASSERT_TRUE (ledger.could_fit (transaction, *receive2));
ASSERT_TRUE (ledger.could_fit (transaction, *epoch1));
ASSERT_EQ (nano::block_status::progress, ledger.process (transaction, epoch1));
ASSERT_TRUE (ledger.could_fit (transaction, *epoch1));
}
TEST (ledger, unchecked_epoch)
{
nano::test::system system (1);
@ -4348,7 +4207,7 @@ TEST (ledger, unchecked_epoch)
}
node1.block_processor.add (send1);
node1.block_processor.add (open1);
ASSERT_TIMELY (5s, node1.store.block.exists (node1.store.tx_begin_read (), epoch1->hash ()));
ASSERT_TIMELY (5s, node1.ledger.block_exists (node1.store.tx_begin_read (), epoch1->hash ()));
{
// Waits for the last blocks to pass through block_processor and unchecked.put queues
ASSERT_TIMELY_EQ (10s, 0, node1.unchecked.count ());
@ -4423,17 +4282,17 @@ TEST (ledger, unchecked_epoch_invalid)
node1.block_processor.add (send1);
node1.block_processor.add (open1);
// Waits for the last blocks to pass through block_processor and unchecked.put queues
ASSERT_TIMELY (10s, node1.store.block.exists (node1.store.tx_begin_read (), epoch2->hash ()));
ASSERT_TIMELY (10s, node1.ledger.block_exists (node1.store.tx_begin_read (), epoch2->hash ()));
{
auto transaction = node1.store.tx_begin_read ();
ASSERT_FALSE (node1.store.block.exists (transaction, epoch1->hash ()));
ASSERT_FALSE (node1.ledger.block_exists (transaction, epoch1->hash ()));
auto unchecked_count = node1.unchecked.count ();
ASSERT_EQ (unchecked_count, 0);
ASSERT_EQ (unchecked_count, node1.unchecked.count ());
auto info = node1.ledger.account_info (transaction, destination.pub);
ASSERT_TRUE (info);
ASSERT_NE (info->epoch (), nano::epoch::epoch_1);
auto epoch2_store = node1.store.block.get (transaction, epoch2->hash ());
auto epoch2_store = node1.ledger.block (transaction, epoch2->hash ());
ASSERT_NE (nullptr, epoch2_store);
ASSERT_EQ (nano::epoch::epoch_0, epoch2_store->sideband ().details.epoch);
ASSERT_TRUE (epoch2_store->sideband ().details.is_send);
@ -4490,7 +4349,7 @@ TEST (ledger, unchecked_open)
}
node1.block_processor.add (send1);
// Waits for the send1 block to pass through block_processor and unchecked.put queues
ASSERT_TIMELY (5s, node1.store.block.exists (node1.store.tx_begin_read (), open1->hash ()));
ASSERT_TIMELY (5s, node1.ledger.block_exists (node1.store.tx_begin_read (), open1->hash ()));
ASSERT_EQ (0, node1.unchecked.count ());
}
@ -4561,7 +4420,7 @@ TEST (ledger, unchecked_receive)
ASSERT_EQ (blocks.size (), 1);
}
node1.block_processor.add (send2);
ASSERT_TIMELY (10s, node1.store.block.exists (node1.store.tx_begin_read (), receive1->hash ()));
ASSERT_TIMELY (10s, node1.ledger.block_exists (node1.store.tx_begin_read (), receive1->hash ()));
ASSERT_EQ (0, node1.unchecked.count ());
}
@ -5503,21 +5362,11 @@ TEST (ledger, pruning_safe_functions)
ASSERT_TRUE (store->block.exists (transaction, nano::dev::genesis->hash ()));
ASSERT_TRUE (store->block.exists (transaction, send2->hash ()));
// Safe ledger actions
bool error (false);
ASSERT_EQ (0, ledger.balance_safe (transaction, send1->hash (), error));
ASSERT_TRUE (error);
error = false;
ASSERT_EQ (nano::dev::constants.genesis_amount - nano::Gxrb_ratio * 2, ledger.balance_safe (transaction, send2->hash (), error));
ASSERT_FALSE (error);
error = false;
ASSERT_EQ (0, ledger.amount_safe (transaction, send2->hash (), error));
ASSERT_TRUE (error);
error = false;
ASSERT_TRUE (ledger.account_safe (transaction, send1->hash (), error).is_zero ());
ASSERT_TRUE (error);
error = false;
ASSERT_EQ (nano::dev::genesis->account (), ledger.account_safe (transaction, send2->hash (), error));
ASSERT_FALSE (error);
ASSERT_FALSE (ledger.balance (transaction, send1->hash ()));
ASSERT_EQ (nano::dev::constants.genesis_amount - nano::Gxrb_ratio * 2, ledger.balance (transaction, send2->hash ()).value ());
ASSERT_FALSE (ledger.amount (transaction, send2->hash ()));
ASSERT_FALSE (ledger.account (transaction, send1->hash ()));
ASSERT_EQ (nano::dev::genesis->account (), ledger.account (transaction, send2->hash ()).value ());
}
TEST (ledger, hash_root_random)

View file

@ -1,3 +1,4 @@
#include <nano/lib/blocks.hpp>
#include <nano/lib/memory.hpp>
#include <nano/node/active_transactions.hpp>
#include <nano/secure/common.hpp>

View file

@ -1,4 +1,5 @@
#include <nano/crypto_lib/random_pool.hpp>
#include <nano/lib/blocks.hpp>
#include <nano/lib/stream.hpp>
#include <nano/node/common.hpp>
#include <nano/node/network.hpp>

View file

@ -1,3 +1,4 @@
#include <nano/lib/blocks.hpp>
#include <nano/node/transport/message_deserializer.hpp>
#include <nano/test_common/system.hpp>
#include <nano/test_common/testutil.hpp>

View file

@ -1,3 +1,4 @@
#include <nano/lib/blocks.hpp>
#include <nano/node/network.hpp>
#include <nano/node/nodeconfig.hpp>
#include <nano/node/scheduler/component.hpp>

View file

@ -1,3 +1,4 @@
#include <nano/lib/blocks.hpp>
#include <nano/lib/stream.hpp>
#include <nano/node/common.hpp>
#include <nano/secure/common.hpp>

View file

@ -1,3 +1,4 @@
#include <nano/lib/blocks.hpp>
#include <nano/lib/config.hpp>
#include <nano/lib/logging.hpp>
#include <nano/node/election.hpp>
@ -668,8 +669,8 @@ TEST (node, fork_keep)
auto winner (*election1->tally ().begin ());
ASSERT_EQ (*send1, *winner.second);
ASSERT_EQ (nano::dev::constants.genesis_amount - 100, winner.first);
ASSERT_TRUE (node1.store.block.exists (transaction0, send1->hash ()));
ASSERT_TRUE (node2.store.block.exists (transaction1, send1->hash ()));
ASSERT_TRUE (node1.ledger.block_exists (transaction0, send1->hash ()));
ASSERT_TRUE (node2.ledger.block_exists (transaction1, send1->hash ()));
}
TEST (node, fork_flip)
@ -811,7 +812,7 @@ TEST (node, fork_bootstrap_flip)
// Insert but don't rebroadcast, simulating settled blocks
ASSERT_EQ (nano::block_status::progress, node1.ledger.process (node1.store.tx_begin_write (), send1));
ASSERT_EQ (nano::block_status::progress, node2.ledger.process (node2.store.tx_begin_write (), send2));
ASSERT_TRUE (node2.store.block.exists (node2.store.tx_begin_read (), send2->hash ()));
ASSERT_TRUE (node2.ledger.block_exists (node2.store.tx_begin_read (), send2->hash ()));
node2.bootstrap_initiator.bootstrap (node1.network.endpoint ()); // Additionally add new peer to confirm & replace bootstrap block
auto again (true);
system0.deadline_set (50s);
@ -820,7 +821,7 @@ TEST (node, fork_bootstrap_flip)
{
ASSERT_NO_ERROR (system0.poll ());
ASSERT_NO_ERROR (system1.poll ());
again = !node2.store.block.exists (node2.store.tx_begin_read (), send1->hash ());
again = !node2.ledger.block_exists (node2.store.tx_begin_read (), send1->hash ());
}
}
@ -972,9 +973,9 @@ TEST (node, fork_open_flip)
// check the correct blocks are in the ledgers
auto transaction1 (node1.store.tx_begin_read ());
auto transaction2 (node2.store.tx_begin_read ());
ASSERT_TRUE (node1.store.block.exists (transaction1, open1->hash ()));
ASSERT_TRUE (node2.store.block.exists (transaction2, open1->hash ()));
ASSERT_FALSE (node2.store.block.exists (transaction2, open2->hash ()));
ASSERT_TRUE (node1.ledger.block_exists (transaction1, open1->hash ()));
ASSERT_TRUE (node2.ledger.block_exists (transaction2, open1->hash ()));
ASSERT_FALSE (node2.ledger.block_exists (transaction2, open2->hash ()));
}
TEST (node, coherent_observer)
@ -983,7 +984,7 @@ TEST (node, coherent_observer)
auto & node1 (*system.nodes[0]);
node1.observers.blocks.add ([&node1] (nano::election_status const & status_a, std::vector<nano::vote_with_weight_info> const &, nano::account const &, nano::uint128_t const &, bool, bool) {
auto transaction (node1.store.tx_begin_read ());
ASSERT_TRUE (node1.store.block.exists (transaction, status_a.winner->hash ()));
ASSERT_TRUE (node1.ledger.block_exists (transaction, status_a.winner->hash ()));
});
system.wallet (0)->insert_adhoc (nano::dev::genesis_key.prv);
nano::keypair key;

View file

@ -1,3 +1,4 @@
#include <nano/lib/blocks.hpp>
#include <nano/node/election.hpp>
#include <nano/test_common/chains.hpp>
#include <nano/test_common/system.hpp>

View file

@ -1,3 +1,4 @@
#include <nano/lib/blocks.hpp>
#include <nano/lib/logging.hpp>
#include <nano/lib/stats.hpp>
#include <nano/lib/work.hpp>

View file

@ -1,3 +1,4 @@
#include <nano/lib/blocks.hpp>
#include <nano/lib/config.hpp>
#include <nano/lib/logging.hpp>
#include <nano/node/repcrawler.hpp>

View file

@ -1,3 +1,4 @@
#include <nano/lib/blocks.hpp>
#include <nano/lib/jsonconfig.hpp>
#include <nano/node/request_aggregator.hpp>
#include <nano/node/transport/inproc.hpp>

View file

@ -1,3 +1,4 @@
#include <nano/lib/blocks.hpp>
#include <nano/node/scheduler/buckets.hpp>
#include <nano/secure/common.hpp>

View file

@ -1,3 +1,4 @@
#include <nano/lib/blocks.hpp>
#include <nano/lib/thread_runner.hpp>
#include <nano/node/transport/inproc.hpp>
#include <nano/test_common/network.hpp>

View file

@ -1,4 +1,5 @@
#include <nano/lib/blockbuilders.hpp>
#include <nano/lib/blocks.hpp>
#include <nano/lib/stats.hpp>
#include <nano/node/unchecked_map.hpp>
#include <nano/secure/common.hpp>

View file

@ -1,3 +1,4 @@
#include <nano/lib/blocks.hpp>
#include <nano/lib/jsonconfig.hpp>
#include <nano/node/transport/inproc.hpp>
#include <nano/node/vote_processor.hpp>

View file

@ -1,3 +1,4 @@
#include <nano/lib/blocks.hpp>
#include <nano/node/common.hpp>
#include <nano/node/voting.hpp>
#include <nano/test_common/system.hpp>

View file

@ -1,4 +1,5 @@
#include <nano/crypto_lib/random_pool.hpp>
#include <nano/lib/blocks.hpp>
#include <nano/lib/thread_runner.hpp>
#include <nano/store/lmdb/wallet_value.hpp>
#include <nano/test_common/system.hpp>
@ -181,7 +182,7 @@ TEST (wallet, spend_all_one)
auto transaction (node1.store.tx_begin_read ());
auto info2 = node1.ledger.account_info (transaction, nano::dev::genesis_key.pub);
ASSERT_NE (latest1, info2->head);
auto block (node1.store.block.get (transaction, info2->head));
auto block = node1.ledger.block (transaction, info2->head);
ASSERT_NE (nullptr, block);
ASSERT_EQ (latest1, block->previous ());
ASSERT_TRUE (info2->balance.is_zero ());
@ -216,7 +217,7 @@ TEST (wallet, spend)
auto info2 = node1.ledger.account_info (transaction, nano::dev::genesis_key.pub);
ASSERT_TRUE (info2);
ASSERT_NE (latest1, info2->head);
auto block (node1.store.block.get (transaction, info2->head));
auto block = node1.ledger.block (transaction, info2->head);
ASSERT_NE (nullptr, block);
ASSERT_EQ (latest1, block->previous ());
ASSERT_TRUE (info2->balance.is_zero ());
@ -1223,7 +1224,7 @@ TEST (wallet, receive_pruned)
}
ASSERT_EQ (1, node2.ledger.cache.pruned_count);
ASSERT_TRUE (node2.ledger.block_or_pruned_exists (send1->hash ()));
ASSERT_FALSE (node2.store.block.exists (node2.store.tx_begin_read (), send1->hash ()));
ASSERT_FALSE (node2.ledger.block_exists (node2.store.tx_begin_read (), send1->hash ()));
wallet2.insert_adhoc (key.prv, false);

View file

@ -1,3 +1,4 @@
#include <nano/lib/blocks.hpp>
#include <nano/store/versioning.hpp>
#include <nano/test_common/system.hpp>
#include <nano/test_common/testutil.hpp>

View file

@ -1,4 +1,5 @@
#include <nano/core_test/fakes/websocket_client.hpp>
#include <nano/lib/blocks.hpp>
#include <nano/node/transport/fake.hpp>
#include <nano/node/websocket.hpp>
#include <nano/test_common/network.hpp>

View file

@ -21,6 +21,11 @@ add_library(
${platform_sources}
asio.hpp
asio.cpp
block_sideband.hpp
block_sideband.cpp
block_type.hpp
block_type.cpp
block_uniquer.hpp
blockbuilders.hpp
blockbuilders.cpp
blocks.hpp

View file

View file

@ -0,0 +1,69 @@
#pragma once
#include <nano/lib/block_type.hpp>
#include <nano/lib/epoch.hpp>
#include <nano/lib/numbers.hpp>
#include <nano/lib/stream.hpp>
#include <nano/lib/timer.hpp>
#include <cstdint>
#include <memory>
namespace nano
{
class object_stream;
}
namespace nano
{
class block_details
{
static_assert (std::is_same<std::underlying_type<nano::epoch>::type, uint8_t> (), "Epoch enum is not the proper type");
static_assert (static_cast<uint8_t> (nano::epoch::max) < (1 << 5), "Epoch max is too large for the sideband");
public:
block_details () = default;
block_details (nano::epoch const epoch_a, bool const is_send_a, bool const is_receive_a, bool const is_epoch_a);
static constexpr size_t size ()
{
return 1;
}
bool operator== (block_details const & other_a) const;
void serialize (nano::stream &) const;
bool deserialize (nano::stream &);
nano::epoch epoch{ nano::epoch::epoch_0 };
bool is_send{ false };
bool is_receive{ false };
bool is_epoch{ false };
private:
uint8_t packed () const;
void unpack (uint8_t);
public: // Logging
void operator() (nano::object_stream &) const;
};
std::string state_subtype (nano::block_details const);
class block_sideband final
{
public:
block_sideband () = default;
block_sideband (nano::account const &, nano::block_hash const &, nano::amount const &, uint64_t const, nano::seconds_t const local_timestamp, nano::block_details const &, nano::epoch const source_epoch_a);
block_sideband (nano::account const &, nano::block_hash const &, nano::amount const &, uint64_t const, nano::seconds_t const local_timestamp, nano::epoch const epoch_a, bool const is_send, bool const is_receive, bool const is_epoch, nano::epoch const source_epoch_a);
void serialize (nano::stream &, nano::block_type) const;
bool deserialize (nano::stream &, nano::block_type);
static size_t size (nano::block_type);
nano::block_hash successor{ 0 };
nano::account account{};
nano::amount balance{ 0 };
uint64_t height{ 0 };
uint64_t timestamp{ 0 };
nano::block_details details;
nano::epoch source_epoch{ nano::epoch::epoch_0 };
public: // Logging
void operator() (nano::object_stream &) const;
};
} // namespace nano

13
nano/lib/block_type.cpp Normal file
View file

@ -0,0 +1,13 @@
#include <nano/lib/block_type.hpp>
#include <magic_enum.hpp>
std::string_view nano::to_string (nano::block_type type)
{
return magic_enum::enum_name (type);
}
void nano::serialize_block_type (nano::stream & stream, const nano::block_type & type)
{
nano::write (stream, type);
}

26
nano/lib/block_type.hpp Normal file
View file

@ -0,0 +1,26 @@
#pragma once
#include <nano/lib/stream.hpp>
#include <cstdint>
#include <string>
namespace nano
{
enum class block_type : uint8_t
{
invalid = 0,
not_a_block = 1,
send = 2,
receive = 3,
open = 4,
change = 5,
state = 6
};
std::string_view to_string (block_type);
/**
* Serialize block type as an 8-bit value
*/
void serialize_block_type (nano::stream &, nano::block_type const &);
} // namespace nano

View file

@ -0,0 +1,10 @@
#pragma once
#include <nano/lib/numbers.hpp>
#include <nano/lib/uniquer.hpp>
namespace nano
{
class block;
using block_uniquer = nano::uniquer<nano::uint256_union, nano::block>;
}

View file

@ -1,4 +1,7 @@
#include <nano/lib/blockbuilders.hpp>
#include <nano/lib/blocks.hpp>
#include <nano/lib/errors.hpp>
#include <nano/lib/utility.hpp>
#include <unordered_map>

View file

@ -1,9 +1,18 @@
#pragma once
#include <nano/lib/blocks.hpp>
#include <nano/lib/numbers.hpp>
#include <memory>
namespace nano
{
class change_block;
class send_block;
class state_block;
class open_block;
class receive_block;
}
namespace nano
{
/** Flags to track builder state */

View file

@ -13,6 +13,12 @@
#include <cryptopp/words.h>
#include <magic_enum.hpp>
size_t constexpr nano::send_block::size;
size_t constexpr nano::receive_block::size;
size_t constexpr nano::open_block::size;
size_t constexpr nano::change_block::size;
size_t constexpr nano::state_block::size;
/** Compare blocks, first by type, then content. This is an optimization over dynamic_cast, which is very slow on some platforms. */
namespace
{
@ -1443,11 +1449,6 @@ std::shared_ptr<nano::block> nano::deserialize_block_json (boost::property_tree:
return result;
}
void nano::serialize_block_type (nano::stream & stream, const nano::block_type & type)
{
nano::write (stream, type);
}
void nano::serialize_block (nano::stream & stream_a, nano::block const & block_a)
{
nano::serialize_block_type (stream_a, block_a.type ());
@ -1986,8 +1987,3 @@ void nano::block_sideband::operator() (nano::object_stream & obs) const
obs.write ("source_epoch", source_epoch);
obs.write ("details", details);
}
std::string_view nano::to_string (nano::block_type type)
{
return magic_enum::enum_name (type);
}

View file

@ -1,89 +1,23 @@
#pragma once
#include <nano/crypto/blake2/blake2.h>
#include <nano/lib/block_sideband.hpp>
#include <nano/lib/block_uniquer.hpp>
#include <nano/lib/config.hpp>
#include <nano/lib/epoch.hpp>
#include <nano/lib/errors.hpp>
#include <nano/lib/numbers.hpp>
#include <nano/lib/object_stream.hpp>
#include <nano/lib/optional_ptr.hpp>
#include <nano/lib/stream.hpp>
#include <nano/lib/timer.hpp>
#include <nano/lib/uniquer.hpp>
#include <nano/lib/utility.hpp>
#include <nano/lib/work.hpp>
#include <boost/property_tree/ptree_fwd.hpp>
#include <unordered_map>
typedef struct blake2b_state__ blake2b_state;
namespace nano
{
class block_visitor;
class mutable_block_visitor;
enum class block_type : uint8_t
{
invalid = 0,
not_a_block = 1,
send = 2,
receive = 3,
open = 4,
change = 5,
state = 6
};
std::string_view to_string (block_type);
class block_details
{
static_assert (std::is_same<std::underlying_type<nano::epoch>::type, uint8_t> (), "Epoch enum is not the proper type");
static_assert (static_cast<uint8_t> (nano::epoch::max) < (1 << 5), "Epoch max is too large for the sideband");
public:
block_details () = default;
block_details (nano::epoch const epoch_a, bool const is_send_a, bool const is_receive_a, bool const is_epoch_a);
static constexpr size_t size ()
{
return 1;
}
bool operator== (block_details const & other_a) const;
void serialize (nano::stream &) const;
bool deserialize (nano::stream &);
nano::epoch epoch{ nano::epoch::epoch_0 };
bool is_send{ false };
bool is_receive{ false };
bool is_epoch{ false };
private:
uint8_t packed () const;
void unpack (uint8_t);
public: // Logging
void operator() (nano::object_stream &) const;
};
std::string state_subtype (nano::block_details const);
class block_sideband final
{
public:
block_sideband () = default;
block_sideband (nano::account const &, nano::block_hash const &, nano::amount const &, uint64_t const, nano::seconds_t const local_timestamp, nano::block_details const &, nano::epoch const source_epoch_a);
block_sideband (nano::account const &, nano::block_hash const &, nano::amount const &, uint64_t const, nano::seconds_t const local_timestamp, nano::epoch const epoch_a, bool const is_send, bool const is_receive, bool const is_epoch, nano::epoch const source_epoch_a);
void serialize (nano::stream &, nano::block_type) const;
bool deserialize (nano::stream &, nano::block_type);
static size_t size (nano::block_type);
nano::block_hash successor{ 0 };
nano::account account{};
nano::amount balance{ 0 };
uint64_t height{ 0 };
uint64_t timestamp{ 0 };
nano::block_details details;
nano::epoch source_epoch{ nano::epoch::epoch_0 };
public: // Logging
void operator() (nano::object_stream &) const;
};
class object_stream;
class block
{
@ -146,8 +80,6 @@ public: // Logging
virtual void operator() (nano::object_stream &) const;
};
using block_list_t = std::vector<std::shared_ptr<nano::block>>;
class send_hashables
{
public:
@ -441,15 +373,9 @@ public:
virtual ~mutable_block_visitor () = default;
};
using block_uniquer = nano::uniquer<nano::uint256_union, nano::block>;
std::shared_ptr<nano::block> deserialize_block (nano::stream &);
std::shared_ptr<nano::block> deserialize_block (nano::stream &, nano::block_type, nano::block_uniquer * = nullptr);
std::shared_ptr<nano::block> deserialize_block_json (boost::property_tree::ptree const &, nano::block_uniquer * = nullptr);
/**
* Serialize block type as an 8-bit value
*/
void serialize_block_type (nano::stream &, nano::block_type const &);
/**
* Serialize a block prefixed with an 8-bit typecode
*/

View file

@ -1,3 +1,4 @@
#include <nano/crypto/blake2/blake2.h>
#include <nano/lib/blocks.hpp>
#include <nano/lib/config.hpp>
#include <nano/lib/logging.hpp>

View file

@ -202,6 +202,7 @@ public:
default_websocket_port (47000),
aec_loop_interval_ms (300), // Update AEC ~3 times per second
cleanup_period (default_cleanup_period),
merge_period (std::chrono::milliseconds (250)),
keepalive_period (std::chrono::seconds (15)),
idle_timeout (default_cleanup_period * 2),
silent_connection_tolerance_time (std::chrono::seconds (120)),
@ -239,6 +240,7 @@ public:
{
aec_loop_interval_ms = 20;
cleanup_period = std::chrono::seconds (1);
merge_period = std::chrono::milliseconds (10);
keepalive_period = std::chrono::seconds (1);
idle_timeout = cleanup_period * 15;
max_peers_per_ip = 20;
@ -279,6 +281,8 @@ public:
{
return cleanup_period * 5;
}
/** How often to connect to other peers */
std::chrono::milliseconds merge_period;
/** How often to send keepalive messages */
std::chrono::seconds keepalive_period;
/** Default maximum idle time for a socket before it's automatically closed */

View file

@ -50,6 +50,7 @@ enum class type : uint8_t
optimistic_scheduler,
handshake,
rep_crawler,
local_block_broadcaster,
bootstrap_ascending,
bootstrap_ascending_accounts,
@ -103,6 +104,7 @@ enum class detail : uint8_t
old,
gap_previous,
gap_source,
rollback,
rollback_failed,
progress,
bad_signature,
@ -341,6 +343,12 @@ enum class detail : uint8_t
crawl_aggressive,
crawl_normal,
// block broadcaster
broadcast_normal,
broadcast_aggressive,
erase_old,
erase_confirmed,
_last // Must be the last enum
};
@ -375,4 +383,4 @@ struct magic_enum::customize::enum_range<nano::stat::detail>
{
static constexpr int min = 0;
static constexpr int max = 512;
};
};

View file

@ -103,6 +103,9 @@ std::string nano::thread_role::get_string (nano::thread_role::name role)
case nano::thread_role::name::rep_crawler:
thread_role_name_string = "Rep Crawler";
break;
case nano::thread_role::name::local_block_broadcasting:
thread_role_name_string = "Local broadcast";
break;
default:
debug_assert (false && "nano::thread_role::get_string unhandled thread role");
}

View file

@ -43,6 +43,7 @@ enum class name
scheduler_optimistic,
scheduler_priority,
rep_crawler,
local_block_broadcasting,
};
/*

View file

@ -1,3 +1,4 @@
#include <nano/crypto/blake2/blake2.h>
#include <nano/crypto_lib/random_pool.hpp>
#include <nano/lib/blocks.hpp>
#include <nano/lib/epoch.hpp>

View file

@ -4,6 +4,7 @@
#include <nano/boost/beast/core/flat_buffer.hpp>
#include <nano/boost/beast/http.hpp>
#include <nano/boost/process/child.hpp>
#include <nano/lib/blocks.hpp>
#include <nano/lib/logging.hpp>
#include <nano/lib/thread_runner.hpp>
#include <nano/lib/threading.hpp>

View file

@ -1,4 +1,5 @@
#include <nano/crypto_lib/random_pool.hpp>
#include <nano/lib/blocks.hpp>
#include <nano/lib/cli.hpp>
#include <nano/lib/thread_runner.hpp>
#include <nano/lib/utility.hpp>
@ -1411,17 +1412,17 @@ int main (int argc, char * const * argv)
auto hash (info.open_block);
nano::block_hash calculated_hash (0);
auto block (node->store.block.get (transaction, hash)); // Block data
auto block = node->ledger.block (transaction, hash); // Block data
uint64_t height (0);
if (node->ledger.pruning && confirmation_height_info.height != 0)
{
hash = confirmation_height_info.frontier;
block = node->store.block.get (transaction, hash);
block = node->ledger.block (transaction, hash);
// Iteration until pruned block
bool pruned_block (false);
while (!pruned_block && !block->previous ().is_zero ())
{
auto previous_block (node->store.block.get (transaction, block->previous ()));
auto previous_block = node->ledger.block (transaction, block->previous ());
if (previous_block != nullptr)
{
hash = previous_block->hash ();
@ -1494,7 +1495,7 @@ int main (int argc, char * const * argv)
bool error_or_pruned (false);
if (!state_block.hashables.previous.is_zero ())
{
prev_balance = node->ledger.balance_safe (transaction, state_block.hashables.previous, error_or_pruned);
prev_balance = node->ledger.balance (transaction, state_block.hashables.previous).value_or (0);
}
if (node->ledger.is_epoch_link (state_block.hashables.link))
{
@ -1518,11 +1519,10 @@ int main (int argc, char * const * argv)
}
else
{
bool error_or_pruned (false);
auto prev_balance (node->ledger.balance_safe (transaction, block->previous (), error_or_pruned));
if (!node->ledger.pruning || !error_or_pruned)
auto prev_balance = node->ledger.balance (transaction, block->previous ());
if (!node->ledger.pruning || prev_balance)
{
if (block->balance () < prev_balance)
if (block->balance () < prev_balance.value ())
{
// State send
block_details_error = !sideband.details.is_send || sideband.details.is_receive || sideband.details.is_epoch;
@ -1534,7 +1534,7 @@ int main (int argc, char * const * argv)
// State change
block_details_error = sideband.details.is_send || sideband.details.is_receive || sideband.details.is_epoch;
}
else if (block->balance () == prev_balance && node->ledger.is_epoch_link (block->link ()))
else if (block->balance () == prev_balance.value () && node->ledger.is_epoch_link (block->link ()))
{
// State epoch
block_details_error = !sideband.details.is_epoch || sideband.details.is_send || sideband.details.is_receive;
@ -1591,7 +1591,7 @@ int main (int argc, char * const * argv)
// Retrieving block data
if (!hash.is_zero ())
{
block = node->store.block.get (transaction, hash);
block = node->ledger.block (transaction, hash);
}
}
// Check if required block exists
@ -1676,7 +1676,7 @@ int main (int argc, char * const * argv)
std::cout << boost::str (boost::format ("%1% pending blocks validated\n") % count);
}
// Check block existance
auto block (node->store.block.get (transaction, key.hash));
auto block = node->ledger.block (transaction, key.hash);
bool pruned (false);
if (block == nullptr)
{
@ -1693,7 +1693,7 @@ int main (int argc, char * const * argv)
bool previous_pruned = node->ledger.pruning && node->store.pruned.exists (transaction, block->previous ());
if (previous_pruned)
{
block = node->store.block.get (transaction, key.hash);
block = node->ledger.block (transaction, key.hash);
}
if (auto state = dynamic_cast<nano::state_block *> (block.get ()))
{
@ -1800,7 +1800,7 @@ int main (int argc, char * const * argv)
while (!hash.is_zero ())
{
// Retrieving block data
auto block (source_node->store.block.get (transaction, hash));
auto block = source_node->ledger.block (transaction, hash);
if (block != nullptr)
{
++count;

View file

@ -20,8 +20,6 @@ add_library(
backlog_population.cpp
bandwidth_limiter.hpp
bandwidth_limiter.cpp
block_broadcast.cpp
block_broadcast.hpp
blockprocessor.hpp
blockprocessor.cpp
bootstrap/block_deserializer.hpp
@ -100,6 +98,8 @@ add_library(
ipc/ipc_server.cpp
json_handler.hpp
json_handler.cpp
local_block_broadcaster.cpp
local_block_broadcaster.hpp
make_store.hpp
make_store.cpp
network.hpp

View file

@ -1,3 +1,4 @@
#include <nano/lib/blocks.hpp>
#include <nano/lib/threading.hpp>
#include <nano/node/active_transactions.hpp>
#include <nano/node/confirmation_height_processor.hpp>

View file

@ -1,51 +0,0 @@
#include <nano/node/block_broadcast.hpp>
#include <nano/node/blockprocessor.hpp>
#include <nano/node/network.hpp>
nano::block_broadcast::block_broadcast (nano::network & network, bool enabled) :
network{ network },
enabled{ enabled }
{
}
void nano::block_broadcast::connect (nano::block_processor & block_processor)
{
if (!enabled)
{
return;
}
block_processor.block_processed.add ([this] (auto const & result, auto const & context) {
switch (result)
{
case nano::block_status::progress:
observe (context);
break;
default:
break;
}
});
}
void nano::block_broadcast::observe (nano::block_processor::context const & context)
{
auto const & block = context.block;
if (context.source == nano::block_source::local)
{
// Block created on this node
// Perform more agressive initial flooding
network.flood_block_initial (block);
}
else
{
if (context.source != nano::block_source::bootstrap && context.source != nano::block_source::bootstrap_legacy)
{
// Block arrived from realtime traffic, do normal gossip.
network.flood_block (block, nano::transport::buffer_drop_policy::limiter);
}
else
{
// Block arrived from bootstrap
// Don't broadcast blocks we're bootstrapping
}
}
}

View file

@ -1,28 +0,0 @@
#pragma once
#include <nano/lib/blocks.hpp>
#include <nano/node/blockprocessor.hpp>
#include <memory>
#include <unordered_set>
namespace nano
{
class network;
// This class tracks blocks that originated from this node.
class block_broadcast
{
public:
block_broadcast (nano::network & network, bool enabled = false);
// Add batch_processed observer to block_processor if enabled
void connect (nano::block_processor & block_processor);
private:
// Block_processor observer
void observe (nano::block_processor::context const &);
nano::network & network;
bool enabled;
};
}

View file

@ -1,3 +1,4 @@
#include <nano/lib/blocks.hpp>
#include <nano/lib/threading.hpp>
#include <nano/lib/timer.hpp>
#include <nano/node/blockprocessor.hpp>
@ -152,11 +153,15 @@ void nano::block_processor::rollback_competitor (store::write_transaction const
}
else
{
node.stats.inc (nano::stat::type::ledger, nano::stat::detail::rollback);
node.logger.debug (nano::log::type::blockprocessor, "Blocks rolled back: {}", rollback_list.size ());
}
// Deleting from votes cache, stop active transaction
for (auto & i : rollback_list)
{
rolled_back.notify (i);
node.history.erase (i->root ());
// Stop all rolled back active transactions except initial
if (i->hash () != successor->hash ())

View file

@ -1,6 +1,5 @@
#pragma once
#include <nano/lib/blocks.hpp>
#include <nano/lib/logging.hpp>
#include <nano/secure/common.hpp>
@ -10,6 +9,13 @@
#include <optional>
#include <thread>
namespace nano
{
class block;
class node;
class write_database_queue;
}
namespace nano::store
{
class write_transaction;
@ -17,8 +23,6 @@ class write_transaction;
namespace nano
{
class node;
class write_database_queue;
enum class block_source
{
@ -86,6 +90,7 @@ public: // Events
// The batch observer feeds the processed observer
nano::observer_set<nano::block_status const &, context const &> block_processed;
nano::observer_set<processed_batch_t const &> batch_processed;
nano::observer_set<std::shared_ptr<nano::block> const &> rolled_back;
private:
// Roll back block in the ledger that conflicts with 'block'

View file

@ -1,6 +1,8 @@
#pragma once
#include <nano/lib/blocks.hpp>
#include <nano/lib/block_type.hpp>
#include <boost/system/error_code.hpp>
#include <memory>
#include <vector>

View file

@ -1,3 +1,4 @@
#include <nano/lib/blocks.hpp>
#include <nano/node/bootstrap/bootstrap.hpp>
#include <nano/node/bootstrap/bootstrap_attempt.hpp>
#include <nano/node/bootstrap/bootstrap_bulk_push.hpp>

View file

@ -1,3 +1,4 @@
#include <nano/lib/blocks.hpp>
#include <nano/node/bootstrap/block_deserializer.hpp>
#include <nano/node/bootstrap/bootstrap.hpp>
#include <nano/node/bootstrap/bootstrap_bulk_pull.hpp>
@ -363,14 +364,14 @@ void nano::bulk_pull_server::set_current_end ()
include_start = false;
debug_assert (request != nullptr);
auto transaction (node->store.tx_begin_read ());
if (!node->store.block.exists (transaction, request->end))
if (!node->ledger.block_exists (transaction, request->end))
{
node->logger.debug (nano::log::type::bulk_pull_server, "Bulk pull end block doesn't exist: {}, sending everything", request->end.to_string ());
request->end.clear ();
}
if (node->store.block.exists (transaction, request->start.as_block_hash ()))
if (node->ledger.block_exists (transaction, request->start.as_block_hash ()))
{
node->logger.debug (nano::log::type::bulk_pull_server, "Bulk pull request for block hash: {}", request->start.to_string ());

View file

@ -1,3 +1,4 @@
#include <nano/lib/blocks.hpp>
#include <nano/node/bootstrap/bootstrap_attempt.hpp>
#include <nano/node/bootstrap/bootstrap_bulk_push.hpp>
#include <nano/node/bootstrap/bootstrap_legacy.hpp>

View file

@ -1,7 +1,10 @@
#pragma once
#include <nano/lib/numbers.hpp>
#include <deque>
#include <future>
#include <memory>
namespace nano
{

View file

@ -1,3 +1,4 @@
#include <nano/lib/blocks.hpp>
#include <nano/node/bootstrap/bootstrap.hpp>
#include <nano/node/bootstrap/bootstrap_lazy.hpp>
#include <nano/node/common.hpp>
@ -346,11 +347,10 @@ void nano::bootstrap_attempt_lazy::lazy_block_state (std::shared_ptr<nano::block
// In other cases previous block balance required to find out subtype of state block
else if (node->ledger.block_or_pruned_exists (transaction, previous))
{
bool error_or_pruned (false);
auto previous_balance (node->ledger.balance_safe (transaction, previous, error_or_pruned));
if (!error_or_pruned)
auto previous_balance = node->ledger.balance (transaction, previous);
if (previous_balance)
{
if (previous_balance <= balance)
if (previous_balance.value () <= balance)
{
lazy_add (link, retry_limit);
}
@ -423,11 +423,10 @@ void nano::bootstrap_attempt_lazy::lazy_backlog_cleanup ()
if (node->ledger.block_or_pruned_exists (transaction, it->first))
{
auto next_block (it->second);
bool error_or_pruned (false);
auto balance (node->ledger.balance_safe (transaction, it->first, error_or_pruned));
if (!error_or_pruned)
auto balance = node->ledger.balance (transaction, it->first);
if (balance)
{
if (balance <= next_block.balance) // balance
if (balance.value () <= next_block.balance) // balance
{
lazy_add (next_block.link, next_block.retry_limit); // link
}

View file

@ -1,3 +1,4 @@
#include <nano/lib/blocks.hpp>
#include <nano/lib/utility.hpp>
#include <nano/node/bootstrap/bootstrap_server.hpp>
#include <nano/node/transport/channel.hpp>
@ -192,7 +193,7 @@ nano::asc_pull_ack nano::bootstrap_server::process (store::transaction const & t
{
case asc_pull_req::hash_type::block:
{
if (store.block.exists (transaction, request.start.as_block_hash ()))
if (ledger.block_exists (transaction, request.start.as_block_hash ()))
{
return prepare_response (transaction, id, request.start.as_block_hash (), count);
}
@ -253,13 +254,13 @@ std::vector<std::shared_ptr<nano::block>> nano::bootstrap_server::prepare_blocks
std::vector<std::shared_ptr<nano::block>> result;
if (!start_block.is_zero ())
{
std::shared_ptr<nano::block> current = store.block.get (transaction, start_block);
std::shared_ptr<nano::block> current = ledger.block (transaction, start_block);
while (current && result.size () < count)
{
result.push_back (current);
auto successor = current->sideband ().successor;
current = store.block.get (transaction, successor);
current = ledger.block (transaction, successor);
}
}
return result;
@ -286,7 +287,7 @@ nano::asc_pull_ack nano::bootstrap_server::process (const store::transaction & t
case asc_pull_req::hash_type::block:
{
// Try to lookup account assuming target is block hash
target = ledger.account_safe (transaction, request.target.as_block_hash ());
target = ledger.account (transaction, request.target.as_block_hash ()).value_or (0);
}
break;
}
@ -337,4 +338,4 @@ nano::asc_pull_ack nano::bootstrap_server::process (const store::transaction & t
response.payload = response_payload;
response.update_header ();
return response;
}
}

View file

@ -1,3 +1,4 @@
#include <nano/lib/blocks.hpp>
#include <nano/lib/stats_enums.hpp>
#include <nano/node/blockprocessor.hpp>
#include <nano/node/bootstrap_ascending/service.hpp>
@ -132,7 +133,7 @@ void nano::bootstrap_ascending::service::inspect (store::transaction const & tx,
{
case nano::block_status::progress:
{
const auto account = ledger.account (tx, hash);
const auto account = ledger.account (block);
const auto is_send = ledger.is_send (tx, block);
// If we've inserted any block in to an account, unmark it as blocked
@ -166,7 +167,7 @@ void nano::bootstrap_ascending::service::inspect (store::transaction const & tx,
break;
case nano::block_status::gap_source:
{
const auto account = block.previous ().is_zero () ? block.account () : ledger.account (tx, block.previous ());
const auto account = block.previous ().is_zero () ? block.account () : ledger.account (tx, block.previous ()).value ();
const auto source = block.source ().is_zero () ? block.link ().as_block_hash () : block.source ();
// Mark account as blocked because it is missing the source block

View file

@ -1,3 +1,4 @@
#include <nano/lib/blocks.hpp>
#include <nano/lib/cli.hpp>
#include <nano/lib/tlsconfig.hpp>
#include <nano/lib/tomlconfig.hpp>

View file

@ -1,3 +1,4 @@
#include <nano/lib/blocks.hpp>
#include <nano/lib/stats.hpp>
#include <nano/node/confirmation_height_bounded.hpp>
#include <nano/node/write_database_queue.hpp>
@ -83,7 +84,7 @@ void nano::confirmation_height_bounded::process (std::shared_ptr<nano::block> or
}
else
{
block = ledger.store.block.get (transaction, current);
block = ledger.block (transaction, current);
}
if (!block)
@ -227,7 +228,7 @@ nano::block_hash nano::confirmation_height_bounded::get_least_unconfirmed_hash_f
{
if (block_height_a > confirmation_height_info_a.height)
{
auto block (ledger.store.block.get (transaction_a, confirmation_height_info_a.frontier));
auto block = ledger.block (transaction_a, confirmation_height_info_a.frontier);
release_assert (block != nullptr);
least_unconfirmed_hash = block->sideband ().successor;
block_height_a = block->sideband ().height + 1;
@ -255,14 +256,14 @@ bool nano::confirmation_height_bounded::iterate (store::read_transaction const &
// Keep iterating upwards until we either reach the desired block or the second receive.
// Once a receive is cemented, we can cement all blocks above it until the next receive, so store those details for later.
++num_blocks;
auto block = ledger.store.block.get (transaction_a, hash);
auto block = ledger.block (transaction_a, hash);
auto source (block->source ());
if (source.is_zero ())
{
source = block->link ().as_block_hash ();
}
if (!source.is_zero () && !ledger.is_epoch_link (source) && ledger.store.block.exists (transaction_a, source))
if (!source.is_zero () && !ledger.is_epoch_link (source) && ledger.block_exists (transaction_a, source))
{
hit_receive = true;
reached_target = true;
@ -384,7 +385,7 @@ void nano::confirmation_height_bounded::cement_blocks (nano::write_guard & scope
// Extra debug checks
nano::confirmation_height_info confirmation_height_info;
ledger.store.confirmation_height.get (transaction, account, confirmation_height_info);
auto block (ledger.store.block.get (transaction, confirmed_frontier));
auto block = ledger.block (transaction, confirmed_frontier);
debug_assert (block != nullptr);
debug_assert (block->sideband ().height == confirmation_height_info.height + num_blocks_cemented);
#endif
@ -414,14 +415,14 @@ void nano::confirmation_height_bounded::cement_blocks (nano::write_guard & scope
}
else
{
auto block = ledger.store.block.get (transaction, confirmation_height_info.frontier);
auto block = ledger.block (transaction, confirmation_height_info.frontier);
new_cemented_frontier = block->sideband ().successor;
num_blocks_confirmed = pending.top_height - confirmation_height_info.height;
start_height = confirmation_height_info.height + 1;
}
auto total_blocks_cemented = 0;
auto block = ledger.store.block.get (transaction, new_cemented_frontier);
auto block = ledger.block (transaction, new_cemented_frontier);
// Cementing starts from the bottom of the chain and works upwards. This is because chains can have effectively
// an infinite number of send/change blocks in a row. We don't want to hold the write transaction open for too long.
@ -480,7 +481,7 @@ void nano::confirmation_height_bounded::cement_blocks (nano::write_guard & scope
if (!last_iteration)
{
new_cemented_frontier = block->sideband ().successor;
block = ledger.store.block.get (transaction, new_cemented_frontier);
block = ledger.block (transaction, new_cemented_frontier);
}
else
{

View file

@ -1,3 +1,4 @@
#include <nano/lib/blocks.hpp>
#include <nano/lib/numbers.hpp>
#include <nano/lib/thread_roles.hpp>
#include <nano/lib/utility.hpp>
@ -239,3 +240,8 @@ nano::block_hash nano::confirmation_height_processor::current () const
nano::lock_guard<nano::mutex> lk (mutex);
return original_block ? original_block->hash () : 0;
}
std::reference_wrapper<nano::block_hash const> nano::confirmation_height_processor::block_wrapper::hash () const
{
return block->hash ();
}

View file

@ -65,10 +65,7 @@ private:
{
}
std::reference_wrapper<nano::block_hash const> hash () const
{
return block->hash ();
}
std::reference_wrapper<nano::block_hash const> hash () const;
std::shared_ptr<nano::block> block;
};

View file

@ -1,3 +1,4 @@
#include <nano/lib/blocks.hpp>
#include <nano/lib/stats.hpp>
#include <nano/node/confirmation_height_unbounded.hpp>
#include <nano/node/write_database_queue.hpp>
@ -221,7 +222,7 @@ void nano::confirmation_height_unbounded::collect_unconfirmed_receive_and_source
source = block->link ().as_block_hash ();
}
if (!source.is_zero () && !ledger.is_epoch_link (source) && ledger.store.block.exists (transaction_a, source))
if (!source.is_zero () && !ledger.is_epoch_link (source) && ledger.block_exists (transaction_a, source))
{
if (!hit_receive && !block_callback_data_a.empty ())
{
@ -376,7 +377,7 @@ void nano::confirmation_height_unbounded::cement_blocks (nano::write_guard & sco
auto confirmation_height = confirmation_height_info.height;
if (pending.height > confirmation_height)
{
auto block = ledger.store.block.get (transaction, pending.hash);
auto block = ledger.block (transaction, pending.hash);
debug_assert (ledger.pruning || block != nullptr);
debug_assert (ledger.pruning || block->sideband ().height == pending.height);
@ -438,7 +439,7 @@ std::shared_ptr<nano::block> nano::confirmation_height_unbounded::get_block_and_
}
else
{
auto block (ledger.store.block.get (transaction_a, hash_a));
auto block = ledger.block (transaction_a, hash_a);
block_cache.emplace (hash_a, block);
return block;
}

View file

@ -1,3 +1,4 @@
#include <nano/lib/blocks.hpp>
#include <nano/node/confirmation_solicitor.hpp>
#include <nano/node/election.hpp>
#include <nano/node/nodeconfig.hpp>

View file

@ -1,3 +1,4 @@
#include <nano/lib/blocks.hpp>
#include <nano/node/confirmation_solicitor.hpp>
#include <nano/node/election.hpp>
#include <nano/node/network.hpp>
@ -801,4 +802,4 @@ void nano::election_extended_status::operator() (nano::object_stream & obs) cons
obs.write ("hash", block->hash ().to_string ());
obs.write ("amount", amount);
});
}
}

View file

@ -1,3 +1,4 @@
#include <nano/lib/blocks.hpp>
#include <nano/lib/threading.hpp>
#include <nano/node/epoch_upgrader.hpp>
#include <nano/node/node.hpp>

View file

@ -36,7 +36,7 @@ public:
server (server_a), node (server_a.node), session_id (server_a.id_dispenser.fetch_add (1)),
io_ctx (io_ctx_a), strand (io_ctx_a.get_executor ()), socket (io_ctx_a), config_transport (config_transport_a)
{
node.logger.debug (nano::log::type::ipc, "Creating session with id: ", session_id.load ());
node.logger.debug (nano::log::type::ipc, "Creating session with id: {}", session_id.load ());
}
~session ()

View file

@ -1,3 +1,4 @@
#include <nano/lib/blocks.hpp>
#include <nano/lib/config.hpp>
#include <nano/lib/json_error_response.hpp>
#include <nano/lib/timer.hpp>
@ -397,7 +398,7 @@ uint64_t nano::json_handler::difficulty_ledger (nano::block const & block_a)
auto previous (block_a.previous ());
if (!previous.is_zero ())
{
block_previous = node.store.block.get (transaction, previous);
block_previous = node.ledger.block (transaction, previous);
}
// Send check
if (block_previous != nullptr)
@ -413,7 +414,7 @@ uint64_t nano::json_handler::difficulty_ledger (nano::block const & block_a)
auto link (block_a.link ());
if (!link.is_zero () && !details.is_send)
{
auto block_link (node.store.block.get (transaction, link.as_block_hash ()));
auto block_link = node.ledger.block (transaction, link.as_block_hash ());
if (block_link != nullptr && node.store.pending.exists (transaction, nano::pending_key (block_a.account (), link.as_block_hash ())))
{
details.epoch = std::max (details.epoch, block_link->sideband ().details.epoch);
@ -641,7 +642,7 @@ void nano::json_handler::account_info ()
{
if (info.block_count != confirmation_height_info.height)
{
confirmed_balance_l = node.ledger.balance (transaction, confirmation_height_info.frontier);
confirmed_balance_l = node.ledger.balance (transaction, confirmation_height_info.frontier).value_or (0);
}
else
{
@ -672,7 +673,7 @@ void nano::json_handler::account_info ()
std::shared_ptr<nano::block> confirmed_frontier_block;
if (include_confirmed && confirmation_height_info.height > 0)
{
confirmed_frontier_block = node.store.block.get (transaction, confirmation_height_info.frontier);
confirmed_frontier_block = node.ledger.block (transaction, confirmation_height_info.frontier);
}
if (representative)
@ -686,7 +687,7 @@ void nano::json_handler::account_info ()
confirmed_representative = confirmed_frontier_block->representative ();
if (confirmed_representative.is_zero ())
{
confirmed_representative = node.store.block.get (transaction, node.ledger.representative (transaction, confirmation_height_info.frontier))->representative ();
confirmed_representative = node.ledger.block (transaction, node.ledger.representative (transaction, confirmation_height_info.frontier))->representative ();
}
}
@ -1145,18 +1146,17 @@ void nano::json_handler::block_info ()
if (!ec)
{
auto transaction (node.store.tx_begin_read ());
auto block (node.store.block.get (transaction, hash));
auto block = node.ledger.block (transaction, hash);
if (block != nullptr)
{
nano::account account (block->account ().is_zero () ? block->sideband ().account : block->account ());
response_l.put ("block_account", account.to_account ());
bool error_or_pruned (false);
auto amount (node.ledger.amount_safe (transaction, hash, error_or_pruned));
if (!error_or_pruned)
auto amount = node.ledger.amount (transaction, hash);
if (amount)
{
response_l.put ("amount", amount.convert_to<std::string> ());
response_l.put ("amount", amount.value ().convert_to<std::string> ());
}
auto balance (node.ledger.balance (transaction, hash));
auto balance = node.ledger.balance (*block);
response_l.put ("balance", balance.convert_to<std::string> ());
response_l.put ("height", std::to_string (block->sideband ().height));
response_l.put ("local_timestamp", std::to_string (block->sideband ().timestamp));
@ -1197,7 +1197,7 @@ void nano::json_handler::block_confirm ()
if (!ec)
{
auto transaction (node.store.tx_begin_read ());
auto block_l (node.store.block.get (transaction, hash));
auto block_l = node.ledger.block (transaction, hash);
if (block_l != nullptr)
{
if (!node.ledger.block_confirmed (transaction, hash))
@ -1214,20 +1214,19 @@ void nano::json_handler::block_confirm ()
nano::election_status status{ block_l, 0, 0, std::chrono::duration_cast<std::chrono::milliseconds> (std::chrono::system_clock::now ().time_since_epoch ()), std::chrono::duration_values<std::chrono::milliseconds>::zero (), 0, 1, 0, nano::election_status_type::active_confirmation_height };
node.active.recently_cemented.put (status);
// Trigger callback for confirmed block
auto account (node.ledger.account (transaction, hash));
bool error_or_pruned (false);
auto amount (node.ledger.amount_safe (transaction, hash, error_or_pruned));
auto account = node.ledger.account (*block_l);
auto amount = node.ledger.amount (transaction, hash);
bool is_state_send (false);
bool is_state_epoch (false);
if (!error_or_pruned)
if (amount)
{
if (auto state = dynamic_cast<nano::state_block *> (block_l.get ()))
{
is_state_send = node.ledger.is_send (transaction, *state);
is_state_epoch = amount == 0 && node.ledger.is_epoch_link (state->link ());
is_state_epoch = amount.value () == 0 && node.ledger.is_epoch_link (state->link ());
}
}
node.observers.blocks.notify (status, {}, account, amount, is_state_send, is_state_epoch);
node.observers.blocks.notify (status, {}, account, amount ? amount.value () : 0, is_state_send, is_state_epoch);
}
response_l.put ("started", "1");
}
@ -1252,7 +1251,7 @@ void nano::json_handler::blocks ()
nano::block_hash hash;
if (!hash.decode_hex (hash_text))
{
auto block (node.store.block.get (transaction, hash));
auto block = node.ledger.block (transaction, hash);
if (block != nullptr)
{
if (json_block_l)
@ -1303,19 +1302,18 @@ void nano::json_handler::blocks_info ()
nano::block_hash hash;
if (!hash.decode_hex (hash_text))
{
auto block (node.store.block.get (transaction, hash));
auto block = node.ledger.block (transaction, hash);
if (block != nullptr)
{
boost::property_tree::ptree entry;
nano::account account (block->account ().is_zero () ? block->sideband ().account : block->account ());
entry.put ("block_account", account.to_account ());
bool error_or_pruned (false);
auto amount (node.ledger.amount_safe (transaction, hash, error_or_pruned));
if (!error_or_pruned)
auto amount = node.ledger.amount (transaction, hash);
if (amount)
{
entry.put ("amount", amount.convert_to<std::string> ());
entry.put ("amount", amount.value ().convert_to<std::string> ());
}
auto balance (node.ledger.balance (transaction, hash));
auto balance = node.ledger.balance (*block);
entry.put ("balance", balance.convert_to<std::string> ());
entry.put ("height", std::to_string (block->sideband ().height));
entry.put ("local_timestamp", std::to_string (block->sideband ().timestamp));
@ -1385,10 +1383,10 @@ void nano::json_handler::blocks_info ()
if (source)
{
nano::block_hash source_hash (node.ledger.block_source (transaction, *block));
auto block_a (node.store.block.get (transaction, source_hash));
auto block_a = node.ledger.block (transaction, source_hash);
if (block_a != nullptr)
{
auto source_account (node.ledger.account (transaction, source_hash));
auto source_account (node.ledger.account (*block_a));
entry.put ("source_account", source_account.to_account ());
}
else
@ -1432,10 +1430,10 @@ void nano::json_handler::block_account ()
if (!ec)
{
auto transaction (node.store.tx_begin_read ());
if (node.store.block.exists (transaction, hash))
auto block = node.ledger.block (transaction, hash);
if (block)
{
auto account (node.ledger.account (transaction, hash));
response_l.put ("account", account.to_account ());
response_l.put ("account", node.ledger.account (*block).to_account ());
}
else
{
@ -1652,7 +1650,7 @@ void nano::json_handler::block_create ()
else if (previous_text.is_initialized () && balance_text.is_initialized () && type == "send")
{
auto transaction (node.store.tx_begin_read ());
if (node.store.block.exists (transaction, previous) && node.ledger.balance (transaction, previous) != balance.number ())
if (node.ledger.block_exists (transaction, previous) && node.ledger.balance (transaction, previous) != balance.number ())
{
ec = nano::error_rpc::block_create_balance_mismatch;
}
@ -1945,7 +1943,7 @@ void nano::json_handler::chain (bool successors)
auto transaction (node.store.tx_begin_read ());
while (!hash.is_zero () && blocks.size () < count)
{
auto block_l (node.store.block.get (transaction, hash));
auto block_l = node.ledger.block (transaction, hash);
if (block_l != nullptr)
{
if (offset > 0)
@ -2395,11 +2393,10 @@ public:
tree.put ("type", "send");
auto account (block_a.hashables.destination.to_account ());
tree.put ("account", account);
bool error_or_pruned (false);
auto amount (handler.node.ledger.amount_safe (transaction, hash, error_or_pruned).convert_to<std::string> ());
if (!error_or_pruned)
auto amount = handler.node.ledger.amount (transaction, hash);
if (amount)
{
tree.put ("amount", amount);
tree.put ("amount", amount.value ().convert_to<std::string> ());
}
if (raw)
{
@ -2411,16 +2408,15 @@ public:
void receive_block (nano::receive_block const & block_a)
{
tree.put ("type", "receive");
bool error_or_pruned (false);
auto amount (handler.node.ledger.amount_safe (transaction, hash, error_or_pruned).convert_to<std::string> ());
if (!error_or_pruned)
auto amount = handler.node.ledger.amount (transaction, hash);
if (amount)
{
auto source_account (handler.node.ledger.account_safe (transaction, block_a.hashables.source, error_or_pruned));
if (!error_or_pruned)
auto source_account = handler.node.ledger.account (transaction, block_a.hashables.source);
if (source_account)
{
tree.put ("account", source_account.to_account ());
tree.put ("account", source_account.value ().to_account ());
}
tree.put ("amount", amount);
tree.put ("amount", amount.value ().convert_to<std::string> ());
}
if (raw)
{
@ -2445,15 +2441,15 @@ public:
if (block_a.hashables.source != handler.node.ledger.constants.genesis->account ())
{
bool error_or_pruned (false);
auto amount (handler.node.ledger.amount_safe (transaction, hash, error_or_pruned).convert_to<std::string> ());
if (!error_or_pruned)
auto amount = handler.node.ledger.amount (transaction, hash);
if (amount)
{
auto source_account (handler.node.ledger.account_safe (transaction, block_a.hashables.source, error_or_pruned));
if (!error_or_pruned)
auto source_account = handler.node.ledger.account (transaction, block_a.hashables.source);
if (source_account)
{
tree.put ("account", source_account.to_account ());
tree.put ("account", source_account.value ().to_account ());
}
tree.put ("amount", amount);
tree.put ("amount", amount.value ().convert_to<std::string> ());
}
}
else
@ -2482,9 +2478,8 @@ public:
tree.put ("previous", block_a.hashables.previous.to_string ());
}
auto balance (block_a.hashables.balance.number ());
bool error_or_pruned (false);
auto previous_balance (handler.node.ledger.balance_safe (transaction, block_a.hashables.previous, error_or_pruned));
if (error_or_pruned)
auto previous_balance = handler.node.ledger.balance (transaction, block_a.hashables.previous);
if (!previous_balance)
{
if (raw)
{
@ -2495,7 +2490,7 @@ public:
tree.put ("type", "unknown");
}
}
else if (balance < previous_balance)
else if (balance < previous_balance.value ())
{
if (should_ignore_account (block_a.hashables.link.as_account ()))
{
@ -2511,7 +2506,7 @@ public:
tree.put ("type", "send");
}
tree.put ("account", block_a.hashables.link.to_account ());
tree.put ("amount", (previous_balance - balance).convert_to<std::string> ());
tree.put ("amount", (previous_balance.value () - balance).convert_to<std::string> ());
}
else
{
@ -2532,8 +2527,8 @@ public:
}
else
{
auto source_account (handler.node.ledger.account_safe (transaction, block_a.hashables.link.as_block_hash (), error_or_pruned));
if (!error_or_pruned && should_ignore_account (source_account))
auto source_account = handler.node.ledger.account (transaction, block_a.hashables.link.as_block_hash ());
if (source_account && should_ignore_account (source_account.value ()))
{
tree.clear ();
return;
@ -2546,11 +2541,11 @@ public:
{
tree.put ("type", "receive");
}
if (!error_or_pruned)
if (source_account)
{
tree.put ("account", source_account.to_account ());
tree.put ("account", source_account.value ().to_account ());
}
tree.put ("amount", (balance - previous_balance).convert_to<std::string> ());
tree.put ("amount", (balance - previous_balance.value ()).convert_to<std::string> ());
}
}
}
@ -2605,9 +2600,9 @@ void nano::json_handler::account_history ()
{
if (!hash.decode_hex (*head_str))
{
if (node.store.block.exists (transaction, hash))
if (node.ledger.block_exists (transaction, hash))
{
account = node.ledger.account (transaction, hash);
account = node.ledger.account (transaction, hash).value ();
}
else
{
@ -2643,7 +2638,7 @@ void nano::json_handler::account_history ()
boost::property_tree::ptree history;
bool output_raw (request.get_optional<bool> ("raw") == true);
response_l.put ("account", account.to_account ());
auto block (node.store.block.get (transaction, hash));
auto block = node.ledger.block (transaction, hash);
while (block != nullptr && count > 0)
{
if (offset > 0)
@ -2671,7 +2666,7 @@ void nano::json_handler::account_history ()
}
}
hash = reverse ? node.store.block.successor (transaction, hash) : block->previous ();
block = node.store.block.get (transaction, hash);
block = node.ledger.block (transaction, hash);
}
response_l.add_child ("history", history);
if (!hash.is_zero ())
@ -2922,7 +2917,6 @@ void nano::json_handler::node_id ()
{
if (!ec)
{
response_l.put ("private", node.node_id.prv.to_string ());
response_l.put ("public", node.node_id.pub.to_string ());
response_l.put ("as_account", node.node_id.pub.to_account ());
response_l.put ("node_id", node.node_id.pub.to_node_id ());
@ -3164,7 +3158,7 @@ void nano::json_handler::receivable_exists ()
if (!ec)
{
auto transaction (node.store.tx_begin_read ());
auto block (node.store.block.get (transaction, hash));
auto block = node.ledger.block (transaction, hash);
if (block != nullptr)
{
auto exists (false);
@ -3198,7 +3192,7 @@ void nano::json_handler::process ()
{
std::shared_ptr<nano::state_block> block_state (std::static_pointer_cast<nano::state_block> (block));
auto transaction (rpc_l->node.store.tx_begin_read ());
if (!block_state->hashables.previous.is_zero () && !rpc_l->node.store.block.exists (transaction, block_state->hashables.previous))
if (!block_state->hashables.previous.is_zero () && !rpc_l->node.ledger.block_exists (transaction, block_state->hashables.previous))
{
rpc_l->ec = nano::error_process::gap_previous;
}
@ -3638,28 +3632,28 @@ void nano::json_handler::republish ()
{
boost::property_tree::ptree blocks;
auto transaction (node.store.tx_begin_read ());
auto block (node.store.block.get (transaction, hash));
auto block = node.ledger.block (transaction, hash);
if (block != nullptr)
{
std::deque<std::shared_ptr<nano::block>> republish_bundle;
for (auto i (0); !hash.is_zero () && i < count; ++i)
{
block = node.store.block.get (transaction, hash);
block = node.ledger.block (transaction, hash);
if (sources != 0) // Republish source chain
{
nano::block_hash source (node.ledger.block_source (transaction, *block));
auto block_a (node.store.block.get (transaction, source));
auto block_a = node.ledger.block (transaction, source);
std::vector<nano::block_hash> hashes;
while (block_a != nullptr && hashes.size () < sources)
{
hashes.push_back (source);
source = block_a->previous ();
block_a = node.store.block.get (transaction, source);
block_a = node.ledger.block (transaction, source);
}
std::reverse (hashes.begin (), hashes.end ());
for (auto & hash_l : hashes)
{
block_a = node.store.block.get (transaction, hash_l);
block_a = node.ledger.block (transaction, hash_l);
republish_bundle.push_back (std::move (block_a));
boost::property_tree::ptree entry_l;
entry_l.put ("", hash_l.to_string ());
@ -3672,14 +3666,14 @@ void nano::json_handler::republish ()
blocks.push_back (std::make_pair ("", entry));
if (destinations != 0) // Republish destination chain
{
auto block_b (node.store.block.get (transaction, hash));
auto block_b = node.ledger.block (transaction, hash);
auto destination (node.ledger.block_destination (transaction, *block_b));
if (!destination.is_zero ())
{
if (!node.store.pending.exists (transaction, nano::pending_key (destination, hash)))
{
nano::block_hash previous (node.ledger.latest (transaction, destination));
auto block_d (node.store.block.get (transaction, previous));
auto block_d = node.ledger.block (transaction, previous);
nano::block_hash source;
std::vector<nano::block_hash> hashes;
while (block_d != nullptr && hash != source)
@ -3687,7 +3681,7 @@ void nano::json_handler::republish ()
hashes.push_back (previous);
source = node.ledger.block_source (transaction, *block_d);
previous = block_d->previous ();
block_d = node.store.block.get (transaction, previous);
block_d = node.ledger.block (transaction, previous);
}
std::reverse (hashes.begin (), hashes.end ());
if (hashes.size () > destinations)
@ -3696,7 +3690,7 @@ void nano::json_handler::republish ()
}
for (auto & hash_l : hashes)
{
block_d = node.store.block.get (transaction, hash_l);
block_d = node.ledger.block (transaction, hash_l);
republish_bundle.push_back (std::move (block_d));
boost::property_tree::ptree entry_l;
entry_l.put ("", hash_l.to_string ());
@ -4658,7 +4652,7 @@ void nano::json_handler::wallet_history ()
auto hash (info->head);
while (timestamp >= modified_since && !hash.is_zero ())
{
auto block (node.store.block.get (block_transaction, hash));
auto block = node.ledger.block (block_transaction, hash);
timestamp = block->sideband ().timestamp;
if (block != nullptr && timestamp >= modified_since)
{
@ -4932,7 +4926,7 @@ void nano::json_handler::wallet_republish ()
while (!latest.is_zero () && hashes.size () < count)
{
hashes.push_back (latest);
block = node.store.block.get (block_transaction, latest);
block = node.ledger.block (block_transaction, latest);
if (block != nullptr)
{
latest = block->previous ();
@ -4945,7 +4939,7 @@ void nano::json_handler::wallet_republish ()
std::reverse (hashes.begin (), hashes.end ());
for (auto & hash : hashes)
{
block = node.store.block.get (block_transaction, hash);
block = node.ledger.block (block_transaction, hash);
republish_bundle.push_back (std::move (block));
boost::property_tree::ptree entry;
entry.put ("", hash.to_string ());
@ -5093,9 +5087,9 @@ void nano::json_handler::work_generate ()
{
// Fetch account from block if not given
auto transaction_l (node.store.tx_begin_read ());
if (node.store.block.exists (transaction_l, hash))
if (node.ledger.block_exists (transaction_l, hash))
{
account = node.ledger.account (transaction_l, hash);
account = node.ledger.account (transaction_l, hash).value ();
}
}
auto secondary_work_peers_l (request.get<bool> ("secondary_work_peers", false));
@ -5463,7 +5457,7 @@ bool block_confirmed (nano::node & node, nano::store::transaction & transaction,
// This just checks it's not currently undergoing an active transaction
else if (!include_only_confirmed)
{
auto block (node.store.block.get (transaction, hash));
auto block = node.ledger.block (transaction, hash);
is_confirmed = (block != nullptr && !node.active.active (*block));
}

View file

@ -0,0 +1,176 @@
#include <nano/lib/blocks.hpp>
#include <nano/lib/threading.hpp>
#include <nano/lib/utility.hpp>
#include <nano/node/blockprocessor.hpp>
#include <nano/node/local_block_broadcaster.hpp>
#include <nano/node/network.hpp>
#include <nano/node/node.hpp>
nano::local_block_broadcaster::local_block_broadcaster (nano::node & node_a, nano::block_processor & block_processor_a, nano::network & network_a, nano::stats & stats_a, bool enabled_a) :
node{ node_a },
block_processor{ block_processor_a },
network{ network_a },
stats{ stats_a },
enabled{ enabled_a }
{
if (!enabled)
{
return;
}
block_processor.batch_processed.add ([this] (auto const & batch) {
bool should_notify = false;
for (auto const & [result, context] : batch)
{
// Only rebroadcast local blocks that were successfully processed (no forks or gaps)
if (result == nano::block_status::progress && context.source == nano::block_source::local)
{
nano::lock_guard<nano::mutex> guard{ mutex };
local_blocks.emplace_back (local_entry{ context.block, std::chrono::steady_clock::now () });
stats.inc (nano::stat::type::local_block_broadcaster, nano::stat::detail::insert);
should_notify = true;
}
}
if (should_notify)
{
condition.notify_all ();
}
});
block_processor.rolled_back.add ([this] (auto const & block) {
nano::lock_guard<nano::mutex> guard{ mutex };
auto erased = local_blocks.get<tag_hash> ().erase (block->hash ());
stats.add (nano::stat::type::local_block_broadcaster, nano::stat::detail::rollback, nano::stat::dir::in, erased);
});
}
nano::local_block_broadcaster::~local_block_broadcaster ()
{
// Thread must be stopped before destruction
debug_assert (!thread.joinable ());
}
void nano::local_block_broadcaster::start ()
{
if (!enabled)
{
return;
}
debug_assert (!thread.joinable ());
thread = std::thread{ [this] () {
nano::thread_role::set (nano::thread_role::name::local_block_broadcasting);
run ();
} };
}
void nano::local_block_broadcaster::stop ()
{
{
nano::lock_guard<nano::mutex> lock{ mutex };
stopped = true;
}
condition.notify_all ();
nano::join_or_pass (thread);
}
void nano::local_block_broadcaster::run ()
{
nano::unique_lock<nano::mutex> lock{ mutex };
while (!stopped)
{
stats.inc (nano::stat::type::local_block_broadcaster, nano::stat::detail::loop);
condition.wait_for (lock, check_interval);
debug_assert ((std::this_thread::yield (), true)); // Introduce some random delay in debug builds
if (!stopped)
{
cleanup ();
run_broadcasts (lock);
debug_assert (lock.owns_lock ());
}
}
}
void nano::local_block_broadcaster::run_broadcasts (nano::unique_lock<nano::mutex> & lock)
{
debug_assert (lock.owns_lock ());
std::vector<std::shared_ptr<nano::block>> to_broadcast;
auto const now = std::chrono::steady_clock::now ();
for (auto & entry : local_blocks)
{
if (elapsed (entry.last_broadcast, broadcast_interval, now))
{
entry.last_broadcast = now;
to_broadcast.push_back (entry.block);
}
}
lock.unlock ();
for (auto const & block : to_broadcast)
{
while (!limiter.should_pass (1))
{
std::this_thread::sleep_for (std::chrono::milliseconds{ 100 });
if (stopped)
{
return;
}
}
stats.inc (nano::stat::type::local_block_broadcaster, nano::stat::detail::broadcast, nano::stat::dir::out);
network.flood_block_initial (block);
}
lock.lock ();
}
void nano::local_block_broadcaster::cleanup ()
{
debug_assert (!mutex.try_lock ());
// Erase oldest blocks if the queue gets too big
while (local_blocks.size () > max_size)
{
stats.inc (nano::stat::type::local_block_broadcaster, nano::stat::detail::erase_oldest);
local_blocks.pop_front ();
}
// TODO: Mutex is held during IO, but it should be fine since it's not performance critical
auto transaction = node.store.tx_begin_read ();
erase_if (local_blocks, [this, &transaction] (auto const & entry) {
transaction.refresh_if_needed ();
if (entry.last_broadcast == std::chrono::steady_clock::time_point{})
{
// This block has never been broadcasted, keep it so it's broadcasted at least once
return false;
}
if (node.block_confirmed_or_being_confirmed (transaction, entry.block->hash ()))
{
stats.inc (nano::stat::type::local_block_broadcaster, nano::stat::detail::erase_confirmed);
return true;
}
return false;
});
}
std::unique_ptr<nano::container_info_component> nano::local_block_broadcaster::collect_container_info (const std::string & name) const
{
nano::lock_guard<nano::mutex> guard{ mutex };
auto composite = std::make_unique<container_info_composite> (name);
composite->add_component (std::make_unique<container_info_leaf> (container_info{ "local", local_blocks.size (), sizeof (decltype (local_blocks)::value_type) }));
return composite;
}
nano::block_hash nano::local_block_broadcaster::local_entry::hash () const
{
return block->hash ();
}

View file

@ -0,0 +1,102 @@
#pragma once
#include <nano/lib/locks.hpp>
#include <nano/lib/processing_queue.hpp>
#include <nano/node/bandwidth_limiter.hpp>
#include <nano/node/blockprocessor.hpp>
#include <nano/secure/common.hpp>
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/mem_fun.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/sequenced_index.hpp>
#include <boost/multi_index_container.hpp>
#include <memory>
#include <thread>
#include <unordered_set>
namespace mi = boost::multi_index;
namespace nano
{
class node;
class network;
}
namespace nano
{
/**
* Broadcasts blocks to the network
* Tracks local blocks for more aggressive propagation
*/
class local_block_broadcaster
{
enum class broadcast_strategy
{
normal,
aggressive,
};
public:
local_block_broadcaster (nano::node &, nano::block_processor &, nano::network &, nano::stats &, bool enabled = false);
~local_block_broadcaster ();
void start ();
void stop ();
std::unique_ptr<container_info_component> collect_container_info (std::string const & name) const;
private:
void run ();
void run_broadcasts (nano::unique_lock<nano::mutex> &);
void cleanup ();
private: // Dependencies
nano::node & node;
nano::block_processor & block_processor;
nano::network & network;
nano::stats & stats;
private:
struct local_entry
{
std::shared_ptr<nano::block> const block;
std::chrono::steady_clock::time_point const arrival;
mutable std::chrono::steady_clock::time_point last_broadcast{}; // Not part of any index
nano::block_hash hash () const;
};
// clang-format off
class tag_sequenced {};
class tag_hash {};
using ordered_locals = boost::multi_index_container<local_entry,
mi::indexed_by<
mi::sequenced<mi::tag<tag_sequenced>>,
mi::hashed_unique<mi::tag<tag_hash>,
mi::const_mem_fun<local_entry, nano::block_hash, &local_entry::hash>>
>>;
// clang-format on
ordered_locals local_blocks;
private:
bool enabled{ false };
nano::bandwidth_limiter limiter{ broadcast_rate_limit, broadcast_rate_burst_ratio };
std::atomic<bool> stopped{ false };
nano::condition_variable condition;
mutable nano::mutex mutex;
std::thread thread;
// TODO: Make these configurable
static std::size_t constexpr max_size{ 1024 * 8 };
static std::chrono::seconds constexpr check_interval{ 30 };
static std::chrono::seconds constexpr broadcast_interval{ 60 };
static std::size_t constexpr broadcast_rate_limit{ 32 };
static double constexpr broadcast_rate_burst_ratio{ 3 };
};
}

View file

@ -1,7 +1,7 @@
#pragma once
#include <nano/lib/asio.hpp>
#include <nano/lib/blocks.hpp>
#include <nano/lib/block_uniquer.hpp>
#include <nano/lib/config.hpp>
#include <nano/lib/errors.hpp>
#include <nano/lib/jsonconfig.hpp>

View file

@ -1,4 +1,5 @@
#include <nano/crypto_lib/random_pool_shuffle.hpp>
#include <nano/lib/blocks.hpp>
#include <nano/lib/threading.hpp>
#include <nano/lib/utility.hpp>
#include <nano/node/bootstrap_ascending/service.hpp>
@ -240,8 +241,6 @@ public:
void keepalive (nano::keepalive const & message_a) override
{
node.network.merge_peers (message_a.peers);
// Check for special node port data
auto peer0 (message_a.peers[0]);
if (peer0.address () == boost::asio::ip::address_v6{} && peer0.port () != 0)

View file

@ -1,3 +1,4 @@
#include <nano/lib/blocks.hpp>
#include <nano/lib/stream.hpp>
#include <nano/lib/tomlconfig.hpp>
#include <nano/lib/utility.hpp>
@ -181,14 +182,13 @@ nano::node::node (boost::asio::io_context & io_ctx_a, std::filesystem::path cons
ascendboot{ config, block_processor, ledger, network, stats },
websocket{ config.websocket_config, observers, wallets, ledger, io_ctx, logger },
epoch_upgrader{ *this, ledger, store, network_params, logger },
local_block_broadcaster{ *this, block_processor, network, stats, !flags.disable_block_processor_republishing },
process_live_dispatcher{ ledger, scheduler.priority, vote_cache, websocket },
startup_time (std::chrono::steady_clock::now ()),
node_seq (seq),
block_broadcast{ network, !flags.disable_block_processor_republishing },
process_live_dispatcher{ ledger, scheduler.priority, vote_cache, websocket }
node_seq (seq)
{
logger.debug (nano::log::type::node, "Constructing node...");
block_broadcast.connect (block_processor);
process_live_dispatcher.connect (block_processor);
unchecked.satisfied.add ([this] (nano::unchecked_info const & info) {
@ -538,6 +538,7 @@ std::unique_ptr<nano::container_info_component> nano::collect_container_info (no
composite->add_component (collect_container_info (node.final_generator, "vote_generator_final"));
composite->add_component (node.ascendboot.collect_container_info ("bootstrap_ascending"));
composite->add_component (node.unchecked.collect_container_info ("unchecked"));
composite->add_component (node.local_block_broadcaster.collect_container_info ("local_block_broadcaster"));
return composite;
}
@ -633,6 +634,7 @@ void nano::node::start ()
port_mapping.start ();
}
wallets.start ();
vote_processor.start ();
active.start ();
generator.start ();
final_generator.start ();
@ -645,6 +647,7 @@ void nano::node::start ()
}
websocket.start ();
telemetry.start ();
local_block_broadcaster.start ();
}
void nano::node::stop ()
@ -686,6 +689,7 @@ void nano::node::stop ()
stats.stop ();
epoch_upgrader.stop ();
workers.stop ();
local_block_broadcaster.stop ();
// work pool is not stopped on purpose due to testing setup
}
@ -714,8 +718,7 @@ nano::uint128_t nano::node::balance (nano::account const & account_a)
std::shared_ptr<nano::block> nano::node::block (nano::block_hash const & hash_a)
{
auto const transaction (store.tx_begin_read ());
return store.block.get (transaction, hash_a);
return ledger.block (store.tx_begin_read (), hash_a);
}
std::pair<nano::uint128_t, nano::uint128_t> nano::node::balance_pending (nano::account const & account_a, bool only_confirmed_a)
@ -908,7 +911,7 @@ bool nano::node::collect_ledger_pruning_targets (std::deque<nano::block_hash> &
uint64_t depth (0);
while (!hash.is_zero () && depth < max_depth_a)
{
auto block (store.block.get (transaction, hash));
auto block = ledger.block (transaction, hash);
if (block != nullptr)
{
if (block->sideband ().timestamp > cutoff_time_a || depth == 0)
@ -1218,14 +1221,13 @@ void nano::node::process_confirmed_data (store::transaction const & transaction_
}
// Faster amount calculation
auto previous (block_a->previous ());
bool error (false);
auto previous_balance (ledger.balance_safe (transaction_a, previous, error));
auto previous_balance = ledger.balance (transaction_a, previous);
auto block_balance = ledger.balance (*block_a);
if (hash_a != ledger.constants.genesis->account ())
{
if (!error)
if (previous_balance)
{
amount_a = block_balance > previous_balance ? block_balance - previous_balance : previous_balance - block_balance;
amount_a = block_balance > previous_balance.value () ? block_balance - previous_balance.value () : previous_balance.value () - block_balance;
}
else
{
@ -1258,7 +1260,7 @@ void nano::node::process_confirmed (nano::election_status const & status_a, uint
{
auto hash (status_a.winner->hash ());
decltype (iteration_a) const num_iters = (config.block_processor_batch_max_time / network_params.node.process_confirmed_interval) * 4;
if (auto block_l = ledger.store.block.get (ledger.store.tx_begin_read (), hash))
if (auto block_l = ledger.block (ledger.store.tx_begin_read (), hash))
{
logger.trace (nano::log::type::node, nano::log::detail::process_confirmed, nano::log::arg{ "block", block_l });

View file

@ -1,5 +1,6 @@
#pragma once
#include <nano/lib/block_uniquer.hpp>
#include <nano/lib/config.hpp>
#include <nano/lib/logging.hpp>
#include <nano/lib/stats.hpp>
@ -8,7 +9,6 @@
#include <nano/node/active_transactions.hpp>
#include <nano/node/backlog_population.hpp>
#include <nano/node/bandwidth_limiter.hpp>
#include <nano/node/block_broadcast.hpp>
#include <nano/node/blockprocessor.hpp>
#include <nano/node/bootstrap/bootstrap.hpp>
#include <nano/node/bootstrap/bootstrap_attempt.hpp>
@ -18,6 +18,7 @@
#include <nano/node/distributed_work_factory.hpp>
#include <nano/node/election.hpp>
#include <nano/node/epoch_upgrader.hpp>
#include <nano/node/local_block_broadcaster.hpp>
#include <nano/node/network.hpp>
#include <nano/node/node_observers.hpp>
#include <nano/node/nodeconfig.hpp>
@ -184,7 +185,7 @@ public:
nano::bootstrap_ascending::service ascendboot;
nano::websocket_server websocket;
nano::epoch_upgrader epoch_upgrader;
nano::block_broadcast block_broadcast;
nano::local_block_broadcaster local_block_broadcaster;
nano::process_live_dispatcher process_live_dispatcher;
std::chrono::steady_clock::time_point const startup_time;

View file

@ -1,4 +1,5 @@
#include <nano/crypto_lib/random_pool.hpp>
#include <nano/lib/blocks.hpp>
#include <nano/lib/config.hpp>
#include <nano/lib/jsonconfig.hpp>
#include <nano/lib/rpcconfig.hpp>
@ -571,4 +572,4 @@ nano::account nano::node_config::random_representative () const
std::size_t index (nano::random_pool::generate_word32 (0, static_cast<CryptoPP::word32> (preconfigured_representatives.size () - 1)));
auto result (preconfigured_representatives[index]);
return result;
}
}

View file

@ -89,7 +89,7 @@ public:
uint16_t external_port{ 0 };
std::chrono::milliseconds block_processor_batch_max_time{ std::chrono::milliseconds (500) };
/** Time to wait for block processing result */
std::chrono::seconds block_process_timeout{ 15 };
std::chrono::seconds block_process_timeout{ 300 };
std::chrono::seconds unchecked_cutoff_time{ std::chrono::seconds (4 * 60 * 60) }; // 4 hours
/** Timeout for initiated async operations */
std::chrono::seconds tcp_io_timeout{ (network_params.network.is_dev_network () && !is_sanitizer_build ()) ? std::chrono::seconds (5) : std::chrono::seconds (15) };

View file

@ -1,3 +1,4 @@
#include <nano/lib/blocks.hpp>
#include <nano/lib/stats.hpp>
#include <nano/node/active_transactions.hpp>
#include <nano/node/common.hpp>
@ -204,12 +205,12 @@ std::pair<std::vector<std::shared_ptr<nano::block>>, std::vector<std::shared_ptr
if (!final_vote_hashes.empty ())
{
generate_final_vote = true;
block = ledger.store.block.get (transaction, final_vote_hashes[0]);
block = ledger.block (transaction, final_vote_hashes[0]);
// Allow same root vote
if (block != nullptr && final_vote_hashes.size () > 1)
{
to_generate_final.push_back (block);
block = ledger.store.block.get (transaction, final_vote_hashes[1]);
block = ledger.block (transaction, final_vote_hashes[1]);
debug_assert (final_vote_hashes.size () == 2);
}
}
@ -223,7 +224,7 @@ std::pair<std::vector<std::shared_ptr<nano::block>>, std::vector<std::shared_ptr
// 4. Ledger by hash
if (block == nullptr)
{
block = ledger.store.block.get (transaction, hash);
block = ledger.block (transaction, hash);
// Confirmation status. Generate final votes for confirmed
if (block != nullptr)
{
@ -250,7 +251,7 @@ std::pair<std::vector<std::shared_ptr<nano::block>>, std::vector<std::shared_ptr
}
if (!successor.is_zero ())
{
auto successor_block = ledger.store.block.get (transaction, successor);
auto successor_block = ledger.block (transaction, successor);
debug_assert (successor_block != nullptr);
block = std::move (successor_block);
// 5. Votes in cache for successor

View file

@ -76,7 +76,7 @@ void nano::scheduler::hinted::activate (const nano::store::read_transaction & tr
stack.pop ();
// Check if block exists
if (auto block = node.store.block.get (transaction, current_hash); block)
if (auto block = node.ledger.block (transaction, current_hash); block)
{
// Ensure block is not already confirmed
if (node.block_confirmed_or_being_confirmed (transaction, current_hash))
@ -283,4 +283,4 @@ nano::error nano::scheduler::hinted_config::deserialize (nano::tomlconfig & toml
}
return toml.get_error ();
}
}

View file

@ -1,3 +1,4 @@
#include <nano/lib/blocks.hpp>
#include <nano/lib/stats.hpp>
#include <nano/lib/tomlconfig.hpp>
#include <nano/node/node.hpp>

View file

@ -1,3 +1,4 @@
#include <nano/lib/blocks.hpp>
#include <nano/node/node.hpp>
#include <nano/node/scheduler/buckets.hpp>
#include <nano/node/scheduler/priority.hpp>
@ -47,12 +48,12 @@ bool nano::scheduler::priority::activate (nano::account const & account_a, store
{
debug_assert (conf_info.frontier != info->head);
auto hash = conf_info.height == 0 ? info->open_block : node.store.block.successor (transaction, conf_info.frontier);
auto block = node.store.block.get (transaction, hash);
auto block = node.ledger.block (transaction, hash);
debug_assert (block != nullptr);
if (node.ledger.dependents_confirmed (transaction, *block))
{
auto const balance = node.ledger.balance (transaction, hash);
auto const previous_balance = node.ledger.balance (transaction, conf_info.frontier);
auto const balance = node.ledger.balance (transaction, hash).value ();
auto const previous_balance = node.ledger.balance (transaction, conf_info.frontier).value_or (0);
auto const balance_priority = std::max (balance, previous_balance);
node.stats.inc (nano::stat::type::election_scheduler, nano::stat::detail::activated);

View file

@ -1,3 +1,4 @@
#include <nano/lib/blocks.hpp>
#include <nano/lib/stats.hpp>
#include <nano/lib/threading.hpp>
#include <nano/node/network.hpp>
@ -439,4 +440,4 @@ nano::telemetry_data nano::consolidate_telemetry_data (std::vector<nano::telemet
consolidated_data.maker = boost::lexical_cast<uint8_t> (version_fragments[4]);
return consolidated_data;
}
}

View file

@ -187,4 +187,4 @@ struct hash<std::reference_wrapper<::nano::transport::channel const>>
return hash (channel_a.get ());
}
};
}
}

View file

@ -357,6 +357,7 @@ void nano::transport::tcp_channels::process_message (nano::message const & messa
void nano::transport::tcp_channels::start ()
{
ongoing_keepalive ();
ongoing_merge (0);
}
void nano::transport::tcp_channels::stop ()
@ -509,6 +510,77 @@ void nano::transport::tcp_channels::ongoing_keepalive ()
});
}
void nano::transport::tcp_channels::ongoing_merge (size_t channel_index)
{
nano::unique_lock<nano::mutex> lock{ mutex };
std::optional<nano::keepalive> keepalive;
size_t count = 0;
while (!keepalive && channels.size () > 0 && count++ < channels.size ())
{
++channel_index;
if (channels.size () <= channel_index)
{
channel_index = 0;
}
auto server = channels.get<random_access_tag> ()[channel_index].response_server;
if (server && server->last_keepalive)
{
keepalive = std::move (server->last_keepalive);
server->last_keepalive = std::nullopt;
}
}
lock.unlock ();
if (keepalive)
{
ongoing_merge (channel_index, *keepalive, 1);
}
else
{
std::weak_ptr<nano::node> node_w = node.shared ();
node.workers.add_timed_task (std::chrono::steady_clock::now () + node.network_params.network.merge_period, [node_w, channel_index] () {
if (auto node_l = node_w.lock ())
{
if (!node_l->network.tcp_channels.stopped)
{
node_l->network.tcp_channels.ongoing_merge (channel_index);
}
}
});
}
}
void nano::transport::tcp_channels::ongoing_merge (size_t channel_index, nano::keepalive keepalive, size_t peer_index)
{
debug_assert (peer_index < keepalive.peers.size ());
node.network.merge_peer (keepalive.peers[peer_index++]);
if (peer_index < keepalive.peers.size ())
{
std::weak_ptr<nano::node> node_w = node.shared ();
node.workers.add_timed_task (std::chrono::steady_clock::now () + node.network_params.network.merge_period, [node_w, channel_index, keepalive, peer_index] () {
if (auto node_l = node_w.lock ())
{
if (!node_l->network.tcp_channels.stopped)
{
node_l->network.tcp_channels.ongoing_merge (channel_index, keepalive, peer_index);
}
}
});
}
else
{
std::weak_ptr<nano::node> node_w = node.shared ();
node.workers.add_timed_task (std::chrono::steady_clock::now () + node.network_params.network.merge_period, [node_w, channel_index] () {
if (auto node_l = node_w.lock ())
{
if (!node_l->network.tcp_channels.stopped)
{
node_l->network.tcp_channels.ongoing_merge (channel_index);
}
}
});
}
}
void nano::transport::tcp_channels::list (std::deque<std::shared_ptr<nano::transport::channel>> & deque_a, uint8_t minimum_version_a, bool include_temporary_channels_a)
{
nano::lock_guard<nano::mutex> lock{ mutex };

View file

@ -128,6 +128,8 @@ namespace transport
std::unique_ptr<container_info_component> collect_container_info (std::string const &);
void purge (std::chrono::steady_clock::time_point const &);
void ongoing_keepalive ();
void ongoing_merge (size_t channel_index);
void ongoing_merge (size_t channel_index, nano::keepalive keepalive, size_t peer_index);
void list (std::deque<std::shared_ptr<nano::transport::channel>> &, uint8_t = 0, bool = true);
void modify (std::shared_ptr<nano::transport::channel_tcp> const &, std::function<void (std::shared_ptr<nano::transport::channel_tcp> const &)>);
void update (nano::tcp_endpoint const &);

View file

@ -623,6 +623,7 @@ nano::transport::tcp_server::realtime_message_visitor::realtime_message_visitor
void nano::transport::tcp_server::realtime_message_visitor::keepalive (const nano::keepalive & message)
{
process = true;
server.set_last_keepalive (message);
}
void nano::transport::tcp_server::realtime_message_visitor::publish (const nano::publish & message)
@ -786,6 +787,15 @@ void nano::transport::tcp_server::timeout ()
}
}
void nano::transport::tcp_server::set_last_keepalive (nano::keepalive const & message)
{
std::lock_guard<nano::mutex> lock{ mutex };
if (!last_keepalive)
{
last_keepalive = message;
}
}
bool nano::transport::tcp_server::to_bootstrap_connection ()
{
auto node = this->node.lock ();

View file

@ -62,6 +62,7 @@ public:
void stop ();
void timeout ();
void set_last_keepalive (nano::keepalive const & message);
std::shared_ptr<nano::transport::socket> const socket;
std::weak_ptr<nano::node> const node;
@ -72,6 +73,7 @@ public:
nano::tcp_endpoint remote_endpoint{ boost::asio::ip::address_v6::any (), 0 };
nano::account remote_node_id{};
std::chrono::steady_clock::time_point last_telemetry_req{};
std::optional<nano::keepalive> last_keepalive;
private:
void send_handshake_response (nano::node_id_handshake::query_payload const & query, bool v2);

View file

@ -1,3 +1,4 @@
#include <nano/lib/blocks.hpp>
#include <nano/lib/locks.hpp>
#include <nano/lib/stats.hpp>
#include <nano/lib/stats_enums.hpp>

View file

@ -1,4 +1,3 @@
#include <nano/lib/stats.hpp>
#include <nano/lib/timer.hpp>
#include <nano/node/active_transactions.hpp>
@ -13,6 +12,7 @@
#include <boost/format.hpp>
#include <chrono>
using namespace std::chrono_literals;
nano::vote_processor::vote_processor (nano::active_transactions & active_a, nano::node_observers & observers_a, nano::stats & stats_a, nano::node_config & config_a, nano::node_flags & flags_a, nano::logger & logger_a, nano::online_reps & online_reps_a, nano::rep_crawler & rep_crawler_a, nano::ledger & ledger_a, nano::network_params & network_params_a) :
@ -25,33 +25,45 @@ nano::vote_processor::vote_processor (nano::active_transactions & active_a, nano
rep_crawler (rep_crawler_a),
ledger (ledger_a),
network_params (network_params_a),
max_votes (flags_a.vote_processor_capacity),
started (false),
stopped (false),
thread ([this] () {
nano::thread_role::set (nano::thread_role::name::vote_processing);
process_loop ();
nano::unique_lock<nano::mutex> lock{ mutex };
votes.clear ();
condition.notify_all ();
})
max_votes (flags_a.vote_processor_capacity)
{
nano::unique_lock<nano::mutex> lock{ mutex };
condition.wait (lock, [&started = started] { return started; });
}
void nano::vote_processor::process_loop ()
nano::vote_processor::~vote_processor ()
{
// Thread must be stopped before destruction
debug_assert (!thread.joinable ());
}
void nano::vote_processor::start ()
{
debug_assert (!thread.joinable ());
thread = std::thread{ [this] () {
nano::thread_role::set (nano::thread_role::name::vote_processing);
run ();
} };
}
void nano::vote_processor::stop ()
{
{
nano::lock_guard<nano::mutex> lock{ mutex };
stopped = true;
}
condition.notify_all ();
if (thread.joinable ())
{
thread.join ();
}
}
void nano::vote_processor::run ()
{
nano::timer<std::chrono::milliseconds> elapsed;
bool log_this_iteration;
nano::unique_lock<nano::mutex> lock{ mutex };
started = true;
lock.unlock ();
condition.notify_all ();
lock.lock ();
while (!stopped)
{
if (!votes.empty ())
@ -181,19 +193,6 @@ nano::vote_code nano::vote_processor::vote_blocking (std::shared_ptr<nano::vote>
return result;
}
void nano::vote_processor::stop ()
{
{
nano::lock_guard<nano::mutex> lock{ mutex };
stopped = true;
}
condition.notify_all ();
if (thread.joinable ())
{
thread.join ();
}
}
void nano::vote_processor::flush ()
{
nano::unique_lock<nano::mutex> lock{ mutex };
@ -208,19 +207,19 @@ void nano::vote_processor::flush ()
}
}
std::size_t nano::vote_processor::size ()
std::size_t nano::vote_processor::size () const
{
nano::lock_guard<nano::mutex> guard{ mutex };
return votes.size ();
}
bool nano::vote_processor::empty ()
bool nano::vote_processor::empty () const
{
nano::lock_guard<nano::mutex> guard{ mutex };
return votes.empty ();
}
bool nano::vote_processor::half_full ()
bool nano::vote_processor::half_full () const
{
return size () >= max_votes / 2;
}

View file

@ -37,6 +37,10 @@ class vote_processor final
{
public:
vote_processor (nano::active_transactions & active_a, nano::node_observers & observers_a, nano::stats & stats_a, nano::node_config & config_a, nano::node_flags & flags_a, nano::logger &, nano::online_reps & online_reps_a, nano::rep_crawler & rep_crawler_a, nano::ledger & ledger_a, nano::network_params & network_params_a);
~vote_processor ();
void start ();
void stop ();
/** Returns false if the vote was processed */
bool vote (std::shared_ptr<nano::vote> const &, std::shared_ptr<nano::transport::channel> const &);
@ -46,16 +50,14 @@ public:
/** Function blocks until either the current queue size (a established flush boundary as it'll continue to increase)
* is processed or the queue is empty (end condition or cutoff's guard, as it is positioned ahead) */
void flush ();
std::size_t size ();
bool empty ();
bool half_full ();
std::size_t size () const;
bool empty () const;
bool half_full () const;
void calculate_weights ();
void stop ();
std::atomic<uint64_t> total_processed{ 0 };
private:
void process_loop ();
private: // Dependencies
nano::active_transactions & active;
nano::node_observers & observers;
nano::stats & stats;
@ -65,16 +67,22 @@ private:
nano::rep_crawler & rep_crawler;
nano::ledger & ledger;
nano::network_params & network_params;
private:
void run ();
std::size_t const max_votes;
std::deque<std::pair<std::shared_ptr<nano::vote>, std::shared_ptr<nano::transport::channel>>> votes;
/** Representatives levels for random early detection */
std::unordered_set<nano::account> representatives_1;
std::unordered_set<nano::account> representatives_2;
std::unordered_set<nano::account> representatives_3;
private:
bool stopped{ false };
nano::condition_variable condition;
nano::mutex mutex{ mutex_identifier (mutexes::vote_processor) };
bool started;
bool stopped;
mutable nano::mutex mutex{ mutex_identifier (mutexes::vote_processor) };
std::thread thread;
friend std::unique_ptr<container_info_component> collect_container_info (vote_processor & vote_processor, std::string const & name);

View file

@ -1,3 +1,4 @@
#include <nano/lib/blocks.hpp>
#include <nano/lib/stats.hpp>
#include <nano/lib/utility.hpp>
#include <nano/node/network.hpp>
@ -186,7 +187,7 @@ nano::vote_generator::~vote_generator ()
bool nano::vote_generator::should_vote (store::write_transaction const & transaction, nano::root const & root_a, nano::block_hash const & hash_a)
{
auto block = ledger.store.block.get (transaction, hash_a);
auto block = ledger.block (transaction, hash_a);
bool should_vote = false;
if (is_final)
{

Some files were not shown because too many files have changed in this diff Show more