mirror of
https://github.com/dashpay/dash.git
synced 2024-12-26 12:32:48 +01:00
Refactor and fix GetRealOutpointPrivateSendRounds (#3460)
* Refactor and fix GetRealOutpointPrivateSendRounds Changes: - streamline logic - use much more compact/direct map to store outpoint rounds - per-wallet map instead of a static one - hold cs_wallet * Bail out early if one of outputs in the same tx is a non-denom one
This commit is contained in:
parent
c06838e205
commit
d5f403d3fd
@ -1576,61 +1576,60 @@ CAmount CWallet::GetDebit(const CTxIn &txin, const isminefilter& filter) const
|
|||||||
// Recursively determine the rounds of a given input (How deep is the PrivateSend chain for a given input)
|
// Recursively determine the rounds of a given input (How deep is the PrivateSend chain for a given input)
|
||||||
int CWallet::GetRealOutpointPrivateSendRounds(const COutPoint& outpoint, int nRounds) const
|
int CWallet::GetRealOutpointPrivateSendRounds(const COutPoint& outpoint, int nRounds) const
|
||||||
{
|
{
|
||||||
static std::map<uint256, CMutableTransaction> mDenomWtxes;
|
LOCK(cs_wallet);
|
||||||
|
|
||||||
if(nRounds >= MAX_PRIVATESEND_ROUNDS) {
|
if (nRounds >= MAX_PRIVATESEND_ROUNDS) {
|
||||||
// there can only be MAX_PRIVATESEND_ROUNDS rounds max
|
// there can only be MAX_PRIVATESEND_ROUNDS rounds max
|
||||||
return MAX_PRIVATESEND_ROUNDS - 1;
|
return MAX_PRIVATESEND_ROUNDS - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint256 hash = outpoint.hash;
|
auto pair = mapOutpointRoundsCache.emplace(outpoint, -10);
|
||||||
unsigned int nout = outpoint.n;
|
auto nRoundsRef = &pair.first->second;
|
||||||
|
if (!pair.second) {
|
||||||
|
// we already processed it, just return what we have
|
||||||
|
return *nRoundsRef;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO wtx should refer to a CWalletTx object, not a pointer, based on surrounding code
|
// TODO wtx should refer to a CWalletTx object, not a pointer, based on surrounding code
|
||||||
const CWalletTx* wtx = GetWalletTx(hash);
|
const CWalletTx* wtx = GetWalletTx(outpoint.hash);
|
||||||
if(wtx != nullptr)
|
|
||||||
{
|
|
||||||
std::map<uint256, CMutableTransaction>::const_iterator mdwi = mDenomWtxes.find(hash);
|
|
||||||
if (mdwi == mDenomWtxes.end()) {
|
|
||||||
// not known yet, let's add it
|
|
||||||
LogPrint(BCLog::PRIVATESEND, "GetRealOutpointPrivateSendRounds INSERTING %s\n", hash.ToString());
|
|
||||||
mDenomWtxes[hash] = CMutableTransaction(*wtx->tx);
|
|
||||||
} else if(mDenomWtxes[hash].vout[nout].nRounds != -10) {
|
|
||||||
// found and it's not an initial value, just return it
|
|
||||||
return mDenomWtxes[hash].vout[nout].nRounds;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (wtx == nullptr || wtx->tx == nullptr) {
|
||||||
|
// no such tx in this wallet
|
||||||
|
*nRoundsRef = -1;
|
||||||
|
LogPrint(BCLog::PRIVATESEND, "%s FAILED %-70s %3d\n", __func__, outpoint.ToStringShort(), -1);
|
||||||
|
return *nRoundsRef;
|
||||||
|
}
|
||||||
|
|
||||||
// bounds check
|
// bounds check
|
||||||
if (nout >= wtx->tx->vout.size()) {
|
if (outpoint.n >= wtx->tx->vout.size()) {
|
||||||
// should never actually hit this
|
// should never actually hit this
|
||||||
LogPrint(BCLog::PRIVATESEND, "GetRealOutpointPrivateSendRounds UPDATED %s %3d %3d\n", hash.ToString(), nout, -4);
|
*nRoundsRef = -4;
|
||||||
return -4;
|
LogPrint(BCLog::PRIVATESEND, "%s FAILED %-70s %3d\n", __func__, outpoint.ToStringShort(), -4);
|
||||||
|
return *nRoundsRef;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CPrivateSend::IsCollateralAmount(wtx->tx->vout[nout].nValue)) {
|
auto txOutRef = &wtx->tx->vout[outpoint.n];
|
||||||
mDenomWtxes[hash].vout[nout].nRounds = -3;
|
|
||||||
LogPrint(BCLog::PRIVATESEND, "GetRealOutpointPrivateSendRounds UPDATED %s %3d %3d\n", hash.ToString(), nout, mDenomWtxes[hash].vout[nout].nRounds);
|
if (CPrivateSend::IsCollateralAmount(txOutRef->nValue)) {
|
||||||
return mDenomWtxes[hash].vout[nout].nRounds;
|
*nRoundsRef = -3;
|
||||||
|
LogPrint(BCLog::PRIVATESEND, "%s UPDATED %-70s %3d\n", __func__, outpoint.ToStringShort(), *nRoundsRef);
|
||||||
|
return *nRoundsRef;
|
||||||
}
|
}
|
||||||
|
|
||||||
//make sure the final output is non-denominate
|
// make sure the final output is non-denominate
|
||||||
if (!CPrivateSend::IsDenominatedAmount(wtx->tx->vout[nout].nValue)) { //NOT DENOM
|
if (!CPrivateSend::IsDenominatedAmount(txOutRef->nValue)) { //NOT DENOM
|
||||||
mDenomWtxes[hash].vout[nout].nRounds = -2;
|
*nRoundsRef = -2;
|
||||||
LogPrint(BCLog::PRIVATESEND, "GetRealOutpointPrivateSendRounds UPDATED %s %3d %3d\n", hash.ToString(), nout, mDenomWtxes[hash].vout[nout].nRounds);
|
LogPrint(BCLog::PRIVATESEND, "%s UPDATED %-70s %3d\n", __func__, outpoint.ToStringShort(), *nRoundsRef);
|
||||||
return mDenomWtxes[hash].vout[nout].nRounds;
|
return *nRoundsRef;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool fAllDenoms = true;
|
|
||||||
for (const auto& out : wtx->tx->vout) {
|
for (const auto& out : wtx->tx->vout) {
|
||||||
fAllDenoms = fAllDenoms && CPrivateSend::IsDenominatedAmount(out.nValue);
|
if (!CPrivateSend::IsDenominatedAmount(out.nValue)) {
|
||||||
}
|
|
||||||
|
|
||||||
// this one is denominated but there is another non-denominated output found in the same tx
|
// this one is denominated but there is another non-denominated output found in the same tx
|
||||||
if (!fAllDenoms) {
|
*nRoundsRef = 0;
|
||||||
mDenomWtxes[hash].vout[nout].nRounds = 0;
|
LogPrint(BCLog::PRIVATESEND, "%s UPDATED %-70s %3d\n", __func__, outpoint.ToStringShort(), *nRoundsRef);
|
||||||
LogPrint(BCLog::PRIVATESEND, "GetRealOutpointPrivateSendRounds UPDATED %s %3d %3d\n", hash.ToString(), nout, mDenomWtxes[hash].vout[nout].nRounds);
|
return *nRoundsRef;
|
||||||
return mDenomWtxes[hash].vout[nout].nRounds;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int nShortest = -10; // an initial value, should be no way to get this by calculations
|
int nShortest = -10; // an initial value, should be no way to get this by calculations
|
||||||
@ -1646,14 +1645,11 @@ int CWallet::GetRealOutpointPrivateSendRounds(const COutPoint& outpoint, int nRo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mDenomWtxes[hash].vout[nout].nRounds = fDenomFound
|
*nRoundsRef = fDenomFound
|
||||||
? (nShortest >= MAX_PRIVATESEND_ROUNDS - 1 ? MAX_PRIVATESEND_ROUNDS : nShortest + 1) // good, we a +1 to the shortest one but only MAX_PRIVATESEND_ROUNDS rounds max allowed
|
? (nShortest >= MAX_PRIVATESEND_ROUNDS - 1 ? MAX_PRIVATESEND_ROUNDS : nShortest + 1) // good, we a +1 to the shortest one but only MAX_PRIVATESEND_ROUNDS rounds max allowed
|
||||||
: 0; // too bad, we are the fist one in that chain
|
: 0; // too bad, we are the fist one in that chain
|
||||||
LogPrint(BCLog::PRIVATESEND, "GetRealOutpointPrivateSendRounds UPDATED %s %3d %3d\n", hash.ToString(), nout, mDenomWtxes[hash].vout[nout].nRounds);
|
LogPrint(BCLog::PRIVATESEND, "%s UPDATED %-70s %3d\n", __func__, outpoint.ToStringShort(), *nRoundsRef);
|
||||||
return mDenomWtxes[hash].vout[nout].nRounds;
|
return *nRoundsRef;
|
||||||
}
|
|
||||||
|
|
||||||
return nRounds - 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// respect current settings
|
// respect current settings
|
||||||
|
@ -747,6 +747,7 @@ private:
|
|||||||
void AddToSpends(const uint256& wtxid);
|
void AddToSpends(const uint256& wtxid);
|
||||||
|
|
||||||
std::set<COutPoint> setWalletUTXO;
|
std::set<COutPoint> setWalletUTXO;
|
||||||
|
mutable std::map<COutPoint, int> mapOutpointRoundsCache;
|
||||||
|
|
||||||
/* Mark a transaction (and its in-wallet descendants) as conflicting with a particular block. */
|
/* Mark a transaction (and its in-wallet descendants) as conflicting with a particular block. */
|
||||||
void MarkConflicted(const uint256& hashBlock, const uint256& hashTx);
|
void MarkConflicted(const uint256& hashBlock, const uint256& hashTx);
|
||||||
|
Loading…
Reference in New Issue
Block a user