Skip to content

Commit fd9bdc6

Browse files
committed
Merge #494: [0.17] Add Elements-style witness structure
52c8601 Remove manual byte editing in wallet_tx_clone func test (Gregory Sanders) 0c05901 Add functional test for Elements witness serialization (Steven Roose) fb72ee8 Add Elements-style witness serialization (Steven Roose) 6ed8fd8 Add -con_elementswitness flag and global variable (Steven Roose) 01b03a9 Add calcfastmerkleroot RPC and test-framework support (Steven Roose) 3f902b0 Add ComputeFastMerkleRoot unit test example generated by elements-0.14.1 (Gregory Sanders) 3b72dab Add CalcFastMerkleRoot (Steven Roose) 7f65e76 Add support for SHA-256 midstate access (Steven Roose) 7a01d4f Remove unnecessary include (Steven Roose) Pull request description: Ports the Elements-style transaction witness structure from v0.14.1. Additionally, the Elements-compatible serialization of the witness data is gated behind a new `-con_elementswitness` flag. Fixes #479. Tree-SHA512: 337fb8a1f0bac7a0c7908d86eefe2f63c6e729ca91372938e6c751e3dec9e4097333f243bec891bd7e63c6e26a5ee0fca55e9ac82190b641db65014da825bfcc
2 parents e51ed82 + 52c8601 commit fd9bdc6

Some content is hidden

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

62 files changed

+1211
-417
lines changed

src/Makefile.am

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,8 @@ libbitcoin_consensus_a_SOURCES = \
367367
prevector.h \
368368
primitives/block.cpp \
369369
primitives/block.h \
370+
primitives/txwitness.cpp \
371+
primitives/txwitness.h \
370372
primitives/transaction.cpp \
371373
primitives/transaction.h \
372374
primitives/pak.cpp \

src/bench/block_assemble.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,8 @@ 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.resize(1);
97+
tx.witness.vtxinwit.back().scriptWitness = witness;
9798
tx.vout.emplace_back(1337, SCRIPT_PUB);
9899
if (NUM_BLOCKS - b >= COINBASE_MATURITY)
99100
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
{
@@ -30,15 +31,17 @@ static void MempoolEviction(benchmark::State& state)
3031
CMutableTransaction tx1 = CMutableTransaction();
3132
tx1.vin.resize(1);
3233
tx1.vin[0].scriptSig = CScript() << OP_1;
33-
tx1.vin[0].scriptWitness.stack.push_back({1});
34+
tx1.witness.vtxinwit.resize(1);
35+
tx1.witness.vtxinwit[0].scriptWitness.stack.push_back({1});
3436
tx1.vout.resize(1);
3537
tx1.vout[0].scriptPubKey = CScript() << OP_1 << OP_EQUAL;
3638
tx1.vout[0].nValue = 10 * COIN;
3739

3840
CMutableTransaction tx2 = CMutableTransaction();
3941
tx2.vin.resize(1);
4042
tx2.vin[0].scriptSig = CScript() << OP_2;
41-
tx2.vin[0].scriptWitness.stack.push_back({2});
43+
tx2.witness.vtxinwit.resize(1);
44+
tx2.witness.vtxinwit[0].scriptWitness.stack.push_back({2});
4245
tx2.vout.resize(1);
4346
tx2.vout[0].scriptPubKey = CScript() << OP_2 << OP_EQUAL;
4447
tx2.vout[0].nValue = 10 * COIN;
@@ -47,7 +50,8 @@ static void MempoolEviction(benchmark::State& state)
4750
tx3.vin.resize(1);
4851
tx3.vin[0].prevout = COutPoint(tx2.GetHash(), 0);
4952
tx3.vin[0].scriptSig = CScript() << OP_2;
50-
tx3.vin[0].scriptWitness.stack.push_back({3});
53+
tx3.witness.vtxinwit.resize(1);
54+
tx3.witness.vtxinwit[0].scriptWitness.stack.push_back({3});
5155
tx3.vout.resize(1);
5256
tx3.vout[0].scriptPubKey = CScript() << OP_3 << OP_EQUAL;
5357
tx3.vout[0].nValue = 10 * COIN;
@@ -56,10 +60,12 @@ static void MempoolEviction(benchmark::State& state)
5660
tx4.vin.resize(2);
5761
tx4.vin[0].prevout.SetNull();
5862
tx4.vin[0].scriptSig = CScript() << OP_4;
59-
tx4.vin[0].scriptWitness.stack.push_back({4});
63+
tx4.witness.vtxinwit.resize(1);
64+
tx4.witness.vtxinwit[0].scriptWitness.stack.push_back({4});
6065
tx4.vin[1].prevout.SetNull();
6166
tx4.vin[1].scriptSig = CScript() << OP_4;
62-
tx4.vin[1].scriptWitness.stack.push_back({4});
67+
tx4.witness.vtxinwit.resize(2);
68+
tx4.witness.vtxinwit[1].scriptWitness.stack.push_back({4});
6369
tx4.vout.resize(2);
6470
tx4.vout[0].scriptPubKey = CScript() << OP_4 << OP_EQUAL;
6571
tx4.vout[0].nValue = 10 * COIN;
@@ -70,10 +76,12 @@ static void MempoolEviction(benchmark::State& state)
7076
tx5.vin.resize(2);
7177
tx5.vin[0].prevout = COutPoint(tx4.GetHash(), 0);
7278
tx5.vin[0].scriptSig = CScript() << OP_4;
73-
tx5.vin[0].scriptWitness.stack.push_back({4});
79+
tx5.witness.vtxinwit.resize(1);
80+
tx5.witness.vtxinwit[0].scriptWitness.stack.push_back({4});
7481
tx5.vin[1].prevout.SetNull();
7582
tx5.vin[1].scriptSig = CScript() << OP_5;
76-
tx5.vin[1].scriptWitness.stack.push_back({5});
83+
tx5.witness.vtxinwit.resize(2);
84+
tx5.witness.vtxinwit[1].scriptWitness.stack.push_back({5});
7785
tx5.vout.resize(2);
7886
tx5.vout[0].scriptPubKey = CScript() << OP_5 << OP_EQUAL;
7987
tx5.vout[0].nValue = 10 * COIN;
@@ -84,10 +92,12 @@ static void MempoolEviction(benchmark::State& state)
8492
tx6.vin.resize(2);
8593
tx6.vin[0].prevout = COutPoint(tx4.GetHash(), 1);
8694
tx6.vin[0].scriptSig = CScript() << OP_4;
87-
tx6.vin[0].scriptWitness.stack.push_back({4});
95+
tx6.witness.vtxinwit.resize(1);
96+
tx6.witness.vtxinwit[0].scriptWitness.stack.push_back({4});
8897
tx6.vin[1].prevout.SetNull();
8998
tx6.vin[1].scriptSig = CScript() << OP_6;
90-
tx6.vin[1].scriptWitness.stack.push_back({6});
99+
tx6.witness.vtxinwit.resize(2);
100+
tx6.witness.vtxinwit[1].scriptWitness.stack.push_back({6});
91101
tx6.vout.resize(2);
92102
tx6.vout[0].scriptPubKey = CScript() << OP_6 << OP_EQUAL;
93103
tx6.vout[0].nValue = 10 * COIN;
@@ -98,10 +108,12 @@ static void MempoolEviction(benchmark::State& state)
98108
tx7.vin.resize(2);
99109
tx7.vin[0].prevout = COutPoint(tx5.GetHash(), 0);
100110
tx7.vin[0].scriptSig = CScript() << OP_5;
101-
tx7.vin[0].scriptWitness.stack.push_back({5});
111+
tx7.witness.vtxinwit.resize(1);
112+
tx7.witness.vtxinwit[0].scriptWitness.stack.push_back({5});
102113
tx7.vin[1].prevout = COutPoint(tx6.GetHash(), 0);
103114
tx7.vin[1].scriptSig = CScript() << OP_6;
104-
tx7.vin[1].scriptWitness.stack.push_back({6});
115+
tx7.witness.vtxinwit.resize(2);
116+
tx7.witness.vtxinwit[1].scriptWitness.stack.push_back({6});
105117
tx7.vout.resize(2);
106118
tx7.vout[0].scriptPubKey = CScript() << OP_7 << OP_EQUAL;
107119
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
@@ -649,7 +649,7 @@ static void MutateTxSign(CMutableTransaction& tx, const std::string& flagStr)
649649
if (!fHashSingle || (i < mergedTx.vout.size()))
650650
ProduceSignature(keystore, MutableTransactionSignatureCreator(&mergedTx, i, amount, nHashType), prevPubKey, sigdata);
651651

652-
UpdateInput(txin, sigdata);
652+
UpdateTransaction(mergedTx, i, sigdata);
653653
}
654654

655655
tx = mergedTx;

src/chainparams.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
#include <chainparamsseeds.h>
99
#include <consensus/merkle.h>
10+
#include <primitives/transaction.h>
1011
#include <tinyformat.h>
1112
#include <util.h>
1213
#include <utilstrencodings.h>
@@ -523,9 +524,10 @@ class CCustomParams : public CRegTestParams {
523524
consensus.max_block_signature_size = gArgs.GetArg("-con_max_block_sig_size", 74);
524525
g_signed_blocks = gArgs.GetBoolArg("-con_signed_blocks", true);
525526

526-
// Note: This global is needed to avoid circular dependency
527-
// Defaults to true for custom chains.
527+
// Note: These globals are needed to avoid circular dependencies.
528+
// Default to true for custom chains.
528529
g_con_blockheightinheader = args.GetBoolArg("-con_blockheightinheader", true);
530+
g_con_elementswitness = args.GetBoolArg("-con_elementswitness", true);
529531

530532
// No subsidy for custom chains by default
531533
consensus.genesis_subsidy = args.GetArg("-con_blocksubsidy", 0);

src/chainparamsbase.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ void SetupChainParamsBaseOptions()
2626
gArgs.AddArg("-con_mandatorycoinbase", "All non-zero valued coinbase outputs must go to this scriptPubKey, if set.", false, OptionsCategory::ELEMENTS);
2727
gArgs.AddArg("-con_blocksubsidy", "Defines the amount of block subsidy to start with, at genesis block.", false, OptionsCategory::ELEMENTS);
2828
gArgs.AddArg("-con_connect_coinbase", "Connect outputs in genesis block to utxo database.", false, OptionsCategory::ELEMENTS);
29+
gArgs.AddArg("-con_elementswitness", "Use Elements-like instead of Core-like witness encoding. This is required for CA/CT. (default: true)", false, OptionsCategory::ELEMENTS);
2930
gArgs.AddArg("-con_blockheightinheader", "Whether the chain includes the block height directly in the header, for easier validation of block height in low-resource environments. (default: true)", false, OptionsCategory::CHAINPARAMS);
3031
gArgs.AddArg("-con_genesis_style=<style>", "Use genesis style <style> (default: elements). Results in genesis block compatibility with various networks. Allowed values: elements, bitcoin", true, OptionsCategory::ELEMENTS);
3132
gArgs.AddArg("-con_signed_blocks", "Signed blockchain. Uses input of `-signblockscript` to define what signatures are necessary to solve it.", false, OptionsCategory::CHAINPARAMS);

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/merkle.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
#include <stdint.h>
99
#include <vector>
1010

11-
#include <primitives/transaction.h>
1211
#include <primitives/block.h>
1312
#include <uint256.h>
1413

src/consensus/tx_verify.cpp

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

160160
for (unsigned int i = 0; i < tx.vin.size(); i++)
161161
{
162-
std::string err;
163-
if (tx.vin[i].m_is_pegin && !IsValidPeginWitness(tx.vin[i].m_pegin_witness, tx.vin[i].prevout, err, true)) {
164-
continue;
165-
}
166-
167162
CTxOut prevout;
168163
if (tx.vin[i].m_is_pegin) {
169-
prevout = GetPeginOutputFromWitness(tx.vin[i].m_pegin_witness);
164+
std::string err;
165+
if (tx.witness.vtxinwit.size() <= i || !IsValidPeginWitness(tx.witness.vtxinwit[i].m_pegin_witness, tx.vin[i].prevout, err, true)) {
166+
continue;
167+
}
168+
prevout = GetPeginOutputFromWitness(tx.witness.vtxinwit[i].m_pegin_witness);
170169
} else {
171170
const Coin& coin = inputs.AccessCoin(tx.vin[i].prevout);
172171
assert(!coin.IsSpent());
173172
prevout = coin.out;
174173
}
175-
nSigOps += CountWitnessSigOps(tx.vin[i].scriptSig, prevout.scriptPubKey, &tx.vin[i].scriptWitness, flags);
174+
175+
const CScriptWitness* pScriptWitness = tx.witness.vtxinwit.size() > i ? &tx.witness.vtxinwit[i].scriptWitness : NULL;
176+
nSigOps += CountWitnessSigOps(tx.vin[i].scriptSig, prevout.scriptPubKey, pScriptWitness, flags);
176177
}
177178
return nSigOps;
178179
}
@@ -241,10 +242,10 @@ bool CheckTxInputs(const CTransaction& tx, CValidationState& state, const CCoins
241242
if (tx.vin[i].m_is_pegin) {
242243
// Check existence and validity of pegin witness
243244
std::string err;
244-
if (!IsValidPeginWitness(tx.vin[i].m_pegin_witness, prevout, err, true)) {
245+
if (tx.witness.vtxinwit.size() <= i || !IsValidPeginWitness(tx.witness.vtxinwit[i].m_pegin_witness, prevout, err, true)) {
245246
return state.DoS(0, false, REJECT_PEGIN, "bad-pegin-witness");
246247
}
247-
std::pair<uint256, COutPoint> pegin = std::make_pair(uint256(tx.vin[i].m_pegin_witness.stack[2]), prevout);
248+
std::pair<uint256, COutPoint> pegin = std::make_pair(uint256(tx.witness.vtxinwit[i].m_pegin_witness.stack[2]), prevout);
248249
if (inputs.IsPeginSpent(pegin)) {
249250
return state.Invalid(false, REJECT_INVALID, "bad-txns-double-pegin", strprintf("Double-pegin of %s:%d", prevout.hash.ToString(), prevout.n));
250251
}
@@ -255,7 +256,7 @@ bool CheckTxInputs(const CTransaction& tx, CValidationState& state, const CCoins
255256
setPeginsSpent.insert(pegin);
256257

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

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, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * (WITNESS_SCALE_FACTOR - 1) + ::GetSerializeSize(block, 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, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * (WITNESS_SCALE_FACTOR - 1) + ::GetSerializeSize(txin, PROTOCOL_VERSION) + ::GetSerializeSize(txin.scriptWitness.stack, PROTOCOL_VERSION);
110+
assert(tx.witness.vtxinwit.size() > nIn);
111+
//TODO(rebase) only count CA/CT witnesses when g_con_elementswitness is true
112+
return ::GetSerializeSize(tx.vin[nIn], PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * (WITNESS_SCALE_FACTOR - 1)
113+
+ ::GetSerializeSize(tx.vin[nIn], PROTOCOL_VERSION)
114+
+ ::GetSerializeSize(tx.witness.vtxinwit[nIn].scriptWitness.stack, PROTOCOL_VERSION)
115+
+ ::GetSerializeSize(tx.witness.vtxinwit[nIn].m_pegin_witness.stack, 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
@@ -200,6 +200,10 @@ void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry,
200200
{
201201
entry.pushKV("txid", tx.GetHash().GetHex());
202202
entry.pushKV("hash", tx.GetWitnessHash().GetHex());
203+
if (g_con_elementswitness) {
204+
entry.pushKV("wtxid", tx.GetWitnessHash().GetHex());
205+
entry.pushKV("withash", tx.GetWitnessOnlyHash().GetHex());
206+
}
203207
entry.pushKV("version", tx.nVersion);
204208
entry.pushKV("size", (int)::GetSerializeSize(tx, PROTOCOL_VERSION));
205209
entry.pushKV("vsize", (GetTransactionWeight(tx) + WITNESS_SCALE_FACTOR - 1) / WITNESS_SCALE_FACTOR);
@@ -220,19 +224,22 @@ void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry,
220224
o.pushKV("hex", HexStr(txin.scriptSig.begin(), txin.scriptSig.end()));
221225
in.pushKV("scriptSig", o);
222226

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

231238
// ELEMENTS:
232239
in.pushKV("is_pegin", txin.m_is_pegin);
233-
if (!tx.vin[i].m_pegin_witness.IsNull()) {
240+
if (tx.witness.vtxinwit.size() > i && !tx.witness.vtxinwit[i].m_pegin_witness.IsNull()) {
234241
UniValue pegin_witness(UniValue::VARR);
235-
for (const auto& item : tx.vin[i].m_pegin_witness.stack) {
242+
for (const auto& item : tx.witness.vtxinwit[i].m_pegin_witness.stack) {
236243
pegin_witness.push_back(HexStr(item.begin(), item.end()));
237244
}
238245
in.pushKV("pegin_witness", pegin_witness);

src/crypto/sha256.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -670,6 +670,23 @@ CSHA256& CSHA256::Write(const unsigned char* data, size_t len)
670670
}
671671
return *this;
672672
}
673+
//
674+
//void CSHA256::Finalize(unsigned char hash[OUTPUT_SIZE])
675+
//{
676+
// static const unsigned char pad[64] = {0x80};
677+
// unsigned char sizedesc[8];
678+
// WriteBE64(sizedesc, bytes << 3);
679+
// Write(pad, 1 + ((119 - (bytes % 64)) % 64));
680+
// Write(sizedesc, 8);
681+
// WriteBE32(hash, s[0]);
682+
// WriteBE32(hash + 4, s[1]);
683+
// WriteBE32(hash + 8, s[2]);
684+
// WriteBE32(hash + 12, s[3]);
685+
// WriteBE32(hash + 16, s[4]);
686+
// WriteBE32(hash + 20, s[5]);
687+
// WriteBE32(hash + 24, s[6]);
688+
// WriteBE32(hash + 28, s[7]);
689+
//}
673690

674691
void CSHA256::Finalize(unsigned char hash[OUTPUT_SIZE])
675692
{
@@ -678,6 +695,11 @@ void CSHA256::Finalize(unsigned char hash[OUTPUT_SIZE])
678695
WriteBE64(sizedesc, bytes << 3);
679696
Write(pad, 1 + ((119 - (bytes % 64)) % 64));
680697
Write(sizedesc, 8);
698+
Midstate(hash, NULL, NULL);
699+
}
700+
701+
void CSHA256::Midstate(unsigned char hash[OUTPUT_SIZE], uint64_t* len, unsigned char *buffer)
702+
{
681703
WriteBE32(hash, s[0]);
682704
WriteBE32(hash + 4, s[1]);
683705
WriteBE32(hash + 8, s[2]);
@@ -686,6 +708,12 @@ void CSHA256::Finalize(unsigned char hash[OUTPUT_SIZE])
686708
WriteBE32(hash + 20, s[5]);
687709
WriteBE32(hash + 24, s[6]);
688710
WriteBE32(hash + 28, s[7]);
711+
if (len) {
712+
*len = bytes << 3;
713+
}
714+
if (buffer) {
715+
memcpy(buffer, buf, bytes % 64);
716+
}
689717
}
690718

691719
CSHA256& CSHA256::Reset()

0 commit comments

Comments
 (0)