diff --git a/src/interfaces/wallet.h b/src/interfaces/wallet.h index e2998c515d..b2bd6955ab 100644 --- a/src/interfaces/wallet.h +++ b/src/interfaces/wallet.h @@ -36,6 +36,7 @@ struct PartiallySignedTransaction; struct WalletContext; struct bilingual_str; typedef uint8_t isminefilter; +struct BlindDetails; namespace interfaces { @@ -140,13 +141,14 @@ class Wallet bool sign, int& change_pos, CAmount& fee, - std::vector& out_amounts, + BlindDetails* blind_details, bilingual_str& fail_reason) = 0; //! Commit transaction. virtual void commitTransaction(CTransactionRef tx, WalletValueMap value_map, - WalletOrderForm order_form) = 0; + WalletOrderForm order_form, + BlindDetails* blind_details) = 0; //! Return whether transaction can be abandoned. virtual bool transactionCanBeAbandoned(const uint256& txid) = 0; diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index 4a38acf46d..5180e66e8d 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -281,11 +281,13 @@ bool SendCoinsDialog::PrepareSendText(QString& question_string, QString& informa // prepare transaction for getting txFee earlier m_current_transaction = std::make_unique(recipients); + if (g_con_elementsmode) + m_current_blind_details = std::make_unique(); WalletModel::SendCoinsReturn prepareStatus; updateCoinControlState(); - prepareStatus = model->prepareTransaction(*m_current_transaction, *m_coin_control); + prepareStatus = model->prepareTransaction(*m_current_transaction, m_current_blind_details.get(), *m_coin_control); // process prepareStatus and on error generate message shown to user processSendCoinsReturn(prepareStatus, @@ -403,6 +405,7 @@ void SendCoinsDialog::sendButtonClicked([[maybe_unused]] bool checked) QString question_string, informative_text, detailed_text; if (!PrepareSendText(question_string, informative_text, detailed_text)) return; assert(m_current_transaction); + assert(!g_con_elementsmode || m_current_blind_details); const QString confirmation = model->wallet().privateKeysDisabled() && !model->wallet().hasExternalSigner() ? tr("Confirm transaction proposal") : tr("Confirm send coins"); const QString confirmButtonText = model->wallet().privateKeysDisabled() && !model->wallet().hasExternalSigner() ? tr("Create Unsigned") : tr("Sign and send"); @@ -461,7 +464,7 @@ void SendCoinsDialog::sendButtonClicked([[maybe_unused]] bool checked) if (complete) { const CTransactionRef tx = MakeTransactionRef(mtx); m_current_transaction->setWtx(tx); - WalletModel::SendCoinsReturn sendStatus = model->sendCoins(*m_current_transaction); + WalletModel::SendCoinsReturn sendStatus = model->sendCoins(*m_current_transaction, m_current_blind_details.get()); // process sendStatus and on error generate message shown to user processSendCoinsReturn(sendStatus); @@ -520,7 +523,7 @@ void SendCoinsDialog::sendButtonClicked([[maybe_unused]] bool checked) } // msgBox.exec() } else { // now send the prepared transaction - WalletModel::SendCoinsReturn sendStatus = model->sendCoins(*m_current_transaction); + WalletModel::SendCoinsReturn sendStatus = model->sendCoins(*m_current_transaction, m_current_blind_details.get()); // process sendStatus and on error generate message shown to user processSendCoinsReturn(sendStatus); @@ -537,11 +540,13 @@ void SendCoinsDialog::sendButtonClicked([[maybe_unused]] bool checked) } fNewRecipientAllowed = true; m_current_transaction.reset(); + m_current_blind_details.reset(); } void SendCoinsDialog::clear() { m_current_transaction.reset(); + m_current_blind_details.reset(); // Clear coin control settings m_coin_control->UnSelectAll(); diff --git a/src/qt/sendcoinsdialog.h b/src/qt/sendcoinsdialog.h index 33736f8095..d3dcbfa28c 100644 --- a/src/qt/sendcoinsdialog.h +++ b/src/qt/sendcoinsdialog.h @@ -64,6 +64,7 @@ public Q_SLOTS: WalletModel *model; std::unique_ptr m_coin_control; std::unique_ptr m_current_transaction; + std::unique_ptr m_current_blind_details; bool fNewRecipientAllowed; bool fFeeMinimized; const PlatformStyle *platformStyle; diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index d784dfb1a9..7353a07c5f 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -176,7 +176,7 @@ bool WalletModel::validateAddress(const QString &address) return IsValidDestinationString(address.toStdString()); } -WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransaction &transaction, const CCoinControl& coinControl) +WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransaction &transaction, BlindDetails *blind_details, const CCoinControl& coinControl) { CAmountMap total; bool fSubtractFeeFromAmount = false; @@ -236,10 +236,13 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact auto& newTx = transaction.getWtx(); std::vector out_amounts; - newTx = m_wallet->createTransaction(vecSend, coinControl, !wallet().privateKeysDisabled() /* sign */, nChangePosRet, nFeeRequired, out_amounts, error); + newTx = m_wallet->createTransaction(vecSend, coinControl, !wallet().privateKeysDisabled() /* sign */, nChangePosRet, nFeeRequired, blind_details, error); transaction.setTransactionFee(nFeeRequired); if (fSubtractFeeFromAmount && newTx) { - assert(out_amounts.size() == newTx->vout.size()); + if(blind_details) { + out_amounts = blind_details->o_amounts; + assert(out_amounts.size() == newTx->vout.size()); + } transaction.reassignAmounts(out_amounts, nChangePosRet); } @@ -266,7 +269,7 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact return SendCoinsReturn(OK); } -WalletModel::SendCoinsReturn WalletModel::sendCoins(WalletModelTransaction &transaction) +WalletModel::SendCoinsReturn WalletModel::sendCoins(WalletModelTransaction &transaction, BlindDetails *blind_details) { QByteArray transaction_array; /* store serialized transaction */ @@ -279,7 +282,7 @@ WalletModel::SendCoinsReturn WalletModel::sendCoins(WalletModelTransaction &tran } auto& newTx = transaction.getWtx(); - wallet().commitTransaction(newTx, {} /* mapValue */, std::move(vOrderForm)); + wallet().commitTransaction(newTx, {} /* mapValue */, std::move(vOrderForm), blind_details); CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); ssTx << *newTx; diff --git a/src/qt/walletmodel.h b/src/qt/walletmodel.h index e76735ea62..efb89a1d95 100644 --- a/src/qt/walletmodel.h +++ b/src/qt/walletmodel.h @@ -100,10 +100,10 @@ class WalletModel : public QObject }; // prepare transaction for getting txfee before sending coins - SendCoinsReturn prepareTransaction(WalletModelTransaction &transaction, const CCoinControl& coinControl); + SendCoinsReturn prepareTransaction(WalletModelTransaction &transaction, BlindDetails *blind_details, const CCoinControl& coinControl); // Send coins to a list of recipients - SendCoinsReturn sendCoins(WalletModelTransaction &transaction); + SendCoinsReturn sendCoins(WalletModelTransaction &transaction, BlindDetails *blind_details); // Wallet encryption bool setWalletEncrypted(const SecureString& passphrase); diff --git a/src/wallet/interfaces.cpp b/src/wallet/interfaces.cpp index fbf9e8da8e..c67efcefb1 100644 --- a/src/wallet/interfaces.cpp +++ b/src/wallet/interfaces.cpp @@ -248,26 +248,25 @@ class WalletImpl : public Wallet bool sign, int& change_pos, CAmount& fee, - std::vector& out_amounts, + BlindDetails* blind_details, bilingual_str& fail_reason) override { LOCK(m_wallet->cs_wallet); CTransactionRef tx; FeeCalculation fee_calc_out; - BlindDetails blind_details; if (!m_wallet->CreateTransaction(recipients, tx, fee, change_pos, - fail_reason, coin_control, fee_calc_out, sign, gArgs.GetBoolArg("-blindedaddresses", g_con_elementsmode) ? &blind_details : nullptr)) { + fail_reason, coin_control, fee_calc_out, sign, blind_details)) { return {}; } - out_amounts = blind_details.o_amounts; return tx; } void commitTransaction(CTransactionRef tx, WalletValueMap value_map, - WalletOrderForm order_form) override + WalletOrderForm order_form, + BlindDetails* blind_details) override { LOCK(m_wallet->cs_wallet); - m_wallet->CommitTransaction(std::move(tx), std::move(value_map), std::move(order_form)); + m_wallet->CommitTransaction(std::move(tx), std::move(value_map), std::move(order_form), blind_details); } bool transactionCanBeAbandoned(const uint256& txid) override { return m_wallet->TransactionCanBeAbandoned(txid); } bool abandonTransaction(const uint256& txid) override