-
Notifications
You must be signed in to change notification settings - Fork 56
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
History store row allocator requires concurrency guard. #150
Comments
And in the local data base, losses are even greater |
What is meant by "local database" above? |
This is if I run the libbitcoin server and in the explorer config writing local url. |
This is what I get when running against the default community server: Note that the last two spends have no correlated outputs (receipts). This implies that the outputs are not indexed to the address It is also possible that spend correlation is being impacted by correlation ID hash collision. If the server is fully-indexed and the outputs are standard (allowing for address parsing) then this is the only possible cause short of a code error. The use of a 64 bit hash to store input-output correlations in the spend table is a longstanding weakness of libbitcoin-server. It does not impact validation as the spend table only supports server queries. In v4 the spend table will be eliminated altogether and these queries will rely on a relational surrogate key index, resolving this issue and significantly reducing server storage. History correlation occurs in the client library. It should be straightforward to modify the client to report the collision, and rebuild bx to verify that in this case collision is the problem. |
As far as I remember, transactions there are standard, not multisig, etc. You can check and make sure. |
it's really in the history database. I wrote this code
Load the base and got a output: count 36 That is, one number is repeated twice. That is, history db has time to lose the previous result between two inserts. Could you look in the nearest code, is there no race condition or other errors? |
Thanks for following up. Your read from with the write may make assumptions that don't hold. add_row is atomic and should not have any problem with concurrency. I'm on my phone for another week, so it will be hard for me to review. |
I hung a mutex on all methods of histories db and I got rid of these errors! In general, I looked at some places, and did not understand how the locks work there. For example:
What happens if 2 threads get one value of old_begin and try to write it down? Other places in the code also do not cause trust |
The above critical sections exist only to guarantee atomicity of the link value read and write. I believe you are correct in that the list insertion has a flaw in that concurrent inserts can result in the orphaning of an inserted element. This would affect address history index in the case of concurrent writes of the same row (address hash) only. [There would be no node/consensus impact.] Expansion of the critical sections beyond value atomicity may introduce a deadlock risk, so I would need to look at it more closely to ensure a fix is both safe an optimal. However otherwise expansion of the critical section above to the full method using an upgraded lock should resolve the orphaning. I don't understand your last comnent, could you clarify? |
For example, this code also causes race condition:
If 2 threads simultaneously take start_info, and see that it does not exist |
Yes, the row allocator needs to be protected in the same manner as the memory allocator. Thanks for your work on this. I can patch within a week. |
It's taken a little longer than expected, but I hope to finish this up in the next couple of days. |
History records are safely written, read and popped with the exception that concurrent link of a new element is a race that is won by only one of the writes in the race. Behavior is well-defined but leads to record loss in the case where there is a concurrent link of two records against the same payment address. This becomes more likely in the case of heavily-used addresses where there are multiple updates from transactions in the same block (which is the only case of concurrent write to the same hash table entry). |
I've resynced my local store and verified the balance as well as correct history pairings for 1BrT827NCgxjctnEBdLiuDzukupwWHP1i2 and 1966U1pjj15tLxPXZ19U48c99EJDkdXeqb. |
Look at the address 1BrT827NCgxjctnEBdLiuDzukupwWHP1i2.
He owns the transaction e521a32cc35519164f6fd74e3b682071e3880c1b5099e5ae863ef340eb916097 (input and output) (https://blockexplorer.com/tx/e521a32cc35519164f6fd74e3b682071e3880c1b5099e5ae863ef340eb916097).
But in the history database, there is no output information.
This can be seen, for example, by transaction f26104fed45e7aaedfddcdeb713d12c1d2369330387b316f1797562c58f0be78.
Bitcoin explorer can not match the input of this transaction to the output
./bx fetch-history -c ./bx.cfg 1BrT827NCgxjctnEBdLiuDzukupwWHP1i2
Is it possible to solve this problem?
The text was updated successfully, but these errors were encountered: