mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-02-21 14:34:49 +01:00
wallet: Store whether a COutput is from the wallet
Instead of determining whether the containing transaction is from the wallet dynamically as needed, just pass it in to COutput and store it. The transaction ownership isn't going to change.
This commit is contained in:
parent
b799814bbd
commit
d51f27d3bb
4 changed files with 15 additions and 19 deletions
|
@ -58,7 +58,7 @@ static void CoinSelection(benchmark::Bench& bench)
|
||||||
// Create coins
|
// Create coins
|
||||||
std::vector<COutput> coins;
|
std::vector<COutput> coins;
|
||||||
for (const auto& wtx : wtxs) {
|
for (const auto& wtx : wtxs) {
|
||||||
coins.emplace_back(wallet, *wtx, /*iIn=*/ 0, /*depth=*/ 6 * 24, /*spendable=*/ true, /*solvable=*/ true, /*safe=*/ true, wtx->GetTxTime(), /*use_max_sig_in=*/ false);
|
coins.emplace_back(wallet, *wtx, /*iIn=*/ 0, /*depth=*/ 6 * 24, /*spendable=*/ true, /*solvable=*/ true, /*safe=*/ true, wtx->GetTxTime(), /*from_me=*/ true, /*use_max_sig_in=*/ false);
|
||||||
}
|
}
|
||||||
|
|
||||||
const CoinEligibilityFilter filter_standard(1, 6, 0);
|
const CoinEligibilityFilter filter_standard(1, 6, 0);
|
||||||
|
|
|
@ -158,6 +158,8 @@ void AvailableCoins(const CWallet& wallet, std::vector<COutput>& vCoins, const C
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool tx_from_me = CachedTxIsFromMe(wallet, wtx, ISMINE_ALL);
|
||||||
|
|
||||||
for (unsigned int i = 0; i < wtx.tx->vout.size(); i++) {
|
for (unsigned int i = 0; i < wtx.tx->vout.size(); i++) {
|
||||||
// Only consider selected coins if add_inputs is false
|
// Only consider selected coins if add_inputs is false
|
||||||
if (coinControl && !coinControl->m_add_inputs && !coinControl->IsSelected(COutPoint(entry.first, i))) {
|
if (coinControl && !coinControl->m_add_inputs && !coinControl->IsSelected(COutPoint(entry.first, i))) {
|
||||||
|
@ -191,7 +193,7 @@ void AvailableCoins(const CWallet& wallet, std::vector<COutput>& vCoins, const C
|
||||||
bool solvable = provider ? IsSolvable(*provider, wtx.tx->vout[i].scriptPubKey) : false;
|
bool solvable = provider ? IsSolvable(*provider, wtx.tx->vout[i].scriptPubKey) : false;
|
||||||
bool spendable = ((mine & ISMINE_SPENDABLE) != ISMINE_NO) || (((mine & ISMINE_WATCH_ONLY) != ISMINE_NO) && (coinControl && coinControl->fAllowWatchOnly && solvable));
|
bool spendable = ((mine & ISMINE_SPENDABLE) != ISMINE_NO) || (((mine & ISMINE_WATCH_ONLY) != ISMINE_NO) && (coinControl && coinControl->fAllowWatchOnly && solvable));
|
||||||
|
|
||||||
vCoins.emplace_back(wallet, wtx, i, nDepth, spendable, solvable, safeTx, wtx.GetTxTime(), /*use_max_sig_in=*/ (coinControl && coinControl->fAllowWatchOnly));
|
vCoins.emplace_back(wallet, wtx, i, nDepth, spendable, solvable, safeTx, wtx.GetTxTime(), tx_from_me, /*use_max_sig_in=*/ (coinControl && coinControl->fAllowWatchOnly));
|
||||||
|
|
||||||
// Checks the sum amount of all UTXO's.
|
// Checks the sum amount of all UTXO's.
|
||||||
if (nMinimumSumAmount != MAX_MONEY) {
|
if (nMinimumSumAmount != MAX_MONEY) {
|
||||||
|
@ -276,7 +278,7 @@ std::map<CTxDestination, std::vector<COutput>> ListCoins(const CWallet& wallet)
|
||||||
CTxDestination address;
|
CTxDestination address;
|
||||||
if (ExtractDestination(FindNonChangeParentOutput(wallet, *wtx.tx, output.n).scriptPubKey, address)) {
|
if (ExtractDestination(FindNonChangeParentOutput(wallet, *wtx.tx, output.n).scriptPubKey, address)) {
|
||||||
result[address].emplace_back(
|
result[address].emplace_back(
|
||||||
wallet, wtx, output.n, depth, /*spendable=*/ true, /*solvable=*/ true, /*safe=*/ false, wtx.GetTxTime(), /*use_max_sig_in=*/ false);
|
wallet, wtx, output.n, depth, /*spendable=*/ true, /*solvable=*/ true, /*safe=*/ false, wtx.GetTxTime(), CachedTxIsFromMe(wallet, wtx, ISMINE_ALL), /*use_max_sig_in=*/ false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -301,7 +303,7 @@ std::vector<OutputGroup> GroupOutputs(const CWallet& wallet, const std::vector<C
|
||||||
|
|
||||||
// Make an OutputGroup containing just this output
|
// Make an OutputGroup containing just this output
|
||||||
OutputGroup group{coin_sel_params};
|
OutputGroup group{coin_sel_params};
|
||||||
group.Insert(input_coin, output.depth, CachedTxIsFromMe(wallet, *output.tx, ISMINE_ALL), ancestors, descendants, positive_only);
|
group.Insert(input_coin, output.depth, output.from_me, ancestors, descendants, positive_only);
|
||||||
|
|
||||||
// Check the OutputGroup's eligibility. Only add the eligible ones.
|
// Check the OutputGroup's eligibility. Only add the eligible ones.
|
||||||
if (positive_only && group.GetSelectionAmount() <= 0) continue;
|
if (positive_only && group.GetSelectionAmount() <= 0) continue;
|
||||||
|
@ -346,7 +348,7 @@ std::vector<OutputGroup> GroupOutputs(const CWallet& wallet, const std::vector<C
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the input_coin to group
|
// Add the input_coin to group
|
||||||
group->Insert(input_coin, output.depth, CachedTxIsFromMe(wallet, *output.tx, ISMINE_ALL), ancestors, descendants, positive_only);
|
group->Insert(input_coin, output.depth, output.from_me, ancestors, descendants, positive_only);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now we go through the entire map and pull out the OutputGroups
|
// Now we go through the entire map and pull out the OutputGroups
|
||||||
|
|
|
@ -51,7 +51,10 @@ public:
|
||||||
/** The time of the transaction containing this output as determined by CWalletTx::nTimeSmart */
|
/** The time of the transaction containing this output as determined by CWalletTx::nTimeSmart */
|
||||||
int64_t time;
|
int64_t time;
|
||||||
|
|
||||||
COutput(const CWallet& wallet, const CWalletTx& wtx, int iIn, int depth, bool spendable, bool solvable, bool safe, int64_t time, bool use_max_sig_in)
|
/** Whether the transaction containing this output is sent from the owning wallet */
|
||||||
|
bool from_me;
|
||||||
|
|
||||||
|
COutput(const CWallet& wallet, const CWalletTx& wtx, int iIn, int depth, bool spendable, bool solvable, bool safe, int64_t time, bool from_me, bool use_max_sig_in)
|
||||||
: tx(&wtx),
|
: tx(&wtx),
|
||||||
i(iIn),
|
i(iIn),
|
||||||
depth(depth),
|
depth(depth),
|
||||||
|
@ -60,7 +63,8 @@ public:
|
||||||
solvable(solvable),
|
solvable(solvable),
|
||||||
use_max_sig(use_max_sig_in),
|
use_max_sig(use_max_sig_in),
|
||||||
safe(safe),
|
safe(safe),
|
||||||
time(time)
|
time(time),
|
||||||
|
from_me(from_me)
|
||||||
{
|
{
|
||||||
// If known and signable by the given wallet, compute input_bytes
|
// If known and signable by the given wallet, compute input_bytes
|
||||||
// Failure will keep this value -1
|
// Failure will keep this value -1
|
||||||
|
|
|
@ -82,23 +82,13 @@ static void add_coin(std::vector<COutput>& coins, CWallet& wallet, const CAmount
|
||||||
assert(destination_ok);
|
assert(destination_ok);
|
||||||
tx.vout[nInput].scriptPubKey = GetScriptForDestination(dest);
|
tx.vout[nInput].scriptPubKey = GetScriptForDestination(dest);
|
||||||
}
|
}
|
||||||
if (fIsFromMe) {
|
|
||||||
// IsFromMe() returns (GetDebit() > 0), and GetDebit() is 0 if vin.empty(),
|
|
||||||
// so stop vin being empty, and cache a non-zero Debit to fake out IsFromMe()
|
|
||||||
tx.vin.resize(1);
|
|
||||||
}
|
|
||||||
uint256 txid = tx.GetHash();
|
uint256 txid = tx.GetHash();
|
||||||
|
|
||||||
LOCK(wallet.cs_wallet);
|
LOCK(wallet.cs_wallet);
|
||||||
auto ret = wallet.mapWallet.emplace(std::piecewise_construct, std::forward_as_tuple(txid), std::forward_as_tuple(MakeTransactionRef(std::move(tx)), TxStateInactive{}));
|
auto ret = wallet.mapWallet.emplace(std::piecewise_construct, std::forward_as_tuple(txid), std::forward_as_tuple(MakeTransactionRef(std::move(tx)), TxStateInactive{}));
|
||||||
assert(ret.second);
|
assert(ret.second);
|
||||||
CWalletTx& wtx = (*ret.first).second;
|
CWalletTx& wtx = (*ret.first).second;
|
||||||
if (fIsFromMe)
|
coins.emplace_back(wallet, wtx, nInput, nAge, /*spendable=*/ true, /*solvable=*/ true, /*safe=*/ true, wtx.GetTxTime(), fIsFromMe, /*use_max_sig_in=*/ false);
|
||||||
{
|
|
||||||
wtx.m_amounts[CWalletTx::DEBIT].Set(ISMINE_SPENDABLE, 1);
|
|
||||||
wtx.m_is_cache_empty = false;
|
|
||||||
}
|
|
||||||
coins.emplace_back(wallet, wtx, nInput, nAge, /*spendable=*/ true, /*solvable=*/ true, /*safe=*/ true, wtx.GetTxTime(), /*use_max_sig_in=*/ false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Check if SelectionResult a is equivalent to SelectionResult b.
|
/** Check if SelectionResult a is equivalent to SelectionResult b.
|
||||||
|
@ -156,7 +146,7 @@ inline std::vector<OutputGroup>& GroupCoins(const std::vector<COutput>& coins)
|
||||||
static_groups.clear();
|
static_groups.clear();
|
||||||
for (auto& coin : coins) {
|
for (auto& coin : coins) {
|
||||||
static_groups.emplace_back();
|
static_groups.emplace_back();
|
||||||
static_groups.back().Insert(coin.GetInputCoin(), coin.depth, coin.tx->m_amounts[CWalletTx::DEBIT].m_cached[ISMINE_SPENDABLE] && coin.tx->m_amounts[CWalletTx::DEBIT].m_value[ISMINE_SPENDABLE] == 1 /* HACK: we can't figure out the is_me flag so we use the conditions defined above; perhaps set safe to false for !fIsFromMe in add_coin() */, 0, 0, false);
|
static_groups.back().Insert(coin.GetInputCoin(), coin.depth, coin.from_me, 0, 0, false);
|
||||||
}
|
}
|
||||||
return static_groups;
|
return static_groups;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue