-
Notifications
You must be signed in to change notification settings - Fork 53
[Exploration] Using Celestia's SMT for Pocket Network V1? #74
base: master
Are you sure you want to change the base?
Conversation
…dateWithSideNodes
Yes.
Yes and no. No: if the canonical commitment involves hashing >2 children at once, then proofs will be larger. The optimal proof sizes are with exactly 2 leaves. Yes: you can implement larger number of children for hypothetically better performance (this really needs to be tested empirically instead of being believed blindly) at the implementation level. That's an optimization that we want to make, modulo manpower and time.
Yes, it's used by Trustix for example: nix-community/trustix@da5ca07 (tweet). You can see dependents here and here.
I'm honestly not aware of any other compact SMT library in Go. If you want a Rust implementation of the same specification, see https://github.com/FuelLabs/fuel-merkle. |
Side nodes mean the neighboring nodes for a proof. Your text output is correct: you can see the neighboring nodes as you go up are indeed |
I think this is not true. To my knowledge, JMT implements a 16-ary tree only for physical storage, but the underlying logical tree is still 2-ary, so proofs are still the same as a normal SMT. In theory, a similar optimization should be possible for this library.
There is a pending PR to this library (#73) that makes the performance much better by @roysc, which further changes should probably be re-based on. By the way, we're not using this library anymore internally at Celestia, because replacing IAVL in the Cosmos store is not trivial. However, there's nothing wrong with using this library independently for other use cases, and if you want to help maintain and improve it, be our guest. |
|
||
A Go library that implements a Sparse Merkle tree for a key-value map. The tree implements the same optimisations specified in the [Libra whitepaper][libra whitepaper], to reduce the number of hash operations required per tree operation to O(k) where k is the number of non-empty elements in the tree. | ||
A Go library that implements a Sparse Merkle Tree for a key-value map. The tree implements the same optimisations specified in the [Jellyfish Merkle Tree whitepaper][jmt whitepaper] originally designed for the [Libra blockchain][libra whitepaper]. It reduces the number of hash operations required per tree operation to `O(k)` where `k` is the number of non-empty elements in the tree. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This library is not based on JMT, just an optimized SMT. The JMT was introduced after the original Libra whitepaper, which is basically an optimized SMT but with further optimizations on the storage layer (storing it as a 16-ary tree, etc), which we don't make here yet. The original Libra whitepaper mentioned an optimized SMT, but did not introduce the JMT (with extra storage optimizations).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Appreciate the responses everyone!
Got it. At the very least I'll update the visualization scripts after the rebase since I think it's valuable. I'm more concerned about being the sole user/maintainer of the library long-term so as to benefit and contribute to security & performance optimizations others are making as well. Do you have a rec as to whether we should focus on celestiaorg/iavl or this library?
Understood and makes sense.
We're building in Go, so it'd be nice to have everything be native (if possible). When the time comes, if it's necessary, we might build a wrapper similar to what harmony did with their VRF bounty (https://gitcoin.co/issue/25313). Premature optimization for the time being though.
Got it. It's basically the "classic" merkle branches we need for the proof.
Will update so it's easier to visualize the ZEROs and fix the big.
Though the number 16 was "arbitrarily" (probably some benchmarking) to account for the tradeoff of read & write volume for RocksDB compaction, the following diagram from the OG paper seems to imply it is non-binary at a logic level as well:
That's great. Will def rebase on top of that once it's in! |
I wouldn't necessarily recommend iavl as a standalone state tree for use cases outside of the Cosmos SDK, the codebase is quite messy, and I believe the Cosmos SDK team wants to refactor or rewrite it. The main reason we're using it is for compatibility with the Cosmos SDK. Since we're not currently using this SMT library though, Celestia Labs isn't actively adding new features etc, but we're happy to merge PRs / accept outside contributions, especially if people want to help maintain it. |
Makes sense 👌 We'd be really interested in helping maintain and contribute to it as it seems to fit our use case. In terms of next steps, I'll take a look at #73 and rebase this on top of it once it's merged in. |
@musalbas This PR isn't ready for review (yet) but I was hoping to use it as a starting point for a conversation.
After reading through cosmos/cosmos-sdk#7100 as well as many of the downstream threads, it seems that using a variation of Libra's JMT is a good alternative to IAVL. I summarized a few of it's highlights here.
We're hoping to use a go native implementation and I very much want to avoid building out own from scratch. I came by this library and would prefer to help build on top of it together. It's easy to use, but I'm still trying to make my way through the code and understand the inner workings.
Specifically, my main questions at the moment are:
The JMT paper describes a general purpose Addressable Radix Merkle Tree with a variable r, but it seems this library only support binary trees.
1.1. Is that correct?
1.2 Is there a plan to extend it?
Is this library being used anywhere?
2.1. I'm primarily asking to in relation to it's performance and security "in the wild".
2.2. Would you recommend an alternative library given that it's been a couple of years?
I personally found it hard to understand what "side nodes" and "path nodes" represent, so I tried to build a little visualizer. After running
go test -v ./... -run TestVisualizationHelper
, I created the output below, but also used a small python notebook to visualize the tree as well.3.1 The textual output says that the side nodes of
C
areSIDE NODES: [ D, J, A, ZERO, ZERO, NODE, NODE ]
, but the tree visualization shows it at a lower height. I believe there's simply a gap in my understanding here so the main question I have is what "side nodes" are really meant to represent?Happy to jump on a call if you think it'll be more productive than a text back & forth!