Fix conflicts.add_two unit test (#4361)
* Add debugging convenience function nano::test::print_all_account_info to print the basic info of all accounts in the ledger. It is intended to be used from unit tests. * Introduce nano::test::setup_new_account() To make it easier to write unit tests * Fix unit test conflicts.add_two
This commit is contained in:
parent
978020e0f8
commit
4889d3cf91
5 changed files with 88 additions and 93 deletions
|
|
@ -1,6 +1,8 @@
|
|||
|
||||
#include <nano/node/election.hpp>
|
||||
#include <nano/node/scheduler/component.hpp>
|
||||
#include <nano/node/scheduler/priority.hpp>
|
||||
#include <nano/test_common/chains.hpp>
|
||||
#include <nano/test_common/system.hpp>
|
||||
#include <nano/test_common/testutil.hpp>
|
||||
|
||||
|
|
@ -89,91 +91,41 @@ TEST (conflicts, add_two)
|
|||
{
|
||||
nano::test::system system{};
|
||||
auto const & node = system.add_node ();
|
||||
nano::keypair key1, key2, key3;
|
||||
auto gk = nano::dev::genesis_key;
|
||||
|
||||
system.wallet (0)->insert_adhoc (nano::dev::genesis_key.prv);
|
||||
|
||||
// define a functor that sends from given account to given destination,
|
||||
// optionally force-confirming the send blocks *and* receiving on the destination account;
|
||||
// the functor returns a pair of the send and receive blocks created or nullptrs if something failed
|
||||
//
|
||||
auto const do_send = [&node, &system] (auto const & previous, auto const & from, auto const & to, bool forceConfirm = true)
|
||||
-> std::pair<std::optional<std::shared_ptr<nano::block>>, std::optional<std::shared_ptr<nano::block>>> {
|
||||
auto const send = nano::send_block_builder{}.make_block ().previous (previous).destination (to.pub).balance (0).sign (from.prv, from.pub).work (*system.work.generate (previous)).build_shared ();
|
||||
|
||||
if (nano::process_result::progress != node->process (*send).code)
|
||||
{
|
||||
return std::make_pair (std::nullopt, std::nullopt);
|
||||
}
|
||||
|
||||
if (!forceConfirm)
|
||||
{
|
||||
return std::make_pair (std::move (send), std::nullopt);
|
||||
}
|
||||
|
||||
auto const is_confirmed = [&node] (auto const & hash) {
|
||||
return node->block_confirmed (hash);
|
||||
};
|
||||
|
||||
node->process_confirmed (nano::election_status{ send });
|
||||
auto const is_send_not_confirmed = system.poll_until_true (5s, std::bind (is_confirmed, send->hash ()));
|
||||
if (is_send_not_confirmed)
|
||||
{
|
||||
return std::make_pair (std::nullopt, std::nullopt);
|
||||
}
|
||||
|
||||
auto const receive = nano::open_block_builder{}.make_block ().account (to.pub).source (send->hash ()).representative (to.pub).sign (to.prv, to.pub).work (*system.work.generate (to.pub)).build_shared ();
|
||||
|
||||
if (nano::process_result::progress != node->process (*receive).code)
|
||||
{
|
||||
return std::make_pair (std::nullopt, std::nullopt);
|
||||
}
|
||||
|
||||
node->process_confirmed (nano::election_status{ receive });
|
||||
auto const is_receive_not_confirmed = system.poll_until_true (5s, std::bind (is_confirmed, receive->hash ()));
|
||||
if (is_receive_not_confirmed)
|
||||
{
|
||||
return std::make_pair (std::move (send), std::nullopt);
|
||||
}
|
||||
|
||||
return std::make_pair (std::move (send), std::move (receive));
|
||||
};
|
||||
|
||||
// send from genesis to account1 and receive it on account1
|
||||
//
|
||||
nano::keypair account1{};
|
||||
auto const [send1, receive1] = do_send (nano::dev::genesis->hash (), nano::dev::genesis_key, account1);
|
||||
ASSERT_TRUE (send1.has_value () && receive1.has_value ());
|
||||
// both blocks having been fully confirmed, we expect 1 (genesis) + 2 (send/receive) = 3 cemented blocks
|
||||
//
|
||||
ASSERT_EQ (3, node->ledger.cache.cemented_count);
|
||||
|
||||
nano::keypair account2{};
|
||||
auto const [send2, receive2] = do_send ((*send1)->hash (), nano::dev::genesis_key, account2);
|
||||
ASSERT_TRUE (send2.has_value () && receive2.has_value ());
|
||||
// create 2 new accounts, that receive 1 raw each, all blocks are force confirmed
|
||||
auto [send1, open1] = nano::test::setup_new_account (system, *node, 1, gk, key1, gk.pub, true);
|
||||
auto [send2, open2] = nano::test::setup_new_account (system, *node, 1, gk, key2, gk.pub, true);
|
||||
ASSERT_EQ (5, node->ledger.cache.cemented_count);
|
||||
|
||||
// send from account1 to account3 but do not receive it on account3 and do not force-confirm the send block
|
||||
//
|
||||
nano::keypair account3{};
|
||||
auto const [send3, dummy1] = do_send ((*receive1)->hash (), account1, account3, false);
|
||||
ASSERT_TRUE (send3.has_value ());
|
||||
// expect the number of cemented blocks not to have changed since the last operation
|
||||
//
|
||||
ASSERT_EQ (5, node->ledger.cache.cemented_count);
|
||||
// send 1 raw to account key3 from key1
|
||||
auto send_a = nano::state_block_builder ()
|
||||
.account (key1.pub)
|
||||
.previous (open1->hash ())
|
||||
.representative (nano::dev::genesis_key.pub)
|
||||
.balance (0)
|
||||
.link (key3.pub)
|
||||
.sign (key1.prv, key1.pub)
|
||||
.work (*system.work.generate (open1->hash ()))
|
||||
.build_shared ();
|
||||
|
||||
auto const [send4, dummy2] = do_send ((*receive2)->hash (), account2, account3, false);
|
||||
ASSERT_TRUE (send4.has_value ());
|
||||
ASSERT_EQ (5, node->ledger.cache.cemented_count);
|
||||
// send 1 raw to account key3 from key2
|
||||
auto send_b = nano::state_block_builder ()
|
||||
.account (key2.pub)
|
||||
.previous (open2->hash ())
|
||||
.representative (nano::dev::genesis_key.pub)
|
||||
.balance (0)
|
||||
.link (key3.pub)
|
||||
.sign (key2.prv, key2.pub)
|
||||
.work (*system.work.generate (open2->hash ()))
|
||||
.build_shared ();
|
||||
|
||||
// activate elections for the previous two send blocks (to account3) that we did not forcefully confirm
|
||||
//
|
||||
node->scheduler.priority.activate (account3.pub, node->store.tx_begin_read ());
|
||||
ASSERT_TIMELY (5s, node->active.election ((*send3)->qualified_root ()) != nullptr);
|
||||
ASSERT_TIMELY (5s, node->active.election ((*send4)->qualified_root ()) != nullptr);
|
||||
|
||||
// wait 3s before asserting just to make sure there would be enough time
|
||||
// for the Active Elections Container to evict both elections in case they would wrongfully get confirmed
|
||||
//
|
||||
ASSERT_TRUE (nano::test::process (*node, { send_a, send_b }));
|
||||
ASSERT_TRUE (nano::test::start_elections (system, *node, { send_a, send_b }));
|
||||
ASSERT_TRUE (node->active.election (send_a->qualified_root ()));
|
||||
ASSERT_TRUE (node->active.election (send_b->qualified_root ()));
|
||||
ASSERT_TIMELY_EQ (5s, node->active.size (), 2);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -148,39 +148,42 @@ nano::block_list_t nano::test::setup_independent_blocks (nano::test::system & sy
|
|||
return blocks;
|
||||
}
|
||||
|
||||
nano::keypair nano::test::setup_rep (nano::test::system & system, nano::node & node, nano::uint128_t const amount, nano::keypair source)
|
||||
std::pair<std::shared_ptr<nano::block>, std::shared_ptr<nano::block>> nano::test::setup_new_account (nano::test::system & system, nano::node & node, nano::uint128_t const amount, nano::keypair source, nano::keypair dest, nano::account dest_rep, bool force_confirm)
|
||||
{
|
||||
auto latest = node.latest (source.pub);
|
||||
auto balance = node.balance (source.pub);
|
||||
|
||||
nano::keypair key;
|
||||
nano::block_builder builder;
|
||||
|
||||
auto send = builder
|
||||
auto send = nano::block_builder ()
|
||||
.state ()
|
||||
.account (source.pub)
|
||||
.previous (latest)
|
||||
.representative (source.pub)
|
||||
.balance (balance - amount)
|
||||
.link (key.pub)
|
||||
.link (dest.pub)
|
||||
.sign (source.prv, source.pub)
|
||||
.work (*system.work.generate (latest))
|
||||
.build_shared ();
|
||||
|
||||
auto open = builder
|
||||
auto open = nano::block_builder ()
|
||||
.state ()
|
||||
.account (key.pub)
|
||||
.account (dest.pub)
|
||||
.previous (0)
|
||||
.representative (key.pub)
|
||||
.representative (dest_rep)
|
||||
.balance (amount)
|
||||
.link (send->hash ())
|
||||
.sign (key.prv, key.pub)
|
||||
.work (*system.work.generate (key.pub))
|
||||
.sign (dest.prv, dest.pub)
|
||||
.work (*system.work.generate (dest.pub))
|
||||
.build_shared ();
|
||||
|
||||
EXPECT_TRUE (nano::test::process (node, { send, open }));
|
||||
EXPECT_TRUE (nano::test::start_elections (system, node, { send, open }, true));
|
||||
EXPECT_TRUE (nano::test::start_elections (system, node, { send, open }, force_confirm));
|
||||
EXPECT_TIMELY (5s, nano::test::confirmed (node, { send, open }));
|
||||
|
||||
return key;
|
||||
return std::make_pair (send, open);
|
||||
}
|
||||
|
||||
nano::keypair nano::test::setup_rep (nano::test::system & system, nano::node & node, nano::uint128_t const amount, nano::keypair source)
|
||||
{
|
||||
nano::keypair destkey;
|
||||
nano::test::setup_new_account (system, node, amount, source, destkey, destkey.pub, true);
|
||||
return destkey;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,6 +32,18 @@ std::vector<std::pair<nano::account, nano::block_list_t>> setup_chains (nano::te
|
|||
*/
|
||||
nano::block_list_t setup_independent_blocks (nano::test::system & system, nano::node & node, int count, nano::keypair source = nano::dev::genesis_key);
|
||||
|
||||
/**
|
||||
* \brief Create a pair of send/receive blocks to implement the transfer of "amount" raw from "source" to the unopened account "dest".
|
||||
* \param system
|
||||
* \param node
|
||||
* \param amount the amount of raw to transfer
|
||||
* \param source the source account
|
||||
* \param dest the destination account
|
||||
* \param dest_rep the rep that the dest account should have
|
||||
* \param force_confirm force confirm the blocks
|
||||
*/
|
||||
std::pair<std::shared_ptr<nano::block>, std::shared_ptr<nano::block>> setup_new_account (nano::test::system & system, nano::node & node, nano::uint128_t const amount, nano::keypair source, nano::keypair dest, nano::account dest_rep, bool force_confirm);
|
||||
|
||||
/**
|
||||
* Sends `amount` raw from `source` account chain into a newly created account and sets that account as its own representative
|
||||
* @return created representative
|
||||
|
|
|
|||
|
|
@ -244,3 +244,24 @@ bool nano::test::start_elections (nano::test::system & system_a, nano::node & no
|
|||
{
|
||||
return nano::test::start_elections (system_a, node_a, blocks_to_hashes (blocks_a), forced_a);
|
||||
}
|
||||
|
||||
void nano::test::print_all_account_info (nano::node & node)
|
||||
{
|
||||
auto const tx = node.ledger.store.tx_begin_read ();
|
||||
auto const end = node.ledger.store.account.end ();
|
||||
for (auto i = node.ledger.store.account.begin (tx); i != end; ++i)
|
||||
{
|
||||
nano::account acc = i->first;
|
||||
nano::account_info acc_info = i->second;
|
||||
nano::confirmation_height_info height_info;
|
||||
std::cout << "Account: " << acc.to_account () << std::endl;
|
||||
std::cout << " Unconfirmed Balance: " << acc_info.balance.to_string_dec () << std::endl;
|
||||
std::cout << " Confirmed Balance: " << node.ledger.account_balance (tx, acc, true) << std::endl;
|
||||
std::cout << " Block Count: " << acc_info.block_count << std::endl;
|
||||
if (!node.ledger.store.confirmation_height.get (tx, acc, height_info))
|
||||
{
|
||||
std::cout << " Conf. Height: " << height_info.height << std::endl;
|
||||
std::cout << " Conf. Frontier: " << height_info.frontier.to_string () << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -416,5 +416,12 @@ namespace test
|
|||
* NOTE: Each election is given 5 seconds to complete, if it does not complete in 5 seconds, it will return an error.
|
||||
*/
|
||||
[[nodiscard]] bool start_elections (nano::test::system &, nano::node &, std::vector<std::shared_ptr<nano::block>> const &, bool const forced_a = false);
|
||||
|
||||
/**
|
||||
* \brief Debugging function to print all accounts in a ledger. Intented to be used to debug unit tests.
|
||||
* \param ledger
|
||||
*/
|
||||
void print_all_account_info (nano::node & node);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue