-
Notifications
You must be signed in to change notification settings - Fork 36.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
Mempool only CHECKLOCKTIMEVERIFY (BIP65) verification, unparameterized version #6124
Conversation
While the existing numeric opcodes are all limited to 4-byte bignum arguments, new opcodes will need different limits.
Will now be needed by CHECKLOCKTIMEVERIFY code.
ACK. This version is well tested. |
As stated, I prefer this one, it is smaller code, has been more tested, save one byte. My aesthetic argument is that we will get nicer human readable script. (< locktime > OP_CLTV and < push > OP_RCLTV, instead of cryptic < locktime > < mode > OP_CLTV ) |
Nit: I think CheckLockTime's full implementation would conceptually fit better implemented as part of BaseSignatureChecker (and it would remove a few lines of code), because the purpose of the BaseSignatureChecker/TransactionSignatureChecker split is just to have a checker that skips expensive ECDSA validation. Checking the locktime is fast, and it feels safer to have BaseSignatureChecker do the check. In practice, the above nit doesn't matter, the only place BaseSignatureChecker is used at the moment is checking for non-standard scriptSigs. Besides that, code review ACK. |
BaseSignatureChecker does not know that the data being signed is a
transaction.
|
// | ||
// Thus as a special case we tell CScriptNum to accept up | ||
// to 5-byte bignums, which are good until 2**32-1, the | ||
// same limit as the nLockTime field itself. |
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 is not clear: 5-byte CScriptNum should be good up to 2**39-1, beyond the limit of the nLockTime field.
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.
Fixed.
7978496
to
afc4ff9
Compare
Yes, the whole point of BaseSignatureChecker is that EvalScript doesn't need to know anything about transactions. |
any plan to merge that for 0.11 ? I know I can play with it with viacoin/testnet with mempool rule, but I think there is no point in delaying it anymore since there is no controversial problems anymore with it. |
I don't see any reason not to do it either. maaku prefers the other version but I don't think he is opposed to this one, which seems to be preferred by almost everyone else. |
utACK |
@@ -76,6 +76,10 @@ enum | |||
// (softfork safe, BIP62 rule 6) | |||
// Note: CLEANSTACK should never be used without P2SH. | |||
SCRIPT_VERIFY_CLEANSTACK = (1U << 8), | |||
|
|||
// Verify CHECKLOCKTIMEVERIFY (BIP65) | |||
// |
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.
Stupidest little nit... this empty comment line can be removed, no? Or better yet explain the feature like the other comments do.
My objections about the unparametrized version should not be interpreted as release blocking. I prefer the original form for a couple of reasons. Tested ACK. I thoroughly reviewed and tested this code as part of the Project Elements release. |
<nLockTime> CHECKLOCKTIMEVERIFY -> <nLockTime> Fails if tx.nLockTime < nLockTime, allowing the funds in a txout to be locked until some block height or block time in the future is reached. Only the logic and unittests are implemented; this commit does not have any actual soft-fork logic in it. Thanks to Pieter Wuille for rebase. Credit goes to Gregory Maxwell for the suggestion of comparing the argument against the transaction nLockTime rather than the current time/blockheight directly.
Transactions that fail CLTV verification will be rejected from the mempool, making it easy to test the feature. However blocks containing "invalid" CLTV-using transactions will still be accepted; this is *not* the soft-fork required to actually enable CLTV for production use.
afc4ff9
to
ffd75ad
Compare
@maaku's Fixed nit. Also thanks for the review! |
code review ACK Are there any remaining blockers to merging this? |
@jgarzik Nothing I can think of. If for some reason we find we totally screwed up plan is to just change the behavior, use a new NOP, and go from there. (as was discussed a few months ago with no objections: #5496 (comment)) |
code review ACK. Will test and write some example RPC regtests within the next days. |
@jonasschnelli RPC regtests? What would those regtests actually do? I do have very simple demo's of CLTV here: https://github.com/petertodd/checklocktimeverify-demos |
@petertodd: some simple CLTV real-world examples. Creating some CLTV transactions (needs hex fiddling because the wallet doesn't support it right now), broadcast, mine some blocks, see what's in there. |
@jonasschnelli Hmm, I suspect the actual testing value of doing that is relatively low, at least until the soft-fork code goes in; the actual opcode itself is very well tested in the script tests, and there's no IsStandard() changes associated. (yet) I personally would add that kind of thing to cltv-demos because I greatly prefer the python library it uses. That said, I certainly have no objection to doing that - and it might come in handy when we do add block tests for the soft-fork code - although I'd ask that we don't wait on it before merging this pull-req. |
Sure. I didn't mention the rpc test to hold this PR back. |
What about changing script.cppL144 from |
@jonasschnelli Good point. Anyone have any idea what doing that will break? :/ |
@petertodd the tests... |
I came up with this because it's exposed in the RPC call |
Nice work on this @petertodd. It'll be very useful once it's rolled out! I ran some CLTV style micropayment channel deposit and refund tests on testnet. Overall, the changes look good. I'm wondering why you chose to make OP_CHECKLOCKTIMEVERIFY not pop the input argument off the top of the stack in the success case? In the success case, by not popping, the semantic of the original no-op definition of OP_NOP2 is preserved. I assume that maintaining the no-op semantic for old clients, so that they could still validate scripts using the new semantic of the opcode, was your reason. During the transition, I don't think preserving the no-op semantic in this case is desirable for the same reason that it is not desirable to start using CLTV outputs prior to the 95% lock-in during a soft fork -- the refund path in CLTV scripts could be interpreted as no-op's on non-time-locked transactions to claim the refund outputs early. If backwards compatibility for older clients was the only reason, then I think that changing to popping the input stack argument should be considered because:
Make sense? |
Here's a table of the combinations of test cases that I tried.
*Note: Failures are caused by trying to get a CScriptNum from the top of the stack and by checks within TransactionSignatureChecker::CheckLockTime. Outcomes are script dependent, but for the cases I tried, always failed. |
If you pop the argument off the stack it becomes a hard fork change.
|
@maaku: Doh, after re-thinking, I think you are right about that. I think I confused myself by asking the wrong question when I was contemplating whether having it pop would then be a hard vs. soft fork change. Now, when I ask myself: The answer is, yes. I even alluded to that in my previous message, "Having new scripts expect that the stack is popped on success would break the new scripts on older validators." Does that match with what you were thinking? If so, then yes, please forget my suggestion of making the CLTV pop. |
Correct.
|
@maaku cool, thanks for correcting me on that. @jonasschnelli and @petertodd : About the "asm" translation update, when we were talking about removing the "OP_" prefixes and adding SIGHASH decodes for #5264 and #5392, we did not come up with too much to worry about breaking when changing the "asm" results. Back then, it seemed like breaking dependencies on "asm", if they existed, was perceived as a potentially desirable outcome anyways. For example, #5264 (comment) |
@mruddy Thanks for reminding me! That's a good argument. :) I'll look into doing that then. |
@petertodd @mruddy Isn't that sort of out of scope for this particular PR? |
@btcdrak @petertodd I think updating the opcode name decode is justifiable in the interest of being complete. People do look at the "asm" in the raw transaction and script decodes. Having it read as OP_NOP2 could be misleading, especially to casual users, after the new semantic is in effect. As far as timing, it's not critical to update the opcode name decode right now (especially if it pushes this pull request out further). The decode update could be done along with the soft-fork updates, or even later as a part of an opcode decode name cleanup (where the "OP_" prefixes get dropped, etc...). But, since there is the justification of being complete with the semantic change, I think it is acceptable to break any possible ill-advised external dependencies on the existing "asm" decode. |
@mruddy That all sounds reasonable. After all, if changing the name isn't a big deal, then changing the name with another pull-req shouldn't be a big deal, and will cut down on the amount of unnecessary code changes in the more pull-req that does change consensus-critical code. IMO, this pull-req is ready for merging as-is. |
@petertodd I'm good with that. Tested ACK |
utACK |
1 similar comment
utACK |
Same as #5496, but with without the "type" parameter. In this pull-req, a future relative CLTV or other new modes would need to be implemented with another opcode. (e.g. the original proposal)
I personally have a preference for this version, as we're in no danger of running out of NOPs.