Have a PSBTAnalysis state that indicates invalid PSBT

Invalid PSBTs need to be re-created, so the next role is the
Creator (new PSBTRole). Additionally, we need to know what went
wrong so an error field was added to PSBTAnalysis.

A PSBTAnalysis indicating invalid will have empty everything,
next will be set to PSBTRole::CREATOR, and an error message.
This commit is contained in:
Andrew Chow 2019-11-19 14:35:14 -05:00
parent b4a1da9ef8
commit 638e40cb60
4 changed files with 18 additions and 1 deletions

View file

@ -30,6 +30,17 @@ struct PSBTAnalysis {
Optional<CAmount> fee; //!< Amount of fee being paid by the transaction Optional<CAmount> fee; //!< Amount of fee being paid by the transaction
std::vector<PSBTInputAnalysis> inputs; //!< More information about the individual inputs of the transaction std::vector<PSBTInputAnalysis> inputs; //!< More information about the individual inputs of the transaction
PSBTRole next; //!< Which of the BIP 174 roles needs to handle the transaction next PSBTRole next; //!< Which of the BIP 174 roles needs to handle the transaction next
std::string error; //!< Error message
void SetInvalid(std::string err_msg)
{
estimated_vsize = nullopt;
estimated_feerate = nullopt;
fee = nullopt;
inputs.clear();
next = PSBTRole::CREATOR;
error = err_msg;
}
}; };
/** /**

View file

@ -348,6 +348,7 @@ TransactionError CombinePSBTs(PartiallySignedTransaction& out, const std::vector
std::string PSBTRoleName(PSBTRole role) { std::string PSBTRoleName(PSBTRole role) {
switch (role) { switch (role) {
case PSBTRole::CREATOR: return "creator";
case PSBTRole::UPDATER: return "updater"; case PSBTRole::UPDATER: return "updater";
case PSBTRole::SIGNER: return "signer"; case PSBTRole::SIGNER: return "signer";
case PSBTRole::FINALIZER: return "finalizer"; case PSBTRole::FINALIZER: return "finalizer";

View file

@ -560,6 +560,7 @@ struct PartiallySignedTransaction
}; };
enum class PSBTRole { enum class PSBTRole {
CREATOR,
UPDATER, UPDATER,
SIGNER, SIGNER,
FINALIZER, FINALIZER,

View file

@ -1672,6 +1672,7 @@ UniValue analyzepsbt(const JSONRPCRequest& request)
" \"estimated_feerate\" : feerate (numeric, optional) Estimated feerate of the final signed transaction in " + CURRENCY_UNIT + "/kB. Shown only if all UTXO slots in the PSBT have been filled.\n" " \"estimated_feerate\" : feerate (numeric, optional) Estimated feerate of the final signed transaction in " + CURRENCY_UNIT + "/kB. Shown only if all UTXO slots in the PSBT have been filled.\n"
" \"fee\" : fee (numeric, optional) The transaction fee paid. Shown only if all UTXO slots in the PSBT have been filled.\n" " \"fee\" : fee (numeric, optional) The transaction fee paid. Shown only if all UTXO slots in the PSBT have been filled.\n"
" \"next\" : \"role\" (string) Role of the next person that this psbt needs to go to\n" " \"next\" : \"role\" (string) Role of the next person that this psbt needs to go to\n"
" \"error\" : \"error\" (string) Error message if there is one"
"}\n" "}\n"
}, },
RPCExamples { RPCExamples {
@ -1724,7 +1725,7 @@ UniValue analyzepsbt(const JSONRPCRequest& request)
} }
inputs_result.push_back(input_univ); inputs_result.push_back(input_univ);
} }
result.pushKV("inputs", inputs_result); if (!inputs_result.empty()) result.pushKV("inputs", inputs_result);
if (psbta.estimated_vsize != nullopt) { if (psbta.estimated_vsize != nullopt) {
result.pushKV("estimated_vsize", (int)*psbta.estimated_vsize); result.pushKV("estimated_vsize", (int)*psbta.estimated_vsize);
@ -1736,6 +1737,9 @@ UniValue analyzepsbt(const JSONRPCRequest& request)
result.pushKV("fee", ValueFromAmount(*psbta.fee)); result.pushKV("fee", ValueFromAmount(*psbta.fee));
} }
result.pushKV("next", PSBTRoleName(psbta.next)); result.pushKV("next", PSBTRoleName(psbta.next));
if (!psbta.error.empty()) {
result.pushKV("error", psbta.error);
}
return result; return result;
} }