Skip to content

Draft: (IGNORE ME) Add bitwise operators to Michelson's byte types

Ghost User requested to merge (removed):d4hines/implement-bitwise into delphi

This MR is purely an exercise I'm doing for @galfour and can be ignored by others.

What I did

The MR extends the Michelson operators NOT, AND, and OR to work on the bytes type.
It does the following:

  • Extends the typed IR to allow the said operations on bytes
  • Extends the mBytes primitive operators with not, or, and and functions
  • Extends the interpreter to perform the respective operations
  • Extends the gas calculations with costs for the new operations

For testing, it adds new integration tests to test_contract_opcodes.py and updates the regression test outputs.

Forgive the improper formatting - make fmt failed with an error that I gave up on trying to fix.

How I did it

This MR is pretty thoughtless/mechanical. I merely copied the implementations for nats. Moreover, as will probably be obvious to an OCaml expert, I don't have a grasp of the native OCaml types for bytes - there is undoubtedly a more efficient way to do it. Lastly, I doubt my gas cost functions have any bearing on reality - it's a shot in the dark based on imitation of the other functions.

Given this was my first look at an OCaml project, and given my time constraints with work, school, etc., my strategy was a depth-first search: ignore the Tezos docs and the rest of the source code, and anywhere I see "and", "not", or "or", extend it with an identical function for bytes. I used the docs only when I ran into problems. In hind sight, I spun my wheels for a long time trying to get the project up with the tests passing, and would have done well to refer to the documentation sooner.

Things I'm Worried About

I'll be honest - I haven't done much low-level programming. Thus, I'm worried I missed something in the implementations of the bitwise functions that would allow a bad actor to cause overflow errors or otherwise take down a node with exceptions.

On a similar note, I'm worried about the cost functions. I haven't done the math to figure out if the gas costs as I implemented them are actually fair, so I'm worried there could be abuse there.

What I learned

OCaml is weird!

It has everything I'd want from a functional language, but also throws in mutation and exceptions, which I find off-putting. Mutation I could live with if done in a controlled manner (like in Rust). Exceptions... they just seem like a bad idea. Total functions ftw.

Tne Tezos Dependency Tree needs Discipline

I was surprised and am somewhat concerned by the sheer number of libraries Tezos uses. These create a very large dependency tree. The larger our dependency tree, the more threat vectors we expose ourselves to, particularly when we leave pure OCaml and get into arbitrary Unix packages. A small dependency tree also affords more control over our own destiny. We should try to trim our deps tree. Ideally, we could even use the Mirage project as a secure base and compile Tezos into a unikernal OS.

The Tezos code base is scary, but not as scary as it looks

I was initially intimidated by the sheer size of the Tezos code base, as well as the variety of contents (OCaml implementation, Python tests, a custom tezt thing, endless scripts). I'm still very cautious; however, the src/proto_alpha folder weighs in at only 52K LOC, with lib_protocol occupying 36K of that, so it definitely seems feasible to wrap one's head around the whole project over time.

The Tezos testing story needs help

Integration tests are useful quality assurance tools; however, they make for a poor development experience. Unit tests are far better for enabling short cycle time, and would have been super helpful as a newbie to the language. I instead relied on guess work, taking coffee breaks while OCaml recompiled the entire project and ran the Python scripts (the --last-failed flag was a Godsend!).

That said, the regression test suite is really handy. Someone has obviously put a lot of love into setting it up, and it was nice to just run the --regtest-reset flag to add new tests.

For a project of this size and import, in addition to the regression tests it already has, I would expect unit tests for rapid cycle times and property-based tests to catch potentially-dangerous edge cases (it looks like the de facto library is qcheck in OCaml - why aren't we using that?).

What I will do next

My random walk through Tezos and OCaml got the job done, but now it's time to go back and learn both for real. I need a cup of coffee and an afternoon in the sun to browse the Tezos docs. I also need to get my hands on a copy of Real World OCaml. I think that will put me in a much better spot for the next PR.

Edited by Ghost User

Merge request reports