11std::vector<uint8_t>
BitsToBytes(
const std::vector<bool> &bits) {
12 std::vector<uint8_t> ret((bits.size() + 7) / 8);
13 for (
unsigned int p = 0; p < bits.size(); p++) {
14 ret[p / 8] |= bits[p] << (p % 8);
19std::vector<bool>
BytesToBits(
const std::vector<uint8_t> &bytes) {
20 std::vector<bool> ret(bytes.size() * 8);
21 for (
unsigned int p = 0; p < ret.size(); p++) {
22 ret[p] = (bytes[p / 8] & (1 << (p % 8))) != 0;
28 const std::set<TxId> *txids) {
31 std::vector<bool> vMatch;
32 std::vector<uint256> vHashes;
34 vMatch.reserve(block.
vtx.size());
35 vHashes.reserve(block.
vtx.size());
38 for (
const auto &tx : block.
vtx) {
43 for (
size_t i = 0; i < block.
vtx.size(); i++) {
44 const CTransaction *tx = block.
vtx[i].get();
45 const TxId &txid = tx->GetId();
54 vMatch.push_back(txids && txids->count(txid));
57 vHashes.push_back(txid);
64 const std::vector<uint256> &vTxid) {
79 right =
CalcHash(height - 1, pos * 2 + 1, vTxid);
85 return Hash(left, right);
89 const std::vector<uint256> &vTxid,
90 const std::vector<bool> &vMatch) {
92 bool fParentOfMatch =
false;
93 for (
size_t p = pos << height; p < (pos + 1) << height && p <
nTransactions;
95 fParentOfMatch |= vMatch[p];
99 vBits.push_back(fParentOfMatch);
100 if (height == 0 || !fParentOfMatch) {
115 std::vector<uint256> &vMatch,
116 std::vector<size_t> &vnIndex) {
117 if (nBitsUsed >=
vBits.size()) {
123 bool fParentOfMatch =
vBits[nBitsUsed++];
124 if (height == 0 || !fParentOfMatch) {
127 if (nHashUsed >=
vHash.size()) {
134 if (height == 0 && fParentOfMatch) {
135 vMatch.push_back(hash);
136 vnIndex.push_back(pos);
147 nHashUsed, vMatch, vnIndex);
158 return Hash(left, right);
162 const std::vector<bool> &vMatch)
163 : nTransactions(vTxid.size()), fBad(false) {
181 std::vector<size_t> &vnIndex) {
210 size_t nBitsUsed = 0, nHashUsed = 0;
221 if ((nBitsUsed + 7) / 8 != (
vBits.size() + 7) / 8) {
226 if (nHashUsed !=
vHash.size()) {
230 return hashMerkleRoot;
std::vector< CTransactionRef > vtx
CBlockHeader GetBlockHeader() const
BloomFilter is a probabilistic filter which SPV clients provide so that we can filter the transaction...
bool MatchInputs(const CTransaction &tx)
Scan inputs to see if the spent outpoints are a match, or the input scripts contain matching elements...
bool MatchAndInsertOutputs(const CTransaction &tx)
Scans output scripts for matches and adds those outpoints to the filter for spend detection.
CBlockHeader header
Public only for unit testing.
std::vector< std::pair< size_t, uint256 > > vMatchedTxn
Public only for unit testing and relay testing (not relayed).
Data structure that represents a partial merkle tree.
uint32_t nTransactions
the total number of transactions in the block
uint256 TraverseAndExtract(int height, size_t pos, size_t &nBitsUsed, size_t &nHashUsed, std::vector< uint256 > &vMatch, std::vector< size_t > &vnIndex)
Recursive function that traverses tree nodes, consuming the bits and hashes produced by TraverseAndBu...
size_t CalcTreeWidth(int height) const
Helper function to efficiently calculate the number of nodes at given height in the merkle tree.
std::vector< bool > vBits
node-is-parent-of-matched-txid bits
bool fBad
flag set when encountering invalid data
uint256 ExtractMatches(std::vector< uint256 > &vMatch, std::vector< size_t > &vnIndex)
Extract the matching txid's represented by this partial merkle tree and their respective indices with...
std::vector< uint256 > vHash
txids and internal hashes
uint256 CalcHash(int height, size_t pos, const std::vector< uint256 > &vTxid)
Calculate the hash of a node in the merkle tree (at leaf level: the txid's themselves)
void TraverseAndBuild(int height, size_t pos, const std::vector< uint256 > &vTxid, const std::vector< bool > &vMatch)
Recursive function that traverses tree nodes, storing the data as bits and hashes.
uint256 Hash(const T &in1)
Compute the 256-bit hash of an object.
std::vector< uint8_t > BitsToBytes(const std::vector< bool > &bits)
std::vector< bool > BytesToBits(const std::vector< uint8_t > &bytes)
A TxId is the identifier of a transaction.