Skip to content

Commit 931b6e9

Browse files
committed
Add Elements-style witness serialization
1 parent 9823039 commit 931b6e9

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+872
-416
lines changed

src/bench/block_assemble.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ static void AssembleBlock(benchmark::State& state)
9393
for (size_t b{0}; b < NUM_BLOCKS; ++b) {
9494
CMutableTransaction tx;
9595
tx.vin.push_back(MineBlock(SCRIPT_PUB));
96-
tx.vin.back().scriptWitness = witness;
96+
tx.witness.vtxinwit.back().scriptWitness = witness;
9797
tx.vout.emplace_back(1337, SCRIPT_PUB);
9898
if (NUM_BLOCKS - b >= COINBASE_MATURITY)
9999
txs.at(b) = MakeTransactionRef(tx);

src/bench/mempool_eviction.cpp

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#include <list>
1010
#include <vector>
11+
#include <primitives/transaction.h>
1112

1213
static void AddTx(const CTransactionRef& tx, const CAmount& nFee, CTxMemPool& pool) EXCLUSIVE_LOCKS_REQUIRED(pool.cs)
1314
{
@@ -31,15 +32,17 @@ static void MempoolEviction(benchmark::State& state)
3132
CMutableTransaction tx1 = CMutableTransaction();
3233
tx1.vin.resize(1);
3334
tx1.vin[0].scriptSig = CScript() << OP_1;
34-
tx1.vin[0].scriptWitness.stack.push_back({1});
35+
tx1.witness.vtxinwit.resize(1);
36+
tx1.witness.vtxinwit[0].scriptWitness.stack.push_back({1});
3537
tx1.vout.resize(1);
3638
tx1.vout[0].scriptPubKey = CScript() << OP_1 << OP_EQUAL;
3739
tx1.vout[0].nValue = 10 * COIN;
3840

3941
CMutableTransaction tx2 = CMutableTransaction();
4042
tx2.vin.resize(1);
4143
tx2.vin[0].scriptSig = CScript() << OP_2;
42-
tx2.vin[0].scriptWitness.stack.push_back({2});
44+
tx1.witness.vtxinwit.resize(1);
45+
tx2.witness.vtxinwit[0].scriptWitness.stack.push_back({2});
4346
tx2.vout.resize(1);
4447
tx2.vout[0].scriptPubKey = CScript() << OP_2 << OP_EQUAL;
4548
tx2.vout[0].nValue = 10 * COIN;
@@ -48,7 +51,8 @@ static void MempoolEviction(benchmark::State& state)
4851
tx3.vin.resize(1);
4952
tx3.vin[0].prevout = COutPoint(tx2.GetHash(), 0);
5053
tx3.vin[0].scriptSig = CScript() << OP_2;
51-
tx3.vin[0].scriptWitness.stack.push_back({3});
54+
tx1.witness.vtxinwit.resize(1);
55+
tx3.witness.vtxinwit[0].scriptWitness.stack.push_back({3});
5256
tx3.vout.resize(1);
5357
tx3.vout[0].scriptPubKey = CScript() << OP_3 << OP_EQUAL;
5458
tx3.vout[0].nValue = 10 * COIN;
@@ -57,10 +61,12 @@ static void MempoolEviction(benchmark::State& state)
5761
tx4.vin.resize(2);
5862
tx4.vin[0].prevout.SetNull();
5963
tx4.vin[0].scriptSig = CScript() << OP_4;
60-
tx4.vin[0].scriptWitness.stack.push_back({4});
64+
tx1.witness.vtxinwit.resize(1);
65+
tx4.witness.vtxinwit[0].scriptWitness.stack.push_back({4});
6166
tx4.vin[1].prevout.SetNull();
6267
tx4.vin[1].scriptSig = CScript() << OP_4;
63-
tx4.vin[1].scriptWitness.stack.push_back({4});
68+
tx1.witness.vtxinwit.resize(2);
69+
tx4.witness.vtxinwit[1].scriptWitness.stack.push_back({4});
6470
tx4.vout.resize(2);
6571
tx4.vout[0].scriptPubKey = CScript() << OP_4 << OP_EQUAL;
6672
tx4.vout[0].nValue = 10 * COIN;
@@ -71,10 +77,12 @@ static void MempoolEviction(benchmark::State& state)
7177
tx5.vin.resize(2);
7278
tx5.vin[0].prevout = COutPoint(tx4.GetHash(), 0);
7379
tx5.vin[0].scriptSig = CScript() << OP_4;
74-
tx5.vin[0].scriptWitness.stack.push_back({4});
80+
tx1.witness.vtxinwit.resize(1);
81+
tx5.witness.vtxinwit[0].scriptWitness.stack.push_back({4});
7582
tx5.vin[1].prevout.SetNull();
7683
tx5.vin[1].scriptSig = CScript() << OP_5;
77-
tx5.vin[1].scriptWitness.stack.push_back({5});
84+
tx1.witness.vtxinwit.resize(2);
85+
tx5.witness.vtxinwit[1].scriptWitness.stack.push_back({5});
7886
tx5.vout.resize(2);
7987
tx5.vout[0].scriptPubKey = CScript() << OP_5 << OP_EQUAL;
8088
tx5.vout[0].nValue = 10 * COIN;
@@ -85,10 +93,12 @@ static void MempoolEviction(benchmark::State& state)
8593
tx6.vin.resize(2);
8694
tx6.vin[0].prevout = COutPoint(tx4.GetHash(), 1);
8795
tx6.vin[0].scriptSig = CScript() << OP_4;
88-
tx6.vin[0].scriptWitness.stack.push_back({4});
96+
tx1.witness.vtxinwit.resize(1);
97+
tx6.witness.vtxinwit[0].scriptWitness.stack.push_back({4});
8998
tx6.vin[1].prevout.SetNull();
9099
tx6.vin[1].scriptSig = CScript() << OP_6;
91-
tx6.vin[1].scriptWitness.stack.push_back({6});
100+
tx1.witness.vtxinwit.resize(2);
101+
tx6.witness.vtxinwit[1].scriptWitness.stack.push_back({6});
92102
tx6.vout.resize(2);
93103
tx6.vout[0].scriptPubKey = CScript() << OP_6 << OP_EQUAL;
94104
tx6.vout[0].nValue = 10 * COIN;
@@ -99,10 +109,12 @@ static void MempoolEviction(benchmark::State& state)
99109
tx7.vin.resize(2);
100110
tx7.vin[0].prevout = COutPoint(tx5.GetHash(), 0);
101111
tx7.vin[0].scriptSig = CScript() << OP_5;
102-
tx7.vin[0].scriptWitness.stack.push_back({5});
112+
tx1.witness.vtxinwit.resize(1);
113+
tx7.witness.vtxinwit[0].scriptWitness.stack.push_back({5});
103114
tx7.vin[1].prevout = COutPoint(tx6.GetHash(), 0);
104115
tx7.vin[1].scriptSig = CScript() << OP_6;
105-
tx7.vin[1].scriptWitness.stack.push_back({6});
116+
tx1.witness.vtxinwit.resize(2);
117+
tx7.witness.vtxinwit[1].scriptWitness.stack.push_back({6});
106118
tx7.vout.resize(2);
107119
tx7.vout[0].scriptPubKey = CScript() << OP_7 << OP_EQUAL;
108120
tx7.vout[0].nValue = 10 * COIN;

src/bench/verify_script.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,8 @@ static void VerifyScriptBench(benchmark::State& state)
7474
CScript witScriptPubkey = CScript() << OP_DUP << OP_HASH160 << ToByteVector(pubkeyHash) << OP_EQUALVERIFY << OP_CHECKSIG;
7575
const CMutableTransaction& txCredit = BuildCreditingTransaction(scriptPubKey);
7676
CMutableTransaction txSpend = BuildSpendingTransaction(scriptSig, txCredit);
77-
CScriptWitness& witness = txSpend.vin[0].scriptWitness;
77+
txSpend.witness.vtxinwit.resize(1);
78+
CScriptWitness& witness = txSpend.witness.vtxinwit[0].scriptWitness;
7879
witness.stack.emplace_back();
7980
key.Sign(SignatureHash(witScriptPubkey, txSpend, 0, SIGHASH_ALL, txCredit.vout[0].nValue, SigVersion::WITNESS_V0), witness.stack.back());
8081
witness.stack.back().push_back(static_cast<unsigned char>(SIGHASH_ALL));
@@ -86,7 +87,7 @@ static void VerifyScriptBench(benchmark::State& state)
8687
bool success = VerifyScript(
8788
txSpend.vin[0].scriptSig,
8889
txCredit.vout[0].scriptPubKey,
89-
&txSpend.vin[0].scriptWitness,
90+
&txSpend.witness.vtxinwit[0].scriptWitness,
9091
flags,
9192
MutableTransactionSignatureChecker(&txSpend, 0, txCredit.vout[0].nValue),
9293
&err);

src/bitcoin-tx.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -647,7 +647,7 @@ static void MutateTxSign(CMutableTransaction& tx, const std::string& flagStr)
647647
if (!fHashSingle || (i < mergedTx.vout.size()))
648648
ProduceSignature(keystore, MutableTransactionSignatureCreator(&mergedTx, i, amount, nHashType), prevPubKey, sigdata);
649649

650-
UpdateInput(txin, sigdata);
650+
UpdateTransaction(mergedTx, i, sigdata);
651651
}
652652

653653
tx = mergedTx;

src/consensus/merkle.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,11 @@ uint256 BlockWitnessMerkleRoot(const CBlock& block, bool* mutated)
7979
leaves.resize(block.vtx.size());
8080
leaves[0].SetNull(); // The witness hash of the coinbase is 0.
8181
for (size_t s = 1; s < block.vtx.size(); s++) {
82-
leaves[s] = block.vtx[s]->GetWitnessHash();
82+
if (g_con_elementswitness) {
83+
leaves[s] = block.vtx[s]->GetWitnessOnlyHash();
84+
} else {
85+
leaves[s] = block.vtx[s]->GetWitnessHash();
86+
}
8387
}
8488
return ComputeMerkleRoot(std::move(leaves), mutated);
8589
}
86-

src/consensus/tx_verify.cpp

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -159,19 +159,20 @@ int64_t GetTransactionSigOpCost(const CTransaction& tx, const CCoinsViewCache& i
159159

160160
for (unsigned int i = 0; i < tx.vin.size(); i++)
161161
{
162-
if (tx.vin[i].m_is_pegin && !IsValidPeginWitness(tx.vin[i].m_pegin_witness, tx.vin[i].prevout)) {
163-
continue;
164-
}
165-
166162
CTxOut prevout;
167163
if (tx.vin[i].m_is_pegin) {
168-
prevout = GetPeginOutputFromWitness(tx.vin[i].m_pegin_witness);
164+
if (tx.witness.vtxinwit.size() <= i || !IsValidPeginWitness(tx.witness.vtxinwit[i].m_pegin_witness, tx.vin[i].prevout)) {
165+
continue;
166+
}
167+
prevout = GetPeginOutputFromWitness(tx.witness.vtxinwit[i].m_pegin_witness);
169168
} else {
170169
const Coin& coin = inputs.AccessCoin(tx.vin[i].prevout);
171170
assert(!coin.IsSpent());
172171
prevout = coin.out;
173172
}
174-
nSigOps += CountWitnessSigOps(tx.vin[i].scriptSig, prevout.scriptPubKey, &tx.vin[i].scriptWitness, flags);
173+
174+
const CScriptWitness* pScriptWitness = tx.witness.vtxinwit.size() > i ? &tx.witness.vtxinwit[i].scriptWitness : NULL;
175+
nSigOps += CountWitnessSigOps(tx.vin[i].scriptSig, prevout.scriptPubKey, pScriptWitness, flags);
175176
}
176177
return nSigOps;
177178
}
@@ -239,10 +240,10 @@ bool CheckTxInputs(const CTransaction& tx, CValidationState& state, const CCoins
239240
const COutPoint &prevout = tx.vin[i].prevout;
240241
if (tx.vin[i].m_is_pegin) {
241242
// Check existence and validity of pegin witness
242-
if (!IsValidPeginWitness(tx.vin[i].m_pegin_witness, prevout)) {
243+
if (tx.witness.vtxinwit.size() <= i || !IsValidPeginWitness(tx.witness.vtxinwit[i].m_pegin_witness, prevout)) {
243244
return state.DoS(0, false, REJECT_PEGIN, "bad-pegin-witness");
244245
}
245-
std::pair<uint256, COutPoint> pegin = std::make_pair(uint256(tx.vin[i].m_pegin_witness.stack[2]), prevout);
246+
std::pair<uint256, COutPoint> pegin = std::make_pair(uint256(tx.witness.vtxinwit[i].m_pegin_witness.stack[2]), prevout);
246247
if (inputs.IsPeginSpent(pegin)) {
247248
return state.Invalid(false, REJECT_INVALID, "bad-txns-double-pegin", strprintf("Double-pegin of %s:%d", prevout.hash.ToString(), prevout.n));
248249
}
@@ -253,7 +254,7 @@ bool CheckTxInputs(const CTransaction& tx, CValidationState& state, const CCoins
253254
setPeginsSpent.insert(pegin);
254255

255256
// Tally the input amount.
256-
const CTxOut out = GetPeginOutputFromWitness(tx.vin[i].m_pegin_witness);
257+
const CTxOut out = GetPeginOutputFromWitness(tx.witness.vtxinwit[i].m_pegin_witness);
257258
if (!MoneyRange(out.nValue)) {
258259
return state.DoS(100, false, REJECT_INVALID, "bad-txns-pegin-inputvalue-outofrange");
259260
}

src/consensus/validation.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,10 +103,16 @@ static inline int64_t GetBlockWeight(const CBlock& block)
103103
{
104104
return ::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * (WITNESS_SCALE_FACTOR - 1) + ::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION);
105105
}
106-
static inline int64_t GetTransactionInputWeight(const CTxIn& txin)
106+
107+
static inline int64_t GetTransactionInputWeight(const CTransaction& tx, const size_t nIn)
107108
{
108109
// scriptWitness size is added here because witnesses and txins are split up in segwit serialization.
109-
return ::GetSerializeSize(txin, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * (WITNESS_SCALE_FACTOR - 1) + ::GetSerializeSize(txin, SER_NETWORK, PROTOCOL_VERSION) + ::GetSerializeSize(txin.scriptWitness.stack, SER_NETWORK, PROTOCOL_VERSION);
110+
assert(tx.witness.vtxinwit.size() > nIn);
111+
//TODO(rebase) only cound CA/CT witnesses when g_con_elementswitness is true
112+
return ::GetSerializeSize(tx.vin[nIn], SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * (WITNESS_SCALE_FACTOR - 1)
113+
+ ::GetSerializeSize(tx.vin[nIn], SER_NETWORK, PROTOCOL_VERSION)
114+
+ ::GetSerializeSize(tx.witness.vtxinwit[nIn].scriptWitness.stack, SER_NETWORK, PROTOCOL_VERSION)
115+
+ ::GetSerializeSize(tx.witness.vtxinwit[nIn].m_pegin_witness.stack, SER_NETWORK, PROTOCOL_VERSION);
110116
}
111117

112118
#endif // BITCOIN_CONSENSUS_VALIDATION_H

src/core_memusage.h

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,37 @@ static inline size_t RecursiveDynamicUsage(const COutPoint& out) {
1818
}
1919

2020
static inline size_t RecursiveDynamicUsage(const CTxIn& in) {
21-
size_t mem = RecursiveDynamicUsage(in.scriptSig) + RecursiveDynamicUsage(in.prevout) + memusage::DynamicUsage(in.scriptWitness.stack);
22-
for (std::vector<std::vector<unsigned char> >::const_iterator it = in.scriptWitness.stack.begin(); it != in.scriptWitness.stack.end(); it++) {
23-
mem += memusage::DynamicUsage(*it);
21+
size_t mem = RecursiveDynamicUsage(in.scriptSig) + RecursiveDynamicUsage(in.prevout);
22+
return mem;
23+
}
24+
25+
static inline size_t RecursiveDynamicUsage(const CScriptWitness& scriptWit) {
26+
size_t mem = memusage::DynamicUsage(scriptWit.stack);
27+
for (std::vector<std::vector<unsigned char> >::const_iterator it = scriptWit.stack.begin(); it != scriptWit.stack.end(); it++) {
28+
mem += memusage::DynamicUsage(*it);
29+
}
30+
return mem;
31+
}
32+
33+
static inline size_t RecursiveDynamicUsage(const CTxInWitness& txInWit) {
34+
size_t mem = RecursiveDynamicUsage(txInWit.scriptWitness);
35+
mem += RecursiveDynamicUsage(txInWit.m_pegin_witness);
36+
return mem;
37+
}
38+
39+
static inline size_t RecursiveDynamicUsage(const CTxOutWitness& txOutWit) {
40+
size_t mem = memusage::DynamicUsage(txOutWit.vchRangeproof);
41+
mem += memusage::DynamicUsage(txOutWit.vchSurjectionproof);
42+
return mem;
43+
}
44+
45+
static inline size_t RecursiveDynamicUsage(const CTxWitness& wit) {
46+
size_t mem = memusage::DynamicUsage(wit.vtxinwit) + memusage::DynamicUsage(wit.vtxoutwit);
47+
for (const auto& txInWit: wit.vtxinwit) {
48+
mem += RecursiveDynamicUsage(txInWit);
49+
}
50+
for (const auto& txOutWit: wit.vtxoutwit) {
51+
mem += RecursiveDynamicUsage(txOutWit);
2452
}
2553
return mem;
2654
}

src/core_write.cpp

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,10 @@ void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry,
201201
{
202202
entry.pushKV("txid", tx.GetHash().GetHex());
203203
entry.pushKV("hash", tx.GetWitnessHash().GetHex());
204+
if (g_con_elementswitness) {
205+
entry.pushKV("wtxid", tx.GetWitnessHash().GetHex());
206+
entry.pushKV("withash", tx.GetWitnessOnlyHash().GetHex());
207+
}
204208
entry.pushKV("version", tx.nVersion);
205209
entry.pushKV("size", (int)::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION));
206210
entry.pushKV("vsize", (GetTransactionWeight(tx) + WITNESS_SCALE_FACTOR - 1) / WITNESS_SCALE_FACTOR);
@@ -221,19 +225,22 @@ void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry,
221225
o.pushKV("hex", HexStr(txin.scriptSig.begin(), txin.scriptSig.end()));
222226
in.pushKV("scriptSig", o);
223227

224-
if (!tx.vin[i].scriptWitness.IsNull()) {
225-
UniValue txinwitness(UniValue::VARR);
226-
for (const auto& item : tx.vin[i].scriptWitness.stack) {
227-
txinwitness.push_back(HexStr(item.begin(), item.end()));
228+
if (tx.witness.vtxinwit.size() > i) {
229+
const CScriptWitness &scriptWitness = tx.witness.vtxinwit[i].scriptWitness;
230+
if (!scriptWitness.IsNull()) {
231+
UniValue txinwitness(UniValue::VARR);
232+
for (const auto &item : scriptWitness.stack) {
233+
txinwitness.push_back(HexStr(item.begin(), item.end()));
234+
}
235+
in.pushKV("txinwitness", txinwitness);
228236
}
229-
in.pushKV("txinwitness", txinwitness);
230237
}
231238

232239
// ELEMENTS:
233240
in.pushKV("is_pegin", txin.m_is_pegin);
234-
if (!tx.vin[i].m_pegin_witness.IsNull()) {
241+
if (tx.witness.vtxinwit.size() > i && !tx.witness.vtxinwit[i].m_pegin_witness.IsNull()) {
235242
UniValue pegin_witness(UniValue::VARR);
236-
for (const auto& item : tx.vin[i].m_pegin_witness.stack) {
243+
for (const auto& item : tx.witness.vtxinwit[i].m_pegin_witness.stack) {
237244
pegin_witness.push_back(HexStr(item.begin(), item.end()));
238245
}
239246
in.pushKV("pegin_witness", pegin_witness);

src/policy/policy.cpp

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -221,10 +221,11 @@ bool IsWitnessStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs)
221221
{
222222
// We don't care if witness for this input is empty, since it must not be bloated.
223223
// If the script is invalid without witness, it would be caught sooner or later during validation.
224-
if (tx.vin[i].scriptWitness.IsNull())
224+
if (tx.witness.vtxinwit.size() <= i || tx.witness.vtxinwit[i].scriptWitness.IsNull()) {
225225
continue;
226+
}
226227

227-
const CTxOut &prev = tx.vin[i].m_is_pegin ? GetPeginOutputFromWitness(tx.vin[i].m_pegin_witness) : mapInputs.AccessCoin(tx.vin[i].prevout).out;
228+
const CTxOut &prev = tx.vin[i].m_is_pegin ? GetPeginOutputFromWitness(tx.witness.vtxinwit[i].m_pegin_witness) : mapInputs.AccessCoin(tx.vin[i].prevout).out;
228229

229230
// get the scriptPubKey corresponding to this input:
230231
CScript prevScript = prev.scriptPubKey;
@@ -250,13 +251,14 @@ bool IsWitnessStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs)
250251

251252
// Check P2WSH standard limits
252253
if (witnessversion == 0 && witnessprogram.size() == WITNESS_V0_SCRIPTHASH_SIZE) {
253-
if (tx.vin[i].scriptWitness.stack.back().size() > MAX_STANDARD_P2WSH_SCRIPT_SIZE)
254+
const CScriptWitness& scriptWitness = tx.witness.vtxinwit[i].scriptWitness;
255+
if (scriptWitness.stack.back().size() > MAX_STANDARD_P2WSH_SCRIPT_SIZE)
254256
return false;
255-
size_t sizeWitnessStack = tx.vin[i].scriptWitness.stack.size() - 1;
257+
size_t sizeWitnessStack = scriptWitness.stack.size() - 1;
256258
if (sizeWitnessStack > MAX_STANDARD_P2WSH_STACK_ITEMS)
257259
return false;
258260
for (unsigned int j = 0; j < sizeWitnessStack; j++) {
259-
if (tx.vin[i].scriptWitness.stack[j].size() > MAX_STANDARD_P2WSH_STACK_ITEM_SIZE)
261+
if (scriptWitness.stack[j].size() > MAX_STANDARD_P2WSH_STACK_ITEM_SIZE)
260262
return false;
261263
}
262264
}
@@ -278,7 +280,7 @@ int64_t GetVirtualTransactionSize(const CTransaction& tx, int64_t nSigOpCost)
278280
return GetVirtualTransactionSize(GetTransactionWeight(tx), nSigOpCost);
279281
}
280282

281-
int64_t GetVirtualTransactionInputSize(const CTxIn& txin, int64_t nSigOpCost)
283+
int64_t GetVirtualTransactionInputSize(const CTransaction& tx, const size_t nIn, int64_t nSigOpCost)
282284
{
283-
return GetVirtualTransactionSize(GetTransactionInputWeight(txin), nSigOpCost);
285+
return GetVirtualTransactionSize(GetTransactionInputWeight(tx, nIn), nSigOpCost);
284286
}

src/policy/policy.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,6 @@ extern unsigned int nBytesPerSigOp;
105105
/** Compute the virtual transaction size (weight reinterpreted as bytes). */
106106
int64_t GetVirtualTransactionSize(int64_t nWeight, int64_t nSigOpCost);
107107
int64_t GetVirtualTransactionSize(const CTransaction& tx, int64_t nSigOpCost = 0);
108-
int64_t GetVirtualTransactionInputSize(const CTxIn& tx, int64_t nSigOpCost = 0);
108+
int64_t GetVirtualTransactionInputSize(const CTransaction& tx, const size_t nIn, int64_t nSigOpCost = 0);
109109

110110
#endif // BITCOIN_POLICY_POLICY_H

0 commit comments

Comments
 (0)