Skip to content

Commit

Permalink
This changes the signature of active_transactions::start to match STL…
Browse files Browse the repository at this point in the history
… container ::insert signatures by returning a pointer to the newly created election and also a bool whether the election creation took place.

This allows the call site to retrieve the election that was inserted and determine if it was the initiator of the election creation.
Also updated tests that were taking extra steps to retrieve the newly created election.
  • Loading branch information
clemahieu committed Feb 11, 2020
1 parent f28580d commit a2fcd08
Show file tree
Hide file tree
Showing 6 changed files with 124 additions and 147 deletions.
29 changes: 11 additions & 18 deletions nano/core_test/conflicts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,12 @@ TEST (conflicts, start_stop)
node1.work_generate_blocking (*send1);
ASSERT_EQ (nano::process_result::progress, node1.process (*send1).code);
ASSERT_EQ (0, node1.active.size ());
node1.active.start (send1);
auto election1 = node1.active.start (send1);
ASSERT_EQ (1, node1.active.size ());
{
nano::lock_guard<std::mutex> guard (node1.active.mutex);
auto existing1 (node1.active.roots.find (send1->qualified_root ()));
ASSERT_NE (node1.active.roots.end (), existing1);
auto votes1 (existing1->election);
ASSERT_NE (nullptr, votes1);
ASSERT_EQ (1, votes1->last_votes.size ());
ASSERT_NE (nullptr, election1.first);
ASSERT_EQ (1, election1.first->last_votes.size ());
}
}

Expand All @@ -42,17 +39,16 @@ TEST (conflicts, add_existing)
node1.active.start (send1);
nano::keypair key2;
auto send2 (std::make_shared<nano::send_block> (genesis.hash (), key2.pub, 0, nano::test_genesis_key.prv, nano::test_genesis_key.pub, 0));
node1.active.start (send2);
auto election1 = node1.active.start (send2);
ASSERT_EQ (1, node1.active.size ());
auto vote1 (std::make_shared<nano::vote> (key2.pub, key2.prv, 0, send2));
node1.active.vote (vote1);
ASSERT_EQ (1, node1.active.size ());
{
nano::lock_guard<std::mutex> guard (node1.active.mutex);
auto votes1 (node1.active.roots.find (send2->qualified_root ())->election);
ASSERT_NE (nullptr, votes1);
ASSERT_EQ (2, votes1->last_votes.size ());
ASSERT_NE (votes1->last_votes.end (), votes1->last_votes.find (key2.pub));
ASSERT_NE (nullptr, election1.first);
ASSERT_EQ (2, election1.first->last_votes.size ());
ASSERT_NE (election1.first->last_votes.end (), election1.first->last_votes.find (key2.pub));
}
}

Expand Down Expand Up @@ -208,18 +204,15 @@ TEST (conflicts, dependency)
ASSERT_EQ (nano::process_result::progress, node1->process (*send1).code);
ASSERT_EQ (nano::process_result::progress, node1->process (*state_open1).code);
ASSERT_EQ (0, node1->active.size ());
node1->active.start (send1);
auto election1 = node1->active.start (send1);
node1->active.start (state_open1);
ASSERT_EQ (2, node1->active.size ());
// Check dependency for send block
{
nano::lock_guard<std::mutex> guard (node1->active.mutex);
auto existing1 (node1->active.roots.find (send1->qualified_root ()));
ASSERT_NE (node1->active.roots.end (), existing1);
auto election1 (existing1->election);
ASSERT_NE (nullptr, election1);
ASSERT_EQ (1, election1->dependent_blocks.size ());
ASSERT_NE (election1->dependent_blocks.end (), election1->dependent_blocks.find (state_open1->hash ()));
ASSERT_NE (nullptr, election1.first);
ASSERT_EQ (1, election1.first->dependent_blocks.size ());
ASSERT_NE (election1.first->dependent_blocks.end (), election1.first->dependent_blocks.find (state_open1->hash ()));
}
}

Expand Down
148 changes: 65 additions & 83 deletions nano/core_test/ledger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -738,11 +738,10 @@ TEST (votes, check_signature)
auto transaction (node1.store.tx_begin_write ());
ASSERT_EQ (nano::process_result::progress, node1.ledger.process (transaction, *send1).code);
}
node1.active.start (send1);
auto election1 = node1.active.start (send1);
{
nano::lock_guard<std::mutex> lock (node1.active.mutex);
auto votes1 (node1.active.roots.find (send1->qualified_root ())->election);
ASSERT_EQ (1, votes1->last_votes.size ());
ASSERT_EQ (1, election1.first->last_votes.size ());
}
auto vote1 (std::make_shared<nano::vote> (nano::test_genesis_key.pub, nano::test_genesis_key.prv, 1, send1));
vote1->signature.bytes[0] ^= 1;
Expand All @@ -762,21 +761,20 @@ TEST (votes, add_one)
node1.work_generate_blocking (*send1);
auto transaction (node1.store.tx_begin_write ());
ASSERT_EQ (nano::process_result::progress, node1.ledger.process (transaction, *send1).code);
node1.active.start (send1);
auto election1 = node1.active.start (send1);
nano::unique_lock<std::mutex> lock (node1.active.mutex);
auto votes1 (node1.active.roots.find (send1->qualified_root ())->election);
ASSERT_EQ (1, votes1->last_votes.size ());
ASSERT_EQ (1, election1.first->last_votes.size ());
lock.unlock ();
auto vote1 (std::make_shared<nano::vote> (nano::test_genesis_key.pub, nano::test_genesis_key.prv, 1, send1));
ASSERT_EQ (nano::vote_code::vote, node1.active.vote (vote1));
auto vote2 (std::make_shared<nano::vote> (nano::test_genesis_key.pub, nano::test_genesis_key.prv, 2, send1));
ASSERT_EQ (nano::vote_code::indeterminate, node1.active.vote (vote2));
lock.lock ();
ASSERT_EQ (2, votes1->last_votes.size ());
auto existing1 (votes1->last_votes.find (nano::test_genesis_key.pub));
ASSERT_NE (votes1->last_votes.end (), existing1);
ASSERT_EQ (2, election1.first->last_votes.size ());
auto existing1 (election1.first->last_votes.find (nano::test_genesis_key.pub));
ASSERT_NE (election1.first->last_votes.end (), existing1);
ASSERT_EQ (send1->hash (), existing1->second.hash);
auto winner (*votes1->tally ().begin ());
auto winner (*election1.first->tally ().begin ());
ASSERT_EQ (*send1, *winner.second);
ASSERT_EQ (nano::genesis_amount - 100, winner.first);
}
Expand All @@ -791,9 +789,8 @@ TEST (votes, add_two)
node1.work_generate_blocking (*send1);
auto transaction (node1.store.tx_begin_write ());
ASSERT_EQ (nano::process_result::progress, node1.ledger.process (transaction, *send1).code);
node1.active.start (send1);
auto election1 = node1.active.start (send1);
nano::unique_lock<std::mutex> lock (node1.active.mutex);
auto votes1 (node1.active.roots.find (send1->qualified_root ())->election);
lock.unlock ();
nano::keypair key2;
auto send2 (std::make_shared<nano::send_block> (genesis.hash (), key2.pub, 0, nano::test_genesis_key.prv, nano::test_genesis_key.pub, 0));
Expand All @@ -802,12 +799,12 @@ TEST (votes, add_two)
auto vote1 (std::make_shared<nano::vote> (nano::test_genesis_key.pub, nano::test_genesis_key.prv, 1, send1));
ASSERT_EQ (nano::vote_code::vote, node1.active.vote (vote1));
lock.lock ();
ASSERT_EQ (3, votes1->last_votes.size ());
ASSERT_NE (votes1->last_votes.end (), votes1->last_votes.find (nano::test_genesis_key.pub));
ASSERT_EQ (send1->hash (), votes1->last_votes[nano::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 winner (*votes1->tally ().begin ());
ASSERT_EQ (3, election1.first->last_votes.size ());
ASSERT_NE (election1.first->last_votes.end (), election1.first->last_votes.find (nano::test_genesis_key.pub));
ASSERT_EQ (send1->hash (), election1.first->last_votes[nano::test_genesis_key.pub].hash);
ASSERT_NE (election1.first->last_votes.end (), election1.first->last_votes.find (key2.pub));
ASSERT_EQ (send2->hash (), election1.first->last_votes[key2.pub].hash);
auto winner (*election1.first->tally ().begin ());
ASSERT_EQ (*send1, *winner.second);
}

Expand All @@ -827,37 +824,36 @@ TEST (votes, add_existing)
auto transaction (node1.store.tx_begin_write ());
ASSERT_EQ (nano::process_result::progress, node1.ledger.process (transaction, *send1).code);
}
node1.active.start (send1);
auto election1 = node1.active.start (send1);
auto vote1 (std::make_shared<nano::vote> (nano::test_genesis_key.pub, nano::test_genesis_key.prv, 1, send1));
ASSERT_EQ (nano::vote_code::vote, node1.active.vote (vote1));
// Block is already processed from vote
ASSERT_TRUE (node1.active.publish (send1));
nano::unique_lock<std::mutex> lock (node1.active.mutex);
auto votes1 (node1.active.roots.find (send1->qualified_root ())->election);
ASSERT_EQ (1, votes1->last_votes[nano::test_genesis_key.pub].sequence);
ASSERT_EQ (1, election1.first->last_votes[nano::test_genesis_key.pub].sequence);
nano::keypair key2;
auto send2 (std::make_shared<nano::send_block> (genesis.hash (), key2.pub, nano::genesis_amount - nano::Gxrb_ratio, nano::test_genesis_key.prv, nano::test_genesis_key.pub, 0));
node1.work_generate_blocking (*send2);
auto vote2 (std::make_shared<nano::vote> (nano::test_genesis_key.pub, nano::test_genesis_key.prv, 2, send2));
// Pretend we've waited the timeout
votes1->last_votes[nano::test_genesis_key.pub].time = std::chrono::steady_clock::now () - std::chrono::seconds (20);
election1.first->last_votes[nano::test_genesis_key.pub].time = std::chrono::steady_clock::now () - std::chrono::seconds (20);
lock.unlock ();
ASSERT_EQ (nano::vote_code::vote, node1.active.vote (vote2));
ASSERT_FALSE (node1.active.publish (send2));
lock.lock ();
ASSERT_EQ (2, votes1->last_votes[nano::test_genesis_key.pub].sequence);
ASSERT_EQ (2, election1.first->last_votes[nano::test_genesis_key.pub].sequence);
// Also resend the old vote, and see if we respect the sequence number
votes1->last_votes[nano::test_genesis_key.pub].time = std::chrono::steady_clock::now () - std::chrono::seconds (20);
election1.first->last_votes[nano::test_genesis_key.pub].time = std::chrono::steady_clock::now () - std::chrono::seconds (20);
lock.unlock ();
ASSERT_EQ (nano::vote_code::replay, node1.active.vote (vote1));
lock.lock ();
ASSERT_EQ (2, votes1->last_votes[nano::test_genesis_key.pub].sequence);
ASSERT_EQ (2, votes1->last_votes.size ());
ASSERT_NE (votes1->last_votes.end (), votes1->last_votes.find (nano::test_genesis_key.pub));
ASSERT_EQ (send2->hash (), votes1->last_votes[nano::test_genesis_key.pub].hash);
ASSERT_EQ (2, election1.first->last_votes[nano::test_genesis_key.pub].sequence);
ASSERT_EQ (2, election1.first->last_votes.size ());
ASSERT_NE (election1.first->last_votes.end (), election1.first->last_votes.find (nano::test_genesis_key.pub));
ASSERT_EQ (send2->hash (), election1.first->last_votes[nano::test_genesis_key.pub].hash);
{
auto transaction (node1.store.tx_begin_read ());
auto winner (*votes1->tally ().begin ());
auto winner (*election1.first->tally ().begin ());
ASSERT_EQ (*send2, *winner.second);
}
}
Expand All @@ -873,25 +869,24 @@ TEST (votes, add_old)
node1.work_generate_blocking (*send1);
auto transaction (node1.store.tx_begin_write ());
ASSERT_EQ (nano::process_result::progress, node1.ledger.process (transaction, *send1).code);
node1.active.start (send1);
auto election1 = node1.active.start (send1);
auto vote1 (std::make_shared<nano::vote> (nano::test_genesis_key.pub, nano::test_genesis_key.prv, 2, send1));
std::shared_ptr<nano::election> votes1;
{
nano::lock_guard<std::mutex> lock (node1.active.mutex);
votes1 = node1.active.roots.find (send1->qualified_root ())->election;
}
auto channel (std::make_shared<nano::transport::channel_udp> (node1.network.udp_channels, node1.network.endpoint (), node1.network_params.protocol.protocol_version));
node1.vote_processor.vote_blocking (vote1, channel);
nano::keypair key2;
auto send2 (std::make_shared<nano::send_block> (genesis.hash (), key2.pub, 0, nano::test_genesis_key.prv, nano::test_genesis_key.pub, 0));
node1.work_generate_blocking (*send2);
auto vote2 (std::make_shared<nano::vote> (nano::test_genesis_key.pub, nano::test_genesis_key.prv, 1, send2));
votes1->last_votes[nano::test_genesis_key.pub].time = std::chrono::steady_clock::now () - std::chrono::seconds (20);
{
nano::lock_guard<std::mutex> lock (node1.active.mutex);
election1.first->last_votes[nano::test_genesis_key.pub].time = std::chrono::steady_clock::now () - std::chrono::seconds (20);
}
node1.vote_processor.vote_blocking (vote2, channel);
ASSERT_EQ (2, votes1->last_votes_size ());
ASSERT_NE (votes1->last_votes.end (), votes1->last_votes.find (nano::test_genesis_key.pub));
ASSERT_EQ (send1->hash (), votes1->last_votes[nano::test_genesis_key.pub].hash);
auto winner (*votes1->tally ().begin ());
ASSERT_EQ (2, election1.first->last_votes_size ());
nano::lock_guard<std::mutex> lock (node1.active.mutex);
ASSERT_NE (election1.first->last_votes.end (), election1.first->last_votes.find (nano::test_genesis_key.pub));
ASSERT_EQ (send1->hash (), election1.first->last_votes[nano::test_genesis_key.pub].hash);
auto winner (*election1.first->tally ().begin ());
ASSERT_EQ (*send1, *winner.second);
}

Expand All @@ -909,35 +904,29 @@ TEST (votes, add_old_different_account)
auto transaction (node1.store.tx_begin_write ());
ASSERT_EQ (nano::process_result::progress, node1.ledger.process (transaction, *send1).code);
ASSERT_EQ (nano::process_result::progress, node1.ledger.process (transaction, *send2).code);
node1.active.start (send1);
node1.active.start (send2);
std::shared_ptr<nano::election> votes1;
std::shared_ptr<nano::election> votes2;
{
nano::unique_lock<std::mutex> lock (node1.active.mutex);
votes1 = node1.active.roots.find (send1->qualified_root ())->election;
votes2 = node1.active.roots.find (send2->qualified_root ())->election;
}
ASSERT_EQ (1, votes1->last_votes_size ());
ASSERT_EQ (1, votes2->last_votes_size ());
auto election1 = node1.active.start (send1);
auto election2 = node1.active.start (send2);
ASSERT_EQ (1, election1.first->last_votes_size ());
ASSERT_EQ (1, election2.first->last_votes_size ());
auto vote1 (std::make_shared<nano::vote> (nano::test_genesis_key.pub, nano::test_genesis_key.prv, 2, send1));
auto channel (std::make_shared<nano::transport::channel_udp> (node1.network.udp_channels, node1.network.endpoint (), node1.network_params.protocol.protocol_version));
auto vote_result1 (node1.vote_processor.vote_blocking (vote1, channel));
ASSERT_EQ (nano::vote_code::vote, vote_result1);
ASSERT_EQ (2, votes1->last_votes.size ());
ASSERT_EQ (1, votes2->last_votes.size ());
ASSERT_EQ (2, election1.first->last_votes_size ());
ASSERT_EQ (1, election2.first->last_votes_size ());
auto vote2 (std::make_shared<nano::vote> (nano::test_genesis_key.pub, nano::test_genesis_key.prv, 1, send2));
auto vote_result2 (node1.vote_processor.vote_blocking (vote2, channel));
ASSERT_EQ (nano::vote_code::vote, vote_result2);
ASSERT_EQ (2, votes1->last_votes.size ());
ASSERT_EQ (2, votes2->last_votes.size ());
ASSERT_NE (votes1->last_votes.end (), votes1->last_votes.find (nano::test_genesis_key.pub));
ASSERT_NE (votes2->last_votes.end (), votes2->last_votes.find (nano::test_genesis_key.pub));
ASSERT_EQ (send1->hash (), votes1->last_votes[nano::test_genesis_key.pub].hash);
ASSERT_EQ (send2->hash (), votes2->last_votes[nano::test_genesis_key.pub].hash);
auto winner1 (*votes1->tally ().begin ());
ASSERT_EQ (2, election1.first->last_votes_size ());
ASSERT_EQ (2, election2.first->last_votes_size ());
nano::unique_lock<std::mutex> lock (node1.active.mutex);
ASSERT_NE (election1.first->last_votes.end (), election1.first->last_votes.find (nano::test_genesis_key.pub));
ASSERT_NE (election2.first->last_votes.end (), election2.first->last_votes.find (nano::test_genesis_key.pub));
ASSERT_EQ (send1->hash (), election1.first->last_votes[nano::test_genesis_key.pub].hash);
ASSERT_EQ (send2->hash (), election2.first->last_votes[nano::test_genesis_key.pub].hash);
auto winner1 (*election1.first->tally ().begin ());
ASSERT_EQ (*send1, *winner1.second);
auto winner2 (*votes2->tally ().begin ());
auto winner2 (*election2.first->tally ().begin ());
ASSERT_EQ (*send2, *winner2.second);
}

Expand All @@ -952,12 +941,7 @@ TEST (votes, add_cooldown)
node1.work_generate_blocking (*send1);
auto transaction (node1.store.tx_begin_write ());
ASSERT_EQ (nano::process_result::progress, node1.ledger.process (transaction, *send1).code);
node1.active.start (send1);
std::shared_ptr<nano::election> votes1;
{
nano::unique_lock<std::mutex> lock (node1.active.mutex);
votes1 = node1.active.roots.find (send1->qualified_root ())->election;
}
auto election1 = node1.active.start (send1);
auto vote1 (std::make_shared<nano::vote> (nano::test_genesis_key.pub, nano::test_genesis_key.prv, 1, send1));
auto channel (std::make_shared<nano::transport::channel_udp> (node1.network.udp_channels, node1.network.endpoint (), node1.network_params.protocol.protocol_version));
node1.vote_processor.vote_blocking (vote1, channel);
Expand All @@ -966,10 +950,11 @@ TEST (votes, add_cooldown)
node1.work_generate_blocking (*send2);
auto vote2 (std::make_shared<nano::vote> (nano::test_genesis_key.pub, nano::test_genesis_key.prv, 2, send2));
node1.vote_processor.vote_blocking (vote2, channel);
ASSERT_EQ (2, votes1->last_votes.size ());
ASSERT_NE (votes1->last_votes.end (), votes1->last_votes.find (nano::test_genesis_key.pub));
ASSERT_EQ (send1->hash (), votes1->last_votes[nano::test_genesis_key.pub].hash);
auto winner (*votes1->tally ().begin ());
nano::unique_lock<std::mutex> lock (node1.active.mutex);
ASSERT_EQ (2, election1.first->last_votes.size ());
ASSERT_NE (election1.first->last_votes.end (), election1.first->last_votes.find (nano::test_genesis_key.pub));
ASSERT_EQ (send1->hash (), election1.first->last_votes[nano::test_genesis_key.pub].hash);
auto winner (*election1.first->tally ().begin ());
ASSERT_EQ (*send1, *winner.second);
}

Expand Down Expand Up @@ -2659,18 +2644,15 @@ TEST (ledger, block_hash_account_conflict)
ASSERT_EQ (nano::process_result::progress, node1.ledger.process (transaction, *receive1).code);
ASSERT_EQ (nano::process_result::progress, node1.ledger.process (transaction, *send2).code);
ASSERT_EQ (nano::process_result::progress, node1.ledger.process (transaction, *open_epoch1).code);
node1.active.start (send1);
node1.active.start (receive1);
node1.active.start (send2);
node1.active.start (open_epoch1);
auto votes1 (node1.active.roots.find (send1->qualified_root ())->election);
auto votes2 (node1.active.roots.find (receive1->qualified_root ())->election);
auto votes3 (node1.active.roots.find (send2->qualified_root ())->election);
auto votes4 (node1.active.roots.find (open_epoch1->qualified_root ())->election);
auto winner1 (*votes1->tally ().begin ());
auto winner2 (*votes2->tally ().begin ());
auto winner3 (*votes3->tally ().begin ());
auto winner4 (*votes4->tally ().begin ());
auto election1 = node1.active.start (send1);
auto election2 = node1.active.start (receive1);
auto election3 = node1.active.start (send2);
auto election4 = node1.active.start (open_epoch1);
nano::lock_guard<std::mutex> lock (node1.active.mutex);
auto winner1 (*election1.first->tally ().begin ());
auto winner2 (*election2.first->tally ().begin ());
auto winner3 (*election3.first->tally ().begin ());
auto winner4 (*election4.first->tally ().begin ());
ASSERT_EQ (*send1, *winner1.second);
ASSERT_EQ (*receive1, *winner2.second);
ASSERT_EQ (*send2, *winner3.second);
Expand Down
14 changes: 4 additions & 10 deletions nano/core_test/node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1827,22 +1827,16 @@ TEST (node, rep_self_vote)
node0->work_generate_blocking (*block0);
ASSERT_EQ (nano::process_result::progress, node0->process (*block0).code);
auto & active (node0->active);
active.start (block0);
std::shared_ptr<nano::election> election;
{
nano::unique_lock<std::mutex> lock (active.mutex);
auto existing (active.roots.find (block0->qualified_root ()));
ASSERT_NE (active.roots.end (), existing);
election = existing->election;
}
auto election1 = active.start (block0);
node0->block_processor.generator.add (block0->hash ());
system.deadline_set (1s);
// Wait until representatives are activated & make vote
while (election->last_votes_size () != 3)
while (election1.first->last_votes_size () != 3)
{
ASSERT_NO_ERROR (system.poll ());
}
auto & rep_votes (election->last_votes);
nano::unique_lock<std::mutex> lock (active.mutex);
auto & rep_votes (election1.first->last_votes);
ASSERT_NE (rep_votes.end (), rep_votes.find (nano::test_genesis_key.pub));
ASSERT_NE (rep_votes.end (), rep_votes.find (rep_big.pub));
}
Expand Down
Loading

0 comments on commit a2fcd08

Please sign in to comment.