Coverage Report

Created: 2025-02-21 14:36

/root/bitcoin/src/test/util/transaction_utils.cpp
Line
Count
Source (jump to first uncovered line)
1
// Copyright (c) 2019-2020 The Bitcoin Core developers
2
// Distributed under the MIT software license, see the accompanying
3
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
5
#include <coins.h>
6
#include <consensus/validation.h>
7
#include <script/signingprovider.h>
8
#include <test/util/transaction_utils.h>
9
10
CMutableTransaction BuildCreditingTransaction(const CScript& scriptPubKey, int nValue)
11
0
{
12
0
    CMutableTransaction txCredit;
13
0
    txCredit.version = 1;
14
0
    txCredit.nLockTime = 0;
15
0
    txCredit.vin.resize(1);
16
0
    txCredit.vout.resize(1);
17
0
    txCredit.vin[0].prevout.SetNull();
18
0
    txCredit.vin[0].scriptSig = CScript() << CScriptNum(0) << CScriptNum(0);
19
0
    txCredit.vin[0].nSequence = CTxIn::SEQUENCE_FINAL;
20
0
    txCredit.vout[0].scriptPubKey = scriptPubKey;
21
0
    txCredit.vout[0].nValue = nValue;
22
23
0
    return txCredit;
24
0
}
25
26
CMutableTransaction BuildSpendingTransaction(const CScript& scriptSig, const CScriptWitness& scriptWitness, const CTransaction& txCredit)
27
0
{
28
0
    CMutableTransaction txSpend;
29
0
    txSpend.version = 1;
30
0
    txSpend.nLockTime = 0;
31
0
    txSpend.vin.resize(1);
32
0
    txSpend.vout.resize(1);
33
0
    txSpend.vin[0].scriptWitness = scriptWitness;
34
0
    txSpend.vin[0].prevout.hash = txCredit.GetHash();
35
0
    txSpend.vin[0].prevout.n = 0;
36
0
    txSpend.vin[0].scriptSig = scriptSig;
37
0
    txSpend.vin[0].nSequence = CTxIn::SEQUENCE_FINAL;
38
0
    txSpend.vout[0].scriptPubKey = CScript();
39
0
    txSpend.vout[0].nValue = txCredit.vout[0].nValue;
40
41
0
    return txSpend;
42
0
}
43
44
std::vector<CMutableTransaction> SetupDummyInputs(FillableSigningProvider& keystoreRet, CCoinsViewCache& coinsRet, const std::array<CAmount,4>& nValues)
45
0
{
46
0
    std::vector<CMutableTransaction> dummyTransactions;
47
0
    dummyTransactions.resize(2);
48
49
    // Add some keys to the keystore:
50
0
    CKey key[4];
51
0
    for (int i = 0; i < 4; i++) {
52
0
        key[i].MakeNewKey(i % 2);
53
0
        keystoreRet.AddKey(key[i]);
54
0
    }
55
56
    // Create some dummy input transactions
57
0
    dummyTransactions[0].vout.resize(2);
58
0
    dummyTransactions[0].vout[0].nValue = nValues[0];
59
0
    dummyTransactions[0].vout[0].scriptPubKey << ToByteVector(key[0].GetPubKey()) << OP_CHECKSIG;
60
0
    dummyTransactions[0].vout[1].nValue = nValues[1];
61
0
    dummyTransactions[0].vout[1].scriptPubKey << ToByteVector(key[1].GetPubKey()) << OP_CHECKSIG;
62
0
    AddCoins(coinsRet, CTransaction(dummyTransactions[0]), 0);
63
64
0
    dummyTransactions[1].vout.resize(2);
65
0
    dummyTransactions[1].vout[0].nValue = nValues[2];
66
0
    dummyTransactions[1].vout[0].scriptPubKey = GetScriptForDestination(PKHash(key[2].GetPubKey()));
67
0
    dummyTransactions[1].vout[1].nValue = nValues[3];
68
0
    dummyTransactions[1].vout[1].scriptPubKey = GetScriptForDestination(PKHash(key[3].GetPubKey()));
69
0
    AddCoins(coinsRet, CTransaction(dummyTransactions[1]), 0);
70
71
0
    return dummyTransactions;
72
0
}
73
74
void BulkTransaction(CMutableTransaction& tx, int32_t target_weight)
75
0
{
76
0
    tx.vout.emplace_back(0, CScript() << OP_RETURN);
77
0
    auto unpadded_weight{GetTransactionWeight(CTransaction(tx))};
78
0
    assert(target_weight >= unpadded_weight);
79
80
    // determine number of needed padding bytes by converting weight difference to vbytes
81
0
    auto dummy_vbytes = (target_weight - unpadded_weight + (WITNESS_SCALE_FACTOR - 1)) / WITNESS_SCALE_FACTOR;
82
    // compensate for the increase of the compact-size encoded script length
83
    // (note that the length encoding of the unpadded output script needs one byte)
84
0
    dummy_vbytes -= GetSizeOfCompactSize(dummy_vbytes) - 1;
85
86
    // pad transaction by repeatedly appending a dummy opcode to the output script
87
0
    tx.vout[0].scriptPubKey.insert(tx.vout[0].scriptPubKey.end(), dummy_vbytes, OP_1);
88
89
    // actual weight should be at most 3 higher than target weight
90
0
    assert(GetTransactionWeight(CTransaction(tx)) >= target_weight);
91
0
    assert(GetTransactionWeight(CTransaction(tx)) <= target_weight + 3);
92
0
}
93
94
bool SignSignature(const SigningProvider &provider, const CScript& fromPubKey, CMutableTransaction& txTo, unsigned int nIn, const CAmount& amount, int nHashType, SignatureData& sig_data)
95
0
{
96
0
    assert(nIn < txTo.vin.size());
97
98
0
    MutableTransactionSignatureCreator creator(txTo, nIn, amount, nHashType);
99
100
0
    bool ret = ProduceSignature(provider, creator, fromPubKey, sig_data);
101
0
    UpdateInput(txTo.vin.at(nIn), sig_data);
102
0
    return ret;
103
0
}
104
105
bool SignSignature(const SigningProvider &provider, const CTransaction& txFrom, CMutableTransaction& txTo, unsigned int nIn, int nHashType, SignatureData& sig_data)
106
0
{
107
0
    assert(nIn < txTo.vin.size());
108
0
    const CTxIn& txin = txTo.vin[nIn];
109
0
    assert(txin.prevout.n < txFrom.vout.size());
110
0
    const CTxOut& txout = txFrom.vout[txin.prevout.n];
111
112
0
    return SignSignature(provider, txout.scriptPubKey, txTo, nIn, txout.nValue, nHashType, sig_data);
113
0
}