Skip to content

Commit

Permalink
Added Segregated witness bitcoin#8149
Browse files Browse the repository at this point in the history
  • Loading branch information
KolbyML committed Apr 19, 2021
1 parent 317a66a commit 8575e22
Show file tree
Hide file tree
Showing 84 changed files with 3,662 additions and 1,812 deletions.
10 changes: 5 additions & 5 deletions src/blockencodings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,15 @@

#define MIN_TRANSACTION_SIZE (::GetSerializeSize(CTransaction(), SER_NETWORK, PROTOCOL_VERSION))

CBlockHeaderAndShortTxIDs::CBlockHeaderAndShortTxIDs(const CBlock& block) :
CBlockHeaderAndShortTxIDs::CBlockHeaderAndShortTxIDs(const CBlock& block, bool fUseWTXID) :
nonce(GetRand(std::numeric_limits<uint64_t>::max())),
shorttxids(block.vtx.size() - 1), prefilledtxn(1), header(block), vchBlockSig(block.vchBlockSig) {
shorttxids(block.vtx.size() - 1), prefilledtxn(1), header(block) {
FillShortTxIDSelector();
//TODO: Use our mempool prior to block acceptance to predictively fill more than just the coinbase
prefilledtxn[0] = {0, block.vtx[0]};
for (size_t i = 1; i < block.vtx.size(); i++) {
const CTransaction& tx = *block.vtx[i];
shorttxids[i - 1] = GetShortID(tx.GetHash());
shorttxids[i - 1] = GetShortID(fUseWTXID ? tx.GetWitnessHash() : tx.GetHash());
}
}

Expand All @@ -50,7 +50,7 @@ uint64_t CBlockHeaderAndShortTxIDs::GetShortID(const uint256& txhash) const {
ReadStatus PartiallyDownloadedBlock::InitData(const CBlockHeaderAndShortTxIDs& cmpctblock, const std::vector<std::pair<uint256, CTransactionRef>>& extra_txn) {
if (cmpctblock.header.IsNull() || (cmpctblock.shorttxids.empty() && cmpctblock.prefilledtxn.empty()))
return READ_STATUS_INVALID;
if (cmpctblock.shorttxids.size() + cmpctblock.prefilledtxn.size() > MaxBlockSize(true) / MIN_TRANSACTION_SIZE)
if (cmpctblock.shorttxids.size() + cmpctblock.prefilledtxn.size() > MAX_BLOCK_WEIGHT / MIN_SERIALIZABLE_TRANSACTION_WEIGHT)
return READ_STATUS_INVALID;

assert(header.IsNull() && txn_available.empty());
Expand Down Expand Up @@ -151,7 +151,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 hashes first
if (txn_available[idit->second] &&
txn_available[idit->second]->GetHash() != extra_txn[i].second->GetHash()) {
txn_available[idit->second]->GetWitnessHash() != extra_txn[i].second->GetWitnessHash()) {
txn_available[idit->second].reset();
mempool_count--;
extra_count--;
Expand Down
2 changes: 1 addition & 1 deletion src/blockencodings.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ class CBlockHeaderAndShortTxIDs {
// Dummy for deserialization
CBlockHeaderAndShortTxIDs() {}

CBlockHeaderAndShortTxIDs(const CBlock& block);
CBlockHeaderAndShortTxIDs(const CBlock& block, bool fUseWTXID);

uint64_t GetShortID(const uint256& txhash) const;

Expand Down
4 changes: 3 additions & 1 deletion src/chain.h
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,9 @@ enum BlockStatus: uint32_t {
BLOCK_FAILED_CHILD = 64, //!< descends from failed block
BLOCK_FAILED_MASK = BLOCK_FAILED_VALID | BLOCK_FAILED_CHILD,

BLOCK_CONFLICT_CHAINLOCK = 128, //!< conflicts with chainlock system
BLOCK_OPT_WITNESS = 128, //!< block data in blk*.data was received with a witness-enforcing client

BLOCK_CONFLICT_CHAINLOCK = 256, //!< conflicts with chainlock system
};

/** The block chain is a tree shaped structure starting with the
Expand Down
61 changes: 16 additions & 45 deletions src/chainparams.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -343,19 +343,11 @@ class CMainParams : public CChainParams {
consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nStartTime = 1486252800; // Feb 5th, 2017
consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nTimeout = 1517788800; // Feb 5th, 2018

// Deployment of DIP0001
consensus.vDeployments[Consensus::DEPLOYMENT_DIP0001].bit = 1;
consensus.vDeployments[Consensus::DEPLOYMENT_DIP0001].nStartTime = 1508025600; // Oct 15th, 2017
consensus.vDeployments[Consensus::DEPLOYMENT_DIP0001].nTimeout = 1539561600; // Oct 15th, 2018
consensus.vDeployments[Consensus::DEPLOYMENT_DIP0001].nWindowSize = 4032;
consensus.vDeployments[Consensus::DEPLOYMENT_DIP0001].nThresholdStart = 3226; // 80% of 4032

// Deployment of BIP147
consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].bit = 2;
consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].nStartTime = 1524477600; // Apr 23th, 2018
consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].nTimeout = 1556013600; // Apr 23th, 2019
consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].nWindowSize = 4032;
consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].nThresholdStart = 3226; // 80% of 4032
// Deployment of SegWit (BIP141, BIP143, and BIP147)
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].bit = 1;
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nStartTime = Consensus::BIP9Deployment::ALWAYS_ACTIVE;
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;


// The best chain should have at least this much work.
consensus.nMinimumChainWork = uint256S("0x00");
Expand Down Expand Up @@ -513,19 +505,10 @@ class CTestNetParams : public CChainParams {
consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nStartTime = 1544655600; // Dec 13th, 2018
consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nTimeout = 1576191600; // Dec 13th, 2019

// Deployment of DIP0001
consensus.vDeployments[Consensus::DEPLOYMENT_DIP0001].bit = 1;
consensus.vDeployments[Consensus::DEPLOYMENT_DIP0001].nStartTime = 1544655600; // Dec 13th, 2018
consensus.vDeployments[Consensus::DEPLOYMENT_DIP0001].nTimeout = 1576191600; // Dec 13th, 2019
consensus.vDeployments[Consensus::DEPLOYMENT_DIP0001].nWindowSize = 100;
consensus.vDeployments[Consensus::DEPLOYMENT_DIP0001].nThresholdStart = 50; // 50% of 100

// Deployment of BIP147
consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].bit = 2;
consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].nStartTime = 1544655600; // Dec 13th, 2018
consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].nTimeout = 1576191600; // Dec 13th, 2019
consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].nWindowSize = 100;
consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].nThresholdStart = 50; // 50% of 100
// Deployment of SegWit (BIP141, BIP143, and BIP147)
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].bit = 1;
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nStartTime = 1462060800; // May 1st 2016
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nTimeout = 1493596800; // May 1st 2017

// The best chain should have at least this much work.
consensus.nMinimumChainWork = uint256S("0x000000000000000000000000000000000000000000000000022f13324cfe06a3"); // 395750
Expand Down Expand Up @@ -654,19 +637,10 @@ class CDevNetParams : public CChainParams {
consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nStartTime = 1506556800; // September 28th, 2017
consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nTimeout = 1538092800; // September 28th, 2018

// Deployment of DIP0001
consensus.vDeployments[Consensus::DEPLOYMENT_DIP0001].bit = 1;
consensus.vDeployments[Consensus::DEPLOYMENT_DIP0001].nStartTime = 1505692800; // Sep 18th, 2017
consensus.vDeployments[Consensus::DEPLOYMENT_DIP0001].nTimeout = 1537228800; // Sep 18th, 2018
consensus.vDeployments[Consensus::DEPLOYMENT_DIP0001].nWindowSize = 100;
consensus.vDeployments[Consensus::DEPLOYMENT_DIP0001].nThresholdStart = 50; // 50% of 100

// Deployment of BIP147
consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].bit = 2;
consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].nStartTime = 1517792400; // Feb 5th, 2018
consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].nTimeout = 1549328400; // Feb 5th, 2019
consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].nWindowSize = 100;
consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].nThresholdStart = 50; // 50% of 100
// Deployment of SegWit (BIP141, BIP143, and BIP147)
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].bit = 1;
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nStartTime = 1462060800; // May 1st 2016
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nTimeout = 1493596800; // May 1st 2017

// The best chain should have at least this much work.
consensus.nMinimumChainWork = uint256S("0x000000000000000000000000000000000000000000000000000000000000000");
Expand Down Expand Up @@ -794,12 +768,9 @@ class CRegTestParams : public CChainParams {
consensus.vDeployments[Consensus::DEPLOYMENT_CSV].bit = 0;
consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nStartTime = 0;
consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nTimeout = 999999999999ULL;
consensus.vDeployments[Consensus::DEPLOYMENT_DIP0001].bit = 1;
consensus.vDeployments[Consensus::DEPLOYMENT_DIP0001].nStartTime = 0;
consensus.vDeployments[Consensus::DEPLOYMENT_DIP0001].nTimeout = 999999999999ULL;
consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].bit = 2;
consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].nStartTime = 0;
consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].nTimeout = 999999999999ULL;
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].bit = 1;
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nStartTime = Consensus::BIP9Deployment::ALWAYS_ACTIVE;
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;

// The best chain should have at least this much work.
consensus.nMinimumChainWork = uint256S("0x00");
Expand Down
3 changes: 2 additions & 1 deletion src/coins.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,8 @@ bool CCoinsViewCache::HaveInputs(const CTransaction& tx) const
return true;
}

static const size_t MAX_OUTPUTS_PER_BLOCK = MaxBlockSize(true) / ::GetSerializeSize(CTxOut(), SER_NETWORK, PROTOCOL_VERSION); // TODO: merge with similar definition in undo.h.
static const size_t MIN_TRANSACTION_OUTPUT_WEIGHT = WITNESS_SCALE_FACTOR * ::GetSerializeSize(CTxOut(), PROTOCOL_VERSION);
static const size_t MAX_OUTPUTS_PER_BLOCK = MAX_BLOCK_WEIGHT / MIN_TRANSACTION_OUTPUT_WEIGHT;

const Coin& AccessByTxid(const CCoinsViewCache& view, const uint256& txid)
{
Expand Down
25 changes: 14 additions & 11 deletions src/consensus/consensus.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,26 @@
#ifndef BITCOIN_CONSENSUS_CONSENSUS_H
#define BITCOIN_CONSENSUS_CONSENSUS_H

/** The maximum allowed size for a serialized block, in bytes (network rule) */
static const unsigned int MAX_LEGACY_BLOCK_SIZE = 1000000;
static const unsigned int MAX_DIP0001_BLOCK_SIZE = 2000000;
inline unsigned int MaxBlockSize(bool fDIP0001Active /*= false */)
{
return fDIP0001Active ? MAX_DIP0001_BLOCK_SIZE : MAX_LEGACY_BLOCK_SIZE;
}
#include <stdlib.h>
#include <stdint.h>

/** The maximum allowed size for a serialized block, in bytes (only for buffer size limits) */
static const unsigned int MAX_BLOCK_SERIALIZED_SIZE = 4000000;
/** The maximum allowed weight for a block, see BIP 141 (network rule) */
static const unsigned int MAX_BLOCK_WEIGHT = 4000000;
/** The maximum allowed number of signature check operations in a block (network rule) */
inline unsigned int MaxBlockSigOps(bool fDIP0001Active /*= false */)
{
return MaxBlockSize(fDIP0001Active) / 50;
}
static const int64_t MAX_BLOCK_SIGOPS_COST = 80000;

/** The maximum allowed size of version 3 extra payload */
static const unsigned int MAX_TX_EXTRA_PAYLOAD = 10000;
/** Coinbase transaction outputs can only be spent after this number of new blocks (network rule) */
static const int COINBASE_MATURITY = 10;

static const int WITNESS_SCALE_FACTOR = 4;

static const size_t MIN_TRANSACTION_WEIGHT = WITNESS_SCALE_FACTOR * 60; // 60 is the lower bound for the size of a valid serialized CTransaction
static const size_t MIN_SERIALIZABLE_TRANSACTION_WEIGHT = WITNESS_SCALE_FACTOR * 10; // 10 is the lower bound for the size of a serialized CTransaction

/** Flags for nSequence and nLockTime locks */
/** Interpret sequence numbers as relative lock-time constraints. */
static constexpr unsigned int LOCKTIME_VERIFY_SEQUENCE = (1 << 0);
Expand Down
10 changes: 10 additions & 0 deletions src/consensus/merkle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,13 @@ uint256 BlockMerkleRoot(const CBlock& block, bool* mutated)
return ComputeMerkleRoot(std::move(leaves), mutated);
}

uint256 BlockWitnessMerkleRoot(const CBlock& block, bool* mutated)
{
std::vector<uint256> leaves;
leaves.resize(block.vtx.size());
leaves[0].SetNull(); // The witness hash of the coinbase is 0.
for (size_t s = 1; s < block.vtx.size(); s++) {
leaves[s] = block.vtx[s]->GetWitnessHash();
}
return ComputeMerkleRoot(leaves, mutated);
}
6 changes: 6 additions & 0 deletions src/consensus/merkle.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,10 @@ uint256 ComputeMerkleRoot(std::vector<uint256> hashes, bool* mutated = nullptr);
*/
uint256 BlockMerkleRoot(const CBlock& block, bool* mutated = nullptr);

/*
* Compute the Merkle root of the witness transactions in a block.
* *mutated is set to true if a duplicated subtree was found.
*/
uint256 BlockWitnessMerkleRoot(const CBlock& block, bool* mutated = nullptr);

#endif
14 changes: 12 additions & 2 deletions src/consensus/params.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
#ifndef BITCOIN_CONSENSUS_PARAMS_H
#define BITCOIN_CONSENSUS_PARAMS_H

#include <stdexcept>
#include <limits>
#include <uint256.h>
#include <amount.h>
#include <map>
Expand All @@ -17,8 +19,7 @@ enum DeploymentPos
{
DEPLOYMENT_TESTDUMMY,
DEPLOYMENT_CSV, // Deployment of BIP68, BIP112, and BIP113.
DEPLOYMENT_DIP0001, // Deployment of DIP0001 and lower transaction fees.
DEPLOYMENT_BIP147, // Deployment of BIP147 (NULLDUMMY)
DEPLOYMENT_SEGWIT, // Deployment of BIP141, BIP143, and BIP147.
// NOTE: Also add new deployments to VersionBitsDeploymentInfo in versionbits.cpp
MAX_VERSION_BITS_DEPLOYMENTS
};
Expand All @@ -41,6 +42,15 @@ struct BIP9Deployment {
int64_t nThresholdMin{0};
/** A coefficient which adjusts the speed a required number of signaling blocks is decreasing from nThresholdStart to nThresholdMin at with each period. */
int64_t nFalloffCoeff{0};

/** Constant for nTimeout very far in the future. */
static constexpr int64_t NO_TIMEOUT = std::numeric_limits<int64_t>::max();

/** Special value for nStartTime indicating that the deployment is always active.
* This is useful for testing, as it means tests don't need to deal with the activation
* process (which takes at least 3 BIP9 intervals). Only tests that specifically test the
* behaviour during activation cannot use this. */
static constexpr int64_t ALWAYS_ACTIVE = -1;
};

enum LLMQType : uint8_t
Expand Down
17 changes: 12 additions & 5 deletions src/consensus/tx_verify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,17 +135,24 @@ unsigned int GetP2SHSigOpCount(const CTransaction& tx, const CCoinsViewCache& in
return nSigOps;
}

unsigned int GetTransactionSigOpCount(const CTransaction& tx, const CCoinsViewCache& inputs, int flags)
int64_t GetTransactionSigOpCost(const CTransaction& tx, const CCoinsViewCache& inputs, int flags)
{
unsigned int nSigOps = GetLegacySigOpCount(tx);
int64_t nSigOps = GetLegacySigOpCount(tx) * WITNESS_SCALE_FACTOR;

if (tx.IsCoinBase())
return nSigOps;

if (flags & SCRIPT_VERIFY_P2SH) {
nSigOps += GetP2SHSigOpCount(tx, inputs);
nSigOps += GetP2SHSigOpCount(tx, inputs) * WITNESS_SCALE_FACTOR;
}

for (unsigned int i = 0; i < tx.vin.size(); i++)
{
const Coin& coin = inputs.AccessCoin(tx.vin[i].prevout);
assert(!coin.IsSpent());
const CTxOut &prevout = coin.out;
nSigOps += CountWitnessSigOps(tx.vin[i].scriptSig, prevout.scriptPubKey, &tx.vin[i].scriptWitness, flags);
}
return nSigOps;
}

Expand All @@ -161,8 +168,8 @@ bool CheckTransaction(const CTransaction& tx, CValidationState &state)
return state.DoS(10, false, REJECT_INVALID, "bad-txns-vin-empty");
if (!allowEmptyTxInOut && tx.vout.empty())
return state.DoS(10, false, REJECT_INVALID, "bad-txns-vout-empty");
// Size limits
if (::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION) > MAX_LEGACY_BLOCK_SIZE)
// Size limits (this doesn't take the witness into account, as that hasn't been checked for malleability)
if (::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * WITNESS_SCALE_FACTOR > MAX_BLOCK_WEIGHT)
return state.DoS(100, false, REJECT_INVALID, "bad-txns-oversize");
if (tx.vExtraPayload.size() > MAX_TX_EXTRA_PAYLOAD)
return state.DoS(100, false, REJECT_INVALID, "bad-txns-payload-oversize");
Expand Down
8 changes: 4 additions & 4 deletions src/consensus/tx_verify.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,13 @@ unsigned int GetLegacySigOpCount(const CTransaction& tx);
unsigned int GetP2SHSigOpCount(const CTransaction& tx, const CCoinsViewCache& mapInputs);

/**
* Count total signature operations for a transaction.
* @param[in] tx Transaction for which we are counting sigops
* Compute total signature operation cost of a transaction.
* @param[in] tx Transaction for which we are computing the cost
* @param[in] inputs Map of previous transactions that have outputs we're spending
* @param[out] flags Script verification flags
* @return Total signature operation count for a tx
* @return Total signature operation cost of tx
*/
unsigned int GetTransactionSigOpCount(const CTransaction& tx, const CCoinsViewCache& inputs, int flags);
int64_t GetTransactionSigOpCost(const CTransaction& tx, const CCoinsViewCache& inputs, int flags);

/**
* Check if transaction is final and can be included in a block with the
Expand Down
20 changes: 20 additions & 0 deletions src/consensus/validation.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
#define BITCOIN_CONSENSUS_VALIDATION_H

#include <string>
#include <version.h>
#include <consensus/consensus.h>
#include <primitives/transaction.h>
#include <primitives/block.h>

/** "reject" message codes */
static const unsigned char REJECT_MALFORMED = 0x01;
Expand Down Expand Up @@ -77,9 +81,25 @@ class CValidationState {
bool CorruptionPossible() const {
return corruptionPossible;
}
void SetCorruptionPossible() {
corruptionPossible = true;
}
unsigned int GetRejectCode() const { return chRejectCode; }
std::string GetRejectReason() const { return strRejectReason; }
std::string GetDebugMessage() const { return strDebugMessage; }
};

// These implement the weight = (stripped_size * 4) + witness_size formula,
// using only serialization with and without witness data. As witness_size
// is equal to total_size - stripped_size, this formula is identical to:
// weight = (stripped_size * 3) + total_size.
static inline int64_t GetTransactionWeight(const CTransaction& tx)
{
return ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * (WITNESS_SCALE_FACTOR - 1) + ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION);
}
static inline int64_t GetBlockWeight(const CBlock& block)
{
return ::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * (WITNESS_SCALE_FACTOR - 1) + ::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION);
}

#endif // BITCOIN_CONSENSUS_VALIDATION_H
2 changes: 1 addition & 1 deletion src/core_io.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ struct CSpentIndexTxInfo;
// core_read.cpp
CScript ParseScript(const std::string& s);
std::string ScriptToAsmStr(const CScript& script, const bool fAttemptSighashDecode = false);
bool DecodeHexTx(CMutableTransaction& tx, const std::string& strHexTx);
bool DecodeHexTx(CMutableTransaction& tx, const std::string& hex_tx, bool try_no_witness = false, bool try_witness = true);
bool DecodeHexBlk(CBlock&, const std::string& strHexBlk);
uint256 ParseHashUV(const UniValue& v, const std::string& strName);
uint256 ParseHashStr(const std::string&, const std::string& strName);
Expand Down
6 changes: 5 additions & 1 deletion src/core_memusage.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@ static inline size_t RecursiveDynamicUsage(const COutPoint& out) {
}

static inline size_t RecursiveDynamicUsage(const CTxIn& in) {
return RecursiveDynamicUsage(in.scriptSig) + RecursiveDynamicUsage(in.prevout);
size_t mem = RecursiveDynamicUsage(in.scriptSig) + RecursiveDynamicUsage(in.prevout) + memusage::DynamicUsage(in.scriptWitness.stack);
for (std::vector<std::vector<unsigned char> >::const_iterator it = in.scriptWitness.stack.begin(); it != in.scriptWitness.stack.end(); it++) {
mem += memusage::DynamicUsage(*it);
}
return mem;
}

static inline size_t RecursiveDynamicUsage(const CTxOut& out) {
Expand Down
Loading

0 comments on commit 8575e22

Please sign in to comment.