Changeset View
Changeset View
Standalone View
Standalone View
src/blockencodings.cpp
Show First 20 Lines • Show All 56 Lines • ▼ Show 20 Lines | if (cmpctblock.shorttxids.size() + cmpctblock.prefilledtxn.size() > | ||||
config->GetMaxBlockSize() / MIN_TRANSACTION_SIZE) { | config->GetMaxBlockSize() / MIN_TRANSACTION_SIZE) { | ||||
return READ_STATUS_INVALID; | return READ_STATUS_INVALID; | ||||
} | } | ||||
assert(header.IsNull() && txns_available.empty()); | assert(header.IsNull() && txns_available.empty()); | ||||
header = cmpctblock.header; | header = cmpctblock.header; | ||||
txns_available.resize(cmpctblock.BlockTxCount()); | txns_available.resize(cmpctblock.BlockTxCount()); | ||||
int32_t lastprefilledindex = -1; | int64_t lastprefilledindex = -1; | ||||
for (size_t i = 0; i < cmpctblock.prefilledtxn.size(); i++) { | for (size_t i = 0; i < cmpctblock.prefilledtxn.size(); i++) { | ||||
auto &prefilledtxn = cmpctblock.prefilledtxn[i]; | auto &prefilledtxn = cmpctblock.prefilledtxn[i]; | ||||
if (prefilledtxn.tx->IsNull()) { | if (prefilledtxn.tx->IsNull()) { | ||||
return READ_STATUS_INVALID; | return READ_STATUS_INVALID; | ||||
} | } | ||||
// index is a uint16_t, so can't overflow here. | // index is a uint32_t, so can't overflow here. | ||||
lastprefilledindex += prefilledtxn.index + 1; | lastprefilledindex += prefilledtxn.index + 1; | ||||
if (lastprefilledindex > std::numeric_limits<uint16_t>::max()) { | if (lastprefilledindex > std::numeric_limits<uint32_t>::max()) { | ||||
return READ_STATUS_INVALID; | return READ_STATUS_INVALID; | ||||
} | } | ||||
if (uint32_t(lastprefilledindex) > cmpctblock.shorttxids.size() + i) { | if (uint32_t(lastprefilledindex) > cmpctblock.shorttxids.size() + i) { | ||||
// If we are inserting a tx at an index greater than our full list | // If we are inserting a tx at an index greater than our full list | ||||
// of shorttxids plus the number of prefilled txn we've inserted, | // of shorttxids plus the number of prefilled txn we've inserted, | ||||
// then we have txn for which we have neither a prefilled txn or a | // then we have txn for which we have neither a prefilled txn or a | ||||
// shorttxid! | // shorttxid! | ||||
return READ_STATUS_INVALID; | return READ_STATUS_INVALID; | ||||
} | } | ||||
txns_available[lastprefilledindex] = prefilledtxn.tx; | txns_available[lastprefilledindex] = prefilledtxn.tx; | ||||
} | } | ||||
prefilled_count = cmpctblock.prefilledtxn.size(); | prefilled_count = cmpctblock.prefilledtxn.size(); | ||||
// Calculate map of txids -> positions and check mempool to see what we have | // Calculate map of txids -> positions and check mempool to see what we have | ||||
// (or don't). Because well-formed cmpctblock messages will have a | // (or don't). Because well-formed cmpctblock messages will have a | ||||
// (relatively) uniform distribution of short IDs, any highly-uneven | // (relatively) uniform distribution of short IDs, any highly-uneven | ||||
// distribution of elements can be safely treated as a READ_STATUS_FAILED. | // distribution of elements can be safely treated as a READ_STATUS_FAILED. | ||||
std::unordered_map<uint64_t, uint16_t> shorttxids( | std::unordered_map<uint64_t, uint32_t> shorttxids( | ||||
cmpctblock.shorttxids.size()); | cmpctblock.shorttxids.size()); | ||||
uint16_t index_offset = 0; | uint32_t index_offset = 0; | ||||
for (size_t i = 0; i < cmpctblock.shorttxids.size(); i++) { | for (size_t i = 0; i < cmpctblock.shorttxids.size(); i++) { | ||||
while (txns_available[i + index_offset]) { | while (txns_available[i + index_offset]) { | ||||
index_offset++; | index_offset++; | ||||
} | } | ||||
shorttxids[cmpctblock.shorttxids[i]] = i + index_offset; | shorttxids[cmpctblock.shorttxids[i]] = i + index_offset; | ||||
// To determine the chance that the number of entries in a bucket | // To determine the chance that the number of entries in a bucket | ||||
// exceeds N, we use the fact that the number of elements in a single | // exceeds N, we use the fact that the number of elements in a single | ||||
Show All 22 Lines | ReadStatus PartiallyDownloadedBlock::InitData( | ||||
std::vector<bool> have_txn(txns_available.size()); | std::vector<bool> have_txn(txns_available.size()); | ||||
{ | { | ||||
LOCK(pool->cs); | LOCK(pool->cs); | ||||
const std::vector<std::pair<uint256, CTxMemPool::txiter>> &vTxHashes = | const std::vector<std::pair<uint256, CTxMemPool::txiter>> &vTxHashes = | ||||
pool->vTxHashes; | pool->vTxHashes; | ||||
for (auto txHash : vTxHashes) { | for (auto txHash : vTxHashes) { | ||||
uint64_t shortid = cmpctblock.GetShortID(txHash.first); | uint64_t shortid = cmpctblock.GetShortID(txHash.first); | ||||
std::unordered_map<uint64_t, uint16_t>::iterator idit = | std::unordered_map<uint64_t, uint32_t>::iterator idit = | ||||
shorttxids.find(shortid); | shorttxids.find(shortid); | ||||
if (idit != shorttxids.end()) { | if (idit != shorttxids.end()) { | ||||
if (!have_txn[idit->second]) { | if (!have_txn[idit->second]) { | ||||
txns_available[idit->second] = txHash.second->GetSharedTx(); | txns_available[idit->second] = txHash.second->GetSharedTx(); | ||||
have_txn[idit->second] = true; | have_txn[idit->second] = true; | ||||
mempool_count++; | mempool_count++; | ||||
} else { | } else { | ||||
// If we find two mempool txn that match the short id, just | // If we find two mempool txn that match the short id, just | ||||
Show All 12 Lines | std::vector<bool> have_txn(txns_available.size()); | ||||
if (mempool_count == shorttxids.size()) { | if (mempool_count == shorttxids.size()) { | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
for (auto &extra_txn : extra_txns) { | for (auto &extra_txn : extra_txns) { | ||||
uint64_t shortid = cmpctblock.GetShortID(extra_txn.first); | uint64_t shortid = cmpctblock.GetShortID(extra_txn.first); | ||||
std::unordered_map<uint64_t, uint16_t>::iterator idit = | std::unordered_map<uint64_t, uint32_t>::iterator idit = | ||||
shorttxids.find(shortid); | shorttxids.find(shortid); | ||||
if (idit != shorttxids.end()) { | if (idit != shorttxids.end()) { | ||||
if (!have_txn[idit->second]) { | if (!have_txn[idit->second]) { | ||||
txns_available[idit->second] = extra_txn.second; | txns_available[idit->second] = extra_txn.second; | ||||
have_txn[idit->second] = true; | have_txn[idit->second] = true; | ||||
mempool_count++; | mempool_count++; | ||||
extra_count++; | extra_count++; | ||||
} else { | } else { | ||||
▲ Show 20 Lines • Show All 95 Lines • Show Last 20 Lines |