Skip to content

Commit

Permalink
Merge pull request nanocurrency#4553 from dsiganos/pending_key_info_i…
Browse files Browse the repository at this point in the history
…mprovements

Documentation for pending key and info classes and some other improvements whilst investigating
  • Loading branch information
dsiganos authored Apr 14, 2024
2 parents 30a0d1e + ded54b2 commit 804dcac
Show file tree
Hide file tree
Showing 7 changed files with 159 additions and 21 deletions.
1 change: 1 addition & 0 deletions nano/core_test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
99 changes: 99 additions & 0 deletions nano/core_test/receivable.cpp
Original file line number Diff line number Diff line change
@@ -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);
}
}
2 changes: 1 addition & 1 deletion nano/secure/ledger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion nano/secure/ledger.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class ledger final
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.
Expand Down
28 changes: 23 additions & 5 deletions nano/secure/pending_info.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand All @@ -27,10 +28,20 @@ class pending_info final
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:
Expand All @@ -40,9 +51,16 @@ class pending_key final
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
{
Expand Down
34 changes: 24 additions & 10 deletions nano/test_common/testutil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -300,32 +301,45 @@ 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;
}
}
}

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)
{
Expand Down
14 changes: 10 additions & 4 deletions nano/test_common/testutil.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ class network_params;
class vote;
class block;
class election;
class ledger;

extern nano::uint128_t const & genesis_amount;

Expand Down Expand Up @@ -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);
}
}

0 comments on commit 804dcac

Please sign in to comment.