Page MenuHomePhabricator

blockencodings.h
No OneTemporary

blockencodings.h

// Copyright (c) 2016 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_BLOCKENCODINGS_H
#define BITCOIN_BLOCKENCODINGS_H
#include <primitives/block.h>
class Config;
class CTxMemPool;
// Dumb helper to handle CTransaction compression at serialize-time
struct TransactionCompressor {
private:
CTransactionRef &tx;
public:
explicit TransactionCompressor(CTransactionRef &txIn) : tx(txIn) {}
ADD_SERIALIZE_METHODS;
template <typename Stream, typename Operation>
inline void SerializationOp(Stream &s, Operation ser_action) {
// TODO: Compress tx encoding
READWRITE(tx);
}
};
class BlockTransactionsRequest {
public:
// A BlockTransactionsRequest message
BlockHash blockhash;
std::vector<uint32_t> indices;
ADD_SERIALIZE_METHODS;
template <typename Stream, typename Operation>
inline void SerializationOp(Stream &s, Operation ser_action) {
READWRITE(blockhash);
uint64_t indices_size = uint64_t(indices.size());
READWRITE(COMPACTSIZE(indices_size));
if (ser_action.ForRead()) {
size_t i = 0;
while (indices.size() < indices_size) {
indices.resize(
std::min(uint64_t(1000 + indices.size()), indices_size));
for (; i < indices.size(); i++) {
uint64_t n = 0;
READWRITE(COMPACTSIZE(n));
if (n > std::numeric_limits<uint32_t>::max()) {
throw std::ios_base::failure(
"index overflowed 32 bits");
}
indices[i] = n;
}
}
uint64_t offset = 0;
for (auto &index : indices) {
if (uint64_t(index) + offset >
std::numeric_limits<uint32_t>::max()) {
throw std::ios_base::failure("indices overflowed 32 bits");
}
index = index + offset;
offset = uint64_t(index) + 1;
}
} else {
for (size_t i = 0; i < indices.size(); i++) {
uint64_t index =
indices[i] - (i == 0 ? 0 : (indices[i - 1] + 1));
READWRITE(COMPACTSIZE(index));
}
}
}
};
class BlockTransactions {
public:
// A BlockTransactions message
BlockHash blockhash;
std::vector<CTransactionRef> txn;
BlockTransactions() {}
explicit BlockTransactions(const BlockTransactionsRequest &req)
: blockhash(req.blockhash), txn(req.indices.size()) {}
ADD_SERIALIZE_METHODS;
template <typename Stream, typename Operation>
inline void SerializationOp(Stream &s, Operation ser_action) {
READWRITE(blockhash);
uint64_t txn_size = (uint64_t)txn.size();
READWRITE(COMPACTSIZE(txn_size));
if (ser_action.ForRead()) {
size_t i = 0;
while (txn.size() < txn_size) {
txn.resize(std::min(uint64_t(1000 + txn.size()), txn_size));
for (; i < txn.size(); i++) {
READWRITE(TransactionCompressor(txn[i]));
}
}
} else {
for (size_t i = 0; i < txn.size(); i++) {
READWRITE(TransactionCompressor(txn[i]));
}
}
}
};
// Dumb serialization/storage-helper for CBlockHeaderAndShortTxIDs and
// PartiallyDownloadedBlock
struct PrefilledTransaction {
// Used as an offset since last prefilled tx in CBlockHeaderAndShortTxIDs,
// as a proper transaction-in-block-index in PartiallyDownloadedBlock
uint32_t index;
CTransactionRef tx;
ADD_SERIALIZE_METHODS;
template <typename Stream, typename Operation>
inline void SerializationOp(Stream &s, Operation ser_action) {
uint64_t n = index;
READWRITE(COMPACTSIZE(n));
if (n > std::numeric_limits<uint32_t>::max()) {
throw std::ios_base::failure("index overflowed 32-bits");
}
index = n;
READWRITE(TransactionCompressor(tx));
}
};
typedef enum ReadStatus_t {
READ_STATUS_OK,
// Invalid object, peer is sending bogus crap.
// FIXME: differenciate bogus crap from crap that do not fit our policy.
READ_STATUS_INVALID,
// Failed to process object.
READ_STATUS_FAILED,
// Used only by FillBlock to indicate a failure in CheckBlock.
READ_STATUS_CHECKBLOCK_FAILED,
} ReadStatus;
class CBlockHeaderAndShortTxIDs {
private:
mutable uint64_t shorttxidk0, shorttxidk1;
uint64_t nonce;
void FillShortTxIDSelector() const;
friend class PartiallyDownloadedBlock;
static const int SHORTTXIDS_LENGTH = 6;
protected:
std::vector<uint64_t> shorttxids;
std::vector<PrefilledTransaction> prefilledtxn;
public:
CBlockHeader header;
// Dummy for deserialization
CBlockHeaderAndShortTxIDs() {}
explicit CBlockHeaderAndShortTxIDs(const CBlock &block);
uint64_t GetShortID(const TxHash &txhash) const;
size_t BlockTxCount() const {
return shorttxids.size() + prefilledtxn.size();
}
ADD_SERIALIZE_METHODS;
template <typename Stream, typename Operation>
inline void SerializationOp(Stream &s, Operation ser_action) {
READWRITE(header);
READWRITE(nonce);
uint64_t shorttxids_size = (uint64_t)shorttxids.size();
READWRITE(COMPACTSIZE(shorttxids_size));
if (ser_action.ForRead()) {
size_t i = 0;
while (shorttxids.size() < shorttxids_size) {
shorttxids.resize(std::min(uint64_t(1000 + shorttxids.size()),
shorttxids_size));
for (; i < shorttxids.size(); i++) {
uint32_t lsb = 0;
uint16_t msb = 0;
READWRITE(lsb);
READWRITE(msb);
shorttxids[i] = (uint64_t(msb) << 32) | uint64_t(lsb);
static_assert(
SHORTTXIDS_LENGTH == 6,
"shorttxids serialization assumes 6-byte shorttxids");
}
}
} else {
for (uint64_t shortid : shorttxids) {
uint32_t lsb = shortid & 0xffffffff;
uint16_t msb = (shortid >> 32) & 0xffff;
READWRITE(lsb);
READWRITE(msb);
}
}
READWRITE(prefilledtxn);
if (BlockTxCount() > std::numeric_limits<uint32_t>::max()) {
throw std::ios_base::failure("indices overflowed 32 bits");
}
if (ser_action.ForRead()) {
FillShortTxIDSelector();
}
}
};
class PartiallyDownloadedBlock {
protected:
std::vector<CTransactionRef> txns_available;
size_t prefilled_count = 0, mempool_count = 0, extra_count = 0;
const CTxMemPool *pool;
const Config *config;
public:
CBlockHeader header;
PartiallyDownloadedBlock(const Config &configIn, CTxMemPool *poolIn)
: pool(poolIn), config(&configIn) {}
// extra_txn is a list of extra transactions to look at, in <txhash,
// reference> form.
ReadStatus
InitData(const CBlockHeaderAndShortTxIDs &cmpctblock,
const std::vector<std::pair<TxHash, CTransactionRef>> &extra_txn);
bool IsTxAvailable(size_t index) const;
ReadStatus FillBlock(CBlock &block,
const std::vector<CTransactionRef> &vtx_missing);
};
#endif // BITCOIN_BLOCKENCODINGS_H

File Metadata

Mime Type
text/x-c++
Expires
Mon, Nov 25, 08:07 (1 d, 20 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
4530468
Default Alt Text
blockencodings.h (7 KB)

Event Timeline