From e1a0cfb50083795f952706cfe1c89160b79e8467 Mon Sep 17 00:00:00 2001 From: furszy Date: Tue, 21 Jul 2020 02:23:38 -0300 Subject: [PATCH] Back port of IsSolvable to check scripts solvability. This is a modified version of btc@0c8ea6380c9f402ed9777fd015b117ba13125a35 --- src/policy/policy.h | 4 ++-- src/script/sign.cpp | 15 +++++++++++++++ src/script/sign.h | 6 ++++++ 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/policy/policy.h b/src/policy/policy.h index 01d3bffbc4133..ce355812c3151 100644 --- a/src/policy/policy.h +++ b/src/policy/policy.h @@ -27,7 +27,7 @@ static const unsigned int MAX_P2SH_SIGOPS = 15; * with. However scripts violating these flags may still be present in valid * blocks and we must accept those blocks. */ -static const unsigned int STANDARD_SCRIPT_VERIFY_FLAGS = MANDATORY_SCRIPT_VERIFY_FLAGS | +static constexpr unsigned int STANDARD_SCRIPT_VERIFY_FLAGS = MANDATORY_SCRIPT_VERIFY_FLAGS | SCRIPT_VERIFY_DERSIG | SCRIPT_VERIFY_STRICTENC | SCRIPT_VERIFY_MINIMALDATA | @@ -36,7 +36,7 @@ static const unsigned int STANDARD_SCRIPT_VERIFY_FLAGS = MANDATORY_SCRIPT_VERIFY SCRIPT_VERIFY_LOW_S; /** For convenience, standard but not mandatory verify flags. */ -static const unsigned int STANDARD_NOT_MANDATORY_VERIFY_FLAGS = STANDARD_SCRIPT_VERIFY_FLAGS & ~MANDATORY_SCRIPT_VERIFY_FLAGS; +static constexpr unsigned int STANDARD_NOT_MANDATORY_VERIFY_FLAGS = STANDARD_SCRIPT_VERIFY_FLAGS & ~MANDATORY_SCRIPT_VERIFY_FLAGS; // Sanity check the magic numbers when we change them BOOST_STATIC_ASSERT(DEFAULT_BLOCK_MAX_SIZE <= MAX_BLOCK_SIZE_CURRENT); diff --git a/src/script/sign.cpp b/src/script/sign.cpp index f6e19e8852ca5..5991779fc8d57 100644 --- a/src/script/sign.cpp +++ b/src/script/sign.cpp @@ -380,3 +380,18 @@ bool DummySignatureCreator::CreateSig(std::vector& vchSig, const vchSig[6 + 33 + 32] = SIGHASH_ALL; return true; } + +bool IsSolvable(const CKeyStore& store, const CScript& script) +{ + // This check is to make sure that the script we created can actually be solved for and signed by us + // if we were to have the private keys. This is just to make sure that the script is valid and that, + // if found in a transaction, we would still accept and relay that transaction. In particular, + DummySignatureCreator creator(&store); + SignatureData sigs; + if (ProduceSignature(creator, script, sigs, false)) { + // VerifyScript check is just defensive, and should never fail. + assert(VerifyScript(sigs.scriptSig, script, STANDARD_SCRIPT_VERIFY_FLAGS, creator.Checker())); + return true; + } + return false; +} diff --git a/src/script/sign.h b/src/script/sign.h index 7e6a3651dd0a5..f3881274ce0c2 100644 --- a/src/script/sign.h +++ b/src/script/sign.h @@ -81,4 +81,10 @@ SignatureData CombineSignatures(const CScript& scriptPubKey, const BaseSignature SignatureData DataFromTransaction(const CMutableTransaction& tx, unsigned int nIn); void UpdateTransaction(CMutableTransaction& tx, unsigned int nIn, const SignatureData& data); +/* Check whether we know how to sign for an output like this, assuming we + * have all private keys. While this function does not need private keys, the passed + * keystore is used to look up public keys and redeemscripts by hash. + * Solvability is unrelated to whether we consider this output to be ours. */ +bool IsSolvable(const CKeyStore& store, const CScript& script); + #endif // BITCOIN_SCRIPT_SIGN_H