Live data from Hacker News

Show HN: Mako – a full Bitcoin implementation in C

github.com

61–70 of 129 posts

Re: Show HN: Mako – a full Bitcoin implementation in C

#61
post #55

Cool to study. Disappointed there are zero comments and the most terse variable names as possible. Almost like it was js-minified.

Some of the terse variable names are the result of my adherence to a GMP-like naming convention, which I find easy to read and aesthetically pleasing. The GMP naming convention is something like: - Pointer/Data - single letter followed by a "p" - Size/Length - single letter followed by an "n" So a function declaration might look like: static void process_bytes(uint8_t *zp, const uint8_t *xp, size_t xn); The above fun…

This is silly. The variable types are already giving you exactly this information. Why would you add a "p" when you already have the "*"? Likewise, size_t tells you that this is a size, no need for the "n".

Instead, the variable names should be used to convey information that the types alone can't convey.

Re: Show HN: Mako – a full Bitcoin implementation in C

#62
post #55

Earlier quoted context omitted.

Some of the terse variable names are the result of my adherence to a GMP-like naming convention, which I find easy to read and aesthetically pleasing. The GMP naming convention is something like: - Pointer/Data - single letter followed by a "p" - Size/Length - single letter followed by an "n" So a function declaration might look like: static void process_bytes(uint8_t *zp, const uint8_t *xp, size_t xn); The above fun…

This is a bad convention. Instead of `x` and `z`, you should describe what those pointers are meant to represent. I get that everything is subjective, but some things are actually just bad due to illegibility, and I think it is worth being frank about this.

I disagree. The function name gives context as to what they're meant to represent if you understand the convention. One of the conventions in mako is something like:

    int btc_tx_import(btc_tx_t *z, const uint8_t *xp, size_t xn);
This function deserializes a raw transaction of `xn` bytes at `xp` and stores the result in the transaction `z`. Zero is returned on failure.

What would be the alternative here? I suppose I could rename `xp` to `data`, `transaction_data`, `raw_tx_data`, or something like that? I don't think it adds any value and it just takes up extra space, making the code less readable.

Re: Show HN: Mako – a full Bitcoin implementation in C

#63
post #55

Earlier quoted context omitted.

Some of the terse variable names are the result of my adherence to a GMP-like naming convention, which I find easy to read and aesthetically pleasing. The GMP naming convention is something like: - Pointer/Data - single letter followed by a "p" - Size/Length - single letter followed by an "n" So a function declaration might look like: static void process_bytes(uint8_t *zp, const uint8_t *xp, size_t xn); The above fun…

This is a bad convention. Instead of `x` and `z`, you should describe what those pointers are meant to represent. I get that everything is subjective, but some things are actually just bad due to illegibility, and I think it is worth being frank about this.

Quality C code is descriptive in the function name and simply organized, the functions are usually doing one or two things and fairly obvious without many values being passed; you're going to glean a lot more from the function name than the variables. The measure for good C code is extremely different than higher level languages you may be more used to writing.

Re: Show HN: Mako – a full Bitcoin implementation in C

#64
post #55

Earlier quoted context omitted.

Some of the terse variable names are the result of my adherence to a GMP-like naming convention, which I find easy to read and aesthetically pleasing. The GMP naming convention is something like: - Pointer/Data - single letter followed by a "p" - Size/Length - single letter followed by an "n" So a function declaration might look like: static void process_bytes(uint8_t *zp, const uint8_t *xp, size_t xn); The above fun…

This is silly. The variable types are already giving you exactly this information. Why would you add a "p" when you already have the "*"? Likewise, size_t tells you that this is a size, no need for the "n". Instead, the variable names should be used to convey information that the types alone can't convey.

> Likewise, size_t tells you that this is a size, no need for the "n".

How do you differentiate the two input lengths? If I were to rename `xp` to `x` and `xn` to `n`, what should `yn` be renamed to? At the very least, there's going to need to be a `yn` somewhere.

It's very common for code to include the type when there are two inputs to a function (even when written more verbosely): e.g. `thing_len`, and `other_thing_len`.

The `p`-suffix convention can also save you in a situation like this:

    int x = 1;
    int *xp = &x;
    int y = 1;
    int *yp = &y;
It avoids naming collisions, and further down in the function, you'll be able to differentiate the pointer and the value. I find it very useful.

If you write multi-precision integer code in C[1] without this convention, you will end up with an unreadable mess. I certainly wish Torbjörn Granlund were here to testify to this.

[1] https://github.com/chjj/mako/blob/master/src/mpi.c

Re: Show HN: Mako – a full Bitcoin implementation in C

#65
post #62

Earlier quoted context omitted.

This is a bad convention. Instead of `x` and `z`, you should describe what those pointers are meant to represent. I get that everything is subjective, but some things are actually just bad due to illegibility, and I think it is worth being frank about this.

I disagree. The function name gives context as to what they're meant to represent if you understand the convention. One of the conventions in mako is something like: int btc_tx_import(btc_tx_t *z, const uint8_t *xp, size_t xn); This function deserializes a raw transaction of `xn` bytes at `xp` and stores the result in the transaction `z`. Zero is returned on failure. What would be the alternative here? I suppose I co…

Your english language description of it gives some good clues to the alternative:

  int btc_tx_import(btc_tx_t *transaction, const uint8_t *raw_transaction, size_t raw_transaction_size);
Or since clearly `tx` is already a convention for "transaction", it could be `tx`, `raw_tx`, and `raw_tx_size`. And sure, I have no problem with the `p` and `n` stuff, so it could be `txp`, `raw_txp`, `raw_txn`.

But from your description, the input is a "raw transaction" and the output is a "transaction". Using `x` to mean "raw transaction" and `z` to mean "transaction" is obtuse. You know that the input is a "raw transaction" and the output is a "transaction", but I as a fresh reader, don't, and your code does not help me understand.

Re: Show HN: Mako – a full Bitcoin implementation in C

#66
post #62

Earlier quoted context omitted.

I disagree. The function name gives context as to what they're meant to represent if you understand the convention. One of the conventions in mako is something like: int btc_tx_import(btc_tx_t *z, const uint8_t *xp, size_t xn); This function deserializes a raw transaction of `xn` bytes at `xp` and stores the result in the transaction `z`. Zero is returned on failure. What would be the alternative here? I suppose I co…

Your english language description of it gives some good clues to the alternative: int btc_tx_import(btc_tx_t *transaction, const uint8_t *raw_transaction, size_t raw_transaction_size); Or since clearly `tx` is already a convention for "transaction", it could be `tx`, `raw_tx`, and `raw_tx_size`. And sure, I have no problem with the `p` and `n` stuff, so it could be `txp`, `raw_txp`, `raw_txn`. But from your descripti…

You make a good point. I will consider changing the names for the import/export functions (but maybe not the MPI code). That or explain the inputs/outputs in detail in docs.

Re: Show HN: Mako – a full Bitcoin implementation in C

#67
post #39
post #24

This look cool! great job, congrats. What are you using as data storage? I understand btcd uses leveldb, are you using something similar?

I considered using leveldb initially, but that would require a C++ compiler and it also requires linking to libstdc++. So at that point, you might as well just write the project in C++, which defeats the point of this project. Mako uses LMDB. Aside from Berkeley DB, it's pretty much the only key-value store in town if you want a pure C project. In the end, it worked out well because I really like LMDB. It has a very…

There's always SQLite, which can also be used as a key-value store.

Re: Show HN: Mako – a full Bitcoin implementation in C

#68

Earlier quoted context omitted.

This is a bad convention. Instead of `x` and `z`, you should describe what those pointers are meant to represent. I get that everything is subjective, but some things are actually just bad due to illegibility, and I think it is worth being frank about this.

Quality C code is descriptive in the function name and simply organized, the functions are usually doing one or two things and fairly obvious without many values being passed; you're going to glean a lot more from the function name than the variables. The measure for good C code is extremely different than higher level languages you may be more used to writing.

I believe that this is a cop out, an excuse for a culture of poor conventions. In all languages, good functions should be named well, simply organized, and doing only one or two things, and without many arguments passed in. Also in all languages, parameters and variables should be named expressively. There's no reason C should be exempt from this.

Re: Show HN: Mako – a full Bitcoin implementation in C

#69

Earlier quoted context omitted.

Independent researches (Microsoft/Mozilla) showed that around 70% of security vulnerabilities are caused by memory safety bugs. That's one heck of a "memory safety and stuff" :) Here's one reference: https://msrc-blog.microsoft.com/2019/07/18/we-need-a-safer-s...

"memory safety bugs" sounds pretty broad. What sort of vulnerability doesn't involve memory access?

its “memory safety”, not “accesses memory”

Re: Show HN: Mako – a full Bitcoin implementation in C

#70
post #55

Cool to study. Disappointed there are zero comments and the most terse variable names as possible. Almost like it was js-minified.

Some of the terse variable names are the result of my adherence to a GMP-like naming convention, which I find easy to read and aesthetically pleasing. The GMP naming convention is something like: - Pointer/Data - single letter followed by a "p" - Size/Length - single letter followed by an "n" So a function declaration might look like: static void process_bytes(uint8_t *zp, const uint8_t *xp, size_t xn); The above fun…

I don't understand why you chose to prefix your variables with x and y rather than something more descriptive. It seems like x and y are completely arbitrary, which is confusing.
Post reply on HN