aboutsummaryrefslogtreecommitdiff
path: root/src/script
diff options
context:
space:
mode:
authorPieter Wuille <pieter.wuille@gmail.com>2016-01-03 18:54:50 +0100
committerPieter Wuille <pieter.wuille@gmail.com>2016-06-22 15:43:00 +0200
commit2b1f6f9ccf36f1e0a2c9d99154e1642f796d7c2b (patch)
tree30b17fa55ea6c9ae0055c0c16d2e271a0c799d16 /src/script
parent7c4bf779e8b74e474551982a24f5acc265293abd (diff)
downloadbitcoin-2b1f6f9ccf36f1e0a2c9d99154e1642f796d7c2b.tar.xz
BIP141: Other consensus critical limits, and BIP145
Includes changes by Suhas Daftuar, Luke-jr, and mruddy.
Diffstat (limited to 'src/script')
-rw-r--r--src/script/interpreter.cpp47
-rw-r--r--src/script/interpreter.h2
2 files changed, 49 insertions, 0 deletions
diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp
index 4deebd050d..bc027e9f0c 100644
--- a/src/script/interpreter.cpp
+++ b/src/script/interpreter.cpp
@@ -1470,3 +1470,50 @@ bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const C
return set_success(serror);
}
+
+size_t static WitnessSigOps(int witversion, const std::vector<unsigned char>& witprogram, const CScriptWitness& witness, int flags)
+{
+ if (witversion == 0) {
+ if (witprogram.size() == 20)
+ return 1;
+
+ if (witprogram.size() == 32 && witness.stack.size() > 0) {
+ CScript subscript(witness.stack.back().begin(), witness.stack.back().end());
+ return subscript.GetSigOpCount(true);
+ }
+ }
+
+ // Future flags may be implemented here.
+ return 0;
+}
+
+size_t CountWitnessSigOps(const CScript& scriptSig, const CScript& scriptPubKey, const CScriptWitness* witness, unsigned int flags)
+{
+ static const CScriptWitness witnessEmpty;
+
+ if ((flags & SCRIPT_VERIFY_WITNESS) == 0) {
+ return 0;
+ }
+ assert((flags & SCRIPT_VERIFY_P2SH) != 0);
+
+ int witnessversion;
+ std::vector<unsigned char> witnessprogram;
+ if (scriptPubKey.IsWitnessProgram(witnessversion, witnessprogram)) {
+ return WitnessSigOps(witnessversion, witnessprogram, witness ? *witness : witnessEmpty, flags);
+ }
+
+ if (scriptPubKey.IsPayToScriptHash() && scriptSig.IsPushOnly()) {
+ CScript::const_iterator pc = scriptSig.begin();
+ vector<unsigned char> data;
+ while (pc < scriptSig.end()) {
+ opcodetype opcode;
+ scriptSig.GetOp(pc, opcode, data);
+ }
+ CScript subscript(data.begin(), data.end());
+ if (subscript.IsWitnessProgram(witnessversion, witnessprogram)) {
+ return WitnessSigOps(witnessversion, witnessprogram, witness ? *witness : witnessEmpty, flags);
+ }
+ }
+
+ return 0;
+}
diff --git a/src/script/interpreter.h b/src/script/interpreter.h
index 8643729425..bd2f211663 100644
--- a/src/script/interpreter.h
+++ b/src/script/interpreter.h
@@ -156,4 +156,6 @@ public:
bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript& script, unsigned int flags, const BaseSignatureChecker& checker, SigVersion sigversion, ScriptError* error = NULL);
bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const CScriptWitness* witness, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* serror = NULL);
+size_t CountWitnessSigOps(const CScript& scriptSig, const CScript& scriptPubKey, const CScriptWitness* witness, unsigned int flags);
+
#endif // BITCOIN_SCRIPT_INTERPRETER_H