Mercurial > hg > bitcoin
changeset 459:91b031e90a14 draft
Fix minimum transaction fee calculation mismatch between CreateTransaction and CreateBlock
author | Gavin Andresen <gavinandresen@gmail.com> |
---|---|
date | Wed, 02 Mar 2011 16:27:24 -0500 |
parents | 39f8c9430b2d |
children | d03afafd281a |
files | main.cpp main.h |
diffstat | 2 files changed, 36 insertions(+), 16 deletions(-) [+] |
line wrap: on
line diff
--- a/main.cpp +++ b/main.cpp @@ -287,7 +287,7 @@ ////////////////////////////////////////////////////////////////////////////// // -// CTransaction +// CTransaction and CTxIndex // bool CTransaction::ReadFromDisk(CTxDB& txdb, COutPoint prevout, CTxIndex& txindexRet) @@ -1034,6 +1034,22 @@ } } +int CTxIndex::GetDepthInMainChain() const +{ + // Read block header + CBlock block; + if (!block.ReadFromDisk(pos.nFile, pos.nBlockPos, false)) + return 0; + // Find the block in the index + map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(block.GetHash()); + if (mi == mapBlockIndex.end()) + return 0; + CBlockIndex* pindex = (*mi).second; + if (!pindex || !pindex->IsInMainChain()) + return 0; + return 1 + nBestHeight - pindex->nHeight; +} + @@ -3327,18 +3343,7 @@ int64 nValueIn = txPrev.vout[txin.prevout.n].nValue; // Read block header - int nConf = 0; - CBlock block; - if (block.ReadFromDisk(txindex.pos.nFile, txindex.pos.nBlockPos, false)) - { - map<uint256, CBlockIndex*>::iterator it = mapBlockIndex.find(block.GetHash()); - if (it != mapBlockIndex.end()) - { - CBlockIndex* pindex = (*it).second; - if (pindex->IsInMainChain()) - nConf = 1 + nBestHeight - pindex->nHeight; - } - } + int nConf = txindex.GetDepthInMainChain(); dPriority += (double)nValueIn * nConf; @@ -3383,7 +3388,7 @@ continue; // Transaction fee required depends on block size - bool fAllowFree = (nBlockSize + nTxSize < 4000 || dPriority > COIN * 144 / 250); + bool fAllowFree = (nBlockSize + nTxSize < 4000 || CTransaction::AllowFree(dPriority)); int64 nMinFee = tx.GetMinFee(nBlockSize, fAllowFree); // Connecting shouldn't fail due to dependency on other memory pool transactions @@ -3859,6 +3864,7 @@ return false; int64 nValueOut = nValue; int64 nTotalValue = nValue + nFeeRet; + double dPriority = 0; // Choose coins to use set<CWalletTx*> setCoins; @@ -3866,7 +3872,11 @@ return false; int64 nValueIn = 0; foreach(CWalletTx* pcoin, setCoins) - nValueIn += pcoin->GetCredit(); + { + int64 nCredit = pcoin->GetCredit(); + nValueIn += nCredit; + dPriority += (double)nCredit * pcoin->GetDepthInMainChain(); + } // Fill a vout to the payee bool fChangeFirst = GetRand(2); @@ -3921,10 +3931,12 @@ unsigned int nBytes = ::GetSerializeSize(*(CTransaction*)&wtxNew, SER_NETWORK); if (nBytes >= MAX_BLOCK_SIZE_GEN/5) return false; + dPriority /= nBytes; // Check that enough fee is included int64 nPayFee = nTransactionFee * (1 + (int64)nBytes / 1000); - int64 nMinFee = wtxNew.GetMinFee(); + bool fAllowFree = CTransaction::AllowFree(dPriority); + int64 nMinFee = wtxNew.GetMinFee(1, fAllowFree); if (nFeeRet < max(nPayFee, nMinFee)) { nFeeRet = max(nPayFee, nMinFee);
--- a/main.h +++ b/main.h @@ -574,6 +574,13 @@ return nValueOut; } + static bool AllowFree(double dPriority) + { + // Large (in bytes) low-priority (new, small-coin) transactions + // need a fee. + return dPriority > COIN * 144 / 250; + } + int64 GetMinFee(unsigned int nBlockSize=1, bool fAllowFree=true) const { // Base fee is 1 cent per kilobyte @@ -998,6 +1005,7 @@ { return !(a == b); } + int GetDepthInMainChain() const; };