235 lines
7.1 KiB
C++
235 lines
7.1 KiB
C++
#include <nano/secure/ledger.hpp>
|
|
#include <nano/secure/ledger_set_any.hpp>
|
|
#include <nano/store/account.hpp>
|
|
#include <nano/store/block.hpp>
|
|
#include <nano/store/component.hpp>
|
|
#include <nano/store/pending.hpp>
|
|
#include <nano/store/pruned.hpp>
|
|
|
|
nano::ledger_set_any::ledger_set_any (nano::ledger const & ledger) :
|
|
ledger{ ledger }
|
|
{
|
|
}
|
|
|
|
std::optional<nano::amount> nano::ledger_set_any::account_balance (secure::transaction const & transaction, nano::account const & account_a) const
|
|
{
|
|
auto block = block_get (transaction, account_head (transaction, account_a));
|
|
if (!block)
|
|
{
|
|
return std::nullopt;
|
|
}
|
|
return block->balance ();
|
|
}
|
|
|
|
auto nano::ledger_set_any::account_begin (secure::transaction const & transaction) const -> account_iterator
|
|
{
|
|
return account_lower_bound (transaction, 0);
|
|
}
|
|
|
|
auto nano::ledger_set_any::account_end () const -> account_iterator
|
|
{
|
|
return account_iterator{};
|
|
}
|
|
|
|
std::optional<nano::account_info> nano::ledger_set_any::account_get (secure::transaction const & transaction, nano::account const & account) const
|
|
{
|
|
return ledger.store.account.get (transaction, account);
|
|
}
|
|
|
|
bool nano::ledger_set_any::account_exists (secure::transaction const & transaction, nano::account const & account) const
|
|
{
|
|
return ledger.store.account.exists (transaction, account);
|
|
}
|
|
|
|
nano::block_hash nano::ledger_set_any::account_head (secure::transaction const & transaction, nano::account const & account) const
|
|
{
|
|
auto info = account_get (transaction, account);
|
|
if (!info)
|
|
{
|
|
return 0;
|
|
}
|
|
return info.value ().head;
|
|
}
|
|
|
|
uint64_t nano::ledger_set_any::account_height (secure::transaction const & transaction, nano::account const & account) const
|
|
{
|
|
auto head_l = account_head (transaction, account);
|
|
if (head_l.is_zero ())
|
|
{
|
|
return 0;
|
|
}
|
|
auto block = block_get (transaction, head_l);
|
|
release_assert (block); // Head block must be in ledger
|
|
return block->sideband ().height;
|
|
}
|
|
|
|
auto nano::ledger_set_any::account_lower_bound (secure::transaction const & transaction, nano::account const & account) const -> account_iterator
|
|
{
|
|
auto disk = ledger.store.account.begin (transaction, account);
|
|
if (disk == ledger.store.account.end (transaction))
|
|
{
|
|
return account_iterator{};
|
|
}
|
|
return account_iterator{ transaction, *this, *disk };
|
|
}
|
|
|
|
auto nano::ledger_set_any::account_upper_bound (secure::transaction const & transaction, nano::account const & account) const -> account_iterator
|
|
{
|
|
return account_lower_bound (transaction, account.number () + 1);
|
|
}
|
|
|
|
std::optional<nano::account> nano::ledger_set_any::block_account (secure::transaction const & transaction, nano::block_hash const & hash) const
|
|
{
|
|
auto block_l = block_get (transaction, hash);
|
|
if (!block_l)
|
|
{
|
|
return std::nullopt;
|
|
}
|
|
return block_l->account ();
|
|
}
|
|
|
|
std::optional<nano::amount> nano::ledger_set_any::block_amount (secure::transaction const & transaction, nano::block_hash const & hash) const
|
|
{
|
|
auto block_l = block_get (transaction, hash);
|
|
if (!block_l)
|
|
{
|
|
return std::nullopt;
|
|
}
|
|
return block_amount (transaction, block_l);
|
|
}
|
|
|
|
std::optional<nano::amount> nano::ledger_set_any::block_amount (secure::transaction const & transaction, std::shared_ptr<nano::block> const & block) const
|
|
{
|
|
auto block_balance = block->balance ();
|
|
if (block->previous ().is_zero ())
|
|
{
|
|
return block_balance.number ();
|
|
}
|
|
auto previous_balance = this->block_balance (transaction, block->previous ());
|
|
if (!previous_balance)
|
|
{
|
|
return std::nullopt;
|
|
}
|
|
return block_balance > previous_balance.value () ? block_balance.number () - previous_balance.value ().number () : previous_balance.value ().number () - block_balance.number ();
|
|
}
|
|
|
|
std::optional<nano::amount> nano::ledger_set_any::block_balance (secure::transaction const & transaction, nano::block_hash const & hash) const
|
|
{
|
|
if (hash.is_zero ())
|
|
{
|
|
return std::nullopt;
|
|
}
|
|
auto block = block_get (transaction, hash);
|
|
if (!block)
|
|
{
|
|
return std::nullopt;
|
|
}
|
|
return block->balance ();
|
|
}
|
|
|
|
bool nano::ledger_set_any::block_exists (secure::transaction const & transaction, nano::block_hash const & hash) const
|
|
{
|
|
if (hash.is_zero ())
|
|
{
|
|
return false;
|
|
}
|
|
return ledger.store.block.exists (transaction, hash);
|
|
}
|
|
|
|
bool nano::ledger_set_any::block_exists_or_pruned (secure::transaction const & transaction, nano::block_hash const & hash) const
|
|
{
|
|
if (hash.is_zero ())
|
|
{
|
|
return false;
|
|
}
|
|
if (ledger.store.pruned.exists (transaction, hash))
|
|
{
|
|
return true;
|
|
}
|
|
return ledger.store.block.exists (transaction, hash);
|
|
}
|
|
|
|
std::shared_ptr<nano::block> nano::ledger_set_any::block_get (secure::transaction const & transaction, nano::block_hash const & hash) const
|
|
{
|
|
if (hash.is_zero ())
|
|
{
|
|
return nullptr;
|
|
}
|
|
return ledger.store.block.get (transaction, hash);
|
|
}
|
|
|
|
uint64_t nano::ledger_set_any::block_height (secure::transaction const & transaction, nano::block_hash const & hash) const
|
|
{
|
|
auto block = block_get (transaction, hash);
|
|
if (!block)
|
|
{
|
|
return 0;
|
|
}
|
|
return block->sideband ().height;
|
|
}
|
|
|
|
std::optional<std::pair<nano::pending_key, nano::pending_info>> nano::ledger_set_any::receivable_lower_bound (secure::transaction const & transaction, nano::account const & account, nano::block_hash const & hash) const
|
|
{
|
|
auto result = ledger.store.pending.begin (transaction, { account, hash });
|
|
if (result == ledger.store.pending.end (transaction))
|
|
{
|
|
return std::nullopt;
|
|
}
|
|
return *result;
|
|
}
|
|
|
|
auto nano::ledger_set_any::receivable_end () const -> receivable_iterator
|
|
{
|
|
return receivable_iterator{};
|
|
}
|
|
|
|
bool nano::ledger_set_any::receivable_exists (secure::transaction const & transaction, nano::account const & account) const
|
|
{
|
|
auto next = receivable_upper_bound (transaction, account, 0);
|
|
return next != receivable_end ();
|
|
}
|
|
|
|
auto nano::ledger_set_any::receivable_upper_bound (secure::transaction const & transaction, nano::account const & account) const -> receivable_iterator
|
|
{
|
|
return receivable_iterator{ transaction, *this, receivable_lower_bound (transaction, account.number () + 1, 0) };
|
|
}
|
|
|
|
auto nano::ledger_set_any::receivable_upper_bound (secure::transaction const & transaction, nano::account const & account, nano::block_hash const & hash) const -> receivable_iterator
|
|
{
|
|
auto result = receivable_lower_bound (transaction, account, hash.number () + 1);
|
|
if (!result || result.value ().first.account != account)
|
|
{
|
|
return receivable_iterator{ transaction, *this, std::nullopt };
|
|
}
|
|
return receivable_iterator{ transaction, *this, result };
|
|
}
|
|
|
|
std::optional<nano::block_hash> nano::ledger_set_any::block_successor (secure::transaction const & transaction, nano::block_hash const & hash) const
|
|
{
|
|
return block_successor (transaction, { hash, hash });
|
|
}
|
|
|
|
std::optional<nano::block_hash> nano::ledger_set_any::block_successor (secure::transaction const & transaction, nano::qualified_root const & root) const
|
|
{
|
|
if (!root.previous ().is_zero ())
|
|
{
|
|
return ledger.store.block.successor (transaction, root.previous ());
|
|
}
|
|
else
|
|
{
|
|
auto info = account_get (transaction, root.root ().as_account ());
|
|
if (info)
|
|
{
|
|
return info->open_block;
|
|
}
|
|
else
|
|
{
|
|
return std::nullopt;
|
|
}
|
|
}
|
|
}
|
|
|
|
std::optional<nano::pending_info> nano::ledger_set_any::pending_get (secure::transaction const & transaction, nano::pending_key const & key) const
|
|
{
|
|
return ledger.store.pending.get (transaction, key);
|
|
}
|