Add function ledger::account_info which encapsulates direct calls to store.account.get. Rather than directly accessing the block store, users should use the ledger interface to query for this information.
This commit is contained in:
		
					parent
					
						
							
								dd1d45a297
							
						
					
				
			
			
				commit
				
					
						6b41733dd0
					
				
			
		
					 14 changed files with 123 additions and 131 deletions
				
			
		| 
						 | 
				
			
			@ -353,9 +353,8 @@ void nano::bulk_pull_server::set_current_end ()
 | 
			
		|||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		nano::account_info info;
 | 
			
		||||
		auto no_address (connection->node->store.account.get (transaction, request->start.as_account (), info));
 | 
			
		||||
		if (no_address)
 | 
			
		||||
		auto info = connection->node->ledger.account_info (transaction, request->start.as_account ());
 | 
			
		||||
		if (!info)
 | 
			
		||||
		{
 | 
			
		||||
			if (connection->node->config.logging.bulk_pull_logging ())
 | 
			
		||||
			{
 | 
			
		||||
| 
						 | 
				
			
			@ -365,7 +364,7 @@ void nano::bulk_pull_server::set_current_end ()
 | 
			
		|||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			current = ascending () ? info.open_block : info.head;
 | 
			
		||||
			current = ascending () ? info->open_block : info->head;
 | 
			
		||||
			if (!request->end.is_zero ())
 | 
			
		||||
			{
 | 
			
		||||
				auto account (connection->node->ledger.account (transaction, request->end));
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -184,7 +184,7 @@ nano::asc_pull_ack nano::bootstrap_server::process (nano::transaction const & tr
 | 
			
		|||
		break;
 | 
			
		||||
		case asc_pull_req::hash_type::account:
 | 
			
		||||
		{
 | 
			
		||||
			auto info = store.account.get (transaction, request.start.as_account ());
 | 
			
		||||
			auto info = ledger.account_info (transaction, request.start.as_account ());
 | 
			
		||||
			if (info)
 | 
			
		||||
			{
 | 
			
		||||
				// Start from open block if pulling by account
 | 
			
		||||
| 
						 | 
				
			
			@ -278,7 +278,7 @@ nano::asc_pull_ack nano::bootstrap_server::process (const nano::transaction & tr
 | 
			
		|||
	nano::asc_pull_ack::account_info_payload response_payload{};
 | 
			
		||||
	response_payload.account = target;
 | 
			
		||||
 | 
			
		||||
	auto account_info = store.account.get (transaction, target);
 | 
			
		||||
	auto account_info = ledger.account_info (transaction, target);
 | 
			
		||||
	if (account_info)
 | 
			
		||||
	{
 | 
			
		||||
		response_payload.account_open = account_info->open_block;
 | 
			
		||||
| 
						 | 
				
			
			@ -297,4 +297,4 @@ nano::asc_pull_ack nano::bootstrap_server::process (const nano::transaction & tr
 | 
			
		|||
	response.payload = response_payload;
 | 
			
		||||
	response.update_header ();
 | 
			
		||||
	return response;
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -237,9 +237,9 @@ nano::block_hash nano::confirmation_height_bounded::get_least_unconfirmed_hash_f
 | 
			
		|||
	else
 | 
			
		||||
	{
 | 
			
		||||
		// No blocks have been confirmed, so the first block will be the open block
 | 
			
		||||
		nano::account_info account_info;
 | 
			
		||||
		release_assert (!ledger.store.account.get (transaction_a, account_a, account_info));
 | 
			
		||||
		least_unconfirmed_hash = account_info.open_block;
 | 
			
		||||
		auto info = ledger.account_info (transaction_a, account_a);
 | 
			
		||||
		release_assert (info);
 | 
			
		||||
		least_unconfirmed_hash = info->open_block;
 | 
			
		||||
		block_height_a = 1;
 | 
			
		||||
	}
 | 
			
		||||
	return least_unconfirmed_hash;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -24,15 +24,15 @@ void nano::election_scheduler::manual (std::shared_ptr<nano::block> const & bloc
 | 
			
		|||
bool nano::election_scheduler::activate (nano::account const & account_a, nano::transaction const & transaction)
 | 
			
		||||
{
 | 
			
		||||
	debug_assert (!account_a.is_zero ());
 | 
			
		||||
	nano::account_info account_info;
 | 
			
		||||
	if (!node.store.account.get (transaction, account_a, account_info))
 | 
			
		||||
	auto info = node.ledger.account_info (transaction, account_a);
 | 
			
		||||
	if (info)
 | 
			
		||||
	{
 | 
			
		||||
		nano::confirmation_height_info conf_info;
 | 
			
		||||
		node.store.confirmation_height.get (transaction, account_a, conf_info);
 | 
			
		||||
		if (conf_info.height < account_info.block_count)
 | 
			
		||||
		if (conf_info.height < info->block_count)
 | 
			
		||||
		{
 | 
			
		||||
			debug_assert (conf_info.frontier != account_info.head);
 | 
			
		||||
			auto hash = conf_info.height == 0 ? account_info.open_block : node.store.block.successor (transaction, conf_info.frontier);
 | 
			
		||||
			debug_assert (conf_info.frontier != info->head);
 | 
			
		||||
			auto hash = conf_info.height == 0 ? info->open_block : node.store.block.successor (transaction, conf_info.frontier);
 | 
			
		||||
			auto block = node.store.block.get (transaction, hash);
 | 
			
		||||
			debug_assert (block != nullptr);
 | 
			
		||||
			if (node.ledger.dependents_confirmed (transaction, *block))
 | 
			
		||||
| 
						 | 
				
			
			@ -40,7 +40,7 @@ bool nano::election_scheduler::activate (nano::account const & account_a, nano::
 | 
			
		|||
				auto balance = node.ledger.balance (transaction, hash);
 | 
			
		||||
				auto previous_balance = node.ledger.balance (transaction, conf_info.frontier);
 | 
			
		||||
				nano::lock_guard<nano::mutex> lock{ mutex };
 | 
			
		||||
				priority.push (account_info.modified, block, std::max (balance, previous_balance));
 | 
			
		||||
				priority.push (info->modified, block, std::max (balance, previous_balance));
 | 
			
		||||
				notify ();
 | 
			
		||||
				return true; // Activated
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -128,18 +128,18 @@ void nano::epoch_upgrader::upgrade_impl (nano::raw_key const & prv_a, nano::epoc
 | 
			
		|||
			for (auto i (accounts_list.get<modified_tag> ().begin ()), n (accounts_list.get<modified_tag> ().end ()); i != n && attempts < upgrade_batch_size && attempts < count_limit && !stopped; ++i)
 | 
			
		||||
			{
 | 
			
		||||
				auto transaction (store.tx_begin_read ());
 | 
			
		||||
				nano::account_info info;
 | 
			
		||||
				nano::account const & account (i->account);
 | 
			
		||||
				if (!store.account.get (transaction, account, info) && info.epoch () < epoch_a)
 | 
			
		||||
				auto info = ledger.account_info (transaction, account);
 | 
			
		||||
				if (info && info->epoch () < epoch_a)
 | 
			
		||||
				{
 | 
			
		||||
					++attempts;
 | 
			
		||||
					auto difficulty (node.network_params.work.threshold (nano::work_version::work_1, nano::block_details (epoch_a, false, false, true)));
 | 
			
		||||
					nano::root const & root (info.head);
 | 
			
		||||
					nano::root const & root (info->head);
 | 
			
		||||
					std::shared_ptr<nano::block> epoch = builder.state ()
 | 
			
		||||
														 .account (account)
 | 
			
		||||
														 .previous (info.head)
 | 
			
		||||
														 .representative (info.representative)
 | 
			
		||||
														 .balance (info.balance)
 | 
			
		||||
														 .previous (info->head)
 | 
			
		||||
														 .representative (info->representative)
 | 
			
		||||
														 .balance (info->balance)
 | 
			
		||||
														 .link (link)
 | 
			
		||||
														 .sign (raw_key, signer)
 | 
			
		||||
														 .work (0)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -261,11 +261,16 @@ nano::account_info nano::json_handler::account_info_impl (nano::transaction cons
 | 
			
		|||
	nano::account_info result;
 | 
			
		||||
	if (!ec)
 | 
			
		||||
	{
 | 
			
		||||
		if (node.store.account.get (transaction_a, account_a, result))
 | 
			
		||||
		auto info = node.ledger.account_info (transaction_a, account_a);
 | 
			
		||||
		if (!info)
 | 
			
		||||
		{
 | 
			
		||||
			ec = nano::error_common::account_not_found;
 | 
			
		||||
			node.bootstrap_initiator.bootstrap_lazy (account_a, false, account_a.to_account ());
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			result = *info;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return result;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -3377,14 +3382,14 @@ void nano::json_handler::receive ()
 | 
			
		|||
					auto work (work_optional_impl ());
 | 
			
		||||
					if (!ec && work)
 | 
			
		||||
					{
 | 
			
		||||
						nano::account_info info;
 | 
			
		||||
						nano::root head;
 | 
			
		||||
						nano::epoch epoch = pending_info.epoch;
 | 
			
		||||
						if (!node.store.account.get (block_transaction, account, info))
 | 
			
		||||
						auto info = node.ledger.account_info (block_transaction, account);
 | 
			
		||||
						if (info)
 | 
			
		||||
						{
 | 
			
		||||
							head = info.head;
 | 
			
		||||
							head = info->head;
 | 
			
		||||
							// When receiving, epoch version is the higher between the previous and the source blocks
 | 
			
		||||
							epoch = std::max (info.epoch (), epoch);
 | 
			
		||||
							epoch = std::max (info->epoch (), epoch);
 | 
			
		||||
						}
 | 
			
		||||
						else
 | 
			
		||||
						{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -783,11 +783,11 @@ nano::uint128_t nano::node::weight (nano::account const & account_a)
 | 
			
		|||
nano::block_hash nano::node::rep_block (nano::account const & account_a)
 | 
			
		||||
{
 | 
			
		||||
	auto const transaction (store.tx_begin_read ());
 | 
			
		||||
	nano::account_info info;
 | 
			
		||||
	nano::block_hash result (0);
 | 
			
		||||
	if (!store.account.get (transaction, account_a, info))
 | 
			
		||||
	auto info = ledger.account_info (transaction, account_a);
 | 
			
		||||
	if (info)
 | 
			
		||||
	{
 | 
			
		||||
		result = ledger.representative (transaction, info.head);
 | 
			
		||||
		result = ledger.representative (transaction, info->head);
 | 
			
		||||
	}
 | 
			
		||||
	return result;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -242,11 +242,10 @@ std::pair<std::vector<std::shared_ptr<nano::block>>, std::vector<std::shared_ptr
 | 
			
		|||
				// Search for account root
 | 
			
		||||
				if (successor.is_zero ())
 | 
			
		||||
				{
 | 
			
		||||
					nano::account_info info;
 | 
			
		||||
					auto error (ledger.store.account.get (transaction, root.as_account (), info));
 | 
			
		||||
					if (!error)
 | 
			
		||||
					auto info = ledger.account_info (transaction, root.as_account ());
 | 
			
		||||
					if (info)
 | 
			
		||||
					{
 | 
			
		||||
						successor = info.open_block;
 | 
			
		||||
						successor = info->open_block;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				if (!successor.is_zero ())
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -849,12 +849,11 @@ std::shared_ptr<nano::block> nano::wallet::receive_action (nano::block_hash cons
 | 
			
		|||
					{
 | 
			
		||||
						store.work_get (transaction, account_a, work_a);
 | 
			
		||||
					}
 | 
			
		||||
					nano::account_info info;
 | 
			
		||||
					auto new_account (wallets.node.ledger.store.account.get (block_transaction, account_a, info));
 | 
			
		||||
					if (!new_account)
 | 
			
		||||
					auto info = wallets.node.ledger.account_info (block_transaction, account_a);
 | 
			
		||||
					if (info)
 | 
			
		||||
					{
 | 
			
		||||
						block = std::make_shared<nano::state_block> (account_a, info.head, info.representative, info.balance.number () + pending_info.amount.number (), send_hash_a, prv, account_a, work_a);
 | 
			
		||||
						details.epoch = std::max (info.epoch (), pending_info.epoch);
 | 
			
		||||
						block = std::make_shared<nano::state_block> (account_a, info->head, info->representative, info->balance.number () + pending_info.amount.number (), send_hash_a, prv, account_a, work_a);
 | 
			
		||||
						details.epoch = std::max (info->epoch (), pending_info.epoch);
 | 
			
		||||
					}
 | 
			
		||||
					else
 | 
			
		||||
					{
 | 
			
		||||
| 
						 | 
				
			
			@ -905,10 +904,8 @@ std::shared_ptr<nano::block> nano::wallet::change_action (nano::account const &
 | 
			
		|||
			auto existing (store.find (transaction, source_a));
 | 
			
		||||
			if (existing != store.end () && !wallets.node.ledger.latest (block_transaction, source_a).is_zero ())
 | 
			
		||||
			{
 | 
			
		||||
				nano::account_info info;
 | 
			
		||||
				auto error1 (wallets.node.ledger.store.account.get (block_transaction, source_a, info));
 | 
			
		||||
				(void)error1;
 | 
			
		||||
				debug_assert (!error1);
 | 
			
		||||
				auto info = wallets.node.ledger.account_info (block_transaction, source_a);
 | 
			
		||||
				debug_assert (info);
 | 
			
		||||
				nano::raw_key prv;
 | 
			
		||||
				auto error2 (store.fetch (transaction, source_a, prv));
 | 
			
		||||
				(void)error2;
 | 
			
		||||
| 
						 | 
				
			
			@ -917,8 +914,8 @@ std::shared_ptr<nano::block> nano::wallet::change_action (nano::account const &
 | 
			
		|||
				{
 | 
			
		||||
					store.work_get (transaction, source_a, work_a);
 | 
			
		||||
				}
 | 
			
		||||
				block = std::make_shared<nano::state_block> (source_a, info.head, representative_a, info.balance, 0, prv, source_a, work_a);
 | 
			
		||||
				details.epoch = info.epoch ();
 | 
			
		||||
				block = std::make_shared<nano::state_block> (source_a, info->head, representative_a, info->balance, 0, prv, source_a, work_a);
 | 
			
		||||
				details.epoch = info->epoch ();
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -977,10 +974,8 @@ std::shared_ptr<nano::block> nano::wallet::send_action (nano::account const & so
 | 
			
		|||
					auto balance (wallets.node.ledger.account_balance (block_transaction, source_a));
 | 
			
		||||
					if (!balance.is_zero () && balance >= amount_a)
 | 
			
		||||
					{
 | 
			
		||||
						nano::account_info info;
 | 
			
		||||
						auto error1 (wallets.node.ledger.store.account.get (block_transaction, source_a, info));
 | 
			
		||||
						(void)error1;
 | 
			
		||||
						debug_assert (!error1);
 | 
			
		||||
						auto info = wallets.node.ledger.account_info (block_transaction, source_a);
 | 
			
		||||
						debug_assert (info);
 | 
			
		||||
						nano::raw_key prv;
 | 
			
		||||
						auto error2 (store.fetch (transaction, source_a, prv));
 | 
			
		||||
						(void)error2;
 | 
			
		||||
| 
						 | 
				
			
			@ -989,8 +984,8 @@ std::shared_ptr<nano::block> nano::wallet::send_action (nano::account const & so
 | 
			
		|||
						{
 | 
			
		||||
							store.work_get (transaction, source_a, work_a);
 | 
			
		||||
						}
 | 
			
		||||
						block = std::make_shared<nano::state_block> (source_a, info.head, info.representative, balance - amount_a, account_a, prv, source_a, work_a);
 | 
			
		||||
						details.epoch = info.epoch ();
 | 
			
		||||
						block = std::make_shared<nano::state_block> (source_a, info->head, info->representative, balance - amount_a, account_a, prv, source_a, work_a);
 | 
			
		||||
						details.epoch = info->epoch ();
 | 
			
		||||
						if (id_mdb_val && block != nullptr)
 | 
			
		||||
						{
 | 
			
		||||
							auto status (mdb_put (wallets.env.tx (transaction), wallets.node.wallets.send_action_ids, *id_mdb_val, nano::mdb_val (block->hash ()), 0));
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -730,10 +730,10 @@ TEST (rpc, wallet_representative_set_force)
 | 
			
		|||
	while (representative != key.pub)
 | 
			
		||||
	{
 | 
			
		||||
		auto transaction (node->store.tx_begin_read ());
 | 
			
		||||
		nano::account_info info;
 | 
			
		||||
		if (!node->store.account.get (transaction, nano::dev::genesis_key.pub, info))
 | 
			
		||||
		auto info = node->ledger.account_info (transaction, nano::dev::genesis_key.pub);
 | 
			
		||||
		if (info)
 | 
			
		||||
		{
 | 
			
		||||
			representative = info.representative;
 | 
			
		||||
			representative = info->representative;
 | 
			
		||||
		}
 | 
			
		||||
		ASSERT_NO_ERROR (system.poll ());
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -34,13 +34,12 @@ public:
 | 
			
		|||
		}
 | 
			
		||||
		if (!error)
 | 
			
		||||
		{
 | 
			
		||||
			nano::account_info info;
 | 
			
		||||
			[[maybe_unused]] auto error (ledger.store.account.get (transaction, pending.source, info));
 | 
			
		||||
			debug_assert (!error);
 | 
			
		||||
			auto info = ledger.account_info (transaction, pending.source);
 | 
			
		||||
			debug_assert (info);
 | 
			
		||||
			ledger.store.pending.del (transaction, key);
 | 
			
		||||
			ledger.cache.rep_weights.representation_add (info.representative, pending.amount.number ());
 | 
			
		||||
			nano::account_info new_info (block_a.hashables.previous, info.representative, info.open_block, ledger.balance (transaction, block_a.hashables.previous), nano::seconds_since_epoch (), info.block_count - 1, nano::epoch::epoch_0);
 | 
			
		||||
			ledger.update_account (transaction, pending.source, info, new_info);
 | 
			
		||||
			ledger.cache.rep_weights.representation_add (info->representative, pending.amount.number ());
 | 
			
		||||
			nano::account_info new_info (block_a.hashables.previous, info->representative, info->open_block, ledger.balance (transaction, block_a.hashables.previous), nano::seconds_since_epoch (), info->block_count - 1, nano::epoch::epoch_0);
 | 
			
		||||
			ledger.update_account (transaction, pending.source, *info, new_info);
 | 
			
		||||
			ledger.store.block.del (transaction, hash);
 | 
			
		||||
			ledger.store.frontier.del (transaction, hash);
 | 
			
		||||
			ledger.store.frontier.put (transaction, block_a.hashables.previous, pending.source);
 | 
			
		||||
| 
						 | 
				
			
			@ -56,12 +55,11 @@ public:
 | 
			
		|||
		// Pending account entry can be incorrect if source block was pruned. But it's not affecting correct ledger processing
 | 
			
		||||
		[[maybe_unused]] bool is_pruned (false);
 | 
			
		||||
		auto source_account (ledger.account_safe (transaction, block_a.hashables.source, is_pruned));
 | 
			
		||||
		nano::account_info info;
 | 
			
		||||
		[[maybe_unused]] auto error (ledger.store.account.get (transaction, destination_account, info));
 | 
			
		||||
		debug_assert (!error);
 | 
			
		||||
		ledger.cache.rep_weights.representation_add (info.representative, 0 - amount);
 | 
			
		||||
		nano::account_info new_info (block_a.hashables.previous, info.representative, info.open_block, ledger.balance (transaction, block_a.hashables.previous), nano::seconds_since_epoch (), info.block_count - 1, nano::epoch::epoch_0);
 | 
			
		||||
		ledger.update_account (transaction, destination_account, info, new_info);
 | 
			
		||||
		auto info = ledger.account_info (transaction, destination_account);
 | 
			
		||||
		debug_assert (info);
 | 
			
		||||
		ledger.cache.rep_weights.representation_add (info->representative, 0 - amount);
 | 
			
		||||
		nano::account_info new_info (block_a.hashables.previous, info->representative, info->open_block, ledger.balance (transaction, block_a.hashables.previous), nano::seconds_since_epoch (), info->block_count - 1, nano::epoch::epoch_0);
 | 
			
		||||
		ledger.update_account (transaction, destination_account, *info, new_info);
 | 
			
		||||
		ledger.store.block.del (transaction, hash);
 | 
			
		||||
		ledger.store.pending.put (transaction, nano::pending_key (destination_account, block_a.hashables.source), { source_account, amount, nano::epoch::epoch_0 });
 | 
			
		||||
		ledger.store.frontier.del (transaction, hash);
 | 
			
		||||
| 
						 | 
				
			
			@ -90,17 +88,16 @@ public:
 | 
			
		|||
		auto hash (block_a.hash ());
 | 
			
		||||
		auto rep_block (ledger.representative (transaction, block_a.hashables.previous));
 | 
			
		||||
		auto account (ledger.account (transaction, block_a.hashables.previous));
 | 
			
		||||
		nano::account_info info;
 | 
			
		||||
		[[maybe_unused]] auto error (ledger.store.account.get (transaction, account, info));
 | 
			
		||||
		debug_assert (!error);
 | 
			
		||||
		auto info = ledger.account_info (transaction, account);
 | 
			
		||||
		debug_assert (info);
 | 
			
		||||
		auto balance (ledger.balance (transaction, block_a.hashables.previous));
 | 
			
		||||
		auto block = ledger.store.block.get (transaction, rep_block);
 | 
			
		||||
		release_assert (block != nullptr);
 | 
			
		||||
		auto representative = block->representative ();
 | 
			
		||||
		ledger.cache.rep_weights.representation_add_dual (block_a.representative (), 0 - balance, representative, balance);
 | 
			
		||||
		ledger.store.block.del (transaction, hash);
 | 
			
		||||
		nano::account_info new_info (block_a.hashables.previous, representative, info.open_block, info.balance, nano::seconds_since_epoch (), info.block_count - 1, nano::epoch::epoch_0);
 | 
			
		||||
		ledger.update_account (transaction, account, info, new_info);
 | 
			
		||||
		nano::account_info new_info (block_a.hashables.previous, representative, info->open_block, info->balance, nano::seconds_since_epoch (), info->block_count - 1, nano::epoch::epoch_0);
 | 
			
		||||
		ledger.update_account (transaction, account, *info, new_info);
 | 
			
		||||
		ledger.store.frontier.del (transaction, hash);
 | 
			
		||||
		ledger.store.frontier.put (transaction, block_a.hashables.previous, account);
 | 
			
		||||
		ledger.store.block.successor_clear (transaction, block_a.hashables.previous);
 | 
			
		||||
| 
						 | 
				
			
			@ -131,8 +128,8 @@ public:
 | 
			
		|||
			ledger.cache.rep_weights.representation_add (block_a.representative (), 0 - block_a.hashables.balance.number ());
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		nano::account_info info;
 | 
			
		||||
		auto error (ledger.store.account.get (transaction, block_a.hashables.account, info));
 | 
			
		||||
		auto info = ledger.account_info (transaction, block_a.hashables.account);
 | 
			
		||||
		debug_assert (info);
 | 
			
		||||
 | 
			
		||||
		if (is_send)
 | 
			
		||||
		{
 | 
			
		||||
| 
						 | 
				
			
			@ -156,8 +153,8 @@ public:
 | 
			
		|||
 | 
			
		||||
		debug_assert (!error);
 | 
			
		||||
		auto previous_version (ledger.store.block.version (transaction, block_a.hashables.previous));
 | 
			
		||||
		nano::account_info new_info (block_a.hashables.previous, representative, info.open_block, balance, nano::seconds_since_epoch (), info.block_count - 1, previous_version);
 | 
			
		||||
		ledger.update_account (transaction, block_a.hashables.account, info, new_info);
 | 
			
		||||
		nano::account_info new_info (block_a.hashables.previous, representative, info->open_block, balance, nano::seconds_since_epoch (), info->block_count - 1, previous_version);
 | 
			
		||||
		ledger.update_account (transaction, block_a.hashables.account, *info, new_info);
 | 
			
		||||
 | 
			
		||||
		auto previous (ledger.store.block.get (transaction, block_a.hashables.previous));
 | 
			
		||||
		if (previous != nullptr)
 | 
			
		||||
| 
						 | 
				
			
			@ -461,11 +458,9 @@ void ledger_processor::change_block (nano::change_block & block_a)
 | 
			
		|||
				result.code = account.is_zero () ? nano::process_result::fork : nano::process_result::progress;
 | 
			
		||||
				if (result.code == nano::process_result::progress)
 | 
			
		||||
				{
 | 
			
		||||
					nano::account_info info;
 | 
			
		||||
					auto latest_error (ledger.store.account.get (transaction, account, info));
 | 
			
		||||
					(void)latest_error;
 | 
			
		||||
					debug_assert (!latest_error);
 | 
			
		||||
					debug_assert (info.head == block_a.hashables.previous);
 | 
			
		||||
					auto info = ledger.account_info (transaction, account);
 | 
			
		||||
					debug_assert (info);
 | 
			
		||||
					debug_assert (info->head == block_a.hashables.previous);
 | 
			
		||||
					result.code = validate_message (account, hash, block_a.signature) ? nano::process_result::bad_signature : nano::process_result::progress; // Is this block signed correctly (Malformed)
 | 
			
		||||
					if (result.code == nano::process_result::progress)
 | 
			
		||||
					{
 | 
			
		||||
| 
						 | 
				
			
			@ -474,12 +469,12 @@ void ledger_processor::change_block (nano::change_block & block_a)
 | 
			
		|||
						if (result.code == nano::process_result::progress)
 | 
			
		||||
						{
 | 
			
		||||
							debug_assert (!validate_message (account, hash, block_a.signature));
 | 
			
		||||
							block_a.sideband_set (nano::block_sideband (account, 0, info.balance, info.block_count + 1, nano::seconds_since_epoch (), block_details, nano::epoch::epoch_0 /* unused */));
 | 
			
		||||
							block_a.sideband_set (nano::block_sideband (account, 0, info->balance, info->block_count + 1, nano::seconds_since_epoch (), block_details, nano::epoch::epoch_0 /* unused */));
 | 
			
		||||
							ledger.store.block.put (transaction, hash, block_a);
 | 
			
		||||
							auto balance (ledger.balance (transaction, block_a.hashables.previous));
 | 
			
		||||
							ledger.cache.rep_weights.representation_add_dual (block_a.representative (), balance, info.representative, 0 - balance);
 | 
			
		||||
							nano::account_info new_info (hash, block_a.representative (), info.open_block, info.balance, nano::seconds_since_epoch (), info.block_count + 1, nano::epoch::epoch_0);
 | 
			
		||||
							ledger.update_account (transaction, account, info, new_info);
 | 
			
		||||
							ledger.cache.rep_weights.representation_add_dual (block_a.representative (), balance, info->representative, 0 - balance);
 | 
			
		||||
							nano::account_info new_info (hash, block_a.representative (), info->open_block, info->balance, nano::seconds_since_epoch (), info->block_count + 1, nano::epoch::epoch_0);
 | 
			
		||||
							ledger.update_account (transaction, account, *info, new_info);
 | 
			
		||||
							ledger.store.frontier.del (transaction, block_a.hashables.previous);
 | 
			
		||||
							ledger.store.frontier.put (transaction, hash, account);
 | 
			
		||||
							ledger.stats.inc (nano::stat::type::ledger, nano::stat::detail::change);
 | 
			
		||||
| 
						 | 
				
			
			@ -517,20 +512,18 @@ void ledger_processor::send_block (nano::send_block & block_a)
 | 
			
		|||
						if (result.code == nano::process_result::progress)
 | 
			
		||||
						{
 | 
			
		||||
							debug_assert (!validate_message (account, hash, block_a.signature));
 | 
			
		||||
							nano::account_info info;
 | 
			
		||||
							auto latest_error (ledger.store.account.get (transaction, account, info));
 | 
			
		||||
							(void)latest_error;
 | 
			
		||||
							debug_assert (!latest_error);
 | 
			
		||||
							debug_assert (info.head == block_a.hashables.previous);
 | 
			
		||||
							result.code = info.balance.number () >= block_a.hashables.balance.number () ? nano::process_result::progress : nano::process_result::negative_spend; // Is this trying to spend a negative amount (Malicious)
 | 
			
		||||
							auto info = ledger.account_info (transaction, account);
 | 
			
		||||
							debug_assert (info);
 | 
			
		||||
							debug_assert (info->head == block_a.hashables.previous);
 | 
			
		||||
							result.code = info->balance.number () >= block_a.hashables.balance.number () ? nano::process_result::progress : nano::process_result::negative_spend; // Is this trying to spend a negative amount (Malicious)
 | 
			
		||||
							if (result.code == nano::process_result::progress)
 | 
			
		||||
							{
 | 
			
		||||
								auto amount (info.balance.number () - block_a.hashables.balance.number ());
 | 
			
		||||
								ledger.cache.rep_weights.representation_add (info.representative, 0 - amount);
 | 
			
		||||
								block_a.sideband_set (nano::block_sideband (account, 0, block_a.hashables.balance /* unused */, info.block_count + 1, nano::seconds_since_epoch (), block_details, nano::epoch::epoch_0 /* unused */));
 | 
			
		||||
								auto amount (info->balance.number () - block_a.hashables.balance.number ());
 | 
			
		||||
								ledger.cache.rep_weights.representation_add (info->representative, 0 - amount);
 | 
			
		||||
								block_a.sideband_set (nano::block_sideband (account, 0, block_a.hashables.balance /* unused */, info->block_count + 1, nano::seconds_since_epoch (), block_details, nano::epoch::epoch_0 /* unused */));
 | 
			
		||||
								ledger.store.block.put (transaction, hash, block_a);
 | 
			
		||||
								nano::account_info new_info (hash, info.representative, info.open_block, block_a.hashables.balance, nano::seconds_since_epoch (), info.block_count + 1, nano::epoch::epoch_0);
 | 
			
		||||
								ledger.update_account (transaction, account, info, new_info);
 | 
			
		||||
								nano::account_info new_info (hash, info->representative, info->open_block, block_a.hashables.balance, nano::seconds_since_epoch (), info->block_count + 1, nano::epoch::epoch_0);
 | 
			
		||||
								ledger.update_account (transaction, account, *info, new_info);
 | 
			
		||||
								ledger.store.pending.put (transaction, nano::pending_key (block_a.hashables.destination, hash), { account, amount, nano::epoch::epoch_0 });
 | 
			
		||||
								ledger.store.frontier.del (transaction, block_a.hashables.previous);
 | 
			
		||||
								ledger.store.frontier.put (transaction, hash, account);
 | 
			
		||||
| 
						 | 
				
			
			@ -569,9 +562,9 @@ void ledger_processor::receive_block (nano::receive_block & block_a)
 | 
			
		|||
						result.code = ledger.block_or_pruned_exists (transaction, block_a.hashables.source) ? nano::process_result::progress : nano::process_result::gap_source; // Have we seen the source block already? (Harmless)
 | 
			
		||||
						if (result.code == nano::process_result::progress)
 | 
			
		||||
						{
 | 
			
		||||
							nano::account_info info;
 | 
			
		||||
							ledger.store.account.get (transaction, account, info);
 | 
			
		||||
							result.code = info.head == block_a.hashables.previous ? nano::process_result::progress : nano::process_result::gap_previous; // Block doesn't immediately follow latest block (Harmless)
 | 
			
		||||
							auto info = ledger.account_info (transaction, account);
 | 
			
		||||
							debug_assert (info);
 | 
			
		||||
							result.code = info->head == block_a.hashables.previous ? nano::process_result::progress : nano::process_result::gap_previous; // Block doesn't immediately follow latest block (Harmless)
 | 
			
		||||
							if (result.code == nano::process_result::progress)
 | 
			
		||||
							{
 | 
			
		||||
								nano::pending_key key (account, block_a.hashables.source);
 | 
			
		||||
| 
						 | 
				
			
			@ -586,7 +579,7 @@ void ledger_processor::receive_block (nano::receive_block & block_a)
 | 
			
		|||
										result.code = ledger.constants.work.difficulty (block_a) >= ledger.constants.work.threshold (block_a.work_version (), block_details) ? nano::process_result::progress : nano::process_result::insufficient_work; // Does this block have sufficient work? (Malformed)
 | 
			
		||||
										if (result.code == nano::process_result::progress)
 | 
			
		||||
										{
 | 
			
		||||
											auto new_balance (info.balance.number () + pending.amount.number ());
 | 
			
		||||
											auto new_balance (info->balance.number () + pending.amount.number ());
 | 
			
		||||
#ifdef NDEBUG
 | 
			
		||||
											if (ledger.store.block.exists (transaction, block_a.hashables.source))
 | 
			
		||||
											{
 | 
			
		||||
| 
						 | 
				
			
			@ -596,11 +589,11 @@ void ledger_processor::receive_block (nano::receive_block & block_a)
 | 
			
		|||
											}
 | 
			
		||||
#endif
 | 
			
		||||
											ledger.store.pending.del (transaction, key);
 | 
			
		||||
											block_a.sideband_set (nano::block_sideband (account, 0, new_balance, info.block_count + 1, nano::seconds_since_epoch (), block_details, nano::epoch::epoch_0 /* unused */));
 | 
			
		||||
											block_a.sideband_set (nano::block_sideband (account, 0, new_balance, info->block_count + 1, nano::seconds_since_epoch (), block_details, nano::epoch::epoch_0 /* unused */));
 | 
			
		||||
											ledger.store.block.put (transaction, hash, block_a);
 | 
			
		||||
											nano::account_info new_info (hash, info.representative, info.open_block, new_balance, nano::seconds_since_epoch (), info.block_count + 1, nano::epoch::epoch_0);
 | 
			
		||||
											ledger.update_account (transaction, account, info, new_info);
 | 
			
		||||
											ledger.cache.rep_weights.representation_add (info.representative, pending.amount.number ());
 | 
			
		||||
											nano::account_info new_info (hash, info->representative, info->open_block, new_balance, nano::seconds_since_epoch (), info->block_count + 1, nano::epoch::epoch_0);
 | 
			
		||||
											ledger.update_account (transaction, account, *info, new_info);
 | 
			
		||||
											ledger.cache.rep_weights.representation_add (info->representative, pending.amount.number ());
 | 
			
		||||
											ledger.store.frontier.del (transaction, block_a.hashables.previous);
 | 
			
		||||
											ledger.store.frontier.put (transaction, hash, account);
 | 
			
		||||
											ledger.stats.inc (nano::stat::type::ledger, nano::stat::detail::receive);
 | 
			
		||||
| 
						 | 
				
			
			@ -779,11 +772,10 @@ nano::uint128_t nano::ledger::account_balance (nano::transaction const & transac
 | 
			
		|||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		nano::account_info info;
 | 
			
		||||
		auto none (store.account.get (transaction_a, account_a, info));
 | 
			
		||||
		if (!none)
 | 
			
		||||
		auto info = account_info (transaction_a, account_a);
 | 
			
		||||
		if (info)
 | 
			
		||||
		{
 | 
			
		||||
			result = info.balance.number ();
 | 
			
		||||
			result = info->balance.number ();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return result;
 | 
			
		||||
| 
						 | 
				
			
			@ -998,7 +990,6 @@ bool nano::ledger::rollback (nano::write_transaction const & transaction_a, nano
 | 
			
		|||
	auto account_l (account (transaction_a, block_a));
 | 
			
		||||
	auto block_account_height (store.block.account_height (transaction_a, block_a));
 | 
			
		||||
	rollback_visitor rollback (transaction_a, *this, list_a);
 | 
			
		||||
	nano::account_info account_info;
 | 
			
		||||
	auto error (false);
 | 
			
		||||
	while (!error && store.block.exists (transaction_a, block_a))
 | 
			
		||||
	{
 | 
			
		||||
| 
						 | 
				
			
			@ -1006,9 +997,9 @@ bool nano::ledger::rollback (nano::write_transaction const & transaction_a, nano
 | 
			
		|||
		store.confirmation_height.get (transaction_a, account_l, confirmation_height_info);
 | 
			
		||||
		if (block_account_height > confirmation_height_info.height)
 | 
			
		||||
		{
 | 
			
		||||
			auto latest_error = store.account.get (transaction_a, account_l, account_info);
 | 
			
		||||
			debug_assert (!latest_error);
 | 
			
		||||
			auto block (store.block.get (transaction_a, account_info.head));
 | 
			
		||||
			auto info = account_info (transaction_a, account_l);
 | 
			
		||||
			debug_assert (info);
 | 
			
		||||
			auto block (store.block.get (transaction_a, info->head));
 | 
			
		||||
			list_a.push_back (block);
 | 
			
		||||
			block->visit (rollback);
 | 
			
		||||
			error = rollback.error;
 | 
			
		||||
| 
						 | 
				
			
			@ -1070,6 +1061,11 @@ nano::account nano::ledger::account_safe (const nano::transaction & transaction,
 | 
			
		|||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::optional<nano::account_info> nano::ledger::account_info (nano::transaction const & transaction, nano::account const & account) const
 | 
			
		||||
{
 | 
			
		||||
	return store.account.get (transaction, account);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Return amount decrease or increase for block
 | 
			
		||||
nano::uint128_t nano::ledger::amount (nano::transaction const & transaction_a, nano::account const & account_a)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -1098,22 +1094,21 @@ nano::uint128_t nano::ledger::amount_safe (nano::transaction const & transaction
 | 
			
		|||
// Return latest block for account
 | 
			
		||||
nano::block_hash nano::ledger::latest (nano::transaction const & transaction_a, nano::account const & account_a)
 | 
			
		||||
{
 | 
			
		||||
	nano::account_info info;
 | 
			
		||||
	auto latest_error (store.account.get (transaction_a, account_a, info));
 | 
			
		||||
	return latest_error ? 0 : info.head;
 | 
			
		||||
	auto info = account_info (transaction_a, account_a);
 | 
			
		||||
	return !info ? 0 : info->head;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Return latest root for account, account number if there are no blocks for this account.
 | 
			
		||||
nano::root nano::ledger::latest_root (nano::transaction const & transaction_a, nano::account const & account_a)
 | 
			
		||||
{
 | 
			
		||||
	nano::account_info info;
 | 
			
		||||
	if (store.account.get (transaction_a, account_a, info))
 | 
			
		||||
	auto info = account_info (transaction_a, account_a);
 | 
			
		||||
	if (!info)
 | 
			
		||||
	{
 | 
			
		||||
		return account_a;
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		return info.head;
 | 
			
		||||
		return info->head;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1331,11 +1326,9 @@ std::shared_ptr<nano::block> nano::ledger::forked_block (nano::transaction const
 | 
			
		|||
	auto result (store.block.get (transaction_a, store.block.successor (transaction_a, root.as_block_hash ())));
 | 
			
		||||
	if (result == nullptr)
 | 
			
		||||
	{
 | 
			
		||||
		nano::account_info info;
 | 
			
		||||
		auto error (store.account.get (transaction_a, root.as_account (), info));
 | 
			
		||||
		(void)error;
 | 
			
		||||
		debug_assert (!error);
 | 
			
		||||
		result = store.block.get (transaction_a, info.open_block);
 | 
			
		||||
		auto info = account_info (transaction_a, root.as_account ());
 | 
			
		||||
		debug_assert (info);
 | 
			
		||||
		result = store.block.get (transaction_a, info->open_block);
 | 
			
		||||
		debug_assert (result != nullptr);
 | 
			
		||||
	}
 | 
			
		||||
	return result;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -32,6 +32,7 @@ public:
 | 
			
		|||
	 * Return account containing hash, expects that block hash exists in ledger
 | 
			
		||||
	 */
 | 
			
		||||
	nano::account account (nano::transaction const &, nano::block_hash const &) const;
 | 
			
		||||
 	std::optional<nano::account_info> account_info (nano::transaction const & transaction, nano::account const & account) const;
 | 
			
		||||
	/**
 | 
			
		||||
	 * For non-prunning nodes same as `ledger::account()`
 | 
			
		||||
	 * For prunning nodes ensures that block hash exists, otherwise returns zero account
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -907,17 +907,18 @@ TEST (confirmation_height, long_chains)
 | 
			
		|||
	ASSERT_TIMELY (30s, node->ledger.block_confirmed (node->store.tx_begin_read (), receive1->hash ()));
 | 
			
		||||
 | 
			
		||||
	auto transaction (node->store.tx_begin_read ());
 | 
			
		||||
	nano::account_info account_info;
 | 
			
		||||
	ASSERT_FALSE (node->store.account.get (transaction, nano::dev::genesis_key.pub, account_info));
 | 
			
		||||
	auto info = node->ledger.account_info (transaction, nano::dev::genesis_key.pub);
 | 
			
		||||
	ASSERT_TRUE (info);
 | 
			
		||||
	nano::confirmation_height_info confirmation_height_info;
 | 
			
		||||
	ASSERT_FALSE (node->store.confirmation_height.get (transaction, nano::dev::genesis_key.pub, confirmation_height_info));
 | 
			
		||||
	ASSERT_EQ (num_blocks + 2, confirmation_height_info.height);
 | 
			
		||||
	ASSERT_EQ (num_blocks + 3, account_info.block_count); // Includes the unpocketed send
 | 
			
		||||
	ASSERT_EQ (num_blocks + 3, info->block_count); // Includes the unpocketed send
 | 
			
		||||
 | 
			
		||||
	ASSERT_FALSE (node->store.account.get (transaction, key1.pub, account_info));
 | 
			
		||||
	info = node->ledger.account_info (transaction, key1.pub);
 | 
			
		||||
	ASSERT_TRUE (info);
 | 
			
		||||
	ASSERT_FALSE (node->store.confirmation_height.get (transaction, key1.pub, confirmation_height_info));
 | 
			
		||||
	ASSERT_EQ (num_blocks + 1, confirmation_height_info.height);
 | 
			
		||||
	ASSERT_EQ (num_blocks + 1, account_info.block_count);
 | 
			
		||||
	ASSERT_EQ (num_blocks + 1, info->block_count);
 | 
			
		||||
 | 
			
		||||
	size_t cemented_count = 0;
 | 
			
		||||
	for (auto i (node->ledger.store.confirmation_height.begin (transaction)), n (node->ledger.store.confirmation_height.end ()); i != n; ++i)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -400,11 +400,10 @@ void nano::test::system::generate_rollback (nano::node & node_a, std::vector<nan
 | 
			
		|||
	debug_assert (std::numeric_limits<CryptoPP::word32>::max () > accounts_a.size ());
 | 
			
		||||
	auto index (random_pool::generate_word32 (0, static_cast<CryptoPP::word32> (accounts_a.size () - 1)));
 | 
			
		||||
	auto account (accounts_a[index]);
 | 
			
		||||
	nano::account_info info;
 | 
			
		||||
	auto error (node_a.store.account.get (transaction, account, info));
 | 
			
		||||
	if (!error)
 | 
			
		||||
	auto info = node_a.ledger.account_info (transaction, account);
 | 
			
		||||
	if (info)
 | 
			
		||||
	{
 | 
			
		||||
		auto hash (info.open_block);
 | 
			
		||||
		auto hash (info->open_block);
 | 
			
		||||
		if (hash != node_a.network_params.ledger.genesis->hash ())
 | 
			
		||||
		{
 | 
			
		||||
			accounts_a[index] = accounts_a[accounts_a.size () - 1];
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue