Prioritizing transaction processing by difficulty. (#1413)

This commit is contained in:
clemahieu 2018-11-29 19:37:22 +01:00 committed by Roy Keene
commit ce8d6ec124
4 changed files with 78 additions and 38 deletions

View file

@ -8,9 +8,9 @@ TEST (conflicts, start_stop)
rai::genesis genesis;
rai::keypair key1;
auto send1 (std::make_shared<rai::send_block> (genesis.hash (), key1.pub, 0, rai::test_genesis_key.prv, rai::test_genesis_key.pub, 0));
node1.work_generate_blocking (*send1);
ASSERT_EQ (rai::process_result::progress, node1.process (*send1).code);
ASSERT_EQ (0, node1.active.roots.size ());
auto node_l (system.nodes[0]);
node1.active.start (send1);
ASSERT_EQ (1, node1.active.roots.size ());
auto root1 (send1->root ());
@ -28,8 +28,8 @@ TEST (conflicts, add_existing)
rai::genesis genesis;
rai::keypair key1;
auto send1 (std::make_shared<rai::send_block> (genesis.hash (), key1.pub, 0, rai::test_genesis_key.prv, rai::test_genesis_key.pub, 0));
node1.work_generate_blocking (*send1);
ASSERT_EQ (rai::process_result::progress, node1.process (*send1).code);
auto node_l (system.nodes[0]);
node1.active.start (send1);
rai::keypair key2;
auto send2 (std::make_shared<rai::send_block> (genesis.hash (), key2.pub, 0, rai::test_genesis_key.prv, rai::test_genesis_key.pub, 0));
@ -51,11 +51,12 @@ TEST (conflicts, add_two)
rai::genesis genesis;
rai::keypair key1;
auto send1 (std::make_shared<rai::send_block> (genesis.hash (), key1.pub, 0, rai::test_genesis_key.prv, rai::test_genesis_key.pub, 0));
node1.work_generate_blocking (*send1);
ASSERT_EQ (rai::process_result::progress, node1.process (*send1).code);
auto node_l (system.nodes[0]);
node1.active.start (send1);
rai::keypair key2;
auto send2 (std::make_shared<rai::send_block> (send1->hash (), key2.pub, 0, rai::test_genesis_key.prv, rai::test_genesis_key.pub, 0));
node1.work_generate_blocking (*send2);
ASSERT_EQ (rai::process_result::progress, node1.process (*send2).code);
node1.active.start (send2);
ASSERT_EQ (2, node1.active.roots.size ());
@ -147,3 +148,28 @@ TEST (vote_uniquer, cleanup)
ASSERT_LT (iterations++, 200);
}
}
TEST (conflicts, reprioritize)
{
rai::system system (24000, 1);
auto & node1 (*system.nodes[0]);
rai::genesis genesis;
rai::keypair key1;
auto send1 (std::make_shared<rai::send_block> (genesis.hash (), key1.pub, 0, rai::test_genesis_key.prv, rai::test_genesis_key.pub, 0));
node1.work_generate_blocking (*send1);
uint64_t difficulty1;
rai::work_validate (*send1, &difficulty1);
node1.process_active (send1);
node1.block_processor.flush ();
auto existing1 (node1.active.roots.find (send1->root ()));
ASSERT_NE (node1.active.roots.end (), existing1);
ASSERT_EQ (difficulty1, existing1->difficulty);
node1.work_generate_blocking (*send1, difficulty1);
uint64_t difficulty2;
rai::work_validate (*send1, &difficulty2);
node1.process_active (send1);
node1.block_processor.flush ();
auto existing2 (node1.active.roots.find (send1->root ()));
ASSERT_NE (node1.active.roots.end (), existing2);
ASSERT_EQ (difficulty2, existing2->difficulty);
}

View file

@ -565,7 +565,7 @@ TEST (ledger, DISABLED_checksum_range)
ASSERT_EQ (hash1, check3);
}
TEST (system, generate_send_existing)
TEST (system, DISABLED_generate_send_existing)
{
rai::system system (24000, 1);
rai::thread_runner runner (system.service, system.nodes[0]->config.io_threads);
@ -780,6 +780,7 @@ TEST (votes, check_signature)
rai::genesis genesis;
rai::keypair key1;
auto send1 (std::make_shared<rai::send_block> (genesis.hash (), key1.pub, rai::genesis_amount - 100, rai::test_genesis_key.prv, rai::test_genesis_key.pub, 0));
node1.work_generate_blocking (*send1);
auto transaction (node1.store.tx_begin (true));
ASSERT_EQ (rai::process_result::progress, node1.ledger.process (transaction, *send1).code);
auto node_l (system.nodes[0]);
@ -802,11 +803,9 @@ TEST (votes, add_one)
rai::genesis genesis;
rai::keypair key1;
auto send1 (std::make_shared<rai::send_block> (genesis.hash (), key1.pub, rai::genesis_amount - 100, rai::test_genesis_key.prv, rai::test_genesis_key.pub, 0));
{
auto transaction (node1.store.tx_begin (true));
ASSERT_EQ (rai::process_result::progress, node1.ledger.process (transaction, *send1).code);
}
auto node_l (system.nodes[0]);
node1.work_generate_blocking (*send1);
auto transaction (node1.store.tx_begin (true));
ASSERT_EQ (rai::process_result::progress, node1.ledger.process (transaction, *send1).code);
node1.active.start (send1);
auto votes1 (node1.active.roots.find (send1->root ())->election);
ASSERT_EQ (1, votes1->last_votes.size ());
@ -818,7 +817,6 @@ TEST (votes, add_one)
auto existing1 (votes1->last_votes.find (rai::test_genesis_key.pub));
ASSERT_NE (votes1->last_votes.end (), existing1);
ASSERT_EQ (send1->hash (), existing1->second.hash);
auto transaction (system.nodes[0]->store.tx_begin ());
auto winner (*votes1->tally (transaction).begin ());
ASSERT_EQ (*send1, *winner.second);
ASSERT_EQ (rai::genesis_amount - 100, winner.first);
@ -831,11 +829,9 @@ TEST (votes, add_two)
rai::genesis genesis;
rai::keypair key1;
auto send1 (std::make_shared<rai::send_block> (genesis.hash (), key1.pub, rai::genesis_amount - 100, rai::test_genesis_key.prv, rai::test_genesis_key.pub, 0));
{
auto transaction (node1.store.tx_begin (true));
ASSERT_EQ (rai::process_result::progress, node1.ledger.process (transaction, *send1).code);
}
auto node_l (system.nodes[0]);
node1.work_generate_blocking (*send1);
auto transaction (node1.store.tx_begin (true));
ASSERT_EQ (rai::process_result::progress, node1.ledger.process (transaction, *send1).code);
node1.active.start (send1);
auto votes1 (node1.active.roots.find (send1->root ())->election);
auto vote1 (std::make_shared<rai::vote> (rai::test_genesis_key.pub, rai::test_genesis_key.prv, 1, send1));
@ -849,7 +845,6 @@ TEST (votes, add_two)
ASSERT_EQ (send1->hash (), votes1->last_votes[rai::test_genesis_key.pub].hash);
ASSERT_NE (votes1->last_votes.end (), votes1->last_votes.find (key2.pub));
ASSERT_EQ (send2->hash (), votes1->last_votes[key2.pub].hash);
auto transaction (system.nodes[0]->store.tx_begin ());
auto winner (*votes1->tally (transaction).begin ());
ASSERT_EQ (*send1, *winner.second);
}
@ -862,11 +857,9 @@ TEST (votes, add_existing)
rai::genesis genesis;
rai::keypair key1;
auto send1 (std::make_shared<rai::send_block> (genesis.hash (), key1.pub, rai::genesis_amount - rai::Gxrb_ratio, rai::test_genesis_key.prv, rai::test_genesis_key.pub, 0));
{
auto transaction (node1.store.tx_begin (true));
ASSERT_EQ (rai::process_result::progress, node1.ledger.process (transaction, *send1).code);
}
auto node_l (system.nodes[0]);
node1.work_generate_blocking (*send1);
auto transaction (node1.store.tx_begin (true));
ASSERT_EQ (rai::process_result::progress, node1.ledger.process (transaction, *send1).code);
node1.active.start (send1);
auto votes1 (node1.active.roots.find (send1->root ())->election);
auto vote1 (std::make_shared<rai::vote> (rai::test_genesis_key.pub, rai::test_genesis_key.prv, 1, send1));
@ -888,7 +881,6 @@ TEST (votes, add_existing)
ASSERT_EQ (2, votes1->last_votes.size ());
ASSERT_NE (votes1->last_votes.end (), votes1->last_votes.find (rai::test_genesis_key.pub));
ASSERT_EQ (send2->hash (), votes1->last_votes[rai::test_genesis_key.pub].hash);
auto transaction (system.nodes[0]->store.tx_begin ());
auto winner (*votes1->tally (transaction).begin ());
ASSERT_EQ (*send2, *winner.second);
}
@ -901,9 +893,9 @@ TEST (votes, add_old)
rai::genesis genesis;
rai::keypair key1;
auto send1 (std::make_shared<rai::send_block> (genesis.hash (), key1.pub, 0, rai::test_genesis_key.prv, rai::test_genesis_key.pub, 0));
node1.work_generate_blocking (*send1);
auto transaction (node1.store.tx_begin (true));
ASSERT_EQ (rai::process_result::progress, node1.ledger.process (transaction, *send1).code);
auto node_l (system.nodes[0]);
node1.active.start (send1);
auto votes1 (node1.active.roots.find (send1->root ())->election);
auto vote1 (std::make_shared<rai::vote> (rai::test_genesis_key.pub, rai::test_genesis_key.prv, 2, send1));
@ -932,13 +924,12 @@ TEST (votes, add_old_different_account)
rai::genesis genesis;
rai::keypair key1;
auto send1 (std::make_shared<rai::send_block> (genesis.hash (), key1.pub, 0, rai::test_genesis_key.prv, rai::test_genesis_key.pub, 0));
node1.work_generate_blocking (*send1);
auto send2 (std::make_shared<rai::send_block> (send1->hash (), key1.pub, 0, rai::test_genesis_key.prv, rai::test_genesis_key.pub, 0));
{
auto transaction (node1.store.tx_begin (true));
ASSERT_EQ (rai::process_result::progress, node1.ledger.process (transaction, *send1).code);
ASSERT_EQ (rai::process_result::progress, node1.ledger.process (transaction, *send2).code);
}
auto node_l (system.nodes[0]);
node1.work_generate_blocking (*send2);
auto transaction (node1.store.tx_begin (true));
ASSERT_EQ (rai::process_result::progress, node1.ledger.process (transaction, *send1).code);
ASSERT_EQ (rai::process_result::progress, node1.ledger.process (transaction, *send2).code);
node1.active.start (send1);
node1.active.start (send2);
auto votes1 (node1.active.roots.find (send1->root ())->election);
@ -946,7 +937,6 @@ TEST (votes, add_old_different_account)
ASSERT_EQ (1, votes1->last_votes.size ());
ASSERT_EQ (1, votes2->last_votes.size ());
auto vote1 (std::make_shared<rai::vote> (rai::test_genesis_key.pub, rai::test_genesis_key.prv, 2, send1));
auto transaction (system.nodes[0]->store.tx_begin ());
std::unique_lock<std::mutex> lock (node1.active.mutex);
auto vote_result1 (node1.vote_processor.vote_blocking (transaction, vote1, node1.network.endpoint ()));
lock.unlock ();
@ -978,9 +968,9 @@ TEST (votes, add_cooldown)
rai::genesis genesis;
rai::keypair key1;
auto send1 (std::make_shared<rai::send_block> (genesis.hash (), key1.pub, 0, rai::test_genesis_key.prv, rai::test_genesis_key.pub, 0));
node1.work_generate_blocking (*send1);
auto transaction (node1.store.tx_begin (true));
ASSERT_EQ (rai::process_result::progress, node1.ledger.process (transaction, *send1).code);
auto node_l (system.nodes[0]);
node1.active.start (send1);
auto votes1 (node1.active.roots.find (send1->root ())->election);
auto vote1 (std::make_shared<rai::vote> (rai::test_genesis_key.pub, rai::test_genesis_key.prv, 1, send1));
@ -989,6 +979,7 @@ TEST (votes, add_cooldown)
lock.unlock ();
rai::keypair key2;
auto send2 (std::make_shared<rai::send_block> (genesis.hash (), key2.pub, 0, rai::test_genesis_key.prv, rai::test_genesis_key.pub, 0));
node1.work_generate_blocking (*send2);
auto vote2 (std::make_shared<rai::vote> (rai::test_genesis_key.pub, rai::test_genesis_key.prv, 2, send2));
lock.lock ();
node1.vote_processor.vote_blocking (transaction, vote2, node1.network.endpoint ());

View file

@ -1420,6 +1420,7 @@ rai::process_return rai::block_processor::process_receive_one (rai::transaction
BOOST_LOG (node.log) << boost::str (boost::format ("Old for: %1%") % block_a->hash ().to_string ());
}
queue_unchecked (transaction_a, hash);
node.active.update_difficulty (*block_a);
break;
}
case rai::process_result::bad_signature:
@ -1925,10 +1926,8 @@ void rai::network::confirm_send (rai::confirm_ack const & confirm_a, std::shared
void rai::node::process_active (std::shared_ptr<rai::block> incoming)
{
if (!block_arrival.add (incoming->hash ()))
{
block_processor.add (incoming, std::chrono::steady_clock::now ());
}
block_arrival.add (incoming->hash ());
block_processor.add (incoming, std::chrono::steady_clock::now ());
}
rai::process_return rai::node::process (rai::block const & block_a)
@ -3119,7 +3118,7 @@ void rai::active_transactions::announce_votes (std::unique_lock<std::mutex> & lo
std::deque<std::pair<std::shared_ptr<rai::block>, std::shared_ptr<std::vector<rai::peer_information>>>> confirm_req_bundle;
auto roots_size (roots.size ());
for (auto i (roots.begin ()), n (roots.end ()); i != n; ++i)
for (auto i (roots.get<1> ().begin ()), n (roots.get<1> ().end ()); i != n; ++i)
{
lock_a.unlock ();
auto election_l (i->election);
@ -3310,7 +3309,10 @@ bool rai::active_transactions::add (std::shared_ptr<rai::block> block_a, std::fu
if (existing == roots.end ())
{
auto election (std::make_shared<rai::election> (node, block_a, confirmation_action_a));
roots.insert (rai::conflict_info{ root, election });
uint64_t difficulty (0);
auto error (rai::work_validate (*block_a, &difficulty));
release_assert (!error);
roots.insert (rai::conflict_info{ root, difficulty, election });
blocks.insert (std::make_pair (block_a->hash (), election));
}
error = existing != roots.end ();
@ -3368,6 +3370,21 @@ bool rai::active_transactions::active (rai::block const & block_a)
return roots.find (block_a.root ()) != roots.end ();
}
void rai::active_transactions::update_difficulty (rai::block const & block_a)
{
std::lock_guard<std::mutex> lock (mutex);
auto existing (roots.find (block_a.root ()));
if (existing != roots.end ())
{
uint64_t difficulty;
auto error (rai::work_validate (block_a, &difficulty));
assert (!error);
roots.modify (existing, [difficulty](rai::conflict_info & info_a) {
info_a.difficulty = difficulty;
});
}
}
// List of active blocks in elections
std::deque<std::shared_ptr<rai::block>> rai::active_transactions::list_blocks (bool single_lock)
{

View file

@ -77,6 +77,7 @@ class conflict_info
{
public:
rai::block_hash root;
uint64_t difficulty;
std::shared_ptr<rai::election> election;
};
// Core class for determining consensus
@ -94,6 +95,7 @@ public:
bool vote (std::shared_ptr<rai::vote>, bool = false);
// Is the root of this block in the roots container
bool active (rai::block const &);
void update_difficulty (rai::block const &);
std::deque<std::shared_ptr<rai::block>> list_blocks (bool = false);
void erase (rai::block const &);
void stop ();
@ -101,7 +103,11 @@ public:
boost::multi_index_container<
rai::conflict_info,
boost::multi_index::indexed_by<
boost::multi_index::hashed_unique<boost::multi_index::member<rai::conflict_info, rai::block_hash, &rai::conflict_info::root>>>>
boost::multi_index::hashed_unique<
boost::multi_index::member<rai::conflict_info, rai::block_hash, &rai::conflict_info::root>>,
boost::multi_index::ordered_non_unique<
boost::multi_index::member<rai::conflict_info, uint64_t, &rai::conflict_info::difficulty>,
std::greater<uint64_t>>>>
roots;
std::unordered_map<rai::block_hash, std::shared_ptr<rai::election>> blocks;
std::deque<rai::election_status> confirmed;