mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-06-30 10:42:23 +02:00
Make AnalyzePSBT next role calculation simple, correct
This commit is contained in:
@ -18,9 +18,7 @@ PSBTAnalysis AnalyzePSBT(PartiallySignedTransaction psbtx)
|
|||||||
PSBTAnalysis result;
|
PSBTAnalysis result;
|
||||||
|
|
||||||
bool calc_fee = true;
|
bool calc_fee = true;
|
||||||
bool all_final = true;
|
|
||||||
bool only_missing_sigs = true;
|
|
||||||
bool only_missing_final = false;
|
|
||||||
CAmount in_amt = 0;
|
CAmount in_amt = 0;
|
||||||
|
|
||||||
result.inputs.resize(psbtx.tx->vin.size());
|
result.inputs.resize(psbtx.tx->vin.size());
|
||||||
@ -29,6 +27,9 @@ PSBTAnalysis AnalyzePSBT(PartiallySignedTransaction psbtx)
|
|||||||
PSBTInput& input = psbtx.inputs[i];
|
PSBTInput& input = psbtx.inputs[i];
|
||||||
PSBTInputAnalysis& input_analysis = result.inputs[i];
|
PSBTInputAnalysis& input_analysis = result.inputs[i];
|
||||||
|
|
||||||
|
// We set next role here and ratchet backwards as required
|
||||||
|
input_analysis.next = PSBTRole::EXTRACTOR;
|
||||||
|
|
||||||
// Check for a UTXO
|
// Check for a UTXO
|
||||||
CTxOut utxo;
|
CTxOut utxo;
|
||||||
if (psbtx.GetInputUTXO(utxo, i)) {
|
if (psbtx.GetInputUTXO(utxo, i)) {
|
||||||
@ -57,7 +58,6 @@ PSBTAnalysis AnalyzePSBT(PartiallySignedTransaction psbtx)
|
|||||||
// Check if it is final
|
// Check if it is final
|
||||||
if (!utxo.IsNull() && !PSBTInputSigned(input)) {
|
if (!utxo.IsNull() && !PSBTInputSigned(input)) {
|
||||||
input_analysis.is_final = false;
|
input_analysis.is_final = false;
|
||||||
all_final = false;
|
|
||||||
|
|
||||||
// Figure out what is missing
|
// Figure out what is missing
|
||||||
SignatureData outdata;
|
SignatureData outdata;
|
||||||
@ -74,11 +74,9 @@ PSBTAnalysis AnalyzePSBT(PartiallySignedTransaction psbtx)
|
|||||||
if (outdata.missing_pubkeys.empty() && outdata.missing_redeem_script.IsNull() && outdata.missing_witness_script.IsNull() && !outdata.missing_sigs.empty()) {
|
if (outdata.missing_pubkeys.empty() && outdata.missing_redeem_script.IsNull() && outdata.missing_witness_script.IsNull() && !outdata.missing_sigs.empty()) {
|
||||||
input_analysis.next = PSBTRole::SIGNER;
|
input_analysis.next = PSBTRole::SIGNER;
|
||||||
} else {
|
} else {
|
||||||
only_missing_sigs = false;
|
|
||||||
input_analysis.next = PSBTRole::UPDATER;
|
input_analysis.next = PSBTRole::UPDATER;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
only_missing_final = true;
|
|
||||||
input_analysis.next = PSBTRole::FINALIZER;
|
input_analysis.next = PSBTRole::FINALIZER;
|
||||||
}
|
}
|
||||||
} else if (!utxo.IsNull()){
|
} else if (!utxo.IsNull()){
|
||||||
@ -86,10 +84,14 @@ PSBTAnalysis AnalyzePSBT(PartiallySignedTransaction psbtx)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (all_final) {
|
// Calculate next role for PSBT by grabbing "minumum" PSBTInput next role
|
||||||
only_missing_sigs = false;
|
result.next = PSBTRole::EXTRACTOR;
|
||||||
result.next = PSBTRole::EXTRACTOR;
|
for (unsigned int i = 0; i < psbtx.tx->vin.size(); ++i) {
|
||||||
|
PSBTInputAnalysis& input_analysis = result.inputs[i];
|
||||||
|
result.next = std::min(result.next, input_analysis.next);
|
||||||
}
|
}
|
||||||
|
assert(result.next > PSBTRole::CREATOR);
|
||||||
|
|
||||||
if (calc_fee) {
|
if (calc_fee) {
|
||||||
// Get the output amount
|
// Get the output amount
|
||||||
CAmount out_amt = std::accumulate(psbtx.tx->vout.begin(), psbtx.tx->vout.end(), CAmount(0),
|
CAmount out_amt = std::accumulate(psbtx.tx->vout.begin(), psbtx.tx->vout.end(), CAmount(0),
|
||||||
@ -139,17 +141,6 @@ PSBTAnalysis AnalyzePSBT(PartiallySignedTransaction psbtx)
|
|||||||
result.estimated_feerate = feerate;
|
result.estimated_feerate = feerate;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (only_missing_sigs) {
|
|
||||||
result.next = PSBTRole::SIGNER;
|
|
||||||
} else if (only_missing_final) {
|
|
||||||
result.next = PSBTRole::FINALIZER;
|
|
||||||
} else if (all_final) {
|
|
||||||
result.next = PSBTRole::EXTRACTOR;
|
|
||||||
} else {
|
|
||||||
result.next = PSBTRole::UPDATER;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
result.next = PSBTRole::UPDATER;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -437,6 +437,10 @@ class PSBTTest(BitcoinTestFramework):
|
|||||||
assert_equal(analysis['next'], 'creator')
|
assert_equal(analysis['next'], 'creator')
|
||||||
assert_equal(analysis['error'], 'PSBT is not valid. Input 0 has invalid value')
|
assert_equal(analysis['error'], 'PSBT is not valid. Input 0 has invalid value')
|
||||||
|
|
||||||
|
self.log.info("PSBT with signed, but not finalized, inputs should have Finalizer as next")
|
||||||
|
analysis = self.nodes[0].analyzepsbt('cHNidP8BAHECAAAAAZYezcxdnbXoQCmrD79t/LzDgtUo9ERqixk8wgioAobrAAAAAAD9////AlDDAAAAAAAAFgAUy/UxxZuzZswcmFnN/E9DGSiHLUsuGPUFAAAAABYAFLsH5o0R38wXx+X2cCosTMCZnQ4baAAAAAABAR8A4fUFAAAAABYAFOBI2h5thf3+Lflb2LGCsVSZwsltIgIC/i4dtVARCRWtROG0HHoGcaVklzJUcwo5homgGkSNAnJHMEQCIGx7zKcMIGr7cEES9BR4Kdt/pzPTK3fKWcGyCJXb7MVnAiALOBgqlMH4GbC1HDh/HmylmO54fyEy4lKde7/BT/PWxwEBAwQBAAAAIgYC/i4dtVARCRWtROG0HHoGcaVklzJUcwo5homgGkSNAnIYDwVpQ1QAAIABAACAAAAAgAAAAAAAAAAAAAAiAgL+CIiB59NSCssOJRGiMYQK1chahgAaaJpIXE41Cyir+xgPBWlDVAAAgAEAAIAAAACAAQAAAAAAAAAA')
|
||||||
|
assert_equal(analysis['next'], 'finalizer')
|
||||||
|
|
||||||
analysis = self.nodes[0].analyzepsbt('cHNidP8BAHECAAAAAfA00BFgAm6tp86RowwH6BMImQNL5zXUcTT97XoLGz0BAAAAAAD/////AgCAgWrj0AcAFgAUKNw0x8HRctAgmvoevm4u1SbN7XL87QKVAAAAABYAFPck4gF7iL4NL4wtfRAKgQbghiTUAAAAAAABAR8A8gUqAQAAABYAFJUDtxf2PHo641HEOBOAIvFMNTr2AAAA')
|
analysis = self.nodes[0].analyzepsbt('cHNidP8BAHECAAAAAfA00BFgAm6tp86RowwH6BMImQNL5zXUcTT97XoLGz0BAAAAAAD/////AgCAgWrj0AcAFgAUKNw0x8HRctAgmvoevm4u1SbN7XL87QKVAAAAABYAFPck4gF7iL4NL4wtfRAKgQbghiTUAAAAAAABAR8A8gUqAQAAABYAFJUDtxf2PHo641HEOBOAIvFMNTr2AAAA')
|
||||||
assert_equal(analysis['next'], 'creator')
|
assert_equal(analysis['next'], 'creator')
|
||||||
assert_equal(analysis['error'], 'PSBT is not valid. Output amount invalid')
|
assert_equal(analysis['error'], 'PSBT is not valid. Output amount invalid')
|
||||||
|
Reference in New Issue
Block a user