Merge #13631: Add CMerkleTx::IsImmatureCoinBase method

23f4343781 Add CMerkleTx::IsImmatureCoinBase method (Ben Woosley)

Pull request description:

  All but one call to `GetBlocksToMaturity` is testing it relative to 0
  for the purposes of determining whether the coinbase tx is immature.
  In such case, the value greater than 0 implies that the tx is coinbase,
  so there is no need to separately test that status.

  This names the concept for easy singular use.

Tree-SHA512: 4470d07404a0707144f9827b9a94c5c4905f23ee6f9248edc5df599a59d28e21ea0201d8abe5d5d73b39cb05b60c861ea8e04767eef04433e2ee95dcfed653ee
This commit is contained in:
Wladimir J. van der Laan 2018-08-25 16:52:25 +02:00
commit 776fa60c4b
No known key found for this signature in database
GPG key ID: 1E4AED62986CD25D
3 changed files with 21 additions and 11 deletions

View file

@ -1851,7 +1851,7 @@ static void ListTransactions(CWallet* const pwallet, const CWalletTx& wtx, const
{ {
if (wtx.GetDepthInMainChain() < 1) if (wtx.GetDepthInMainChain() < 1)
entry.pushKV("category", "orphan"); entry.pushKV("category", "orphan");
else if (wtx.GetBlocksToMaturity() > 0) else if (wtx.IsImmatureCoinBase())
entry.pushKV("category", "immature"); entry.pushKV("category", "immature");
else else
entry.pushKV("category", "generate"); entry.pushKV("category", "generate");
@ -2147,7 +2147,7 @@ static UniValue listaccounts(const JSONRPCRequest& request)
std::list<COutputEntry> listReceived; std::list<COutputEntry> listReceived;
std::list<COutputEntry> listSent; std::list<COutputEntry> listSent;
int nDepth = wtx.GetDepthInMainChain(); int nDepth = wtx.GetDepthInMainChain();
if (wtx.GetBlocksToMaturity() > 0 || nDepth < 0) if (wtx.IsImmatureCoinBase() || nDepth < 0)
continue; continue;
wtx.GetAmounts(listReceived, listSent, nFee, strSentAccount, includeWatchonly); wtx.GetAmounts(listReceived, listSent, nFee, strSentAccount, includeWatchonly);
mapAccountBalances[strSentAccount] -= nFee; mapAccountBalances[strSentAccount] -= nFee;

View file

@ -1894,7 +1894,7 @@ CAmount CWalletTx::GetDebit(const isminefilter& filter) const
CAmount CWalletTx::GetCredit(const isminefilter& filter) const CAmount CWalletTx::GetCredit(const isminefilter& filter) const
{ {
// Must wait until coinbase is safely deep enough in the chain before valuing it // Must wait until coinbase is safely deep enough in the chain before valuing it
if (IsCoinBase() && GetBlocksToMaturity() > 0) if (IsImmatureCoinBase())
return 0; return 0;
CAmount credit = 0; CAmount credit = 0;
@ -1926,8 +1926,7 @@ CAmount CWalletTx::GetCredit(const isminefilter& filter) const
CAmount CWalletTx::GetImmatureCredit(bool fUseCache) const CAmount CWalletTx::GetImmatureCredit(bool fUseCache) const
{ {
if (IsCoinBase() && GetBlocksToMaturity() > 0 && IsInMainChain()) if (IsImmatureCoinBase() && IsInMainChain()) {
{
if (fUseCache && fImmatureCreditCached) if (fUseCache && fImmatureCreditCached)
return nImmatureCreditCached; return nImmatureCreditCached;
nImmatureCreditCached = pwallet->GetCredit(*tx, ISMINE_SPENDABLE); nImmatureCreditCached = pwallet->GetCredit(*tx, ISMINE_SPENDABLE);
@ -1944,7 +1943,7 @@ CAmount CWalletTx::GetAvailableCredit(bool fUseCache, const isminefilter& filter
return 0; return 0;
// Must wait until coinbase is safely deep enough in the chain before valuing it // Must wait until coinbase is safely deep enough in the chain before valuing it
if (IsCoinBase() && GetBlocksToMaturity() > 0) if (IsImmatureCoinBase())
return 0; return 0;
CAmount* cache = nullptr; CAmount* cache = nullptr;
@ -1985,8 +1984,7 @@ CAmount CWalletTx::GetAvailableCredit(bool fUseCache, const isminefilter& filter
CAmount CWalletTx::GetImmatureWatchOnlyCredit(const bool fUseCache) const CAmount CWalletTx::GetImmatureWatchOnlyCredit(const bool fUseCache) const
{ {
if (IsCoinBase() && GetBlocksToMaturity() > 0 && IsInMainChain()) if (IsImmatureCoinBase() && IsInMainChain()) {
{
if (fUseCache && fImmatureWatchCreditCached) if (fUseCache && fImmatureWatchCreditCached)
return nImmatureWatchCreditCached; return nImmatureWatchCreditCached;
nImmatureWatchCreditCached = pwallet->GetCredit(*tx, ISMINE_WATCH_ONLY); nImmatureWatchCreditCached = pwallet->GetCredit(*tx, ISMINE_WATCH_ONLY);
@ -2199,7 +2197,7 @@ CAmount CWallet::GetLegacyBalance(const isminefilter& filter, int minDepth, cons
for (const auto& entry : mapWallet) { for (const auto& entry : mapWallet) {
const CWalletTx& wtx = entry.second; const CWalletTx& wtx = entry.second;
const int depth = wtx.GetDepthInMainChain(); const int depth = wtx.GetDepthInMainChain();
if (depth < 0 || !CheckFinalTx(*wtx.tx) || wtx.GetBlocksToMaturity() > 0) { if (depth < 0 || !CheckFinalTx(*wtx.tx) || wtx.IsImmatureCoinBase()) {
continue; continue;
} }
@ -2259,7 +2257,7 @@ void CWallet::AvailableCoins(std::vector<COutput> &vCoins, bool fOnlySafe, const
if (!CheckFinalTx(*pcoin->tx)) if (!CheckFinalTx(*pcoin->tx))
continue; continue;
if (pcoin->IsCoinBase() && pcoin->GetBlocksToMaturity() > 0) if (pcoin->IsImmatureCoinBase())
continue; continue;
int nDepth = pcoin->GetDepthInMainChain(); int nDepth = pcoin->GetDepthInMainChain();
@ -3528,7 +3526,7 @@ std::map<CTxDestination, CAmount> CWallet::GetAddressBalances()
if (!pcoin->IsTrusted()) if (!pcoin->IsTrusted())
continue; continue;
if (pcoin->IsCoinBase() && pcoin->GetBlocksToMaturity() > 0) if (pcoin->IsImmatureCoinBase())
continue; continue;
int nDepth = pcoin->GetDepthInMainChain(); int nDepth = pcoin->GetDepthInMainChain();
@ -4406,6 +4404,11 @@ int CMerkleTx::GetBlocksToMaturity() const
return std::max(0, (COINBASE_MATURITY+1) - chain_depth); return std::max(0, (COINBASE_MATURITY+1) - chain_depth);
} }
bool CMerkleTx::IsImmatureCoinBase() const
{
// note GetBlocksToMaturity is 0 for non-coinbase tx
return GetBlocksToMaturity() > 0;
}
bool CWalletTx::AcceptToMemoryPool(const CAmount& nAbsurdFee, CValidationState& state) bool CWalletTx::AcceptToMemoryPool(const CAmount& nAbsurdFee, CValidationState& state)
{ {

View file

@ -266,6 +266,12 @@ public:
*/ */
int GetDepthInMainChain() const; int GetDepthInMainChain() const;
bool IsInMainChain() const { return GetDepthInMainChain() > 0; } bool IsInMainChain() const { return GetDepthInMainChain() > 0; }
/**
* @return number of blocks to maturity for this transaction:
* 0 : is not a coinbase transaction, or is a mature coinbase transaction
* >0 : is a coinbase transaction which matures in this many blocks
*/
int GetBlocksToMaturity() const; int GetBlocksToMaturity() const;
bool hashUnset() const { return (hashBlock.IsNull() || hashBlock == ABANDON_HASH); } bool hashUnset() const { return (hashBlock.IsNull() || hashBlock == ABANDON_HASH); }
bool isAbandoned() const { return (hashBlock == ABANDON_HASH); } bool isAbandoned() const { return (hashBlock == ABANDON_HASH); }
@ -273,6 +279,7 @@ public:
const uint256& GetHash() const { return tx->GetHash(); } const uint256& GetHash() const { return tx->GetHash(); }
bool IsCoinBase() const { return tx->IsCoinBase(); } bool IsCoinBase() const { return tx->IsCoinBase(); }
bool IsImmatureCoinBase() const;
}; };
//Get the marginal bytes of spending the specified output //Get the marginal bytes of spending the specified output