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

refactor: Use typesafe Wtxid in compact block encodings #29752

Merged
merged 2 commits into from
Apr 9, 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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
15 changes: 9 additions & 6 deletions src/blockencodings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,14 @@ void CBlockHeaderAndShortTxIDs::FillShortTxIDSelector() const {
shorttxidk1 = shorttxidhash.GetUint64(1);
}

uint64_t CBlockHeaderAndShortTxIDs::GetShortID(const uint256& txhash) const {
uint64_t CBlockHeaderAndShortTxIDs::GetShortID(const Wtxid& wtxid) const {
static_assert(SHORTTXIDS_LENGTH == 6, "shorttxids calculation assumes 6-byte shorttxids");
return SipHashUint256(shorttxidk0, shorttxidk1, txhash) & 0xffffffffffffL;
return SipHashUint256(shorttxidk0, shorttxidk1, wtxid) & 0xffffffffffffL;
}



ReadStatus PartiallyDownloadedBlock::InitData(const CBlockHeaderAndShortTxIDs& cmpctblock, const std::vector<std::pair<uint256, CTransactionRef>>& extra_txn) {
ReadStatus PartiallyDownloadedBlock::InitData(const CBlockHeaderAndShortTxIDs& cmpctblock, const std::vector<CTransactionRef>& extra_txn) {
if (cmpctblock.header.IsNull() || (cmpctblock.shorttxids.empty() && cmpctblock.prefilledtxn.empty()))
return READ_STATUS_INVALID;
if (cmpctblock.shorttxids.size() + cmpctblock.prefilledtxn.size() > MAX_BLOCK_WEIGHT / MIN_SERIALIZABLE_TRANSACTION_WEIGHT)
Expand Down Expand Up @@ -134,11 +134,14 @@ ReadStatus PartiallyDownloadedBlock::InitData(const CBlockHeaderAndShortTxIDs& c
}

for (size_t i = 0; i < extra_txn.size(); i++) {
uint64_t shortid = cmpctblock.GetShortID(extra_txn[i].first);
if (extra_txn[i] == nullptr) {
continue;
}
uint64_t shortid = cmpctblock.GetShortID(extra_txn[i]->GetWitnessHash());
std::unordered_map<uint64_t, uint16_t>::iterator idit = shorttxids.find(shortid);
if (idit != shorttxids.end()) {
if (!have_txn[idit->second]) {
txn_available[idit->second] = extra_txn[i].second;
txn_available[idit->second] = extra_txn[i];
have_txn[idit->second] = true;
mempool_count++;
extra_count++;
Expand All @@ -150,7 +153,7 @@ ReadStatus PartiallyDownloadedBlock::InitData(const CBlockHeaderAndShortTxIDs& c
// Note that we don't want duplication between extra_txn and mempool to
// trigger this case, so we compare witness hashes first
if (txn_available[idit->second] &&
txn_available[idit->second]->GetWitnessHash() != extra_txn[i].second->GetWitnessHash()) {
txn_available[idit->second]->GetWitnessHash() != extra_txn[i]->GetWitnessHash()) {
txn_available[idit->second].reset();
mempool_count--;
extra_count--;
Expand Down
4 changes: 2 additions & 2 deletions src/blockencodings.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ class CBlockHeaderAndShortTxIDs {

CBlockHeaderAndShortTxIDs(const CBlock& block);

uint64_t GetShortID(const uint256& txhash) const;
uint64_t GetShortID(const Wtxid& wtxid) const;

size_t BlockTxCount() const { return shorttxids.size() + prefilledtxn.size(); }

Expand Down Expand Up @@ -142,7 +142,7 @@ class PartiallyDownloadedBlock {
explicit PartiallyDownloadedBlock(CTxMemPool* poolIn) : pool(poolIn) {}

// extra_txn is a list of extra transactions to look at, in <witness hash, reference> form
ReadStatus InitData(const CBlockHeaderAndShortTxIDs& cmpctblock, const std::vector<std::pair<uint256, CTransactionRef>>& extra_txn);
ReadStatus InitData(const CBlockHeaderAndShortTxIDs& cmpctblock, const std::vector<CTransactionRef>& extra_txn);
bool IsTxAvailable(size_t index) const;
ReadStatus FillBlock(CBlock& block, const std::vector<CTransactionRef>& vtx_missing);
};
Expand Down
4 changes: 2 additions & 2 deletions src/net_processing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1006,7 +1006,7 @@ class PeerManagerImpl final : public PeerManager
/** Orphan/conflicted/etc transactions that are kept for compact block reconstruction.
* The last -blockreconstructionextratxn/DEFAULT_BLOCK_RECONSTRUCTION_EXTRA_TXN of
* these are kept in a ring buffer */
std::vector<std::pair<uint256, CTransactionRef>> vExtraTxnForCompact GUARDED_BY(g_msgproc_mutex);
std::vector<CTransactionRef> vExtraTxnForCompact GUARDED_BY(g_msgproc_mutex);
/** Offset into vExtraTxnForCompact to insert the next tx */
size_t vExtraTxnForCompactIt GUARDED_BY(g_msgproc_mutex) = 0;

Expand Down Expand Up @@ -1802,7 +1802,7 @@ void PeerManagerImpl::AddToCompactExtraTransactions(const CTransactionRef& tx)
return;
if (!vExtraTxnForCompact.size())
vExtraTxnForCompact.resize(m_opts.max_extra_txs);
vExtraTxnForCompact[vExtraTxnForCompactIt] = std::make_pair(tx->GetWitnessHash(), tx);
vExtraTxnForCompact[vExtraTxnForCompactIt] = tx;
vExtraTxnForCompactIt = (vExtraTxnForCompactIt + 1) % m_opts.max_extra_txs;
}

Expand Down
10 changes: 5 additions & 5 deletions src/test/blockencodings_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

#include <boost/test/unit_test.hpp>

std::vector<std::pair<uint256, CTransactionRef>> extra_txn;
std::vector<CTransactionRef> extra_txn;

BOOST_FIXTURE_TEST_SUITE(blockencodings_tests, RegTestingSetup)

Expand Down Expand Up @@ -126,7 +126,7 @@ class TestHeaderAndShortIDs {
explicit TestHeaderAndShortIDs(const CBlock& block) :
TestHeaderAndShortIDs(CBlockHeaderAndShortTxIDs{block}) {}

uint64_t GetShortID(const uint256& txhash) const {
uint64_t GetShortID(const Wtxid& txhash) const {
DataStream stream{};
stream << *this;
CBlockHeaderAndShortTxIDs base;
Expand Down Expand Up @@ -155,8 +155,8 @@ BOOST_AUTO_TEST_CASE(NonCoinbasePreforwardRTTest)
shortIDs.prefilledtxn.resize(1);
shortIDs.prefilledtxn[0] = {1, block.vtx[1]};
shortIDs.shorttxids.resize(2);
shortIDs.shorttxids[0] = shortIDs.GetShortID(block.vtx[0]->GetHash());
shortIDs.shorttxids[1] = shortIDs.GetShortID(block.vtx[2]->GetHash());
shortIDs.shorttxids[0] = shortIDs.GetShortID(block.vtx[0]->GetWitnessHash());
shortIDs.shorttxids[1] = shortIDs.GetShortID(block.vtx[2]->GetWitnessHash());

DataStream stream{};
stream << shortIDs;
Expand Down Expand Up @@ -226,7 +226,7 @@ BOOST_AUTO_TEST_CASE(SufficientPreforwardRTTest)
shortIDs.prefilledtxn[0] = {0, block.vtx[0]};
shortIDs.prefilledtxn[1] = {1, block.vtx[2]}; // id == 1 as it is 1 after index 1
shortIDs.shorttxids.resize(1);
shortIDs.shorttxids[0] = shortIDs.GetShortID(block.vtx[1]->GetHash());
shortIDs.shorttxids[0] = shortIDs.GetShortID(block.vtx[1]->GetWitnessHash());

DataStream stream{};
stream << shortIDs;
Expand Down
4 changes: 2 additions & 2 deletions src/test/fuzz/partially_downloaded_block.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,15 +60,15 @@ FUZZ_TARGET(partially_downloaded_block, .init = initialize_pdb)
// The coinbase is always available
available.insert(0);

std::vector<std::pair<uint256, CTransactionRef>> extra_txn;
std::vector<CTransactionRef> extra_txn;
for (size_t i = 1; i < block->vtx.size(); ++i) {
auto tx{block->vtx[i]};

bool add_to_extra_txn{fuzzed_data_provider.ConsumeBool()};
bool add_to_mempool{fuzzed_data_provider.ConsumeBool()};

if (add_to_extra_txn) {
extra_txn.emplace_back(tx->GetWitnessHash(), tx);
extra_txn.emplace_back(tx);
available.insert(i);
}

Expand Down