Skip to content

Conversation

@ahtotruu
Copy link
Contributor

An SMT can now be created in child, parent or normal mode.

Normal mode is for use in a monolithic (non-sharded) aggregator and behaves as before.

Child mode is for use in a child aggregator in sharded setup. Difference from normal mode:

  • takes shard ID as a parameter and uses its most significant bit as the "path" for the root node to get the correct hash value for the corresponding leaf node of the parent aggregator's SMT.

Parent mode is for use in parent aggregator in sharded setup. Differences from normal mode:

  • allows values in leaves to be updated;
  • leaves are not hashed (instead they contain hash values computed by and received from child aggregators);
  • to maintain fixed structure, the tree is fully populated (not sparse at all, contrary to the name).

Child mode (for child aggregator in sharded setup) differs
from normal mode (for monolithic aggregator) by taking a
shard ID and using its most significant bit as the "path"
for the root node to get the corrrect hash value for the
corresponding node of the parent aggregator's SMT.
Parent mode (for parent aggregator in sharded setup) differs
from normal mode (for monolithic aggregator) in three ways:
- is allows values in leaves to be updated;
- the leaves are not hashed (instead they contain hash values
  computed by and received from child aggregators);
- to maintain fixed structure, the tree is really not sparse
  at all.
@ahtotruu
Copy link
Contributor Author

Note that this change breaks compatibility for client-side SDKs and probably should not be merged until the SDKs also have updates ready.

@ahtotruu ahtotruu requested review from jait91 and lploom October 16, 2025 21:54
@ahtotruu ahtotruu changed the base branch from main to cbor-hashing October 17, 2025 09:33
Copy link
Contributor

@lploom lploom left a comment

Choose a reason for hiding this comment

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

LGTM!

Comment on lines +676 to +684
// JoinPaths joins the hash proofs from a child and parent in sharded setting
func JoinPaths(child, parent *api.MerkleTreePath) (*api.MerkleTreePath, error) {
if len(child.Root) < 4 {
return nil, fmt.Errorf("invalid child root hash format")
}
if len(parent.Steps) == 0 {
return nil, fmt.Errorf("empty parent hash steps")
}
if parent.Steps[0].Data == nil || *parent.Steps[0].Data != child.Root[4:] {
Copy link
Contributor

Choose a reason for hiding this comment

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

maybe create a constant or add a comment what this 4 means

Copy link
Contributor Author

@ahtotruu ahtotruu Oct 22, 2025

Choose a reason for hiding this comment

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

Since we now use one hash function identifier for the whole inclusion proof, perhaps in fact better to extract it into a separate field and change the root hash into a plain hash value instead of keeping them merged into an imprint?

Base automatically changed from cbor-hashing to main October 22, 2025 08:01
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.

3 participants