Fix reported by TSAN issues (#1739)
* prevent reported possible deadlocks & segfaults * improve mutexes in core_test & slow_test
This commit is contained in:
parent
13f5ab9ba0
commit
ba597fff81
23 changed files with 301 additions and 202 deletions
|
@ -197,7 +197,7 @@ ge25519_is_neutral_vartime(const ge25519 *p) {
|
|||
curve25519_contract(point_buffer[0], p->x);
|
||||
curve25519_contract(point_buffer[1], p->y);
|
||||
curve25519_contract(point_buffer[2], p->z);
|
||||
memcpy(batch_point_buffer[1], point_buffer[1], 32);
|
||||
// memcpy(batch_point_buffer[1], point_buffer[1], 32); // remove used in testing batch_point_buffer to fix tsan warnings
|
||||
return (memcmp(point_buffer[0], zero, 32) == 0) && (memcmp(point_buffer[1], point_buffer[2], 32) == 0);
|
||||
}
|
||||
|
||||
|
|
|
@ -10,15 +10,18 @@ TEST (conflicts, start_stop)
|
|||
auto send1 (std::make_shared<nano::send_block> (genesis.hash (), key1.pub, 0, nano::test_genesis_key.prv, nano::test_genesis_key.pub, 0));
|
||||
node1.work_generate_blocking (*send1);
|
||||
ASSERT_EQ (nano::process_result::progress, node1.process (*send1).code);
|
||||
ASSERT_EQ (0, node1.active.roots.size ());
|
||||
ASSERT_EQ (0, node1.active.size ());
|
||||
node1.active.start (send1);
|
||||
ASSERT_EQ (1, node1.active.roots.size ());
|
||||
ASSERT_EQ (1, node1.active.size ());
|
||||
auto root1 (send1->root ());
|
||||
auto existing1 (node1.active.roots.find (nano::uint512_union (send1->previous (), root1)));
|
||||
ASSERT_NE (node1.active.roots.end (), existing1);
|
||||
auto votes1 (existing1->election);
|
||||
ASSERT_NE (nullptr, votes1);
|
||||
ASSERT_EQ (1, votes1->last_votes.size ());
|
||||
{
|
||||
std::lock_guard<std::mutex> guard (node1.active.mutex);
|
||||
auto existing1 (node1.active.roots.find (nano::uint512_union (send1->previous (), root1)));
|
||||
ASSERT_NE (node1.active.roots.end (), existing1);
|
||||
auto votes1 (existing1->election);
|
||||
ASSERT_NE (nullptr, votes1);
|
||||
ASSERT_EQ (1, votes1->last_votes.size ());
|
||||
}
|
||||
}
|
||||
|
||||
TEST (conflicts, add_existing)
|
||||
|
@ -34,14 +37,17 @@ TEST (conflicts, add_existing)
|
|||
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);
|
||||
ASSERT_EQ (1, node1.active.roots.size ());
|
||||
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.roots.size ());
|
||||
auto votes1 (node1.active.roots.find (nano::uint512_union (send2->previous (), send2->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_EQ (1, node1.active.size ());
|
||||
{
|
||||
std::lock_guard<std::mutex> guard (node1.active.mutex);
|
||||
auto votes1 (node1.active.roots.find (nano::uint512_union (send2->previous (), send2->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));
|
||||
}
|
||||
}
|
||||
|
||||
TEST (conflicts, add_two)
|
||||
|
@ -59,7 +65,7 @@ TEST (conflicts, add_two)
|
|||
node1.work_generate_blocking (*send2);
|
||||
ASSERT_EQ (nano::process_result::progress, node1.process (*send2).code);
|
||||
node1.active.start (send2);
|
||||
ASSERT_EQ (2, node1.active.roots.size ());
|
||||
ASSERT_EQ (2, node1.active.size ());
|
||||
}
|
||||
|
||||
TEST (vote_uniquer, null)
|
||||
|
@ -159,17 +165,24 @@ TEST (conflicts, reprioritize)
|
|||
node1.work_generate_blocking (*send1);
|
||||
uint64_t difficulty1;
|
||||
nano::work_validate (*send1, &difficulty1);
|
||||
nano::send_block send1_copy (*send1);
|
||||
node1.process_active (send1);
|
||||
node1.block_processor.flush ();
|
||||
auto existing1 (node1.active.roots.find (nano::uint512_union (send1->previous (), send1->root ())));
|
||||
ASSERT_NE (node1.active.roots.end (), existing1);
|
||||
ASSERT_EQ (difficulty1, existing1->difficulty);
|
||||
node1.work_generate_blocking (*send1, difficulty1);
|
||||
{
|
||||
std::lock_guard<std::mutex> guard (node1.active.mutex);
|
||||
auto existing1 (node1.active.roots.find (nano::uint512_union (send1->previous (), send1->root ())));
|
||||
ASSERT_NE (node1.active.roots.end (), existing1);
|
||||
ASSERT_EQ (difficulty1, existing1->difficulty);
|
||||
}
|
||||
node1.work_generate_blocking (send1_copy, difficulty1);
|
||||
uint64_t difficulty2;
|
||||
nano::work_validate (*send1, &difficulty2);
|
||||
node1.process_active (send1);
|
||||
nano::work_validate (send1_copy, &difficulty2);
|
||||
node1.process_active (std::make_shared<nano::send_block> (send1_copy));
|
||||
node1.block_processor.flush ();
|
||||
auto existing2 (node1.active.roots.find (nano::uint512_union (send1->previous (), send1->root ())));
|
||||
ASSERT_NE (node1.active.roots.end (), existing2);
|
||||
ASSERT_EQ (difficulty2, existing2->difficulty);
|
||||
{
|
||||
std::lock_guard<std::mutex> guard (node1.active.mutex);
|
||||
auto existing2 (node1.active.roots.find (nano::uint512_union (send1->previous (), send1->root ())));
|
||||
ASSERT_NE (node1.active.roots.end (), existing2);
|
||||
ASSERT_EQ (difficulty2, existing2->difficulty);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,13 +20,19 @@ TEST (gap_cache, add_existing)
|
|||
auto block1 (std::make_shared<nano::send_block> (0, 1, 2, nano::keypair ().prv, 4, 5));
|
||||
auto transaction (system.nodes[0]->store.tx_begin (true));
|
||||
cache.add (transaction, block1->hash ());
|
||||
std::unique_lock<std::mutex> lock (cache.mutex);
|
||||
auto existing1 (cache.blocks.get<1> ().find (block1->hash ()));
|
||||
ASSERT_NE (cache.blocks.get<1> ().end (), existing1);
|
||||
auto arrival (existing1->arrival);
|
||||
lock.unlock ();
|
||||
system.deadline_set (20s);
|
||||
while (arrival == std::chrono::steady_clock::now ())
|
||||
;
|
||||
{
|
||||
ASSERT_NO_ERROR (system.poll ());
|
||||
}
|
||||
cache.add (transaction, block1->hash ());
|
||||
ASSERT_EQ (1, cache.blocks.size ());
|
||||
ASSERT_EQ (1, cache.size ());
|
||||
lock.lock ();
|
||||
auto existing2 (cache.blocks.get<1> ().find (block1->hash ()));
|
||||
ASSERT_NE (cache.blocks.get<1> ().end (), existing2);
|
||||
ASSERT_GT (existing2->arrival, arrival);
|
||||
|
@ -39,14 +45,20 @@ TEST (gap_cache, comparison)
|
|||
auto block1 (std::make_shared<nano::send_block> (1, 0, 2, nano::keypair ().prv, 4, 5));
|
||||
auto transaction (system.nodes[0]->store.tx_begin (true));
|
||||
cache.add (transaction, block1->hash ());
|
||||
std::unique_lock<std::mutex> lock (cache.mutex);
|
||||
auto existing1 (cache.blocks.get<1> ().find (block1->hash ()));
|
||||
ASSERT_NE (cache.blocks.get<1> ().end (), existing1);
|
||||
auto arrival (existing1->arrival);
|
||||
lock.unlock ();
|
||||
system.deadline_set (20s);
|
||||
while (std::chrono::steady_clock::now () == arrival)
|
||||
;
|
||||
{
|
||||
ASSERT_NO_ERROR (system.poll ());
|
||||
}
|
||||
auto block3 (std::make_shared<nano::send_block> (0, 42, 1, nano::keypair ().prv, 3, 4));
|
||||
cache.add (transaction, block3->hash ());
|
||||
ASSERT_EQ (2, cache.blocks.size ());
|
||||
ASSERT_EQ (2, cache.size ());
|
||||
lock.lock ();
|
||||
auto existing2 (cache.blocks.get<1> ().find (block3->hash ()));
|
||||
ASSERT_NE (cache.blocks.get<1> ().end (), existing2);
|
||||
ASSERT_GT (existing2->arrival, arrival);
|
||||
|
@ -92,16 +104,16 @@ TEST (gap_cache, two_dependencies)
|
|||
auto send1 (std::make_shared<nano::send_block> (genesis.hash (), key.pub, 1, nano::test_genesis_key.prv, nano::test_genesis_key.pub, system.work.generate (genesis.hash ())));
|
||||
auto send2 (std::make_shared<nano::send_block> (send1->hash (), key.pub, 0, nano::test_genesis_key.prv, nano::test_genesis_key.pub, system.work.generate (send1->hash ())));
|
||||
auto open (std::make_shared<nano::open_block> (send1->hash (), key.pub, key.pub, key.prv, key.pub, system.work.generate (key.pub)));
|
||||
ASSERT_EQ (0, system.nodes[0]->gap_cache.blocks.size ());
|
||||
ASSERT_EQ (0, system.nodes[0]->gap_cache.size ());
|
||||
system.nodes[0]->block_processor.add (send2, nano::seconds_since_epoch ());
|
||||
system.nodes[0]->block_processor.flush ();
|
||||
ASSERT_EQ (1, system.nodes[0]->gap_cache.blocks.size ());
|
||||
ASSERT_EQ (1, system.nodes[0]->gap_cache.size ());
|
||||
system.nodes[0]->block_processor.add (open, nano::seconds_since_epoch ());
|
||||
system.nodes[0]->block_processor.flush ();
|
||||
ASSERT_EQ (2, system.nodes[0]->gap_cache.blocks.size ());
|
||||
ASSERT_EQ (2, system.nodes[0]->gap_cache.size ());
|
||||
system.nodes[0]->block_processor.add (send1, nano::seconds_since_epoch ());
|
||||
system.nodes[0]->block_processor.flush ();
|
||||
ASSERT_EQ (0, system.nodes[0]->gap_cache.blocks.size ());
|
||||
ASSERT_EQ (0, system.nodes[0]->gap_cache.size ());
|
||||
auto transaction (system.nodes[0]->store.tx_begin ());
|
||||
ASSERT_TRUE (system.nodes[0]->store.block_exists (transaction, send1->hash ()));
|
||||
ASSERT_TRUE (system.nodes[0]->store.block_exists (transaction, send2->hash ()));
|
||||
|
|
|
@ -717,9 +717,9 @@ TEST (votes, check_signature)
|
|||
ASSERT_EQ (nano::process_result::progress, node1.ledger.process (transaction, *send1).code);
|
||||
auto node_l (system.nodes[0]);
|
||||
node1.active.start (send1);
|
||||
std::lock_guard<std::mutex> lock (node1.active.mutex);
|
||||
auto votes1 (node1.active.roots.find (nano::uint512_union (send1->previous (), send1->root ()))->election);
|
||||
ASSERT_EQ (1, votes1->last_votes.size ());
|
||||
std::unique_lock<std::mutex> lock (node1.active.mutex);
|
||||
auto vote1 (std::make_shared<nano::vote> (nano::test_genesis_key.pub, nano::test_genesis_key.prv, 1, send1));
|
||||
vote1->signature.bytes[0] ^= 1;
|
||||
ASSERT_EQ (nano::vote_code::invalid, node1.vote_processor.vote_blocking (transaction, vote1, nano::endpoint (boost::asio::ip::address_v6 (), 0)));
|
||||
|
@ -739,12 +739,15 @@ TEST (votes, add_one)
|
|||
auto transaction (node1.store.tx_begin (true));
|
||||
ASSERT_EQ (nano::process_result::progress, node1.ledger.process (transaction, *send1).code);
|
||||
node1.active.start (send1);
|
||||
std::unique_lock<std::mutex> lock (node1.active.mutex);
|
||||
auto votes1 (node1.active.roots.find (nano::uint512_union (send1->previous (), send1->root ()))->election);
|
||||
ASSERT_EQ (1, votes1->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_FALSE (node1.active.vote (vote1));
|
||||
auto vote2 (std::make_shared<nano::vote> (nano::test_genesis_key.pub, nano::test_genesis_key.prv, 2, send1));
|
||||
ASSERT_FALSE (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);
|
||||
|
@ -765,20 +768,23 @@ TEST (votes, add_two)
|
|||
auto transaction (node1.store.tx_begin (true));
|
||||
ASSERT_EQ (nano::process_result::progress, node1.ledger.process (transaction, *send1).code);
|
||||
node1.active.start (send1);
|
||||
auto votes1 (node1.active.roots.find (nano::uint512_union (send1->previous (), send1->root ()))->election);
|
||||
auto vote1 (std::make_shared<nano::vote> (nano::test_genesis_key.pub, nano::test_genesis_key.prv, 1, send1));
|
||||
ASSERT_FALSE (node1.active.vote (vote1));
|
||||
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));
|
||||
auto vote2 (std::make_shared<nano::vote> (key2.pub, key2.prv, 1, send2));
|
||||
ASSERT_FALSE (node1.active.vote (vote2));
|
||||
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 (transaction).begin ());
|
||||
ASSERT_EQ (*send1, *winner.second);
|
||||
{
|
||||
std::lock_guard<std::mutex> lock (node1.active.mutex);
|
||||
auto votes1 (node1.active.roots.find (nano::uint512_union (send1->previous (), send1->root ()))->election);
|
||||
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 (transaction).begin ());
|
||||
ASSERT_EQ (*send1, *winner.second);
|
||||
}
|
||||
}
|
||||
|
||||
// Higher sequence numbers change the vote
|
||||
|
@ -793,22 +799,27 @@ TEST (votes, add_existing)
|
|||
auto transaction (node1.store.tx_begin (true));
|
||||
ASSERT_EQ (nano::process_result::progress, node1.ledger.process (transaction, *send1).code);
|
||||
node1.active.start (send1);
|
||||
auto votes1 (node1.active.roots.find (nano::uint512_union (send1->previous (), send1->root ()))->election);
|
||||
auto vote1 (std::make_shared<nano::vote> (nano::test_genesis_key.pub, nano::test_genesis_key.prv, 1, send1));
|
||||
ASSERT_FALSE (node1.active.vote (vote1));
|
||||
ASSERT_FALSE (node1.active.publish (send1));
|
||||
std::unique_lock<std::mutex> lock (node1.active.mutex);
|
||||
auto votes1 (node1.active.roots.find (nano::uint512_union (send1->previous (), send1->root ()))->election);
|
||||
ASSERT_EQ (1, votes1->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));
|
||||
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);
|
||||
lock.unlock ();
|
||||
ASSERT_FALSE (node1.active.vote (vote2));
|
||||
ASSERT_FALSE (node1.active.publish (send2));
|
||||
lock.lock ();
|
||||
ASSERT_EQ (2, votes1->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);
|
||||
lock.unlock ();
|
||||
ASSERT_TRUE (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));
|
||||
|
@ -829,18 +840,15 @@ TEST (votes, add_old)
|
|||
auto transaction (node1.store.tx_begin (true));
|
||||
ASSERT_EQ (nano::process_result::progress, node1.ledger.process (transaction, *send1).code);
|
||||
node1.active.start (send1);
|
||||
auto votes1 (node1.active.roots.find (nano::uint512_union (send1->previous (), send1->root ()))->election);
|
||||
auto vote1 (std::make_shared<nano::vote> (nano::test_genesis_key.pub, nano::test_genesis_key.prv, 2, send1));
|
||||
std::unique_lock<std::mutex> lock (node1.active.mutex);
|
||||
std::lock_guard<std::mutex> lock (node1.active.mutex);
|
||||
auto votes1 (node1.active.roots.find (nano::uint512_union (send1->previous (), send1->root ()))->election);
|
||||
node1.vote_processor.vote_blocking (transaction, vote1, node1.network.endpoint ());
|
||||
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));
|
||||
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);
|
||||
lock.lock ();
|
||||
node1.vote_processor.vote_blocking (transaction, vote2, node1.network.endpoint ());
|
||||
lock.unlock ();
|
||||
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);
|
||||
|
@ -864,21 +872,18 @@ TEST (votes, add_old_different_account)
|
|||
ASSERT_EQ (nano::process_result::progress, node1.ledger.process (transaction, *send2).code);
|
||||
node1.active.start (send1);
|
||||
node1.active.start (send2);
|
||||
std::unique_lock<std::mutex> lock (node1.active.mutex);
|
||||
auto votes1 (node1.active.roots.find (nano::uint512_union (send1->previous (), send1->root ()))->election);
|
||||
auto votes2 (node1.active.roots.find (nano::uint512_union (send2->previous (), send2->root ()))->election);
|
||||
ASSERT_EQ (1, votes1->last_votes.size ());
|
||||
ASSERT_EQ (1, votes2->last_votes.size ());
|
||||
auto vote1 (std::make_shared<nano::vote> (nano::test_genesis_key.pub, nano::test_genesis_key.prv, 2, send1));
|
||||
std::unique_lock<std::mutex> lock (node1.active.mutex);
|
||||
auto vote_result1 (node1.vote_processor.vote_blocking (transaction, vote1, node1.network.endpoint ()));
|
||||
lock.unlock ();
|
||||
ASSERT_EQ (nano::vote_code::vote, vote_result1);
|
||||
ASSERT_EQ (2, votes1->last_votes.size ());
|
||||
ASSERT_EQ (1, votes2->last_votes.size ());
|
||||
lock.lock ();
|
||||
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 (transaction, vote2, node1.network.endpoint ()));
|
||||
lock.unlock ();
|
||||
ASSERT_EQ (nano::vote_code::vote, vote_result2);
|
||||
ASSERT_EQ (2, votes1->last_votes.size ());
|
||||
ASSERT_EQ (2, votes2->last_votes.size ());
|
||||
|
@ -904,18 +909,15 @@ TEST (votes, add_cooldown)
|
|||
auto transaction (node1.store.tx_begin (true));
|
||||
ASSERT_EQ (nano::process_result::progress, node1.ledger.process (transaction, *send1).code);
|
||||
node1.active.start (send1);
|
||||
std::unique_lock<std::mutex> lock (node1.active.mutex);
|
||||
auto votes1 (node1.active.roots.find (nano::uint512_union (send1->previous (), send1->root ()))->election);
|
||||
auto vote1 (std::make_shared<nano::vote> (nano::test_genesis_key.pub, nano::test_genesis_key.prv, 1, send1));
|
||||
std::unique_lock<std::mutex> lock (node1.active.mutex);
|
||||
node1.vote_processor.vote_blocking (transaction, vote1, node1.network.endpoint ());
|
||||
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));
|
||||
node1.work_generate_blocking (*send2);
|
||||
auto vote2 (std::make_shared<nano::vote> (nano::test_genesis_key.pub, nano::test_genesis_key.prv, 2, send2));
|
||||
lock.lock ();
|
||||
node1.vote_processor.vote_blocking (transaction, vote2, node1.network.endpoint ());
|
||||
lock.unlock ();
|
||||
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);
|
||||
|
@ -2495,7 +2497,7 @@ TEST (ledger, unchecked_epoch_invalid)
|
|||
auto transaction (node1.store.tx_begin ());
|
||||
ASSERT_FALSE (node1.store.block_exists (transaction, epoch1->hash ()));
|
||||
ASSERT_TRUE (node1.store.block_exists (transaction, epoch2->hash ()));
|
||||
ASSERT_TRUE (node1.active.roots.empty ());
|
||||
ASSERT_TRUE (node1.active.empty ());
|
||||
auto unchecked_count (node1.store.unchecked_count (transaction));
|
||||
ASSERT_EQ (unchecked_count, 0);
|
||||
nano::account_info info;
|
||||
|
|
|
@ -58,7 +58,7 @@ TEST (network, self_discard)
|
|||
nano::udp_data data;
|
||||
data.endpoint = system.nodes[0]->network.endpoint ();
|
||||
ASSERT_EQ (0, system.nodes[0]->stats.count (nano::stat::type::error, nano::stat::detail::bad_sender));
|
||||
system.nodes[0]->network.receive_action (&data);
|
||||
system.nodes[0]->network.receive_action (&data, system.nodes[0]->network.endpoint ());
|
||||
ASSERT_EQ (1, system.nodes[0]->stats.count (nano::stat::type::error, nano::stat::detail::bad_sender));
|
||||
}
|
||||
|
||||
|
@ -612,7 +612,7 @@ TEST (bootstrap_processor, process_one)
|
|||
{
|
||||
ASSERT_NO_ERROR (system.poll ());
|
||||
}
|
||||
ASSERT_EQ (0, node1->active.roots.size ());
|
||||
ASSERT_EQ (0, node1->active.size ());
|
||||
node1->stop ();
|
||||
}
|
||||
|
||||
|
@ -665,7 +665,7 @@ TEST (bootstrap_processor, process_state)
|
|||
{
|
||||
ASSERT_NO_ERROR (system.poll ());
|
||||
}
|
||||
ASSERT_EQ (0, node1->active.roots.size ());
|
||||
ASSERT_EQ (0, node1->active.size ());
|
||||
node1->stop ();
|
||||
}
|
||||
|
||||
|
@ -1062,7 +1062,7 @@ TEST (bulk, offline_send)
|
|||
ASSERT_NE (std::numeric_limits<nano::uint256_t>::max (), system.nodes[0]->balance (nano::test_genesis_key.pub));
|
||||
// Wait to finish election background tasks
|
||||
system.deadline_set (10s);
|
||||
while (!system.nodes[0]->active.roots.empty ())
|
||||
while (!system.nodes[0]->active.empty ())
|
||||
{
|
||||
ASSERT_NO_ERROR (system.poll ());
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ TEST (node, block_store_path_failure)
|
|||
nano::logging logging;
|
||||
logging.init (path);
|
||||
nano::work_pool work (std::numeric_limits<unsigned>::max (), nullptr);
|
||||
auto node (std::make_shared<nano::node> (init, *service, 0, path, alarm, logging, work));
|
||||
auto node (std::make_shared<nano::node> (init, *service, 24000, path, alarm, logging, work));
|
||||
ASSERT_TRUE (node->wallets.items.empty ());
|
||||
node->stop ();
|
||||
}
|
||||
|
@ -199,9 +199,12 @@ TEST (node, node_receive_quorum)
|
|||
auto done (false);
|
||||
while (!done)
|
||||
{
|
||||
auto info (system.nodes[0]->active.roots.find (nano::uint512_union (previous, previous)));
|
||||
ASSERT_NE (system.nodes[0]->active.roots.end (), info);
|
||||
done = info->election->announcements > nano::active_transactions::announcement_min;
|
||||
{
|
||||
std::lock_guard<std::mutex> guard (system.nodes[0]->active.mutex);
|
||||
auto info (system.nodes[0]->active.roots.find (nano::uint512_union (previous, previous)));
|
||||
ASSERT_NE (system.nodes[0]->active.roots.end (), info);
|
||||
done = info->election->announcements > nano::active_transactions::announcement_min;
|
||||
}
|
||||
ASSERT_NO_ERROR (system.poll ());
|
||||
}
|
||||
nano::system system2 (24001, 1);
|
||||
|
@ -275,13 +278,13 @@ TEST (node, receive_gap)
|
|||
{
|
||||
nano::system system (24000, 1);
|
||||
auto & node1 (*system.nodes[0]);
|
||||
ASSERT_EQ (0, node1.gap_cache.blocks.size ());
|
||||
ASSERT_EQ (0, node1.gap_cache.size ());
|
||||
auto block (std::make_shared<nano::send_block> (5, 1, 2, nano::keypair ().prv, 4, 0));
|
||||
node1.work_generate_blocking (*block);
|
||||
nano::publish message (block);
|
||||
node1.process_message (message, node1.network.endpoint ());
|
||||
node1.block_processor.flush ();
|
||||
ASSERT_EQ (1, node1.gap_cache.blocks.size ());
|
||||
ASSERT_EQ (1, node1.gap_cache.size ());
|
||||
}
|
||||
|
||||
TEST (node, merge_peers)
|
||||
|
@ -368,7 +371,7 @@ TEST (node, unlock_search)
|
|||
{
|
||||
ASSERT_NO_ERROR (system.poll ());
|
||||
}
|
||||
while (!system.nodes[0]->active.roots.empty ())
|
||||
while (!system.nodes[0]->active.empty ())
|
||||
{
|
||||
ASSERT_NO_ERROR (system.poll ());
|
||||
}
|
||||
|
@ -822,21 +825,23 @@ TEST (node, fork_publish)
|
|||
node1.work_generate_blocking (*send2);
|
||||
node1.process_active (send1);
|
||||
node1.block_processor.flush ();
|
||||
ASSERT_EQ (1, node1.active.roots.size ());
|
||||
ASSERT_EQ (1, node1.active.size ());
|
||||
std::unique_lock<std::mutex> lock (node1.active.mutex);
|
||||
auto existing (node1.active.roots.find (nano::uint512_union (send1->previous (), send1->root ())));
|
||||
ASSERT_NE (node1.active.roots.end (), existing);
|
||||
auto election (existing->election);
|
||||
lock.unlock ();
|
||||
system.deadline_set (1s);
|
||||
// Wait until the genesis rep activated & makes vote
|
||||
while (election->last_votes.size () != 2)
|
||||
while (election->last_votes_size () != 2)
|
||||
{
|
||||
auto transaction (node1.store.tx_begin ());
|
||||
election->compute_rep_votes (transaction);
|
||||
node1.block_processor.generator.add (send1->hash ());
|
||||
node1.vote_processor.flush ();
|
||||
ASSERT_NO_ERROR (system.poll ());
|
||||
}
|
||||
node1.process_active (send2);
|
||||
node1.block_processor.flush ();
|
||||
lock.lock ();
|
||||
auto existing1 (election->last_votes.find (nano::test_genesis_key.pub));
|
||||
ASSERT_NE (election->last_votes.end (), existing1);
|
||||
ASSERT_EQ (send1->hash (), existing1->second.hash);
|
||||
|
@ -864,18 +869,20 @@ TEST (node, fork_keep)
|
|||
node1.block_processor.flush ();
|
||||
node2.process_active (send1);
|
||||
node2.block_processor.flush ();
|
||||
ASSERT_EQ (1, node1.active.roots.size ());
|
||||
ASSERT_EQ (1, node2.active.roots.size ());
|
||||
ASSERT_EQ (1, node1.active.size ());
|
||||
ASSERT_EQ (1, node2.active.size ());
|
||||
system.wallet (0)->insert_adhoc (nano::test_genesis_key.prv);
|
||||
node1.process_active (send2);
|
||||
node1.block_processor.flush ();
|
||||
node2.process_active (send2);
|
||||
node2.block_processor.flush ();
|
||||
std::unique_lock<std::mutex> lock (node2.active.mutex);
|
||||
auto conflict (node2.active.roots.find (nano::uint512_union (genesis.hash (), genesis.hash ())));
|
||||
ASSERT_NE (node2.active.roots.end (), conflict);
|
||||
auto votes1 (conflict->election);
|
||||
ASSERT_NE (nullptr, votes1);
|
||||
ASSERT_EQ (1, votes1->last_votes.size ());
|
||||
lock.unlock ();
|
||||
{
|
||||
auto transaction0 (system.nodes[0]->store.tx_begin ());
|
||||
auto transaction1 (system.nodes[1]->store.tx_begin ());
|
||||
|
@ -884,13 +891,14 @@ TEST (node, fork_keep)
|
|||
}
|
||||
system.deadline_set (1.5min);
|
||||
// Wait until the genesis rep makes a vote
|
||||
while (votes1->last_votes.size () == 1)
|
||||
while (votes1->last_votes_size () == 1)
|
||||
{
|
||||
ASSERT_NO_ERROR (system.poll ());
|
||||
}
|
||||
auto transaction0 (system.nodes[0]->store.tx_begin ());
|
||||
auto transaction1 (system.nodes[1]->store.tx_begin ());
|
||||
// The vote should be in agreement with what we already have.
|
||||
lock.lock ();
|
||||
auto winner (*votes1->tally (transaction1).begin ());
|
||||
ASSERT_EQ (*send1, *winner.second);
|
||||
ASSERT_EQ (nano::genesis_amount - 100, winner.first);
|
||||
|
@ -915,18 +923,20 @@ TEST (node, fork_flip)
|
|||
node1.block_processor.flush ();
|
||||
node2.process_message (publish2, node1.network.endpoint ());
|
||||
node2.block_processor.flush ();
|
||||
ASSERT_EQ (1, node1.active.roots.size ());
|
||||
ASSERT_EQ (1, node2.active.roots.size ());
|
||||
ASSERT_EQ (1, node1.active.size ());
|
||||
ASSERT_EQ (1, node2.active.size ());
|
||||
system.wallet (0)->insert_adhoc (nano::test_genesis_key.prv);
|
||||
node1.process_message (publish2, node1.network.endpoint ());
|
||||
node1.block_processor.flush ();
|
||||
node2.process_message (publish1, node2.network.endpoint ());
|
||||
node2.block_processor.flush ();
|
||||
std::unique_lock<std::mutex> lock (node2.active.mutex);
|
||||
auto conflict (node2.active.roots.find (nano::uint512_union (genesis.hash (), genesis.hash ())));
|
||||
ASSERT_NE (node2.active.roots.end (), conflict);
|
||||
auto votes1 (conflict->election);
|
||||
ASSERT_NE (nullptr, votes1);
|
||||
ASSERT_EQ (1, votes1->last_votes.size ());
|
||||
lock.unlock ();
|
||||
{
|
||||
auto transaction (system.nodes[0]->store.tx_begin ());
|
||||
ASSERT_TRUE (node1.store.block_exists (transaction, publish1.block->hash ()));
|
||||
|
@ -944,6 +954,7 @@ TEST (node, fork_flip)
|
|||
}
|
||||
auto transaction1 (system.nodes[0]->store.tx_begin ());
|
||||
auto transaction2 (system.nodes[1]->store.tx_begin ());
|
||||
lock.lock ();
|
||||
auto winner (*votes1->tally (transaction2).begin ());
|
||||
ASSERT_EQ (*publish1.block, *winner.second);
|
||||
ASSERT_EQ (nano::genesis_amount - 100, winner.first);
|
||||
|
@ -972,19 +983,21 @@ TEST (node, fork_multi_flip)
|
|||
node2.process_message (publish2, node2.network.endpoint ());
|
||||
node2.process_message (publish3, node2.network.endpoint ());
|
||||
node2.block_processor.flush ();
|
||||
ASSERT_EQ (1, node1.active.roots.size ());
|
||||
ASSERT_EQ (2, node2.active.roots.size ());
|
||||
ASSERT_EQ (1, node1.active.size ());
|
||||
ASSERT_EQ (2, node2.active.size ());
|
||||
system.wallet (0)->insert_adhoc (nano::test_genesis_key.prv);
|
||||
node1.process_message (publish2, node1.network.endpoint ());
|
||||
node1.process_message (publish3, node1.network.endpoint ());
|
||||
node1.block_processor.flush ();
|
||||
node2.process_message (publish1, node2.network.endpoint ());
|
||||
node2.block_processor.flush ();
|
||||
std::unique_lock<std::mutex> lock (node2.active.mutex);
|
||||
auto conflict (node2.active.roots.find (nano::uint512_union (genesis.hash (), genesis.hash ())));
|
||||
ASSERT_NE (node2.active.roots.end (), conflict);
|
||||
auto votes1 (conflict->election);
|
||||
ASSERT_NE (nullptr, votes1);
|
||||
ASSERT_EQ (1, votes1->last_votes.size ());
|
||||
lock.unlock ();
|
||||
{
|
||||
auto transaction (system.nodes[0]->store.tx_begin ());
|
||||
ASSERT_TRUE (node1.store.block_exists (transaction, publish1.block->hash ()));
|
||||
|
@ -1003,6 +1016,7 @@ TEST (node, fork_multi_flip)
|
|||
}
|
||||
auto transaction1 (system.nodes[0]->store.tx_begin ());
|
||||
auto transaction2 (system.nodes[1]->store.tx_begin ());
|
||||
lock.lock ();
|
||||
auto winner (*votes1->tally (transaction2).begin ());
|
||||
ASSERT_EQ (*publish1.block, *winner.second);
|
||||
ASSERT_EQ (nano::genesis_amount - 100, winner.first);
|
||||
|
@ -1070,7 +1084,7 @@ TEST (node, fork_open)
|
|||
node1.block_processor.flush ();
|
||||
auto open2 (std::make_shared<nano::open_block> (publish1.block->hash (), 2, key1.pub, key1.prv, key1.pub, system.work.generate (key1.pub)));
|
||||
nano::publish publish3 (open2);
|
||||
ASSERT_EQ (2, node1.active.roots.size ());
|
||||
ASSERT_EQ (2, node1.active.size ());
|
||||
system.wallet (0)->insert_adhoc (nano::test_genesis_key.prv);
|
||||
node1.process_message (publish3, node1.network.endpoint ());
|
||||
node1.block_processor.flush ();
|
||||
|
@ -1100,19 +1114,21 @@ TEST (node, fork_open_flip)
|
|||
// node2 gets copy that will be evicted
|
||||
node2.process_active (open2);
|
||||
node2.block_processor.flush ();
|
||||
ASSERT_EQ (2, node1.active.roots.size ());
|
||||
ASSERT_EQ (2, node2.active.roots.size ());
|
||||
ASSERT_EQ (2, node1.active.size ());
|
||||
ASSERT_EQ (2, node2.active.size ());
|
||||
system.wallet (0)->insert_adhoc (nano::test_genesis_key.prv);
|
||||
// Notify both nodes that a fork exists
|
||||
node1.process_active (open2);
|
||||
node1.block_processor.flush ();
|
||||
node2.process_active (open1);
|
||||
node2.block_processor.flush ();
|
||||
std::unique_lock<std::mutex> lock (node2.active.mutex);
|
||||
auto conflict (node2.active.roots.find (nano::uint512_union (open1->previous (), open1->root ())));
|
||||
ASSERT_NE (node2.active.roots.end (), conflict);
|
||||
auto votes1 (conflict->election);
|
||||
ASSERT_NE (nullptr, votes1);
|
||||
ASSERT_EQ (1, votes1->last_votes.size ());
|
||||
lock.unlock ();
|
||||
ASSERT_TRUE (node1.block (open1->hash ()) != nullptr);
|
||||
ASSERT_TRUE (node2.block (open2->hash ()) != nullptr);
|
||||
system.deadline_set (10s);
|
||||
|
@ -1124,6 +1140,7 @@ TEST (node, fork_open_flip)
|
|||
node2.block_processor.flush ();
|
||||
auto transaction1 (system.nodes[0]->store.tx_begin ());
|
||||
auto transaction2 (system.nodes[1]->store.tx_begin ());
|
||||
lock.lock ();
|
||||
auto winner (*votes1->tally (transaction2).begin ());
|
||||
ASSERT_EQ (*open1, *winner.second);
|
||||
ASSERT_EQ (nano::genesis_amount - 1, winner.first);
|
||||
|
@ -1381,23 +1398,30 @@ TEST (node, rep_self_vote)
|
|||
}
|
||||
system.wallet (0)->insert_adhoc (rep_big.prv);
|
||||
system.wallet (0)->insert_adhoc (nano::test_genesis_key.prv);
|
||||
ASSERT_EQ (system.wallet (0)->wallets.reps_count, 2);
|
||||
auto block0 (std::make_shared<nano::send_block> (node0->latest (nano::test_genesis_key.pub), rep_big.pub, nano::uint128_t ("0x60000000000000000000000000000000"), nano::test_genesis_key.prv, nano::test_genesis_key.pub, 0));
|
||||
node0->work_generate_blocking (*block0);
|
||||
ASSERT_EQ (nano::process_result::progress, node0->process (*block0).code);
|
||||
auto & active (node0->active);
|
||||
active.start (block0);
|
||||
std::unique_lock<std::mutex> lock (active.mutex);
|
||||
auto existing (active.roots.find (nano::uint512_union (block0->previous (), block0->root ())));
|
||||
ASSERT_NE (active.roots.end (), existing);
|
||||
auto election (existing->election);
|
||||
lock.unlock ();
|
||||
system.deadline_set (1s);
|
||||
// Wait until representatives are activated & make vote
|
||||
while (existing->election->last_votes.size () != 3)
|
||||
while (election->last_votes_size () != 3)
|
||||
{
|
||||
lock.lock ();
|
||||
auto transaction (node0->store.tx_begin ());
|
||||
existing->election->compute_rep_votes (transaction);
|
||||
election->compute_rep_votes (transaction);
|
||||
lock.unlock ();
|
||||
node0->vote_processor.flush ();
|
||||
ASSERT_NO_ERROR (system.poll ());
|
||||
}
|
||||
auto & rep_votes (existing->election->last_votes);
|
||||
lock.lock ();
|
||||
auto & rep_votes (election->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));
|
||||
}
|
||||
|
@ -1418,7 +1442,7 @@ TEST (node, DISABLED_bootstrap_no_publish)
|
|||
}
|
||||
ASSERT_FALSE (node1->bootstrap_initiator.in_progress ());
|
||||
node1->bootstrap_initiator.bootstrap (node0->network.endpoint ());
|
||||
ASSERT_TRUE (node1->active.roots.empty ());
|
||||
ASSERT_TRUE (node1->active.empty ());
|
||||
system1.deadline_set (10s);
|
||||
while (node1->block (send0.hash ()) == nullptr)
|
||||
{
|
||||
|
@ -1426,7 +1450,7 @@ TEST (node, DISABLED_bootstrap_no_publish)
|
|||
system0.poll ();
|
||||
auto ec = system1.poll ();
|
||||
// There should never be an active transaction because the only activity is bootstrapping 1 block which shouldn't be publishing.
|
||||
ASSERT_TRUE (node1->active.roots.empty ());
|
||||
ASSERT_TRUE (node1->active.empty ());
|
||||
ASSERT_NO_ERROR (ec);
|
||||
}
|
||||
}
|
||||
|
@ -1448,7 +1472,7 @@ TEST (node, bootstrap_bulk_push)
|
|||
}
|
||||
ASSERT_FALSE (node0->bootstrap_initiator.in_progress ());
|
||||
ASSERT_FALSE (node1->bootstrap_initiator.in_progress ());
|
||||
ASSERT_TRUE (node1->active.roots.empty ());
|
||||
ASSERT_TRUE (node1->active.empty ());
|
||||
node0->bootstrap_initiator.bootstrap (node1->network.endpoint (), false);
|
||||
system1.deadline_set (10s);
|
||||
while (node1->block (send0.hash ()) == nullptr)
|
||||
|
@ -1457,7 +1481,7 @@ TEST (node, bootstrap_bulk_push)
|
|||
ASSERT_NO_ERROR (system1.poll ());
|
||||
}
|
||||
// since this uses bulk_push, the new block should be republished
|
||||
ASSERT_FALSE (node1->active.roots.empty ());
|
||||
ASSERT_FALSE (node1->active.empty ());
|
||||
}
|
||||
|
||||
// Bootstrapping a forked open block should succeed.
|
||||
|
@ -1486,7 +1510,7 @@ TEST (node, bootstrap_fork_open)
|
|||
}
|
||||
ASSERT_FALSE (node1->bootstrap_initiator.in_progress ());
|
||||
node1->bootstrap_initiator.bootstrap (node0->network.endpoint ());
|
||||
ASSERT_TRUE (node1->active.roots.empty ());
|
||||
ASSERT_TRUE (node1->active.empty ());
|
||||
system0.deadline_set (10s);
|
||||
while (node1->ledger.block_exists (open1.hash ()))
|
||||
{
|
||||
|
@ -1575,7 +1599,7 @@ TEST (node, no_voting)
|
|||
// Broadcast a confirm so others should know this is a rep node
|
||||
wallet0->send_action (nano::test_genesis_key.pub, key1.pub, nano::Mxrb_ratio);
|
||||
system.deadline_set (10s);
|
||||
while (!node1.active.roots.empty ())
|
||||
while (!node1.active.empty ())
|
||||
{
|
||||
ASSERT_NO_ERROR (system.poll ());
|
||||
}
|
||||
|
@ -1743,9 +1767,9 @@ TEST (node, block_confirm)
|
|||
ASSERT_EQ (nano::process_result::progress, system.nodes[1]->ledger.process (transaction, *send2).code);
|
||||
}
|
||||
system.nodes[0]->block_confirm (send2);
|
||||
ASSERT_TRUE (system.nodes[0]->active.confirmed.empty ());
|
||||
ASSERT_TRUE (system.nodes[0]->active.list_confirmed ().empty ());
|
||||
system.deadline_set (10s);
|
||||
while (system.nodes[0]->active.confirmed.empty ())
|
||||
while (system.nodes[0]->active.list_confirmed ().empty ())
|
||||
{
|
||||
ASSERT_NO_ERROR (system.poll ());
|
||||
}
|
||||
|
@ -1812,17 +1836,20 @@ TEST (node, confirm_quorum)
|
|||
}
|
||||
system.wallet (0)->send_action (nano::test_genesis_key.pub, nano::test_genesis_key.pub, new_balance.number ());
|
||||
system.deadline_set (10s);
|
||||
while (system.nodes[0]->active.roots.empty ())
|
||||
while (system.nodes[0]->active.empty ())
|
||||
{
|
||||
ASSERT_NO_ERROR (system.poll ());
|
||||
}
|
||||
auto done (false);
|
||||
while (!done)
|
||||
{
|
||||
ASSERT_FALSE (system.nodes[0]->active.roots.empty ());
|
||||
auto info (system.nodes[0]->active.roots.find (nano::uint512_union (send1->hash (), send1->hash ())));
|
||||
ASSERT_NE (system.nodes[0]->active.roots.end (), info);
|
||||
done = info->election->announcements > nano::active_transactions::announcement_min;
|
||||
ASSERT_FALSE (system.nodes[0]->active.empty ());
|
||||
{
|
||||
std::lock_guard<std::mutex> guard (system.nodes[0]->active.mutex);
|
||||
auto info (system.nodes[0]->active.roots.find (nano::uint512_union (send1->hash (), send1->hash ())));
|
||||
ASSERT_NE (system.nodes[0]->active.roots.end (), info);
|
||||
done = info->election->announcements > nano::active_transactions::announcement_min;
|
||||
}
|
||||
ASSERT_NO_ERROR (system.poll ());
|
||||
}
|
||||
ASSERT_EQ (0, system.nodes[0]->balance (nano::test_genesis_key.pub));
|
||||
|
@ -2157,12 +2184,12 @@ TEST (node, block_processor_reject_rolled_back)
|
|||
node.block_processor.flush ();
|
||||
ASSERT_FALSE (node.ledger.block_exists (send1->hash ()));
|
||||
ASSERT_TRUE (node.ledger.block_exists (send2->hash ()));
|
||||
ASSERT_TRUE (node.active.roots.empty ());
|
||||
ASSERT_TRUE (node.active.empty ());
|
||||
// Block send1 cannot be processed & start fork resolution election
|
||||
node.block_processor.add (send1);
|
||||
node.block_processor.flush ();
|
||||
ASSERT_FALSE (node.ledger.block_exists (send1->hash ()));
|
||||
ASSERT_TRUE (node.active.roots.empty ());
|
||||
ASSERT_TRUE (node.active.empty ());
|
||||
}
|
||||
|
||||
TEST (node, confirm_back)
|
||||
|
@ -2179,7 +2206,7 @@ TEST (node, confirm_back)
|
|||
node.process_active (open);
|
||||
node.process_active (send2);
|
||||
node.block_processor.flush ();
|
||||
ASSERT_EQ (3, node.active.roots.size ());
|
||||
ASSERT_EQ (3, node.active.size ());
|
||||
std::vector<nano::block_hash> vote_blocks;
|
||||
vote_blocks.push_back (send2->hash ());
|
||||
auto vote (std::make_shared<nano::vote> (nano::test_genesis_key.pub, nano::test_genesis_key.prv, 0, vote_blocks));
|
||||
|
@ -2189,7 +2216,7 @@ TEST (node, confirm_back)
|
|||
node.vote_processor.vote_blocking (transaction, vote, node.network.endpoint ());
|
||||
}
|
||||
system.deadline_set (10s);
|
||||
while (!node.active.roots.empty ())
|
||||
while (!node.active.empty ())
|
||||
{
|
||||
ASSERT_NO_ERROR (system.poll ());
|
||||
}
|
||||
|
|
|
@ -284,15 +284,14 @@ TEST (rpc, send)
|
|||
request.put ("source", nano::test_genesis_key.pub.to_account ());
|
||||
request.put ("destination", nano::test_genesis_key.pub.to_account ());
|
||||
request.put ("amount", "100");
|
||||
system.deadline_set (10s);
|
||||
boost::thread thread2 ([&system]() {
|
||||
system.deadline_set (10s);
|
||||
while (system.nodes[0]->balance (nano::test_genesis_key.pub) == nano::genesis_amount)
|
||||
{
|
||||
ASSERT_NO_ERROR (system.poll ());
|
||||
}
|
||||
});
|
||||
test_response response (request, rpc, system.io_ctx);
|
||||
system.deadline_set (5s);
|
||||
while (response.status == 0)
|
||||
{
|
||||
ASSERT_NO_ERROR (system.poll ());
|
||||
|
@ -320,15 +319,14 @@ TEST (rpc, send_fail)
|
|||
request.put ("destination", nano::test_genesis_key.pub.to_account ());
|
||||
request.put ("amount", "100");
|
||||
std::atomic<bool> done (false);
|
||||
system.deadline_set (10s);
|
||||
boost::thread thread2 ([&system, &done]() {
|
||||
system.deadline_set (10s);
|
||||
while (!done)
|
||||
{
|
||||
ASSERT_NO_ERROR (system.poll ());
|
||||
}
|
||||
});
|
||||
test_response response (request, rpc, system.io_ctx);
|
||||
system.deadline_set (5s);
|
||||
while (response.status == 0)
|
||||
{
|
||||
ASSERT_NO_ERROR (system.poll ());
|
||||
|
@ -1853,9 +1851,12 @@ TEST (rpc, search_pending)
|
|||
nano::system system (24000, 1);
|
||||
system.wallet (0)->insert_adhoc (nano::test_genesis_key.prv);
|
||||
auto wallet (system.nodes[0]->wallets.items.begin ()->first.to_string ());
|
||||
nano::send_block block (system.nodes[0]->latest (nano::test_genesis_key.pub), nano::test_genesis_key.pub, nano::genesis_amount - system.nodes[0]->config.receive_minimum.number (), nano::test_genesis_key.prv, nano::test_genesis_key.pub, 0);
|
||||
auto transaction (system.nodes[0]->store.tx_begin (true));
|
||||
ASSERT_EQ (nano::process_result::progress, system.nodes[0]->ledger.process (transaction, block).code);
|
||||
auto latest (system.nodes[0]->latest (nano::test_genesis_key.pub));
|
||||
nano::send_block block (latest, nano::test_genesis_key.pub, nano::genesis_amount - system.nodes[0]->config.receive_minimum.number (), nano::test_genesis_key.prv, nano::test_genesis_key.pub, system.nodes[0]->work_generate_blocking (latest));
|
||||
{
|
||||
auto transaction (system.nodes[0]->store.tx_begin (true));
|
||||
ASSERT_EQ (nano::process_result::progress, system.nodes[0]->ledger.process (transaction, block).code);
|
||||
}
|
||||
nano::rpc rpc (system.io_ctx, *system.nodes[0], nano::rpc_config (true));
|
||||
rpc.start ();
|
||||
boost::property_tree::ptree request;
|
||||
|
@ -3204,9 +3205,12 @@ TEST (rpc, search_pending_all)
|
|||
{
|
||||
nano::system system (24000, 1);
|
||||
system.wallet (0)->insert_adhoc (nano::test_genesis_key.prv);
|
||||
nano::send_block block (system.nodes[0]->latest (nano::test_genesis_key.pub), nano::test_genesis_key.pub, nano::genesis_amount - system.nodes[0]->config.receive_minimum.number (), nano::test_genesis_key.prv, nano::test_genesis_key.pub, 0);
|
||||
auto transaction (system.nodes[0]->store.tx_begin (true));
|
||||
ASSERT_EQ (nano::process_result::progress, system.nodes[0]->ledger.process (transaction, block).code);
|
||||
auto latest (system.nodes[0]->latest (nano::test_genesis_key.pub));
|
||||
nano::send_block block (latest, nano::test_genesis_key.pub, nano::genesis_amount - system.nodes[0]->config.receive_minimum.number (), nano::test_genesis_key.prv, nano::test_genesis_key.pub, system.nodes[0]->work_generate_blocking (latest));
|
||||
{
|
||||
auto transaction (system.nodes[0]->store.tx_begin (true));
|
||||
ASSERT_EQ (nano::process_result::progress, system.nodes[0]->ledger.process (transaction, block).code);
|
||||
}
|
||||
nano::rpc rpc (system.io_ctx, *system.nodes[0], nano::rpc_config (true));
|
||||
rpc.start ();
|
||||
boost::property_tree::ptree request;
|
||||
|
@ -4172,10 +4176,10 @@ TEST (rpc, confirmation_history)
|
|||
nano::system system (24000, 1);
|
||||
nano::keypair key;
|
||||
system.wallet (0)->insert_adhoc (nano::test_genesis_key.prv);
|
||||
ASSERT_TRUE (system.nodes[0]->active.confirmed.empty ());
|
||||
ASSERT_TRUE (system.nodes[0]->active.list_confirmed ().empty ());
|
||||
auto block (system.wallet (0)->send_action (nano::test_genesis_key.pub, key.pub, nano::Gxrb_ratio));
|
||||
system.deadline_set (10s);
|
||||
while (system.nodes[0]->active.confirmed.empty ())
|
||||
while (system.nodes[0]->active.list_confirmed ().empty ())
|
||||
{
|
||||
ASSERT_NO_ERROR (system.poll ());
|
||||
}
|
||||
|
@ -4209,12 +4213,12 @@ TEST (rpc, confirmation_history_hash)
|
|||
nano::system system (24000, 1);
|
||||
nano::keypair key;
|
||||
system.wallet (0)->insert_adhoc (nano::test_genesis_key.prv);
|
||||
ASSERT_TRUE (system.nodes[0]->active.confirmed.empty ());
|
||||
ASSERT_TRUE (system.nodes[0]->active.list_confirmed ().empty ());
|
||||
auto send1 (system.wallet (0)->send_action (nano::test_genesis_key.pub, key.pub, nano::Gxrb_ratio));
|
||||
auto send2 (system.wallet (0)->send_action (nano::test_genesis_key.pub, key.pub, nano::Gxrb_ratio));
|
||||
auto send3 (system.wallet (0)->send_action (nano::test_genesis_key.pub, key.pub, nano::Gxrb_ratio));
|
||||
system.deadline_set (10s);
|
||||
while (system.nodes[0]->active.confirmed.size () != 3)
|
||||
while (system.nodes[0]->active.list_confirmed ().size () != 3)
|
||||
{
|
||||
ASSERT_NO_ERROR (system.poll ());
|
||||
}
|
||||
|
|
|
@ -178,7 +178,7 @@ TEST (wallet, send_async)
|
|||
ASSERT_NO_ERROR (system.poll ());
|
||||
}
|
||||
});
|
||||
bool success (false);
|
||||
std::atomic<bool> success (false);
|
||||
system.wallet (0)->send_async (nano::test_genesis_key.pub, key2.pub, std::numeric_limits<nano::uint128_t>::max (), [&success](std::shared_ptr<nano::block> block_a) { ASSERT_NE (nullptr, block_a); success = true; });
|
||||
thread.join ();
|
||||
ASSERT_TRUE (success);
|
||||
|
|
|
@ -85,11 +85,11 @@ TEST (wallets, upgrade)
|
|||
auto node1 (std::make_shared<nano::node> (init1, system.io_ctx, 24001, path, system.alarm, system.logging, system.work));
|
||||
ASSERT_FALSE (init1.error ());
|
||||
node1->wallets.create (id.pub);
|
||||
auto transaction_source (node1->wallets.env.tx_begin (true));
|
||||
MDB_txn * tx_source (*boost::polymorphic_downcast<nano::mdb_txn *> (transaction_source.impl.get ()));
|
||||
auto & mdb_store (dynamic_cast<nano::mdb_store &> (node1->store));
|
||||
auto transaction_destination (mdb_store.tx_begin_write ());
|
||||
MDB_txn * tx_destination (*boost::polymorphic_downcast<nano::mdb_txn *> (transaction_destination.impl.get ()));
|
||||
auto transaction_source (node1->wallets.env.tx_begin (true));
|
||||
MDB_txn * tx_source (*boost::polymorphic_downcast<nano::mdb_txn *> (transaction_source.impl.get ()));
|
||||
node1->wallets.move_table (id.pub.to_string (), tx_source, tx_destination);
|
||||
node1->store.version_put (transaction_destination, 11);
|
||||
}
|
||||
|
@ -97,10 +97,10 @@ TEST (wallets, upgrade)
|
|||
auto node1 (std::make_shared<nano::node> (init1, system.io_ctx, 24001, path, system.alarm, system.logging, system.work));
|
||||
ASSERT_EQ (1, node1->wallets.items.size ());
|
||||
ASSERT_EQ (id.pub, node1->wallets.items.begin ()->first);
|
||||
auto transaction_old (node1->store.tx_begin_write ());
|
||||
MDB_txn * tx_old (*boost::polymorphic_downcast<nano::mdb_txn *> (transaction_old.impl.get ()));
|
||||
auto transaction_new (node1->wallets.env.tx_begin (true));
|
||||
MDB_txn * tx_new (*boost::polymorphic_downcast<nano::mdb_txn *> (transaction_new.impl.get ()));
|
||||
auto transaction_old (node1->store.tx_begin_write ());
|
||||
MDB_txn * tx_old (*boost::polymorphic_downcast<nano::mdb_txn *> (transaction_old.impl.get ()));
|
||||
MDB_dbi old_handle;
|
||||
ASSERT_EQ (MDB_NOTFOUND, mdb_dbi_open (tx_old, id.pub.to_string ().c_str (), 0, &old_handle));
|
||||
MDB_dbi new_handle;
|
||||
|
|
|
@ -610,7 +610,7 @@ int main (int argc, char * const * argv)
|
|||
node->vote_processor.vote (vote, node->network.endpoint ());
|
||||
votes.pop_front ();
|
||||
}
|
||||
while (!node->active.roots.empty ())
|
||||
while (!node->active.empty ())
|
||||
{
|
||||
std::this_thread::sleep_for (std::chrono::milliseconds (100));
|
||||
}
|
||||
|
|
|
@ -72,8 +72,8 @@ void nano::block_processor::add (nano::unchecked_info const & info_a)
|
|||
}
|
||||
blocks_hashes.insert (hash);
|
||||
}
|
||||
condition.notify_all ();
|
||||
}
|
||||
condition.notify_all ();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -106,10 +106,7 @@ void nano::block_processor::process_blocks ()
|
|||
}
|
||||
else
|
||||
{
|
||||
lock.unlock ();
|
||||
condition.notify_all ();
|
||||
lock.lock ();
|
||||
|
||||
condition.wait (lock);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1400,14 +1400,15 @@ void nano::bootstrap_attempt::lazy_add (nano::block_hash const & hash_a)
|
|||
|
||||
void nano::bootstrap_attempt::lazy_pull_flush ()
|
||||
{
|
||||
std::unique_lock<std::mutex> lock (lazy_mutex);
|
||||
assert (!mutex.try_lock ());
|
||||
std::unique_lock<std::mutex> lazy_lock (lazy_mutex);
|
||||
auto transaction (node->store.tx_begin_read ());
|
||||
for (auto & pull_start : lazy_pulls)
|
||||
{
|
||||
// Recheck if block was already processed
|
||||
if (lazy_blocks.find (pull_start) == lazy_blocks.end () && !node->store.block_exists (transaction, pull_start))
|
||||
{
|
||||
add_pull (nano::pull_info (pull_start, pull_start, nano::block_hash (0), lazy_max_pull_blocks));
|
||||
pulls.push_back (nano::pull_info (pull_start, pull_start, nano::block_hash (0), lazy_max_pull_blocks));
|
||||
}
|
||||
}
|
||||
lazy_pulls.clear ();
|
||||
|
@ -1480,17 +1481,15 @@ void nano::bootstrap_attempt::lazy_run ()
|
|||
// Flushing lazy pulls
|
||||
if (iterations % 100 == 0)
|
||||
{
|
||||
lock.unlock ();
|
||||
lazy_pull_flush ();
|
||||
lock.lock ();
|
||||
}
|
||||
}
|
||||
// Flushing may resolve forks which can add more pulls
|
||||
// Flushing lazy pulls
|
||||
lock.unlock ();
|
||||
node->block_processor.flush ();
|
||||
lazy_pull_flush ();
|
||||
lock.lock ();
|
||||
lazy_pull_flush ();
|
||||
}
|
||||
if (!stopped)
|
||||
{
|
||||
|
|
|
@ -118,7 +118,7 @@ public:
|
|||
std::atomic<uint64_t> total_blocks;
|
||||
std::atomic<unsigned> runs_count;
|
||||
std::vector<std::pair<nano::block_hash, nano::block_hash>> bulk_push_targets;
|
||||
bool stopped;
|
||||
std::atomic<bool> stopped;
|
||||
nano::bootstrap_mode mode;
|
||||
std::mutex mutex;
|
||||
std::condition_variable condition;
|
||||
|
|
|
@ -612,7 +612,7 @@ nano::confirm_ack::confirm_ack (bool & error_a, nano::stream & stream_a, nano::m
|
|||
message (header_a),
|
||||
vote (std::make_shared<nano::vote> (error_a, stream_a, header.block_type ()))
|
||||
{
|
||||
if (uniquer_a)
|
||||
if (!error_a && uniquer_a)
|
||||
{
|
||||
vote = uniquer_a->unique (vote);
|
||||
}
|
||||
|
@ -622,6 +622,7 @@ nano::confirm_ack::confirm_ack (std::shared_ptr<nano::vote> vote_a) :
|
|||
message (nano::message_type::confirm_ack),
|
||||
vote (vote_a)
|
||||
{
|
||||
assert (!vote_a->blocks.empty ());
|
||||
auto & first_vote_block (vote_a->blocks[0]);
|
||||
if (first_vote_block.which ())
|
||||
{
|
||||
|
@ -640,17 +641,6 @@ void nano::confirm_ack::serialize (nano::stream & stream_a) const
|
|||
vote->serialize (stream_a, header.block_type ());
|
||||
}
|
||||
|
||||
bool nano::confirm_ack::deserialize (nano::stream & stream_a, nano::vote_uniquer * uniquer_a)
|
||||
{
|
||||
assert (header.type == nano::message_type::confirm_ack);
|
||||
auto result (vote->deserialize (stream_a));
|
||||
if (uniquer_a)
|
||||
{
|
||||
vote = uniquer_a->unique (vote);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool nano::confirm_ack::operator== (nano::confirm_ack const & other_a) const
|
||||
{
|
||||
auto result (*vote == *other_a.vote);
|
||||
|
|
|
@ -313,7 +313,6 @@ public:
|
|||
confirm_ack (bool &, nano::stream &, nano::message_header const &, nano::vote_uniquer * = nullptr);
|
||||
confirm_ack (std::shared_ptr<nano::vote>);
|
||||
void serialize (nano::stream &) const override;
|
||||
bool deserialize (nano::stream &, nano::vote_uniquer * = nullptr);
|
||||
void visit (nano::message_visitor &) const override;
|
||||
bool operator== (nano::confirm_ack const &) const;
|
||||
std::shared_ptr<nano::vote> vote;
|
||||
|
|
|
@ -847,6 +847,7 @@ void nano::mdb_store::version_put (nano::transaction const & transaction_a, int
|
|||
{
|
||||
auto status (mdb_drop (env.tx (transaction_a), blocks_info, 1));
|
||||
release_assert (status == MDB_SUCCESS);
|
||||
blocks_info = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -136,6 +136,7 @@ void nano::network::receive ()
|
|||
|
||||
void nano::network::process_packets ()
|
||||
{
|
||||
auto local_endpoint (endpoint ());
|
||||
while (on.load ())
|
||||
{
|
||||
auto data (buffer_container.dequeue ());
|
||||
|
@ -144,7 +145,7 @@ void nano::network::process_packets ()
|
|||
break;
|
||||
}
|
||||
//std::cerr << data->endpoint.address ().to_string ();
|
||||
receive_action (data);
|
||||
receive_action (data, local_endpoint);
|
||||
buffer_container.release (data);
|
||||
}
|
||||
}
|
||||
|
@ -152,7 +153,11 @@ void nano::network::process_packets ()
|
|||
void nano::network::stop ()
|
||||
{
|
||||
on = false;
|
||||
socket.close ();
|
||||
std::unique_lock<std::mutex> lock (socket_mutex);
|
||||
if (socket.is_open ())
|
||||
{
|
||||
socket.close ();
|
||||
}
|
||||
resolver.cancel ();
|
||||
buffer_container.stop ();
|
||||
}
|
||||
|
@ -806,10 +811,14 @@ public:
|
|||
};
|
||||
}
|
||||
|
||||
void nano::network::receive_action (nano::udp_data * data_a)
|
||||
void nano::network::receive_action (nano::udp_data * data_a, nano::endpoint const & local_endpoint_a)
|
||||
{
|
||||
auto allowed_sender (true);
|
||||
if (data_a->endpoint == endpoint ())
|
||||
if (!on)
|
||||
{
|
||||
allowed_sender = false;
|
||||
}
|
||||
else if (data_a->endpoint == local_endpoint_a)
|
||||
{
|
||||
allowed_sender = false;
|
||||
}
|
||||
|
@ -968,7 +977,11 @@ namespace nano
|
|||
std::unique_ptr<seq_con_info_component> collect_seq_con_info (alarm & alarm, const std::string & name)
|
||||
{
|
||||
auto composite = std::make_unique<seq_con_info_composite> (name);
|
||||
auto count = alarm.operations.size ();
|
||||
size_t count = 0;
|
||||
{
|
||||
std::lock_guard<std::mutex> guard (alarm.mutex);
|
||||
count = alarm.operations.size ();
|
||||
}
|
||||
auto sizeof_element = sizeof (decltype (alarm.operations)::value_type);
|
||||
composite->add_component (std::make_unique<seq_con_info_leaf> (seq_con_info{ "operations", count, sizeof_element }));
|
||||
return composite;
|
||||
|
@ -1833,16 +1846,17 @@ nano::uint128_t nano::gap_cache::bootstrap_threshold (nano::transaction const &
|
|||
return result;
|
||||
}
|
||||
|
||||
size_t nano::gap_cache::size ()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock (mutex);
|
||||
return blocks.size ();
|
||||
}
|
||||
|
||||
namespace nano
|
||||
{
|
||||
std::unique_ptr<seq_con_info_component> collect_seq_con_info (gap_cache & gap_cache, const std::string & name)
|
||||
{
|
||||
size_t count = 0;
|
||||
{
|
||||
std::lock_guard<std::mutex> (gap_cache.mutex);
|
||||
count = gap_cache.blocks.size ();
|
||||
}
|
||||
|
||||
auto count = gap_cache.size ();
|
||||
auto sizeof_element = sizeof (decltype (gap_cache.blocks)::value_type);
|
||||
auto composite = std::make_unique<seq_con_info_composite> (name);
|
||||
composite->add_component (std::make_unique<seq_con_info_leaf> (seq_con_info{ "blocks", count, sizeof_element }));
|
||||
|
@ -2703,6 +2717,7 @@ void nano::node::process_message (nano::message & message_a, nano::endpoint cons
|
|||
nano::endpoint nano::network::endpoint ()
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
std::unique_lock<std::mutex> lock (socket_mutex);
|
||||
auto port (socket.local_endpoint (ec).port ());
|
||||
if (ec)
|
||||
{
|
||||
|
@ -2963,18 +2978,21 @@ void nano::network::send_buffer (uint8_t const * data_a, size_t size_a, nano::en
|
|||
{
|
||||
BOOST_LOG (node.log) << "Sending packet";
|
||||
}
|
||||
socket.async_send_to (boost::asio::buffer (data_a, size_a), endpoint_a, [this, callback_a](boost::system::error_code const & ec, size_t size_a) {
|
||||
callback_a (ec, size_a);
|
||||
this->node.stats.add (nano::stat::type::traffic, nano::stat::dir::out, size_a);
|
||||
if (ec == boost::system::errc::host_unreachable)
|
||||
{
|
||||
this->node.stats.inc (nano::stat::type::error, nano::stat::detail::unreachable_host, nano::stat::dir::out);
|
||||
}
|
||||
if (this->node.config.logging.network_packet_logging ())
|
||||
{
|
||||
BOOST_LOG (this->node.log) << "Packet send complete";
|
||||
}
|
||||
});
|
||||
if (on.load ())
|
||||
{
|
||||
socket.async_send_to (boost::asio::buffer (data_a, size_a), endpoint_a, [this, callback_a](boost::system::error_code const & ec, size_t size_a) {
|
||||
callback_a (ec, size_a);
|
||||
this->node.stats.add (nano::stat::type::traffic, nano::stat::dir::out, size_a);
|
||||
if (ec == boost::system::errc::host_unreachable)
|
||||
{
|
||||
this->node.stats.inc (nano::stat::type::error, nano::stat::detail::unreachable_host, nano::stat::dir::out);
|
||||
}
|
||||
if (this->node.config.logging.network_packet_logging ())
|
||||
{
|
||||
BOOST_LOG (this->node.log) << "Packet send complete";
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<nano::node> nano::node::shared ()
|
||||
|
@ -3268,6 +3286,12 @@ bool nano::election::publish (std::shared_ptr<nano::block> block_a)
|
|||
return result;
|
||||
}
|
||||
|
||||
size_t nano::election::last_votes_size ()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock (node.active.mutex);
|
||||
return last_votes.size ();
|
||||
}
|
||||
|
||||
void nano::active_transactions::request_confirm (std::unique_lock<std::mutex> & lock_a)
|
||||
{
|
||||
std::unordered_set<nano::uint512_union> inactive;
|
||||
|
@ -3282,13 +3306,12 @@ void nano::active_transactions::request_confirm (std::unique_lock<std::mutex> &
|
|||
for (auto i (roots.get<1> ().begin ()), n (roots.get<1> ().end ()); i != n; ++i)
|
||||
{
|
||||
auto root (i->root);
|
||||
lock_a.unlock ();
|
||||
auto election_l (i->election);
|
||||
if ((election_l->confirmed || election_l->stopped) && i->election->announcements >= announcement_min - 1)
|
||||
if ((election_l->confirmed || election_l->stopped) && election_l->announcements >= announcement_min - 1)
|
||||
{
|
||||
if (election_l->confirmed)
|
||||
{
|
||||
confirmed.push_back (i->election->status);
|
||||
confirmed.push_back (election_l->status);
|
||||
if (confirmed.size () > election_history_size)
|
||||
{
|
||||
confirmed.pop_front ();
|
||||
|
@ -3298,12 +3321,12 @@ void nano::active_transactions::request_confirm (std::unique_lock<std::mutex> &
|
|||
}
|
||||
else
|
||||
{
|
||||
if (i->election->announcements > announcement_long)
|
||||
if (election_l->announcements > announcement_long)
|
||||
{
|
||||
++unconfirmed_count;
|
||||
unconfirmed_announcements += i->election->announcements;
|
||||
unconfirmed_announcements += election_l->announcements;
|
||||
// Log votes for very long unconfirmed elections
|
||||
if (i->election->announcements % 50 == 1)
|
||||
if (election_l->announcements % 50 == 1)
|
||||
{
|
||||
auto tally_l (election_l->tally (transaction));
|
||||
election_l->log_votes (tally_l);
|
||||
|
@ -3311,7 +3334,7 @@ void nano::active_transactions::request_confirm (std::unique_lock<std::mutex> &
|
|||
/* Escalation for long unconfirmed elections
|
||||
Start new elections for previous block & source
|
||||
if there are less than 100 active elections */
|
||||
if (i->election->announcements % announcement_long == 1 && roots_size < 100 && !nano::is_test_network)
|
||||
if (election_l->announcements % announcement_long == 1 && roots_size < 100 && !nano::is_test_network)
|
||||
{
|
||||
std::shared_ptr<nano::block> previous;
|
||||
auto previous_hash (election_l->status.winner->previous ());
|
||||
|
@ -3339,7 +3362,7 @@ void nano::active_transactions::request_confirm (std::unique_lock<std::mutex> &
|
|||
}
|
||||
}
|
||||
}
|
||||
if (i->election->announcements < announcement_long || i->election->announcements % announcement_long == 1)
|
||||
if (election_l->announcements < announcement_long || election_l->announcements % announcement_long == 1)
|
||||
{
|
||||
if (node.ledger.could_fit (transaction, *election_l->status.winner))
|
||||
{
|
||||
|
@ -3351,20 +3374,20 @@ void nano::active_transactions::request_confirm (std::unique_lock<std::mutex> &
|
|||
}
|
||||
else
|
||||
{
|
||||
if (i->election->announcements != 0)
|
||||
if (election_l->announcements != 0)
|
||||
{
|
||||
election_l->stop ();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (i->election->announcements % 4 == 1)
|
||||
if (election_l->announcements % 4 == 1)
|
||||
{
|
||||
auto reps (std::make_shared<std::vector<nano::peer_information>> (node.peers.representatives (std::numeric_limits<size_t>::max ())));
|
||||
std::unordered_set<nano::account> probable_reps;
|
||||
nano::uint128_t total_weight (0);
|
||||
for (auto j (reps->begin ()), m (reps->end ()); j != m;)
|
||||
{
|
||||
auto & rep_votes (i->election->last_votes);
|
||||
auto & rep_votes (election_l->last_votes);
|
||||
auto rep_acct (j->probable_rep_account);
|
||||
// Calculate if representative isn't recorded for several IP addresses
|
||||
if (probable_reps.find (rep_acct) == probable_reps.end ())
|
||||
|
@ -3400,7 +3423,7 @@ void nano::active_transactions::request_confirm (std::unique_lock<std::mutex> &
|
|||
{
|
||||
if (confirm_req_bundle.size () < max_broadcast_queue)
|
||||
{
|
||||
confirm_req_bundle.push_back (std::make_pair (i->election->status.winner, reps));
|
||||
confirm_req_bundle.push_back (std::make_pair (election_l->status.winner, reps));
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -3408,7 +3431,7 @@ void nano::active_transactions::request_confirm (std::unique_lock<std::mutex> &
|
|||
for (auto & rep : *reps)
|
||||
{
|
||||
auto rep_request (requests_bundle.find (rep.endpoint));
|
||||
auto block (i->election->status.winner);
|
||||
auto block (election_l->status.winner);
|
||||
auto root_hash (std::make_pair (block->hash (), block->root ()));
|
||||
if (rep_request == requests_bundle.end ())
|
||||
{
|
||||
|
@ -3429,14 +3452,14 @@ void nano::active_transactions::request_confirm (std::unique_lock<std::mutex> &
|
|||
{
|
||||
if (!nano::is_test_network)
|
||||
{
|
||||
confirm_req_bundle.push_back (std::make_pair (i->election->status.winner, std::make_shared<std::vector<nano::peer_information>> (node.peers.list_vector (100))));
|
||||
confirm_req_bundle.push_back (std::make_pair (election_l->status.winner, std::make_shared<std::vector<nano::peer_information>> (node.peers.list_vector (100))));
|
||||
}
|
||||
else
|
||||
{
|
||||
for (auto & rep : *reps)
|
||||
{
|
||||
auto rep_request (requests_bundle.find (rep.endpoint));
|
||||
auto block (i->election->status.winner);
|
||||
auto block (election_l->status.winner);
|
||||
auto root_hash (std::make_pair (block->hash (), block->root ()));
|
||||
if (rep_request == requests_bundle.end ())
|
||||
{
|
||||
|
@ -3453,8 +3476,8 @@ void nano::active_transactions::request_confirm (std::unique_lock<std::mutex> &
|
|||
}
|
||||
}
|
||||
++election_l->announcements;
|
||||
lock_a.lock ();
|
||||
}
|
||||
lock_a.unlock ();
|
||||
// Rebroadcast unconfirmed blocks
|
||||
if (!rebroadcast_bundle.empty ())
|
||||
{
|
||||
|
@ -3470,6 +3493,7 @@ void nano::active_transactions::request_confirm (std::unique_lock<std::mutex> &
|
|||
{
|
||||
node.network.broadcast_confirm_req_batch (confirm_req_bundle);
|
||||
}
|
||||
lock_a.lock ();
|
||||
for (auto i (inactive.begin ()), n (inactive.end ()); i != n; ++i)
|
||||
{
|
||||
auto root_it (roots.find (*i));
|
||||
|
@ -3631,6 +3655,12 @@ std::deque<std::shared_ptr<nano::block>> nano::active_transactions::list_blocks
|
|||
return result;
|
||||
}
|
||||
|
||||
std::deque<nano::election_status> nano::active_transactions::list_confirmed ()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock (mutex);
|
||||
return confirmed;
|
||||
}
|
||||
|
||||
void nano::active_transactions::erase (nano::block const & block_a)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock (mutex);
|
||||
|
@ -3641,6 +3671,18 @@ void nano::active_transactions::erase (nano::block const & block_a)
|
|||
}
|
||||
}
|
||||
|
||||
bool nano::active_transactions::empty ()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock (mutex);
|
||||
return roots.empty ();
|
||||
}
|
||||
|
||||
size_t nano::active_transactions::size ()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock (mutex);
|
||||
return roots.size ();
|
||||
}
|
||||
|
||||
nano::active_transactions::active_transactions (nano::node & node_a) :
|
||||
node (node_a),
|
||||
started (false),
|
||||
|
|
|
@ -79,6 +79,7 @@ public:
|
|||
void confirm_if_quorum (nano::transaction const &);
|
||||
void log_votes (nano::tally_t const &);
|
||||
bool publish (std::shared_ptr<nano::block> block_a);
|
||||
size_t last_votes_size ();
|
||||
void stop ();
|
||||
nano::node & node;
|
||||
std::unordered_map<nano::account, nano::vote_info> last_votes;
|
||||
|
@ -117,6 +118,8 @@ public:
|
|||
void update_difficulty (nano::block const &);
|
||||
std::deque<std::shared_ptr<nano::block>> list_blocks (bool = false);
|
||||
void erase (nano::block const &);
|
||||
bool empty ();
|
||||
size_t size ();
|
||||
void stop ();
|
||||
bool publish (std::shared_ptr<nano::block> block_a);
|
||||
boost::multi_index_container<
|
||||
|
@ -129,6 +132,7 @@ public:
|
|||
std::greater<uint64_t>>>>
|
||||
roots;
|
||||
std::unordered_map<nano::block_hash, std::shared_ptr<nano::election>> blocks;
|
||||
std::deque<nano::election_status> list_confirmed ();
|
||||
std::deque<nano::election_status> confirmed;
|
||||
nano::node & node;
|
||||
std::mutex mutex;
|
||||
|
@ -194,6 +198,7 @@ public:
|
|||
void add (nano::transaction const &, nano::block_hash const &, std::chrono::steady_clock::time_point = std::chrono::steady_clock::now ());
|
||||
void vote (std::shared_ptr<nano::vote>);
|
||||
nano::uint128_t bootstrap_threshold (nano::transaction const &);
|
||||
size_t size ();
|
||||
boost::multi_index_container<
|
||||
nano::gap_information,
|
||||
boost::multi_index::indexed_by<
|
||||
|
@ -324,7 +329,7 @@ public:
|
|||
void process_packets ();
|
||||
void start ();
|
||||
void stop ();
|
||||
void receive_action (nano::udp_data *);
|
||||
void receive_action (nano::udp_data *, nano::endpoint const &);
|
||||
void rpc_action (boost::system::error_code const &, size_t);
|
||||
void republish_vote (std::shared_ptr<nano::vote>);
|
||||
void republish_block (std::shared_ptr<nano::block>);
|
||||
|
|
|
@ -1519,8 +1519,8 @@ void nano::rpc_handler::confirmation_history ()
|
|||
}
|
||||
if (!ec)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock (node.active.mutex);
|
||||
for (auto i (node.active.confirmed.begin ()), n (node.active.confirmed.end ()); i != n; ++i)
|
||||
auto confirmed (node.active.list_confirmed ());
|
||||
for (auto i (confirmed.begin ()), n (confirmed.end ()); i != n; ++i)
|
||||
{
|
||||
if (hash.is_zero () || i->winner->hash () == hash)
|
||||
{
|
||||
|
|
|
@ -758,9 +758,11 @@ wallets (wallets_a)
|
|||
|
||||
void nano::wallet::enter_initial_password ()
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock (store.mutex);
|
||||
nano::raw_key password_l;
|
||||
store.password.value (password_l);
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock (store.mutex);
|
||||
store.password.value (password_l);
|
||||
}
|
||||
if (password_l.data.is_zero ())
|
||||
{
|
||||
auto transaction (wallets.tx_begin_write ());
|
||||
|
@ -1320,7 +1322,7 @@ void nano::wallet::work_cache_blocking (nano::account const & account_a, nano::b
|
|||
BOOST_LOG (wallets.node.log) << "Work generation for " << root_a.to_string () << ", with a difficulty of " << difficulty << " complete: " << (std::chrono::duration_cast<std::chrono::microseconds> (std::chrono::steady_clock::now () - begin).count ()) << " us";
|
||||
}
|
||||
auto transaction (wallets.tx_begin_write ());
|
||||
if (store.exists (transaction, account_a))
|
||||
if (live () && store.exists (transaction, account_a))
|
||||
{
|
||||
work_update (transaction, account_a, root_a, work);
|
||||
}
|
||||
|
@ -1439,6 +1441,8 @@ void nano::wallets::destroy (nano::uint256_union const & id_a)
|
|||
{
|
||||
std::lock_guard<std::mutex> lock (mutex);
|
||||
auto transaction (tx_begin_write ());
|
||||
// action_mutex should be after transactions to prevent deadlocks in deterministic_insert () & insert_adhoc ()
|
||||
std::lock_guard<std::mutex> action_lock (action_mutex);
|
||||
auto existing (items.find (id_a));
|
||||
assert (existing != items.end ());
|
||||
auto wallet (existing->second);
|
||||
|
@ -1491,7 +1495,7 @@ void nano::wallets::reload ()
|
|||
|
||||
void nano::wallets::do_wallet_actions ()
|
||||
{
|
||||
std::unique_lock<std::mutex> lock (mutex);
|
||||
std::unique_lock<std::mutex> action_lock (action_mutex);
|
||||
while (!stopped)
|
||||
{
|
||||
if (!actions.empty ())
|
||||
|
@ -1502,16 +1506,16 @@ void nano::wallets::do_wallet_actions ()
|
|||
actions.erase (first);
|
||||
if (wallet->live ())
|
||||
{
|
||||
lock.unlock ();
|
||||
action_lock.unlock ();
|
||||
observer (true);
|
||||
current (*wallet);
|
||||
observer (false);
|
||||
lock.lock ();
|
||||
action_lock.lock ();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
condition.wait (lock);
|
||||
condition.wait (action_lock);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1519,7 +1523,7 @@ void nano::wallets::do_wallet_actions ()
|
|||
void nano::wallets::queue_wallet_action (nano::uint128_t const & amount_a, std::shared_ptr<nano::wallet> wallet_a, std::function<void(nano::wallet &)> const & action_a)
|
||||
{
|
||||
{
|
||||
std::lock_guard<std::mutex> lock (mutex);
|
||||
std::lock_guard<std::mutex> action_lock (action_mutex);
|
||||
actions.insert (std::make_pair (amount_a, std::make_pair (wallet_a, std::move (action_a))));
|
||||
}
|
||||
condition.notify_all ();
|
||||
|
@ -1580,7 +1584,7 @@ bool nano::wallets::exists (nano::transaction const & transaction_a, nano::publi
|
|||
void nano::wallets::stop ()
|
||||
{
|
||||
{
|
||||
std::lock_guard<std::mutex> lock (mutex);
|
||||
std::lock_guard<std::mutex> action_lock (action_mutex);
|
||||
stopped = true;
|
||||
actions.clear ();
|
||||
}
|
||||
|
|
|
@ -190,13 +190,14 @@ public:
|
|||
std::unordered_map<nano::uint256_union, std::shared_ptr<nano::wallet>> items;
|
||||
std::multimap<nano::uint128_t, std::pair<std::shared_ptr<nano::wallet>, std::function<void(nano::wallet &)>>, std::greater<nano::uint128_t>> actions;
|
||||
std::mutex mutex;
|
||||
std::mutex action_mutex;
|
||||
std::condition_variable condition;
|
||||
nano::kdf kdf;
|
||||
MDB_dbi handle;
|
||||
MDB_dbi send_action_ids;
|
||||
nano::node & node;
|
||||
nano::mdb_env & env;
|
||||
bool stopped;
|
||||
std::atomic<bool> stopped;
|
||||
boost::thread thread;
|
||||
static nano::uint128_t const generate_priority;
|
||||
static nano::uint128_t const high_priority;
|
||||
|
|
|
@ -734,7 +734,7 @@ uniquer (uniquer_a)
|
|||
std::shared_ptr<nano::vote> nano::vote_uniquer::unique (std::shared_ptr<nano::vote> vote_a)
|
||||
{
|
||||
auto result (vote_a);
|
||||
if (result != nullptr)
|
||||
if (result != nullptr && !result->blocks.empty ())
|
||||
{
|
||||
if (!result->blocks[0].which ())
|
||||
{
|
||||
|
|
|
@ -201,13 +201,13 @@ TEST (node, fork_storm)
|
|||
empty = 0;
|
||||
single = 0;
|
||||
std::for_each (system.nodes.begin (), system.nodes.end (), [&](std::shared_ptr<nano::node> const & node_a) {
|
||||
if (node_a->active.roots.empty ())
|
||||
if (node_a->active.empty ())
|
||||
{
|
||||
++empty;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (node_a->active.roots.begin ()->election->last_votes.size () == 1)
|
||||
if (node_a->active.roots.begin ()->election->last_votes_size () == 1)
|
||||
{
|
||||
++single;
|
||||
}
|
||||
|
@ -409,11 +409,14 @@ TEST (wallets, rep_scan)
|
|||
nano::system system (24000, 1);
|
||||
auto & node (*system.nodes[0]);
|
||||
auto wallet (system.wallet (0));
|
||||
auto transaction (node.wallets.tx_begin_write ());
|
||||
for (auto i (0); i < 10000; ++i)
|
||||
{
|
||||
wallet->deterministic_insert (transaction);
|
||||
auto transaction (node.wallets.tx_begin_write ());
|
||||
for (auto i (0); i < 10000; ++i)
|
||||
{
|
||||
wallet->deterministic_insert (transaction);
|
||||
}
|
||||
}
|
||||
auto transaction (node.store.tx_begin_read ());
|
||||
auto begin (std::chrono::steady_clock::now ());
|
||||
node.wallets.foreach_representative (transaction, [](nano::public_key const & pub_a, nano::raw_key const & prv_a) {
|
||||
});
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue