Skip to content

Commit

Permalink
Merge bitcoin#19426: refactor: Change * to & in MutableTransactionSig…
Browse files Browse the repository at this point in the history
…natureCreator

fac6cfc refactor: Change * to & in MutableTransactionSignatureCreator (MarcoFalke)

Pull request description:

  The `MutableTransactionSignatureCreator` constructor takes in a pointer to a mutable transaction. This is problematic for several reasons:

  * It would be undefined behaviour to pass in a nullptr because for signature creation, the memory of the mutable transaction is accessed
  * No caller currently passes in a nullptr, so passing a reference as a pointer is confusing

  Fix all issues by replacing `*` with `&` in `MutableTransactionSignatureCreator`

ACKs for top commit:
  theStack:
    Code-review ACK fac6cfc
  jonatack:
    ACK fac6cfc

Tree-SHA512: d84296b030bd4fa2709e5adbfe43a5f8377d218957d844af69a819893252af671df7f00004f5ba601a0bd70f3c1c2e58c4f00e75684da663f28432bb5c89fb86
  • Loading branch information
MacroFake committed May 6, 2022
2 parents b2e7811 + fac6cfc commit b557a24
Show file tree
Hide file tree
Showing 10 changed files with 28 additions and 26 deletions.
2 changes: 1 addition & 1 deletion src/bitcoin-tx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -667,7 +667,7 @@ static void MutateTxSign(CMutableTransaction& tx, const std::string& flagStr)
SignatureData sigdata = DataFromTransaction(mergedTx, i, coin.out);
// Only sign SIGHASH_SINGLE if there's a corresponding output:
if (!fHashSingle || (i < mergedTx.vout.size()))
ProduceSignature(keystore, MutableTransactionSignatureCreator(&mergedTx, i, amount, nHashType), prevPubKey, sigdata);
ProduceSignature(keystore, MutableTransactionSignatureCreator(mergedTx, i, amount, nHashType), prevPubKey, sigdata);

if (amount == MAX_MONEY && !sigdata.scriptWitness.IsNull()) {
throw std::runtime_error(strprintf("Missing amount for CTxOut with scriptPubKey=%s", HexStr(prevPubKey)));
Expand Down
4 changes: 2 additions & 2 deletions src/psbt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ void UpdatePSBTOutput(const SigningProvider& provider, PartiallySignedTransactio
// Construct a would-be spend of this output, to update sigdata with.
// Note that ProduceSignature is used to fill in metadata (not actual signatures),
// so provider does not need to provide any private keys (it can be a HidingSigningProvider).
MutableTransactionSignatureCreator creator(&tx, /*input_idx=*/0, out.nValue, SIGHASH_ALL);
MutableTransactionSignatureCreator creator(tx, /*input_idx=*/0, out.nValue, SIGHASH_ALL);
ProduceSignature(provider, creator, out.scriptPubKey, sigdata);

// Put redeem_script, witness_script, key paths, into PSBTOutput.
Expand Down Expand Up @@ -301,7 +301,7 @@ bool SignPSBTInput(const SigningProvider& provider, PartiallySignedTransaction&
if (txdata == nullptr) {
sig_complete = ProduceSignature(provider, DUMMY_SIGNATURE_CREATOR, utxo.scriptPubKey, sigdata);
} else {
MutableTransactionSignatureCreator creator(&tx, index, utxo.nValue, txdata, sighash);
MutableTransactionSignatureCreator creator(tx, index, utxo.nValue, txdata, sighash);
sig_complete = ProduceSignature(provider, creator, utxo.scriptPubKey, sigdata);
}
// Verify that a witness signature was produced in case one was required.
Expand Down
2 changes: 1 addition & 1 deletion src/rpc/rawtransaction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -567,7 +567,7 @@ static RPCHelpMan combinerawtransaction()
sigdata.MergeSignatureData(DataFromTransaction(txv, i, coin.out));
}
}
ProduceSignature(DUMMY_SIGNING_PROVIDER, MutableTransactionSignatureCreator(&mergedTx, i, coin.out.nValue, 1), coin.out.scriptPubKey, sigdata);
ProduceSignature(DUMMY_SIGNING_PROVIDER, MutableTransactionSignatureCreator(mergedTx, i, coin.out.nValue, 1), coin.out.scriptPubKey, sigdata);

UpdateInput(txin, sigdata);
}
Expand Down
20 changes: 10 additions & 10 deletions src/script/sign.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,16 @@

typedef std::vector<unsigned char> valtype;

MutableTransactionSignatureCreator::MutableTransactionSignatureCreator(const CMutableTransaction* tx, unsigned int input_idx, const CAmount& amount, int hash_type)
: txTo{tx}, nIn{input_idx}, nHashType{hash_type}, amount{amount}, checker{txTo, nIn, amount, MissingDataBehavior::FAIL},
MutableTransactionSignatureCreator::MutableTransactionSignatureCreator(const CMutableTransaction& tx, unsigned int input_idx, const CAmount& amount, int hash_type)
: m_txto{tx}, nIn{input_idx}, nHashType{hash_type}, amount{amount}, checker{&m_txto, nIn, amount, MissingDataBehavior::FAIL},
m_txdata(nullptr)
{
}

MutableTransactionSignatureCreator::MutableTransactionSignatureCreator(const CMutableTransaction* tx, unsigned int input_idx, const CAmount& amount, const PrecomputedTransactionData* txdata, int hash_type)
: txTo{tx}, nIn{input_idx}, nHashType{hash_type}, amount{amount},
checker{txdata ? MutableTransactionSignatureChecker{txTo, nIn, amount, *txdata, MissingDataBehavior::FAIL} :
MutableTransactionSignatureChecker{txTo, nIn, amount, MissingDataBehavior::FAIL}},
MutableTransactionSignatureCreator::MutableTransactionSignatureCreator(const CMutableTransaction& tx, unsigned int input_idx, const CAmount& amount, const PrecomputedTransactionData* txdata, int hash_type)
: m_txto{tx}, nIn{input_idx}, nHashType{hash_type}, amount{amount},
checker{txdata ? MutableTransactionSignatureChecker{&m_txto, nIn, amount, *txdata, MissingDataBehavior::FAIL} :
MutableTransactionSignatureChecker{&m_txto, nIn, amount, MissingDataBehavior::FAIL}},
m_txdata(txdata)
{
}
Expand All @@ -50,7 +50,7 @@ bool MutableTransactionSignatureCreator::CreateSig(const SigningProvider& provid
// BASE/WITNESS_V0 signatures don't support explicit SIGHASH_DEFAULT, use SIGHASH_ALL instead.
const int hashtype = nHashType == SIGHASH_DEFAULT ? SIGHASH_ALL : nHashType;

uint256 hash = SignatureHash(scriptCode, *txTo, nIn, hashtype, amount, sigversion, m_txdata);
uint256 hash = SignatureHash(scriptCode, m_txto, nIn, hashtype, amount, sigversion, m_txdata);
if (!key.Sign(hash, vchSig))
return false;
vchSig.push_back((unsigned char)hashtype);
Expand Down Expand Up @@ -80,7 +80,7 @@ bool MutableTransactionSignatureCreator::CreateSchnorrSig(const SigningProvider&
execdata.m_tapleaf_hash = *leaf_hash;
}
uint256 hash;
if (!SignatureHashSchnorr(hash, execdata, *txTo, nIn, nHashType, sigversion, *m_txdata, MissingDataBehavior::FAIL)) return false;
if (!SignatureHashSchnorr(hash, execdata, m_txto, nIn, nHashType, sigversion, *m_txdata, MissingDataBehavior::FAIL)) return false;
sig.resize(64);
// Use uint256{} as aux_rnd for now.
if (!key.SignSchnorr(hash, sig, merkle_root, {})) return false;
Expand Down Expand Up @@ -540,7 +540,7 @@ bool SignSignature(const SigningProvider &provider, const CScript& fromPubKey, C
{
assert(nIn < txTo.vin.size());

MutableTransactionSignatureCreator creator(&txTo, nIn, amount, nHashType);
MutableTransactionSignatureCreator creator(txTo, nIn, amount, nHashType);

SignatureData sigdata;
bool ret = ProduceSignature(provider, creator, fromPubKey, sigdata);
Expand Down Expand Up @@ -679,7 +679,7 @@ bool SignTransaction(CMutableTransaction& mtx, const SigningProvider* keystore,
SignatureData sigdata = DataFromTransaction(mtx, i, coin->second.out);
// Only sign SIGHASH_SINGLE if there's a corresponding output:
if (!fHashSingle || (i < mtx.vout.size())) {
ProduceSignature(*keystore, MutableTransactionSignatureCreator(&mtx, i, amount, &txdata, nHashType), prevPubKey, sigdata);
ProduceSignature(*keystore, MutableTransactionSignatureCreator(mtx, i, amount, &txdata, nHashType), prevPubKey, sigdata);
}

UpdateInput(txin, sigdata);
Expand Down
10 changes: 6 additions & 4 deletions src/script/sign.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#ifndef BITCOIN_SCRIPT_SIGN_H
#define BITCOIN_SCRIPT_SIGN_H

#include <attributes.h>
#include <coins.h>
#include <hash.h>
#include <pubkey.h>
Expand Down Expand Up @@ -34,17 +35,18 @@ class BaseSignatureCreator {
};

/** A signature creator for transactions. */
class MutableTransactionSignatureCreator : public BaseSignatureCreator {
const CMutableTransaction* txTo;
class MutableTransactionSignatureCreator : public BaseSignatureCreator
{
const CMutableTransaction& m_txto;
unsigned int nIn;
int nHashType;
CAmount amount;
const MutableTransactionSignatureChecker checker;
const PrecomputedTransactionData* m_txdata;

public:
MutableTransactionSignatureCreator(const CMutableTransaction* tx, unsigned int input_idx, const CAmount& amount, int hash_type);
MutableTransactionSignatureCreator(const CMutableTransaction* tx, unsigned int input_idx, const CAmount& amount, const PrecomputedTransactionData* txdata, int hash_type);
MutableTransactionSignatureCreator(const CMutableTransaction& tx LIFETIMEBOUND, unsigned int input_idx, const CAmount& amount, int hash_type);
MutableTransactionSignatureCreator(const CMutableTransaction& tx LIFETIMEBOUND, unsigned int input_idx, const CAmount& amount, const PrecomputedTransactionData* txdata, int hash_type);
const BaseSignatureChecker& Checker() const override { return checker; }
bool CreateSig(const SigningProvider& provider, std::vector<unsigned char>& vchSig, const CKeyID& keyid, const CScript& scriptCode, SigVersion sigversion) const override;
bool CreateSchnorrSig(const SigningProvider& provider, std::vector<unsigned char>& sig, const XOnlyPubKey& pubkey, const uint256* leaf_hash, const uint256* merkle_root, SigVersion sigversion) const override;
Expand Down
2 changes: 1 addition & 1 deletion src/test/descriptor_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,7 @@ void DoCheck(const std::string& prv, const std::string& pub, const std::string&
std::vector<CTxOut> utxos(1);
PrecomputedTransactionData txdata;
txdata.Init(spend, std::move(utxos), /*force=*/true);
MutableTransactionSignatureCreator creator(&spend, 0, CAmount{0}, &txdata, SIGHASH_DEFAULT);
MutableTransactionSignatureCreator creator{spend, 0, CAmount{0}, &txdata, SIGHASH_DEFAULT};
SignatureData sigdata;
BOOST_CHECK_MESSAGE(ProduceSignature(Merge(keys_priv, script_provider), creator, spks[n], sigdata), prv);
}
Expand Down
2 changes: 1 addition & 1 deletion src/test/fuzz/script_sign.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ FUZZ_TARGET_INIT(script_sign, initialize_script_sign)
}
if (n_in < script_tx_to.vin.size()) {
(void)SignSignature(provider, ConsumeScript(fuzzed_data_provider), script_tx_to, n_in, ConsumeMoney(fuzzed_data_provider), fuzzed_data_provider.ConsumeIntegral<int>());
MutableTransactionSignatureCreator signature_creator{&tx_to, n_in, ConsumeMoney(fuzzed_data_provider), fuzzed_data_provider.ConsumeIntegral<int>()};
MutableTransactionSignatureCreator signature_creator{tx_to, n_in, ConsumeMoney(fuzzed_data_provider), fuzzed_data_provider.ConsumeIntegral<int>()};
std::vector<unsigned char> vch_sig;
CKeyID address;
if (fuzzed_data_provider.ConsumeBool()) {
Expand Down
4 changes: 2 additions & 2 deletions src/test/script_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1162,7 +1162,7 @@ SignatureData CombineSignatures(const CTxOut& txout, const CMutableTransaction&
SignatureData data;
data.MergeSignatureData(scriptSig1);
data.MergeSignatureData(scriptSig2);
ProduceSignature(DUMMY_SIGNING_PROVIDER, MutableTransactionSignatureCreator(&tx, 0, txout.nValue, SIGHASH_DEFAULT), txout.scriptPubKey, data);
ProduceSignature(DUMMY_SIGNING_PROVIDER, MutableTransactionSignatureCreator(tx, 0, txout.nValue, SIGHASH_DEFAULT), txout.scriptPubKey, data);
return data;
}

Expand Down Expand Up @@ -1796,7 +1796,7 @@ BOOST_AUTO_TEST_CASE(bip341_keypath_test_vectors)
// Sign and verify signature.
FlatSigningProvider provider;
provider.keys[key.GetPubKey().GetID()] = key;
MutableTransactionSignatureCreator creator(&tx, txinpos, utxos[txinpos].nValue, &txdata, hashtype);
MutableTransactionSignatureCreator creator(tx, txinpos, utxos[txinpos].nValue, &txdata, hashtype);
std::vector<unsigned char> signature;
BOOST_CHECK(creator.CreateSchnorrSig(provider, signature, pubkey, nullptr, &merkle_root, SigVersion::TAPROOT));
BOOST_CHECK_EQUAL(HexStr(signature), input["expected"]["witness"][0].get_str());
Expand Down
2 changes: 1 addition & 1 deletion src/test/transaction_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -559,7 +559,7 @@ SignatureData CombineSignatures(const CMutableTransaction& input1, const CMutabl
SignatureData sigdata;
sigdata = DataFromTransaction(input1, 0, tx->vout[0]);
sigdata.MergeSignatureData(DataFromTransaction(input2, 0, tx->vout[0]));
ProduceSignature(DUMMY_SIGNING_PROVIDER, MutableTransactionSignatureCreator(&input1, 0, tx->vout[0].nValue, SIGHASH_ALL), tx->vout[0].scriptPubKey, sigdata);
ProduceSignature(DUMMY_SIGNING_PROVIDER, MutableTransactionSignatureCreator(input1, 0, tx->vout[0].nValue, SIGHASH_ALL), tx->vout[0].scriptPubKey, sigdata);
return sigdata;
}

Expand Down
6 changes: 3 additions & 3 deletions src/test/txvalidationcache_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ BOOST_FIXTURE_TEST_CASE(checkinputs_test, Dersig100Setup)

// Sign
SignatureData sigdata;
BOOST_CHECK(ProduceSignature(keystore, MutableTransactionSignatureCreator(&valid_with_witness_tx, 0, 11*CENT, SIGHASH_ALL), spend_tx.vout[1].scriptPubKey, sigdata));
BOOST_CHECK(ProduceSignature(keystore, MutableTransactionSignatureCreator(valid_with_witness_tx, 0, 11 * CENT, SIGHASH_ALL), spend_tx.vout[1].scriptPubKey, sigdata));
UpdateInput(valid_with_witness_tx.vin[0], sigdata);

// This should be valid under all script flags.
Expand All @@ -355,9 +355,9 @@ BOOST_FIXTURE_TEST_CASE(checkinputs_test, Dersig100Setup)
tx.vout[0].scriptPubKey = p2pk_scriptPubKey;

// Sign
for (int i=0; i<2; ++i) {
for (int i = 0; i < 2; ++i) {
SignatureData sigdata;
BOOST_CHECK(ProduceSignature(keystore, MutableTransactionSignatureCreator(&tx, i, 11*CENT, SIGHASH_ALL), spend_tx.vout[i].scriptPubKey, sigdata));
BOOST_CHECK(ProduceSignature(keystore, MutableTransactionSignatureCreator(tx, i, 11 * CENT, SIGHASH_ALL), spend_tx.vout[i].scriptPubKey, sigdata));
UpdateInput(tx.vin[i], sigdata);
}

Expand Down

0 comments on commit b557a24

Please sign in to comment.