diff options
author | Glenn Willen <gwillen@nerdnet.org> | 2019-02-09 20:51:33 -0800 |
---|---|---|
committer | Glenn Willen <gwillen@nerdnet.org> | 2019-02-11 14:08:04 -0800 |
commit | bd0dbe8763fc3029cf96531c9ccaba280b939445 (patch) | |
tree | f9ac966b3363bec18db36714ffc37ec3c36dd4be /src/wallet | |
parent | c6c3d42a7d6b525144fc7fc6653cd11139d2b34a (diff) |
Switch away from exceptions in refactored tx code
After refactoring general-purpose PSBT and transaction code out of RPC code,
for use in the GUI, it's no longer appropriate to throw exceptions. Instead we
now return bools for success, and take an output parameter for an error object.
We still use JSONRPCError() for the error objects, since only RPC callers
actually care about the error codes.
Diffstat (limited to 'src/wallet')
-rw-r--r-- | src/wallet/psbtwallet.cpp | 14 | ||||
-rw-r--r-- | src/wallet/psbtwallet.h | 24 | ||||
-rw-r--r-- | src/wallet/rpcwallet.cpp | 13 | ||||
-rw-r--r-- | src/wallet/test/psbt_wallet_tests.cpp | 4 |
4 files changed, 45 insertions, 10 deletions
diff --git a/src/wallet/psbtwallet.cpp b/src/wallet/psbtwallet.cpp index a62ad08370..761e7b7dd7 100644 --- a/src/wallet/psbtwallet.cpp +++ b/src/wallet/psbtwallet.cpp @@ -2,14 +2,13 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include <rpc/protocol.h> #include <wallet/psbtwallet.h> -bool FillPSBT(const CWallet* pwallet, PartiallySignedTransaction& psbtx, int sighash_type, bool sign, bool bip32derivs) +bool FillPSBT(const CWallet* pwallet, PartiallySignedTransaction& psbtx, TransactionError& error, bool& complete, int sighash_type, bool sign, bool bip32derivs) { LOCK(pwallet->cs_wallet); // Get all of the previous transactions - bool complete = true; + complete = true; for (unsigned int i = 0; i < psbtx.tx->vin.size(); ++i) { const CTxIn& txin = psbtx.tx->vin[i]; PSBTInput& input = psbtx.inputs.at(i); @@ -20,7 +19,8 @@ bool FillPSBT(const CWallet* pwallet, PartiallySignedTransaction& psbtx, int sig // Verify input looks sane. This will check that we have at most one uxto, witness or non-witness. if (!input.IsSane()) { - throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "PSBT input is not sane."); + error = TransactionError::INVALID_PSBT; + return false; } // If we have no utxo, grab it from the wallet. @@ -37,7 +37,8 @@ bool FillPSBT(const CWallet* pwallet, PartiallySignedTransaction& psbtx, int sig // Get the Sighash type if (sign && input.sighash_type > 0 && input.sighash_type != sighash_type) { - throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Specified Sighash and sighash in PSBT do not match."); + error = TransactionError::SIGHASH_MISMATCH; + return false; } complete &= SignPSBTInput(HidingSigningProvider(pwallet, !sign, !bip32derivs), psbtx, i, sighash_type); @@ -56,5 +57,6 @@ bool FillPSBT(const CWallet* pwallet, PartiallySignedTransaction& psbtx, int sig ProduceSignature(HidingSigningProvider(pwallet, true, !bip32derivs), creator, out.scriptPubKey, sigdata); psbt_out.FromSignatureData(sigdata); } - return complete; + + return true; } diff --git a/src/wallet/psbtwallet.h b/src/wallet/psbtwallet.h index 4f888a06ec..b679f5c6ba 100644 --- a/src/wallet/psbtwallet.h +++ b/src/wallet/psbtwallet.h @@ -5,10 +5,32 @@ #ifndef BITCOIN_WALLET_PSBTWALLET_H #define BITCOIN_WALLET_PSBTWALLET_H +#include <node/transaction.h> #include <psbt.h> #include <primitives/transaction.h> #include <wallet/wallet.h> -bool FillPSBT(const CWallet* pwallet, PartiallySignedTransaction& psbtx, int sighash_type = 1 /* SIGHASH_ALL */, bool sign = true, bool bip32derivs = false); +/** + * Fills out a PSBT with information from the wallet. Fills in UTXOs if we have + * them. Tries to sign if sign=true. Sets `complete` if the PSBT is now complete + * (i.e. has all required signatures or signature-parts, and is ready to + * finalize.) Sets `error` and returns false if something goes wrong. + * + * @param[in] pwallet pointer to a wallet + * @param[in] &psbtx reference to PartiallySignedTransaction to fill in + * @param[out] &error reference to UniValue to fill with error info on failure + * @param[out] &complete indicates whether the PSBT is now complete + * @param[in] sighash_type the sighash type to use when signing (if PSBT does not specify) + * @param[in] sign whether to sign or not + * @param[in] bip32derivs whether to fill in bip32 derivation information if available + * return true on success, false on error (and fills in `error`) + */ +bool FillPSBT(const CWallet* pwallet, + PartiallySignedTransaction& psbtx, + TransactionError& error, + bool& complete, + int sighash_type = 1 /* SIGHASH_ALL */, + bool sign = true, + bool bip32derivs = false); #endif // BITCOIN_WALLET_PSBTWALLET_H diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 905b183307..6811d927f2 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -13,6 +13,7 @@ #include <validation.h> #include <key_io.h> #include <net.h> +#include <node/transaction.h> #include <outputtype.h> #include <policy/feerate.h> #include <policy/fees.h> @@ -4003,7 +4004,11 @@ UniValue walletprocesspsbt(const JSONRPCRequest& request) // Fill transaction with our data and also sign bool sign = request.params[1].isNull() ? true : request.params[1].get_bool(); bool bip32derivs = request.params[3].isNull() ? false : request.params[3].get_bool(); - bool complete = FillPSBT(pwallet, psbtx, nHashType, sign, bip32derivs); + bool complete = true; + TransactionError err; + if (!FillPSBT(pwallet, psbtx, err, complete, nHashType, sign, bip32derivs)) { + throw JSONRPCTransactionError(err); + } UniValue result(UniValue::VOBJ); CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); @@ -4117,7 +4122,11 @@ UniValue walletcreatefundedpsbt(const JSONRPCRequest& request) // Fill transaction with out data but don't sign bool bip32derivs = request.params[4].isNull() ? false : request.params[4].get_bool(); - FillPSBT(pwallet, psbtx, 1, false, bip32derivs); + bool complete = true; + TransactionError err; + if (!FillPSBT(pwallet, psbtx, err, complete, 1, false, bip32derivs)) { + throw JSONRPCTransactionError(err); + } // Serialize the PSBT CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); diff --git a/src/wallet/test/psbt_wallet_tests.cpp b/src/wallet/test/psbt_wallet_tests.cpp index 0c5b7c7e98..e89d4121bc 100644 --- a/src/wallet/test/psbt_wallet_tests.cpp +++ b/src/wallet/test/psbt_wallet_tests.cpp @@ -61,7 +61,9 @@ BOOST_AUTO_TEST_CASE(psbt_updater_test) ssData >> psbtx; // Fill transaction with our data - FillPSBT(&m_wallet, psbtx, SIGHASH_ALL, false, true); + TransactionError err; + bool complete = true; + FillPSBT(&m_wallet, psbtx, err, complete, SIGHASH_ALL, false, true); // Get the final tx CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); |