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