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