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
65 changes: 14 additions & 51 deletions include/bitcoin/database/impl/query/batch/ecdsa.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -74,75 +74,38 @@ bool CLASS::purge_ecdsa_signatures() NOEXCEPT
}

TEMPLATE
bool CLASS::set_signature(const hash_digest& digest,
const ec_compressed& point, const ec_signature& signature, uint16_t id,
bool CLASS::set_signatures(const system::chain::ecdsa_signatures& sigs,
const header_link& link) NOEXCEPT
{
using correlate_t = table::ecdsa_correlate::put_ref;
using digest_t = table::ecdsa_digest::put_ref;
using compressed_t = table::ecdsa_compressed::put_ref;
using signature_t = table::ecdsa_signature::put_ref;
using correlate_t = table::ecdsa_correlate::put_signatures;
using digest_t = table::ecdsa_digest::put_signatures;
using compressed_t = table::ecdsa_compressed::put_signatures;
using signature_t = table::ecdsa_signature::put_signatures;

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

using namespace system;
const auto row = possible_narrow_cast<ecdsa_link::integer>(one);

// Allocate 1 row across all columns.
const auto fk = store_.ecdsa.allocate(row);
if (fk.is_terminal())
return false;

// Guard against remap (required for nomaps::put(fk)).
const auto guard = store_.ecdsa.guard();

// Write one value to each column in corresponding positions.
return
store_.ecdsa.correlate.put(fk, correlate_t{ {}, link, id }) &&
store_.ecdsa.digest.put(fk, digest_t{ {}, digest }) &&
store_.ecdsa.compressed.put(fk, compressed_t{ {}, point }) &&
store_.ecdsa.signature.put(fk, signature_t{ {}, signature });
// ========================================================================
}

TEMPLATE
bool CLASS::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
{
using correlate_t = table::ecdsa_correlate::put_refs;
using digest_t = table::ecdsa_digest::put_refs;
using compressed_t = table::ecdsa_compressed::put_refs;
using signature_t = table::ecdsa_signature::put_refs;
if (sigs.empty())
return true;

using namespace system;
const auto csigs = sigs.size();
const auto ckeys = keys.size();
const auto count = chain::multisig::rows(csigs, ckeys);
const auto rows = possible_narrow_cast<ecdsa_link::integer>(sigs.rows());

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

const auto rows = possible_narrow_cast<ecdsa_link::integer>(count);

// Allocate rows across all columns.
// Allocate all of the block's rows across all columns.
const auto fk = store_.ecdsa.allocate(rows);
if (fk.is_terminal())
return false;

// Guard against remap (required for nomaps::put(fk)).
const auto guard = store_.ecdsa.guard();

// Write values to each column in corresponding positions.
// Deinterleave the accumulator into the columns, expanding group bands.
return
store_.ecdsa.correlate.put(fk, correlate_t{ {}, count, link, ckeys, csigs, id }) &&
store_.ecdsa.digest.put(fk, digest_t{ {}, count, digest }) &&
store_.ecdsa.compressed.put(fk, compressed_t{ {}, count, keys, csigs }) &&
store_.ecdsa.signature.put(fk, signature_t{ {}, count, ckeys, sigs });
store_.ecdsa.correlate.put(fk, correlate_t{ {}, link, sigs }) &&
store_.ecdsa.digest.put(fk, digest_t{ {}, sigs }) &&
store_.ecdsa.compressed.put(fk, compressed_t{ {}, sigs }) &&
store_.ecdsa.signature.put(fk, signature_t{ {}, sigs });
// ========================================================================
}

Expand Down
75 changes: 20 additions & 55 deletions include/bitcoin/database/impl/query/batch/schnorr.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -73,74 +73,39 @@ bool CLASS::purge_schnorr_signatures() NOEXCEPT
}

TEMPLATE
bool CLASS::set_signature(const hash_digest& digest, const ec_xonly& point,
const ec_signature& signature, const header_link& link) NOEXCEPT
bool CLASS::set_signatures(const system::chain::schnorr_signatures& sigs,
const header_link& link) NOEXCEPT
{
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;
using correlate_t = table::schnorr_correlate::put_signatures;
using digest_t = table::schnorr_digest::put_signatures;
using xonly_t = table::schnorr_xonly::put_signatures;
using signature_t = table::schnorr_signature::put_signatures;

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

using namespace system;
const auto row = possible_narrow_cast<schnorr_link::integer>(one);

// Allocate 1 row across all columns.
const auto fk = store_.schnorr.allocate(row);
if (fk.is_terminal())
return false;

// Guard against remap (required for nomaps::put(fk)).
const auto guard = store_.schnorr.guard();

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

TEMPLATE
schnorr_link CLASS::allocate_signatures(size_t count) NOEXCEPT
{
// Allocate count rows across all columns (hot storage).
// ========================================================================
const auto scope = get_transactor();

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

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;
const auto rows = possible_narrow_cast<schnorr_link::integer>(
sigs.rows().size());

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

// Allocate all of the block's rows across all columns.
const auto fk = store_.schnorr.allocate(rows);
if (fk.is_terminal())
return false;

// Guard against remap (required for nomaps::put(fk)).
const auto guard = store_.schnorr.guard();

// Deinterleave the accumulator into the columns.
return
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 });
store_.schnorr.correlate.put(fk, correlate_t{ {}, link, sigs }) &&
store_.schnorr.digest.put(fk, digest_t{ {}, sigs }) &&
store_.schnorr.xonly.put(fk, xonly_t{ {}, sigs }) &&
store_.schnorr.signature.put(fk, signature_t{ {}, sigs });
// ========================================================================
}

Expand Down
21 changes: 4 additions & 17 deletions include/bitcoin/database/query.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -592,25 +592,12 @@ class query
bool set_silent(const tx_link& link, const transaction& tx) NOEXCEPT;
bool set_silent(const header_link& link, const block& block) NOEXCEPT;

/// Set single ecdsa signature row.
bool set_signature(const hash_digest& digest, const ec_compressed& point,
const ec_signature& signature, uint16_t id,
/// Commit a block's captured ecdsa signature groups (band-expanded).
bool set_signatures(const system::chain::ecdsa_signatures& sigs,
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 schnorr threshold signature rows.
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,
/// Commit a block's captured schnorr signature rows.
bool set_signatures(const system::chain::schnorr_signatures& sigs,
const header_link& link) NOEXCEPT;

/// Invoke callback for each candidate match, false implies cancel.
Expand Down
132 changes: 132 additions & 0 deletions include/bitcoin/database/tables/caches/ecdsa.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,36 @@ struct ecdsa_digest
const size_t rows{};
const hash_digest& digest;
};

struct put_signatures
: public schema::ecdsa_digest
{
inline link count() const NOEXCEPT
{
return system::possible_narrow_cast<link::integer>(sigs.rows());
}

inline bool to_data(flipper& sink) const NOEXCEPT
{
using namespace system;
sigs.for_each([&](const hash_digest& digest,
std::span<const ec_compressed> keys,
std::span<const ec_signature> sigs) NOEXCEPT
{
// Group capture is limited to common signature hash.
const auto rows = chain::multisig::rows(sigs.size(),
keys.size());

for (size_t row{}; row < rows; ++row)
sink.write_bytes(digest);
});

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

const system::chain::ecdsa_signatures& sigs;
};
};

/// ecdsa_compressed is an array of ecdsa verification compressed public keys.
Expand Down Expand Up @@ -127,6 +157,36 @@ struct ecdsa_compressed
const std::span<const system::ec_compressed> keys;
const size_t sigs{};
};

struct put_signatures
: public schema::ecdsa_compressed
{
inline link count() const NOEXCEPT
{
return system::possible_narrow_cast<link::integer>(sigs.rows());
}

inline bool to_data(flipper& sink) const NOEXCEPT
{
using namespace system;
sigs.for_each([&](const hash_digest&,
std::span<const ec_compressed> keys,
std::span<const ec_signature> sigs) NOEXCEPT
{
const auto m = sigs.size();
const auto gap = keys.size() - m;

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

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

const system::chain::ecdsa_signatures& sigs;
};
};

/// ecdsa_signature is an array of ecdsa verification signatures.
Expand Down Expand Up @@ -181,6 +241,36 @@ struct ecdsa_signature
const size_t keys{};
const std::span<const system::ec_signature> sigs;
};

struct put_signatures
: public schema::ecdsa_signature
{
inline link count() const NOEXCEPT
{
return system::possible_narrow_cast<link::integer>(sigs.rows());
}

inline bool to_data(flipper& sink) const NOEXCEPT
{
using namespace system;
sigs.for_each([&](const hash_digest&,
std::span<const ec_compressed> keys,
std::span<const ec_signature> sigs) NOEXCEPT
{
const auto m = sigs.size();
const auto gap = keys.size() - m;

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

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

const system::chain::ecdsa_signatures& sigs;
};
};

/// ecdsa_correlate is an array of ecdsa correlation records.
Expand Down Expand Up @@ -271,6 +361,48 @@ struct ecdsa_correlate
const size_t sigs{};
const uint16_t group{};
};

struct put_signatures
: public schema::ecdsa_correlate
{
inline link count() const NOEXCEPT
{
return system::possible_narrow_cast<link::integer>(sigs.rows());
}

inline bool to_data(flipper& sink) const NOEXCEPT
{
using namespace system;
uint16_t group{};
sigs.for_each([&](const hash_digest&,
std::span<const ec_compressed> keys,
std::span<const ec_signature> sigs) NOEXCEPT
{
const auto m = sigs.size();
const auto gap = keys.size() - m;

// Group id is the group capture ordinal (ecdsa_signatures).
for (size_t sig{}; sig < m; ++sig)
{
for (auto key = sig; key <= gap + sig; ++key)
{
sink.write_little_endian<hd::integer, hd::size>(
header_fk);
sink.write_byte(pack_word<uint8_t>(sig, key));
sink.write_little_endian<uint16_t>(group);
}
}

++group;
});

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

const hd::integer header_fk{};
const system::chain::ecdsa_signatures& sigs;
};
};

/// Aggregate (files)
Expand Down
Loading
Loading