Use fee/priority estimates in wallet CreateTransaction
The wallet now uses the mempool fee estimator with a new command-line option: -txconfirmtarget (default: 1) instead of using hard-coded fees or priorities. A new bitcoind that hasn't seen enough transactions to estimate will fall back to the old hard-coded minimum priority or transaction fee. -paytxfee option overrides -txconfirmtarget. Relaying and mining code isn't changed. For Qt, the coin control dialog now uses priority estimates to label transaction priority (instead of hard-coded constants); unspent outputs were consistently labeled with a much higher priority than is justified by the free transactions actually being accepted into blocks. I did not implement any GUI for setting -txconfirmtarget; I would suggest getting rid of the "Pay transaction fee" GUI and replace it with either "target number of confirmations" or maybe a "faster confirmation <--> lower fee" slider or select box.
This commit is contained in:
@@ -18,6 +18,7 @@ using namespace std;
|
||||
|
||||
// Settings
|
||||
CFeeRate payTxFee(DEFAULT_TRANSACTION_FEE);
|
||||
unsigned int nTxConfirmTarget = 1;
|
||||
bool bSpendZeroConfChange = true;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
@@ -1273,6 +1274,7 @@ bool CWallet::CreateTransaction(const vector<pair<CScript, int64_t> >& vecSend,
|
||||
return false;
|
||||
}
|
||||
|
||||
wtxNew.fTimeReceivedIsTxTime = true;
|
||||
wtxNew.BindWallet(this);
|
||||
CMutableTransaction txNew;
|
||||
|
||||
@@ -1393,19 +1395,31 @@ bool CWallet::CreateTransaction(const vector<pair<CScript, int64_t> >& vecSend,
|
||||
}
|
||||
dPriority = wtxNew.ComputePriority(dPriority, nBytes);
|
||||
|
||||
// Check that enough fee is included
|
||||
int64_t nPayFee = payTxFee.GetFee(nBytes);
|
||||
bool fAllowFree = AllowFree(dPriority);
|
||||
int64_t nMinFee = GetMinFee(wtxNew, nBytes, fAllowFree, GMF_SEND);
|
||||
if (nFeeRet < max(nPayFee, nMinFee))
|
||||
int64_t nFeeNeeded = GetMinimumFee(nBytes, nTxConfirmTarget, mempool);
|
||||
|
||||
if (nFeeRet >= nFeeNeeded)
|
||||
break; // Done, enough fee included.
|
||||
|
||||
// Too big to send for free? Include more fee and try again:
|
||||
if (nBytes > MAX_FREE_TRANSACTION_CREATE_SIZE)
|
||||
{
|
||||
nFeeRet = max(nPayFee, nMinFee);
|
||||
nFeeRet = nFeeNeeded;
|
||||
continue;
|
||||
}
|
||||
|
||||
wtxNew.fTimeReceivedIsTxTime = true;
|
||||
// Not enough fee: enough priority?
|
||||
double dPriorityNeeded = mempool.estimatePriority(nTxConfirmTarget);
|
||||
// Not enough mempool history to estimate: use hard-coded AllowFree.
|
||||
if (dPriorityNeeded <= 0 && AllowFree(dPriority))
|
||||
break;
|
||||
|
||||
break;
|
||||
// Small enough, and priority high enough, to send for free
|
||||
if (dPriority >= dPriorityNeeded)
|
||||
break;
|
||||
|
||||
// Include more fee and try again.
|
||||
nFeeRet = nFeeNeeded;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1513,6 +1527,20 @@ string CWallet::SendMoneyToDestination(const CTxDestination& address, int64_t nV
|
||||
return SendMoney(scriptPubKey, nValue, wtxNew);
|
||||
}
|
||||
|
||||
int64_t CWallet::GetMinimumFee(unsigned int nTxBytes, unsigned int nConfirmTarget, const CTxMemPool& pool)
|
||||
{
|
||||
// payTxFee is user-set "I want to pay this much"
|
||||
int64_t nFeeNeeded = payTxFee.GetFee(nTxBytes);
|
||||
// User didn't set: use -txconfirmtarget to estimate...
|
||||
if (nFeeNeeded == 0)
|
||||
nFeeNeeded = pool.estimateFee(nConfirmTarget).GetFee(nTxBytes);
|
||||
// ... unless we don't have enough mempool data, in which case fall
|
||||
// back to a hard-coded fee
|
||||
if (nFeeNeeded == 0)
|
||||
nFeeNeeded = CTransaction::minTxFee.GetFee(nTxBytes);
|
||||
return nFeeNeeded;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user