mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-01-21 15:50:07 +01:00
Add policy: null signature for failed CHECK(MULTI)SIG
This commit is contained in:
@@ -885,6 +885,9 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, un
|
||||
}
|
||||
bool fSuccess = checker.CheckSig(vchSig, vchPubKey, scriptCode, sigversion);
|
||||
|
||||
if (!fSuccess && (flags & SCRIPT_VERIFY_NULLFAIL) && vchSig.size())
|
||||
return set_error(serror, SCRIPT_ERR_SIG_NULLFAIL);
|
||||
|
||||
popstack(stack);
|
||||
popstack(stack);
|
||||
stack.push_back(fSuccess ? vchTrue : vchFalse);
|
||||
@@ -914,6 +917,9 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, un
|
||||
if (nOpCount > MAX_OPS_PER_SCRIPT)
|
||||
return set_error(serror, SCRIPT_ERR_OP_COUNT);
|
||||
int ikey = ++i;
|
||||
// ikey2 is the position of last non-signature item in the stack. Top stack item = 1.
|
||||
// With SCRIPT_VERIFY_NULLFAIL, this is used for cleanup if operation fails.
|
||||
int ikey2 = nKeysCount + 2;
|
||||
i += nKeysCount;
|
||||
if ((int)stack.size() < i)
|
||||
return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
|
||||
@@ -970,8 +976,14 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, un
|
||||
}
|
||||
|
||||
// Clean up stack of actual arguments
|
||||
while (i-- > 1)
|
||||
while (i-- > 1) {
|
||||
// If the operation failed, we require that all signatures must be empty vector
|
||||
if (!fSuccess && (flags & SCRIPT_VERIFY_NULLFAIL) && !ikey2 && stacktop(-1).size())
|
||||
return set_error(serror, SCRIPT_ERR_SIG_NULLFAIL);
|
||||
if (ikey2 > 0)
|
||||
ikey2--;
|
||||
popstack(stack);
|
||||
}
|
||||
|
||||
// A bug causes CHECKMULTISIG to consume one extra argument
|
||||
// whose contents were not checked in any way.
|
||||
|
||||
@@ -98,6 +98,10 @@ enum
|
||||
// Segwit script only: Require the argument of OP_IF/NOTIF to be exactly 0x01 or empty vector
|
||||
//
|
||||
SCRIPT_VERIFY_MINIMALIF = (1U << 13),
|
||||
|
||||
// Signature(s) must be empty vector if an CHECK(MULTI)SIG operation failed
|
||||
//
|
||||
SCRIPT_VERIFY_NULLFAIL = (1U << 14),
|
||||
};
|
||||
|
||||
bool CheckSignatureEncoding(const std::vector<unsigned char> &vchSig, unsigned int flags, ScriptError* serror);
|
||||
|
||||
@@ -65,6 +65,8 @@ const char* ScriptErrorString(const ScriptError serror)
|
||||
return "Dummy CHECKMULTISIG argument must be zero";
|
||||
case SCRIPT_ERR_MINIMALIF:
|
||||
return "OP_IF/NOTIF argument must be minimal";
|
||||
case SCRIPT_ERR_SIG_NULLFAIL:
|
||||
return "Signature must be zero for failed CHECK(MULTI)SIG operation";
|
||||
case SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS:
|
||||
return "NOPx reserved for soft-fork upgrades";
|
||||
case SCRIPT_ERR_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM:
|
||||
|
||||
@@ -49,6 +49,7 @@ typedef enum ScriptError_t
|
||||
SCRIPT_ERR_PUBKEYTYPE,
|
||||
SCRIPT_ERR_CLEANSTACK,
|
||||
SCRIPT_ERR_MINIMALIF,
|
||||
SCRIPT_ERR_SIG_NULLFAIL,
|
||||
|
||||
/* softfork safeness */
|
||||
SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS,
|
||||
|
||||
Reference in New Issue
Block a user