Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/consensus/params.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ enum DeploymentPos : uint16_t {
DEPLOYMENT_TESTDUMMY,
DEPLOYMENT_TAPROOT, // Deployment of Schnorr/Taproot (BIPs 340-342)
// NOTE: Also add new deployments to VersionBitsDeploymentInfo in deploymentinfo.cpp
DEPLOYMENT_CSFS, // Deployment of CHECKSIGFROMSTACK (BIP 348) (regtest only)
MAX_VERSION_BITS_DEPLOYMENTS
};
constexpr bool ValidDeployment(DeploymentPos dep) { return dep < MAX_VERSION_BITS_DEPLOYMENTS; }
Expand Down
4 changes: 4 additions & 0 deletions src/deploymentinfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ const struct VBDeploymentInfo VersionBitsDeploymentInfo[Consensus::MAX_VERSION_B
/*.name =*/ "taproot",
/*.gbt_force =*/ true,
},
{
/*.name =*/ "csfs",
/*.gbt_force =*/ true,
},
};

std::string DeploymentName(Consensus::BuriedDeployment dep)
Expand Down
5 changes: 5 additions & 0 deletions src/kernel/chainparams.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -591,6 +591,11 @@ class CRegTestParams : public CChainParams
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].min_activation_height = 0; // No activation delay

consensus.vDeployments[Consensus::DEPLOYMENT_CSFS].bit = 1;
consensus.vDeployments[Consensus::DEPLOYMENT_CSFS].nStartTime = Consensus::BIP9Deployment::ALWAYS_ACTIVE;
consensus.vDeployments[Consensus::DEPLOYMENT_CSFS].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
consensus.vDeployments[Consensus::DEPLOYMENT_CSFS].min_activation_height = 0; // No activation delay

consensus.nMinimumChainWork = uint256{};
consensus.defaultAssumeValid = uint256{};

Expand Down
3 changes: 2 additions & 1 deletion src/policy/policy.h
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,8 @@ static constexpr unsigned int STANDARD_SCRIPT_VERIFY_FLAGS{MANDATORY_SCRIPT_VERI
SCRIPT_VERIFY_CONST_SCRIPTCODE |
SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_TAPROOT_VERSION |
SCRIPT_VERIFY_DISCOURAGE_OP_SUCCESS |
SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_PUBKEYTYPE};
SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_PUBKEYTYPE |
SCRIPT_VERIFY_CHECKSIGFROMSTACK};

/** For convenience, standard but not mandatory verify flags. */
static constexpr unsigned int STANDARD_NOT_MANDATORY_VERIFY_FLAGS{STANDARD_SCRIPT_VERIFY_FLAGS & ~MANDATORY_SCRIPT_VERIFY_FLAGS};
Expand Down
5 changes: 3 additions & 2 deletions src/pubkey.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -227,12 +227,13 @@ bool XOnlyPubKey::IsFullyValid() const
return secp256k1_xonly_pubkey_parse(secp256k1_context_static, &pubkey, m_keydata.data());
}

bool XOnlyPubKey::VerifySchnorr(const uint256& msg, Span<const unsigned char> sigbytes) const
bool XOnlyPubKey::VerifySchnorr(
const std::span<const unsigned char> msg, std::span<const unsigned char> sigbytes) const
{
assert(sigbytes.size() == 64);
secp256k1_xonly_pubkey pubkey;
if (!secp256k1_xonly_pubkey_parse(secp256k1_context_static, &pubkey, m_keydata.data())) return false;
return secp256k1_schnorrsig_verify(secp256k1_context_static, sigbytes.data(), msg.begin(), 32, &pubkey);
return secp256k1_schnorrsig_verify(secp256k1_context_static, sigbytes.data(), msg.data(), msg.size(), &pubkey);
}

static const HashWriter HASHER_TAPTWEAK{TaggedHash("TapTweak")};
Expand Down
3 changes: 2 additions & 1 deletion src/pubkey.h
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,8 @@ class XOnlyPubKey
*
* sigbytes must be exactly 64 bytes.
*/
bool VerifySchnorr(const uint256& msg, Span<const unsigned char> sigbytes) const;
bool VerifySchnorr(
const std::span<const unsigned char> msg, std::span<const unsigned char> sigbytes) const;

/** Compute the Taproot tweak as specified in BIP341, with *this as internal
* key:
Expand Down
4 changes: 4 additions & 0 deletions src/rpc/blockchain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1849,6 +1849,10 @@ UniValue DeploymentInfo(const CBlockIndex* blockindex, const ChainstateManager&
SoftForkDescPushBack(blockindex, softforks, chainman, Consensus::DEPLOYMENT_SEGWIT);
SoftForkDescPushBack(blockindex, softforks, chainman, Consensus::DEPLOYMENT_TESTDUMMY);
SoftForkDescPushBack(blockindex, softforks, chainman, Consensus::DEPLOYMENT_TAPROOT);

if (chainman.GetParams().GetChainType() == ChainType::REGTEST) {
SoftForkDescPushBack(blockindex, softforks, chainman, Consensus::DEPLOYMENT_CSFS);
}
return softforks;
}
} // anon namespace
Expand Down
95 changes: 92 additions & 3 deletions src/script/interpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,53 @@ static bool EvalChecksigPreTapscript(const valtype& vchSig, const valtype& vchPu
return true;
}

static bool EvalChecksigFromStack(const valtype& sig, const valtype& msg, const valtype& pubkey_in, ScriptExecutionData& execdata, unsigned int flags, SigVersion sigversion, ScriptError* serror, bool& success)
{
/*
* The following validation sequence is consensus critical. Please note how --
* upgradable public key versions precede other rules;
* the script execution fails when using empty signature with invalid public key;
* the script execution fails when using non-empty invalid signature.
*/
success = !sig.empty();
if (success && sigversion == SigVersion::TAPSCRIPT) {
// Implement the sigops/witnesssize ratio test.
// Passing with an upgradable public key version is also counted.
assert(execdata.m_validation_weight_left_init);
execdata.m_validation_weight_left -= VALIDATION_WEIGHT_PER_SIGOP_PASSED;
if (execdata.m_validation_weight_left < 0) {
return set_error(serror, SCRIPT_ERR_TAPSCRIPT_VALIDATION_WEIGHT);
}
}
if (pubkey_in.size() == 0) {
return set_error(serror, SCRIPT_ERR_PUBKEYTYPE);
} else if (pubkey_in.size() == 32) {
if (!success) {
return true;
}
if (sig.size() != 64) {
return set_error(serror, SCRIPT_ERR_SCHNORR_SIG_SIZE);
}

XOnlyPubKey pubkey{pubkey_in};

if (!pubkey.VerifySchnorr(msg, sig)) {
return set_error(serror, SCRIPT_ERR_SCHNORR_SIG);
}
} else {
/*
* New public key version softforks should be defined before this `else` block.
* Generally, the new code should not do anything but failing the script execution. To avoid
* consensus bugs, it should not modify any existing values (including `success`).
*/
if ((flags & SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_PUBKEYTYPE) != 0) {
return set_error(serror, SCRIPT_ERR_DISCOURAGE_UPGRADABLE_PUBKEYTYPE);
}
}

return true;
}

static bool EvalChecksigTapscript(const valtype& sig, const valtype& pubkey, ScriptExecutionData& execdata, unsigned int flags, const BaseSignatureChecker& checker, SigVersion sigversion, ScriptError* serror, bool& success)
{
assert(sigversion == SigVersion::TAPSCRIPT);
Expand Down Expand Up @@ -1213,6 +1260,39 @@ bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript&
}
break;

case OP_CHECKSIGFROMSTACK:
{
// OP_CHECKSIGFROMSTACK is only available in Tapscript
if (sigversion == SigVersion::BASE || sigversion == SigVersion::WITNESS_V0) {
return set_error(serror, SCRIPT_ERR_BAD_OPCODE);
}

// <sig> <msg> <pubkey>
if (stack.size() < 3) {
return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
}

const valtype& vchSigIn = stacktop(-3);
const valtype& vchMsg = stacktop(-2);
const valtype& vchPubKey = stacktop(-1);

bool fSuccess = true;

// Note that (as with CHECKSIG) if a signature was supplied and its
// verification fails, we do _not_ push a "false" result to the stack.
// Rather, we terminate script execution immediately. This might be
// surprising if you're reading this for the first time.
if (!EvalChecksigFromStack(vchSigIn, vchMsg, vchPubKey, execdata, flags, sigversion, serror, fSuccess)) {
return false;
}

popstack(stack);
popstack(stack);
popstack(stack);
stack.push_back(fSuccess ? vchTrue : vchFalse);
}
break;

default:
return set_error(serror, SCRIPT_ERR_BAD_OPCODE);
}
Expand Down Expand Up @@ -1807,10 +1887,19 @@ static bool ExecuteWitnessScript(const Span<const valtype>& stack_span, const CS
}
// New opcodes will be listed here. May use a different sigversion to modify existing opcodes.
if (IsOpSuccess(opcode)) {
if (flags & SCRIPT_VERIFY_DISCOURAGE_OP_SUCCESS) {
return set_error(serror, SCRIPT_ERR_DISCOURAGE_OP_SUCCESS);
if (opcode == OP_CHECKSIGFROMSTACK) {
if (flags & SCRIPT_VERIFY_DISCOURAGE_CHECKSIGFROMSTACK) {
return set_error(serror, SCRIPT_ERR_DISCOURAGE_OP_SUCCESS);
} else if (!(flags & SCRIPT_VERIFY_CHECKSIGFROMSTACK)) {
return set_success(serror);
}
} else {
// OP_SUCCESS behaviour
if (flags & SCRIPT_VERIFY_DISCOURAGE_OP_SUCCESS) {
return set_error(serror, SCRIPT_ERR_DISCOURAGE_OP_SUCCESS);
}
return set_success(serror);
}
return set_success(serror);
}
}

Expand Down
6 changes: 6 additions & 0 deletions src/script/interpreter.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,12 @@ enum : uint32_t {
// Making unknown public key versions (in BIP 342 scripts) non-standard
SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_PUBKEYTYPE = (1U << 20),

// Validating OP_CHECKSIGFROMSTACK(VERIFY)
SCRIPT_VERIFY_CHECKSIGFROMSTACK = (1U << 21),

// Making OP_CHECKSIGFROMSTACK(VERIFY) non-standard
SCRIPT_VERIFY_DISCOURAGE_CHECKSIGFROMSTACK = (1U << 22),

// Constants to point to the highest flag in use. Add new flags above this line.
//
SCRIPT_VERIFY_END_MARKER
Expand Down
3 changes: 3 additions & 0 deletions src/script/script.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,9 @@ std::string GetOpName(opcodetype opcode)
// Opcode added by BIP 342 (Tapscript)
case OP_CHECKSIGADD : return "OP_CHECKSIGADD";

// Tapscript expansion
case OP_CHECKSIGFROMSTACK : return "OP_CHECKSIGFROMSTACK";

case OP_INVALIDOPCODE : return "OP_INVALIDOPCODE";

default:
Expand Down
1 change: 1 addition & 0 deletions src/script/script.h
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ enum opcodetype
OP_CHECKSIGVERIFY = 0xad,
OP_CHECKMULTISIG = 0xae,
OP_CHECKMULTISIGVERIFY = 0xaf,
OP_CHECKSIGFROMSTACK = 0xcc,

// expansion
OP_NOP1 = 0xb0,
Expand Down
8 changes: 8 additions & 0 deletions src/test/data/tx_invalid.json
Original file line number Diff line number Diff line change
Expand Up @@ -393,5 +393,13 @@
["ceafe58e0f6e7d67c0409fbbf673c84c166e3c5d3c24af58f7175b18df3bb3db", 1, "2 0x48 0x3045022015bd0139bcccf990a6af6ec5c1c52ed8222e03a0d51c334df139968525d2fcd20221009f9efe325476eb64c3958e4713e9eefe49bf1d820ed58d2112721b134e2a1a5303 0x21 0x0378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71 0x21 0x0378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71 3 CHECKMULTISIG"]],
"0100000002dbb33bdf185b17f758af243c5d3c6e164cc873f6bb9f40c0677d6e0f8ee5afce000000006b4830450221009627444320dc5ef8d7f68f35010b4c050a6ed0d96b67a84db99fda9c9de58b1e02203e4b4aaa019e012e65d69b487fdf8719df72f488fa91506a80c49a33929f1fd50121022b78b756e2258af13779c1a1f37ea6800259716ca4b7f0b87610e0bf3ab52a01ffffffffdbb33bdf185b17f758af243c5d3c6e164cc873f6bb9f40c0677d6e0f8ee5afce010000009300483045022015bd0139bcccf990a6af6ec5c1c52ed8222e03a0d51c334df139968525d2fcd20221009f9efe325476eb64c3958e4713e9eefe49bf1d820ed58d2112721b134e2a1a5303483045022015bd0139bcccf990a6af6ec5c1c52ed8222e03a0d51c334df139968525d2fcd20221009f9efe325476eb64c3958e4713e9eefe49bf1d820ed58d2112721b134e2a1a5303ffffffff01a0860100000000001976a9149bc0bbdd3024da4d0c38ed1aecf5c68dd1d3fa1288ac00000000", "CONST_SCRIPTCODE"],

["Test OP_CHECKSIGFROMSTACK, fails immediately with sig for wrong data"],
[[["a2522fa96033c5736f3142ff616426cd03a3d0f077f609e22c5a33a96e04e597",
0,
"1 0x20 0x6e929e9354a357e9a1254feac061741a11c66508786c66b3b29edc79b9c46e19",
155000]],
"0200000000010197e5046ea9335a2ce209f677f0d0a303cd266461ff42316f73c53360a92f52a20000000000ffffffff01f04902000000000022512040104c71081b266fdf4008db8b0a1c3291f2e1cb680753936de9b76dac45a6ef0340b5258eeb9df148d499d14b8e23fe5315a230b7f1dee497a04605426ffe068f2e0920c9b63ba28b1c6cea39c0e659af1658825d23e859c5ae773a0be996f1c4744520feadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef204835c505a762f5e55c2e8eda1c05437d973809a0236178510208a6ac3f7632bfcc008721c050929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac000000000",
"P2SH,WITNESS,TAPROOT,CHECKSIGFROMSTACK"],

["Make diffs cleaner by leaving a comment here without comma at the end"]
]
29 changes: 29 additions & 0 deletions src/test/data/tx_valid.json
Original file line number Diff line number Diff line change
Expand Up @@ -520,5 +520,34 @@
[[["1111111111111111111111111111111111111111111111111111111111111111", 0, "0x00 0x14 0x751e76e8199196d454941c45d1b3a323f1433bd6", 5000000]],
"0100000000010111111111111111111111111111111111111111111111111111111111111111110000000000ffffffff0130244c0000000000fd02014cdc1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111175210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798ac02483045022100c1a4a6581996a7fdfea77d58d537955a5655c1d619b6f3ab6874f28bb2e19708022056402db6fede03caae045a3be616a1a2d0919a475ed4be828dc9ff21f24063aa01210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179800000000", "NONE"],

["Test OP_CHECKSIGFROMSTACK"],
[[["e2f2baee9c59389b34e39742ce05debf64aaa7a00fbdab88614f4d3c133186d5",
0,
"1 0x20 0xed98cc178a5e3f2537ec8bf5ab9a14e56b8a188d666ba6ce788405e849ba7da8",
155000]],
"02000000000101d58631133c4d4f6188abbd0fa0a7aa64bfde05ce4297e3349b38599ceebaf2e20000000000ffffffff01f0490200000000002251203408099b8f38a71ab6dfafdf0b266bd0a0f58096b5c453624c752bae6c0f19560340cd3e61f2754dd13e51a6d86d18092f795c626d36deaf0cf076a87648d9f4e4cfceaaa8e8a7eee1ee13dd09ef2c14eedd475f4e9adcf8a2391b910271b2203aa24320deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef208fdb638cf9201fcae809f31b7d5b5ef9ae712cd374c8c89b06d52b9d2c3885bfcc21c050929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac000000000",
"DISCOURAGE_CHECKSIGFROMSTACK"],
["Test OP_CHECKSIGFROMSTACK succeeds with unknown key type"],
[[["e2f2baee9c59389b34e39742ce05debf64aaa7a00fbdab88614f4d3c133186d5",
0,
"1 0x20 0xde96616e5e3961cbbd7bab3ea0e6b6e1ace088299857136fbb3703454c784afb",
155000]],
"02000000000101d58631133c4d4f6188abbd0fa0a7aa64bfde05ce4297e3349b38599ceebaf2e20000000000ffffffff01f0490200000000002251203408099b8f38a71ab6dfafdf0b266bd0a0f58096b5c453624c752bae6c0f19560340cd3e61f2754dd13e51a6d86d18092f795c626d36deaf0cf076a87648d9f4e4cfceaaa8e8a7eee1ee13dd09ef2c14eedd475f4e9adcf8a2391b910271b2203aa24420deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef21038fdb638cf9201fcae809f31b7d5b5ef9ae712cd374c8c89b06d52b9d2c3885bfcc21c050929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac000000000",
"DISCOURAGE_CHECKSIGFROMSTACK,DISCOURAGE_UPGRADABLE_PUBKEYTYPE"],
["Test OP_CHECKSIGFROMSTACK yields 0 for 0-sig"],
[[["e2f2baee9c59389b34e39742ce05debf64aaa7a00fbdab88614f4d3c133186d5",
0,
"1 0x20 0x7f3db202bc0db8c15de91c5da0dd64bd52ae81f5847cda623e1304c524cad314",
155000]],
"02000000000101d58631133c4d4f6188abbd0fa0a7aa64bfde05ce4297e3349b38599ceebaf2e20000000000ffffffff01f0490200000000002251203408099b8f38a71ab6dfafdf0b266bd0a0f58096b5c453624c752bae6c0f195603004520deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef208fdb638cf9201fcae809f31b7d5b5ef9ae712cd374c8c89b06d52b9d2c3885bfcc008721c050929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac000000000",
"DISCOURAGE_CHECKSIGFROMSTACK"],
["Test OP_CHECKSIGFROMSTACK, shorter message"],
[[["e2f2baee9c59389b34e39742ce05debf64aaa7a00fbdab88614f4d3c133186d5",
0,
"1 0x20 0x313a784205aef89c9d203c1e4cfacd2e31fa55f42dcd77e5e2db9d0513d50827",
155000]],
"02000000000101d58631133c4d4f6188abbd0fa0a7aa64bfde05ce4297e3349b38599ceebaf2e20000000000ffffffff01f0490200000000002251203408099b8f38a71ab6dfafdf0b266bd0a0f58096b5c453624c752bae6c0f195603403c5a935ce7a3856bc3e75eae403a21ff2e5a9f919c0f6f4d6bf7f58c834c13484882fc6f98587fe48e6945a49c0ca4fc62fb5f641a216ea62ac2dbc0071976833411636865636b73696766726f6d737461636b208fdb638cf9201fcae809f31b7d5b5ef9ae712cd374c8c89b06d52b9d2c3885bfcc21c150929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac000000000",
"DISCOURAGE_CHECKSIGFROMSTACK"],

["Make diffs cleaner by leaving a comment here without comma at the end"]
]
2 changes: 2 additions & 0 deletions src/test/transaction_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ static std::map<std::string, unsigned int> mapFlagNames = {
{std::string("DISCOURAGE_UPGRADABLE_PUBKEYTYPE"), (unsigned int)SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_PUBKEYTYPE},
{std::string("DISCOURAGE_OP_SUCCESS"), (unsigned int)SCRIPT_VERIFY_DISCOURAGE_OP_SUCCESS},
{std::string("DISCOURAGE_UPGRADABLE_TAPROOT_VERSION"), (unsigned int)SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_TAPROOT_VERSION},
{std::string("CHECKSIGFROMSTACK"), (unsigned int)SCRIPT_VERIFY_CHECKSIGFROMSTACK},
{std::string("DISCOURAGE_CHECKSIGFROMSTACK"), (unsigned int)SCRIPT_VERIFY_DISCOURAGE_CHECKSIGFROMSTACK},
};

unsigned int ParseScriptFlags(std::string strFlags)
Expand Down
8 changes: 7 additions & 1 deletion src/test/versionbits_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -434,7 +434,13 @@ BOOST_FIXTURE_TEST_CASE(versionbits_computeblockversion, BlockVersionTest)
// not take precedence over STARTED/LOCKED_IN. So all softforks on
// the same bit might overlap, even when non-overlapping start-end
// times are picked.
const uint32_t dep_mask{vbcache.Mask(chainParams->GetConsensus(), dep)};
const uint32_t dep_mask{uint32_t{1} << chainParams->GetConsensus().vDeployments[dep].bit};

if (chain_type != ChainType::REGTEST && dep == Consensus::DEPLOYMENT_CSFS) {
// CSFS only exists as a deployment on regtest, so skip over it for other
// chains.
continue;
}
BOOST_CHECK(!(chain_all_vbits & dep_mask));
chain_all_vbits |= dep_mask;
check_computeblockversion(vbcache, chainParams->GetConsensus(), dep);
Expand Down
13 changes: 12 additions & 1 deletion src/validation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1500,7 +1500,13 @@ bool MemPoolAccept::PolicyScriptChecks(const ATMPArgs& args, Workspace& ws)
const CTransaction& tx = *ws.m_ptx;
TxValidationState& state = ws.m_state;

const unsigned int scriptVerifyFlags = PolicyScriptVerifyFlags(args.m_ignore_rejects);
unsigned int scriptVerifyFlags = STANDARD_SCRIPT_VERIFY_FLAGS;

// CHECKSIGFROMSTACK (BIP348) is always active on regtest, but no other chain.
if (args.m_chainparams.GetChainType() == ChainType::REGTEST) {
scriptVerifyFlags |= SCRIPT_VERIFY_CHECKSIGFROMSTACK;
scriptVerifyFlags &= ~SCRIPT_VERIFY_DISCOURAGE_CHECKSIGFROMSTACK;
}

// Check input scripts and signatures.
// This is done last to help prevent CPU exhaustion denial-of-service attacks.
Expand Down Expand Up @@ -2687,6 +2693,11 @@ static unsigned int GetBlockScriptFlags(const CBlockIndex& block_index, const Ch
flags = it->second;
}

// Enforce CHECKSIGFROMSTACK (BIP348)
if (DeploymentActiveAt(block_index, chainman, Consensus::DEPLOYMENT_CSFS)) {
flags |= SCRIPT_VERIFY_CHECKSIGFROMSTACK;
}

// Enforce the DERSIG (BIP66) rule
if (DeploymentActiveAt(block_index, chainman, Consensus::DEPLOYMENT_DERSIG)) {
flags |= SCRIPT_VERIFY_DERSIG;
Expand Down
Loading