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
11 changes: 0 additions & 11 deletions .github/workflows/ci-expanded.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,6 @@ jobs:
env:
CONCURRENCY_GROUP: ${{ github.workflow }}-${{ github.repository_owner == 'libbitcoin' && (github.event.pull_request.number || github.run_id) || github.ref }}

permissions:
actions: write

steps:
- name: state
run: |
Expand All @@ -39,14 +36,6 @@ jobs:
echo "base_ref : ${{ github.base_ref }}"
echo "head_ref : ${{ github.head_ref }}"

- name: cancel on pull_request closed
if: github.event_name == 'pull_request' && github.event.action == 'closed'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh api --method POST \
-H "Accept: application/vnd.github+json" "/repos/${{ github.repository }}/actions/runs/${{ github.run_id }}/cancel"


gnu:
if: github.event_name != 'pull_request' || github.event.action != 'closed'
Expand Down
11 changes: 0 additions & 11 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,6 @@ jobs:
env:
CONCURRENCY_GROUP: ${{ github.workflow }}-${{ github.repository_owner == 'libbitcoin' && (github.event.pull_request.number || github.run_id) || github.ref }}

permissions:
actions: write

steps:
- name: state
run: |
Expand All @@ -60,14 +57,6 @@ jobs:
echo "base_ref : ${{ github.base_ref }}"
echo "head_ref : ${{ github.head_ref }}"

- name: cancel on pull_request closed
if: github.event_name == 'pull_request' && github.event.action == 'closed'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh api --method POST \
-H "Accept: application/vnd.github+json" "/repos/${{ github.repository }}/actions/runs/${{ github.run_id }}/cancel"


gnu:
if: github.event_name != 'pull_request' || github.event.action != 'closed'
Expand Down
17 changes: 17 additions & 0 deletions include/bitcoin/database/impl/primitives/hashhead.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,23 @@ size_t CLASS::poisson_span(double load_factor) NOEXCEPT
deviations * std::sqrt(load_factor) + minimum));
}

// False positive over poisson bucket occupancy.
TEMPLATE
double CLASS::false_positive(size_t k, double load_factor) NOEXCEPT
{
using namespace system;
auto rate = 0.0;
auto poisson = std::exp(-load_factor);
const auto span = poisson_span(load_factor);
for (auto n = one; n <= span; ++n)
{
poisson *= load_factor / to_floating(n);
rate += poisson * bloom_false_positive(k, n);
}

return rate;
}

// False positive over poisson bucket occupancy, weighted by the occupancy.
TEMPLATE
double CLASS::expected_walk(size_t k, double load_factor) NOEXCEPT
Expand Down
18 changes: 18 additions & 0 deletions include/bitcoin/database/impl/primitives/hashmap.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,24 @@ uint32_t CLASS::derive_buckets(uint64_t expected, uint32_t low,
return head::derive_buckets(expected, low, high);
}

TEMPLATE
size_t CLASS::optimal_k(size_t count, size_t buckets) NOEXCEPT
{
return head::optimal_k(count, buckets);
}

TEMPLATE
double CLASS::false_positive(size_t k, double load_factor) NOEXCEPT
{
return head::false_positive(k, load_factor);
}

TEMPLATE
double CLASS::expected_walk(size_t k, double load_factor) NOEXCEPT
{
return head::expected_walk(k, load_factor);
}

TEMPLATE
size_t CLASS::filter_k() const NOEXCEPT
{
Expand Down
18 changes: 18 additions & 0 deletions include/bitcoin/database/impl/primitives/hashmaps.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,24 @@ uint32_t CLASS::derive_buckets(uint64_t expected, uint32_t low,
return head::derive_buckets(expected, low, high);
}

TEMPLATE
size_t CLASS::optimal_k(size_t count, size_t buckets) NOEXCEPT
{
return head::optimal_k(count, buckets);
}

TEMPLATE
double CLASS::false_positive(size_t k, double load_factor) NOEXCEPT
{
return head::false_positive(k, load_factor);
}

TEMPLATE
double CLASS::expected_walk(size_t k, double load_factor) NOEXCEPT
{
return head::expected_walk(k, load_factor);
}

TEMPLATE
size_t CLASS::filter_k() const NOEXCEPT
{
Expand Down
4 changes: 2 additions & 2 deletions include/bitcoin/database/impl/query/batch/ecdsa.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ size_t CLASS::ecdsa_records(bool bank) const NOEXCEPT

TEMPLATE
bool CLASS::verify_ecdsa_signatures(const stopper& cancel,
header_links& links, bool& device, bool bank) NOEXCEPT
header_links& links, bool& device, bool bank, bool gpu) NOEXCEPT
{
auto& bank_table = store_.ecdsa_bank(bank);
const auto correlate_ptr = bank_table.correlate.get_memory();
Expand Down Expand Up @@ -64,7 +64,7 @@ bool CLASS::verify_ecdsa_signatures(const stopper& cancel,
};

// False return only implies canceled.
links = ecdsa::batch::verify(device, cancel, batch);
links = ecdsa::batch::verify(device, cancel, batch, gpu);
return !cancel;
}

Expand Down
4 changes: 2 additions & 2 deletions include/bitcoin/database/impl/query/batch/schnorr.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ size_t CLASS::schnorr_records(bool bank) const NOEXCEPT

TEMPLATE
bool CLASS::verify_schnorr_signatures(const stopper& cancel,
header_links& links, bool& device, bool bank) NOEXCEPT
header_links& links, bool& device, bool bank, bool gpu) NOEXCEPT
{
auto& bank_table = store_.schnorr_bank(bank);
const auto correlate_ptr = bank_table.correlate.get_memory();
Expand Down Expand Up @@ -63,7 +63,7 @@ bool CLASS::verify_schnorr_signatures(const stopper& cancel,
};

// False return only implies canceled.
links = schnorr::batch::verify(device, cancel, batch);
links = schnorr::batch::verify(device, cancel, batch, gpu);
return !cancel;
}

Expand Down
13 changes: 7 additions & 6 deletions include/bitcoin/database/impl/query/batch/silent.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ bool CLASS::scan_silent(const stopper& cancel,

// False return only implies canceled.
// Callbacks invoked on caller thread if turbo is false.
system::scan::batch::scan(cancel, batch, keys, callback, store_.turbo());
const auto minimum = store_.gpu_scan_minimum();
scan::batch::scan(cancel, batch, keys, minimum, callback, store_.turbo());
return !cancel;
}

Expand Down Expand Up @@ -366,8 +367,8 @@ bool CLASS::get_silent_prevouts(data_chunk& prevouts,
// compute on the processor), and each tx is then published by its correlate
// (an invalid tx with no outputs).
TEMPLATE
code CLASS::compute_silents(const stopper& cancel, bool& device,
bool bank) NOEXCEPT
code CLASS::compute_silents(const stopper& cancel, bool& device, bool bank,
bool gpu) NOEXCEPT
{
using namespace system;
auto& bank_table = store_.silent_bank(bank);
Expand Down Expand Up @@ -422,16 +423,16 @@ code CLASS::compute_silents(const stopper& cancel, bool& device,
};

data_chunk valid(txs);
const silent::batch batch{ { sums, txs }, { hashes, txs } };
const silent::batch rows{ { sums, txs }, { hashes, txs } };
const auto compute = [&]() NOEXCEPT
{
return silent::batch::compute(points, valid, device, cancel, batch);
return silent::batch::compute(points, valid, device, cancel, rows, gpu);
};

// The device computes concurrently with the write, the processor before.
bool success{};
std::future<bool> computed{};
const auto accelerated = batched::accelerated();
const auto accelerated = gpu && batched::accelerated();
if (accelerated)
computed = std::async(std::launch::async, compute);
else
Expand Down
6 changes: 6 additions & 0 deletions include/bitcoin/database/impl/store/store.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,12 @@ bool CLASS::turbo() const NOEXCEPT
return configuration_.turbo;
}

TEMPLATE
size_t CLASS::gpu_scan_minimum() const NOEXCEPT
{
return configuration_.gpu_scan_minimum;
}

TEMPLATE
bool CLASS::mark_unconfirmable() const NOEXCEPT
{
Expand Down
20 changes: 15 additions & 5 deletions include/bitcoin/database/primitives/hashhead.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,13 @@ class hashhead

using bytes = typename Link::bytes;

/// Bucket filter, disabled if the cell has no bits beyond the link.
static constexpr size_t filter_bits = to_bits(CellSize) - Link::bits;
static constexpr size_t filter_k_max = (filter_bits < two) ? zero :
std::min(filter_bits, bits<uint64_t> /
system::ceilinged_log2(filter_bits));
using filter_t = system::bloom<filter_bits, filter_k_max>;

/// A hash head is disabled if it has no buckets.
hashhead(storage& head, size_t buckets, size_t expected=zero) NOEXCEPT;

Expand All @@ -59,6 +66,12 @@ class hashhead
/// Optimal filter k-value for expected load factor.
static size_t optimal_k(size_t count, size_t buckets) NOEXCEPT;

/// Expected filter false positive rate of a new key at load factor.
static double false_positive(size_t k, double load_factor) NOEXCEPT;

/// Expected filter false positive walk of a new key at load factor.
static double expected_walk(size_t k, double load_factor) NOEXCEPT;

/// Buckets for expected elements, scaled by memory between load factors.
static uint32_t derive_buckets(uint64_t expected, uint32_t low,
uint32_t high) NOEXCEPT;
Expand Down Expand Up @@ -101,12 +114,10 @@ class hashhead
static constexpr size_t cell_size = CellSize;
static constexpr size_t link_size = Link::size;
static constexpr size_t link_bits = Link::bits;
static constexpr size_t m = to_bits(cell_size) - link_bits;
static constexpr size_t m = filter_bits;
static constexpr size_t k_default = system::floored_log2(m);
static constexpr size_t k_max = (m < two) ? zero : std::min(m,
bits<uint64_t> / system::ceilinged_log2(m));
static constexpr size_t k_max = filter_k_max;

using filter_t = system::bloom<m, k_max>;
using cell = unsigned_type<cell_size>;
using filter = filter_t::type;
using link = Link::integer;
Expand All @@ -127,7 +138,6 @@ class hashhead

static double bloom_false_positive(size_t k, size_t n) NOEXCEPT;
static size_t poisson_span(double load_factor) NOEXCEPT;
static double expected_walk(size_t k, double load_factor) NOEXCEPT;

inline cell get_cell(const Link& index) const NOEXCEPT;
inline bool set_cell(bool& collision, bytes& next, const Link& current,
Expand Down
16 changes: 16 additions & 0 deletions include/bitcoin/database/primitives/hashmap.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,22 @@ class hashmap
static uint32_t derive_buckets(uint64_t expected, uint32_t low,
uint32_t high) NOEXCEPT;

/// Bucket filter (hashhead::filter_t).
using filter_t = typename hashhead<Link, Key, CellSize>::filter_t;
static constexpr size_t filter_bits =
hashhead<Link, Key, CellSize>::filter_bits;
static constexpr size_t filter_k_max =
hashhead<Link, Key, CellSize>::filter_k_max;

/// Optimal filter k-value for expected load factor (hashhead::optimal_k).
static size_t optimal_k(size_t count, size_t buckets) NOEXCEPT;

/// Expected filter false positive rate (hashhead::false_positive).
static double false_positive(size_t k, double load_factor) NOEXCEPT;

/// Expected filter false positive walk (hashhead::expected_walk).
static double expected_walk(size_t k, double load_factor) NOEXCEPT;

/// Filter selections, derived at construct, overridden by set_filter_k.
size_t filter_k() const NOEXCEPT;

Expand Down
16 changes: 16 additions & 0 deletions include/bitcoin/database/primitives/hashmaps.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,22 @@ class hashmaps
static uint32_t derive_buckets(uint64_t expected, uint32_t low,
uint32_t high) NOEXCEPT;

/// Bucket filter (hashhead::filter_t).
using filter_t = typename hashhead<Link, Key, CellSize>::filter_t;
static constexpr size_t filter_bits =
hashhead<Link, Key, CellSize>::filter_bits;
static constexpr size_t filter_k_max =
hashhead<Link, Key, CellSize>::filter_k_max;

/// Optimal filter k-value for expected load factor (hashhead::optimal_k).
static size_t optimal_k(size_t count, size_t buckets) NOEXCEPT;

/// Expected filter false positive rate (hashhead::false_positive).
static double false_positive(size_t k, double load_factor) NOEXCEPT;

/// Expected filter false positive walk (hashhead::expected_walk).
static double expected_walk(size_t k, double load_factor) NOEXCEPT;

/// Filter selections, derived at construct, overridden by set_filter_k.
size_t filter_k() const NOEXCEPT;

Expand Down
8 changes: 4 additions & 4 deletions include/bitcoin/database/query.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -758,8 +758,8 @@ class query
const header_link& link, const block_view& block) const NOEXCEPT;

/// Compute a bank's silent payment batch, then set its scan records.
code compute_silents(const stopper& cancel, bool& device,
bool bank) NOEXCEPT;
code compute_silents(const stopper& cancel, bool& device, bool bank,
bool gpu) NOEXCEPT;

/// Commit a block's captured ecdsa signature groups (band-expanded).
bool set_signatures(const system::chain::ecdsa_signatures& sigs,
Expand Down Expand Up @@ -799,9 +799,9 @@ class query
/// Verify all signatures in table, false implies cancel, device set if
/// verified on the device.
bool verify_ecdsa_signatures(const stopper& cancel, header_links&,
bool& device, bool bank) NOEXCEPT;
bool& device, bool bank, bool gpu) NOEXCEPT;
bool verify_schnorr_signatures(const stopper& cancel, header_links&,
bool& device, bool bank) NOEXCEPT;
bool& device, bool bank, bool gpu) NOEXCEPT;

/// Purge all entries in table.
bool purge_prevalids(bool bank) NOEXCEPT;
Expand Down
3 changes: 3 additions & 0 deletions include/bitcoin/database/settings.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ struct BCD_API settings
/// Enable concurrency in individual client-server queries.
bool turbo{ false };

/// Minimum transactions for a silent payment scan on the device.
uint32_t gpu_scan_minimum{ 65'536 };

/// Mark blocks as unconfirmable (disorganize vs. stall).
bool mark_unconfirmable{ true };

Expand Down
3 changes: 3 additions & 0 deletions include/bitcoin/database/store.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ class store
/// Allows full throttle concurrent query execution (may use 100% CPU).
bool turbo() const NOEXCEPT;

/// Minimum transactions for a silent payment scan on the device.
size_t gpu_scan_minimum() const NOEXCEPT;

/// Mark blocks as unconfirmable (disorganize vs. stall), configuration.
bool mark_unconfirmable() const NOEXCEPT;

Expand Down
12 changes: 12 additions & 0 deletions test/primitives/hashhead.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,18 @@ BOOST_AUTO_TEST_CASE(hashhead__optimal_k__load_factor__banded)
BOOST_REQUIRE_EQUAL(filtered_::optimal_k(200, 10), 1u);
}

BOOST_AUTO_TEST_CASE(hashhead__false_positive__zero_load__zero)
{
BOOST_REQUIRE_EQUAL(filtered_::false_positive(4, 0.0), 0.0);
BOOST_REQUIRE_EQUAL(filtered_::expected_walk(4, 0.0), 0.0);
}

BOOST_AUTO_TEST_CASE(hashhead__false_positive__load__increasing_below_walk)
{
BOOST_REQUIRE_LT(filtered_::false_positive(4, 1.0), filtered_::false_positive(4, 2.0));
BOOST_REQUIRE_LT(filtered_::false_positive(4, 2.0), filtered_::expected_walk(4, 2.0));
}

BOOST_AUTO_TEST_CASE(hashhead__construct__expected__derived_k)
{
data_chunk data{};
Expand Down
Loading
Loading