github.com/dashpay/godash@v0.0.0-20160726055534-e038a21e0e3d/policy.go (about) 1 // Copyright (c) 2013-2016 The btcsuite developers 2 // Copyright (c) 2016 The Dash developers 3 // Use of this source code is governed by an ISC 4 // license that can be found in the LICENSE file. 5 6 package main 7 8 import ( 9 "fmt" 10 11 "github.com/dashpay/godash/blockchain" 12 "github.com/dashpay/godash/txscript" 13 "github.com/dashpay/godash/wire" 14 "github.com/dashpay/godashutil" 15 ) 16 17 const ( 18 // maxStandardTxSize is the maximum size allowed for transactions that 19 // are considered standard and will therefore be relayed and considered 20 // for mining. 21 maxStandardTxSize = 100000 22 23 // maxStandardSigScriptSize is the maximum size allowed for a 24 // transaction input signature script to be considered standard. This 25 // value allows for a 15-of-15 CHECKMULTISIG pay-to-script-hash with 26 // compressed keys. 27 // 28 // The form of the overall script is: OP_0 <15 signatures> OP_PUSHDATA2 29 // <2 bytes len> [OP_15 <15 pubkeys> OP_15 OP_CHECKMULTISIG] 30 // 31 // For the p2sh script portion, each of the 15 compressed pubkeys are 32 // 33 bytes (plus one for the OP_DATA_33 opcode), and the thus it totals 33 // to (15*34)+3 = 513 bytes. Next, each of the 15 signatures is a max 34 // of 73 bytes (plus one for the OP_DATA_73 opcode). Also, there is one 35 // extra byte for the initial extra OP_0 push and 3 bytes for the 36 // OP_PUSHDATA2 needed to specify the 513 bytes for the script push. 37 // That brings the total to 1+(15*74)+3+513 = 1627. This value also 38 // adds a few extra bytes to provide a little buffer. 39 // (1 + 15*74 + 3) + (15*34 + 3) + 23 = 1650 40 maxStandardSigScriptSize = 1650 41 42 // defaultMinRelayTxFee is the minimum fee in satoshi that is required 43 // for a transaction to be treated as free for relay and mining 44 // purposes. It is also used to help determine if a transaction is 45 // considered dust and as a base for calculating minimum required fees 46 // for larger transactions. This value is in Satoshi/1000 bytes. 47 defaultMinRelayTxFee = godashutil.Amount(1000) 48 49 // maxStandardMultiSigKeys is the maximum number of public keys allowed 50 // in a multi-signature transaction output script for it to be 51 // considered standard. 52 maxStandardMultiSigKeys = 3 53 ) 54 55 // calcMinRequiredTxRelayFee returns the minimum transaction fee required for a 56 // transaction with the passed serialized size to be accepted into the memory 57 // pool and relayed. 58 func calcMinRequiredTxRelayFee(serializedSize int64, minRelayTxFee godashutil.Amount) int64 { 59 // Calculate the minimum fee for a transaction to be allowed into the 60 // mempool and relayed by scaling the base fee (which is the minimum 61 // free transaction relay fee). minTxRelayFee is in Satoshi/kB so 62 // multiply by serializedSize (which is in bytes) and divide by 1000 to 63 // get minimum Satoshis. 64 minFee := (serializedSize * int64(minRelayTxFee)) / 1000 65 66 if minFee == 0 && minRelayTxFee > 0 { 67 minFee = int64(minRelayTxFee) 68 } 69 70 // Set the minimum fee to the maximum possible value if the calculated 71 // fee is not in the valid range for monetary amounts. 72 if minFee < 0 || minFee > godashutil.MaxSatoshi { 73 minFee = godashutil.MaxSatoshi 74 } 75 76 return minFee 77 } 78 79 // calcPriority returns a transaction priority given a transaction and the sum 80 // of each of its input values multiplied by their age (# of confirmations). 81 // Thus, the final formula for the priority is: 82 // sum(inputValue * inputAge) / adjustedTxSize 83 func calcPriority(tx *wire.MsgTx, utxoView *blockchain.UtxoViewpoint, nextBlockHeight int32) float64 { 84 // In order to encourage spending multiple old unspent transaction 85 // outputs thereby reducing the total set, don't count the constant 86 // overhead for each input as well as enough bytes of the signature 87 // script to cover a pay-to-script-hash redemption with a compressed 88 // pubkey. This makes additional inputs free by boosting the priority 89 // of the transaction accordingly. No more incentive is given to avoid 90 // encouraging gaming future transactions through the use of junk 91 // outputs. This is the same logic used in the reference 92 // implementation. 93 // 94 // The constant overhead for a txin is 41 bytes since the previous 95 // outpoint is 36 bytes + 4 bytes for the sequence + 1 byte the 96 // signature script length. 97 // 98 // A compressed pubkey pay-to-script-hash redemption with a maximum len 99 // signature is of the form: 100 // [OP_DATA_73 <73-byte sig> + OP_DATA_35 + {OP_DATA_33 101 // <33 byte compresed pubkey> + OP_CHECKSIG}] 102 // 103 // Thus 1 + 73 + 1 + 1 + 33 + 1 = 110 104 overhead := 0 105 for _, txIn := range tx.TxIn { 106 // Max inputs + size can't possibly overflow here. 107 overhead += 41 + minInt(110, len(txIn.SignatureScript)) 108 } 109 110 serializedTxSize := tx.SerializeSize() 111 if overhead >= serializedTxSize { 112 return 0.0 113 } 114 115 inputValueAge := calcInputValueAge(tx, utxoView, nextBlockHeight) 116 return inputValueAge / float64(serializedTxSize-overhead) 117 } 118 119 // calcInputValueAge is a helper function used to calculate the input age of 120 // a transaction. The input age for a txin is the number of confirmations 121 // since the referenced txout multiplied by its output value. The total input 122 // age is the sum of this value for each txin. Any inputs to the transaction 123 // which are currently in the mempool and hence not mined into a block yet, 124 // contribute no additional input age to the transaction. 125 func calcInputValueAge(tx *wire.MsgTx, utxoView *blockchain.UtxoViewpoint, nextBlockHeight int32) float64 { 126 var totalInputAge float64 127 for _, txIn := range tx.TxIn { 128 // Don't attempt to accumulate the total input age if the 129 // referenced transaction output doesn't exist. 130 originHash := &txIn.PreviousOutPoint.Hash 131 originIndex := txIn.PreviousOutPoint.Index 132 txEntry := utxoView.LookupEntry(originHash) 133 if txEntry != nil && !txEntry.IsOutputSpent(originIndex) { 134 // Inputs with dependencies currently in the mempool 135 // have their block height set to a special constant. 136 // Their input age should be computed as zero since 137 // their parent hasn't made it into a block yet. 138 var inputAge int32 139 originHeight := txEntry.BlockHeight() 140 if originHeight == mempoolHeight { 141 inputAge = 0 142 } else { 143 inputAge = nextBlockHeight - originHeight 144 } 145 146 // Sum the input value times age. 147 inputValue := txEntry.AmountByIndex(originIndex) 148 totalInputAge += float64(inputValue * int64(inputAge)) 149 } 150 } 151 152 return totalInputAge 153 } 154 155 // checkInputsStandard performs a series of checks on a transaction's inputs 156 // to ensure they are "standard". A standard transaction input is one that 157 // that consumes the expected number of elements from the stack and that number 158 // is the same as the output script pushes. This help prevent resource 159 // exhaustion attacks by "creative" use of scripts that are super expensive to 160 // process like OP_DUP OP_CHECKSIG OP_DROP repeated a large number of times 161 // followed by a final OP_TRUE. 162 func checkInputsStandard(tx *godashutil.Tx, utxoView *blockchain.UtxoViewpoint) error { 163 // NOTE: The reference implementation also does a coinbase check here, 164 // but coinbases have already been rejected prior to calling this 165 // function so no need to recheck. 166 167 for i, txIn := range tx.MsgTx().TxIn { 168 // It is safe to elide existence and index checks here since 169 // they have already been checked prior to calling this 170 // function. 171 prevOut := txIn.PreviousOutPoint 172 entry := utxoView.LookupEntry(&prevOut.Hash) 173 originPkScript := entry.PkScriptByIndex(prevOut.Index) 174 175 // Calculate stats for the script pair. 176 scriptInfo, err := txscript.CalcScriptInfo(txIn.SignatureScript, 177 originPkScript, true) 178 if err != nil { 179 str := fmt.Sprintf("transaction input #%d script parse "+ 180 "failure: %v", i, err) 181 return txRuleError(wire.RejectNonstandard, str) 182 } 183 184 // A negative value for expected inputs indicates the script is 185 // non-standard in some way. 186 if scriptInfo.ExpectedInputs < 0 { 187 str := fmt.Sprintf("transaction input #%d expects %d "+ 188 "inputs", i, scriptInfo.ExpectedInputs) 189 return txRuleError(wire.RejectNonstandard, str) 190 } 191 192 // The script pair is non-standard if the number of available 193 // inputs does not match the number of expected inputs. 194 if scriptInfo.NumInputs != scriptInfo.ExpectedInputs { 195 str := fmt.Sprintf("transaction input #%d expects %d "+ 196 "inputs, but referenced output script provides "+ 197 "%d", i, scriptInfo.ExpectedInputs, 198 scriptInfo.NumInputs) 199 return txRuleError(wire.RejectNonstandard, str) 200 } 201 } 202 203 return nil 204 } 205 206 // checkPkScriptStandard performs a series of checks on a transaction output 207 // script (public key script) to ensure it is a "standard" public key script. 208 // A standard public key script is one that is a recognized form, and for 209 // multi-signature scripts, only contains from 1 to maxStandardMultiSigKeys 210 // public keys. 211 func checkPkScriptStandard(pkScript []byte, scriptClass txscript.ScriptClass) error { 212 switch scriptClass { 213 case txscript.MultiSigTy: 214 numPubKeys, numSigs, err := txscript.CalcMultiSigStats(pkScript) 215 if err != nil { 216 str := fmt.Sprintf("multi-signature script parse "+ 217 "failure: %v", err) 218 return txRuleError(wire.RejectNonstandard, str) 219 } 220 221 // A standard multi-signature public key script must contain 222 // from 1 to maxStandardMultiSigKeys public keys. 223 if numPubKeys < 1 { 224 str := "multi-signature script with no pubkeys" 225 return txRuleError(wire.RejectNonstandard, str) 226 } 227 if numPubKeys > maxStandardMultiSigKeys { 228 str := fmt.Sprintf("multi-signature script with %d "+ 229 "public keys which is more than the allowed "+ 230 "max of %d", numPubKeys, maxStandardMultiSigKeys) 231 return txRuleError(wire.RejectNonstandard, str) 232 } 233 234 // A standard multi-signature public key script must have at 235 // least 1 signature and no more signatures than available 236 // public keys. 237 if numSigs < 1 { 238 return txRuleError(wire.RejectNonstandard, 239 "multi-signature script with no signatures") 240 } 241 if numSigs > numPubKeys { 242 str := fmt.Sprintf("multi-signature script with %d "+ 243 "signatures which is more than the available "+ 244 "%d public keys", numSigs, numPubKeys) 245 return txRuleError(wire.RejectNonstandard, str) 246 } 247 248 case txscript.NonStandardTy: 249 return txRuleError(wire.RejectNonstandard, 250 "non-standard script form") 251 } 252 253 return nil 254 } 255 256 // isDust returns whether or not the passed transaction output amount is 257 // considered dust or not based on the passed minimum transaction relay fee. 258 // Dust is defined in terms of the minimum transaction relay fee. In 259 // particular, if the cost to the network to spend coins is more than 1/3 of the 260 // minimum transaction relay fee, it is considered dust. 261 func isDust(txOut *wire.TxOut, minRelayTxFee godashutil.Amount) bool { 262 // Unspendable outputs are considered dust. 263 if txscript.IsUnspendable(txOut.PkScript) { 264 return true 265 } 266 267 // The total serialized size consists of the output and the associated 268 // input script to redeem it. Since there is no input script 269 // to redeem it yet, use the minimum size of a typical input script. 270 // 271 // Pay-to-pubkey-hash bytes breakdown: 272 // 273 // Output to hash (34 bytes): 274 // 8 value, 1 script len, 25 script [1 OP_DUP, 1 OP_HASH_160, 275 // 1 OP_DATA_20, 20 hash, 1 OP_EQUALVERIFY, 1 OP_CHECKSIG] 276 // 277 // Input with compressed pubkey (148 bytes): 278 // 36 prev outpoint, 1 script len, 107 script [1 OP_DATA_72, 72 sig, 279 // 1 OP_DATA_33, 33 compressed pubkey], 4 sequence 280 // 281 // Input with uncompressed pubkey (180 bytes): 282 // 36 prev outpoint, 1 script len, 139 script [1 OP_DATA_72, 72 sig, 283 // 1 OP_DATA_65, 65 compressed pubkey], 4 sequence 284 // 285 // Pay-to-pubkey bytes breakdown: 286 // 287 // Output to compressed pubkey (44 bytes): 288 // 8 value, 1 script len, 35 script [1 OP_DATA_33, 289 // 33 compressed pubkey, 1 OP_CHECKSIG] 290 // 291 // Output to uncompressed pubkey (76 bytes): 292 // 8 value, 1 script len, 67 script [1 OP_DATA_65, 65 pubkey, 293 // 1 OP_CHECKSIG] 294 // 295 // Input (114 bytes): 296 // 36 prev outpoint, 1 script len, 73 script [1 OP_DATA_72, 297 // 72 sig], 4 sequence 298 // 299 // Theoretically this could examine the script type of the output script 300 // and use a different size for the typical input script size for 301 // pay-to-pubkey vs pay-to-pubkey-hash inputs per the above breakdowns, 302 // but the only combinination which is less than the value chosen is 303 // a pay-to-pubkey script with a compressed pubkey, which is not very 304 // common. 305 // 306 // The most common scripts are pay-to-pubkey-hash, and as per the above 307 // breakdown, the minimum size of a p2pkh input script is 148 bytes. So 308 // that figure is used. 309 totalSize := txOut.SerializeSize() + 148 310 311 // The output is considered dust if the cost to the network to spend the 312 // coins is more than 1/3 of the minimum free transaction relay fee. 313 // minFreeTxRelayFee is in Satoshi/KB, so multiply by 1000 to 314 // convert to bytes. 315 // 316 // Using the typical values for a pay-to-pubkey-hash transaction from 317 // the breakdown above and the default minimum free transaction relay 318 // fee of 1000, this equates to values less than 546 satoshi being 319 // considered dust. 320 // 321 // The following is equivalent to (value/totalSize) * (1/3) * 1000 322 // without needing to do floating point math. 323 return txOut.Value*1000/(3*int64(totalSize)) < int64(minRelayTxFee) 324 } 325 326 // checkTransactionStandard performs a series of checks on a transaction to 327 // ensure it is a "standard" transaction. A standard transaction is one that 328 // conforms to several additional limiting cases over what is considered a 329 // "sane" transaction such as having a version in the supported range, being 330 // finalized, conforming to more stringent size constraints, having scripts 331 // of recognized forms, and not containing "dust" outputs (those that are 332 // so small it costs more to process them than they are worth). 333 func checkTransactionStandard(tx *godashutil.Tx, height int32, timeSource blockchain.MedianTimeSource, minRelayTxFee godashutil.Amount) error { 334 // The transaction must be a currently supported version. 335 msgTx := tx.MsgTx() 336 if msgTx.Version > wire.TxVersion || msgTx.Version < 1 { 337 str := fmt.Sprintf("transaction version %d is not in the "+ 338 "valid range of %d-%d", msgTx.Version, 1, 339 wire.TxVersion) 340 return txRuleError(wire.RejectNonstandard, str) 341 } 342 343 // The transaction must be finalized to be standard and therefore 344 // considered for inclusion in a block. 345 adjustedTime := timeSource.AdjustedTime() 346 if !blockchain.IsFinalizedTransaction(tx, height, adjustedTime) { 347 return txRuleError(wire.RejectNonstandard, 348 "transaction is not finalized") 349 } 350 351 // Since extremely large transactions with a lot of inputs can cost 352 // almost as much to process as the sender fees, limit the maximum 353 // size of a transaction. This also helps mitigate CPU exhaustion 354 // attacks. 355 serializedLen := msgTx.SerializeSize() 356 if serializedLen > maxStandardTxSize { 357 str := fmt.Sprintf("transaction size of %v is larger than max "+ 358 "allowed size of %v", serializedLen, maxStandardTxSize) 359 return txRuleError(wire.RejectNonstandard, str) 360 } 361 362 for i, txIn := range msgTx.TxIn { 363 // Each transaction input signature script must not exceed the 364 // maximum size allowed for a standard transaction. See 365 // the comment on maxStandardSigScriptSize for more details. 366 sigScriptLen := len(txIn.SignatureScript) 367 if sigScriptLen > maxStandardSigScriptSize { 368 str := fmt.Sprintf("transaction input %d: signature "+ 369 "script size of %d bytes is large than max "+ 370 "allowed size of %d bytes", i, sigScriptLen, 371 maxStandardSigScriptSize) 372 return txRuleError(wire.RejectNonstandard, str) 373 } 374 375 // Each transaction input signature script must only contain 376 // opcodes which push data onto the stack. 377 if !txscript.IsPushOnlyScript(txIn.SignatureScript) { 378 str := fmt.Sprintf("transaction input %d: signature "+ 379 "script is not push only", i) 380 return txRuleError(wire.RejectNonstandard, str) 381 } 382 } 383 384 // None of the output public key scripts can be a non-standard script or 385 // be "dust" (except when the script is a null data script). 386 numNullDataOutputs := 0 387 for i, txOut := range msgTx.TxOut { 388 scriptClass := txscript.GetScriptClass(txOut.PkScript) 389 err := checkPkScriptStandard(txOut.PkScript, scriptClass) 390 if err != nil { 391 // Attempt to extract a reject code from the error so 392 // it can be retained. When not possible, fall back to 393 // a non standard error. 394 rejectCode := wire.RejectNonstandard 395 if rejCode, found := extractRejectCode(err); found { 396 rejectCode = rejCode 397 } 398 str := fmt.Sprintf("transaction output %d: %v", i, err) 399 return txRuleError(rejectCode, str) 400 } 401 402 // Accumulate the number of outputs which only carry data. For 403 // all other script types, ensure the output value is not 404 // "dust". 405 if scriptClass == txscript.NullDataTy { 406 numNullDataOutputs++ 407 } else if isDust(txOut, minRelayTxFee) { 408 str := fmt.Sprintf("transaction output %d: payment "+ 409 "of %d is dust", i, txOut.Value) 410 return txRuleError(wire.RejectDust, str) 411 } 412 } 413 414 // A standard transaction must not have more than one output script that 415 // only carries data. 416 if numNullDataOutputs > 1 { 417 str := "more than one transaction output in a nulldata script" 418 return txRuleError(wire.RejectNonstandard, str) 419 } 420 421 return nil 422 } 423 424 // minInt is a helper function to return the minimum of two ints. This avoids 425 // a math import and the need to cast to floats. 426 func minInt(a, b int) int { 427 if a < b { 428 return a 429 } 430 return b 431 }