diff --git a/blockchain/validate.go b/blockchain/validate.go index 2fd5d7fd..ef2c283b 100644 --- a/blockchain/validate.go +++ b/blockchain/validate.go @@ -231,8 +231,8 @@ func withinLevelBounds(reduction int64, lv int64) bool { } // CheckTransactionSanity performs some preliminary checks on a transaction to -// ensure it is sane. These checks are context free. -func CheckTransactionSanity(tx *btcutil.Tx) error { +// ensure it is sane. +func CheckTransactionSanity(tx *btcutil.Tx, enforceSoftFork bool) error { // A transaction must have at least one input. msgTx := tx.MsgTx() if len(msgTx.TxIn) == 0 { @@ -291,6 +291,11 @@ func CheckTransactionSanity(tx *btcutil.Tx) error { btcutil.MaxSatoshi) return ruleError(ErrBadTxOutValue, str) } + + err := txscript.AllClaimsAreSane(txOut.PkScript, enforceSoftFork) + if err != nil { + return ruleError(ErrBadTxOutValue, err.Error()) + } } // Check for duplicate transaction inputs. @@ -545,7 +550,7 @@ func checkBlockSanity(block *btcutil.Block, powLimit *big.Int, timeSource Median // Do some preliminary checks on each transaction to ensure they are // sane before continuing. for _, tx := range transactions { - err := CheckTransactionSanity(tx) + err := CheckTransactionSanity(tx, false) if err != nil { return err } diff --git a/mempool/mempool.go b/mempool/mempool.go index b54856c8..0aecff7e 100644 --- a/mempool/mempool.go +++ b/mempool/mempool.go @@ -963,7 +963,7 @@ func (mp *TxPool) maybeAcceptTransaction(tx *btcutil.Tx, isNew, rateLimit, rejec // Perform preliminary sanity checks on the transaction. This makes // use of blockchain which contains the invariant rules for what // transactions are allowed into blocks. - err := blockchain.CheckTransactionSanity(tx) + err := blockchain.CheckTransactionSanity(tx, true) if err != nil { if cerr, ok := err.(blockchain.RuleError); ok { return nil, nil, chainRuleError(cerr) diff --git a/mempool/policy.go b/mempool/policy.go index 1fe85079..c18b0d7d 100644 --- a/mempool/policy.go +++ b/mempool/policy.go @@ -99,7 +99,7 @@ func checkInputsStandard(tx *btcutil.Tx, utxoView *blockchain.UtxoViewpoint) err // they have already been checked prior to calling this // function. entry := utxoView.LookupEntry(txIn.PreviousOutPoint) - originPkScript := entry.PkScript() + originPkScript := txscript.StripClaimScriptPrefix(entry.PkScript()) switch txscript.GetScriptClass(originPkScript) { case txscript.ScriptHashTy: numSigOps := txscript.GetPreciseSigOpCount( @@ -339,8 +339,9 @@ func checkTransactionStandard(tx *btcutil.Tx, height int32, // be "dust" (except when the script is a null data script). numNullDataOutputs := 0 for i, txOut := range msgTx.TxOut { - scriptClass := txscript.GetScriptClass(txOut.PkScript) - err := checkPkScriptStandard(txOut.PkScript, scriptClass) + pkScript := txscript.StripClaimScriptPrefix(txOut.PkScript) + scriptClass := txscript.GetScriptClass(pkScript) + err := checkPkScriptStandard(pkScript, scriptClass) if err != nil { // Attempt to extract a reject code from the error so // it can be retained. When not possible, fall back to