-
Notifications
You must be signed in to change notification settings - Fork 372
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
Reverse bitcoin_hash in memory #144
Conversation
This looks good. I'm queuing up patches for -protocol/-client/-explorer. |
So is it true that the obelisk wire protocol hash is reversed and the in-memory representation is now "unreversed", meaning that we need to explicitly reverse in -protocol (and will need to in new -server code)? Doing so fixes test failures in -protocol. |
I'm going to templatize encode/decode_hash as follows: template <typename Hash>
std::string encode_hash(const Hash& hash); template <typename Hash>
bool decode_hash(Hash& out, const std::string& in) Because we lost implementation for the other hash sizes. |
We have to make a decision for BX on hash encoding. A large number of tests are failing due to the reversal. Wire encoding is what is typically presented, such as in blockchain.info info. The easiest way to repair the tests, existing documentation, and to retain correlation with other services, is to reverse the hash for all presentation. That sort of begs the question however, why we wouldn't just treat the reversed format as canonical internally. |
I tried reversing the output for hash encode and decode, but the problem is much deeper than that. Any libbitcoin function that accepts or returns, directly or indirectly, a |
As an API our constraints are different to a monolithic blob, so I tried to keep the representation close to what people expect. There are 2 options: custom hash type with reversed representation, or reversing the data in hashing functions (which is what libbitcoin does). |
@genjix I think that they key question is "what people expect". While there are a number of conversions internally to accomplish this, the API does expose what people expect to see. I think this is the proper choice as it hides the confusion in the library implementation instead of exposing it to API users. BX uses most of the libbitcoin APIs and after looking through the tests failures, and trying to make it work, it's clear that in order to represent what people expect there would be conversions in a lot of places, where there are none presently. |
I'm sorry, but both you guys you have it all wrong. In the old system, everything followed this double-reversal pattern:
As you can see, the only operation that isn't double-reversed is the base16 conversion. This means that everything external to the libraries is already the right way around! The obelisk wire protocol, for instance, has the bytes in the same order you would get from sha256(sha256), since the serializer was un-reversing them. In the new system, things work like this:
Now, instead of reversing bytes everywhere, we reverse the bytes in one place - the text conversion. This is why So, I have good confidence that I can fix BX completely, reliably, and correctly by swapping out a grand total of 3 functions. None of the other libraries should need any changes whatsoever. As far as outside library users like are concerned, yes, this breaks API. However, the current API is insane, and is not what anybody would expect. It is utterly inconsistent with all other Bitcoin software. Just look at that first chart again, and notice that every operation that touches the blockchain has to un-reverse the hash before it can proceed. Here at AirBitz, these reversed hashes have bitten us pretty hard. Any time we go to cobble together a tool in another language, like Python, we have to account for the fact that the binary data inside our database is reversed. We would not be having these nightmares if the binary data had been the right way round in the first place. |
The experience I had after checking out the changes was that compilation was relatively easy to achieve and I had a handful of test failures in The In bx, after reversing |
I'll take a poke as well. One requirement with this new branch is that all bitcoin_hashes must go through |
I noticed something along these lines, which is why I want to take another look. I'm tied up in the clang/osx Travis build configuration at the moment. |
This looks like a bug in libbitcoin-protocol! The protobuf field is "bytes", and the description indicates that it's bytes, but the converter is actually shoving in base16 ASCII text. |
I just ran the following procedure, so it looks like the hash reversal doesn't actually affect libbitcoin-protocol:
Things still work at step 4, so we're good here. Pull requests coming soon, once I add a 'hash_literal' to libbitcoin. |
Cool, I won't get to this until the morning but I'm hopeful based on seeing something I missed last time around. |
Ok, I've updated the branch based on my work with libbitcoin-protocol. The base16 and hash conversions now have a bettery symmetry:
|
The protocol changes are in libbitcoin/libbitcoin-protocol#36 |
I have finished fixing bx. I was able to do the same 4-step process using As with libbitcoin-protocol, there were some cases where decode_hash was being used for ec_secret's. There were also a lot of cases where The pull request is libbitcoin/libbitcoin-explorer#171 |
I have just done another update. This one fixes the problem with |
I have created a new pull request, #147, which includes just the base16 changes. We can go ahead and pull that while we wait to decide on the hash reversal. |
0befb8f
to
198effd
Compare
After further discussion with @swansontec, and narrowing the actual issue down to this simple commit, I'm convinced we should take this change. The expected representation is achieved through the encode/decode functions, which should always be used with to textually serialize our hashes in any case. |
With this change, the reversal only takes place in the encode_hash and decode_hash functions.
Reverse bitcoin_hash in memory
This is a pretty big change. Please see the email on the mailing list. Let's hold off on merging this for a day or two, to be sure it's stable.