-
Notifications
You must be signed in to change notification settings - Fork 6
BIP348 OP_CHECKSIGFROMSTACK #72
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
BIP348 OP_CHECKSIGFROMSTACK #72
Conversation
8b70161
to
c401fa4
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code review ACK c401fa4 - Seems reasonable to enable this for experimentation (in the same vein as the other already deployed changes on signet).
Reviewed that this matches the spec in the BIP as well as bitcoin#32247 (the implementations are different but behave the same afaict).
I helped at fairly complete tests to bitcoin#32247 so those can be ported over (again, if there is interest by the maintainer here) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me, save for setting discouragement by standardness before activation. Happy to reACK after you pull in the additional test coverage.
SCRIPT_VERIFY_CHECKSIGFROMSTACK = (1U << 28), | ||
|
||
// Making OP_CHECKSIGFROMSTACK non-standard | ||
SCRIPT_VERIFY_DISCOURAGE_CHECKSIGFROMSTACK = (1U << 29), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You didn't add it to the call to DepDiscourageFlags()
in PolicyScriptChecks()
Concept ACK and ACK of correctness of opcode implementation compared with BIP 348. I'm not too familiar with how policy rules are expressed, so can't speak for that. |
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers. ConflictsReviewers, this pull request conflicts with the following ones:
If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first. |
c401fa4
to
5a7b2ac
Compare
Added a regtest-only deployment and functional testing. I have another branch where I tested pre-activation relay logic and things checked out, but activating a heretical deployment was a little more annoying than in Core so I left it out: https://github.com/instagibbs/bitcoin/tree/2025-06-csfs-activation-tests CI failure seems unrelated? |
@@ -145,6 +145,7 @@ class CMainParams : public CChainParams { | |||
consensus.vDeployments[Consensus::DEPLOYMENT_CHECKTEMPLATEVERIFY] = SetupDeployment{.activate = 0x60007700, .abandon = 0x40007700, .never = true}; | |||
consensus.vDeployments[Consensus::DEPLOYMENT_ANYPREVOUT] = SetupDeployment{.activate = 0x60007600, .abandon = 0x40007600, .never = true}; | |||
consensus.vDeployments[Consensus::DEPLOYMENT_OP_CAT] = SetupDeployment{.activate = 0x62000100, .abandon = 0x42000100, .never = true}; | |||
consensus.vDeployments[Consensus::DEPLOYMENT_CHECKSIGFROMSTACK] = SetupDeployment{.activate = 0x62000100, .abandon = 0x42000100, .never = true}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You probably want different values from the OP_CAT deployment?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm going to need an explainer to figure out deployments in inquisition; can fix it along with potential signet one
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ajtowns could you provide guidance here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See #82; though you'll need a binana number. Maybe figure out a nice way to make a binana doc just reference a particular revision of a bip? (Have BIN-2025-xxx.md just have a header and a table that maps binana revision numbers to bips repo commit ids maybe?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bitcoin-inquisition/binana#1 turns out IK is already a thing in BINANA (and compatible), CSFS needs modification. Can the BINANA be modified with author's consent or do you suggest a new one? I believe the *VERIFY variant is considered abandoned.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Modifications should be with author's agreement, and bumping the revision number and date. If it's just changing to reference an updated spec from the same author in the bips repo, I'd be happy to assume the author's agreement. Just getting a new number assigned is fine too (though I guess I'd want to add the author to the table in the README to better distinguish them in that case?).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it's just changing to reference an updated spec from the same author in the bips repo, I'd be happy to assume the author's agreement
I'd want the literal spec in BIP348 (obviously), seems easiest.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@reardencode Are you ok with this idea?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that seems reasonable. Definitely better than trying to keep the two docs in sync.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe figure out a nice way to make a binana doc just reference a particular revision of a bip?
You might like to reference BIN16-118 for how to simplify BINANA assignments for BIPs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ACK 5a7b2ac
Verified that the consensus changes match BIP-348 and reviewed the tests, didn't look closely at the deployment parameters (only checked that it's regtest-only).
OP_CHECKSIGFROMSTACK = CScriptOp(0xcc) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
duplicate line, it's already added in the main commit
OP_CHECKSIGFROMSTACK = CScriptOp(0xcc) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed
src/script/interpreter.cpp
Outdated
@@ -1988,6 +2088,12 @@ std::optional<bool> CheckTapscriptOpSuccess(const CScript& exec_script, unsigned | |||
} else if (!(flags & SCRIPT_VERIFY_OP_CAT)) { | |||
return set_success(serror); | |||
} | |||
} else if (opcode == OP_CHECKSIGFROMSTACK) { | |||
if (flags & SCRIPT_VERIFY_DISCOURAGE_CHECKSIGFROMSTACK) { | |||
return set_error(serror, SCRIPT_ERR_DISCOURAGE_OP_SUCCESS); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: could introduce a new error code SCRIPT_ERR_DISCOURAGE_OP_CHECKSIGFROMSTACK
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added
5a7b2ac
to
28b0830
Compare
Implements script validation, but no exposure to any network as of yet.
28b0830
to
871b0b0
Compare
871b0b0
to
69394e6
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ack 69394e6
@@ -1076,6 +1078,13 @@ def big_spend_inputs(ctx): | |||
|
|||
# == Test for sigops ratio limit == | |||
|
|||
# BIP348 CSFS signatures are embedded directly into the tapleaves vs the witness stack |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment was a bit confusing to me - perhaps someting like: "BIP348 CSFS messages and signatures can be embedded directly into the tapleaves to simplify testing since they do necessarily cover the spending transaction"
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); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
doesn't sound right to validate the signature before checking this
EvalChecksigTapscript
does this check first before validating the sig and in the core PR it is done first as well
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR follows the BIP more closely than random implementation details of taproot. I'm willing to change it but I'd need general agreement on it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The BIP says "These opcodes are treated identically to other signature checking opcodes and count against the sigops and budget." which to me implies it should closely follow the random implementation details of the other signature checking opcodes...
(Checking the budget before incurring the expense doesn't seem like a random implementation detail, though...)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is strictly equivalent? There is no execution path where we would perform the verification but not end up either accounting for it here or immediately stopping Script execution.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you'd do one extra signature validation, not the end of the world jut calling it out that its different from how checksig implemented
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@benthecarman I assume he meant consensus semantically, not implementation-wise.
If it's a blocker for moving forward it can be changed...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not a huge deal, just calling out the difference
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is strictly equivalent?
You get a different error message (failing signature vs exceeded the budget); and you spend more execution time reporting the failed signature. Still fails in either case, so not the end of the world, but seems strictly worse, and not particularly justified by any of the BIP text. Matching the EvalChecksigTapscript
implementation seems more logical to me. 🤷♂️
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"reverted" to taproot flow in #87
* Returns false when script execution must immediately fail. | ||
* `success_out` must be set when returning 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_out) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: this is between EvalChecksigPreTapscript
and EvalChecksigTapscript
which can be a little confusing/annoying
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
moved in #87
closing for now since 29.x is active |
Partial resurrection of #45 , focused specifically on BIP348 spec adherence.
I kept the limited tests that pertained to OP_CHECKSIGFROMSTACK, but clearly it will need to cover the basic cases the BIP calls for.
If there's any intention to review this I can add the testing we think is appropriate, and activate on regtest/signet/whatever.