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