Skip to content

Commit

Permalink
Improve readability of recent rate limiter changes.
Browse files Browse the repository at this point in the history
This commit builds on the recent limiter updates.  The recent changes
introduced a new function named calcTxFee which could easily be confused
with calculating the fees of the transaction rather than its intended
purpose of calculating the minimum transaciton relay fee.

Rather than taking that approach, this commit instead renames the existing
function to calcMinRequiredTxRelayFee and uses a consistent variable name
for the serialized size of a transaction.  It then moves the check for
whether or not the check should be applied based on the serialized size of
the transcation and block priority to the call site.

This approach also has the benefit of avoiding two calls to the
calculation function since it's a local at the call site.

ok @jrick, @dajohi
  • Loading branch information
davecgh committed Aug 19, 2014
1 parent 61a53ad commit 3dc3fef
Showing 1 changed file with 21 additions and 29 deletions.
50 changes: 21 additions & 29 deletions mempool.go
Expand Up @@ -370,43 +370,25 @@ func checkInputsStandard(tx *btcutil.Tx, txStore btcchain.TxStore) error {
return nil
}

// calcTxFee returns the minimum transaction fee required for the passed
// transaction.
func calcTxFee(size int) int64 {
// calcMinRequiredTxRelayFee returns the minimum transaction fee required for a
// transaction with the passed serialized size to be accepted into the memory
// pool and relayed.
func calcMinRequiredTxRelayFee(serializedSize int64) int64 {
// Calculate the minimum fee for a transaction to be allowed into the
// mempool and relayed by scaling the base fee (which is the minimum
// free transaction relay fee). minTxRelayFee is in Satoshi/KB, so
// divide the transaction size by 1000 to convert to kilobytes. Also,
// integer division is used so fees only increase on full kilobyte
// boundaries.
minFee := (1 + size/1000) * minTxRelayFee
minFee := (1 + serializedSize/1000) * minTxRelayFee

// Set the minimum fee to the maximum possible value if the calculated
// fee is not in the valid range for monetary amounts.
if minFee < 0 || minFee > btcutil.MaxSatoshi {
minFee = btcutil.MaxSatoshi
}

return int64(minFee)
}

// calcMinRelayFee retuns the minimum transaction fee required for the passed
// transaction to be accepted into the memory pool and relayed.
func calcMinTxRelayFee(size int) int64 {
// Most miners allow a free transaction area in blocks they mine to go
// alongside the area used for high-priority transactions as well as
// transactions with fees. A transaction size of up to 1000 bytes is
// considered safe to go into this section. Further, the minimum fee
// calculated below on its own would encourage several small
// transactions to avoid fees rather than one single larger transaction
// which is more desirable. Therefore, as long as the size of the
// transaction does not exceeed 1000 less than the reserved space for
// high-priority transactions, don't require a fee for it.
if size < (defaultBlockPrioritySize - 1000) {
return 0
}

return calcTxFee(size)
return minFee
}

// removeOrphan removes the passed orphan transaction from the orphan pool and
Expand Down Expand Up @@ -895,18 +877,28 @@ func (mp *txMemPool) maybeAcceptTransaction(tx *btcutil.Tx, isOrphan *bool, isNe
// reasonable number of ECDSA signature verifications.

// Don't allow transactions with fees too low to get into a mined block.
serializedSize := tx.MsgTx().SerializeSize()
minRequiredFee := calcMinTxRelayFee(serializedSize)
if txFee < minRequiredFee {
//
// Most miners allow a free transaction area in blocks they mine to go
// alongside the area used for high-priority transactions as well as
// transactions with fees. A transaction size of up to 1000 bytes is
// considered safe to go into this section. Further, the minimum fee
// calculated below on its own would encourage several small
// transactions to avoid fees rather than one single larger transaction
// which is more desirable. Therefore, as long as the size of the
// transaction does not exceeed 1000 less than the reserved space for
// high-priority transactions, don't require a fee for it.
serializedSize := int64(tx.MsgTx().SerializeSize())
minFee := calcMinRequiredTxRelayFee(serializedSize)
if serializedSize >= (defaultBlockPrioritySize-1000) && txFee < minFee {
str := fmt.Sprintf("transaction %v has %d fees which is under "+
"the required amount of %d", txHash, txFee,
minRequiredFee)
minFee)
return txRuleError(btcwire.RejectInsufficientFee, str)
}

// Free-to-relay transactions are rate limited here to prevent
// penny-flooding with tiny transactions as a form of attack.
if rateLimit && txFee < calcTxFee(serializedSize) {
if rateLimit && txFee < minFee {
nowUnix := time.Now().Unix()
// we decay passed data with an exponentially decaying ~10
// minutes window - matches bitcoind handling.
Expand Down

0 comments on commit 3dc3fef

Please sign in to comment.