github.com/palcoin-project/palcd@v1.0.0/mining/policy.go (about)

     1  // Copyright (c) 2014-2016 The btcsuite developers
     2  // Use of this source code is governed by an ISC
     3  // license that can be found in the LICENSE file.
     4  
     5  package mining
     6  
     7  import (
     8  	"github.com/palcoin-project/palcd/blockchain"
     9  	"github.com/palcoin-project/palcd/wire"
    10  	"github.com/palcoin-project/palcutil"
    11  )
    12  
    13  const (
    14  	// UnminedHeight is the height used for the "block" height field of the
    15  	// contextual transaction information provided in a transaction store
    16  	// when it has not yet been mined into a block.
    17  	UnminedHeight = 0x7fffffff
    18  )
    19  
    20  // Policy houses the policy (configuration parameters) which is used to control
    21  // the generation of block templates.  See the documentation for
    22  // NewBlockTemplate for more details on each of these parameters are used.
    23  type Policy struct {
    24  	// BlockMinWeight is the minimum block weight to be used when
    25  	// generating a block template.
    26  	BlockMinWeight uint32
    27  
    28  	// BlockMaxWeight is the maximum block weight to be used when
    29  	// generating a block template.
    30  	BlockMaxWeight uint32
    31  
    32  	// BlockMinWeight is the minimum block size to be used when generating
    33  	// a block template.
    34  	BlockMinSize uint32
    35  
    36  	// BlockMaxSize is the maximum block size to be used when generating a
    37  	// block template.
    38  	BlockMaxSize uint32
    39  
    40  	// BlockPrioritySize is the size in bytes for high-priority / low-fee
    41  	// transactions to be used when generating a block template.
    42  	BlockPrioritySize uint32
    43  
    44  	// TxMinFreeFee is the minimum fee in Satoshi/1000 bytes that is
    45  	// required for a transaction to be treated as free for mining purposes
    46  	// (block template generation).
    47  	TxMinFreeFee palcutil.Amount
    48  }
    49  
    50  // minInt is a helper function to return the minimum of two ints.  This avoids
    51  // a math import and the need to cast to floats.
    52  func minInt(a, b int) int {
    53  	if a < b {
    54  		return a
    55  	}
    56  	return b
    57  }
    58  
    59  // calcInputValueAge is a helper function used to calculate the input age of
    60  // a transaction.  The input age for a txin is the number of confirmations
    61  // since the referenced txout multiplied by its output value.  The total input
    62  // age is the sum of this value for each txin.  Any inputs to the transaction
    63  // which are currently in the mempool and hence not mined into a block yet,
    64  // contribute no additional input age to the transaction.
    65  func calcInputValueAge(tx *wire.MsgTx, utxoView *blockchain.UtxoViewpoint, nextBlockHeight int32) float64 {
    66  	var totalInputAge float64
    67  	for _, txIn := range tx.TxIn {
    68  		// Don't attempt to accumulate the total input age if the
    69  		// referenced transaction output doesn't exist.
    70  		entry := utxoView.LookupEntry(txIn.PreviousOutPoint)
    71  		if entry != nil && !entry.IsSpent() {
    72  			// Inputs with dependencies currently in the mempool
    73  			// have their block height set to a special constant.
    74  			// Their input age should computed as zero since their
    75  			// parent hasn't made it into a block yet.
    76  			var inputAge int32
    77  			originHeight := entry.BlockHeight()
    78  			if originHeight == UnminedHeight {
    79  				inputAge = 0
    80  			} else {
    81  				inputAge = nextBlockHeight - originHeight
    82  			}
    83  
    84  			// Sum the input value times age.
    85  			inputValue := entry.Amount()
    86  			totalInputAge += float64(inputValue * int64(inputAge))
    87  		}
    88  	}
    89  
    90  	return totalInputAge
    91  }
    92  
    93  // CalcPriority returns a transaction priority given a transaction and the sum
    94  // of each of its input values multiplied by their age (# of confirmations).
    95  // Thus, the final formula for the priority is:
    96  // sum(inputValue * inputAge) / adjustedTxSize
    97  func CalcPriority(tx *wire.MsgTx, utxoView *blockchain.UtxoViewpoint, nextBlockHeight int32) float64 {
    98  	// In order to encourage spending multiple old unspent transaction
    99  	// outputs thereby reducing the total set, don't count the constant
   100  	// overhead for each input as well as enough bytes of the signature
   101  	// script to cover a pay-to-script-hash redemption with a compressed
   102  	// pubkey.  This makes additional inputs free by boosting the priority
   103  	// of the transaction accordingly.  No more incentive is given to avoid
   104  	// encouraging gaming future transactions through the use of junk
   105  	// outputs.  This is the same logic used in the reference
   106  	// implementation.
   107  	//
   108  	// The constant overhead for a txin is 41 bytes since the previous
   109  	// outpoint is 36 bytes + 4 bytes for the sequence + 1 byte the
   110  	// signature script length.
   111  	//
   112  	// A compressed pubkey pay-to-script-hash redemption with a maximum len
   113  	// signature is of the form:
   114  	// [OP_DATA_73 <73-byte sig> + OP_DATA_35 + {OP_DATA_33
   115  	// <33 byte compresed pubkey> + OP_CHECKSIG}]
   116  	//
   117  	// Thus 1 + 73 + 1 + 1 + 33 + 1 = 110
   118  	overhead := 0
   119  	for _, txIn := range tx.TxIn {
   120  		// Max inputs + size can't possibly overflow here.
   121  		overhead += 41 + minInt(110, len(txIn.SignatureScript))
   122  	}
   123  
   124  	serializedTxSize := tx.SerializeSize()
   125  	if overhead >= serializedTxSize {
   126  		return 0.0
   127  	}
   128  
   129  	inputValueAge := calcInputValueAge(tx, utxoView, nextBlockHeight)
   130  	return inputValueAge / float64(serializedTxSize-overhead)
   131  }