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
6 changes: 6 additions & 0 deletions include/bitcoin/database/impl/primitives/nomaps.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,12 @@ bool CLASS::truncate(const Link& count) NOEXCEPT
return manager_.truncate(count);
}

TEMPLATE
bool CLASS::drop() NOEXCEPT
{
return manager_.truncate(0) && backup();
}

// Faults.
// ----------------------------------------------------------------------------

Expand Down
6 changes: 4 additions & 2 deletions include/bitcoin/database/impl/query/batch/ecdsa.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#ifndef LIBBITCOIN_DATABASE_QUERY_BATCH_ECDSA_IPP
#define LIBBITCOIN_DATABASE_QUERY_BATCH_ECDSA_IPP

#include <span>
#include <bitcoin/database/define.hpp>
#include <bitcoin/database/types/types.hpp>

Expand Down Expand Up @@ -106,7 +107,8 @@ bool CLASS::set_signature(const hash_digest& digest,

TEMPLATE
bool CLASS::set_signatures(const hash_digest& digest,
const ec_compresseds& keys, const ec_signatures& sigs, uint16_t id,
const std::span<const ec_compressed>& keys,
const std::span<const ec_signature>& sigs, uint16_t id,
const header_link& link) NOEXCEPT
{
using correlate_t = table::ecdsa_correlate::put_refs;
Expand All @@ -116,7 +118,7 @@ bool CLASS::set_signatures(const hash_digest& digest,

const auto csigs = sigs.size();
const auto ckeys = keys.size();
const auto count = table::ecdsa_count(csigs, ckeys);
const auto count = system::chain::multisig::rows(csigs, ckeys);

// Caller must guard reads, this is writing into hot storage.
// ========================================================================
Expand Down
44 changes: 24 additions & 20 deletions include/bitcoin/database/impl/query/batch/schnorr.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -104,34 +104,38 @@ bool CLASS::set_signature(const hash_digest& digest, const ec_xonly& point,
}

TEMPLATE
bool CLASS::set_signatures(const threshold& batch,
const header_link& link) NOEXCEPT
schnorr_link CLASS::allocate_signatures(size_t count) NOEXCEPT
{
using correlate_t = table::schnorr_correlate::put_refs;
using digest_t = table::schnorr_digest::put_refs;
using xonly_t = table::schnorr_xonly::put_refs;
using signature_t = table::schnorr_signature::put_refs;

// Caller must guard reads, this is writing into hot storage.
// Allocate count rows across all columns (hot storage).
// ========================================================================
const auto scope = get_transactor();

using namespace system;
const auto& set = batch.tuples;
const auto rows = possible_narrow_cast<schnorr_link::integer>(set.size());
const auto rows = possible_narrow_cast<schnorr_link::integer>(count);
return store_.schnorr.allocate(rows);
// ========================================================================
}

// Allocate rows across all columns.
// TODO: this could provide a single remap lock for all puts below.
const auto fk = store_.schnorr.allocate(rows);
if (fk.is_terminal())
return false;
TEMPLATE
bool CLASS::set_signature(const schnorr_link& schnorr_fk,
const hash_digest& digest, const ec_xonly& point,
const ec_signature& signature, const header_link& link) NOEXCEPT
{
using namespace system;
using correlate_t = table::schnorr_correlate::put_ref;
using digest_t = table::schnorr_digest::put_ref;
using xonly_t = table::schnorr_xonly::put_ref;
using signature_t = table::schnorr_signature::put_ref;

// Caller must guard reads, this is writing into hot storage.
// ========================================================================
const auto scope = get_transactor();

// Write one value to each column in corresponding positions.
return
store_.schnorr.correlate.put(fk, correlate_t{ {}, set.size(), link }) &&
store_.schnorr.digest.put(fk, digest_t{ {}, set }) &&
store_.schnorr.xonly.put(fk, xonly_t{ {}, set }) &&
store_.schnorr.signature.put(fk, signature_t{ {}, set });
store_.schnorr.correlate.put(schnorr_fk, correlate_t{ {}, link }) &&
store_.schnorr.digest.put(schnorr_fk, digest_t{ {}, digest }) &&
store_.schnorr.xonly.put(schnorr_fk, xonly_t{ {}, point }) &&
store_.schnorr.signature.put(schnorr_fk, signature_t{ {}, signature });
// ========================================================================
}

Expand Down
13 changes: 11 additions & 2 deletions include/bitcoin/database/impl/store/store_restore.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,17 @@ code CLASS::restore(const event_handler& handler) NOEXCEPT
restore(ec, confirmed, table_t::confirmed_table);
restore(ec, strong_tx, table_t::strong_tx_table);

restore(ec, ecdsa, table_t::ecdsa_table);
restore(ec, schnorr, table_t::schnorr_table);
// ecdsa, schnorr, and prevalid are dropped.
//---------------------------------------------------------------------
// Signatures could be retained and verified, but this just becomes
// redundant work unless prevalid is retained. That would require flush
// of batched_ at snapshot (requires handle message and send complete).
// Would also require an external transactor or terminal prefills in
// threshold batched rows to prevent recovering unpopulated rows. The
// extra complexity isn't probably worth saving the batch for a snap.
//---------------------------------------------------------------------
dropped(ec, ecdsa, table_t::ecdsa_table);
dropped(ec, schnorr, table_t::schnorr_table);
restore(ec, silent, table_t::silent_table);
restore(ec, duplicate, table_t::duplicate_table);
dropped(ec, prevalid, table_t::prevalid_table);
Expand Down
3 changes: 2 additions & 1 deletion include/bitcoin/database/primitives/nomaps.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ class nomaps

bool create() NOEXCEPT;
bool close() NOEXCEPT;
bool backup(bool) NOEXCEPT;
bool backup(bool=false) NOEXCEPT;
bool restore() NOEXCEPT;
bool verify() const NOEXCEPT;

Expand All @@ -60,6 +60,7 @@ class nomaps
Link count() const NOEXCEPT;
Link allocate(const Link& count) NOEXCEPT;
bool truncate(const Link& count) NOEXCEPT;
bool drop() NOEXCEPT;

/// Faults.
/// -----------------------------------------------------------------------
Expand Down
16 changes: 10 additions & 6 deletions include/bitcoin/database/query.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#define LIBBITCOIN_DATABASE_QUERY_HPP

#include <mutex>
#include <span>
#include <bitcoin/database/define.hpp>
#include <bitcoin/database/settings.hpp>
#include <bitcoin/database/types/types.hpp>
Expand Down Expand Up @@ -597,17 +598,20 @@ class query
const ec_signature& signature, uint16_t id,
const header_link& link) NOEXCEPT;

/// Set ecdsa multisig rows.
bool set_signatures(const hash_digest& digest,
const std::span<const ec_compressed>& keys,
const std::span<const ec_signature>& sigs, uint16_t id,
const header_link& link) NOEXCEPT;

/// Set single schnorr signature row.
bool set_signature(const hash_digest& digest, const ec_xonly& point,
const ec_signature& signature, const header_link& link) NOEXCEPT;

/// Set ecdsa multisig rows.
bool set_signatures(const hash_digest& digest, const ec_compresseds& keys,
const ec_signatures& sigs, uint16_t id,
const header_link& link) NOEXCEPT;

/// Set schnorr threshold signature rows.
bool set_signatures(const threshold& batch,
schnorr_link allocate_signatures(size_t count) NOEXCEPT;
bool set_signature(const schnorr_link& first, const hash_digest& digest,
const ec_xonly& point, const ec_signature& signature,
const header_link& link) NOEXCEPT;

/// Invoke callback for each candidate match, false implies cancel.
Expand Down
60 changes: 22 additions & 38 deletions include/bitcoin/database/tables/caches/ecdsa.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,29 +28,6 @@ namespace libbitcoin {
namespace database {
namespace table {

/// Utilities
/// ---------------------------------------------------------------------------
constexpr auto ecdsa_max = system::power2(to_half(byte_bits));

constexpr bool ecdsa_check(size_t m, size_t n) NOEXCEPT
{
return !is_zero(m) && !is_zero(n) && !(n > ecdsa_max) && !(m > n);
}

constexpr size_t ecdsa_count(size_t m, size_t n) NOEXCEPT
{
using namespace system;
const auto gap = n - m;
if (is_subtract_overflow(n, m) || is_add_overflow(gap, one))
return {};

const auto sum = add1(gap);
if (is_multiply_overflow(m, sum))
return {};

return m * sum;
}

/// ecdsa_digest is an array of ecdsa verification record signature hashes.
struct ecdsa_digest
: public no_map<schema::ecdsa_digest>
Expand Down Expand Up @@ -80,8 +57,9 @@ struct ecdsa_digest
{
inline link count() const NOEXCEPT
{
return system::possible_narrow_cast<link::integer>(
ecdsa_count(sigs, keys));
using namespace system;
return possible_narrow_cast<link::integer>(
chain::multisig::rows(sigs, keys));
}

inline bool to_data(flipper& sink) const NOEXCEPT
Expand Down Expand Up @@ -129,27 +107,29 @@ struct ecdsa_compressed
{
inline link count() const NOEXCEPT
{
return system::possible_narrow_cast<link::integer>(
ecdsa_count(sigs, keys.size()));
using namespace system;
return possible_narrow_cast<link::integer>(
chain::multisig::rows(sigs, keys.size()));
}

inline bool to_data(flipper& sink) const NOEXCEPT
{
using namespace system::chain;
const auto m = sigs;
const auto n = keys.size();
if (!ecdsa_check(m, n))
if (!multisig::check(m, n))
return false;

const auto gap = (n - m);
for (size_t sig{}; sig < m; ++sig)
for (auto key = sig; key <= gap + sig; ++key)
sink.write_bytes(keys.at(key));
sink.write_bytes(keys[key]);

BC_ASSERT(!sink || sink.get_write_position() == count() * minrow);
return sink;
}

const system::ec_compresseds& keys;
const std::span<const system::ec_compressed> keys;
const size_t sigs{};
};
};
Expand Down Expand Up @@ -183,28 +163,30 @@ struct ecdsa_signature
{
inline link count() const NOEXCEPT
{
return system::possible_narrow_cast<link::integer>(
ecdsa_count(sigs.size(), keys));
using namespace system;
return possible_narrow_cast<link::integer>(
chain::multisig::rows(sigs.size(), keys));
}

inline bool to_data(flipper& sink) const NOEXCEPT
{
using namespace system::chain;
const auto m = sigs.size();
const auto n = keys;
if (!ecdsa_check(m, n))
if (!multisig::check(m, n))
return false;

const auto gap = (n - m);
for (size_t sig{}; sig < m; ++sig)
for (auto key = sig; key <= gap + sig; ++key)
sink.write_bytes(sigs.at(sig));
sink.write_bytes(sigs[sig]);

BC_ASSERT(!sink || sink.get_write_position() == count() * minrow);
return sink;
}

const size_t keys{};
const system::ec_signatures& sigs;
const std::span<const system::ec_signature> sigs;
};
};

Expand Down Expand Up @@ -265,15 +247,17 @@ struct ecdsa_correlate
{
inline link count() const NOEXCEPT
{
return system::possible_narrow_cast<link::integer>(
ecdsa_count(sigs, keys));
using namespace system;
return possible_narrow_cast<link::integer>(
chain::multisig::rows(sigs, keys));
}

inline bool to_data(flipper& sink) const NOEXCEPT
{
using namespace system::chain;
const auto m = sigs;
const auto n = keys;
if (!ecdsa_check(m, n))
if (!multisig::check(m, n))
return false;

const auto gap = (n - m);
Expand Down
Loading
Loading