From 7854bff5b29ad3ee467de66660fbc7806ce7aa81 Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Fri, 15 Jun 2018 13:06:26 -0700 Subject: [PATCH] [lbry] blockchain, mempool: validate txscripts Co-authored-by: Brannon King --- blockchain/validate.go | 11 ++++++++--- mempool/mempool.go | 10 +++++++++- mempool/policy.go | 7 ++++--- 3 files changed, 21 insertions(+), 7 deletions(-) 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 7ada3d29..65d8e8cf 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) @@ -1155,6 +1155,14 @@ func (mp *TxPool) maybeAcceptTransaction(tx *btcutil.Tx, isNew, rateLimit, rejec return nil, nil, txRuleError(wire.RejectInsufficientFee, str) } + minFee = txscript.CalcMinClaimTrieFee(tx.MsgTx(), txscript.MinFeePerNameclaimChar) + if txFee < minFee { + str := fmt.Sprintf("transaction %v has %d fees which is under "+ + "the required amount of %d for Claims", txHash, txFee, + minFee) + return nil, nil, txRuleError(wire.RejectInsufficientFee, str) + } + // Require that free transactions have sufficient priority to be mined // in the next block. Transactions which are being added back to the // memory pool from blocks that have been disconnected during a reorg diff --git a/mempool/policy.go b/mempool/policy.go index 7e973293..a58f110b 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( @@ -332,8 +332,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