Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bypass: set_strong before linking txs to header, comments. #483

Merged
merged 2 commits into from
Jun 2, 2024
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
32 changes: 19 additions & 13 deletions include/bitcoin/database/impl/query/archive.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,12 @@ inline bool CLASS::is_coinbase(const tx_link& link) const NOEXCEPT
}

TEMPLATE
inline bool CLASS::is_malleated(const block& block) const NOEXCEPT
inline bool CLASS::is_malleated64(const block& block) const NOEXCEPT
{
// This is a very cheap prequalification.
if (!block.is_malleable64())
return false;

auto it = store_.txs.it(to_header(block.hash()));
const auto transactions = *block.transactions_ptr();
do
Expand All @@ -94,7 +98,7 @@ inline bool CLASS::is_malleated(const block& block) const NOEXCEPT
if (txs.tx_fks.size() != transactions.size())
continue;

bool match{ true };
auto match{ true };
auto tx = transactions.begin();
for (const auto& link: txs.tx_fks)
{
Expand All @@ -113,7 +117,7 @@ inline bool CLASS::is_malleated(const block& block) const NOEXCEPT
}

TEMPLATE
inline bool CLASS::is_malleable(const header_link& link) const NOEXCEPT
inline bool CLASS::is_malleable64(const header_link& link) const NOEXCEPT
{
table::txs::get_malleable txs{};
return store_.txs.get(to_txs_link(link), txs) && txs.malleable;
Expand Down Expand Up @@ -735,7 +739,8 @@ code CLASS::set_code(tx_link& out_fk, const transaction& tx) NOEXCEPT
// GUARD (tx redundancy)
// Only fully effective if there is a single database thread.
// This reduces point store by ~45GiB, but causes thrashing.
if (minimize_) hash_fk = to_point(hash);
if (minimize_)
hash_fk = to_point(hash);

if (hash_fk.is_terminal())
{
Expand Down Expand Up @@ -974,7 +979,10 @@ code CLASS::set_code(txs_link& out_fk, const transactions& txs,
links.reserve(txs.size());
for (const auto& tx: txs)
{
if ((ec = set_code(tx_fk, *tx))) return ec;
// Each tx is set under a distinct transactor.
if ((ec = set_code(tx_fk, *tx)))
return ec;

links.push_back(tx_fk.value);
}

Expand All @@ -985,6 +993,10 @@ code CLASS::set_code(txs_link& out_fk, const transactions& txs,
// ========================================================================
const auto scope = store_.get_transactor();

// Clean allocation failure (e.g. disk full), see set_strong() comments.
if (confirm && !set_strong(key, links, true))
return error::txs_confirm;

// Header link is the key for the txs table.
// Clean single allocation failure (e.g. disk full).
out_fk = store_.txs.put_link(key, table::txs::slab
Expand All @@ -995,13 +1007,7 @@ code CLASS::set_code(txs_link& out_fk, const transactions& txs,
links
});

if (out_fk.is_terminal())
return error::txs_txs_put;

if (confirm && !set_strong(key, links, true))
return error::txs_confirm;

return error::success;
return out_fk.is_terminal() ? error::txs_txs_put : error::success;
// ========================================================================
}

Expand All @@ -1011,7 +1017,7 @@ bool CLASS::set_dissasociated(const header_link& key) NOEXCEPT
if (key.is_terminal())
return false;

const auto malleable = is_malleable(key);
const auto malleable = is_malleable64(key);

// ========================================================================
const auto scope = store_.get_transactor();
Expand Down
6 changes: 5 additions & 1 deletion include/bitcoin/database/impl/query/confirm.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,9 @@ bool CLASS::set_strong(const header_link& link, const tx_links& txs,
{
return std::all_of(txs.begin(), txs.end(), [&](const tx_link& fk) NOEXCEPT
{
// Clean allocation failure (e.g. disk full), block not confirmed.
// If under checkpoint txs is set later, so under fault will reoccur.
// Otherwise confirmed by height is set later so will also reoccur.
// Confirmation by height always sequential so can be no inconsistency.
return store_.strong_tx.put(fk, table::strong_tx::record
{
{},
Expand All @@ -371,6 +373,7 @@ bool CLASS::set_strong(const header_link& link) NOEXCEPT
// ========================================================================
const auto scope = store_.get_transactor();

// Clean allocation failure (e.g. disk full), see set_strong() comments.
return set_strong(link, txs, true);
// ========================================================================
}
Expand All @@ -385,6 +388,7 @@ bool CLASS::set_unstrong(const header_link& link) NOEXCEPT
// ========================================================================
const auto scope = store_.get_transactor();

// Clean allocation failure (e.g. disk full), see set_strong() comments.
return set_strong(link, txs, false);
// ========================================================================
}
Expand Down
4 changes: 2 additions & 2 deletions include/bitcoin/database/query.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -280,8 +280,8 @@ class query
inline bool is_block(const hash_digest& key) const NOEXCEPT;
inline bool is_tx(const hash_digest& key) const NOEXCEPT;
inline bool is_coinbase(const tx_link& link) const NOEXCEPT;
inline bool is_malleated(const block& block) const NOEXCEPT;
inline bool is_malleable(const header_link& link) const NOEXCEPT;
inline bool is_malleated64(const block& block) const NOEXCEPT;
inline bool is_malleable64(const header_link& link) const NOEXCEPT;
inline bool is_associated(const header_link& link) const NOEXCEPT;

bool set(const header& header, const chain_context& ctx) NOEXCEPT;
Expand Down
66 changes: 33 additions & 33 deletions test/query/archive.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -754,10 +754,10 @@ BOOST_AUTO_TEST_CASE(query_archive__set_block_txs__get_block__expected)
BOOST_REQUIRE_EQUAL(hashes.size(), 1u);
BOOST_REQUIRE_EQUAL(hashes, test::genesis.transaction_hashes(false));

BOOST_REQUIRE(!query.is_malleable(0));
BOOST_REQUIRE(!query.is_malleable64(0));
BOOST_REQUIRE(query.set_dissasociated(0));
BOOST_REQUIRE(!query.is_associated(0));
BOOST_REQUIRE(!query.is_malleable(0));
BOOST_REQUIRE(!query.is_malleable64(0));
}

// Moved to protected, set_link(block) covers.
Expand Down Expand Up @@ -906,7 +906,7 @@ BOOST_AUTO_TEST_CASE(query_archive__is_coinbase__non_coinbase__false)
BOOST_REQUIRE(!query.is_coinbase(42));
}

BOOST_AUTO_TEST_CASE(query_archive__is_malleable__non_malleable__false)
BOOST_AUTO_TEST_CASE(query_archive__is_malleable64__non_malleable__false)
{
settings settings{};
settings.path = TEST_DIRECTORY;
Expand All @@ -917,19 +917,19 @@ BOOST_AUTO_TEST_CASE(query_archive__is_malleable__non_malleable__false)
BOOST_REQUIRE(query.set(test::block1a, context{}));
BOOST_REQUIRE(query.set(test::block2a, context{}));

BOOST_REQUIRE(!query.is_malleable(1));
BOOST_REQUIRE(!query.is_malleable(2));
BOOST_REQUIRE(!query.is_malleable(3));
BOOST_REQUIRE(!query.is_malleable(4));
BOOST_REQUIRE(!query.is_malleable(5));
BOOST_REQUIRE(!query.is_malleable(42));
BOOST_REQUIRE(!query.is_malleable64(1));
BOOST_REQUIRE(!query.is_malleable64(2));
BOOST_REQUIRE(!query.is_malleable64(3));
BOOST_REQUIRE(!query.is_malleable64(4));
BOOST_REQUIRE(!query.is_malleable64(5));
BOOST_REQUIRE(!query.is_malleable64(42));

BOOST_REQUIRE(!query.is_malleated(test::genesis));
BOOST_REQUIRE(!query.is_malleated(test::block1a));
BOOST_REQUIRE(!query.is_malleated(test::block2a));
BOOST_REQUIRE(!query.is_malleated64(test::genesis));
BOOST_REQUIRE(!query.is_malleated64(test::block1a));
BOOST_REQUIRE(!query.is_malleated64(test::block2a));
}

BOOST_AUTO_TEST_CASE(query_archive__is_malleable__malleable__true)
BOOST_AUTO_TEST_CASE(query_archive__is_malleable64__malleable__true)
{
using namespace system::chain;
transaction tx64
Expand Down Expand Up @@ -963,16 +963,16 @@ BOOST_AUTO_TEST_CASE(query_archive__is_malleable__malleable__true)
BOOST_REQUIRE(query.is_associated(3));

// Only genesis is non-malleable.
BOOST_REQUIRE(!query.is_malleable(0));
BOOST_REQUIRE(query.is_malleable(1));
BOOST_REQUIRE(query.is_malleable(2));
BOOST_REQUIRE(query.is_malleable(3));
BOOST_REQUIRE(!query.is_malleable64(0));
BOOST_REQUIRE(query.is_malleable64(1));
BOOST_REQUIRE(query.is_malleable64(2));
BOOST_REQUIRE(query.is_malleable64(3));

// Only genesis is non-malleated when compared against itself, since not malleable.
BOOST_REQUIRE(!query.is_malleated(test::genesis));
BOOST_REQUIRE(query.is_malleated(block1));
BOOST_REQUIRE(query.is_malleated(block2));
BOOST_REQUIRE(query.is_malleated(block3));
BOOST_REQUIRE(!query.is_malleated64(test::genesis));
BOOST_REQUIRE(query.is_malleated64(block1));
BOOST_REQUIRE(query.is_malleated64(block2));
BOOST_REQUIRE(query.is_malleated64(block3));

// Disassociate 3 blocks.
BOOST_REQUIRE(query.set_dissasociated(query.to_header(block1.hash())));
Expand All @@ -985,14 +985,14 @@ BOOST_AUTO_TEST_CASE(query_archive__is_malleable__malleable__true)
BOOST_REQUIRE(!query.is_associated(3));

// Verify all 3 remain malleable.
BOOST_REQUIRE(query.is_malleable(1));
BOOST_REQUIRE(query.is_malleable(2));
BOOST_REQUIRE(query.is_malleable(3));
BOOST_REQUIRE(query.is_malleable64(1));
BOOST_REQUIRE(query.is_malleable64(2));
BOOST_REQUIRE(query.is_malleable64(3));

// Verify all 3 remain malleated by first association (against themselves).
BOOST_REQUIRE(query.is_malleated(block1));
BOOST_REQUIRE(query.is_malleated(block2));
BOOST_REQUIRE(query.is_malleated(block3));
BOOST_REQUIRE(query.is_malleated64(block1));
BOOST_REQUIRE(query.is_malleated64(block2));
BOOST_REQUIRE(query.is_malleated64(block3));

// Reassociate the same transaction sets (first(n), disassociated (0), second(n))
BOOST_REQUIRE(!query.set_link(*block1.transactions_ptr(), 1, block1.serialized_size(true)).is_terminal());
Expand All @@ -1005,14 +1005,14 @@ BOOST_AUTO_TEST_CASE(query_archive__is_malleable__malleable__true)
BOOST_REQUIRE(query.is_associated(3));

// Verify all 3 are associated as malleable.
BOOST_REQUIRE(query.is_malleable(1));
BOOST_REQUIRE(query.is_malleable(2));
BOOST_REQUIRE(query.is_malleable(3));
BOOST_REQUIRE(query.is_malleable64(1));
BOOST_REQUIRE(query.is_malleable64(2));
BOOST_REQUIRE(query.is_malleable64(3));

// Verify all 3 remain malleated by second association (against themselves).
BOOST_REQUIRE(query.is_malleated(block1));
BOOST_REQUIRE(query.is_malleated(block2));
BOOST_REQUIRE(query.is_malleated(block3));
BOOST_REQUIRE(query.is_malleated64(block1));
BOOST_REQUIRE(query.is_malleated64(block2));
BOOST_REQUIRE(query.is_malleated64(block3));

// Verify stored block sizes.
BOOST_REQUIRE_EQUAL(query.get_block_size(0), test::genesis.serialized_size(true));
Expand Down
Loading