github.com/btcsuite/btcd@v0.24.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/btcsuite/btcd/blockchain" 9 "github.com/btcsuite/btcd/btcutil" 10 "github.com/btcsuite/btcd/wire" 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 btcutil.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 }