-
Notifications
You must be signed in to change notification settings - Fork 38.7k
Fix off-by-one errors in the interpretation of IsFinal() #2342
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
Conversation
|
Automatic sanity-testing: PASSED, see http://jenkins.bluematt.me/pull-tester/67c7dab125e98a0c7b5e55035ddc5c90ab3b369d for binaries and test log. |
src/main.cpp
Outdated
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: transactions that can't be included
|
I like this idea, but it does need unit tests and some investigation for potential effects, as noted in the message. |
|
Here's a list of all effectively-height-locked transactions in the main chain (that means: excluding those where all inputs have nSequence=UINT_MAX): http://bitcoin.sipa.be/lockheight.txt - It seems the inclusion height is always at least two more than the number in nLockTime - one more than strictly required. |
|
Not many people uses nLockTime; about 75% of those transactions are mine. Can you run your script on testnet? I did one "min-height" tx myself, I wonder if anyone else did any. Mainly I think that BlueMatt's tests need more nLockTime stuff, IE the https://github.com/TheBlueMatt/test-scripts stuff. I don't think I'll have time to write any myself until after the conference. |
|
Status? Still has a FIXME. Let's close this or get it updated and merged. |
|
@jgarzik Updated, removed FIXME. Min-height nLockTime has been tested on testnet without any issues. |
|
Thinking about this some more. Regardless of the correctness, I don't like the addition of magic numbers (+1, +2) in various code locations. |
|
The +1 isn't a magic number; note how in one place the patch removes a +1. Rather it's there from how nBestHeight is the height of the current best block, and in some places we want to check IsFinal() against the next block. I'd argue the +2 isn't a magic number either, as it's a combination of +1 to get the next block, and another +1 from the assumption that no-one controls >50% of the hashing power as the comment mentions. Speaking of, while I was thinking about this and working on my mempool rewrite, it occurred to me that given that nBestHeight can decrements under the highly unusual condition of a re-org right on a re-target boundary passing around not quite yet final tx's might help exercise mempool and related code dealing with non-final txs. Not a particularly strong argument, but it's worth thinking about. |
|
@petertodd Needs rebase. |
|
Rebased and added CreateNewBlock() unittests |
|
I did another scan of the blockchain looking for nLockTime using transactions: https://s3.amazonaws.com/peter.todd/nLockTime.log Still none mined at the minimum possible heights, and very few that have used lock-by-time. However this has been tested on testnet. |
|
ACK |
|
FYI I rebased this here laanwj@c3858c5 , needed changes to the main and GUI code were: Needed changes miner_tests: The tests pass successfully. Seeing that @sipa already acked this 5 months ago, if you can check that my rebase is correct we may be able to merge this before the 0.9 release. |
Previously CreateNewBlock() didn't take into account the fact that IsFinalTx() without any arguments tests if the transaction is considered final in the *current* block, when both those functions really needed to know if the transaction would be final in the *next* block. Additionally the UI had a similar misunderstanding. Also adds some basic tests to check that CreateNewBlock() is in fact mining nLockTime-using transactions correctly. Thanks to Wladimir J. van der Laan for rebase.
|
@laanwj Thanks. ACK |
|
Automatic sanity-testing: PASSED, see http://jenkins.bluematt.me/pull-tester/665bdd3bc9ba4ac566edf5ba3fa8bbd93eb4780f for binaries and test log. |
665bdd3 Fix off-by-one errors in use of IsFinalTx() (Peter Todd)
Basically AcceptBlock() checks IsFinal() for transactions in a block with nHeight of the block being tested, or essentially nBestHeight+1 however CreateNewBlock() was using just nBestHeight, so transactions were being included into blocks one block later than they could be.
Additionally the new IsFinal() test in IsStandard() had the same issue, as well as the UI. (ironically, a fix I wrote a few months ago, lead astray by simply watching to see when transactions got mined on testnet)
The bug in CreateNewBlock() is especially nasty for fidelity bond sacrifice transactions, because a miner who knew the trick could collect all the fees for himself, one block before anyone else had a chance. (subject to hash power of course)
Anyway, I should update the patch with unittests and investigate the issue more carefully; for instance, have there ever been any nLockTime'd transactions ever mined in the main chain at the minimum possible block? Also, can the same logic be fixed for time-locked transactions?