Merge pull request #4553 from dsiganos/pending_key_info_improvements
Documentation for pending key and info classes and some other improvements whilst investigating
This commit is contained in:
commit
804dcaceb1
7 changed files with 159 additions and 21 deletions
|
@ -39,6 +39,7 @@ add_executable(
|
|||
processing_queue.cpp
|
||||
processor_service.cpp
|
||||
rep_crawler.cpp
|
||||
receivable.cpp
|
||||
peer_container.cpp
|
||||
rep_weight_store.cpp
|
||||
scheduler_buckets.cpp
|
||||
|
|
99
nano/core_test/receivable.cpp
Normal file
99
nano/core_test/receivable.cpp
Normal file
|
@ -0,0 +1,99 @@
|
|||
#include <nano/test_common/system.hpp>
|
||||
#include <nano/test_common/testutil.hpp>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
// this test sends 3 send blocks in 3 different epochs and checks that
|
||||
// the pending table records the epochs correctly for each send
|
||||
TEST (receivable, pending_table_query_epochs)
|
||||
{
|
||||
nano::test::system system{ 1 };
|
||||
auto & node = *system.nodes[0];
|
||||
nano::keypair key2;
|
||||
nano::block_builder builder;
|
||||
|
||||
// epoch 0 send
|
||||
auto send0 = builder
|
||||
.send ()
|
||||
.previous (nano::dev::genesis->hash ())
|
||||
.destination (key2.pub)
|
||||
.balance (nano::dev::constants.genesis_amount - 1)
|
||||
.sign (nano::dev::genesis_key.prv, nano::dev::genesis_key.pub)
|
||||
.work (*system.work.generate (nano::dev::genesis->hash ()))
|
||||
.build ();
|
||||
nano::test::process (node, { send0 });
|
||||
ASSERT_TIMELY (5s, nano::test::exists (node, { send0 }));
|
||||
|
||||
auto epoch1 = system.upgrade_genesis_epoch (node, nano::epoch::epoch_1);
|
||||
ASSERT_TRUE (epoch1);
|
||||
ASSERT_TIMELY (5s, nano::test::exists (node, { epoch1 }));
|
||||
|
||||
// epoch 1 send
|
||||
auto send1 = builder
|
||||
.state ()
|
||||
.account (nano::dev::genesis_key.pub)
|
||||
.representative (nano::dev::genesis_key.pub)
|
||||
.previous (epoch1->hash ())
|
||||
.link (key2.pub)
|
||||
.balance (nano::dev::constants.genesis_amount - 11)
|
||||
.sign (nano::dev::genesis_key.prv, nano::dev::genesis_key.pub)
|
||||
.work (*system.work.generate (epoch1->hash ()))
|
||||
.build ();
|
||||
ASSERT_TRUE (nano::test::process (node, { send1 }));
|
||||
ASSERT_TIMELY (5s, nano::test::exists (node, { send1 }));
|
||||
|
||||
auto epoch2 = system.upgrade_genesis_epoch (node, nano::epoch::epoch_2);
|
||||
ASSERT_TRUE (epoch2);
|
||||
ASSERT_TIMELY (5s, nano::test::exists (node, { epoch2 }));
|
||||
|
||||
// epoch 2 send
|
||||
auto send2 = builder
|
||||
.state ()
|
||||
.account (nano::dev::genesis_key.pub)
|
||||
.representative (nano::dev::genesis_key.pub)
|
||||
.previous (epoch2->hash ())
|
||||
.link (key2.pub)
|
||||
.balance (nano::dev::constants.genesis_amount - 111)
|
||||
.sign (nano::dev::genesis_key.prv, nano::dev::genesis_key.pub)
|
||||
.work (*system.work.generate (epoch2->hash ()))
|
||||
.build ();
|
||||
nano::test::process (node, { send2 });
|
||||
ASSERT_TIMELY (5s, nano::test::exists (node, { send2 }));
|
||||
|
||||
auto tx = node.store.tx_begin_read ();
|
||||
|
||||
// check epoch 0 send
|
||||
{
|
||||
nano::pending_key key{ key2.pub, send0->hash () };
|
||||
auto opt_info = node.store.pending.get (tx, key);
|
||||
ASSERT_TRUE (opt_info.has_value ());
|
||||
auto info = opt_info.value ();
|
||||
ASSERT_EQ (info.source, nano::dev::genesis_key.pub);
|
||||
ASSERT_EQ (info.amount, 1);
|
||||
ASSERT_EQ (info.epoch, nano::epoch::epoch_0);
|
||||
}
|
||||
|
||||
// check epoch 1 send
|
||||
{
|
||||
nano::pending_key key{ key2.pub, send1->hash () };
|
||||
auto opt_info = node.store.pending.get (tx, key);
|
||||
ASSERT_TRUE (opt_info.has_value ());
|
||||
auto info = opt_info.value ();
|
||||
ASSERT_EQ (info.source, nano::dev::genesis_key.pub);
|
||||
ASSERT_EQ (info.amount, 10);
|
||||
ASSERT_EQ (info.epoch, nano::epoch::epoch_1);
|
||||
}
|
||||
|
||||
// check epoch 2 send
|
||||
{
|
||||
nano::pending_key key{ key2.pub, send2->hash () };
|
||||
auto opt_info = node.store.pending.get (tx, key);
|
||||
ASSERT_TRUE (opt_info.has_value ());
|
||||
auto info = opt_info.value ();
|
||||
ASSERT_EQ (info.source, nano::dev::genesis_key.pub);
|
||||
ASSERT_EQ (info.amount, 100);
|
||||
ASSERT_EQ (info.epoch, nano::epoch::epoch_2);
|
||||
}
|
||||
}
|
|
@ -794,7 +794,7 @@ bool nano::ledger::block_exists (store::transaction const & transaction, nano::b
|
|||
}
|
||||
|
||||
// Balance for an account by account number
|
||||
nano::uint128_t nano::ledger::account_balance (store::transaction const & transaction_a, nano::account const & account_a, bool only_confirmed_a)
|
||||
nano::uint128_t nano::ledger::account_balance (store::transaction const & transaction_a, nano::account const & account_a, bool only_confirmed_a) const
|
||||
{
|
||||
nano::uint128_t result (0);
|
||||
if (only_confirmed_a)
|
||||
|
|
|
@ -43,7 +43,7 @@ public:
|
|||
std::optional<nano::uint128_t> balance (store::transaction const &, nano::block_hash const &) const;
|
||||
std::shared_ptr<nano::block> block (store::transaction const & transaction, nano::block_hash const & hash) const;
|
||||
bool block_exists (store::transaction const & transaction, nano::block_hash const & hash) const;
|
||||
nano::uint128_t account_balance (store::transaction const &, nano::account const &, bool = false);
|
||||
nano::uint128_t account_balance (store::transaction const &, nano::account const &, bool = false) const;
|
||||
nano::uint128_t account_receivable (store::transaction const &, nano::account const &, bool = false);
|
||||
/**
|
||||
* Returns the cached vote weight for the given representative.
|
||||
|
|
|
@ -18,6 +18,7 @@ namespace nano
|
|||
{
|
||||
/**
|
||||
* Information on an uncollected send
|
||||
* This class captures the data stored in a pending table entry
|
||||
*/
|
||||
class pending_info final
|
||||
{
|
||||
|
@ -27,10 +28,20 @@ public:
|
|||
size_t db_size () const;
|
||||
bool deserialize (nano::stream &);
|
||||
bool operator== (nano::pending_info const &) const;
|
||||
nano::account source{};
|
||||
nano::amount amount{ 0 };
|
||||
nano::epoch epoch{ nano::epoch::epoch_0 };
|
||||
nano::account source{}; // the account sending the funds
|
||||
nano::amount amount{ 0 }; // amount receivable in this transaction
|
||||
nano::epoch epoch{ nano::epoch::epoch_0 }; // epoch of sending block, this info is stored here to make it possible to prune the send block
|
||||
|
||||
friend std::ostream & operator<< (std::ostream & os, const nano::pending_info & info)
|
||||
{
|
||||
const int epoch = nano::normalized_epoch (info.epoch);
|
||||
os << "Source: " << info.source << ", Amount: " << info.amount.to_string_dec () << " Epoch: " << epoch;
|
||||
return os;
|
||||
}
|
||||
};
|
||||
|
||||
// This class represents the data written into the pending (receivable) database table key
|
||||
// the receiving account and hash of the send block identify a pending db table entry
|
||||
class pending_key final
|
||||
{
|
||||
public:
|
||||
|
@ -40,9 +51,16 @@ public:
|
|||
bool operator== (nano::pending_key const &) const;
|
||||
bool operator< (nano::pending_key const &) const;
|
||||
nano::account const & key () const;
|
||||
nano::account account{};
|
||||
nano::block_hash hash{ 0 };
|
||||
nano::account account{}; // receiving account
|
||||
nano::block_hash hash{ 0 }; // hash of the send block
|
||||
|
||||
friend std::ostream & operator<< (std::ostream & os, const nano::pending_key & key)
|
||||
{
|
||||
os << "Account: " << key.account << ", Hash: " << key.hash;
|
||||
return os;
|
||||
}
|
||||
};
|
||||
|
||||
// This class iterates receivable enttries for an account
|
||||
class receivable_iterator
|
||||
{
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include <nano/node/scheduler/priority.hpp>
|
||||
#include <nano/node/transport/fake.hpp>
|
||||
#include <nano/secure/ledger.hpp>
|
||||
#include <nano/secure/pending_info.hpp>
|
||||
#include <nano/store/block.hpp>
|
||||
#include <nano/test_common/system.hpp>
|
||||
#include <nano/test_common/testutil.hpp>
|
||||
|
@ -300,20 +301,33 @@ uint64_t nano::test::account_height (nano::node const & node, nano::account cons
|
|||
return height_info.height;
|
||||
}
|
||||
|
||||
void nano::test::print_all_account_info (nano::node & node)
|
||||
void nano::test::print_all_receivable_entries (const nano::store::component & store)
|
||||
{
|
||||
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)
|
||||
std::cout << "Printing all receivable entries:\n";
|
||||
auto const tx = store.tx_begin_read ();
|
||||
auto const end = store.pending.end ();
|
||||
for (auto i = store.pending.begin (tx); i != end; ++i)
|
||||
{
|
||||
std::cout << "Key: " << i->first << std::endl;
|
||||
std::cout << "Info: " << i->second << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void nano::test::print_all_account_info (const nano::ledger & ledger)
|
||||
{
|
||||
std::cout << "Printing all account info:\n";
|
||||
auto const tx = ledger.store.tx_begin_read ();
|
||||
auto const end = ledger.store.account.end ();
|
||||
for (auto i = 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 << " Confirmed Balance: " << 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))
|
||||
if (!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;
|
||||
|
@ -321,11 +335,11 @@ void nano::test::print_all_account_info (nano::node & node)
|
|||
}
|
||||
}
|
||||
|
||||
void nano::test::print_all_blocks (nano::node & node)
|
||||
void nano::test::print_all_blocks (const nano::store::component & store)
|
||||
{
|
||||
auto tx = node.store.tx_begin_read ();
|
||||
auto i = node.store.block.begin (tx);
|
||||
auto end = node.store.block.end ();
|
||||
auto tx = store.tx_begin_read ();
|
||||
auto i = store.block.begin (tx);
|
||||
auto end = store.block.end ();
|
||||
std::cout << "Listing all blocks" << std::endl;
|
||||
for (; i != end; ++i)
|
||||
{
|
||||
|
|
|
@ -169,6 +169,7 @@ class network_params;
|
|||
class vote;
|
||||
class block;
|
||||
class election;
|
||||
class ledger;
|
||||
|
||||
extern nano::uint128_t const & genesis_amount;
|
||||
|
||||
|
@ -418,13 +419,18 @@ namespace test
|
|||
uint64_t account_height (nano::node const & node, nano::account const & acc);
|
||||
|
||||
/**
|
||||
* \brief Debugging function to print all accounts in a ledger. Intented to be used to debug unit tests.
|
||||
* \brief Debugging function to print all entries in the pending table. Intended to be used to debug unit tests.
|
||||
*/
|
||||
void print_all_account_info (nano::node & node);
|
||||
void print_all_receivable_entries (const nano::store::component & store);
|
||||
|
||||
/**
|
||||
* \brief Debugging function to print all blocks in a node. Intented to be used to debug unit tests.
|
||||
* \brief Debugging function to print all accounts in a ledger. Intended to be used to debug unit tests.
|
||||
*/
|
||||
void print_all_blocks (nano::node & node);
|
||||
void print_all_account_info (const nano::ledger & ledger);
|
||||
|
||||
/**
|
||||
* \brief Debugging function to print all blocks in a node. Intended to be used to debug unit tests.
|
||||
*/
|
||||
void print_all_blocks (const nano::store::component & store);
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue