Skip to content

Commit

Permalink
A few nitpicks with recent getrawmempool updates.
Browse files Browse the repository at this point in the history
This commit addresses a few nitpicks in the recent getrawmppol update
which populates the starting and current priority fields.

In particular:

- Move the new calcInputValueAge function before the function which
  invokes it so it is consistent with the rest of the mempool code
- Double space after periods for consistency
- Correct the comments for calcInputValueAge to indiciate that inputs
  which are in the the memory pool count as zero toward the value age
  rather than the incorrect claim that that the overal input value age is
  zero when one of them does
- Rename endingPriority to currentPriority to match the RPC field and its
  actual function
- Make the comment about using zero when input transactions can't be found
  for some reason more accurate since there can be (and frequently is)
  more than one input transaction
  • Loading branch information
davecgh committed Nov 17, 2014
1 parent a49b0d0 commit 1973aa5
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 44 deletions.
74 changes: 36 additions & 38 deletions mempool.go
Expand Up @@ -671,39 +671,13 @@ func (mp *txMemPool) addTransaction(tx *btcutil.Tx, height, fee int64) {
mp.lastUpdated = time.Now()
}

// StartingPriority calculates the priority of this tx descriptor's
// underlying transaction relative to when it was first added to the mempool.
// The result is lazily computed and then cached for subsequent function
// calls.
func (txD *TxDesc) StartingPriority(txStore btcchain.TxStore) float64 {
// Return our cached result.
if txD.startingPriority != float64(0) {
return txD.startingPriority
}

// Compute our starting priority caching the result.
inputAge := calcInputValueAge(txD, txStore, txD.Height)
txSize := txD.Tx.MsgTx().SerializeSize()
txD.startingPriority = calcPriority(txD.Tx, txSize, inputAge)

return txD.startingPriority
}

// CurrentPriority calculates the current priority of this tx descriptor's
// underlying transaction relative to the next block height.
func (txD *TxDesc) CurrentPriority(txStore btcchain.TxStore, nextBlockHeight int64) float64 {
inputAge := calcInputValueAge(txD, txStore, nextBlockHeight)
txSize := txD.Tx.MsgTx().SerializeSize()
return calcPriority(txD.Tx, txSize, inputAge)
}

// calcInputValueAge is a helper function used to calculate the input age of
// a transaction. The input age for a txin is the number of confirmations
// since the referenced txout multiplied by its output value.
// The total input age is the sum of this value for each txin. If the tx
// depends on one currently in the mempool, then its input age is zero.
func calcInputValueAge(txDesc *TxDesc, txStore btcchain.TxStore,
nextBlockHeight int64) float64 {
// a transaction. The input age for a txin is the number of confirmations
// since the referenced txout multiplied by its output value. The total input
// age is the sum of this value for each txin. Any inputs to the transaction
// which are currently in the mempool and hence not mined into a block yet,
// contribute no additional input age to the transaction.
func calcInputValueAge(txDesc *TxDesc, txStore btcchain.TxStore, nextBlockHeight int64) float64 {
var totalInputAge float64
for _, txIn := range txDesc.Tx.MsgTx().TxIn {
originHash := &txIn.PreviousOutPoint.Hash
Expand All @@ -712,12 +686,10 @@ func calcInputValueAge(txDesc *TxDesc, txStore btcchain.TxStore,
// Don't attempt to accumulate the total input age if the txIn
// in question doesn't exist.
if txData, exists := txStore[*originHash]; exists && txData.Tx != nil {
originTxOut := txData.Tx.MsgTx().TxOut[originIndex]

// Transactions with dependencies currently in the
// mempool have their block height set to a special
// constant. Their input age should computed as zero
// since their parent hasn't made it into a block yet.
// Inputs with dependencies currently in the mempool
// have their block height set to a special constant.
// Their input age should computed as zero since their
// parent hasn't made it into a block yet.
var inputAge int64
if txData.BlockHeight == mempoolHeight {
inputAge = 0
Expand All @@ -726,6 +698,7 @@ func calcInputValueAge(txDesc *TxDesc, txStore btcchain.TxStore,
}

// Sum the input value times age.
originTxOut := txData.Tx.MsgTx().TxOut[originIndex]
inputValue := originTxOut.Value
totalInputAge += float64(inputValue * inputAge)
}
Expand All @@ -734,6 +707,31 @@ func calcInputValueAge(txDesc *TxDesc, txStore btcchain.TxStore,
return totalInputAge
}

// StartingPriority calculates the priority of this tx descriptor's underlying
// transaction relative to when it was first added to the mempool. The result
// is lazily computed and then cached for subsequent function calls.
func (txD *TxDesc) StartingPriority(txStore btcchain.TxStore) float64 {
// Return our cached result.
if txD.startingPriority != float64(0) {
return txD.startingPriority
}

// Compute our starting priority caching the result.
inputAge := calcInputValueAge(txD, txStore, txD.Height)
txSize := txD.Tx.MsgTx().SerializeSize()
txD.startingPriority = calcPriority(txD.Tx, txSize, inputAge)

return txD.startingPriority
}

// CurrentPriority calculates the current priority of this tx descriptor's
// underlying transaction relative to the next block height.
func (txD *TxDesc) CurrentPriority(txStore btcchain.TxStore, nextBlockHeight int64) float64 {
inputAge := calcInputValueAge(txD, txStore, nextBlockHeight)
txSize := txD.Tx.MsgTx().SerializeSize()
return calcPriority(txD.Tx, txSize, inputAge)
}

// checkPoolDoubleSpend checks whether or not the passed transaction is
// attempting to spend coins already spent by other transactions in the pool.
// Note it does not check for double spends against transactions already in the
Expand Down
12 changes: 6 additions & 6 deletions rpcserver.go
Expand Up @@ -2305,14 +2305,14 @@ func handleGetRawMempool(s *rpcServer, cmd btcjson.Cmd, closeChan <-chan struct{
mp.RLock()
defer mp.RUnlock()
for _, desc := range descs {
// Calculate the starting and ending priority from the
// the tx's inputs. If we can't find the input for some
// reason, then we display zero in place.
// Calculate the starting and current priority from the
// the tx's inputs. Use zeros if one or more of the
// input transactions can't be found for some reason.
var startingPriority, currentPriority float64
inputTxs, err := mp.fetchInputTransactions(desc.Tx)
var startingPriority, endingPriority float64
if err == nil {
startingPriority = desc.StartingPriority(inputTxs)
endingPriority = desc.CurrentPriority(inputTxs,
currentPriority = desc.CurrentPriority(inputTxs,
newestHeight+1)
}

Expand All @@ -2322,7 +2322,7 @@ func handleGetRawMempool(s *rpcServer, cmd btcjson.Cmd, closeChan <-chan struct{
Time: desc.Added.Unix(),
Height: desc.Height,
StartingPriority: startingPriority,
CurrentPriority: endingPriority,
CurrentPriority: currentPriority,
Depends: make([]string, 0),
}
for _, txIn := range desc.Tx.MsgTx().TxIn {
Expand Down

0 comments on commit 1973aa5

Please sign in to comment.