mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-04-29 14:59:39 -04:00
Update RPCs for PSBTv2
This commit is contained in:
parent
44174d76d0
commit
a1d5544d16
1 changed files with 30 additions and 28 deletions
|
@ -182,10 +182,7 @@ PartiallySignedTransaction ProcessPSBT(const std::string& psbt_string, const std
|
|||
|
||||
// Fetch previous transactions:
|
||||
// First, look in the txindex and the mempool
|
||||
for (unsigned int i = 0; i < psbtx.tx->vin.size(); ++i) {
|
||||
PSBTInput& psbt_input = psbtx.inputs.at(i);
|
||||
const CTxIn& tx_in = psbtx.tx->vin.at(i);
|
||||
|
||||
for (PSBTInput& psbt_input : psbtx.inputs) {
|
||||
// The `non_witness_utxo` is the whole previous transaction
|
||||
if (psbt_input.non_witness_utxo) continue;
|
||||
|
||||
|
@ -194,29 +191,26 @@ PartiallySignedTransaction ProcessPSBT(const std::string& psbt_string, const std
|
|||
// Look in the txindex
|
||||
if (g_txindex) {
|
||||
uint256 block_hash;
|
||||
g_txindex->FindTx(tx_in.prevout.hash, block_hash, tx);
|
||||
g_txindex->FindTx(psbt_input.prev_txid, block_hash, tx);
|
||||
}
|
||||
// If we still don't have it look in the mempool
|
||||
if (!tx) {
|
||||
tx = node.mempool->get(tx_in.prevout.hash);
|
||||
tx = node.mempool->get(psbt_input.prev_txid);
|
||||
}
|
||||
if (tx) {
|
||||
psbt_input.non_witness_utxo = tx;
|
||||
} else {
|
||||
coins[tx_in.prevout]; // Create empty map entry keyed by prevout
|
||||
coins[psbt_input.GetOutPoint()]; // Create empty map entry keyed by prevout
|
||||
}
|
||||
}
|
||||
|
||||
// If we still haven't found all of the inputs, look for the missing ones in the utxo set
|
||||
if (!coins.empty()) {
|
||||
FindCoins(node, coins);
|
||||
for (unsigned int i = 0; i < psbtx.tx->vin.size(); ++i) {
|
||||
PSBTInput& input = psbtx.inputs.at(i);
|
||||
|
||||
for (PSBTInput& input : psbtx.inputs) {
|
||||
// If there are still missing utxos, add them if they were found in the utxo set
|
||||
if (!input.non_witness_utxo) {
|
||||
const CTxIn& tx_in = psbtx.tx->vin.at(i);
|
||||
const Coin& coin = coins.at(tx_in.prevout);
|
||||
const Coin& coin = coins.at(input.GetOutPoint());
|
||||
if (!coin.out.IsNull() && IsSegWitOutput(provider, coin.out.scriptPubKey)) {
|
||||
input.witness_utxo = coin.out;
|
||||
}
|
||||
|
@ -226,7 +220,7 @@ PartiallySignedTransaction ProcessPSBT(const std::string& psbt_string, const std
|
|||
|
||||
const PrecomputedTransactionData& txdata = PrecomputePSBTData(psbtx);
|
||||
|
||||
for (unsigned int i = 0; i < psbtx.tx->vin.size(); ++i) {
|
||||
for (unsigned int i = 0; i < psbtx.inputs.size(); ++i) {
|
||||
if (PSBTInputSigned(psbtx.inputs.at(i))) {
|
||||
continue;
|
||||
}
|
||||
|
@ -239,7 +233,7 @@ PartiallySignedTransaction ProcessPSBT(const std::string& psbt_string, const std
|
|||
}
|
||||
|
||||
// Update script/keypath information using descriptor data.
|
||||
for (unsigned int i = 0; i < psbtx.tx->vout.size(); ++i) {
|
||||
for (unsigned int i = 0; i < psbtx.outputs.size(); ++i) {
|
||||
UpdatePSBTOutput(provider, psbtx, i);
|
||||
}
|
||||
|
||||
|
@ -1101,10 +1095,12 @@ static RPCHelpMan decodepsbt()
|
|||
|
||||
UniValue result(UniValue::VOBJ);
|
||||
|
||||
// Add the decoded tx
|
||||
UniValue tx_univ(UniValue::VOBJ);
|
||||
TxToUniv(CTransaction(*psbtx.tx), /*block_hash=*/uint256(), /*entry=*/tx_univ, /*include_hex=*/false);
|
||||
result.pushKV("tx", std::move(tx_univ));
|
||||
if (psbtx.tx != std::nullopt) {
|
||||
// Add the decoded tx
|
||||
UniValue tx_univ(UniValue::VOBJ);
|
||||
TxToUniv(CTransaction(*psbtx.tx), /*block_hash=*/uint256(), /*entry=*/tx_univ, /*include_hex=*/false);
|
||||
result.pushKV("tx", std::move(tx_univ));
|
||||
}
|
||||
|
||||
// Add the global xpubs
|
||||
UniValue global_xpubs(UniValue::VARR);
|
||||
|
@ -1170,7 +1166,7 @@ static RPCHelpMan decodepsbt()
|
|||
have_a_utxo = true;
|
||||
}
|
||||
if (input.non_witness_utxo) {
|
||||
txout = input.non_witness_utxo->vout[psbtx.tx->vin[i].prevout.n];
|
||||
txout = input.non_witness_utxo->vout[*input.prev_out];
|
||||
|
||||
UniValue non_wit(UniValue::VOBJ);
|
||||
TxToUniv(*input.non_witness_utxo, /*block_hash=*/uint256(), /*entry=*/non_wit, /*include_hex=*/false);
|
||||
|
@ -1529,8 +1525,8 @@ static RPCHelpMan decodepsbt()
|
|||
outputs.push_back(std::move(out));
|
||||
|
||||
// Fee calculation
|
||||
if (MoneyRange(psbtx.tx->vout[i].nValue) && MoneyRange(output_value + psbtx.tx->vout[i].nValue)) {
|
||||
output_value += psbtx.tx->vout[i].nValue;
|
||||
if (MoneyRange(*output.amount) && MoneyRange(output_value + *output.amount)) {
|
||||
output_value += *output.amount;
|
||||
} else {
|
||||
// Hack to just not show fee later
|
||||
have_all_utxos = false;
|
||||
|
@ -1842,29 +1838,32 @@ static RPCHelpMan joinpsbts()
|
|||
}
|
||||
psbtxs.push_back(psbtx);
|
||||
// Choose the highest version number
|
||||
if (psbtx.tx->version > best_version) {
|
||||
best_version = psbtx.tx->version;
|
||||
if (*psbtx.tx_version > best_version) {
|
||||
best_version = *psbtx.tx_version;
|
||||
}
|
||||
// Choose the lowest lock time
|
||||
if (psbtx.tx->nLockTime < best_locktime) {
|
||||
best_locktime = psbtx.tx->nLockTime;
|
||||
if (*psbtx.fallback_locktime < best_locktime) {
|
||||
best_locktime = *psbtx.fallback_locktime;
|
||||
}
|
||||
}
|
||||
|
||||
// Create a blank psbt where everything will be added
|
||||
PartiallySignedTransaction merged_psbt;
|
||||
merged_psbt.tx_version = best_version;
|
||||
merged_psbt.fallback_locktime = best_locktime;
|
||||
// TODO: Remove for PSBTv2
|
||||
merged_psbt.tx = CMutableTransaction();
|
||||
merged_psbt.tx->version = best_version;
|
||||
merged_psbt.tx->nLockTime = best_locktime;
|
||||
|
||||
// Merge
|
||||
for (auto& psbt : psbtxs) {
|
||||
for (unsigned int i = 0; i < psbt.tx->vin.size(); ++i) {
|
||||
for (unsigned int i = 0; i < psbt.inputs.size(); ++i) {
|
||||
if (!merged_psbt.AddInput(psbt.inputs[i])) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Input %s:%d exists in multiple PSBTs", psbt.tx->vin[i].prevout.hash.ToString(), psbt.tx->vin[i].prevout.n));
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Input %s:%d exists in multiple PSBTs", psbt.inputs[i].prev_txid.ToString(), *psbt.inputs[i].prev_out));
|
||||
}
|
||||
}
|
||||
for (unsigned int i = 0; i < psbt.tx->vout.size(); ++i) {
|
||||
for (unsigned int i = 0; i < psbt.outputs.size(); ++i) {
|
||||
merged_psbt.AddOutput(psbt.outputs[i]);
|
||||
}
|
||||
for (auto& xpub_pair : psbt.m_xpubs) {
|
||||
|
@ -1888,6 +1887,9 @@ static RPCHelpMan joinpsbts()
|
|||
std::shuffle(output_indices.begin(), output_indices.end(), FastRandomContext());
|
||||
|
||||
PartiallySignedTransaction shuffled_psbt;
|
||||
shuffled_psbt.tx_version = merged_psbt.tx_version;
|
||||
shuffled_psbt.fallback_locktime = merged_psbt.fallback_locktime;
|
||||
// TODO: Remove for PSBTv2
|
||||
shuffled_psbt.tx = CMutableTransaction();
|
||||
shuffled_psbt.tx->version = merged_psbt.tx->version;
|
||||
shuffled_psbt.tx->nLockTime = merged_psbt.tx->nLockTime;
|
||||
|
|
Loading…
Add table
Reference in a new issue