Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial design to reduce metadata overhead #169

Merged
merged 7 commits into from
Jul 19, 2023
Merged

Conversation

dryajov
Copy link
Contributor

@dryajov dryajov commented Jul 5, 2023

This document proposes a change to reduce metadata overhead in manifest files as well as consolidating the slot blocks handling with the network block handling.

@benbierens
Copy link

I like this plan. I have read the doc briefly and I'll read it again some more shortly, but I have a question for you:
Is it required that Merkle trees are binary, aka max 2 elements per node?
I understand how the leaf index as binary gives you the path from root to leaf, and how the hashes along the way are useful for inclusion proofs. But I was thinking... what if we allow 4 elements per node? the leaf index as binary would still represent the path from root to leaf except in chunks of 2 bits instead of 1. The same holds true for 3 bits and 8 elements per node, etc. An approach like this might greatly reduce the number of levels to our trees for large datasets, and I don't see a downside to this. Your thoughts please! :D

@tbekas
Copy link

tbekas commented Jul 5, 2023

@benbierens I think that 2 elements per node is optimal when it comes to the size of the proofs. Think about the extreme case when you have N leaves and N elements per node. The size of the proof for each of the N leaves will be O(N).

@dryajov I like the Idea. I'm not convinced yet that we need to store the entire tree. I think we could (should) store only a merkle proof next to a block and that should suffice for all the use cases in my opinion.

It will take only 2 times more on the disk, but I think it would reduce the complexity of the flows and possibly increase the performance of disk operations (sequential reads only).

1. Once new peers have been discovered and connected, go to step 1.1.1
2. Once blocks are received from the remote nodes
1. The hashes are verified against the requested Merkle root and if they pass
1. The block is persisted to the network
Copy link

@tbekas tbekas Jul 5, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably you meant persisted to the repo/local store

Copy link
Member

@markspanbroek markspanbroek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like it! Makes a lot sense to use a merkle root instead of the block hashes in the manifest.


#### Announcing over the DHT

Also, datasets are now announced by their Merkle root instead of each individual block as was the case in the previous implementation. Announcing individual blocks is still supported, for example manifests are announced exactly the same as before, by their cid. Announcing individual blocks is also supported (but not required) and can be usefull in the case of bandwidth incentives.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would a Codex node that stores only the data for a single slot, still announce that data under the merkle root of the entire dataset?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question - yes, so far I don't see a better way of doing so. There isn't a good way of announcing block ranges over a DHT, but even in that case, blocks in slots aren't continuous. Definitely not ideal, and something to investigate further.

@dryajov
Copy link
Contributor Author

dryajov commented Jul 5, 2023

@benbierens I think that 2 elements per node is optimal when it comes to the size of the proofs. Think about the extreme case when you have N leaves and N elements per node. The size of the proof for each of the N leaves will be O(N).

This, the size of proofs increases with the arity of the tree.

@dryajov I like the Idea. I'm not convinced yet that we need to store the entire tree. I think we could (should) store only a merkle proof next to a block and that should suffice for all the use cases in my opinion.

It will take only 2 times more on the disk, but I think it would reduce the complexity of the flows and possibly increase the performance of disk operations (sequential reads only).

The problem with this approach is that, in the new flow, you only know the root of the tree and the index of the leaf, you don't know the actual leaf or block hash before hand, the merkle tree serves as a kind of an index, where you read the tree and fetch the leaf (block hash) and after you can read it from the repo.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants