Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 55 additions & 42 deletions include/bitcoin/database/impl/query/address/address_history.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -52,29 +52,30 @@ code CLASS::get_unconfirmed_history(const stopper& cancel, histories& out,
return parallel_history_transform(cancel, turbo, out, txs,
[this](const auto& link, auto& cancel, auto& fail) NOEXCEPT -> history
{
if (cancel)
if (cancel || fail)
return {};

if (const auto block = find_strong(link); is_confirmed_block(block))
// chain::checkpoint invalid in default construction (filter).
const auto block = find_strong(link);
if (is_confirmed_block(block))
return {};

auto hash = get_tx_key(link);
if (hash == system::null_hash)
{
constexpr auto excluded = history::excluded_position;
return { system::chain::checkpoint{}, {}, excluded };
fail = true;
return {};
}
else
{
uint64_t fee{};
auto hash = get_tx_key(link);
if (hash == system::null_hash || !get_tx_fee(fee, link))
{
fail = true;
}

const auto height = is_confirmed_all_prevouts(link) ?
history::rooted_height : history::unrooted_height;

constexpr auto unconfirmed = history::unconfirmed_position;
return { { std::move(hash), height }, fee, unconfirmed };
}
uint64_t fee{};
auto height = history::unrooted_height;
if (!get_tx_fee(fee, link))
fee = history::missing_prevout;
else if (is_confirmed_all_prevouts(link))
height = history::rooted_height;

return { { std::move(hash), height }, fee,
history::unconfirmed_position };
});
}

Expand All @@ -96,28 +97,29 @@ code CLASS::get_confirmed_history(const stopper& cancel, histories& out,
return parallel_history_transform(cancel, turbo, out, txs,
[this](const auto& link, auto& cancel, auto& fail) NOEXCEPT -> history
{
if (cancel)
if (cancel || fail)
return {};

if (const auto block = find_strong(link); is_confirmed_block(block))
{
uint64_t fee{};
size_t height{}, position{};
auto hash = get_tx_key(link);
if (hash == system::null_hash || !get_tx_fee(fee, link) ||
!get_height(height, block) ||
!get_tx_position(position, link, block))
{
fail = true;
}
// chain::checkpoint invalid in default construction (filter).
const auto block = find_strong(link);
if (!is_confirmed_block(block))
return {};

return { { std::move(hash), height }, fee, position };
}
else
size_t height{}, position{};
auto hash = get_tx_key(link);
if (hash == system::null_hash ||
!get_height(height, block) ||
!get_tx_position(position, link, block))
{
constexpr auto exclude = history::excluded_position;
return { system::chain::checkpoint{}, {}, exclude };
fail = true;
return {};
}

uint64_t fee{};
if (!get_tx_fee(fee, link))
fee = history::missing_prevout;

return { { std::move(hash), height }, fee, position };
});
}

Expand All @@ -139,25 +141,36 @@ code CLASS::get_history(const stopper& cancel, histories& out,
return parallel_history_transform(cancel, turbo, out, links,
[this](const auto& link, auto& cancel, auto& fail) NOEXCEPT -> history
{
if (cancel)
if (cancel || fail)
return {};

uint64_t fee{};
auto hash = get_tx_key(link);
if (hash == system::null_hash || !get_tx_fee(fee, link))
if (hash == system::null_hash)
{
fail = true;
return {};
}

size_t height{}, position{};
if (const auto block = find_strong(link); is_confirmed_block(block))
uint64_t fee{};
if (!get_tx_fee(fee, link))
fee = history::missing_prevout;

auto height = history::unrooted_height;
auto position = history::unconfirmed_position;
if (const auto block = find_strong(link);
is_confirmed_block(block))
{
if (!get_height(height, block) ||
!get_tx_position(position, link, block))
{
fail = true;
return {};
}
}
else
{
height = is_confirmed_all_prevouts(link) ?
history::rooted_height : history::unrooted_height;
if (is_confirmed_all_prevouts(link))
height = history::rooted_height;
}

return { { std::move(hash), height }, fee, position };
Expand Down
48 changes: 11 additions & 37 deletions include/bitcoin/database/impl/query/navigate/navigate_reverse.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -52,26 +52,8 @@ TEMPLATE
code CLASS::to_touched_txs(tx_links& out,
const output_links& outputs) const NOEXCEPT
{
// Reserve one for each output tx and one for spending input tx (estimate).
out.clear();
out.reserve(two * outputs.size());

// Orders are reversed due to expected tx_links reversal, for faster sort.
for (const auto& output: std::views::reverse(outputs))
{
out.push_back(to_output_tx(output));
if (out.back() == tx_link::terminal)
return error::integrity;

for (const auto& input: std::views::reverse(to_spenders(output)))
{
out.push_back(to_input_tx(input));
if (out.back() == tx_link::terminal)
return error::integrity;
}
}

return {};
const stopper cancel{};
return to_touched_txs(cancel, out, outputs);
}

TEMPLATE
Expand All @@ -88,37 +70,29 @@ code CLASS::to_touched_txs(const stopper& cancel, tx_links& out,
if (cancel)
return error::canceled;

out.push_back(to_output_tx(output));
if (out.back() == tx_link::terminal)
if (const auto tx = to_output_tx(output); tx.is_terminal())
return error::integrity;
else
out.push_back(tx);

for (const auto& input: std::views::reverse(to_spenders(output)))
{
out.push_back(to_input_tx(input));
if (out.back() == tx_link::terminal)
if (const auto tx = to_input_tx(input); tx.is_terminal())
return error::integrity;
else
out.push_back(tx);
}
}

return {};
return error::success;
}

TEMPLATE
code CLASS::to_address_outputs(output_links& out,
const hash_digest& key) const NOEXCEPT
{
// Pushing into the vector is more efficient than precomputation of size.
out.clear();
for (auto it = store_.address.it(key); it; ++it)
{
table::address::record address{};
if (!store_.address.get(it, address))
return error::integrity;

out.push_back(address.output_fk);
}

return error::success;
const stopper cancel{};
return to_address_outputs(cancel, out, key);
}

TEMPLATE
Expand Down
2 changes: 1 addition & 1 deletion include/bitcoin/database/types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ struct BCD_API history
{
static constexpr size_t rooted_height = zero;
static constexpr size_t unrooted_height = max_size_t;
static constexpr size_t excluded_position = max_size_t;
static constexpr size_t missing_prevout = max_uint64;
static constexpr size_t unconfirmed_position = zero;

struct less_than
Expand Down
4 changes: 2 additions & 2 deletions src/types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ bool history::equal_to::operator()(const history& a, const history& b) const NOE

bool history::exclude::operator()(const history& element) const NOEXCEPT
{
return element.position == max_size_t;
return !element.tx.is_valid();
}

void history::sort_and_dedup(std::vector<history>& out) NOEXCEPT
Expand Down Expand Up @@ -140,7 +140,7 @@ bool unspent::equal_to::operator()(const unspent& a,

bool unspent::exclude::operator()(const unspent& element) const NOEXCEPT
{
return element.position == max_size_t;
return !element.tx.is_valid();
}

void unspent::sort_and_dedup(std::vector<unspent>& out) NOEXCEPT
Expand Down
Loading