MCPcopy Create free account
hub / github.com/bitcoin/bitcoin / CreateValidTransaction

Method CreateValidTransaction

src/test/util/setup_common.cpp:478–539  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

476}
477
478std::pair<CMutableTransaction, CAmount> TestChain100Setup::CreateValidTransaction(const std::vector<CTransactionRef>& input_transactions,
479 const std::vector<COutPoint>& inputs,
480 int input_height,
481 const std::vector<CKey>& input_signing_keys,
482 const std::vector<CTxOut>& outputs,
483 const std::optional<CFeeRate>& feerate,
484 const std::optional<uint32_t>& fee_output)
485{
486 CMutableTransaction mempool_txn;
487 mempool_txn.vin.reserve(inputs.size());
488 mempool_txn.vout.reserve(outputs.size());
489
490 for (const auto& outpoint : inputs) {
491 mempool_txn.vin.emplace_back(outpoint, CScript(), MAX_BIP125_RBF_SEQUENCE);
492 }
493 mempool_txn.vout = outputs;
494
495 // - Add the signing key to a keystore
496 FillableSigningProvider keystore;
497 for (const auto& input_signing_key : input_signing_keys) {
498 keystore.AddKey(input_signing_key);
499 }
500 // - Populate a CoinsViewCache with the unspent output
501 CCoinsViewCache coins_cache{&CoinsViewEmpty::Get()};
502 for (const auto& input_transaction : input_transactions) {
503 AddCoins(coins_cache, *input_transaction.get(), input_height);
504 }
505 // Build Outpoint to Coin map for SignTransaction
506 std::map<COutPoint, Coin> input_coins;
507 CAmount inputs_amount{0};
508 for (const auto& outpoint_to_spend : inputs) {
509 // Use GetCoin to properly populate utxo_to_spend
510 auto utxo_to_spend{coins_cache.GetCoin(outpoint_to_spend).value()};
511 input_coins.insert({outpoint_to_spend, utxo_to_spend});
512 inputs_amount += utxo_to_spend.out.nValue;
513 }
514 // - Default signature hashing type
515 int nHashType = SIGHASH_ALL;
516 std::map<int, bilingual_str> input_errors;
517 assert(SignTransaction(mempool_txn, &keystore, input_coins, {.sighash_type = nHashType}, input_errors));
518 CAmount current_fee = inputs_amount - std::accumulate(outputs.begin(), outputs.end(), CAmount(0),
519 [](const CAmount& acc, const CTxOut& out) {
520 return acc + out.nValue;
521 });
522 // Deduct fees from fee_output to meet feerate if set
523 if (feerate.has_value()) {
524 assert(fee_output.has_value());
525 assert(fee_output.value() < mempool_txn.vout.size());
526 CAmount target_fee = feerate.value().GetFee(GetVirtualTransactionSize(CTransaction{mempool_txn}));
527 CAmount deduction = target_fee - current_fee;
528 if (deduction > 0) {
529 // Only deduct fee if there's anything to deduct. If the caller has put more fees than
530 // the target feerate, don't change the fee.
531 mempool_txn.vout[fee_output.value()].nValue -= deduction;
532 // Re-sign since an output has changed
533 input_errors.clear();
534 assert(SignTransaction(mempool_txn, &keystore, input_coins, {.sighash_type = nHashType}, input_errors));
535 current_fee = target_fee;

Callers 1

CreateTestBlockFunction · 0.80

Calls 15

CScriptClass · 0.70
AddCoinsFunction · 0.50
SignTransactionFunction · 0.50
reserveMethod · 0.45
sizeMethod · 0.45
emplace_backMethod · 0.45
AddKeyMethod · 0.45
getMethod · 0.45
valueMethod · 0.45
GetCoinMethod · 0.45
insertMethod · 0.45

Tested by

no test coverage detected