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
2 changes: 2 additions & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ test_libbitcoin_database_test_SOURCES = \
test/query/extent.cpp \
test/query/height.cpp \
test/query/initialize.cpp \
test/query/network.cpp \
test/query/objects.cpp \
test/query/optional.cpp \
test/query/translate.cpp \
Expand Down Expand Up @@ -181,6 +182,7 @@ include_bitcoin_database_impl_query_HEADERS = \
include/bitcoin/database/impl/query/extent.ipp \
include/bitcoin/database/impl/query/height.ipp \
include/bitcoin/database/impl/query/initialize.ipp \
include/bitcoin/database/impl/query/network.ipp \
include/bitcoin/database/impl/query/objects.ipp \
include/bitcoin/database/impl/query/optional.ipp \
include/bitcoin/database/impl/query/query.ipp \
Expand Down
1 change: 1 addition & 0 deletions builds/cmake/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,7 @@ if (with-tests)
"../../test/query/extent.cpp"
"../../test/query/height.cpp"
"../../test/query/initialize.cpp"
"../../test/query/network.cpp"
"../../test/query/objects.cpp"
"../../test/query/optional.cpp"
"../../test/query/translate.cpp"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@
<ObjectFileName>$(IntDir)test_query_height.obj</ObjectFileName>
</ClCompile>
<ClCompile Include="..\..\..\..\test\query\initialize.cpp" />
<ClCompile Include="..\..\..\..\test\query\network.cpp" />
<ClCompile Include="..\..\..\..\test\query\objects.cpp" />
<ClCompile Include="..\..\..\..\test\query\optional.cpp" />
<ClCompile Include="..\..\..\..\test\query\translate.cpp" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,9 @@
<ClCompile Include="..\..\..\..\test\query\initialize.cpp">
<Filter>src\query</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\test\query\network.cpp">
<Filter>src\query</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\test\query\objects.cpp">
<Filter>src\query</Filter>
</ClCompile>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@
<None Include="..\..\..\..\include\bitcoin\database\impl\query\extent.ipp" />
<None Include="..\..\..\..\include\bitcoin\database\impl\query\height.ipp" />
<None Include="..\..\..\..\include\bitcoin\database\impl\query\initialize.ipp" />
<None Include="..\..\..\..\include\bitcoin\database\impl\query\network.ipp" />
<None Include="..\..\..\..\include\bitcoin\database\impl\query\objects.ipp" />
<None Include="..\..\..\..\include\bitcoin\database\impl\query\optional.ipp" />
<None Include="..\..\..\..\include\bitcoin\database\impl\query\query.ipp" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,9 @@
<None Include="..\..\..\..\include\bitcoin\database\impl\query\initialize.ipp">
<Filter>include\bitcoin\database\impl\query</Filter>
</None>
<None Include="..\..\..\..\include\bitcoin\database\impl\query\network.ipp">
<Filter>include\bitcoin\database\impl\query</Filter>
</None>
<None Include="..\..\..\..\include\bitcoin\database\impl\query\objects.ipp">
<Filter>include\bitcoin\database\impl\query</Filter>
</None>
Expand Down
92 changes: 0 additions & 92 deletions include/bitcoin/database/impl/query/height.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -60,98 +60,6 @@ size_t CLASS::get_confirmed_size(size_t top) const NOEXCEPT
return wire;
}

// locator readers
// ----------------------------------------------------------------------------
// These do not require strict consistency.

TEMPLATE
CLASS::headers CLASS::get_headers(const hashes& locator,
const hash_digest& stop, size_t limit) const NOEXCEPT
{
headers out{};
const auto span = get_locator_span(locator, stop, limit);
out.reserve(span.size());

for (auto height = span.begin; height < span.end; ++height)
{
// Terminal implies intervening reorganization.
const auto link = to_confirmed(height);
if (link.is_terminal())
return {};

out.push_back(get_header(link));
BC_ASSERT(!is_null(out.back()));
}

return out;
}

TEMPLATE
hashes CLASS::get_blocks(const hashes& locator,
const hash_digest& stop, size_t limit) const NOEXCEPT
{
hashes out{};
const auto span = get_locator_span(locator, stop, limit);
out.reserve(span.size());

for (auto height = span.begin; height < span.end; ++height)
{
// Terminal implies intervening reorganization.
const auto link = to_confirmed(height);
if (link.is_terminal())
return {};

out.push_back(get_header_key(link));
BC_ASSERT(out.back() != system::null_hash);
}

return out;
}

TEMPLATE
CLASS::span CLASS::get_locator_span(const hashes& locator,
const hash_digest& stop, size_t limit) const NOEXCEPT
{
using namespace system;
span out{};

// Start at fork point, stop at given header (both excluded).
const auto start = add1(get_fork(locator));
const auto last1 = (stop == null_hash) ? max_uint32 :
get_height(to_header(stop)).value;

// Determine number of headers requested, limited by max allowed.
const auto request = floored_subtract<size_t>(last1, start);
const auto allowed = std::min(request, limit);

// Set end to (start + allowed), limited by (top + 1).
const auto top1 = ceilinged_add(get_top_confirmed(), one);
const auto end = std::min(ceilinged_add(start, allowed), top1);

// Convert negative range to empty.
out.end = std::max(start, end);
return out;
}

// protected
TEMPLATE
size_t CLASS::get_fork(const hashes& locator) const NOEXCEPT
{
// Locator is presumed (by convention) to be in order by height.
for (const auto& hash: locator)
{
const auto link = to_header(hash);
const auto height = get_height(link);

table::height::record confirmed{};
if (store_.confirmed.get(height, confirmed) &&
confirmed.header_fk == link)
return height;
}

return zero;
}

// shared_lock readers
// ----------------------------------------------------------------------------
// Protected against index pop (low contention) to ensure branch consistency.
Expand Down
124 changes: 124 additions & 0 deletions include/bitcoin/database/impl/query/network.ipp
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
/**
* 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_QUERY_NETWORK_IPP
#define LIBBITCOIN_DATABASE_QUERY_NETWORK_IPP

#include <algorithm>
#include <bitcoin/system.hpp>
#include <bitcoin/database/define.hpp>

namespace libbitcoin {
namespace database {

// locator readers
// ----------------------------------------------------------------------------
// These do not require strict consistency.

TEMPLATE
CLASS::headers CLASS::get_headers(const hashes& locator,
const hash_digest& stop, size_t limit) const NOEXCEPT
{
headers out{};
const auto span = get_locator_span(locator, stop, limit);
out.reserve(span.size());

for (auto height = span.begin; height < span.end; ++height)
{
// Terminal implies intervening reorganization.
const auto link = to_confirmed(height);
if (link.is_terminal())
return {};

out.push_back(get_header(link));
BC_ASSERT(!is_null(out.back()));
}

return out;
}

TEMPLATE
hashes CLASS::get_blocks(const hashes& locator,
const hash_digest& stop, size_t limit) const NOEXCEPT
{
hashes out{};
const auto span = get_locator_span(locator, stop, limit);
out.reserve(span.size());

for (auto height = span.begin; height < span.end; ++height)
{
// Terminal implies intervening reorganization.
const auto link = to_confirmed(height);
if (link.is_terminal())
return {};

out.push_back(get_header_key(link));
BC_ASSERT(out.back() != system::null_hash);
}

return out;
}

TEMPLATE
CLASS::span CLASS::get_locator_span(const hashes& locator,
const hash_digest& stop, size_t limit) const NOEXCEPT
{
using namespace system;
span out{};

// Start at fork point, stop at given header (both excluded).
const auto start = add1(get_fork(locator));
const auto last1 = (stop == null_hash) ? max_uint32 :
get_height(to_header(stop)).value;

// Determine number of headers requested, limited by max allowed.
const auto request = floored_subtract<size_t>(last1, start);
const auto allowed = std::min(request, limit);

// Set end to (start + allowed), limited by (top + 1).
const auto top1 = ceilinged_add(get_top_confirmed(), one);
const auto end = std::min(ceilinged_add(start, allowed), top1);

// Convert negative range to empty.
out.end = std::max(start, end);
return out;
}

// protected
TEMPLATE
size_t CLASS::get_fork(const hashes& locator) const NOEXCEPT
{
// Locator is presumed (by convention) to be in order by height.
for (const auto& hash: locator)
{
const auto link = to_header(hash);
const auto height = get_height(link);

table::height::record confirmed{};
if (store_.confirmed.get(height, confirmed) &&
confirmed.header_fk == link)
return height;
}

return zero;
}

} // namespace database
} // namespace libbitcoin

#endif
1 change: 1 addition & 0 deletions include/bitcoin/database/query.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -711,6 +711,7 @@ BC_PUSH_WARNING(NO_THROW_IN_NOEXCEPT)
#include <bitcoin/database/impl/query/extent.ipp>
#include <bitcoin/database/impl/query/height.ipp>
#include <bitcoin/database/impl/query/initialize.ipp>
#include <bitcoin/database/impl/query/network.ipp>
#include <bitcoin/database/impl/query/objects.ipp>
#include <bitcoin/database/impl/query/optional.ipp>
#include <bitcoin/database/impl/query/translate.ipp>
Expand Down
51 changes: 51 additions & 0 deletions test/query/network.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/**
* 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/>.
*/
#include "../test.hpp"
#include "../mocks/blocks.hpp"
#include "../mocks/chunk_store.hpp"

struct query_network_setup_fixture
{
DELETE_COPY_MOVE(query_network_setup_fixture);
BC_PUSH_WARNING(NO_THROW_IN_NOEXCEPT)

query_network_setup_fixture() NOEXCEPT
{
BOOST_REQUIRE(test::clear(test::directory));
}

~query_network_setup_fixture() NOEXCEPT
{
BOOST_REQUIRE(test::clear(test::directory));
}

BC_POP_WARNING()
};

BOOST_FIXTURE_TEST_SUITE(query_network_tests, query_network_setup_fixture)

const auto events_handler = [](auto, auto) {};


BOOST_AUTO_TEST_CASE(query_network_test)
{
BOOST_REQUIRE(true);
}

BOOST_AUTO_TEST_SUITE_END()
Loading