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:
|
// Fetch previous transactions:
|
||||||
// First, look in the txindex and the mempool
|
// First, look in the txindex and the mempool
|
||||||
for (unsigned int i = 0; i < psbtx.tx->vin.size(); ++i) {
|
for (PSBTInput& psbt_input : psbtx.inputs) {
|
||||||
PSBTInput& psbt_input = psbtx.inputs.at(i);
|
|
||||||
const CTxIn& tx_in = psbtx.tx->vin.at(i);
|
|
||||||
|
|
||||||
// The `non_witness_utxo` is the whole previous transaction
|
// The `non_witness_utxo` is the whole previous transaction
|
||||||
if (psbt_input.non_witness_utxo) continue;
|
if (psbt_input.non_witness_utxo) continue;
|
||||||
|
|
||||||
|
@ -194,29 +191,26 @@ PartiallySignedTransaction ProcessPSBT(const std::string& psbt_string, const std
|
||||||
// Look in the txindex
|
// Look in the txindex
|
||||||
if (g_txindex) {
|
if (g_txindex) {
|
||||||
uint256 block_hash;
|
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 we still don't have it look in the mempool
|
||||||
if (!tx) {
|
if (!tx) {
|
||||||
tx = node.mempool->get(tx_in.prevout.hash);
|
tx = node.mempool->get(psbt_input.prev_txid);
|
||||||
}
|
}
|
||||||
if (tx) {
|
if (tx) {
|
||||||
psbt_input.non_witness_utxo = tx;
|
psbt_input.non_witness_utxo = tx;
|
||||||
} else {
|
} 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 we still haven't found all of the inputs, look for the missing ones in the utxo set
|
||||||
if (!coins.empty()) {
|
if (!coins.empty()) {
|
||||||
FindCoins(node, coins);
|
FindCoins(node, coins);
|
||||||
for (unsigned int i = 0; i < psbtx.tx->vin.size(); ++i) {
|
for (PSBTInput& input : psbtx.inputs) {
|
||||||
PSBTInput& input = psbtx.inputs.at(i);
|
|
||||||
|
|
||||||
// If there are still missing utxos, add them if they were found in the utxo set
|
// If there are still missing utxos, add them if they were found in the utxo set
|
||||||
if (!input.non_witness_utxo) {
|
if (!input.non_witness_utxo) {
|
||||||
const CTxIn& tx_in = psbtx.tx->vin.at(i);
|
const Coin& coin = coins.at(input.GetOutPoint());
|
||||||
const Coin& coin = coins.at(tx_in.prevout);
|
|
||||||
if (!coin.out.IsNull() && IsSegWitOutput(provider, coin.out.scriptPubKey)) {
|
if (!coin.out.IsNull() && IsSegWitOutput(provider, coin.out.scriptPubKey)) {
|
||||||
input.witness_utxo = coin.out;
|
input.witness_utxo = coin.out;
|
||||||
}
|
}
|
||||||
|
@ -226,7 +220,7 @@ PartiallySignedTransaction ProcessPSBT(const std::string& psbt_string, const std
|
||||||
|
|
||||||
const PrecomputedTransactionData& txdata = PrecomputePSBTData(psbtx);
|
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))) {
|
if (PSBTInputSigned(psbtx.inputs.at(i))) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -239,7 +233,7 @@ PartiallySignedTransaction ProcessPSBT(const std::string& psbt_string, const std
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update script/keypath information using descriptor data.
|
// 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);
|
UpdatePSBTOutput(provider, psbtx, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1101,10 +1095,12 @@ static RPCHelpMan decodepsbt()
|
||||||
|
|
||||||
UniValue result(UniValue::VOBJ);
|
UniValue result(UniValue::VOBJ);
|
||||||
|
|
||||||
// Add the decoded tx
|
if (psbtx.tx != std::nullopt) {
|
||||||
UniValue tx_univ(UniValue::VOBJ);
|
// Add the decoded tx
|
||||||
TxToUniv(CTransaction(*psbtx.tx), /*block_hash=*/uint256(), /*entry=*/tx_univ, /*include_hex=*/false);
|
UniValue tx_univ(UniValue::VOBJ);
|
||||||
result.pushKV("tx", std::move(tx_univ));
|
TxToUniv(CTransaction(*psbtx.tx), /*block_hash=*/uint256(), /*entry=*/tx_univ, /*include_hex=*/false);
|
||||||
|
result.pushKV("tx", std::move(tx_univ));
|
||||||
|
}
|
||||||
|
|
||||||
// Add the global xpubs
|
// Add the global xpubs
|
||||||
UniValue global_xpubs(UniValue::VARR);
|
UniValue global_xpubs(UniValue::VARR);
|
||||||
|
@ -1170,7 +1166,7 @@ static RPCHelpMan decodepsbt()
|
||||||
have_a_utxo = true;
|
have_a_utxo = true;
|
||||||
}
|
}
|
||||||
if (input.non_witness_utxo) {
|
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);
|
UniValue non_wit(UniValue::VOBJ);
|
||||||
TxToUniv(*input.non_witness_utxo, /*block_hash=*/uint256(), /*entry=*/non_wit, /*include_hex=*/false);
|
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));
|
outputs.push_back(std::move(out));
|
||||||
|
|
||||||
// Fee calculation
|
// Fee calculation
|
||||||
if (MoneyRange(psbtx.tx->vout[i].nValue) && MoneyRange(output_value + psbtx.tx->vout[i].nValue)) {
|
if (MoneyRange(*output.amount) && MoneyRange(output_value + *output.amount)) {
|
||||||
output_value += psbtx.tx->vout[i].nValue;
|
output_value += *output.amount;
|
||||||
} else {
|
} else {
|
||||||
// Hack to just not show fee later
|
// Hack to just not show fee later
|
||||||
have_all_utxos = false;
|
have_all_utxos = false;
|
||||||
|
@ -1842,29 +1838,32 @@ static RPCHelpMan joinpsbts()
|
||||||
}
|
}
|
||||||
psbtxs.push_back(psbtx);
|
psbtxs.push_back(psbtx);
|
||||||
// Choose the highest version number
|
// Choose the highest version number
|
||||||
if (psbtx.tx->version > best_version) {
|
if (*psbtx.tx_version > best_version) {
|
||||||
best_version = psbtx.tx->version;
|
best_version = *psbtx.tx_version;
|
||||||
}
|
}
|
||||||
// Choose the lowest lock time
|
// Choose the lowest lock time
|
||||||
if (psbtx.tx->nLockTime < best_locktime) {
|
if (*psbtx.fallback_locktime < best_locktime) {
|
||||||
best_locktime = psbtx.tx->nLockTime;
|
best_locktime = *psbtx.fallback_locktime;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a blank psbt where everything will be added
|
// Create a blank psbt where everything will be added
|
||||||
PartiallySignedTransaction merged_psbt;
|
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 = CMutableTransaction();
|
||||||
merged_psbt.tx->version = best_version;
|
merged_psbt.tx->version = best_version;
|
||||||
merged_psbt.tx->nLockTime = best_locktime;
|
merged_psbt.tx->nLockTime = best_locktime;
|
||||||
|
|
||||||
// Merge
|
// Merge
|
||||||
for (auto& psbt : psbtxs) {
|
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])) {
|
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]);
|
merged_psbt.AddOutput(psbt.outputs[i]);
|
||||||
}
|
}
|
||||||
for (auto& xpub_pair : psbt.m_xpubs) {
|
for (auto& xpub_pair : psbt.m_xpubs) {
|
||||||
|
@ -1888,6 +1887,9 @@ static RPCHelpMan joinpsbts()
|
||||||
std::shuffle(output_indices.begin(), output_indices.end(), FastRandomContext());
|
std::shuffle(output_indices.begin(), output_indices.end(), FastRandomContext());
|
||||||
|
|
||||||
PartiallySignedTransaction shuffled_psbt;
|
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 = CMutableTransaction();
|
||||||
shuffled_psbt.tx->version = merged_psbt.tx->version;
|
shuffled_psbt.tx->version = merged_psbt.tx->version;
|
||||||
shuffled_psbt.tx->nLockTime = merged_psbt.tx->nLockTime;
|
shuffled_psbt.tx->nLockTime = merged_psbt.tx->nLockTime;
|
||||||
|
|
Loading…
Add table
Reference in a new issue