-
Notifications
You must be signed in to change notification settings - Fork 35.6k
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
[BIP-117] Tail call semantics #12132
Conversation
src/script/interpreter.cpp
Outdated
script = CScript(policyScript.begin(), policyScript.end()); | ||
popstack(stack); | ||
// Only allow one tail-call: | ||
allow_tail_call = false; |
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.
Apologies for being annoying//this may be a stupid question: but why only do TCO once?
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.
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.
Thank you very much!
@@ -1039,6 +1043,20 @@ bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript& | |||
if (!vfExec.empty()) | |||
return set_error(serror, SCRIPT_ERR_UNBALANCED_CONDITIONAL); | |||
|
|||
if (allow_tail_call && !stack.empty() && ((stack.size() + altstack.size()) >= 2) && CastToBool(stack.back())) { |
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 third condition of the specification is not checked:
https://github.com/bitcoin/bips/blob/master/bip-0117.mediawiki#specification
the following Nth element on the main stack (or alt stack, as above) is between 1 and 520 bytes,
Should it?
About being able to concatenate up to 17 elements to form the script: why stop at 17? Would be great to include some rationale about this in the BIP, or possibly extend the BIP to allow longer scripts if that makes sense.
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.
Oops. The current version of this pull request does not match the BIP. My fault -- we were so busy converting MERKLEBRANCHVERIFY to be multi-element that it slipped though cracks. The BIP was updated to the new scheme which allows the script to be split across multiple stack elements, but this PR does not reflect that. I will update this PR to match the BIP.
To answer your question though, the reason that a maximum number of 17 elements is allowed, is due to the fact that only OP_1 through OP_16 are provided as single-byte opcodes, and 17*520 = 8,840 bytes is close enough to the maximum script limit of 10,000 bytes that it doesn't necessarily make sense to have a further exception for 18 or 19 pushes to reach the full limit. Particularly since MAST eliminates the need for such long scripts in the first place.
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.
Thanks!
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 PR has been updated to allow for multiple script elements, as specified in BIP 117.
a3e81f4
to
d088acb
Compare
Travis build error looks like a transient issue. |
If, at the end of script execution, the stack has more than one item on it, the top-most element is interpreted as a serialized script and executed, with the remaining elements on the stack as inputs. No state is maintained, and termination of the subscript terminates execution of the script as a whole. Only one tail-call is allowed per script execution, and neither P2SH nor segwit nor execution of the scriptSig results in tail-call semantics, although the P2SH or segwit redeem script can make a single tail-call.
…sactions that fail tail-call verification will be rejected from the mempool, making it easier to test and later soft-fork activate this feature. Blocks which contain transactions with "invalid" tail-call semantics will still be accepted; this is *not* the soft-fork required to use tail-call semantics in production.
Implements BIP 117 as policy rules for transaction relay, causing transactions which violate the new tail-call semantics to be treated as non-standard. This is not the soft-fork activation logic needed to use tail-call scripts in production.
Tail-call semantics is a sort of user-programmable P2SH which combines well with BIP 116's MERKLEBRANCHVERIFY to allows for a script to commit to a practically unbounded number of code pathways, and then reveal the actual code pathway used at spend time, achieving a form of generalized MAST.