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
1 change: 1 addition & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ include_bitcoin_database_HEADERS = \
include/bitcoin/database/query.hpp \
include/bitcoin/database/settings.hpp \
include/bitcoin/database/store.hpp \
include/bitcoin/database/types.hpp \
include/bitcoin/database/version.hpp

include_bitcoin_database_filedir = ${includedir}/bitcoin/database/file
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@
<ClInclude Include="..\..\..\..\include\bitcoin\database\tables\states.hpp" />
<ClInclude Include="..\..\..\..\include\bitcoin\database\tables\table.hpp" />
<ClInclude Include="..\..\..\..\include\bitcoin\database\tables\tables.hpp" />
<ClInclude Include="..\..\..\..\include\bitcoin\database\types.hpp" />
<ClInclude Include="..\..\..\..\include\bitcoin\database\version.hpp" />
<ClInclude Include="..\..\..\..\src\memory\mman-win32\mman.hpp" />
</ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,9 @@
<ClInclude Include="..\..\..\..\include\bitcoin\database\tables\tables.hpp">
<Filter>include\bitcoin\database\tables</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\include\bitcoin\database\types.hpp">
<Filter>include\bitcoin\database</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\include\bitcoin\database\version.hpp">
<Filter>include\bitcoin\database</Filter>
</ClInclude>
Expand Down
1 change: 1 addition & 0 deletions include/bitcoin/database.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <bitcoin/database/query.hpp>
#include <bitcoin/database/settings.hpp>
#include <bitcoin/database/store.hpp>
#include <bitcoin/database/types.hpp>
#include <bitcoin/database/version.hpp>
#include <bitcoin/database/file/file.hpp>
#include <bitcoin/database/file/rotator.hpp>
Expand Down
18 changes: 9 additions & 9 deletions include/bitcoin/database/impl/query/consensus.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ bool CLASS::is_strong(const tx_link& tx) const NOEXCEPT

// protected
TEMPLATE
error::error_t CLASS::unspendable(uint32_t sequence, bool coinbase,
code CLASS::unspendable(uint32_t sequence, bool coinbase,
const tx_link& tx, uint32_t version, const context& ctx) const NOEXCEPT
{
// Ensure prevout tx is in a strong block, first try self link.
Expand Down Expand Up @@ -317,27 +317,27 @@ code CLASS::block_confirmable(const header_link& link) const NOEXCEPT

// Get points for each tx, and sum the total number.
std::transform(parallel, txs.begin(), txs.end(), sets.begin(), to_set);
if (failure)
return { failure.load() };
if (failure != error::success)
return failure.load();

// Check double spends strength, populates prevout parent tx/cb/sq links.
if ((ec = populate_prevouts(sets, points, link)))
return ec;

const auto is_unspendable = [this, &ctx, &failure](const auto& set) NOEXCEPT
const auto is_spendable = [this, &ctx, &failure](const auto& set) NOEXCEPT
{
error::error_t ec{};
code ec{};
for (const auto& point: set.points)
if (!point.tx.is_terminal() && ((ec = unspendable(point.sequence,
point.coinbase, point.tx, set.version, ctx))))
failure.store(ec);
failure.store(static_cast<error::error_t>(ec.value()));

return failure != error::success;
return failure == error::success;
};

// Check all spends for spendability (strong, unlocked and mature).
if (std::any_of(parallel, sets.begin(), sets.end(), is_unspendable))
return { failure.load() };
if (!std::all_of(parallel, sets.begin(), sets.end(), is_spendable))
return failure.load();

return error::success;
}
Expand Down
51 changes: 32 additions & 19 deletions include/bitcoin/database/impl/query/objects.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -305,8 +305,27 @@ typename CLASS::output::cptr CLASS::get_output(
}

TEMPLATE
typename CLASS::outpoint CLASS::get_spent(
const output_link& link) const NOEXCEPT
typename CLASS::inputs_ptr CLASS::get_spenders(
const output_link& link, bool witness) const NOEXCEPT
{
using namespace system;
const auto point_fks = to_spenders(link);
const auto inputs = to_shared<chain::input_cptrs>();
inputs->reserve(point_fks.size());

// TODO: eliminate shared memory pointer reallocation.
for (const auto& point_fk: point_fks)
if (!push_bool(*inputs, get_input(point_fk, witness)))
return {};

return inputs;
}

// Inpoint and outpoint result sets.
// ----------------------------------------------------------------------------

TEMPLATE
outpoint CLASS::get_spent(const output_link& link) const NOEXCEPT
{
table::output::get_parent_value out{};
if (!store_.output.get(link, out))
Expand All @@ -320,34 +339,28 @@ typename CLASS::outpoint CLASS::get_spent(
}

TEMPLATE
typename CLASS::point CLASS::get_spender(const point_link& link) const NOEXCEPT
inpoint CLASS::get_spender(const point_link& link) const NOEXCEPT
{
const auto tx = to_spending_tx(link);
if (tx.is_terminal())
const auto tx_fk = to_spending_tx(link);
if (tx_fk.is_terminal())
return {};

const auto index = to_input_index(tx, link);
const auto index = to_input_index(tx_fk, link);
if (index == point::null_index)
return {};

return { get_tx_key(tx), index };
return { get_tx_key(tx_fk), index };
}

TEMPLATE
typename CLASS::inputs_ptr CLASS::get_spenders(
const output_link& link, bool witness) const NOEXCEPT
inpoints CLASS::get_spenders(const point& point) const NOEXCEPT
{
using namespace system;
const auto point_fks = to_spenders(link);
const auto inputs = to_shared<chain::input_cptrs>();
inputs->reserve(point_fks.size());

// TODO: eliminate shared memory pointer reallocation.
for (const auto& point_fk: point_fks)
if (!push_bool(*inputs, get_input(point_fk, witness)))
return {};
inpoints ins{};
for (const auto& point_fk: to_spenders(point))
ins.insert(get_spender(point_fk));

return inputs;
// std::set (lexically sorted/deduped).
return ins;
}

// Populate prevout objects.
Expand Down
37 changes: 7 additions & 30 deletions include/bitcoin/database/query.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,36 +24,11 @@
#include <utility>
#include <bitcoin/system.hpp>
#include <bitcoin/database/define.hpp>
#include <bitcoin/database/error.hpp>
#include <bitcoin/database/primitives/primitives.hpp>
#include <bitcoin/database/tables/tables.hpp>
#include <bitcoin/database/types.hpp>

namespace libbitcoin {
namespace database {

/// Database type aliases.
using height_link = table::height::link;
using header_link = table::header::link;
using output_link = table::output::link;
using input_link = table::input::link;
using outs_link = table::outs::link;
using ins_link = table::ins::link;
using point_link = table::point::link;
using tx_link = table::transaction::link;
using filter_link = table::filter_tx::link;
using strong_link = table::strong_tx::link;

using header_links = std::vector<header_link::integer>;
using tx_links = std::vector<tx_link::integer>;
using input_links = std::vector<input_link::integer>;
using output_links = std::vector<output_link::integer>;
using point_links = std::vector<point_link::integer>;
using two_counts = std::pair<size_t, size_t>;
using point_key = table::point::key;

struct header_state{ header_link link; code ec; };
using header_states = std::vector<header_state>;

// Writers (non-const) are only: push_, pop_, set_ and initialize.
template <typename Store>
class query
Expand All @@ -66,7 +41,6 @@ class query
using point = system::chain::point;
using input = system::chain::input;
using output = system::chain::output;
using outpoint = system::chain::outpoint;
using header = system::chain::header;
using script = system::chain::script;
using witness = system::chain::witness;
Expand Down Expand Up @@ -396,14 +370,17 @@ class query
input::cptr get_input(const tx_link& link, uint32_t index,
bool witness) const NOEXCEPT;

point get_spender(const point_link& link) const NOEXCEPT;
outpoint get_spent(const output_link& link) const NOEXCEPT;
script::cptr get_output_script(const output_link& link) const NOEXCEPT;
output::cptr get_output(const output_link& link) const NOEXCEPT;
output::cptr get_output(const tx_link& link, uint32_t index) const NOEXCEPT;
inputs_ptr get_spenders(const output_link& link,
bool witness) const NOEXCEPT;

/// Inpoint and outpoint result sets.
outpoint get_spent(const output_link& link) const NOEXCEPT;
inpoint get_spender(const point_link& link) const NOEXCEPT;
inpoints get_spenders(const point& point) const NOEXCEPT;

/// False implies missing prevouts, node input.metadata is populated.
bool populate_with_metadata(const input& input) const NOEXCEPT;
bool populate_with_metadata(const block& block) const NOEXCEPT;
Expand Down Expand Up @@ -652,7 +629,7 @@ class query
const context& ctx) const NOEXCEPT;

/// Called by block_confirmable (populate and check double spends).
error::error_t unspendable(uint32_t sequence, bool coinbase,
code unspendable(uint32_t sequence, bool coinbase,
const tx_link& prevout_tx, uint32_t version,
const context& ctx) const NOEXCEPT;

Expand Down
62 changes: 62 additions & 0 deletions include/bitcoin/database/types.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/**
* Copyright (c) 2011-2025 libbitcoin developers (see AUTHORS)
*
* This file is part of libbitcoin.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef LIBBITCOIN_DATABASE_TYPES_HPP
#define LIBBITCOIN_DATABASE_TYPES_HPP

#include <set>
#include <utility>
#include <bitcoin/database/define.hpp>
#include <bitcoin/database/tables/tables.hpp>

namespace libbitcoin {
namespace database {

/// Database type aliases.
using height_link = table::height::link;
using header_link = table::header::link;
using output_link = table::output::link;
using input_link = table::input::link;
using outs_link = table::outs::link;
using ins_link = table::ins::link;
using point_link = table::point::link;
using tx_link = table::transaction::link;
using filter_link = table::filter_tx::link;
using strong_link = table::strong_tx::link;

using header_links = std::vector<header_link::integer>;
using tx_links = std::vector<tx_link::integer>;
using input_links = std::vector<input_link::integer>;
using output_links = std::vector<output_link::integer>;
using point_links = std::vector<point_link::integer>;
using two_counts = std::pair<size_t, size_t>;
using point_key = table::point::key;

struct header_state{ header_link link; code ec; };
using header_states = std::vector<header_state>;

// TODO: define a system::chain::inpoint with added state.
using inpoint = system::chain::point;
using inpoints = std::set<inpoint>;
using outpoint = system::chain::outpoint;
using outpoints = std::set<outpoint>;

} // namespace database
} // namespace libbitcoin

#endif
Loading