From f87684a007cb6655024e32d6b5e3f2fbc408b0f6 Mon Sep 17 00:00:00 2001 From: Glenn Willen Date: Wed, 1 May 2019 18:27:26 -0700 Subject: [PATCH 1/4] Add convenience method GetNonIssuanceBlindingData --- src/wallet/wallet.cpp | 29 +++++++++++------------------ src/wallet/wallet.h | 3 +++ 2 files changed, 14 insertions(+), 18 deletions(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 2b801c4c8d..c3a51ad469 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -5386,48 +5386,41 @@ void CWalletTx::GetBlindingData(const unsigned int map_index, const std::vector< if (asset_out) *asset_out = asset_tag; } -CAmount CWalletTx::GetOutputValueOut(unsigned int output_index) const { +void CWalletTx::GetNonIssuanceBlindingData(const unsigned int output_index, CPubKey* blinding_pubkey_out, CAmount* value_out, uint256* value_factor_out, CAsset* asset_out, uint256* asset_factor_out) const { assert(output_index < tx->vout.size()); const CTxOut& out = tx->vout[output_index]; const CTxWitness& wit = tx->witness; + GetBlindingData(output_index, wit.vtxoutwit.size() <= output_index ? std::vector() : wit.vtxoutwit[output_index].vchRangeproof, out.nValue, out.nAsset, out.nNonce, out.scriptPubKey, + blinding_pubkey_out, value_out, value_factor_out, asset_out, asset_factor_out); +} + +CAmount CWalletTx::GetOutputValueOut(unsigned int output_index) const { CAmount ret; - GetBlindingData(output_index, wit.vtxoutwit.size() <= output_index ? std::vector() : wit.vtxoutwit[output_index].vchRangeproof, out.nValue, out.nAsset, out.nNonce, out.scriptPubKey, nullptr, &ret, nullptr, nullptr, nullptr); + GetNonIssuanceBlindingData(output_index, nullptr, &ret, nullptr, nullptr, nullptr); return ret; } uint256 CWalletTx::GetOutputAmountBlindingFactor(unsigned int output_index) const { - assert(output_index < tx->vout.size()); - const CTxOut& out = tx->vout[output_index]; - const CTxWitness& wit = tx->witness; uint256 ret; - GetBlindingData(output_index, wit.vtxoutwit.size() <= output_index ? std::vector() : wit.vtxoutwit[output_index].vchRangeproof, out.nValue, out.nAsset, out.nNonce, out.scriptPubKey, nullptr, nullptr, &ret, nullptr, nullptr); + GetNonIssuanceBlindingData(output_index, nullptr, nullptr, &ret, nullptr, nullptr); return ret; } uint256 CWalletTx::GetOutputAssetBlindingFactor(unsigned int output_index) const { - assert(output_index < tx->vout.size()); - const CTxOut& out = tx->vout[output_index]; - const CTxWitness& wit = tx->witness; uint256 ret; - GetBlindingData(output_index, wit.vtxoutwit.size() <= output_index ? std::vector() : wit.vtxoutwit[output_index].vchRangeproof, out.nValue, out.nAsset, out.nNonce, out.scriptPubKey, nullptr, nullptr, nullptr, nullptr, &ret); + GetNonIssuanceBlindingData(output_index, nullptr, nullptr, nullptr, nullptr, &ret); return ret; } CAsset CWalletTx::GetOutputAsset(unsigned int output_index) const { - assert(output_index < tx->vout.size()); - const CTxOut& out = tx->vout[output_index]; - const CTxWitness& wit = tx->witness; CAsset ret; - GetBlindingData(output_index, wit.vtxoutwit.size() <= output_index ? std::vector() : wit.vtxoutwit[output_index].vchRangeproof, out.nValue, out.nAsset, out.nNonce, out.scriptPubKey, nullptr, nullptr, nullptr, &ret, nullptr); + GetNonIssuanceBlindingData(output_index, nullptr, nullptr, nullptr, &ret, nullptr); return ret; } CPubKey CWalletTx::GetOutputBlindingPubKey(unsigned int output_index) const { - assert(output_index < tx->vout.size()); - const CTxOut& out = tx->vout[output_index]; - const CTxWitness& wit = tx->witness; CPubKey ret; - GetBlindingData(output_index, wit.vtxoutwit.size() <= output_index ? std::vector() : wit.vtxoutwit[output_index].vchRangeproof, out.nValue, out.nAsset, out.nNonce, out.scriptPubKey, &ret, nullptr, nullptr, nullptr, nullptr); + GetNonIssuanceBlindingData(output_index, &ret, nullptr, nullptr, nullptr, nullptr); return ret; } diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 7fa912b20d..4262744a9a 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -573,6 +573,9 @@ class CWalletTx : public CMerkleTx // Unneeded for issuance. void SetBlindingData(const unsigned int output_index, const CPubKey& blinding_pubkey, const CAmount value, const uint256& value_factor, const CAsset& asset, const uint256& asset_factor); + // Convenience method to retrieve all blinding data at once, for an ordinary non-issuance tx + void GetNonIssuanceBlindingData(const unsigned int output_index, CPubKey* blinding_pubkey_out, CAmount* value_out, uint256* value_factor_out, CAsset* asset_out, uint256* asset_factor_out) const; + //! Returns either the value out (if it is known) or -1 CAmount GetOutputValueOut(unsigned int ouput_index) const; From 2848b520b2b169bc9e80a1b8198e3e5500004fa1 Mon Sep 17 00:00:00 2001 From: Glenn Willen Date: Wed, 1 May 2019 18:28:10 -0700 Subject: [PATCH 2/4] PSBT for Confidential Assets --- src/core_io.h | 4 - src/core_read.cpp | 27 -- src/core_write.cpp | 23 +- src/node/transaction.cpp | 6 + src/node/transaction.h | 3 + src/psbt.cpp | 77 ++++- src/psbt.h | 224 +++++++++++++ src/rpc/client.cpp | 2 + src/rpc/rawtransaction.cpp | 300 ++++++++++++++--- src/rpc/rawtransaction.h | 6 +- src/wallet/psbtwallet.cpp | 160 +++++++++- src/wallet/psbtwallet.h | 4 + src/wallet/rpcwallet.cpp | 158 ++++++--- src/wallet/rpcwallet.h | 1 + src/wallet/test/psbt_wallet_tests.cpp | 6 +- src/wallet/wallet.cpp | 4 +- test/functional/rpc_fundrawtransaction.py | 3 +- test/functional/rpc_psbt.py | 373 ++++++++++++++++++---- test/functional/test_runner.py | 3 +- test/lint/lint-spelling.ignore-words.txt | 1 + 20 files changed, 1162 insertions(+), 223 deletions(-) diff --git a/src/core_io.h b/src/core_io.h index 1227928a21..ab61f41e6a 100644 --- a/src/core_io.h +++ b/src/core_io.h @@ -39,10 +39,6 @@ bool DecodeHexBlockHeader(CBlockHeader&, const std::string& hex_header); bool ParseHashStr(const std::string& strHex, uint256& result); std::vector ParseHexUV(const UniValue& v, const std::string& strName); -//! Decode a base64ed PSBT into a PartiallySignedTransaction -NODISCARD bool DecodeBase64PSBT(PartiallySignedTransaction& decoded_psbt, const std::string& base64_psbt, std::string& error); -//! Decode a raw (binary blob) PSBT into a PartiallySignedTransaction -NODISCARD bool DecodeRawPSBT(PartiallySignedTransaction& decoded_psbt, const std::string& raw_psbt, std::string& error); int ParseSighashString(const UniValue& sighash); // core_write.cpp diff --git a/src/core_read.cpp b/src/core_read.cpp index 536a7f4f17..8dfb6c21a5 100644 --- a/src/core_read.cpp +++ b/src/core_read.cpp @@ -177,33 +177,6 @@ bool DecodeHexBlk(CBlock& block, const std::string& strHexBlk) return true; } -bool DecodeBase64PSBT(PartiallySignedTransaction& psbt, const std::string& base64_tx, std::string& error) -{ - bool invalid; - std::string tx_data = DecodeBase64(base64_tx, &invalid); - if (invalid) { - error = "invalid base64"; - return false; - } - return DecodeRawPSBT(psbt, tx_data, error); -} - -bool DecodeRawPSBT(PartiallySignedTransaction& psbt, const std::string& tx_data, std::string& error) -{ - CDataStream ss_data(tx_data.data(), tx_data.data() + tx_data.size(), SER_NETWORK, PROTOCOL_VERSION); - try { - ss_data >> psbt; - if (!ss_data.empty()) { - error = "extra data after PSBT"; - return false; - } - } catch (const std::exception& e) { - error = e.what(); - return false; - } - return true; -} - bool ParseHashStr(const std::string& strHex, uint256& result) { if ((strHex.size() != 64) || !IsHex(strHex)) diff --git a/src/core_write.cpp b/src/core_write.cpp index 8070e98db9..c9c3740a51 100644 --- a/src/core_write.cpp +++ b/src/core_write.cpp @@ -9,6 +9,7 @@ #include #include #include