dncurrency/nano/core_test/gap_cache.cpp
clemahieu 066724f6b8
Rename republish_x to flood_x to better describe what we're doing. (#1825)
Flood messages through a common function instead of having their own code.
2019-03-14 00:14:25 +00:00

121 lines
5.3 KiB
C++

#include <gtest/gtest.h>
#include <nano/core_test/testutil.hpp>
#include <nano/node/testing.hpp>
using namespace std::chrono_literals;
TEST (gap_cache, add_new)
{
nano::system system (24000, 1);
nano::gap_cache cache (*system.nodes[0]);
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 ());
}
TEST (gap_cache, add_existing)
{
nano::system system (24000, 1);
nano::gap_cache cache (*system.nodes[0]);
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.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);
}
TEST (gap_cache, comparison)
{
nano::system system (24000, 1);
nano::gap_cache cache (*system.nodes[0]);
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.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);
ASSERT_EQ (arrival, cache.blocks.get<1> ().begin ()->arrival);
}
TEST (gap_cache, gap_bootstrap)
{
nano::system system (24000, 2);
nano::block_hash latest (system.nodes[0]->latest (nano::test_genesis_key.pub));
nano::keypair key;
auto send (std::make_shared<nano::send_block> (latest, key.pub, nano::genesis_amount - 100, nano::test_genesis_key.prv, nano::test_genesis_key.pub, system.work.generate (latest)));
{
auto transaction (system.nodes[0]->store.tx_begin (true));
ASSERT_EQ (nano::process_result::progress, system.nodes[0]->block_processor.process_one (transaction, send).code);
}
ASSERT_EQ (nano::genesis_amount - 100, system.nodes[0]->balance (nano::genesis_account));
ASSERT_EQ (nano::genesis_amount, system.nodes[1]->balance (nano::genesis_account));
system.wallet (0)->insert_adhoc (nano::test_genesis_key.prv);
system.wallet (0)->insert_adhoc (key.prv);
auto latest_block (system.wallet (0)->send_action (nano::test_genesis_key.pub, key.pub, 100));
ASSERT_NE (nullptr, latest_block);
ASSERT_EQ (nano::genesis_amount - 200, system.nodes[0]->balance (nano::genesis_account));
ASSERT_EQ (nano::genesis_amount, system.nodes[1]->balance (nano::genesis_account));
system.deadline_set (10s);
{
// The separate publish and vote system doesn't work very well here because it's instantly confirmed.
// We help it get the block and vote out here.
auto transaction (system.nodes[0]->store.tx_begin ());
system.nodes[0]->network.flood_block (latest_block);
}
while (system.nodes[1]->balance (nano::genesis_account) != nano::genesis_amount - 200)
{
ASSERT_NO_ERROR (system.poll ());
}
}
TEST (gap_cache, two_dependencies)
{
nano::system system (24000, 1);
nano::keypair key;
nano::genesis genesis;
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.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.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.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.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 ()));
ASSERT_TRUE (system.nodes[0]->store.block_exists (transaction, open->hash ()));
}