Skip to content

Commit

Permalink
Make AnalyzePSBT next role calculation simple, correct
Browse files Browse the repository at this point in the history
Github-Pull: bitcoin#18224
Rebased-From: 1ef28b4
  • Loading branch information
instagibbs authored and luke-jr committed Mar 4, 2020
1 parent 58ba7c3 commit eda8c7e
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 20 deletions.
31 changes: 11 additions & 20 deletions src/node/psbt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,7 @@ PSBTAnalysis AnalyzePSBT(PartiallySignedTransaction psbtx)
PSBTAnalysis result;

bool calc_fee = true;
bool all_final = true;
bool only_missing_sigs = true;
bool only_missing_final = false;

CAmount in_amt = 0;

result.inputs.resize(psbtx.tx->vin.size());
Expand All @@ -29,6 +27,9 @@ PSBTAnalysis AnalyzePSBT(PartiallySignedTransaction psbtx)
PSBTInput& input = psbtx.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
CTxOut utxo;
if (psbtx.GetInputUTXO(utxo, i)) {
Expand Down Expand Up @@ -57,7 +58,6 @@ PSBTAnalysis AnalyzePSBT(PartiallySignedTransaction psbtx)
// Check if it is final
if (!utxo.IsNull() && !PSBTInputSigned(input)) {
input_analysis.is_final = false;
all_final = false;

// Figure out what is missing
SignatureData outdata;
Expand All @@ -74,22 +74,24 @@ PSBTAnalysis AnalyzePSBT(PartiallySignedTransaction psbtx)
if (outdata.missing_pubkeys.empty() && outdata.missing_redeem_script.IsNull() && outdata.missing_witness_script.IsNull() && !outdata.missing_sigs.empty()) {
input_analysis.next = PSBTRole::SIGNER;
} else {
only_missing_sigs = false;
input_analysis.next = PSBTRole::UPDATER;
}
} else {
only_missing_final = true;
input_analysis.next = PSBTRole::FINALIZER;
}
} else if (!utxo.IsNull()){
input_analysis.is_final = true;
}
}

if (all_final) {
only_missing_sigs = false;
result.next = PSBTRole::EXTRACTOR;
// Calculate next role for PSBT by grabbing "minumum" PSBTInput next role
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) {
// Get the output amount
CAmount out_amt = std::accumulate(psbtx.tx->vout.begin(), psbtx.tx->vout.end(), CAmount(0),
Expand Down Expand Up @@ -139,17 +141,6 @@ PSBTAnalysis AnalyzePSBT(PartiallySignedTransaction psbtx)
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;
Expand Down
4 changes: 4 additions & 0 deletions test/functional/rpc_psbt.py
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,10 @@ def test_psbt_input_keys(psbt_input, keys):
assert_equal(analysis['next'], 'creator')
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')
assert_equal(analysis['next'], 'creator')
assert_equal(analysis['error'], 'PSBT is not valid. Output amount invalid')
Expand Down

0 comments on commit eda8c7e

Please sign in to comment.