Binary trie format

@AlexeyAkhunov originally pushes for M4 (see above) – I suspect that M4 simplifies many things, at the cost of hashing overhead. But we found that hashing overhead may not be as bad as we thought. @gballet 's chart above uses BLAKE2b, so we will get another 2x speedup if we use BLAKE3 (i.e. BLAKE2s with 7 rounds). If this is still too slow, there is a further 4x speedup with simd to do 4 hashes simultaneously, not to speak of multi-threading or GPU if we need more speed.

This would be a naive implementation. I suspect that Geth can keep their machinery, but sometimes do many hashes instead of one hash.

I think that M4 deserves a fair chance. Since it seems that M4 solves many problems for statelessness/regenesis.

I beg to differ, those charts show there is a 40x slowdown compared to M5 - and that’s just for the merkelization. And it’s already including some of the SIMD speedups.

GPUs and multithreading greatly increase the client’s code complexity, and the assumption shouldn’t be made that they will be available in all clients. M5 can also benefit from all these improvements… and yet, it doesn’t need to.

Currently, there isn’t any BLAKE3 implementation for golang, it makes adding this feature a dependency of a library that will be released at some unknown point in the future. Why delay when there is a workable, practical solution?

I am aware that it could make witnesses a few percent bigger, in some cases. IMO it’s not a good enough reason to slow down mainnet more than it already will, as a result of using binary.

What are the problems that M4 solves for statelessness/regenesis, that M5 doesn’t also solve at an acceptable level?

M5 doesn’t solve anything today. M5 seems to create problems for statelessness/regenesis.

Agreed. M4 doesn’t need them either – a M4 block witness merkleizes in ~25ms, which is fast enough.

M4 solves witness canonicalness, satisfies the access list-witness property (i.e. “cleanness”), and has no witness bloat. M5 fails all of these. These are relevant to things like witness gas accounting, state networks, and the witness specification.

I think that we should focus on specifying statelessness/regenesis. Then we can see how M5 interacts with statelessness/regenesis.

None of these properties have practical value at this time. If they did, we would have seen a clear explanation of why they are useful, which never came - not for lack of asking.

They never came, because as you correctly point out, neither regenesis nor eth1x stateless are very well specified. These are complex endeavor, and it’s understandable.

Meanwhile, M5 is here and ticks all the boxes when it comes to performance, client storage size, and conversion time. It enables other efforts such as code merkelization and other stateless clients.

I suggest that we stop this particular conversation here. I will focus on M5, and once stateless/regenesis is properly defined, switching from M5 to M4 (whatever it will look like) isn’t going to be complicated.