diff options
Diffstat (limited to 'src/wallet/wallet.cpp')
-rw-r--r-- | src/wallet/wallet.cpp | 58 |
1 files changed, 42 insertions, 16 deletions
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 30b9869be0..2cbb89e5a8 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1034,7 +1034,8 @@ void CWalletTx::GetAmounts(list<COutputEntry>& listReceived, // In either case, we need to get the destination address CTxDestination address; - if (!ExtractDestination(txout.scriptPubKey, address)) + + if (!ExtractDestination(txout.scriptPubKey, address) && !txout.scriptPubKey.IsUnspendable()) { LogPrintf("CWalletTx::GetAmounts: Unknown transaction type found, txid %s\n", this->GetHash().ToString()); @@ -1359,6 +1360,15 @@ CAmount CWalletTx::GetChange() const return nChangeCached; } +bool CWalletTx::InMempool() const +{ + LOCK(mempool.cs); + if (mempool.exists(GetHash())) { + return true; + } + return false; +} + bool CWalletTx::IsTrusted() const { // Quick answer in most cases @@ -1373,12 +1383,8 @@ bool CWalletTx::IsTrusted() const return false; // Don't trust unconfirmed transactions from us unless they are in the mempool. - { - LOCK(mempool.cs); - if (!mempool.exists(GetHash())) { - return false; - } - } + if (!InMempool()) + return false; // Trusted if all inputs are from us and are in the mempool: BOOST_FOREACH(const CTxIn& txin, vin) @@ -1632,6 +1638,16 @@ static void ApproximateBestSubset(vector<pair<CAmount, pair<const CWalletTx*,uns } } } + + //Reduces the approximate best subset by removing any inputs that are smaller than the surplus of nTotal beyond nTargetValue. + for (unsigned int i = 0; i < vValue.size(); i++) + { + if (vfBest[i] && (nBest - vValue[i].first) >= nTargetValue ) + { + vfBest[i] = false; + nBest -= vValue[i].first; + } + } } bool CWallet::SelectCoinsMinConf(const CAmount& nTargetValue, int nConfMine, int nConfTheirs, vector<COutput> vCoins, @@ -1871,15 +1887,25 @@ bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend, CWalletTx& wt // Discourage fee sniping. // - // However because of a off-by-one-error in previous versions we need to - // neuter it by setting nLockTime to at least one less than nBestHeight. - // Secondly currently propagation of transactions created for block heights - // corresponding to blocks that were just mined may be iffy - transactions - // aren't re-accepted into the mempool - we additionally neuter the code by - // going ten blocks back. Doesn't yet do anything for sniping, but does act - // to shake out wallet bugs like not showing nLockTime'd transactions at - // all. - txNew.nLockTime = std::max(0, chainActive.Height() - 10); + // For a large miner the value of the transactions in the best block and + // the mempool can exceed the cost of deliberately attempting to mine two + // blocks to orphan the current best block. By setting nLockTime such that + // only the next block can include the transaction, we discourage this + // practice as the height restricted and limited blocksize gives miners + // considering fee sniping fewer options for pulling off this attack. + // + // A simple way to think about this is from the wallet's point of view we + // always want the blockchain to move forward. By setting nLockTime this + // way we're basically making the statement that we only want this + // transaction to appear in the next block; we don't want to potentially + // encourage reorgs by allowing transactions to appear at lower heights + // than the next block in forks of the best chain. + // + // Of course, the subsidy is high enough, and transaction volume low + // enough, that fee sniping isn't a problem yet, but by implementing a fix + // now we ensure code won't be written that makes assumptions about + // nLockTime that preclude a fix later. + txNew.nLockTime = chainActive.Height(); // Secondly occasionally randomly pick a nLockTime even further back, so // that transactions that are delayed after signing for whatever reason, |