aboutsummaryrefslogtreecommitdiff
path: root/src/script/interpreter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/script/interpreter.cpp')
-rw-r--r--src/script/interpreter.cpp47
1 files changed, 47 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;
+}