Skip to content

Commit

Permalink
Teach the scheduler priority queue to consider both the block's and p…
Browse files Browse the repository at this point in the history
…revious block's balances and prioritize to the max of both.
  • Loading branch information
clemahieu committed Dec 8, 2022
1 parent 7965c51 commit 096685b
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 26 deletions.
54 changes: 31 additions & 23 deletions nano/core_test/prioritization.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,25 +129,33 @@ TEST (prioritization, index_max)
TEST (prioritization, insert_Gxrb)
{
nano::prioritization prioritization;
prioritization.push (1000, block0 ());
prioritization.push (1000, block0 (), 0);
ASSERT_EQ (1, prioritization.size ());
ASSERT_EQ (1, prioritization.bucket_size (48));
}

TEST (prioritization, insert_Mxrb)
{
nano::prioritization prioritization;
prioritization.push (1000, block1 ());
prioritization.push (1000, block1 (), 0);
ASSERT_EQ (1, prioritization.size ());
ASSERT_EQ (1, prioritization.bucket_size (13));
}

TEST (prioritization, insert_prev_balance)
{
nano::prioritization prioritization;
prioritization.push (1000, block1 (), nano::Gxrb_ratio);
ASSERT_EQ (1, prioritization.size ());
ASSERT_EQ (1, prioritization.bucket_size (48));
}

// Test two blocks with the same priority
TEST (prioritization, insert_same_priority)
{
nano::prioritization prioritization;
prioritization.push (1000, block0 ());
prioritization.push (1000, block2 ());
prioritization.push (1000, block0 (), 0);
prioritization.push (1000, block2 (), 0);
ASSERT_EQ (2, prioritization.size ());
ASSERT_EQ (2, prioritization.bucket_size (48));
}
Expand All @@ -156,17 +164,17 @@ TEST (prioritization, insert_same_priority)
TEST (prioritization, insert_duplicate)
{
nano::prioritization prioritization;
prioritization.push (1000, block0 ());
prioritization.push (1000, block0 ());
prioritization.push (1000, block0 (), 0);
prioritization.push (1000, block0 (), 0);
ASSERT_EQ (1, prioritization.size ());
ASSERT_EQ (1, prioritization.bucket_size (48));
}

TEST (prioritization, insert_older)
{
nano::prioritization prioritization;
prioritization.push (1000, block0 ());
prioritization.push (1100, block2 ());
prioritization.push (1000, block0 (), 0);
prioritization.push (1100, block2 (), 0);
ASSERT_EQ (block0 (), prioritization.top ());
prioritization.pop ();
ASSERT_EQ (block2 (), prioritization.top ());
Expand All @@ -177,7 +185,7 @@ TEST (prioritization, pop)
{
nano::prioritization prioritization;
ASSERT_TRUE (prioritization.empty ());
prioritization.push (1000, block0 ());
prioritization.push (1000, block0 (), 0);
ASSERT_FALSE (prioritization.empty ());
prioritization.pop ();
ASSERT_TRUE (prioritization.empty ());
Expand All @@ -186,15 +194,15 @@ TEST (prioritization, pop)
TEST (prioritization, top_one)
{
nano::prioritization prioritization;
prioritization.push (1000, block0 ());
prioritization.push (1000, block0 (), 0);
ASSERT_EQ (block0 (), prioritization.top ());
}

TEST (prioritization, top_two)
{
nano::prioritization prioritization;
prioritization.push (1000, block0 ());
prioritization.push (1, block1 ());
prioritization.push (1000, block0 (), 0);
prioritization.push (1, block1 (), 0);
ASSERT_EQ (block0 (), prioritization.top ());
prioritization.pop ();
ASSERT_EQ (block1 (), prioritization.top ());
Expand All @@ -205,11 +213,11 @@ TEST (prioritization, top_two)
TEST (prioritization, top_round_robin)
{
nano::prioritization prioritization;
prioritization.push (1000, blockzero ());
prioritization.push (1000, blockzero (), 0);
ASSERT_EQ (blockzero (), prioritization.top ());
prioritization.push (1000, block0 ());
prioritization.push (1000, block1 ());
prioritization.push (1100, block3 ());
prioritization.push (1000, block0 (), 0);
prioritization.push (1000, block1 (), 0);
prioritization.push (1100, block3 (), 0);
prioritization.pop (); // blockzero
EXPECT_EQ (block1 (), prioritization.top ());
prioritization.pop ();
Expand All @@ -223,29 +231,29 @@ TEST (prioritization, top_round_robin)
TEST (prioritization, trim_normal)
{
nano::prioritization prioritization{ 1 };
prioritization.push (1000, block0 ());
prioritization.push (1100, block2 ());
prioritization.push (1000, block0 (), 0);
prioritization.push (1100, block2 (), 0);
ASSERT_EQ (1, prioritization.size ());
ASSERT_EQ (block0 (), prioritization.top ());
}

TEST (prioritization, trim_reverse)
{
nano::prioritization prioritization{ 1 };
prioritization.push (1100, block2 ());
prioritization.push (1000, block0 ());
prioritization.push (1100, block2 (), 0);
prioritization.push (1000, block0 (), 0);
ASSERT_EQ (1, prioritization.size ());
ASSERT_EQ (block0 (), prioritization.top ());
}

TEST (prioritization, trim_even)
{
nano::prioritization prioritization{ 2 };
prioritization.push (1000, block0 ());
prioritization.push (1100, block2 ());
prioritization.push (1000, block0 (), 0);
prioritization.push (1100, block2 (), 0);
ASSERT_EQ (1, prioritization.size ());
ASSERT_EQ (block0 (), prioritization.top ());
prioritization.push (1000, block1 ());
prioritization.push (1000, block1 (), 0);
ASSERT_EQ (2, prioritization.size ());
ASSERT_EQ (block0 (), prioritization.top ());
prioritization.pop ();
Expand Down
3 changes: 2 additions & 1 deletion nano/node/election_scheduler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,9 @@ void nano::election_scheduler::activate (nano::account const & account_a, nano::
debug_assert (block != nullptr);
if (node.ledger.dependents_confirmed (transaction, *block))
{
auto previous_balance = node.ledger.balance (transaction, conf_info.frontier);
nano::lock_guard<nano::mutex> lock{ mutex };
priority.push (account_info.modified, block);
priority.push (account_info.modified, block, previous_balance);
notify ();
}
}
Expand Down
3 changes: 2 additions & 1 deletion nano/node/prioritization.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,12 +82,13 @@ std::size_t nano::prioritization::index (nano::uint128_t const & balance) const
* Push a block and its associated time into the prioritization container.
* The time is given here because sideband might not exist in the case of state blocks.
*/
void nano::prioritization::push (uint64_t time, std::shared_ptr<nano::block> block)
void nano::prioritization::push (uint64_t time, std::shared_ptr<nano::block> block, nano::amount const & previous_balance)
{
auto was_empty = empty ();
auto block_has_balance = block->type () == nano::block_type::state || block->type () == nano::block_type::send;
debug_assert (block_has_balance || block->has_sideband ());
auto balance = block_has_balance ? block->balance () : block->sideband ().balance;
balance = std::max (balance, previous_balance);
auto & bucket = buckets[index (balance.number ())];
bucket.emplace (value_type{ time, block });
if (bucket.size () > std::max (decltype (maximum){ 1 }, maximum / buckets.size ()))
Expand Down
2 changes: 1 addition & 1 deletion nano/node/prioritization.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ class prioritization final

public:
prioritization (uint64_t maximum = 250000u);
void push (uint64_t time, std::shared_ptr<nano::block> block);
void push (uint64_t time, std::shared_ptr<nano::block> block, nano::amount const & previous_balance);
std::shared_ptr<nano::block> top () const;
void pop ();
std::size_t size () const;
Expand Down

0 comments on commit 096685b

Please sign in to comment.