Change election scheduler to consider previous balance (#4022)
* Teach the scheduler priority queue to consider both the block's and previous block's balances and prioritize to the max of both. * Move priority calculations in to the election_scheduler and directly accept the priority value in prioritization::push.
This commit is contained in:
		
					parent
					
						
							
								a5d9aeb94a
							
						
					
				
			
			
				commit
				
					
						c96f37b34c
					
				
			
		
					 4 changed files with 29 additions and 30 deletions
				
			
		| 
						 | 
					@ -129,7 +129,7 @@ TEST (prioritization, index_max)
 | 
				
			||||||
TEST (prioritization, insert_Gxrb)
 | 
					TEST (prioritization, insert_Gxrb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	nano::prioritization prioritization;
 | 
						nano::prioritization prioritization;
 | 
				
			||||||
	prioritization.push (1000, block0 ());
 | 
						prioritization.push (1000, block0 (), nano::Gxrb_ratio);
 | 
				
			||||||
	ASSERT_EQ (1, prioritization.size ());
 | 
						ASSERT_EQ (1, prioritization.size ());
 | 
				
			||||||
	ASSERT_EQ (1, prioritization.bucket_size (48));
 | 
						ASSERT_EQ (1, prioritization.bucket_size (48));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -137,7 +137,7 @@ TEST (prioritization, insert_Gxrb)
 | 
				
			||||||
TEST (prioritization, insert_Mxrb)
 | 
					TEST (prioritization, insert_Mxrb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	nano::prioritization prioritization;
 | 
						nano::prioritization prioritization;
 | 
				
			||||||
	prioritization.push (1000, block1 ());
 | 
						prioritization.push (1000, block1 (), nano::Mxrb_ratio);
 | 
				
			||||||
	ASSERT_EQ (1, prioritization.size ());
 | 
						ASSERT_EQ (1, prioritization.size ());
 | 
				
			||||||
	ASSERT_EQ (1, prioritization.bucket_size (13));
 | 
						ASSERT_EQ (1, prioritization.bucket_size (13));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -146,8 +146,8 @@ TEST (prioritization, insert_Mxrb)
 | 
				
			||||||
TEST (prioritization, insert_same_priority)
 | 
					TEST (prioritization, insert_same_priority)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	nano::prioritization prioritization;
 | 
						nano::prioritization prioritization;
 | 
				
			||||||
	prioritization.push (1000, block0 ());
 | 
						prioritization.push (1000, block0 (), nano::Gxrb_ratio);
 | 
				
			||||||
	prioritization.push (1000, block2 ());
 | 
						prioritization.push (1000, block2 (), nano::Gxrb_ratio);
 | 
				
			||||||
	ASSERT_EQ (2, prioritization.size ());
 | 
						ASSERT_EQ (2, prioritization.size ());
 | 
				
			||||||
	ASSERT_EQ (2, prioritization.bucket_size (48));
 | 
						ASSERT_EQ (2, prioritization.bucket_size (48));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -156,8 +156,8 @@ TEST (prioritization, insert_same_priority)
 | 
				
			||||||
TEST (prioritization, insert_duplicate)
 | 
					TEST (prioritization, insert_duplicate)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	nano::prioritization prioritization;
 | 
						nano::prioritization prioritization;
 | 
				
			||||||
	prioritization.push (1000, block0 ());
 | 
						prioritization.push (1000, block0 (), nano::Gxrb_ratio);
 | 
				
			||||||
	prioritization.push (1000, block0 ());
 | 
						prioritization.push (1000, block0 (), nano::Gxrb_ratio);
 | 
				
			||||||
	ASSERT_EQ (1, prioritization.size ());
 | 
						ASSERT_EQ (1, prioritization.size ());
 | 
				
			||||||
	ASSERT_EQ (1, prioritization.bucket_size (48));
 | 
						ASSERT_EQ (1, prioritization.bucket_size (48));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -165,8 +165,8 @@ TEST (prioritization, insert_duplicate)
 | 
				
			||||||
TEST (prioritization, insert_older)
 | 
					TEST (prioritization, insert_older)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	nano::prioritization prioritization;
 | 
						nano::prioritization prioritization;
 | 
				
			||||||
	prioritization.push (1000, block0 ());
 | 
						prioritization.push (1000, block0 (), nano::Gxrb_ratio);
 | 
				
			||||||
	prioritization.push (1100, block2 ());
 | 
						prioritization.push (1100, block2 (), nano::Gxrb_ratio);
 | 
				
			||||||
	ASSERT_EQ (block0 (), prioritization.top ());
 | 
						ASSERT_EQ (block0 (), prioritization.top ());
 | 
				
			||||||
	prioritization.pop ();
 | 
						prioritization.pop ();
 | 
				
			||||||
	ASSERT_EQ (block2 (), prioritization.top ());
 | 
						ASSERT_EQ (block2 (), prioritization.top ());
 | 
				
			||||||
| 
						 | 
					@ -177,7 +177,7 @@ TEST (prioritization, pop)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	nano::prioritization prioritization;
 | 
						nano::prioritization prioritization;
 | 
				
			||||||
	ASSERT_TRUE (prioritization.empty ());
 | 
						ASSERT_TRUE (prioritization.empty ());
 | 
				
			||||||
	prioritization.push (1000, block0 ());
 | 
						prioritization.push (1000, block0 (), nano::Gxrb_ratio);
 | 
				
			||||||
	ASSERT_FALSE (prioritization.empty ());
 | 
						ASSERT_FALSE (prioritization.empty ());
 | 
				
			||||||
	prioritization.pop ();
 | 
						prioritization.pop ();
 | 
				
			||||||
	ASSERT_TRUE (prioritization.empty ());
 | 
						ASSERT_TRUE (prioritization.empty ());
 | 
				
			||||||
| 
						 | 
					@ -186,15 +186,15 @@ TEST (prioritization, pop)
 | 
				
			||||||
TEST (prioritization, top_one)
 | 
					TEST (prioritization, top_one)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	nano::prioritization prioritization;
 | 
						nano::prioritization prioritization;
 | 
				
			||||||
	prioritization.push (1000, block0 ());
 | 
						prioritization.push (1000, block0 (), nano::Gxrb_ratio);
 | 
				
			||||||
	ASSERT_EQ (block0 (), prioritization.top ());
 | 
						ASSERT_EQ (block0 (), prioritization.top ());
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
TEST (prioritization, top_two)
 | 
					TEST (prioritization, top_two)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	nano::prioritization prioritization;
 | 
						nano::prioritization prioritization;
 | 
				
			||||||
	prioritization.push (1000, block0 ());
 | 
						prioritization.push (1000, block0 (), nano::Gxrb_ratio);
 | 
				
			||||||
	prioritization.push (1, block1 ());
 | 
						prioritization.push (1, block1 (), nano::Mxrb_ratio);
 | 
				
			||||||
	ASSERT_EQ (block0 (), prioritization.top ());
 | 
						ASSERT_EQ (block0 (), prioritization.top ());
 | 
				
			||||||
	prioritization.pop ();
 | 
						prioritization.pop ();
 | 
				
			||||||
	ASSERT_EQ (block1 (), prioritization.top ());
 | 
						ASSERT_EQ (block1 (), prioritization.top ());
 | 
				
			||||||
| 
						 | 
					@ -205,11 +205,11 @@ TEST (prioritization, top_two)
 | 
				
			||||||
TEST (prioritization, top_round_robin)
 | 
					TEST (prioritization, top_round_robin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	nano::prioritization prioritization;
 | 
						nano::prioritization prioritization;
 | 
				
			||||||
	prioritization.push (1000, blockzero ());
 | 
						prioritization.push (1000, blockzero (), 0);
 | 
				
			||||||
	ASSERT_EQ (blockzero (), prioritization.top ());
 | 
						ASSERT_EQ (blockzero (), prioritization.top ());
 | 
				
			||||||
	prioritization.push (1000, block0 ());
 | 
						prioritization.push (1000, block0 (), nano::Gxrb_ratio);
 | 
				
			||||||
	prioritization.push (1000, block1 ());
 | 
						prioritization.push (1000, block1 (), nano::Mxrb_ratio);
 | 
				
			||||||
	prioritization.push (1100, block3 ());
 | 
						prioritization.push (1100, block3 (), nano::Mxrb_ratio);
 | 
				
			||||||
	prioritization.pop (); // blockzero
 | 
						prioritization.pop (); // blockzero
 | 
				
			||||||
	EXPECT_EQ (block1 (), prioritization.top ());
 | 
						EXPECT_EQ (block1 (), prioritization.top ());
 | 
				
			||||||
	prioritization.pop ();
 | 
						prioritization.pop ();
 | 
				
			||||||
| 
						 | 
					@ -223,8 +223,8 @@ TEST (prioritization, top_round_robin)
 | 
				
			||||||
TEST (prioritization, trim_normal)
 | 
					TEST (prioritization, trim_normal)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	nano::prioritization prioritization{ 1 };
 | 
						nano::prioritization prioritization{ 1 };
 | 
				
			||||||
	prioritization.push (1000, block0 ());
 | 
						prioritization.push (1000, block0 (), nano::Gxrb_ratio);
 | 
				
			||||||
	prioritization.push (1100, block2 ());
 | 
						prioritization.push (1100, block2 (), nano::Gxrb_ratio);
 | 
				
			||||||
	ASSERT_EQ (1, prioritization.size ());
 | 
						ASSERT_EQ (1, prioritization.size ());
 | 
				
			||||||
	ASSERT_EQ (block0 (), prioritization.top ());
 | 
						ASSERT_EQ (block0 (), prioritization.top ());
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -232,8 +232,8 @@ TEST (prioritization, trim_normal)
 | 
				
			||||||
TEST (prioritization, trim_reverse)
 | 
					TEST (prioritization, trim_reverse)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	nano::prioritization prioritization{ 1 };
 | 
						nano::prioritization prioritization{ 1 };
 | 
				
			||||||
	prioritization.push (1100, block2 ());
 | 
						prioritization.push (1100, block2 (), nano::Gxrb_ratio);
 | 
				
			||||||
	prioritization.push (1000, block0 ());
 | 
						prioritization.push (1000, block0 (), nano::Gxrb_ratio);
 | 
				
			||||||
	ASSERT_EQ (1, prioritization.size ());
 | 
						ASSERT_EQ (1, prioritization.size ());
 | 
				
			||||||
	ASSERT_EQ (block0 (), prioritization.top ());
 | 
						ASSERT_EQ (block0 (), prioritization.top ());
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -241,11 +241,11 @@ TEST (prioritization, trim_reverse)
 | 
				
			||||||
TEST (prioritization, trim_even)
 | 
					TEST (prioritization, trim_even)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	nano::prioritization prioritization{ 2 };
 | 
						nano::prioritization prioritization{ 2 };
 | 
				
			||||||
	prioritization.push (1000, block0 ());
 | 
						prioritization.push (1000, block0 (), nano::Gxrb_ratio);
 | 
				
			||||||
	prioritization.push (1100, block2 ());
 | 
						prioritization.push (1100, block2 (), nano::Gxrb_ratio);
 | 
				
			||||||
	ASSERT_EQ (1, prioritization.size ());
 | 
						ASSERT_EQ (1, prioritization.size ());
 | 
				
			||||||
	ASSERT_EQ (block0 (), prioritization.top ());
 | 
						ASSERT_EQ (block0 (), prioritization.top ());
 | 
				
			||||||
	prioritization.push (1000, block1 ());
 | 
						prioritization.push (1000, block1 (), nano::Mxrb_ratio);
 | 
				
			||||||
	ASSERT_EQ (2, prioritization.size ());
 | 
						ASSERT_EQ (2, prioritization.size ());
 | 
				
			||||||
	ASSERT_EQ (block0 (), prioritization.top ());
 | 
						ASSERT_EQ (block0 (), prioritization.top ());
 | 
				
			||||||
	prioritization.pop ();
 | 
						prioritization.pop ();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -37,8 +37,10 @@ void nano::election_scheduler::activate (nano::account const & account_a, nano::
 | 
				
			||||||
			debug_assert (block != nullptr);
 | 
								debug_assert (block != nullptr);
 | 
				
			||||||
			if (node.ledger.dependents_confirmed (transaction, *block))
 | 
								if (node.ledger.dependents_confirmed (transaction, *block))
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
 | 
									auto balance = node.ledger.balance (transaction, hash);
 | 
				
			||||||
 | 
									auto previous_balance = node.ledger.balance (transaction, conf_info.frontier);
 | 
				
			||||||
				nano::lock_guard<nano::mutex> lock{ mutex };
 | 
									nano::lock_guard<nano::mutex> lock{ mutex };
 | 
				
			||||||
				priority.push (account_info.modified, block);
 | 
									priority.push (account_info.modified, block, std::max (balance, previous_balance));
 | 
				
			||||||
				notify ();
 | 
									notify ();
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -82,13 +82,10 @@ std::size_t nano::prioritization::index (nano::uint128_t const & balance) const
 | 
				
			||||||
 * Push a block and its associated time into the prioritization container.
 | 
					 * 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.
 | 
					 * 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 & priority)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	auto was_empty = empty ();
 | 
						auto was_empty = empty ();
 | 
				
			||||||
	auto block_has_balance = block->type () == nano::block_type::state || block->type () == nano::block_type::send;
 | 
						auto & bucket = buckets[index (priority.number ())];
 | 
				
			||||||
	debug_assert (block_has_balance || block->has_sideband ());
 | 
					 | 
				
			||||||
	auto balance = block_has_balance ? block->balance () : block->sideband ().balance;
 | 
					 | 
				
			||||||
	auto & bucket = buckets[index (balance.number ())];
 | 
					 | 
				
			||||||
	bucket.emplace (value_type{ time, block });
 | 
						bucket.emplace (value_type{ time, block });
 | 
				
			||||||
	if (bucket.size () > std::max (decltype (maximum){ 1 }, maximum / buckets.size ()))
 | 
						if (bucket.size () > std::max (decltype (maximum){ 1 }, maximum / buckets.size ()))
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -55,7 +55,7 @@ class prioritization final
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
	prioritization (uint64_t maximum = 250000u);
 | 
						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 & priority);
 | 
				
			||||||
	std::shared_ptr<nano::block> top () const;
 | 
						std::shared_ptr<nano::block> top () const;
 | 
				
			||||||
	void pop ();
 | 
						void pop ();
 | 
				
			||||||
	std::size_t size () const;
 | 
						std::size_t size () const;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue