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

Haskell tends to include IBs in more EBs than does Rust #248

Open
bwbush opened this issue Mar 12, 2025 · 7 comments
Open

Haskell tends to include IBs in more EBs than does Rust #248

bwbush opened this issue Mar 12, 2025 · 7 comments
Assignees
Labels
question Further information is requested

Comments

@bwbush
Copy link
Collaborator

bwbush commented Mar 12, 2025

Observation

  • The Haskell simulation typically references each IB in zero or three EBs.
  • The Rust simulation typically references each IB in fewer than three EBs.
  • Is the cause of this different worth tracking down?

Evidence

Image

Image

Context

@bwbush bwbush added the question Further information is requested label Mar 12, 2025
@Saizan
Copy link
Contributor

Saizan commented Mar 13, 2025

My guess would be that each generated EB references most IBs, so the difference is probably about minor differences in the implementation of sortition.

@bwbush would it be easy to show data about number of generated EBs per pipeline?

@bwbush
Copy link
Collaborator Author

bwbush commented Mar 13, 2025

would it be easy to show data about number of generated EBs per pipeline?

Yes, and I was planning to do checks today that EBs only reference IBs from their own pipeline.

@SupernaviX
Copy link
Contributor

For each node, the rust simulation runs a VRF lottery by

  • sampling a random number in 0..total_stake
  • checking if the random number is less than stake * success_rate

The default config has an EB generation rate of 1.5, so rust is running this lottery once with a success rate of 1.0 and once with a success rate of 0.5. If either run wins, the node generates a single EB.

@Saizan
Copy link
Contributor

Saizan commented Mar 14, 2025

We try to match voter_check in crypto-benchmarks.rs more directly, precomputing the thresholds for the different number of "wins" given a double sampled between 0 and 1.

For EBs then we additionally cap them to max 1 per node.

@bwbush
Copy link
Collaborator Author

bwbush commented Mar 19, 2025

Here are the results at tag leios-2025w12, which subjectively seem in closer agreement, but still have deviations.

Image

@bwbush bwbush assigned bwbush and unassigned bwbush Mar 19, 2025
@Saizan
Copy link
Contributor

Saizan commented Mar 26, 2025

Any IBs not endorsed appear to be from pipelines without an EB. So that part seems to work as expected.

According to the sortition spec, if we weren't forcing at most 1 EB per node, we should expect the number of EBs to be Poisson distributed with \lambda equal to eb-generation-probability. For 1.5 we would have the following PMF
Image
What we are actually doing each pipeline is to take the sum of 100 samples of a poisson distribution with \lambda 1.5e-2, but each sample capped at 1. Anyhow, within 150 slots we are doing this only about 5 times, so things seem quite within variance.
(Note that the distribution of IBs in EBs is not quite the same: it's skewed by variance in IB generation and by the pipelines that have gone through Propose stage but not yet Endorse, inflating the count for 0 EBs above 1 EBs).

Finally it can look suspicious that all the runs have the same gap. However, because they all have the same stage length and rb-generation-probability, we are actually doing the same number of PRNG samplings and in the same order, so consistency is expected (what changes is only how many IBs you are granted for the same sampled value). One would really need to do runs with different seeds to see more variation.

Rather than more runs we can directly do the sampling described above. Doing 10000 iterations gives this distribution, which should be what we expect to see in the long run with eb-gen-probability=1.5

Image

@Saizan
Copy link
Contributor

Saizan commented Mar 26, 2025

For each node, the rust simulation runs a VRF lottery by

* sampling a random number in `0..total_stake`

* checking if the random number is less than `stake * success_rate`

The default config has an EB generation rate of 1.5, so rust is running this lottery once with a success rate of 1.0 and once with a success rate of 0.5. If either run wins, the node generates a single EB.

The distribution for the above looks pretty close to Haskell's

Image

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

No branches or pull requests

4 participants