Skip to content

Conversation

@akhi3030
Copy link

@akhi3030 akhi3030 commented Nov 18, 2025

Problem

We are in the process of introducing double merkle for alpenglow. In particular, we will be supporting chain and double merkle tree.

Summary of Changes

Introducing a new type to represent the root hash will help in improving the readability of the code and make it easier to understand.

Note to reviewers

I am not happy with how many new crates depend upon votor-messages in this PR. Happy to receive feedback on alternative locations to define SliceRoot.

@akhi3030 akhi3030 force-pushed the introduce-slice-root branch 2 times, most recently from 0421c44 to 7ffe975 Compare November 18, 2025 18:45
@akhi3030 akhi3030 force-pushed the introduce-slice-root branch from 7ffe975 to 28d4e7b Compare November 18, 2025 19:16
@akhi3030 akhi3030 force-pushed the introduce-slice-root branch 2 times, most recently from 9823850 to 030c2b6 Compare November 19, 2025 15:04
@akhi3030 akhi3030 force-pushed the introduce-slice-root branch from 030c2b6 to a35ce2f Compare November 19, 2025 15:16
@codecov-commenter
Copy link

codecov-commenter commented Nov 19, 2025

Codecov Report

❌ Patch coverage is 97.86477% with 6 lines in your changes missing coverage. Please review.
✅ Project coverage is 82.6%. Comparing base (b23518a) to head (51370f5).
⚠️ Report is 35 commits behind head on master.

Additional details and impacted files
@@           Coverage Diff           @@
##           master    #9130   +/-   ##
=======================================
  Coverage    82.6%    82.6%           
=======================================
  Files         890      891    +1     
  Lines      320729   320758   +29     
=======================================
+ Hits       265011   265062   +51     
+ Misses      55718    55696   -22     
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@@ -0,0 +1,33 @@
//! Module to define [`SliceRoot`].

Choose a reason for hiding this comment

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

AlpenglowBlockId will also go in here so maybe name this differently or just put them in consensus_message.rs IDK

Copy link
Author

Choose a reason for hiding this comment

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

Even though I ended up not making the fields of Sliceroot private, in general, when introducing new types, it is a good idea to try to make them private. In which case, it also helps if the types are in their own module otherwise other code can access the internal fields. So I think I would prefer to introduce AlpenglowBlockId in yet another module.

@akhi3030 akhi3030 changed the title wip: intro SliceRoot Introduces SliceRoot Nov 25, 2025
@akhi3030 akhi3030 marked this pull request as ready for review November 25, 2025 06:46
@akhi3030 akhi3030 requested a review from a team as a code owner November 25, 2025 06:46
@alexpyattaev
Copy link

Can you link a design doc to the PR so we keep a better record of why this is happening?

@akhi3030
Copy link
Author

Can you link a design doc to the PR so we keep a better record of why this is happening?

@kobi-lizard: have you written something down somewhere? The only "design" that I am aware of is anza-xyz/alpenglow#518.

Copy, Clone, Default, Debug, Hash, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize,
)]
#[repr(transparent)]
pub struct SliceRoot(pub Hash);

Choose a reason for hiding this comment

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

Why are we placing it in Votor if this deals with shreds? Maybe time for rotor crate?

Also not sure why do we need a wrapper around Hash at all. Could we define an alias instead?

Copy link
Author

Choose a reason for hiding this comment

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

Why are we placing it in Votor if this deals with shreds? Maybe time for rotor crate?

I am definitely not happy with the current placement. I like the idea of introducing a rotor crate.

Also not sure why do we need a wrapper around Hash at all. Could we define an alias instead?

With type aliases, the compiler will not hold my hand to ensure that I am using the right type. I can use any old Hash. Using a wrapper struct helps in providing documentation and the additional feedback at the call sites to help the developer check that they are using the right type and not just some random Hash.

Choose a reason for hiding this comment

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

I see. Ether way, making turbine depend on Votor feels wrong :)

Copy link

Choose a reason for hiding this comment

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

Agreed with Alex (and Ashwin from https://github.com/anza-xyz/agave/pull/9130/files#r2560958890) - I don't think votor is the right place for this. Rather, I agree with Ashwin's comment from linked comment:

Then the hash relevant to shreds could be named -> FecSetRoot and could live in ledger or turbine crates.

Since the erasure coding and FEC sets are created in solana-ledger, my vote would be solana-ledger

@kobi-lizard
Copy link

Why this is happening and why alias is wrong:
Right now Hash is used to mean many things. You can see in this PR sometimes we put comments next to Hash "this is the Merkle root" or such. Right now if an argument/variable has a variation of "block_id" in the name the chained Merkle root is used. Some of these need to change to double Merkle, some of it needs to stay for the time being. When I started drafting the Double Merkle stuff I was overwhelmed with keeping track of which Hash is what: chained Merkle root, double Merkle root, different Hash? You could swap one for the other and Rust wouldn't tell you what's wrong. With alias it's the same.
Point is, types are for slow people like me so that Rust tells them "change this thing here" and I don't have to have the meaning of different Hashes in 100 places uploaded to my brain.

Copy, Clone, Default, Debug, Hash, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize,
)]
#[repr(transparent)]
pub struct SliceRoot(pub Hash);

Choose a reason for hiding this comment

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

I find this name pretty confusing as slice is already pretty overloaded, could we rename this to FECSetRoot or SetRoot?

Copy link

Choose a reason for hiding this comment

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

Agreed with Ashwin, I'm not a fan of SliceRoot. We already have terminology to refer to this concept (FEC Set) so I see no need to introduce more terminology especially when slice is already a Rust keyword.

I think something like FecSetRoot or FecSetMerkleRoot makes sense; given that elements of a merkle tree are hashes, we probably don't need to include Hash in the name but I'd probably be fine with it too

}

pub fn parent_block_id(&self) -> Option<Hash> {
pub fn parent_block_id(&self) -> Option<SliceRoot> {
Copy link

@AshwinSekar AshwinSekar Nov 25, 2025

Choose a reason for hiding this comment

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

I think if we're going to rename the types we could do something like:
Block id hash -> ChainedMerkleBlockId
new block id hash -> DoubleMerkleBlockId

Both of these can live in votor-messages since they are primarily used for consensus and then we can remove the runtime dependency

Then the hash relevant to shreds could be named -> FecSetRoot and could live in ledger or turbine crates.

I haven't walked all the dependencies to see if this is feasible but if we split into a higher level of granularity then we might be able to avoid setting up a new crate or having everything depend on votor-messages

Copy link
Author

Choose a reason for hiding this comment

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

@AshwinSekar: not sure I completely understand the proposal.

When we do introduce double merkle, won't we need to update the ledger and turnbine crates accordingly?

@AshwinSekar AshwinSekar requested a review from steviez November 25, 2025 18:10
@akhi3030 akhi3030 force-pushed the introduce-slice-root branch from 9ff23f9 to 266510c Compare November 28, 2025 16:52
@alexpyattaev
Copy link

A conceptual question: why are we renaming FEC sets into slices in this PR?

@akhi3030 akhi3030 force-pushed the introduce-slice-root branch from 266510c to 0545153 Compare November 29, 2025 18:57
@akhi3030
Copy link
Author

A conceptual question: why are we renaming FEC sets into slices in this PR?

I am sure Quentin (who somehow I cannot tag here) and @kobi-lizard can explain this better. The general idea is that FEC set refers to the specific technology being used instead of what the actual data structure is. The idea is that a block is made up of some data structure that can be called Slices and not the specific technology that we happen to be using to implement them.

I agree with you though that sneaking in new terminology like this is probably not a good idea and we should get wider buy-in before we do that. I plan on renaming the structs based on #9130 (comment).

@alexpyattaev
Copy link

I agree with you though that sneaking in new terminology like this is probably not a good idea and we should get wider buy-in before we do that. I plan on renaming the structs based on #9130 (comment).

What benefit does renaming bring? I can see a bunch of problems it creates (code churn, mess in discussions etc), which problems does it solve? Once there is a meaningful change in the logic of the protocol we should consider name changes.

@akhi3030
Copy link
Author

akhi3030 commented Dec 1, 2025

I agree with you though that sneaking in new terminology like this is probably not a good idea and we should get wider buy-in before we do that. I plan on renaming the structs based on #9130 (comment).

What benefit does renaming bring? I can see a bunch of problems it creates (code churn, mess in discussions etc), which problems does it solve? Once there is a meaningful change in the logic of the protocol we should consider name changes.

Indeed... these are precisely the reasons to not shoehorn in a renaming and get general consensus before attempting it.

@akhi3030
Copy link
Author

Ended up creating #9504 instead of modifying this one as updating this seemed to be more work. Closing this.

@akhi3030 akhi3030 closed this Dec 11, 2025
@akhi3030 akhi3030 deleted the introduce-slice-root branch December 11, 2025 13:24
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.

6 participants