OP_REVERSEBYTES#358
Conversation
|
This is a great idea! Though of course, whether it comes in November will depend a lot if there is the dev bandwidth to actually make this consensus change. (Though the change itself is almost trivial, it requires activation logic + lots of testing.) |
see #358 (comment) for a rationale
|
Why doesn't SLP use little endian instead? |
spec/op_reverse.md
Outdated
|
|
||
| * Covenants and looping scripts usually take the script code of the preimage [9] as input, which means every operation counts twice: Once for the stack item containing the script code, and once for the P2SH script stack item [10]. In the example above, this would save 32 bytes per conversion, and if there's, say, three of those conversions in a script, it would already amount to 96 bytes - a non-trivial amount of bytes for a transaction. | ||
| * The cognitive load of developing scripts using the larger snippet above is increased unnecessarily. Developing scripts, by hand or by using tools such as macros or Spedn, already puts a lot of cognitive load on developers, and errors can be devastating to the community. A prominent example of such a failure is the contentious hard-fork on the Ethereum blockchain that was caused by a bug in The DAO smart contract. | ||
| * The first version assumes that Script uses 32-byte numbers, however, once 64-bit numbers are implemented, the script fails when numbers that do not fit in 32-bits are used [11], and has to be updated. The second version will work with up to 64-bit numbers. |
There was a problem hiding this comment.
| * The first version assumes that Script uses 32-byte numbers, however, once 64-bit numbers are implemented, the script fails when numbers that do not fit in 32-bits are used [11], and has to be updated. The second version will work with up to 64-bit numbers. | |
| * The first version assumes that Script uses 32-byte numbers, however, once 64-bit numbers are implemented, the script fails when numbers that do not fit in 32-bits are used [11], and has to be updated. The second version will work with up to 64-bit numbers. OP_REVERSE itself has no limit on the length of the byte vector it reverses. |
Clarification.
There was a problem hiding this comment.
I've rewritten the rationale to be less SLP-centered, do you think we could add this clarification somewhere else?
spec/op_reverse.md
Outdated
| * The cognitive load of developing scripts using the larger snippet above is increased unnecessarily. Developing scripts, by hand or by using tools such as macros or Spedn, already puts a lot of cognitive load on developers, and errors can be devastating to the community. A prominent example of such a failure is the contentious hard-fork on the Ethereum blockchain that was caused by a bug in The DAO smart contract. | ||
| * The first version assumes that Script uses 32-byte numbers, however, once 64-bit numbers are implemented, the script fails when numbers that do not fit in 32-bits are used [11], and has to be updated. The second version will work with up to 64-bit numbers. | ||
|
|
||
| Further, there's likely many additional use cases beside encoding SLP values, as many protocols outside of Bitcoin use big endian numbers, and all of them would benefit from this opcode. Also, it can be used to check palindromes. |
There was a problem hiding this comment.
| Further, there's likely many additional use cases beside encoding SLP values, as many protocols outside of Bitcoin use big endian numbers, and all of them would benefit from this opcode. Also, it can be used to check palindromes. | |
| Further, there's likely many additional use cases beside encoding SLP values, as many protocols outside of Bitcoin use big endian numbers, and all of them would benefit from this opcode. It can also be used to check palindromes. Besides number encoding, OP_REVERSE may be useful for manipulation of non-numeric data. |
BigBlockIfTrue
left a comment
There was a problem hiding this comment.
Nice work. I included some suggestions for minor changes.
|
I posted off-github:
|
|
Specifically: why wouldn't the big-endian to little-endian conversion when interacting with "protocols outside of Bitcoin" happen off-chain? |
I've rewritten the rationale to be non-SLP specific. It now focuses mostly on why encoding numbers in big-endian is desireable. |
* Adds more basic unit tests * Adds unit test checking whether reversing twice returns the original value. * Covers both even and odd lengths of the byte vector. Co-Authored-By: BigBlockIfTrue <32314686+BigBlockIfTrue@users.noreply.github.com>
|
@markblundeberg Thoughts on the updated version? c26607c |
|
Hmm interesting, though it still feels like most protocols can just adapt and provide little endian numbers. Do you see any use case besides endianness conversions? |
There aren't many; but given the crazy things some C developers came up with for optimizing their code (like fast inverse square root), there's probably some real-life function that corresponds to reversing the bytes of an integer. Otherwise, on the top of my head, I came up with these additional use cases, which are just versions of already possible things, but requiring Simple proof-of-work check: Without 6 bytes, checks number of leading zeros. With 5 bytes, checks whether the N leading bytes are a palindrome ( Pushing a large number (only relevant once we've got 64-bit or higher numbers): Without 8 bytes With 4 bytes With 256-bit numbers, the first one would take 32 bytes whereas the second one would take 5 bytes. I know, the benefit is either niche or not really significant, but it is a possible use case. |
That's true, but not all protocols can just adapt, which is not possible for SLP tokens. One more point on endianness: Most services (explorer.bitcoin.com/rest.bitcoin.com, Bitdb, etc.) and protocols (most notably, SLP tokens) encode hashes (e.g. transaction hashes) in big endian. However, OP_SHA256 and OP_HASH256 encode hashes in little endian. If a script would calculate the hash of some external transaction and compare it to an input, or match the input against the outpoint, that input would have to be encoded in a little endian hash, making interaction with e.g. bitcoin.com's REST API and Bitdb very cumbersome. Of course, it's possible to add a switch/function to those services, but that will make interaction unnecessarily confusing and increase the congnitive load needlessly. At the end, it's mostly a question of goals: Should things be easy to do or is it already sufficient if they're just possible? For example, should we re-enable Similar with the already re-enabled However, it seems many would eventually like to see |
|
I think there's better ways to do something like |
|
Amaury (@deadalnix ) has suggested changing the name to "BSWAP", to match the similar instruction in other languages: |
|
I agree with the renaming of
|
|
Sorry to crash the renaming party, but I'd like to propose
|
|
I agree with @BigBlockIfTrue . (That being said, the name of the opcode is fairly unimportant in the grand scheme of things, so hopefully not too much time will be invested in deciding its name.) |
|
oh true |
|
Sorry to prolong this bikeshedding, but I'll repeat what I said in the review of the ABC Diff for the implementation of this (https://reviews.bitcoinabc.org/D4871). I'm not a fan of using the term "Endian" to me seems hardware specific, and usually implies some power-of-2 number of bytes. This opcode will be able to reverse bytes in strings of any length. "Endian" is a technical jargon term, and to me seems confusing. I also think it's possible people may use this opcode for things other than endian conversion, since it can reverse the byte order for any arbitrary-length string. I would suggest "OP_REVERSEBYTES". It fits with the criteria @BigBlockIfTrue mentioned, and it seems like just a straight description of what it does, without any jargon. |
|
Thanks everyone for the valuable feedback. As someone who writes Script by hand, having nice opcode names is not unimportant. To put an end to the bikeshed, I‘ll use the opcode name |
ftrader
left a comment
There was a problem hiding this comment.
Specification looks good but Unit Tests as enumerated seem insufficient.
At very least the size ranges of possible stack input data - from 1 byte to as many as are possible in data item that the operator should reverse - should be subjected to test.
Mengerian
left a comment
There was a problem hiding this comment.
could you change the file name to match the other recent ones on the spec folder? it would be 2020-05-15-reversebytes.md or something like that.
Also maybe change the title of the PR to "OP_REVERSEBYTES"
Mengerian
left a comment
There was a problem hiding this comment.
Looks good! Thanks Tobias.
* Create op_reverse.md * Update op_reverse.md * Change opcode to 192 (0xc0) see bitcoincashorg/bitcoincash.org#358 (comment) for a rationale * Rewritten rationale * Added and clarified unittests * Adds more basic unit tests * Adds unit test checking whether reversing twice returns the original value. * Covers both even and odd lengths of the byte vector. Co-Authored-By: BigBlockIfTrue <32314686+BigBlockIfTrue@users.noreply.github.com> * Renamed to OP_BSWAP, changed opcode number, added activation date * Fixed activation date in unit tests * Renamed OP_BSWAP to OP_ENDIAN_REVERSE * Rename OP_ENDIAN_REVERSE to OP_REVERSEENDIAN * Changed OP_REVERSEENDIAN to OP_REVERSEBYTES * Updated unittests and other minor changes * Rename op_reversebytes.md to 2020-05-15-op_reversebytes.md Co-authored-by: BigBlockIfTrue <32314686+BigBlockIfTrue@users.noreply.github.com>
A proposal to add OP_REVERSEBYTES to Script