aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGavin Andresen <gavinandresen@gmail.com>2011-03-02 16:27:24 -0500
committerGavin Andresen <gavinandresen@gmail.com>2011-03-02 16:27:24 -0500
commit395c1f44bd480416a12c881c89721e72ab40ee32 (patch)
treead062f8dd6980c8e00dc474f2dcc77a83e882a96
parent411493b1f70d1493b1203bce847baa9f41e79f91 (diff)
downloadbitcoin-395c1f44bd480416a12c881c89721e72ab40ee32.tar.xz
Fix minimum transaction fee calculation mismatch between CreateTransaction and CreateBlock
-rw-r--r--main.cpp44
-rw-r--r--main.h8
2 files changed, 36 insertions, 16 deletions
diff --git a/main.cpp b/main.cpp
index a47f3a97b4..c65cd72de7 100644
--- a/main.cpp
+++ b/main.cpp
@@ -287,7 +287,7 @@ void EraseOrphanTx(uint256 hash)
//////////////////////////////////////////////////////////////////////////////
//
-// CTransaction
+// CTransaction and CTxIndex
//
bool CTransaction::ReadFromDisk(CTxDB& txdb, COutPoint prevout, CTxIndex& txindexRet)
@@ -1034,6 +1034,22 @@ void ResendWalletTransactions()
}
}
+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 @@ CBlock* CreateNewBlock(CReserveKey& reservekey)
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 @@ CBlock* CreateNewBlock(CReserveKey& reservekey)
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 @@ bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CR
return false;
int64 nValueOut = nValue;
int64 nTotalValue = nValue + nFeeRet;
+ double dPriority = 0;
// Choose coins to use
set<CWalletTx*> setCoins;
@@ -3866,7 +3872,11 @@ bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CR
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 @@ bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CR
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);
diff --git a/main.h b/main.h
index a7ef336e00..668d7f98b3 100644
--- a/main.h
+++ b/main.h
@@ -574,6 +574,13 @@ public:
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 @@ public:
{
return !(a == b);
}
+ int GetDepthInMainChain() const;
};