Skip to content

shredder introduce shred builder / new api#8048

Closed
puhtaytow wants to merge 1 commit intoanza-xyz:masterfrom
puhtaytow:shredder-new-api-0
Closed

shredder introduce shred builder / new api#8048
puhtaytow wants to merge 1 commit intoanza-xyz:masterfrom
puhtaytow:shredder-new-api-0

Conversation

@puhtaytow
Copy link
Copy Markdown

@puhtaytow puhtaytow commented Sep 14, 2025

Problem

Current Shredder API forces tests to pass all parameters explicitly, even when these are irrelevant. This makes unit tests unnecessairly verbose and harder to read/ work with.

  • High boilerplate for simple tests
  • Repeated setup of ReedSolomonCache and ProcessShredsStats, Keypair, and Entry data
  • Manual handling of next_shred_index/next_code_index, even if not needed
  • Tests must provide version, reference_tick, parent_slot in scenario where defaults would suffice

Summary of Changes

Introduce ShredBuilder, a type-state builder with fluent api to construct shreds for tests in ergonomic and flexible way:

  • Data sources: random bytes, provided bytes and transactions
  • Provides defaults: parent_slot = slot - 1, version = 0, reference_tick = 0, start_index = 0
  • Optional overrides: with_parent_slot, with_version, with_reference_tick, with_start_index, with_invalid_index (specific failure tests)
  • Internalizes Keypair, ReedSolomonCache and ProcessShredsStats out of box
  • Returns an iterator of shreds for convinience
  • Backward compatible in case of extending the fluent api with new setters

No changes to production shredding logic.

@puhtaytow puhtaytow marked this pull request as draft September 14, 2025 06:44
@mergify mergify Bot requested a review from a team September 14, 2025 06:45
@puhtaytow
Copy link
Copy Markdown
Author

@alexpyattaev if you could look when you have a minute and leave early comments 🙏

Comment thread ledger/src/shredder.rs Outdated
Comment thread ledger/src/shredder.rs Outdated
where
S: ShredBuilderDataFiller,
{
pub fn with_parent_slot(&mut self, parent_slot: Slot) -> &mut Self {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

can we add tests for these as well and/or blend them into existing tests?

Comment thread ledger/src/shredder.rs Outdated
self
}

pub fn with_invalid_index(&mut self, index: u32) -> &mut Self {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

especially need test for this one, as well as doc-comments explaining each

@alexpyattaev
Copy link
Copy Markdown

Overall looking really nice, thank you!

@puhtaytow puhtaytow force-pushed the shredder-new-api-0 branch 18 times, most recently from a5ea76f to 3bc8c7c Compare September 15, 2025 14:42
Copy link
Copy Markdown

@steviez steviez left a comment

Choose a reason for hiding this comment

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

Can you please update the PR description with the motivation for this PR. Namely, what is the problem with the current code and how does this PR address that problem / make things better

@puhtaytow puhtaytow force-pushed the shredder-new-api-0 branch 4 times, most recently from 0cca75c to 6e84663 Compare September 15, 2025 15:32
@puhtaytow
Copy link
Copy Markdown
Author

puhtaytow commented Sep 15, 2025

Can you please update the PR description with the motivation for this PR. Namely, what is the problem with the current code and how does this PR address that problem / make things better

Sure, it wasn't there at the first point as i made the draft just so Alex could put early comments.
It is updated now, if you could read and tell me if something doesn't make sense then please 🙏

--edit

Please keep in mind as its still WiP.

@steviez
Copy link
Copy Markdown

steviez commented Sep 15, 2025

Sure, it wasn't there at the first point as i made the draft just so Alex could put early comments

Ahh ok, I still got some notifications for it which is why I commented

It is updated now, if you could read and tell me if something doesn't make sense then please

Thank you !

Please keep in mind as its still WiP.

🫡

Comment thread ledger/src/shredder.rs Outdated
};

/// Helper to construct [`ShredBuilder`] with different options
fn shred_builder_options_setter(
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Why do we need this? Seems like the exact pattern we wanted to avoid no?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

It seemed for a moment like good way, but its clearly not. I'm workin on it 🙏

Copy link
Copy Markdown

@steviez steviez left a comment

Choose a reason for hiding this comment

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

Current Shredder API forces tests to pass all parameters explicitly, even when these are irrelevant. This makes unit tests unnecessairly verbose and harder to read/ work with.

I agree with the sentiment that having to specify all the arguments in test code where we often use defaults is annoying.

That being said, I also typically try to avoid modifying "production" code for the sake of supporting "test" code. For example,

Provides defaults: parent_slot = slot - 1, version = 0, reference_tick = 0, start_index = 0

This changes makes test more manageable at the cost of making it easier to screw up production code. As is, the verbose code requires the caller to pass those parameters which requires them to think about it. This is good for the production code

As an alternative, what if we introduced a wrapper like TestShredder that held the "extra" state and a production Shredder internally.

Semi-related - I think it probably makes sense to sense to finish other cleanup (like making merkle_root a Hash instead of Option<Hash>) first

@puhtaytow
Copy link
Copy Markdown
Author

what if we introduced a wrapper like TestShredder that held the "extra" state and a production Shredder internally.

I think it probably makes sense to sense to finish other cleanup (like making merkle_root a Hash instead of Option) first

Sure, ill switch to the cleanup and lets see what Alex think about the suggested alternative. From my perspective, any good solution is good :)

Obviously thank you for the input as always 🙏

@steviez
Copy link
Copy Markdown

steviez commented Sep 17, 2025

Sure, ill switch to the cleanup and lets see what Alex think about the suggested alternative

Cool, I imagine the cleanup should be pretty straight forward and less stuff to possibly support with whatever we land on here

Obviously thank you for the input as always 🙏

🤝

@alexpyattaev
Copy link
Copy Markdown

As for API design we can definitely have a function that requires all arguments to be provided for prod, and only use the builder in tests.

@puhtaytow
Copy link
Copy Markdown
Author

I'm also thinking if this new test api, could for example replace wrappers like this..

fn make_shreds_from_entries<R: Rng>(
rng: &mut R,
shredder: &Shredder,
keypair: &Keypair,
entries: &[Entry],
is_last_in_slot: bool,
chained_merkle_root: Option<Hash>,
reed_solomon_cache: &ReedSolomonCache,
stats: &mut ProcessShredsStats,
) -> (Vec<Shred>, Vec<Shred>) {
let (data, code) = shredder.entries_to_merkle_shreds_for_tests(
keypair,
entries,
is_last_in_slot,
chained_merkle_root,
rng.gen_range(0..2_000), // next_shred_index
rng.gen_range(0..2_000), // next_code_index
reed_solomon_cache,
stats,
);
(black_box(data), black_box(code))
}

We could add optional rng as param and allow this way randomly generated indexes for benches, and remove this helper.

Just an idea.

@puhtaytow puhtaytow closed this Feb 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants