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

     1  // Copyright (c) 2013-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 mempool
     6  
     7  import (
     8  	"fmt"
     9  	"time"
    10  
    11  	"github.com/palcoin-project/palcd/blockchain"
    12  	"github.com/palcoin-project/palcd/txscript"
    13  	"github.com/palcoin-project/palcd/wire"
    14  	"github.com/palcoin-project/palcutil"
    15  )
    16  
    17  const (
    18  	// maxStandardP2SHSigOps is the maximum number of signature operations
    19  	// that are considered standard in a pay-to-script-hash script.
    20  	maxStandardP2SHSigOps = 15
    21  
    22  	// maxStandardTxCost is the max weight permitted by any transaction
    23  	// according to the current default policy.
    24  	maxStandardTxWeight = 400000
    25  
    26  	// maxStandardSigScriptSize is the maximum size allowed for a
    27  	// transaction input signature script to be considered standard.  This
    28  	// value allows for a 15-of-15 CHECKMULTISIG pay-to-script-hash with
    29  	// compressed keys.
    30  	//
    31  	// The form of the overall script is: OP_0 <15 signatures> OP_PUSHDATA2
    32  	// <2 bytes len> [OP_15 <15 pubkeys> OP_15 OP_CHECKMULTISIG]
    33  	//
    34  	// For the p2sh script portion, each of the 15 compressed pubkeys are
    35  	// 33 bytes (plus one for the OP_DATA_33 opcode), and the thus it totals
    36  	// to (15*34)+3 = 513 bytes.  Next, each of the 15 signatures is a max
    37  	// of 73 bytes (plus one for the OP_DATA_73 opcode).  Also, there is one
    38  	// extra byte for the initial extra OP_0 push and 3 bytes for the
    39  	// OP_PUSHDATA2 needed to specify the 513 bytes for the script push.
    40  	// That brings the total to 1+(15*74)+3+513 = 1627.  This value also
    41  	// adds a few extra bytes to provide a little buffer.
    42  	// (1 + 15*74 + 3) + (15*34 + 3) + 23 = 1650
    43  	maxStandardSigScriptSize = 1650
    44  
    45  	// DefaultMinRelayTxFee is the minimum fee in satoshi that is required
    46  	// for a transaction to be treated as free for relay and mining
    47  	// purposes.  It is also used to help determine if a transaction is
    48  	// considered dust and as a base for calculating minimum required fees
    49  	// for larger transactions.  This value is in Satoshi/1000 bytes.
    50  	DefaultMinRelayTxFee = palcutil.Amount(1000)
    51  
    52  	// maxStandardMultiSigKeys is the maximum number of public keys allowed
    53  	// in a multi-signature transaction output script for it to be
    54  	// considered standard.
    55  	maxStandardMultiSigKeys = 3
    56  )
    57  
    58  // calcMinRequiredTxRelayFee returns the minimum transaction fee required for a
    59  // transaction with the passed serialized size to be accepted into the memory
    60  // pool and relayed.
    61  func calcMinRequiredTxRelayFee(serializedSize int64, minRelayTxFee palcutil.Amount) int64 {
    62  	// Calculate the minimum fee for a transaction to be allowed into the
    63  	// mempool and relayed by scaling the base fee (which is the minimum
    64  	// free transaction relay fee).  minRelayTxFee is in Satoshi/kB so
    65  	// multiply by serializedSize (which is in bytes) and divide by 1000 to
    66  	// get minimum Satoshis.
    67  	minFee := (serializedSize * int64(minRelayTxFee)) / 1000
    68  
    69  	if minFee == 0 && minRelayTxFee > 0 {
    70  		minFee = int64(minRelayTxFee)
    71  	}
    72  
    73  	// Set the minimum fee to the maximum possible value if the calculated
    74  	// fee is not in the valid range for monetary amounts.
    75  	if minFee < 0 || minFee > palcutil.MaxSatoshi {
    76  		minFee = palcutil.MaxSatoshi
    77  	}
    78  
    79  	return minFee
    80  }
    81  
    82  // checkInputsStandard performs a series of checks on a transaction's inputs
    83  // to ensure they are "standard".  A standard transaction input within the
    84  // context of this function is one whose referenced public key script is of a
    85  // standard form and, for pay-to-script-hash, does not have more than
    86  // maxStandardP2SHSigOps signature operations.  However, it should also be noted
    87  // that standard inputs also are those which have a clean stack after execution
    88  // and only contain pushed data in their signature scripts.  This function does
    89  // not perform those checks because the script engine already does this more
    90  // accurately and concisely via the txscript.ScriptVerifyCleanStack and
    91  // txscript.ScriptVerifySigPushOnly flags.
    92  func checkInputsStandard(tx *palcutil.Tx, utxoView *blockchain.UtxoViewpoint) error {
    93  	// NOTE: The reference implementation also does a coinbase check here,
    94  	// but coinbases have already been rejected prior to calling this
    95  	// function so no need to recheck.
    96  
    97  	for i, txIn := range tx.MsgTx().TxIn {
    98  		// It is safe to elide existence and index checks here since
    99  		// they have already been checked prior to calling this
   100  		// function.
   101  		entry := utxoView.LookupEntry(txIn.PreviousOutPoint)
   102  		originPkScript := entry.PkScript()
   103  		switch txscript.GetScriptClass(originPkScript) {
   104  		case txscript.ScriptHashTy:
   105  			numSigOps := txscript.GetPreciseSigOpCount(
   106  				txIn.SignatureScript, originPkScript, true)
   107  			if numSigOps > maxStandardP2SHSigOps {
   108  				str := fmt.Sprintf("transaction input #%d has "+
   109  					"%d signature operations which is more "+
   110  					"than the allowed max amount of %d",
   111  					i, numSigOps, maxStandardP2SHSigOps)
   112  				return txRuleError(wire.RejectNonstandard, str)
   113  			}
   114  
   115  		case txscript.NonStandardTy:
   116  			str := fmt.Sprintf("transaction input #%d has a "+
   117  				"non-standard script form", i)
   118  			return txRuleError(wire.RejectNonstandard, str)
   119  		}
   120  	}
   121  
   122  	return nil
   123  }
   124  
   125  // checkPkScriptStandard performs a series of checks on a transaction output
   126  // script (public key script) to ensure it is a "standard" public key script.
   127  // A standard public key script is one that is a recognized form, and for
   128  // multi-signature scripts, only contains from 1 to maxStandardMultiSigKeys
   129  // public keys.
   130  func checkPkScriptStandard(pkScript []byte, scriptClass txscript.ScriptClass) error {
   131  	switch scriptClass {
   132  	case txscript.MultiSigTy:
   133  		numPubKeys, numSigs, err := txscript.CalcMultiSigStats(pkScript)
   134  		if err != nil {
   135  			str := fmt.Sprintf("multi-signature script parse "+
   136  				"failure: %v", err)
   137  			return txRuleError(wire.RejectNonstandard, str)
   138  		}
   139  
   140  		// A standard multi-signature public key script must contain
   141  		// from 1 to maxStandardMultiSigKeys public keys.
   142  		if numPubKeys < 1 {
   143  			str := "multi-signature script with no pubkeys"
   144  			return txRuleError(wire.RejectNonstandard, str)
   145  		}
   146  		if numPubKeys > maxStandardMultiSigKeys {
   147  			str := fmt.Sprintf("multi-signature script with %d "+
   148  				"public keys which is more than the allowed "+
   149  				"max of %d", numPubKeys, maxStandardMultiSigKeys)
   150  			return txRuleError(wire.RejectNonstandard, str)
   151  		}
   152  
   153  		// A standard multi-signature public key script must have at
   154  		// least 1 signature and no more signatures than available
   155  		// public keys.
   156  		if numSigs < 1 {
   157  			return txRuleError(wire.RejectNonstandard,
   158  				"multi-signature script with no signatures")
   159  		}
   160  		if numSigs > numPubKeys {
   161  			str := fmt.Sprintf("multi-signature script with %d "+
   162  				"signatures which is more than the available "+
   163  				"%d public keys", numSigs, numPubKeys)
   164  			return txRuleError(wire.RejectNonstandard, str)
   165  		}
   166  
   167  	case txscript.NonStandardTy:
   168  		return txRuleError(wire.RejectNonstandard,
   169  			"non-standard script form")
   170  	}
   171  
   172  	return nil
   173  }
   174  
   175  // IsDust returns whether or not the passed transaction output amount is
   176  // considered dust or not based on the passed minimum transaction relay fee.
   177  // Dust is defined in terms of the minimum transaction relay fee.  In
   178  // particular, if the cost to the network to spend coins is more than 1/3 of the
   179  // minimum transaction relay fee, it is considered dust.
   180  func IsDust(txOut *wire.TxOut, minRelayTxFee palcutil.Amount) bool {
   181  	// Unspendable outputs are considered dust.
   182  	if txscript.IsUnspendable(txOut.PkScript) {
   183  		return true
   184  	}
   185  
   186  	// The total serialized size consists of the output and the associated
   187  	// input script to redeem it.  Since there is no input script
   188  	// to redeem it yet, use the minimum size of a typical input script.
   189  	//
   190  	// Pay-to-pubkey-hash bytes breakdown:
   191  	//
   192  	//  Output to hash (34 bytes):
   193  	//   8 value, 1 script len, 25 script [1 OP_DUP, 1 OP_HASH_160,
   194  	//   1 OP_DATA_20, 20 hash, 1 OP_EQUALVERIFY, 1 OP_CHECKSIG]
   195  	//
   196  	//  Input with compressed pubkey (148 bytes):
   197  	//   36 prev outpoint, 1 script len, 107 script [1 OP_DATA_72, 72 sig,
   198  	//   1 OP_DATA_33, 33 compressed pubkey], 4 sequence
   199  	//
   200  	//  Input with uncompressed pubkey (180 bytes):
   201  	//   36 prev outpoint, 1 script len, 139 script [1 OP_DATA_72, 72 sig,
   202  	//   1 OP_DATA_65, 65 compressed pubkey], 4 sequence
   203  	//
   204  	// Pay-to-pubkey bytes breakdown:
   205  	//
   206  	//  Output to compressed pubkey (44 bytes):
   207  	//   8 value, 1 script len, 35 script [1 OP_DATA_33,
   208  	//   33 compressed pubkey, 1 OP_CHECKSIG]
   209  	//
   210  	//  Output to uncompressed pubkey (76 bytes):
   211  	//   8 value, 1 script len, 67 script [1 OP_DATA_65, 65 pubkey,
   212  	//   1 OP_CHECKSIG]
   213  	//
   214  	//  Input (114 bytes):
   215  	//   36 prev outpoint, 1 script len, 73 script [1 OP_DATA_72,
   216  	//   72 sig], 4 sequence
   217  	//
   218  	// Pay-to-witness-pubkey-hash bytes breakdown:
   219  	//
   220  	//  Output to witness key hash (31 bytes);
   221  	//   8 value, 1 script len, 22 script [1 OP_0, 1 OP_DATA_20,
   222  	//   20 bytes hash160]
   223  	//
   224  	//  Input (67 bytes as the 107 witness stack is discounted):
   225  	//   36 prev outpoint, 1 script len, 0 script (not sigScript), 107
   226  	//   witness stack bytes [1 element length, 33 compressed pubkey,
   227  	//   element length 72 sig], 4 sequence
   228  	//
   229  	//
   230  	// Theoretically this could examine the script type of the output script
   231  	// and use a different size for the typical input script size for
   232  	// pay-to-pubkey vs pay-to-pubkey-hash inputs per the above breakdowns,
   233  	// but the only combination which is less than the value chosen is
   234  	// a pay-to-pubkey script with a compressed pubkey, which is not very
   235  	// common.
   236  	//
   237  	// The most common scripts are pay-to-pubkey-hash, and as per the above
   238  	// breakdown, the minimum size of a p2pkh input script is 148 bytes.  So
   239  	// that figure is used. If the output being spent is a witness program,
   240  	// then we apply the witness discount to the size of the signature.
   241  	//
   242  	// The segwit analogue to p2pkh is a p2wkh output. This is the smallest
   243  	// output possible using the new segwit features. The 107 bytes of
   244  	// witness data is discounted by a factor of 4, leading to a computed
   245  	// value of 67 bytes of witness data.
   246  	//
   247  	// Both cases share a 41 byte preamble required to reference the input
   248  	// being spent and the sequence number of the input.
   249  	totalSize := txOut.SerializeSize() + 41
   250  	if txscript.IsWitnessProgram(txOut.PkScript) {
   251  		totalSize += (107 / blockchain.WitnessScaleFactor)
   252  	} else {
   253  		totalSize += 107
   254  	}
   255  
   256  	// The output is considered dust if the cost to the network to spend the
   257  	// coins is more than 1/3 of the minimum free transaction relay fee.
   258  	// minFreeTxRelayFee is in Satoshi/KB, so multiply by 1000 to
   259  	// convert to bytes.
   260  	//
   261  	// Using the typical values for a pay-to-pubkey-hash transaction from
   262  	// the breakdown above and the default minimum free transaction relay
   263  	// fee of 1000, this equates to values less than 546 satoshi being
   264  	// considered dust.
   265  	//
   266  	// The following is equivalent to (value/totalSize) * (1/3) * 1000
   267  	// without needing to do floating point math.
   268  	return txOut.Value*1000/(3*int64(totalSize)) < int64(minRelayTxFee)
   269  }
   270  
   271  // checkTransactionStandard performs a series of checks on a transaction to
   272  // ensure it is a "standard" transaction.  A standard transaction is one that
   273  // conforms to several additional limiting cases over what is considered a
   274  // "sane" transaction such as having a version in the supported range, being
   275  // finalized, conforming to more stringent size constraints, having scripts
   276  // of recognized forms, and not containing "dust" outputs (those that are
   277  // so small it costs more to process them than they are worth).
   278  func checkTransactionStandard(tx *palcutil.Tx, height int32,
   279  	medianTimePast time.Time, minRelayTxFee palcutil.Amount,
   280  	maxTxVersion int32) error {
   281  
   282  	// The transaction must be a currently supported version.
   283  	msgTx := tx.MsgTx()
   284  	if msgTx.Version > maxTxVersion || msgTx.Version < 1 {
   285  		str := fmt.Sprintf("transaction version %d is not in the "+
   286  			"valid range of %d-%d", msgTx.Version, 1,
   287  			maxTxVersion)
   288  		return txRuleError(wire.RejectNonstandard, str)
   289  	}
   290  
   291  	// The transaction must be finalized to be standard and therefore
   292  	// considered for inclusion in a block.
   293  	if !blockchain.IsFinalizedTransaction(tx, height, medianTimePast) {
   294  		return txRuleError(wire.RejectNonstandard,
   295  			"transaction is not finalized")
   296  	}
   297  
   298  	// Since extremely large transactions with a lot of inputs can cost
   299  	// almost as much to process as the sender fees, limit the maximum
   300  	// size of a transaction.  This also helps mitigate CPU exhaustion
   301  	// attacks.
   302  	txWeight := blockchain.GetTransactionWeight(tx)
   303  	if txWeight > maxStandardTxWeight {
   304  		str := fmt.Sprintf("weight of transaction %v is larger than max "+
   305  			"allowed weight of %v", txWeight, maxStandardTxWeight)
   306  		return txRuleError(wire.RejectNonstandard, str)
   307  	}
   308  
   309  	for i, txIn := range msgTx.TxIn {
   310  		// Each transaction input signature script must not exceed the
   311  		// maximum size allowed for a standard transaction.  See
   312  		// the comment on maxStandardSigScriptSize for more details.
   313  		sigScriptLen := len(txIn.SignatureScript)
   314  		if sigScriptLen > maxStandardSigScriptSize {
   315  			str := fmt.Sprintf("transaction input %d: signature "+
   316  				"script size of %d bytes is large than max "+
   317  				"allowed size of %d bytes", i, sigScriptLen,
   318  				maxStandardSigScriptSize)
   319  			return txRuleError(wire.RejectNonstandard, str)
   320  		}
   321  
   322  		// Each transaction input signature script must only contain
   323  		// opcodes which push data onto the stack.
   324  		if !txscript.IsPushOnlyScript(txIn.SignatureScript) {
   325  			str := fmt.Sprintf("transaction input %d: signature "+
   326  				"script is not push only", i)
   327  			return txRuleError(wire.RejectNonstandard, str)
   328  		}
   329  	}
   330  
   331  	// None of the output public key scripts can be a non-standard script or
   332  	// be "dust" (except when the script is a null data script).
   333  	numNullDataOutputs := 0
   334  	for i, txOut := range msgTx.TxOut {
   335  		scriptClass := txscript.GetScriptClass(txOut.PkScript)
   336  		err := checkPkScriptStandard(txOut.PkScript, scriptClass)
   337  		if err != nil {
   338  			// Attempt to extract a reject code from the error so
   339  			// it can be retained.  When not possible, fall back to
   340  			// a non standard error.
   341  			rejectCode := wire.RejectNonstandard
   342  			if rejCode, found := extractRejectCode(err); found {
   343  				rejectCode = rejCode
   344  			}
   345  			str := fmt.Sprintf("transaction output %d: %v", i, err)
   346  			return txRuleError(rejectCode, str)
   347  		}
   348  
   349  		// Accumulate the number of outputs which only carry data.  For
   350  		// all other script types, ensure the output value is not
   351  		// "dust".
   352  		if scriptClass == txscript.NullDataTy {
   353  			numNullDataOutputs++
   354  		} else if IsDust(txOut, minRelayTxFee) {
   355  			str := fmt.Sprintf("transaction output %d: payment "+
   356  				"of %d is dust", i, txOut.Value)
   357  			return txRuleError(wire.RejectDust, str)
   358  		}
   359  	}
   360  
   361  	// A standard transaction must not have more than one output script that
   362  	// only carries data.
   363  	if numNullDataOutputs > 1 {
   364  		str := "more than one transaction output in a nulldata script"
   365  		return txRuleError(wire.RejectNonstandard, str)
   366  	}
   367  
   368  	return nil
   369  }
   370  
   371  // GetTxVirtualSize computes the virtual size of a given transaction. A
   372  // transaction's virtual size is based off its weight, creating a discount for
   373  // any witness data it contains, proportional to the current
   374  // blockchain.WitnessScaleFactor value.
   375  func GetTxVirtualSize(tx *palcutil.Tx) int64 {
   376  	// vSize := (weight(tx) + 3) / 4
   377  	//       := (((baseSize * 3) + totalSize) + 3) / 4
   378  	// We add 3 here as a way to compute the ceiling of the prior arithmetic
   379  	// to 4. The division by 4 creates a discount for wit witness data.
   380  	return (blockchain.GetTransactionWeight(tx) + (blockchain.WitnessScaleFactor - 1)) /
   381  		blockchain.WitnessScaleFactor
   382  }