wallet: refactor, include 'FeeCalculation' inside 'CreatedTransactionResult'
This commit is contained in:
8 files changed
+15
-25
No files matched your search
@@ -220,8 +220,7 @@ Result CreateRateBumpTransaction(CWallet& wallet, const uint256& txid, const CCo
|
|||||||
|
|
||||||
constexpr int RANDOM_CHANGE_POSITION = -1;
|
constexpr int RANDOM_CHANGE_POSITION = -1;
|
||||||
bilingual_str fail_reason;
|
bilingual_str fail_reason;
|
||||||
FeeCalculation fee_calc_out;
|
std::optional<CreatedTransactionResult> txr = CreateTransaction(wallet, recipients, RANDOM_CHANGE_POSITION, fail_reason, new_coin_control, false);
|
||||||
std::optional<CreatedTransactionResult> txr = CreateTransaction(wallet, recipients, RANDOM_CHANGE_POSITION, fail_reason, new_coin_control, fee_calc_out, false);
|
|
||||||
if (!txr) {
|
if (!txr) {
|
||||||
errors.push_back(Untranslated("Unable to create transaction.") + Untranslated(" ") + fail_reason);
|
errors.push_back(Untranslated("Unable to create transaction.") + Untranslated(" ") + fail_reason);
|
||||||
return Result::WALLET_ERROR;
|
return Result::WALLET_ERROR;
|
||||||
|
|||||||
@@ -258,9 +258,8 @@ public:
|
|||||||
bilingual_str& fail_reason) override
|
bilingual_str& fail_reason) override
|
||||||
{
|
{
|
||||||
LOCK(m_wallet->cs_wallet);
|
LOCK(m_wallet->cs_wallet);
|
||||||
FeeCalculation fee_calc_out;
|
|
||||||
std::optional<CreatedTransactionResult> txr = CreateTransaction(*m_wallet, recipients, change_pos,
|
std::optional<CreatedTransactionResult> txr = CreateTransaction(*m_wallet, recipients, change_pos,
|
||||||
fail_reason, coin_control, fee_calc_out, sign);
|
fail_reason, coin_control, sign);
|
||||||
if (!txr) return {};
|
if (!txr) return {};
|
||||||
fee = txr->fee;
|
fee = txr->fee;
|
||||||
change_pos = txr->change_pos;
|
change_pos = txr->change_pos;
|
||||||
|
|||||||
@@ -157,8 +157,7 @@ UniValue SendMoney(CWallet& wallet, const CCoinControl &coin_control, std::vecto
|
|||||||
// Send
|
// Send
|
||||||
constexpr int RANDOM_CHANGE_POSITION = -1;
|
constexpr int RANDOM_CHANGE_POSITION = -1;
|
||||||
bilingual_str error;
|
bilingual_str error;
|
||||||
FeeCalculation fee_calc_out;
|
std::optional<CreatedTransactionResult> txr = CreateTransaction(wallet, recipients, RANDOM_CHANGE_POSITION, error, coin_control, true);
|
||||||
std::optional<CreatedTransactionResult> txr = CreateTransaction(wallet, recipients, RANDOM_CHANGE_POSITION, error, coin_control, fee_calc_out, true);
|
|
||||||
if (!txr) {
|
if (!txr) {
|
||||||
throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, error.original);
|
throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, error.original);
|
||||||
}
|
}
|
||||||
@@ -167,7 +166,7 @@ UniValue SendMoney(CWallet& wallet, const CCoinControl &coin_control, std::vecto
|
|||||||
if (verbose) {
|
if (verbose) {
|
||||||
UniValue entry(UniValue::VOBJ);
|
UniValue entry(UniValue::VOBJ);
|
||||||
entry.pushKV("txid", tx->GetHash().GetHex());
|
entry.pushKV("txid", tx->GetHash().GetHex());
|
||||||
entry.pushKV("fee_reason", StringForFeeReason(fee_calc_out.reason));
|
entry.pushKV("fee_reason", StringForFeeReason(txr->fee_calc.reason));
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
return tx->GetHash().GetHex();
|
return tx->GetHash().GetHex();
|
||||||
|
|||||||
@@ -662,7 +662,6 @@ static std::optional<CreatedTransactionResult> CreateTransactionInternal(
|
|||||||
int change_pos,
|
int change_pos,
|
||||||
bilingual_str& error,
|
bilingual_str& error,
|
||||||
const CCoinControl& coin_control,
|
const CCoinControl& coin_control,
|
||||||
FeeCalculation& fee_calc_out,
|
|
||||||
bool sign) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet)
|
bool sign) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet)
|
||||||
{
|
{
|
||||||
AssertLockHeld(wallet.cs_wallet);
|
AssertLockHeld(wallet.cs_wallet);
|
||||||
@@ -954,7 +953,6 @@ static std::optional<CreatedTransactionResult> CreateTransactionInternal(
|
|||||||
// Before we return success, we assume any change key will be used to prevent
|
// Before we return success, we assume any change key will be used to prevent
|
||||||
// accidental re-use.
|
// accidental re-use.
|
||||||
reservedest.KeepDestination();
|
reservedest.KeepDestination();
|
||||||
fee_calc_out = feeCalc;
|
|
||||||
|
|
||||||
wallet.WalletLogPrintf("Fee Calculation: Fee:%d Bytes:%u Tgt:%d (requested %d) Reason:\"%s\" Decay %.5f: Estimation: (%g - %g) %.2f%% %.1f/(%.1f %d mem %.1f out) Fail: (%g - %g) %.2f%% %.1f/(%.1f %d mem %.1f out)\n",
|
wallet.WalletLogPrintf("Fee Calculation: Fee:%d Bytes:%u Tgt:%d (requested %d) Reason:\"%s\" Decay %.5f: Estimation: (%g - %g) %.2f%% %.1f/(%.1f %d mem %.1f out) Fail: (%g - %g) %.2f%% %.1f/(%.1f %d mem %.1f out)\n",
|
||||||
nFeeRet, nBytes, feeCalc.returnedTarget, feeCalc.desiredTarget, StringForFeeReason(feeCalc.reason), feeCalc.est.decay,
|
nFeeRet, nBytes, feeCalc.returnedTarget, feeCalc.desiredTarget, StringForFeeReason(feeCalc.reason), feeCalc.est.decay,
|
||||||
@@ -964,7 +962,7 @@ static std::optional<CreatedTransactionResult> CreateTransactionInternal(
|
|||||||
feeCalc.est.fail.start, feeCalc.est.fail.end,
|
feeCalc.est.fail.start, feeCalc.est.fail.end,
|
||||||
(feeCalc.est.fail.totalConfirmed + feeCalc.est.fail.inMempool + feeCalc.est.fail.leftMempool) > 0.0 ? 100 * feeCalc.est.fail.withinTarget / (feeCalc.est.fail.totalConfirmed + feeCalc.est.fail.inMempool + feeCalc.est.fail.leftMempool) : 0.0,
|
(feeCalc.est.fail.totalConfirmed + feeCalc.est.fail.inMempool + feeCalc.est.fail.leftMempool) > 0.0 ? 100 * feeCalc.est.fail.withinTarget / (feeCalc.est.fail.totalConfirmed + feeCalc.est.fail.inMempool + feeCalc.est.fail.leftMempool) : 0.0,
|
||||||
feeCalc.est.fail.withinTarget, feeCalc.est.fail.totalConfirmed, feeCalc.est.fail.inMempool, feeCalc.est.fail.leftMempool);
|
feeCalc.est.fail.withinTarget, feeCalc.est.fail.totalConfirmed, feeCalc.est.fail.inMempool, feeCalc.est.fail.leftMempool);
|
||||||
return CreatedTransactionResult(tx, nFeeRet, nChangePosInOut);
|
return CreatedTransactionResult(tx, nFeeRet, nChangePosInOut, feeCalc);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<CreatedTransactionResult> CreateTransaction(
|
std::optional<CreatedTransactionResult> CreateTransaction(
|
||||||
@@ -973,7 +971,6 @@ std::optional<CreatedTransactionResult> CreateTransaction(
|
|||||||
int change_pos,
|
int change_pos,
|
||||||
bilingual_str& error,
|
bilingual_str& error,
|
||||||
const CCoinControl& coin_control,
|
const CCoinControl& coin_control,
|
||||||
FeeCalculation& fee_calc_out,
|
|
||||||
bool sign)
|
bool sign)
|
||||||
{
|
{
|
||||||
if (vecSend.empty()) {
|
if (vecSend.empty()) {
|
||||||
@@ -988,7 +985,7 @@ std::optional<CreatedTransactionResult> CreateTransaction(
|
|||||||
|
|
||||||
LOCK(wallet.cs_wallet);
|
LOCK(wallet.cs_wallet);
|
||||||
|
|
||||||
std::optional<CreatedTransactionResult> txr_ungrouped = CreateTransactionInternal(wallet, vecSend, change_pos, error, coin_control, fee_calc_out, sign);
|
std::optional<CreatedTransactionResult> txr_ungrouped = CreateTransactionInternal(wallet, vecSend, change_pos, error, coin_control, sign);
|
||||||
TRACE4(coin_selection, normal_create_tx_internal, wallet.GetName().c_str(), txr_ungrouped.has_value(),
|
TRACE4(coin_selection, normal_create_tx_internal, wallet.GetName().c_str(), txr_ungrouped.has_value(),
|
||||||
txr_ungrouped.has_value() ? txr_ungrouped->fee : 0, txr_ungrouped.has_value() ? txr_ungrouped->change_pos : 0);
|
txr_ungrouped.has_value() ? txr_ungrouped->fee : 0, txr_ungrouped.has_value() ? txr_ungrouped->change_pos : 0);
|
||||||
if (!txr_ungrouped) return std::nullopt;
|
if (!txr_ungrouped) return std::nullopt;
|
||||||
@@ -998,7 +995,7 @@ std::optional<CreatedTransactionResult> CreateTransaction(
|
|||||||
CCoinControl tmp_cc = coin_control;
|
CCoinControl tmp_cc = coin_control;
|
||||||
tmp_cc.m_avoid_partial_spends = true;
|
tmp_cc.m_avoid_partial_spends = true;
|
||||||
bilingual_str error2; // fired and forgotten; if an error occurs, we discard the results
|
bilingual_str error2; // fired and forgotten; if an error occurs, we discard the results
|
||||||
std::optional<CreatedTransactionResult> txr_grouped = CreateTransactionInternal(wallet, vecSend, change_pos, error2, tmp_cc, fee_calc_out, sign);
|
std::optional<CreatedTransactionResult> txr_grouped = CreateTransactionInternal(wallet, vecSend, change_pos, error2, tmp_cc, sign);
|
||||||
// if fee of this alternative one is within the range of the max fee, we use this one
|
// if fee of this alternative one is within the range of the max fee, we use this one
|
||||||
const bool use_aps{txr_grouped.has_value() ? (txr_grouped->fee <= txr_ungrouped->fee + wallet.m_max_aps_fee) : false};
|
const bool use_aps{txr_grouped.has_value() ? (txr_grouped->fee <= txr_ungrouped->fee + wallet.m_max_aps_fee) : false};
|
||||||
TRACE5(coin_selection, aps_create_tx_internal, wallet.GetName().c_str(), use_aps, txr_grouped.has_value(),
|
TRACE5(coin_selection, aps_create_tx_internal, wallet.GetName().c_str(), use_aps, txr_grouped.has_value(),
|
||||||
@@ -1045,8 +1042,7 @@ bool FundTransaction(CWallet& wallet, CMutableTransaction& tx, CAmount& nFeeRet,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FeeCalculation fee_calc_out;
|
std::optional<CreatedTransactionResult> txr = CreateTransaction(wallet, vecSend, nChangePosInOut, error, coinControl, false);
|
||||||
std::optional<CreatedTransactionResult> txr = CreateTransaction(wallet, vecSend, nChangePosInOut, error, coinControl, fee_calc_out, false);
|
|
||||||
if (!txr) return false;
|
if (!txr) return false;
|
||||||
CTransactionRef tx_new = txr->tx;
|
CTransactionRef tx_new = txr->tx;
|
||||||
nFeeRet = txr->fee;
|
nFeeRet = txr->fee;
|
||||||
|
|||||||
+5
-3
@@ -6,6 +6,7 @@
|
|||||||
#define BITCOIN_WALLET_SPEND_H
|
#define BITCOIN_WALLET_SPEND_H
|
||||||
|
|
||||||
#include <consensus/amount.h>
|
#include <consensus/amount.h>
|
||||||
|
#include <policy/fees.h> // for FeeCalculation
|
||||||
#include <wallet/coinselection.h>
|
#include <wallet/coinselection.h>
|
||||||
#include <wallet/transaction.h>
|
#include <wallet/transaction.h>
|
||||||
#include <wallet/wallet.h>
|
#include <wallet/wallet.h>
|
||||||
@@ -107,10 +108,11 @@ struct CreatedTransactionResult
|
|||||||
{
|
{
|
||||||
CTransactionRef tx;
|
CTransactionRef tx;
|
||||||
CAmount fee;
|
CAmount fee;
|
||||||
|
FeeCalculation fee_calc;
|
||||||
int change_pos;
|
int change_pos;
|
||||||
|
|
||||||
CreatedTransactionResult(CTransactionRef tx, CAmount fee, int change_pos)
|
CreatedTransactionResult(CTransactionRef _tx, CAmount _fee, int _change_pos, const FeeCalculation& _fee_calc)
|
||||||
: tx(tx), fee(fee), change_pos(change_pos) {}
|
: tx(_tx), fee(_fee), fee_calc(_fee_calc), change_pos(_change_pos) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -118,7 +120,7 @@ struct CreatedTransactionResult
|
|||||||
* selected by SelectCoins(); Also create the change output, when needed
|
* selected by SelectCoins(); Also create the change output, when needed
|
||||||
* @note passing change_pos as -1 will result in setting a random position
|
* @note passing change_pos as -1 will result in setting a random position
|
||||||
*/
|
*/
|
||||||
std::optional<CreatedTransactionResult> CreateTransaction(CWallet& wallet, const std::vector<CRecipient>& vecSend, int change_pos, bilingual_str& error, const CCoinControl& coin_control, FeeCalculation& fee_calc_out, bool sign = true);
|
std::optional<CreatedTransactionResult> CreateTransaction(CWallet& wallet, const std::vector<CRecipient>& vecSend, int change_pos, bilingual_str& error, const CCoinControl& coin_control, bool sign = true);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Insert additional inputs into the transaction by
|
* Insert additional inputs into the transaction by
|
||||||
|
|||||||
@@ -34,8 +34,7 @@ BOOST_FIXTURE_TEST_CASE(SubtractFee, TestChain100Setup)
|
|||||||
coin_control.fOverrideFeeRate = true;
|
coin_control.fOverrideFeeRate = true;
|
||||||
// We need to use a change type with high cost of change so that the leftover amount will be dropped to fee instead of added as a change output
|
// We need to use a change type with high cost of change so that the leftover amount will be dropped to fee instead of added as a change output
|
||||||
coin_control.m_change_type = OutputType::LEGACY;
|
coin_control.m_change_type = OutputType::LEGACY;
|
||||||
FeeCalculation fee_calc;
|
std::optional<CreatedTransactionResult> txr = CreateTransaction(*wallet, {recipient}, RANDOM_CHANGE_POSITION, error, coin_control);
|
||||||
std::optional<CreatedTransactionResult> txr = CreateTransaction(*wallet, {recipient}, RANDOM_CHANGE_POSITION, error, coin_control, fee_calc);
|
|
||||||
BOOST_CHECK(txr.has_value());
|
BOOST_CHECK(txr.has_value());
|
||||||
BOOST_CHECK_EQUAL(txr->tx->vout.size(), 1);
|
BOOST_CHECK_EQUAL(txr->tx->vout.size(), 1);
|
||||||
BOOST_CHECK_EQUAL(txr->tx->vout[0].nValue, recipient.nAmount + leftover_input_amount - txr->fee);
|
BOOST_CHECK_EQUAL(txr->tx->vout[0].nValue, recipient.nAmount + leftover_input_amount - txr->fee);
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
|
|
||||||
#include <wallet/wallet.h>
|
#include <wallet/wallet.h>
|
||||||
|
|
||||||
#include <any>
|
|
||||||
#include <future>
|
#include <future>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
@@ -13,7 +12,6 @@
|
|||||||
#include <interfaces/chain.h>
|
#include <interfaces/chain.h>
|
||||||
#include <key_io.h>
|
#include <key_io.h>
|
||||||
#include <node/blockstorage.h>
|
#include <node/blockstorage.h>
|
||||||
#include <node/context.h>
|
|
||||||
#include <policy/policy.h>
|
#include <policy/policy.h>
|
||||||
#include <rpc/server.h>
|
#include <rpc/server.h>
|
||||||
#include <test/util/logging.h>
|
#include <test/util/logging.h>
|
||||||
@@ -523,10 +521,9 @@ public:
|
|||||||
CTransactionRef tx;
|
CTransactionRef tx;
|
||||||
bilingual_str error;
|
bilingual_str error;
|
||||||
CCoinControl dummy;
|
CCoinControl dummy;
|
||||||
FeeCalculation fee_calc_out;
|
|
||||||
{
|
{
|
||||||
constexpr int RANDOM_CHANGE_POSITION = -1;
|
constexpr int RANDOM_CHANGE_POSITION = -1;
|
||||||
std::optional<CreatedTransactionResult> txr = CreateTransaction(*wallet, {recipient}, RANDOM_CHANGE_POSITION, error, dummy, fee_calc_out);
|
std::optional<CreatedTransactionResult> txr = CreateTransaction(*wallet, {recipient}, RANDOM_CHANGE_POSITION, error, dummy);
|
||||||
BOOST_CHECK(txr.has_value());
|
BOOST_CHECK(txr.has_value());
|
||||||
tx = txr->tx;
|
tx = txr->tx;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,7 +45,6 @@ using LoadWalletFn = std::function<void(std::unique_ptr<interfaces::Wallet> wall
|
|||||||
|
|
||||||
class CScript;
|
class CScript;
|
||||||
enum class FeeEstimateMode;
|
enum class FeeEstimateMode;
|
||||||
struct FeeCalculation;
|
|
||||||
struct bilingual_str;
|
struct bilingual_str;
|
||||||
|
|
||||||
namespace wallet {
|
namespace wallet {
|
||||||
|
|||||||
Reference in new issue
Block a user