From 9238ecb41752e097443d0bc117df35ebd4ac932e Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Sat, 11 Oct 2014 22:41:05 +0000 Subject: Policy: MOVEONLY: 3 functions to policy.o: - [script/standard.o] IsStandard - [main.o] IsStandardTx - [main.o] AreInputsStandard Also, don't use namespace std in policy.cpp --- src/policy/policy.cpp | 178 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 178 insertions(+) create mode 100644 src/policy/policy.cpp (limited to 'src/policy/policy.cpp') diff --git a/src/policy/policy.cpp b/src/policy/policy.cpp new file mode 100644 index 000000000..169fef4af --- /dev/null +++ b/src/policy/policy.cpp @@ -0,0 +1,178 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2014 The Bitcoin developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +// NOTE: This file is intended to be customised by the end user, and includes only local node policy logic + +#include "policy/policy.h" + +#include "main.h" +#include "tinyformat.h" +#include "util.h" +#include "utilstrencodings.h" + +#include + + /** + * Check transaction inputs to mitigate two + * potential denial-of-service attacks: + * + * 1. scriptSigs with extra data stuffed into them, + * not consumed by scriptPubKey (or P2SH script) + * 2. P2SH scripts with a crazy number of expensive + * CHECKSIG/CHECKMULTISIG operations + * + * Check transaction inputs, and make sure any + * pay-to-script-hash transactions are evaluating IsStandard scripts + * + * Why bother? To avoid denial-of-service attacks; an attacker + * can submit a standard HASH... OP_EQUAL transaction, + * which will get accepted into blocks. The redemption + * script can be anything; an attacker could use a very + * expensive-to-check-upon-redemption script like: + * DUP CHECKSIG DROP ... repeated 100 times... OP_1 + */ + +bool IsStandard(const CScript& scriptPubKey, txnouttype& whichType) +{ + std::vector > vSolutions; + if (!Solver(scriptPubKey, whichType, vSolutions)) + return false; + + if (whichType == TX_MULTISIG) + { + unsigned char m = vSolutions.front()[0]; + unsigned char n = vSolutions.back()[0]; + // Support up to x-of-3 multisig txns as standard + if (n < 1 || n > 3) + return false; + if (m < 1 || m > n) + return false; + } + + return whichType != TX_NONSTANDARD; +} + +bool IsStandardTx(const CTransaction& tx, std::string& reason) +{ + if (tx.nVersion > CTransaction::CURRENT_VERSION || tx.nVersion < 1) { + reason = "version"; + return false; + } + + // Extremely large transactions with lots of inputs can cost the network + // almost as much to process as they cost the sender in fees, because + // computing signature hashes is O(ninputs*txsize). Limiting transactions + // to MAX_STANDARD_TX_SIZE mitigates CPU exhaustion attacks. + unsigned int sz = tx.GetSerializeSize(SER_NETWORK, CTransaction::CURRENT_VERSION); + if (sz >= MAX_STANDARD_TX_SIZE) { + reason = "tx-size"; + return false; + } + + BOOST_FOREACH(const CTxIn& txin, tx.vin) + { + // Biggest 'standard' txin is a 15-of-15 P2SH multisig with compressed + // keys. (remember the 520 byte limit on redeemScript size) That works + // out to a (15*(33+1))+3=513 byte redeemScript, 513+1+15*(73+1)+3=1627 + // bytes of scriptSig, which we round off to 1650 bytes for some minor + // future-proofing. That's also enough to spend a 20-of-20 + // CHECKMULTISIG scriptPubKey, though such a scriptPubKey is not + // considered standard) + if (txin.scriptSig.size() > 1650) { + reason = "scriptsig-size"; + return false; + } + if (!txin.scriptSig.IsPushOnly()) { + reason = "scriptsig-not-pushonly"; + return false; + } + } + + unsigned int nDataOut = 0; + txnouttype whichType; + BOOST_FOREACH(const CTxOut& txout, tx.vout) { + if (!::IsStandard(txout.scriptPubKey, whichType)) { + reason = "scriptpubkey"; + return false; + } + + if (whichType == TX_NULL_DATA) + nDataOut++; + else if ((whichType == TX_MULTISIG) && (!fIsBareMultisigStd)) { + reason = "bare-multisig"; + return false; + } else if (txout.IsDust(::minRelayTxFee)) { + reason = "dust"; + return false; + } + } + + // only one OP_RETURN txout is permitted + if (nDataOut > 1) { + reason = "multi-op-return"; + return false; + } + + return true; +} + +bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs) +{ + if (tx.IsCoinBase()) + return true; // Coinbases don't use vin normally + + for (unsigned int i = 0; i < tx.vin.size(); i++) + { + const CTxOut& prev = mapInputs.GetOutputFor(tx.vin[i]); + + std::vector > vSolutions; + txnouttype whichType; + // get the scriptPubKey corresponding to this input: + const CScript& prevScript = prev.scriptPubKey; + if (!Solver(prevScript, whichType, vSolutions)) + return false; + int nArgsExpected = ScriptSigArgsExpected(whichType, vSolutions); + if (nArgsExpected < 0) + return false; + + // Transactions with extra stuff in their scriptSigs are + // non-standard. Note that this EvalScript() call will + // be quick, because if there are any operations + // beside "push data" in the scriptSig + // IsStandardTx() will have already returned false + // and this method isn't called. + std::vector > stack; + if (!EvalScript(stack, tx.vin[i].scriptSig, SCRIPT_VERIFY_NONE, BaseSignatureChecker())) + return false; + + if (whichType == TX_SCRIPTHASH) + { + if (stack.empty()) + return false; + CScript subscript(stack.back().begin(), stack.back().end()); + std::vector > vSolutions2; + txnouttype whichType2; + if (Solver(subscript, whichType2, vSolutions2)) + { + int tmpExpected = ScriptSigArgsExpected(whichType2, vSolutions2); + if (tmpExpected < 0) + return false; + nArgsExpected += tmpExpected; + } + else + { + // Any other Script with less than 15 sigops OK: + unsigned int sigops = subscript.GetSigOpCount(true); + // ... extra data left on the stack after execution is OK, too: + return (sigops <= MAX_P2SH_SIGOPS); + } + } + + if (stack.size() != (unsigned int)nArgsExpected) + return false; + } + + return true; +} -- cgit v1.2.3 From da894ab5da222ad317039eb008ec6443fb9113d9 Mon Sep 17 00:00:00 2001 From: Peter Todd Date: Mon, 13 Oct 2014 10:18:05 -0400 Subject: Accept any sequence of PUSHDATAs in OP_RETURN outputs Previously only one PUSHDATA was allowed, needlessly limiting applications such as matching OP_RETURN contents with bloom filters that operate on a per-PUSHDATA level. Now any combination that passes IsPushOnly() is allowed, so long as the total size of the scriptPubKey is less than 42 bytes. (unchanged modulo non-minimal PUSHDATA encodings) Also, this fixes the odd bug where previously the PUSHDATA could be replaced by any single opcode, even sigops consuming opcodes such as CHECKMULTISIG. (20 sigops!) --- src/policy/policy.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/policy/policy.cpp') diff --git a/src/policy/policy.cpp b/src/policy/policy.cpp index 169fef4af..4c96fbf5a 100644 --- a/src/policy/policy.cpp +++ b/src/policy/policy.cpp @@ -49,7 +49,9 @@ bool IsStandard(const CScript& scriptPubKey, txnouttype& whichType) return false; if (m < 1 || m > n) return false; - } + } else if (whichType == TX_NULL_DATA && + (!GetBoolArg("-datacarrier", true) || scriptPubKey.size() > nMaxDatacarrierBytes)) + return false; return whichType != TX_NONSTANDARD; } -- cgit v1.2.3 From b966aa836a3bc5bfa1314248258308f0026d41bb Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Sat, 27 Jun 2015 19:21:41 +0000 Subject: Constrain constant values to a single location in code --- src/policy/policy.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/policy/policy.cpp') diff --git a/src/policy/policy.cpp b/src/policy/policy.cpp index 4c96fbf5a..46c7f1894 100644 --- a/src/policy/policy.cpp +++ b/src/policy/policy.cpp @@ -50,7 +50,7 @@ bool IsStandard(const CScript& scriptPubKey, txnouttype& whichType) if (m < 1 || m > n) return false; } else if (whichType == TX_NULL_DATA && - (!GetBoolArg("-datacarrier", true) || scriptPubKey.size() > nMaxDatacarrierBytes)) + (!fAcceptDatacarrier || scriptPubKey.size() > nMaxDatacarrierBytes)) return false; return whichType != TX_NONSTANDARD; -- cgit v1.2.3 From fa24439ff3d8ab5b9efaf66ef4dae6713b88cb35 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Sun, 13 Dec 2015 17:58:29 +0100 Subject: Bump copyright headers to 2015 --- src/policy/policy.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/policy/policy.cpp') diff --git a/src/policy/policy.cpp b/src/policy/policy.cpp index 46c7f1894..273a482fa 100644 --- a/src/policy/policy.cpp +++ b/src/policy/policy.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2015 The Bitcoin developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -- cgit v1.2.3 From 6cd198f3807c9b4e9753f997f2af4a704fc0e147 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcel=20Kr=C3=BCger?= Date: Wed, 30 Dec 2015 21:53:40 +0100 Subject: Removed comment about IsStandard for P2SH scripts Since #4365 (62599373883a66a958136f48ab0e2b826e3d5bf8) P2SH scripts do not have to be IsStandard scripts. --- src/policy/policy.cpp | 3 --- 1 file changed, 3 deletions(-) (limited to 'src/policy/policy.cpp') diff --git a/src/policy/policy.cpp b/src/policy/policy.cpp index 46c7f1894..75bd4ba0d 100644 --- a/src/policy/policy.cpp +++ b/src/policy/policy.cpp @@ -23,9 +23,6 @@ * 2. P2SH scripts with a crazy number of expensive * CHECKSIG/CHECKMULTISIG operations * - * Check transaction inputs, and make sure any - * pay-to-script-hash transactions are evaluating IsStandard scripts - * * Why bother? To avoid denial-of-service attacks; an attacker * can submit a standard HASH... OP_EQUAL transaction, * which will get accepted into blocks. The redemption -- cgit v1.2.3 From 5d743099b5fe77ba423110bea4f5dfd854fef3b2 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Thu, 21 Jan 2016 13:15:19 +0100 Subject: Get rid of inaccurate ScriptSigArgsExpected (cherry picked from commit 52b29dca7670c3f6d2ab918c0fff1d17c4e494ad) --- src/policy/policy.cpp | 37 ++++++------------------------------- 1 file changed, 6 insertions(+), 31 deletions(-) (limited to 'src/policy/policy.cpp') diff --git a/src/policy/policy.cpp b/src/policy/policy.cpp index 019df7227..332abc430 100644 --- a/src/policy/policy.cpp +++ b/src/policy/policy.cpp @@ -132,45 +132,20 @@ bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs) const CScript& prevScript = prev.scriptPubKey; if (!Solver(prevScript, whichType, vSolutions)) return false; - int nArgsExpected = ScriptSigArgsExpected(whichType, vSolutions); - if (nArgsExpected < 0) - return false; - - // Transactions with extra stuff in their scriptSigs are - // non-standard. Note that this EvalScript() call will - // be quick, because if there are any operations - // beside "push data" in the scriptSig - // IsStandardTx() will have already returned false - // and this method isn't called. - std::vector > stack; - if (!EvalScript(stack, tx.vin[i].scriptSig, SCRIPT_VERIFY_NONE, BaseSignatureChecker())) - return false; if (whichType == TX_SCRIPTHASH) { + std::vector > stack; + // convert the scriptSig into a stack, so we can inspect the redeemScript + if (!EvalScript(stack, tx.vin[i].scriptSig, SCRIPT_VERIFY_NONE, BaseSignatureChecker(), 0)) + return false; if (stack.empty()) return false; CScript subscript(stack.back().begin(), stack.back().end()); - std::vector > vSolutions2; - txnouttype whichType2; - if (Solver(subscript, whichType2, vSolutions2)) - { - int tmpExpected = ScriptSigArgsExpected(whichType2, vSolutions2); - if (tmpExpected < 0) - return false; - nArgsExpected += tmpExpected; - } - else - { - // Any other Script with less than 15 sigops OK: - unsigned int sigops = subscript.GetSigOpCount(true); - // ... extra data left on the stack after execution is OK, too: - return (sigops <= MAX_P2SH_SIGOPS); + if (subscript.GetSigOpCount(true) > MAX_P2SH_SIGOPS) { + return false; } } - - if (stack.size() != (unsigned int)nArgsExpected) - return false; } return true; -- cgit v1.2.3 From 12c89c918534f8e615e80381b692d89d6b09d174 Mon Sep 17 00:00:00 2001 From: BtcDrak Date: Fri, 19 Feb 2016 19:52:31 +0000 Subject: Policy: allow transaction version 2 relay policy. This commit introduces a way to gracefully bump the default transaction version in a two step process. --- src/policy/policy.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/policy/policy.cpp') diff --git a/src/policy/policy.cpp b/src/policy/policy.cpp index 332abc430..e3ed7be00 100644 --- a/src/policy/policy.cpp +++ b/src/policy/policy.cpp @@ -55,7 +55,7 @@ bool IsStandard(const CScript& scriptPubKey, txnouttype& whichType) bool IsStandardTx(const CTransaction& tx, std::string& reason) { - if (tx.nVersion > CTransaction::CURRENT_VERSION || tx.nVersion < 1) { + if (tx.nVersion > CTransaction::MAX_STANDARD_VERSION || tx.nVersion < 1) { reason = "version"; return false; } -- cgit v1.2.3 From 03c77fdc143fb8d533011f23164daac560e381b2 Mon Sep 17 00:00:00 2001 From: Matthew English Date: Fri, 1 Apr 2016 23:44:26 +0200 Subject: Doc: Update isStandardTx comment --- src/policy/policy.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/policy/policy.cpp') diff --git a/src/policy/policy.cpp b/src/policy/policy.cpp index e3ed7be00..d1a15451d 100644 --- a/src/policy/policy.cpp +++ b/src/policy/policy.cpp @@ -73,12 +73,12 @@ bool IsStandardTx(const CTransaction& tx, std::string& reason) BOOST_FOREACH(const CTxIn& txin, tx.vin) { // Biggest 'standard' txin is a 15-of-15 P2SH multisig with compressed - // keys. (remember the 520 byte limit on redeemScript size) That works + // keys (remember the 520 byte limit on redeemScript size). That works // out to a (15*(33+1))+3=513 byte redeemScript, 513+1+15*(73+1)+3=1627 // bytes of scriptSig, which we round off to 1650 bytes for some minor // future-proofing. That's also enough to spend a 20-of-20 // CHECKMULTISIG scriptPubKey, though such a scriptPubKey is not - // considered standard) + // considered standard. if (txin.scriptSig.size() > 1650) { reason = "scriptsig-size"; return false; -- cgit v1.2.3 From 3dd410294d42f251e4808ef1dfcfcd64817edbac Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Sun, 27 Dec 2015 19:49:08 +0100 Subject: BIP143: Verification logic Includes simplifications by Eric Lombrozo. --- src/policy/policy.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/policy/policy.cpp') diff --git a/src/policy/policy.cpp b/src/policy/policy.cpp index d1a15451d..67434a38f 100644 --- a/src/policy/policy.cpp +++ b/src/policy/policy.cpp @@ -137,7 +137,7 @@ bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs) { std::vector > stack; // convert the scriptSig into a stack, so we can inspect the redeemScript - if (!EvalScript(stack, tx.vin[i].scriptSig, SCRIPT_VERIFY_NONE, BaseSignatureChecker(), 0)) + if (!EvalScript(stack, tx.vin[i].scriptSig, SCRIPT_VERIFY_NONE, BaseSignatureChecker(), SIGVERSION_BASE)) return false; if (stack.empty()) return false; -- cgit v1.2.3 From 2b1f6f9ccf36f1e0a2c9d99154e1642f796d7c2b Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Sun, 3 Jan 2016 18:54:50 +0100 Subject: BIP141: Other consensus critical limits, and BIP145 Includes changes by Suhas Daftuar, Luke-jr, and mruddy. --- src/policy/policy.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'src/policy/policy.cpp') diff --git a/src/policy/policy.cpp b/src/policy/policy.cpp index 67434a38f..f2148bfe1 100644 --- a/src/policy/policy.cpp +++ b/src/policy/policy.cpp @@ -64,8 +64,8 @@ bool IsStandardTx(const CTransaction& tx, std::string& reason) // almost as much to process as they cost the sender in fees, because // computing signature hashes is O(ninputs*txsize). Limiting transactions // to MAX_STANDARD_TX_SIZE mitigates CPU exhaustion attacks. - unsigned int sz = tx.GetSerializeSize(SER_NETWORK, CTransaction::CURRENT_VERSION); - if (sz >= MAX_STANDARD_TX_SIZE) { + unsigned int sz = GetTransactionCost(tx); + if (sz >= MAX_STANDARD_TX_COST) { reason = "tx-size"; return false; } @@ -150,3 +150,13 @@ bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs) return true; } + +int64_t GetVirtualTransactionSize(int64_t nCost) +{ + return (nCost + WITNESS_SCALE_FACTOR - 1) / WITNESS_SCALE_FACTOR; +} + +int64_t GetVirtualTransactionSize(const CTransaction& tx) +{ + return GetVirtualTransactionSize(GetTransactionCost(tx)); +} -- cgit v1.2.3 From 2c06bae39edfaa9c0855d83377ad8fda09e4fa08 Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Mon, 18 Jul 2016 13:28:26 -0400 Subject: Rename "block cost" to "block weight" --- src/policy/policy.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/policy/policy.cpp') diff --git a/src/policy/policy.cpp b/src/policy/policy.cpp index f2148bfe1..8617db00c 100644 --- a/src/policy/policy.cpp +++ b/src/policy/policy.cpp @@ -64,8 +64,8 @@ bool IsStandardTx(const CTransaction& tx, std::string& reason) // almost as much to process as they cost the sender in fees, because // computing signature hashes is O(ninputs*txsize). Limiting transactions // to MAX_STANDARD_TX_SIZE mitigates CPU exhaustion attacks. - unsigned int sz = GetTransactionCost(tx); - if (sz >= MAX_STANDARD_TX_COST) { + unsigned int sz = GetTransactionWeight(tx); + if (sz >= MAX_STANDARD_TX_WEIGHT) { reason = "tx-size"; return false; } @@ -151,12 +151,12 @@ bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs) return true; } -int64_t GetVirtualTransactionSize(int64_t nCost) +int64_t GetVirtualTransactionSize(int64_t nWeight) { - return (nCost + WITNESS_SCALE_FACTOR - 1) / WITNESS_SCALE_FACTOR; + return (nWeight + WITNESS_SCALE_FACTOR - 1) / WITNESS_SCALE_FACTOR; } int64_t GetVirtualTransactionSize(const CTransaction& tx) { - return GetVirtualTransactionSize(GetTransactionCost(tx)); + return GetVirtualTransactionSize(GetTransactionWeight(tx)); } -- cgit v1.2.3 From ab942c15bd3854650afa810d7c22d7fd30d346c1 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Mon, 18 Jul 2016 20:57:20 +0200 Subject: Treat high-sigop transactions as larger rather than rejecting them --- src/policy/policy.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'src/policy/policy.cpp') diff --git a/src/policy/policy.cpp b/src/policy/policy.cpp index 8617db00c..0cd3ac711 100644 --- a/src/policy/policy.cpp +++ b/src/policy/policy.cpp @@ -151,12 +151,14 @@ bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs) return true; } -int64_t GetVirtualTransactionSize(int64_t nWeight) +unsigned int nBytesPerSigOp = DEFAULT_BYTES_PER_SIGOP; + +int64_t GetVirtualTransactionSize(int64_t nWeight, int64_t nSigOpCost) { - return (nWeight + WITNESS_SCALE_FACTOR - 1) / WITNESS_SCALE_FACTOR; + return (std::max(nWeight, nSigOpCost * nBytesPerSigOp) + WITNESS_SCALE_FACTOR - 1) / WITNESS_SCALE_FACTOR; } -int64_t GetVirtualTransactionSize(const CTransaction& tx) +int64_t GetVirtualTransactionSize(const CTransaction& tx, int64_t nSigOpCost) { - return GetVirtualTransactionSize(GetTransactionWeight(tx)); + return GetVirtualTransactionSize(GetTransactionWeight(tx), nSigOpCost); } -- cgit v1.2.3 From 1ffaff2f747af683513d6d74a7241d41e3f6e051 Mon Sep 17 00:00:00 2001 From: Johnson Lau Date: Wed, 20 Jul 2016 18:31:45 +0800 Subject: Make witness v0 outputs non-standard before segwit activation --- src/policy/policy.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src/policy/policy.cpp') diff --git a/src/policy/policy.cpp b/src/policy/policy.cpp index 8617db00c..de3996bb4 100644 --- a/src/policy/policy.cpp +++ b/src/policy/policy.cpp @@ -31,7 +31,7 @@ * DUP CHECKSIG DROP ... repeated 100 times... OP_1 */ -bool IsStandard(const CScript& scriptPubKey, txnouttype& whichType) +bool IsStandard(const CScript& scriptPubKey, txnouttype& whichType, const bool witnessEnabled) { std::vector > vSolutions; if (!Solver(scriptPubKey, whichType, vSolutions)) @@ -49,11 +49,14 @@ bool IsStandard(const CScript& scriptPubKey, txnouttype& whichType) } else if (whichType == TX_NULL_DATA && (!fAcceptDatacarrier || scriptPubKey.size() > nMaxDatacarrierBytes)) return false; + + else if (!witnessEnabled && (whichType == TX_WITNESS_V0_KEYHASH || whichType == TX_WITNESS_V0_SCRIPTHASH)) + return false; return whichType != TX_NONSTANDARD; } -bool IsStandardTx(const CTransaction& tx, std::string& reason) +bool IsStandardTx(const CTransaction& tx, std::string& reason, const bool witnessEnabled) { if (tx.nVersion > CTransaction::MAX_STANDARD_VERSION || tx.nVersion < 1) { reason = "version"; @@ -92,7 +95,7 @@ bool IsStandardTx(const CTransaction& tx, std::string& reason) unsigned int nDataOut = 0; txnouttype whichType; BOOST_FOREACH(const CTxOut& txout, tx.vout) { - if (!::IsStandard(txout.scriptPubKey, whichType)) { + if (!::IsStandard(txout.scriptPubKey, whichType, witnessEnabled)) { reason = "scriptpubkey"; return false; } -- cgit v1.2.3 From c59c434b7d1211c13f7904b9bc675e16910a1c0a Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Fri, 22 Jul 2016 11:09:45 -0400 Subject: qa: Add test for standardness of segwit v0 outputs --- src/policy/policy.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/policy/policy.cpp') diff --git a/src/policy/policy.cpp b/src/policy/policy.cpp index de3996bb4..57df1f0b1 100644 --- a/src/policy/policy.cpp +++ b/src/policy/policy.cpp @@ -49,7 +49,7 @@ bool IsStandard(const CScript& scriptPubKey, txnouttype& whichType, const bool w } else if (whichType == TX_NULL_DATA && (!fAcceptDatacarrier || scriptPubKey.size() > nMaxDatacarrierBytes)) return false; - + else if (!witnessEnabled && (whichType == TX_WITNESS_V0_KEYHASH || whichType == TX_WITNESS_V0_SCRIPTHASH)) return false; -- cgit v1.2.3 From 3ade2f64cfe43ab53e4869ffc35d5fd23201e1c1 Mon Sep 17 00:00:00 2001 From: Johnson Lau Date: Sun, 16 Oct 2016 23:53:16 +0800 Subject: Add standard limits for P2WSH with tests --- src/policy/policy.cpp | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) (limited to 'src/policy/policy.cpp') diff --git a/src/policy/policy.cpp b/src/policy/policy.cpp index 48080abc7..ae42b2bd7 100644 --- a/src/policy/policy.cpp +++ b/src/policy/policy.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2015 The Bitcoin developers +// Copyright (c) 2009-2016 The Bitcoin developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -154,6 +154,58 @@ bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs) return true; } +bool IsWitnessStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs) +{ + if (tx.IsCoinBase()) + return true; // Coinbases are skipped + + for (unsigned int i = 0; i < tx.vin.size(); i++) + { + // We don't care if witness for this input is empty, since it must not be bloated. + // If the script is invalid without witness, it would be caught sooner or later during validation. + if (tx.wit.vtxinwit[i].IsNull()) + continue; + + const CTxOut &prev = mapInputs.GetOutputFor(tx.vin[i]); + + // get the scriptPubKey corresponding to this input: + CScript prevScript = prev.scriptPubKey; + + if (prevScript.IsPayToScriptHash()) { + std::vector > stack; + // If the scriptPubKey is P2SH, we try to extract the redeemScript casually by converting the scriptSig + // into a stack. We do not check IsPushOnly nor compare the hash as these will be done later anyway. + // If the check fails at this stage, we know that this txid must be a bad one. + if (!EvalScript(stack, tx.vin[i].scriptSig, SCRIPT_VERIFY_NONE, BaseSignatureChecker(), SIGVERSION_BASE)) + return false; + if (stack.empty()) + return false; + prevScript = CScript(stack.back().begin(), stack.back().end()); + } + + int witnessversion = 0; + std::vector witnessprogram; + + // Non-witness program must not be associated with any witness + if (!prevScript.IsWitnessProgram(witnessversion, witnessprogram)) + return false; + + // Check P2WSH standard limits + if (witnessversion == 0 && witnessprogram.size() == 32) { + if (tx.wit.vtxinwit[i].scriptWitness.stack.back().size() > MAX_STANDARD_P2WSH_SCRIPT_SIZE) + return false; + size_t sizeWitnessStack = tx.wit.vtxinwit[i].scriptWitness.stack.size() - 1; + if (sizeWitnessStack > MAX_STANDARD_P2WSH_STACK_ITEMS) + return false; + for (unsigned int j = 0; j < sizeWitnessStack; j++) { + if (tx.wit.vtxinwit[i].scriptWitness.stack[j].size() > MAX_STANDARD_P2WSH_STACK_ITEM_SIZE) + return false; + } + } + } + return true; +} + unsigned int nBytesPerSigOp = DEFAULT_BYTES_PER_SIGOP; int64_t GetVirtualTransactionSize(int64_t nWeight, int64_t nSigOpCost) -- cgit v1.2.3 From 4b04e32c20b3e00ce30f3555677d9c937ca7482f Mon Sep 17 00:00:00 2001 From: isle2983 Date: Sun, 6 Nov 2016 10:12:50 -0700 Subject: [copyright] copyright header style uniform Three categories of modifications: 1) 1 instance of 'The Bitcoin Core developers \n', 1 instance of 'the Bitcoin Core developers\n', 3 instances of 'Bitcoin Core Developers\n', and 12 instances of 'The Bitcoin developers\n' are made uniform with the 443 instances of 'The Bitcoin Core developers\n' 2) 3 instances of 'BitPay, Inc\.\n' are made uniform with the other 6 instances of 'BitPay Inc\.\n' 3) 4 instances where there was no '(c)' between the 'Copyright' and the year where it deviates from the style of the local directory. --- src/policy/policy.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/policy/policy.cpp') diff --git a/src/policy/policy.cpp b/src/policy/policy.cpp index ae42b2bd7..a3eee474a 100644 --- a/src/policy/policy.cpp +++ b/src/policy/policy.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2016 The Bitcoin developers +// Copyright (c) 2009-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -- cgit v1.2.3 From 07ede5d711e7fd601770c1f57110830bf540f0bc Mon Sep 17 00:00:00 2001 From: Brian Deery Date: Mon, 14 Nov 2016 00:38:07 -0600 Subject: update comments for tx weight --- src/policy/policy.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/policy/policy.cpp') diff --git a/src/policy/policy.cpp b/src/policy/policy.cpp index a3eee474a..3ad1ff7ba 100644 --- a/src/policy/policy.cpp +++ b/src/policy/policy.cpp @@ -66,7 +66,7 @@ bool IsStandardTx(const CTransaction& tx, std::string& reason, const bool witnes // Extremely large transactions with lots of inputs can cost the network // almost as much to process as they cost the sender in fees, because // computing signature hashes is O(ninputs*txsize). Limiting transactions - // to MAX_STANDARD_TX_SIZE mitigates CPU exhaustion attacks. + // to MAX_STANDARD_TX_WEIGHT mitigates CPU exhaustion attacks. unsigned int sz = GetTransactionWeight(tx); if (sz >= MAX_STANDARD_TX_WEIGHT) { reason = "tx-size"; -- cgit v1.2.3 From 76faa3cdfedbd3fc91be4ecfff77fc6dc18134fb Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Thu, 1 Dec 2016 16:06:41 -0800 Subject: Rename the remaining main.{h,cpp} to validation.{h,cpp} --- src/policy/policy.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/policy/policy.cpp') diff --git a/src/policy/policy.cpp b/src/policy/policy.cpp index 3ad1ff7ba..0c71a079f 100644 --- a/src/policy/policy.cpp +++ b/src/policy/policy.cpp @@ -7,7 +7,7 @@ #include "policy/policy.h" -#include "main.h" +#include "validation.h" #include "tinyformat.h" #include "util.h" #include "utilstrencodings.h" -- cgit v1.2.3 From f6fb7acda4aefd01b8ef6cd77063bfc0c4f4ab36 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Thu, 4 Aug 2016 02:49:16 +0200 Subject: Move CTxInWitness inside CTxIn --- src/policy/policy.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/policy/policy.cpp') diff --git a/src/policy/policy.cpp b/src/policy/policy.cpp index 0c71a079f..d318a0997 100644 --- a/src/policy/policy.cpp +++ b/src/policy/policy.cpp @@ -163,7 +163,7 @@ bool IsWitnessStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs) { // We don't care if witness for this input is empty, since it must not be bloated. // If the script is invalid without witness, it would be caught sooner or later during validation. - if (tx.wit.vtxinwit[i].IsNull()) + if (tx.vin[i].scriptWitness.IsNull()) continue; const CTxOut &prev = mapInputs.GetOutputFor(tx.vin[i]); @@ -192,13 +192,13 @@ bool IsWitnessStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs) // Check P2WSH standard limits if (witnessversion == 0 && witnessprogram.size() == 32) { - if (tx.wit.vtxinwit[i].scriptWitness.stack.back().size() > MAX_STANDARD_P2WSH_SCRIPT_SIZE) + if (tx.vin[i].scriptWitness.stack.back().size() > MAX_STANDARD_P2WSH_SCRIPT_SIZE) return false; - size_t sizeWitnessStack = tx.wit.vtxinwit[i].scriptWitness.stack.size() - 1; + size_t sizeWitnessStack = tx.vin[i].scriptWitness.stack.size() - 1; if (sizeWitnessStack > MAX_STANDARD_P2WSH_STACK_ITEMS) return false; for (unsigned int j = 0; j < sizeWitnessStack; j++) { - if (tx.wit.vtxinwit[i].scriptWitness.stack[j].size() > MAX_STANDARD_P2WSH_STACK_ITEM_SIZE) + if (tx.vin[i].scriptWitness.stack[j].size() > MAX_STANDARD_P2WSH_STACK_ITEM_SIZE) return false; } } -- cgit v1.2.3 From 7b1add3c28aae8caf2e1517f15cd953eacbb4931 Mon Sep 17 00:00:00 2001 From: Alex Morcos Date: Tue, 13 Dec 2016 13:43:35 -0500 Subject: Introduce -incrementalrelayfee --- src/policy/policy.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/policy/policy.cpp') diff --git a/src/policy/policy.cpp b/src/policy/policy.cpp index d318a0997..4dacd6b54 100644 --- a/src/policy/policy.cpp +++ b/src/policy/policy.cpp @@ -206,6 +206,7 @@ bool IsWitnessStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs) return true; } +CFeeRate incrementalRelayFee = CFeeRate(DEFAULT_INCREMENTAL_RELAY_FEE); unsigned int nBytesPerSigOp = DEFAULT_BYTES_PER_SIGOP; int64_t GetVirtualTransactionSize(int64_t nWeight, int64_t nSigOpCost) -- cgit v1.2.3 From eb30d1a5b215c6dd3763d7f7948f2dd8cb61f6bf Mon Sep 17 00:00:00 2001 From: Alex Morcos Date: Tue, 13 Dec 2016 16:19:17 -0500 Subject: Introduce -dustrelayfee --- src/policy/policy.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/policy/policy.cpp') diff --git a/src/policy/policy.cpp b/src/policy/policy.cpp index 4dacd6b54..ec398f662 100644 --- a/src/policy/policy.cpp +++ b/src/policy/policy.cpp @@ -105,7 +105,7 @@ bool IsStandardTx(const CTransaction& tx, std::string& reason, const bool witnes else if ((whichType == TX_MULTISIG) && (!fIsBareMultisigStd)) { reason = "bare-multisig"; return false; - } else if (txout.IsDust(::minRelayTxFee)) { + } else if (txout.IsDust(dustRelayFee)) { reason = "dust"; return false; } @@ -207,6 +207,7 @@ bool IsWitnessStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs) } CFeeRate incrementalRelayFee = CFeeRate(DEFAULT_INCREMENTAL_RELAY_FEE); +CFeeRate dustRelayFee = CFeeRate(DUST_RELAY_TX_FEE); unsigned int nBytesPerSigOp = DEFAULT_BYTES_PER_SIGOP; int64_t GetVirtualTransactionSize(int64_t nWeight, int64_t nSigOpCost) -- cgit v1.2.3