Skip to content

Commit

Permalink
More CreateCoinStake work.
Browse files Browse the repository at this point in the history
  • Loading branch information
akyo8 committed Feb 24, 2021
1 parent 3483b88 commit f2c18c0
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 20 deletions.
5 changes: 3 additions & 2 deletions src/wallet/coinselection.cpp
Expand Up @@ -8,6 +8,7 @@
#include <policy/feerate.h>
#include <util/system.h>
#include <util/moneystr.h>
#include <wallet.h>

// Descending order comparator
struct {
Expand Down Expand Up @@ -62,7 +63,7 @@ struct {

static const size_t TOTAL_TRIES = 100000;

bool SelectCoinsBnB(std::vector<OutputGroup>& utxo_pool, const CAmount& target_value, const CAmount& cost_of_change, std::set<CInputCoin>& out_set, CAmount& value_ret, CAmount not_input_fees)
bool SelectCoinsBnB(std::vector<OutputGroup>& utxo_pool, const CAmount& target_value, const CAmount& cost_of_change, std::set<COutput>& out_set, CAmount& value_ret, CAmount not_input_fees)
{
out_set.clear();
CAmount curr_value = 0;
Expand Down Expand Up @@ -216,7 +217,7 @@ static void ApproximateBestSubset(const std::vector<OutputGroup>& groups, const
}
}

bool KnapsackSolver(const CAmount& nTargetValue, std::vector<OutputGroup>& groups, std::set<CInputCoin>& setCoinsRet, CAmount& nValueRet)
bool KnapsackSolver(const CAmount& nTargetValue, std::vector<OutputGroup>& groups, std::set<COutput>& setCoinsRet, CAmount& nValueRet)
{
setCoinsRet.clear();
nValueRet = 0;
Expand Down
21 changes: 13 additions & 8 deletions src/wallet/coinselection.h
Expand Up @@ -10,6 +10,7 @@
#include <random.h>

class CFeeRate;
class COutput;

//! target minimum change amount
static constexpr CAmount MIN_CHANGE{COIN / 100};
Expand Down Expand Up @@ -44,15 +45,18 @@ class CInputCoin {
/** Pre-computed estimated size of this output as a fully-signed input in a transaction. Can be -1 if it could not be calculated */
int m_input_bytes{-1};

bool operator<(const CInputCoin& rhs) const {
bool operator<(const COutput& rhs) const
{
return outpoint < rhs.outpoint;
}

bool operator!=(const CInputCoin& rhs) const {
bool operator!=(const COutput& rhs) const
{
return outpoint != rhs.outpoint;
}

bool operator==(const CInputCoin& rhs) const {
bool operator==(const COutput& rhs) const
{
return outpoint == rhs.outpoint;
}
};
Expand All @@ -70,7 +74,7 @@ struct CoinEligibilityFilter

struct OutputGroup
{
std::vector<CInputCoin> m_outputs;
std::vector<COutput> m_outputs;
bool m_from_me{true};
CAmount m_value{0};
int m_depth{999};
Expand All @@ -81,19 +85,20 @@ struct OutputGroup
CAmount long_term_fee{0};

OutputGroup() {}
OutputGroup(std::vector<CInputCoin>&& outputs, bool from_me, CAmount value, int depth, size_t ancestors, size_t descendants)
OutputGroup(std::vector<COutput>&& outputs, bool from_me, CAmount value, int depth, size_t ancestors, size_t descendants)
: m_outputs(std::move(outputs))
, m_from_me(from_me)
, m_value(value)
, m_depth(depth)
, m_ancestors(ancestors)
, m_descendants(descendants)
{}
OutputGroup(const CInputCoin& output, int depth, bool from_me, size_t ancestors, size_t descendants) : OutputGroup() {
OutputGroup(const COutput& output, int depth, bool from_me, size_t ancestors, size_t descendants) : OutputGroup()
{
Insert(output, depth, from_me, ancestors, descendants);
}
void Insert(const CInputCoin& output, int depth, bool from_me, size_t ancestors, size_t descendants);
std::vector<CInputCoin>::iterator Discard(const CInputCoin& output);
void Insert(const COutput& output, int depth, bool from_me, size_t ancestors, size_t descendants);
std::vector<COutput>::iterator Discard(const COutput& output);
bool EligibleForSpending(const CoinEligibilityFilter& eligibility_filter) const;

//! Update the OutputGroup's fee, long_term_fee, and effective_value based on the given feerates
Expand Down
14 changes: 7 additions & 7 deletions src/wallet/wallet.cpp
Expand Up @@ -401,7 +401,7 @@ void CWallet::CreateCoinStake(unsigned int nBits, int64_t nSearchInterval, CTran
CScript scriptPubKeyKernel;

for (const auto& entry : setCoins) {
uint256 hashPrevTx = entry.outpoint.hash;
uint256 hashPrevTx = entry.GetInputCoin().outpoint.hash;
uint256 hashPrevBlock;
CTransactionRef txPrev;

Expand Down Expand Up @@ -452,7 +452,7 @@ void CWallet::CreateCoinStake(unsigned int nBits, int64_t nSearchInterval, CTran
std::vector<valtype> vSolutions;
txnouttype whichType;
CScript scriptPubKeyOut;
scriptPubKeyKernel = entry.txout.scriptPubKey;
scriptPubKeyKernel = entry.GetInputCoin().txout.scriptPubKey;
if (!Solver(scriptPubKeyKernel, whichType, vSolutions)) {
if (gArgs.GetBoolArg("-printcoinstake", false))
printf("CreateCoinStake : failed to parse kernel\n");
Expand Down Expand Up @@ -483,7 +483,7 @@ void CWallet::CreateCoinStake(unsigned int nBits, int64_t nSearchInterval, CTran

mtx.nTime -= n;
mtx.vin.push_back(CTxIn(hashPrevTx, prevTxOffsetIndex));
nCredit += entry.txout.nValue;
nCredit += entry.GetInputCoin().txout.nValue;

// printf(">> Wallet: CreateCoinStake: nCredit = %"PRI64d"\n", nCredit);

Expand All @@ -508,22 +508,22 @@ void CWallet::CreateCoinStake(unsigned int nBits, int64_t nSearchInterval, CTran
}

for (const auto& entry : setCoins) {
uint256 hashPrevTx = entry.outpoint.hash;
uint256 hashPrevTx = entry.GetInputCoin().outpoint.hash;

// Attempt to add more inputs
// Only add coins of the same key/address as kernel
if (mtx.vout.size() == 2 && ((entry.txout.scriptPubKey == scriptPubKeyKernel || entry.txout.scriptPubKey == mtx.vout[1].scriptPubKey)) && entry.outpoint.hash != mtx.vin[0].prevout.hash) {
if (mtx.vout.size() == 2 && ((entry.GetInputCoin().txout.scriptPubKey == scriptPubKeyKernel || entry.GetInputCoin().txout.scriptPubKey == mtx.vout[1].scriptPubKey)) && entry.GetInputCoin().outpoint.hash != mtx.vin[0].prevout.hash) {
// Stop adding more inputs if already too many inputs
if (mtx.vin.size() >= 100)
break;
// Stop adding more inputs if value is already pretty significant
if (nCredit > nCombineThreshold)
break;
// Stop adding inputs if reached reserve limit
if (nCredit + entry.txout.nValue > nBalance - nReserveBalance)
if (nCredit + entry.GetInputCoin().txout.nValue > nBalance - nReserveBalance)
break;
// Do not add additional significant input
if (entry.txout.nValue > nCombineThreshold)
if (entry.GetInputCoin().txout.nValue > nCombineThreshold)
continue;
// Do not add input that is still too young
if (pcoin.first->nTime + nStakeMaxAge > mtx.nTime)
Expand Down
5 changes: 2 additions & 3 deletions src/wallet/wallet.h
Expand Up @@ -744,7 +744,7 @@ class CWallet final : public WalletStorage, public interfaces::Chain::Notificati
* all coins from coinControl are selected; Never select unconfirmed coins
* if they are not ours
*/
bool SelectCoins(const std::vector<COutput>& vAvailableCoins, const CAmount& nTargetValue, std::set<CInputCoin>& setCoinsRet, CAmount& nValueRet,
bool SelectCoins(const std::vector<COutput>& vAvailableCoins, const CAmount& nTargetValue, std::set<COutput>& setCoinsRet, CAmount& nValueRet,
const CCoinControl& coin_control, CoinSelectionParams& coin_selection_params, bool& bnb_used) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);

/** Get a name for this wallet for logging/debugging purposes.
Expand Down Expand Up @@ -822,8 +822,7 @@ class CWallet final : public WalletStorage, public interfaces::Chain::Notificati
* completion the coin set and corresponding actual target value is
* assembled
*/
bool SelectCoinsMinConf(const CAmount& nTargetValue, const CoinEligibilityFilter& eligibility_filter, std::vector<OutputGroup> groups,
std::set<CInputCoin>& setCoinsRet, CAmount& nValueRet, const CoinSelectionParams& coin_selection_params, bool& bnb_used) const;
bool SelectCoinsMinConf(const CAmount& nTargetValue, const CoinEligibilityFilter& eligibility_filter, std::vector<OutputGroup> groups, std::set<COutput>& setCoinsRet, CAmount& nValueRet, const CoinSelectionParams& coin_selection_params, bool& bnb_used) const;

bool IsSpent(const uint256& hash, unsigned int n) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);

Expand Down

0 comments on commit f2c18c0

Please sign in to comment.