Skip to content

Commit

Permalink
This change reorganizes the names of some classes related to the sche…
Browse files Browse the repository at this point in the history
…duler. (#4270)

nano::scheduler::buckets has been renamed nano::scheduler::priority in order to match other election initating strategies like nano::scheduler::optimistic and nano::scheduler::hinted.

The class nano::prioritization has been renamed to nano::scheduler::buckets placing it under a more appropriate namespace and better indicating what the class is modeling.
  • Loading branch information
clemahieu authored Aug 31, 2023
1 parent 1fbd6d4 commit 7b540db
Show file tree
Hide file tree
Showing 27 changed files with 751 additions and 736 deletions.
2 changes: 1 addition & 1 deletion nano/core_test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ add_executable(
bootstrap.cpp
bootstrap_ascending.cpp
bootstrap_server.cpp
buckets.cpp
cli.cpp
confirmation_height.cpp
confirmation_solicitor.cpp
Expand Down Expand Up @@ -38,7 +39,6 @@ add_executable(
processing_queue.cpp
processor_service.cpp
peer_container.cpp
prioritization.cpp
request_aggregator.cpp
signal_manager.cpp
signing.cpp
Expand Down
28 changes: 14 additions & 14 deletions nano/core_test/active_transactions.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#include <nano/lib/jsonconfig.hpp>
#include <nano/node/election.hpp>
#include <nano/node/scheduler/buckets.hpp>
#include <nano/node/scheduler/component.hpp>
#include <nano/node/scheduler/priority.hpp>
#include <nano/node/transport/inproc.hpp>
#include <nano/test_common/chains.hpp>
#include <nano/test_common/system.hpp>
Expand Down Expand Up @@ -418,7 +418,7 @@ TEST (active_transactions, inactive_votes_cache_multiple_votes)
ASSERT_TIMELY (5s, node.inactive_vote_cache.find (send1->hash ()));
ASSERT_TIMELY (5s, node.inactive_vote_cache.find (send1->hash ())->voters.size () == 2);
ASSERT_EQ (1, node.inactive_vote_cache.cache_size ());
node.scheduler.buckets.activate (nano::dev::genesis_key.pub, node.store.tx_begin_read ());
node.scheduler.priority.activate (nano::dev::genesis_key.pub, node.store.tx_begin_read ());
std::shared_ptr<nano::election> election;
ASSERT_TIMELY (5s, election = node.active.election (send1->qualified_root ()));
ASSERT_EQ (3, election->votes ().size ()); // 2 votes and 1 default not_an_acount
Expand Down Expand Up @@ -996,7 +996,7 @@ TEST (active_transactions, confirmation_consistency)
system.deadline_set (5s);
while (!node.ledger.block_confirmed (node.store.tx_begin_read (), block->hash ()))
{
node.scheduler.buckets.activate (nano::dev::genesis_key.pub, node.store.tx_begin_read ());
node.scheduler.priority.activate (nano::dev::genesis_key.pub, node.store.tx_begin_read ());
ASSERT_NO_ERROR (system.poll (5ms));
}
ASSERT_NO_ERROR (system.poll_until_true (1s, [&node, &block, i] {
Expand Down Expand Up @@ -1140,19 +1140,19 @@ TEST (active_transactions, activate_account_chain)
ASSERT_EQ (nano::process_result::progress, node.process (*open).code);
ASSERT_EQ (nano::process_result::progress, node.process (*receive).code);

node.scheduler.buckets.activate (nano::dev::genesis_key.pub, node.store.tx_begin_read ());
node.scheduler.priority.activate (nano::dev::genesis_key.pub, node.store.tx_begin_read ());
ASSERT_TIMELY (5s, node.active.election (send->qualified_root ()));
auto election1 = node.active.election (send->qualified_root ());
ASSERT_EQ (1, node.active.size ());
ASSERT_EQ (1, election1->blocks ().count (send->hash ()));
node.scheduler.buckets.activate (nano::dev::genesis_key.pub, node.store.tx_begin_read ());
node.scheduler.priority.activate (nano::dev::genesis_key.pub, node.store.tx_begin_read ());
auto election2 = node.active.election (send->qualified_root ());
ASSERT_EQ (election2, election1);
election1->force_confirm ();
ASSERT_TIMELY (3s, node.block_confirmed (send->hash ()));
// On cementing, the next election is started
ASSERT_TIMELY (3s, node.active.active (send2->qualified_root ()));
node.scheduler.buckets.activate (nano::dev::genesis_key.pub, node.store.tx_begin_read ());
node.scheduler.priority.activate (nano::dev::genesis_key.pub, node.store.tx_begin_read ());
auto election3 = node.active.election (send2->qualified_root ());
ASSERT_NE (nullptr, election3);
ASSERT_EQ (1, election3->blocks ().count (send2->hash ()));
Expand All @@ -1161,19 +1161,19 @@ TEST (active_transactions, activate_account_chain)
// On cementing, the next election is started
ASSERT_TIMELY (3s, node.active.active (open->qualified_root ()));
ASSERT_TIMELY (3s, node.active.active (send3->qualified_root ()));
node.scheduler.buckets.activate (nano::dev::genesis_key.pub, node.store.tx_begin_read ());
node.scheduler.priority.activate (nano::dev::genesis_key.pub, node.store.tx_begin_read ());
auto election4 = node.active.election (send3->qualified_root ());
ASSERT_NE (nullptr, election4);
ASSERT_EQ (1, election4->blocks ().count (send3->hash ()));
node.scheduler.buckets.activate (key.pub, node.store.tx_begin_read ());
node.scheduler.priority.activate (key.pub, node.store.tx_begin_read ());
auto election5 = node.active.election (open->qualified_root ());
ASSERT_NE (nullptr, election5);
ASSERT_EQ (1, election5->blocks ().count (open->hash ()));
election5->force_confirm ();
ASSERT_TIMELY (3s, node.block_confirmed (open->hash ()));
// Until send3 is also confirmed, the receive block should not activate
std::this_thread::sleep_for (200ms);
node.scheduler.buckets.activate (key.pub, node.store.tx_begin_read ());
node.scheduler.priority.activate (key.pub, node.store.tx_begin_read ());
election4->force_confirm ();
ASSERT_TIMELY (3s, node.block_confirmed (send3->hash ()));
ASSERT_TIMELY (3s, node.active.active (receive->qualified_root ()));
Expand Down Expand Up @@ -1314,7 +1314,7 @@ TEST (active_transactions, vacancy)
ASSERT_EQ (nano::process_result::progress, node.process (*send).code);
ASSERT_EQ (1, node.active.vacancy ());
ASSERT_EQ (0, node.active.size ());
node.scheduler.buckets.activate (nano::dev::genesis_key.pub, node.store.tx_begin_read ());
node.scheduler.priority.activate (nano::dev::genesis_key.pub, node.store.tx_begin_read ());
ASSERT_TIMELY (1s, updated);
updated = false;
ASSERT_EQ (0, node.active.vacancy ());
Expand Down Expand Up @@ -1393,11 +1393,11 @@ TEST (active_transactions, fifo)
ASSERT_EQ (nano::process_result::progress, node.process (*receive2).code);

// Ensure first transaction becomes active
node.scheduler.buckets.manual (receive1);
node.scheduler.priority.manual (receive1);
ASSERT_TIMELY (5s, node.active.election (receive1->qualified_root ()) != nullptr);

// Ensure second transaction becomes active
node.scheduler.buckets.manual (receive2);
node.scheduler.priority.manual (receive2);
ASSERT_TIMELY (5s, node.active.election (receive2->qualified_root ()) != nullptr);

// Ensure excess transactions get trimmed
Expand Down Expand Up @@ -1503,7 +1503,7 @@ TEST (active_transactions, allow_limited_overflow)
// Insert the first part of the blocks into normal election scheduler
for (auto const & block : blocks1)
{
node.scheduler.buckets.activate (block->account (), node.store.tx_begin_read ());
node.scheduler.priority.activate (block->account (), node.store.tx_begin_read ());
}

// Ensure number of active elections reaches AEC limit and there is no overfill
Expand Down Expand Up @@ -1565,7 +1565,7 @@ TEST (active_transactions, allow_limited_overflow_adapt)
// Insert the first part of the blocks into normal election scheduler
for (auto const & block : blocks1)
{
node.scheduler.buckets.activate (block->account (), node.store.tx_begin_read ());
node.scheduler.priority.activate (block->account (), node.store.tx_begin_read ());
}

// Ensure number of active elections reaches AEC limit and there is no overfill
Expand Down
253 changes: 253 additions & 0 deletions nano/core_test/buckets.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,253 @@
#include <nano/node/scheduler/buckets.hpp>
#include <nano/secure/common.hpp>

#include <gtest/gtest.h>

#include <unordered_set>

nano::keypair & keyzero ()
{
static nano::keypair result;
return result;
}
nano::keypair & key0 ()
{
static nano::keypair result;
return result;
}
nano::keypair & key1 ()
{
static nano::keypair result;
return result;
}
nano::keypair & key2 ()
{
static nano::keypair result;
return result;
}
nano::keypair & key3 ()
{
static nano::keypair result;
return result;
}
std::shared_ptr<nano::state_block> & blockzero ()
{
nano::block_builder builder;
static auto result = builder
.state ()
.account (keyzero ().pub)
.previous (0)
.representative (keyzero ().pub)
.balance (0)
.link (0)
.sign (keyzero ().prv, keyzero ().pub)
.work (0)
.build_shared ();
return result;
}
std::shared_ptr<nano::state_block> & block0 ()
{
nano::block_builder builder;
static auto result = builder
.state ()
.account (key0 ().pub)
.previous (0)
.representative (key0 ().pub)
.balance (nano::Gxrb_ratio)
.link (0)
.sign (key0 ().prv, key0 ().pub)
.work (0)
.build_shared ();
return result;
}
std::shared_ptr<nano::state_block> & block1 ()
{
nano::block_builder builder;
static auto result = builder
.state ()
.account (key1 ().pub)
.previous (0)
.representative (key1 ().pub)
.balance (nano::Mxrb_ratio)
.link (0)
.sign (key1 ().prv, key1 ().pub)
.work (0)
.build_shared ();
return result;
}
std::shared_ptr<nano::state_block> & block2 ()
{
nano::block_builder builder;
static auto result = builder
.state ()
.account (key2 ().pub)
.previous (0)
.representative (key2 ().pub)
.balance (nano::Gxrb_ratio)
.link (0)
.sign (key2 ().prv, key2 ().pub)
.work (0)
.build_shared ();
return result;
}
std::shared_ptr<nano::state_block> & block3 ()
{
nano::block_builder builder;
static auto result = builder
.state ()
.account (key3 ().pub)
.previous (0)
.representative (key3 ().pub)
.balance (nano::Mxrb_ratio)
.link (0)
.sign (key3 ().prv, key3 ().pub)
.work (0)
.build_shared ();
return result;
}

TEST (scheduler_buckets, construction)
{
nano::scheduler::buckets buckets;
ASSERT_EQ (0, buckets.size ());
ASSERT_TRUE (buckets.empty ());
ASSERT_EQ (62, buckets.bucket_count ());
}

TEST (scheduler_buckets, index_min)
{
nano::scheduler::buckets buckets;
ASSERT_EQ (0, buckets.index (std::numeric_limits<nano::uint128_t>::min ()));
}

TEST (scheduler_buckets, index_max)
{
nano::scheduler::buckets buckets;
ASSERT_EQ (buckets.bucket_count () - 1, buckets.index (std::numeric_limits<nano::uint128_t>::max ()));
}

TEST (scheduler_buckets, insert_Gxrb)
{
nano::scheduler::buckets buckets;
buckets.push (1000, block0 (), nano::Gxrb_ratio);
ASSERT_EQ (1, buckets.size ());
ASSERT_EQ (1, buckets.bucket_size (48));
}

TEST (scheduler_buckets, insert_Mxrb)
{
nano::scheduler::buckets buckets;
buckets.push (1000, block1 (), nano::Mxrb_ratio);
ASSERT_EQ (1, buckets.size ());
ASSERT_EQ (1, buckets.bucket_size (13));
}

// Test two blocks with the same priority
TEST (scheduler_buckets, insert_same_priority)
{
nano::scheduler::buckets buckets;
buckets.push (1000, block0 (), nano::Gxrb_ratio);
buckets.push (1000, block2 (), nano::Gxrb_ratio);
ASSERT_EQ (2, buckets.size ());
ASSERT_EQ (2, buckets.bucket_size (48));
}

// Test the same block inserted multiple times
TEST (scheduler_buckets, insert_duplicate)
{
nano::scheduler::buckets buckets;
buckets.push (1000, block0 (), nano::Gxrb_ratio);
buckets.push (1000, block0 (), nano::Gxrb_ratio);
ASSERT_EQ (1, buckets.size ());
ASSERT_EQ (1, buckets.bucket_size (48));
}

TEST (scheduler_buckets, insert_older)
{
nano::scheduler::buckets buckets;
buckets.push (1000, block0 (), nano::Gxrb_ratio);
buckets.push (1100, block2 (), nano::Gxrb_ratio);
ASSERT_EQ (block0 (), buckets.top ());
buckets.pop ();
ASSERT_EQ (block2 (), buckets.top ());
buckets.pop ();
}

TEST (scheduler_buckets, pop)
{
nano::scheduler::buckets buckets;
ASSERT_TRUE (buckets.empty ());
buckets.push (1000, block0 (), nano::Gxrb_ratio);
ASSERT_FALSE (buckets.empty ());
buckets.pop ();
ASSERT_TRUE (buckets.empty ());
}

TEST (scheduler_buckets, top_one)
{
nano::scheduler::buckets buckets;
buckets.push (1000, block0 (), nano::Gxrb_ratio);
ASSERT_EQ (block0 (), buckets.top ());
}

TEST (scheduler_buckets, top_two)
{
nano::scheduler::buckets buckets;
buckets.push (1000, block0 (), nano::Gxrb_ratio);
buckets.push (1, block1 (), nano::Mxrb_ratio);
ASSERT_EQ (block0 (), buckets.top ());
buckets.pop ();
ASSERT_EQ (block1 (), buckets.top ());
buckets.pop ();
ASSERT_TRUE (buckets.empty ());
}

TEST (scheduler_buckets, top_round_robin)
{
nano::scheduler::buckets buckets;
buckets.push (1000, blockzero (), 0);
ASSERT_EQ (blockzero (), buckets.top ());
buckets.push (1000, block0 (), nano::Gxrb_ratio);
buckets.push (1000, block1 (), nano::Mxrb_ratio);
buckets.push (1100, block3 (), nano::Mxrb_ratio);
buckets.pop (); // blockzero
EXPECT_EQ (block1 (), buckets.top ());
buckets.pop ();
EXPECT_EQ (block0 (), buckets.top ());
buckets.pop ();
EXPECT_EQ (block3 (), buckets.top ());
buckets.pop ();
EXPECT_TRUE (buckets.empty ());
}

TEST (scheduler_buckets, trim_normal)
{
nano::scheduler::buckets buckets{ 1 };
buckets.push (1000, block0 (), nano::Gxrb_ratio);
buckets.push (1100, block2 (), nano::Gxrb_ratio);
ASSERT_EQ (1, buckets.size ());
ASSERT_EQ (block0 (), buckets.top ());
}

TEST (scheduler_buckets, trim_reverse)
{
nano::scheduler::buckets buckets{ 1 };
buckets.push (1100, block2 (), nano::Gxrb_ratio);
buckets.push (1000, block0 (), nano::Gxrb_ratio);
ASSERT_EQ (1, buckets.size ());
ASSERT_EQ (block0 (), buckets.top ());
}

TEST (scheduler_buckets, trim_even)
{
nano::scheduler::buckets buckets{ 2 };
buckets.push (1000, block0 (), nano::Gxrb_ratio);
buckets.push (1100, block2 (), nano::Gxrb_ratio);
ASSERT_EQ (1, buckets.size ());
ASSERT_EQ (block0 (), buckets.top ());
buckets.push (1000, block1 (), nano::Mxrb_ratio);
ASSERT_EQ (2, buckets.size ());
ASSERT_EQ (block0 (), buckets.top ());
buckets.pop ();
ASSERT_EQ (block1 (), buckets.top ());
}
Loading

0 comments on commit 7b540db

Please sign in to comment.