Fix minimum transaction fee calculation mismatch between CreateTransaction and CreateBlock
This commit is contained in:
parent
411493b1f7
commit
395c1f44bd
2 changed files with 36 additions and 16 deletions
44
main.cpp
44
main.cpp
|
@ -287,7 +287,7 @@ void EraseOrphanTx(uint256 hash)
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// CTransaction
|
// CTransaction and CTxIndex
|
||||||
//
|
//
|
||||||
|
|
||||||
bool CTransaction::ReadFromDisk(CTxDB& txdb, COutPoint prevout, CTxIndex& txindexRet)
|
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;
|
int64 nValueIn = txPrev.vout[txin.prevout.n].nValue;
|
||||||
|
|
||||||
// Read block header
|
// Read block header
|
||||||
int nConf = 0;
|
int nConf = txindex.GetDepthInMainChain();
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dPriority += (double)nValueIn * nConf;
|
dPriority += (double)nValueIn * nConf;
|
||||||
|
|
||||||
|
@ -3383,7 +3388,7 @@ CBlock* CreateNewBlock(CReserveKey& reservekey)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Transaction fee required depends on block size
|
// 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);
|
int64 nMinFee = tx.GetMinFee(nBlockSize, fAllowFree);
|
||||||
|
|
||||||
// Connecting shouldn't fail due to dependency on other memory pool transactions
|
// 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;
|
return false;
|
||||||
int64 nValueOut = nValue;
|
int64 nValueOut = nValue;
|
||||||
int64 nTotalValue = nValue + nFeeRet;
|
int64 nTotalValue = nValue + nFeeRet;
|
||||||
|
double dPriority = 0;
|
||||||
|
|
||||||
// Choose coins to use
|
// Choose coins to use
|
||||||
set<CWalletTx*> setCoins;
|
set<CWalletTx*> setCoins;
|
||||||
|
@ -3866,7 +3872,11 @@ bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CR
|
||||||
return false;
|
return false;
|
||||||
int64 nValueIn = 0;
|
int64 nValueIn = 0;
|
||||||
foreach(CWalletTx* pcoin, setCoins)
|
foreach(CWalletTx* pcoin, setCoins)
|
||||||
nValueIn += pcoin->GetCredit();
|
{
|
||||||
|
int64 nCredit = pcoin->GetCredit();
|
||||||
|
nValueIn += nCredit;
|
||||||
|
dPriority += (double)nCredit * pcoin->GetDepthInMainChain();
|
||||||
|
}
|
||||||
|
|
||||||
// Fill a vout to the payee
|
// Fill a vout to the payee
|
||||||
bool fChangeFirst = GetRand(2);
|
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);
|
unsigned int nBytes = ::GetSerializeSize(*(CTransaction*)&wtxNew, SER_NETWORK);
|
||||||
if (nBytes >= MAX_BLOCK_SIZE_GEN/5)
|
if (nBytes >= MAX_BLOCK_SIZE_GEN/5)
|
||||||
return false;
|
return false;
|
||||||
|
dPriority /= nBytes;
|
||||||
|
|
||||||
// Check that enough fee is included
|
// Check that enough fee is included
|
||||||
int64 nPayFee = nTransactionFee * (1 + (int64)nBytes / 1000);
|
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))
|
if (nFeeRet < max(nPayFee, nMinFee))
|
||||||
{
|
{
|
||||||
nFeeRet = max(nPayFee, nMinFee);
|
nFeeRet = max(nPayFee, nMinFee);
|
||||||
|
|
8
main.h
8
main.h
|
@ -574,6 +574,13 @@ public:
|
||||||
return nValueOut;
|
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
|
int64 GetMinFee(unsigned int nBlockSize=1, bool fAllowFree=true) const
|
||||||
{
|
{
|
||||||
// Base fee is 1 cent per kilobyte
|
// Base fee is 1 cent per kilobyte
|
||||||
|
@ -998,6 +1005,7 @@ public:
|
||||||
{
|
{
|
||||||
return !(a == b);
|
return !(a == b);
|
||||||
}
|
}
|
||||||
|
int GetDepthInMainChain() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue