Skip to content

Commit a1d9fc8

Browse files
committed
Initial draft of the Haskell SimulatorModel.md
1 parent 37f7c35 commit a1d9fc8

File tree

1 file changed

+223
-0
lines changed

1 file changed

+223
-0
lines changed

simulation/docs/SimulatorModel.md

Lines changed: 223 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,223 @@
1+
# Introduction
2+
3+
This document summarizes the structure and behaviors of the Haskell Leios simulator.
4+
The level of detail is between the code itself and the various work-in-progress Leios specifications.
5+
6+
The Leios node is modeled as a set of threads that maintain shared state via the [stm](https://hackage.haskell.org/package/stm) library, as with the existing `ouroboros-network` and `ouroboros-consensus` implementation libraries.
7+
This document will primarily describe those threads and the components of their shared state.
8+
9+
TODO also discuss the mini protocol multiplexing and TCP model
10+
11+
# Lifetime of an object
12+
13+
The objects within the simulator include Input Blocks (IBs), Endorser Blocks (EBs) (aka Endorsement Blocks, aka Endorse Blocks), Vote Bundles (VBs), and Ranking Blocks (RBs).
14+
Certificates are not explicit; for example, a certificate's computational cost is instead associated with the containing RB.
15+
16+
Within a single simulated node, the lifetime of every such object follows a common sequence.
17+
18+
- *Generate*, the duration when the node is generating an object.
19+
- *Receive*, the moment a node receives (the entirety of) an ojbect from a peer.
20+
(It is often useful to consider a node to have received an object when it finished generating that object.)
21+
- *Wait*, the duration when the node cannot yet validate an object (eg a known necessary input is missing).
22+
- *Validate*, the duration when when node is computing whether the object is valid.
23+
- *Diffuse*, the duration when the node is offering/sending the object to its peers.
24+
- *Adopt*, the moment the node updates it state in response to the successful validation.
25+
- *Forget*, the moment the node updates it state once the object is no longer necessary/relevant.
26+
27+
Only generation and validation consume modeled CPU, and nothing consumes any modeled RAM/disk capacity/bandwidth.
28+
29+
Modeled CPU consumption for a some object happens all-at-once and at most once.
30+
For example, the IBs transitively included by an RB does not affect the cost of adopting that RB.
31+
32+
# Threads
33+
34+
The `LeiosProtocol.Short.Node.leiosNode` function constructs the node's set of threads.
35+
36+
## Generate threads
37+
38+
At the onset of each slot, the node generates whichever IBs, EBs, VBs, and RBs are required by the mocked Praos and Leios election lotteries.
39+
40+
### Mocked leader schedules
41+
42+
Different objects arise at different rates, but the simulator reuses some common infrastructure for them.
43+
In particular, for each slot, each node is given a random number between (ie `uniformR (0, 1 :: Double)` from the [random](https://hackage-content.haskell.org/package/random-1.3.1/docs/System-Random.html#v:uniformR) package (which is inclusive).
44+
For each object, that number will be mapped to a number of "wins", ie elections, via [Inverse transform sampling](https://en.wikipedia.org/wiki/Inverse_transform_sampling).
45+
46+
The probability distribution of wins is parameterized on the node's stake, which varies per node but not per slot, and on a corresponding protocol parameter, which varies per kind of object.
47+
48+
### Generating IBs
49+
50+
The IB election lottery allows for a node to generate multiple IBs in a slot.
51+
Each opportunity within a slot is called a "subslot", but the generated IB required by the subslots of some slot are all made (in subslot order) at the slot's onset.
52+
53+
The probability distribution of the node's IB elections in a slot is determined by the `inputBlockFrequencyPerSlot` parameter.
54+
55+
- If the rate is ≤1, then the distribution is `Bernoulli(stake*inputBlockFrequencyPerSlot)`.
56+
- If the rate is >1, then the distribution is `Poisson(stake*inputBlockFrequencyPerSlot)`.
57+
58+
Each IB (see `LeiosProtocol.Common.InputBlock`) consists of the following fields.
59+
60+
- A globally unique ID, which for convenience is the ID of the issuing node and an incrementing counter.
61+
- The slot and subslot of its (implicit) election proof.
62+
- The hash of an RB.
63+
- The byte size of the IB header.
64+
- The byte size of the IB body.
65+
66+
More details for some fields.
67+
68+
- The RB hash is the youngest RB on the node's selection for which the node has already computed the ledger state.
69+
- The header byte size is the constant `inputBlockHeader`.
70+
- The body byte size is the constant `inputBlockBodyAvgSize`.
71+
72+
Each generated IB begins diffusing immediately and is adopted immediately.
73+
If the node should validate its IB before diffusion and adoption, then that cost should be included in the generation cost.
74+
75+
### Generating EBs
76+
77+
The EB leader schedule allows for a node to generate at most one EB in a slot.
78+
79+
The probability distribution of the node's EB elections in a slot is determined by the `endorseBlockFrequencyPerStage` parameter.
80+
81+
- If the rate is ≤1, then the distribution is `Bernoulli(stake*inputBlockFrequencyPerSlot)`.
82+
- If the rate is >1, then the distribution is `Bernoulli(1 - PoissonPmf(0; stake*inputBlockFrequencyPerSlot))`.
83+
(Note the subtle `min 1 . f` in the definition of `endorseBlockRate`.)
84+
85+
*Remark*.
86+
Those probability distributions converge as `stake` approaches 0.
87+
88+
Each EB (see `LeiosProtocol.Common.EndorseBlock`) consists of the following fields.
89+
90+
- A globally unique ID, which for convenience is the ID of the issuing node and an incrementing counter.
91+
- The slot of its (implicit) election proof.
92+
- The list of IB IDs.
93+
- The list of EB IDs.
94+
- The byte size.
95+
96+
More details for some fields.
97+
98+
- An EB from iteration `i` includes the IDs of all IBs that were already adopted, are also from iteration `i`, and arrived before the end of `i`'s Deliver2 stage.
99+
- If the Leios variant is set to `short`, this EB includes no EB IDs.
100+
- If the Leios variant is set to `full`, an EB from iteration `i` includes the ID of the best eligible EB from each iteration with any eligible EBs.
101+
- An eligible EB has already been adopted, has already been certified, and is from an iteration in the closed interval `[i - min i (2 + pipelinesToReferenceFromEB), i-3]`.
102+
- The best eligible EB from the eligible EBs within a particular iteration has more IBs and on a tie arrived earlier.
103+
- The byte size is computed as `ebSizeBytesConstant + ebSizeBytesPerIb * (#IBs + #EBs)`.
104+
- (TODO The field with EB IDs is `endorseBlocksEarlierPipeline`, not `endorseBlocksEarlierStage`.
105+
The latter is a stub related to equivocation detection; it is always empty during the simulation.)
106+
107+
Each generated EB begins diffusing immediately and is adopted immediately.
108+
If the node should validate its EB before diffusion and adoption, then that cost should be included in the generation cost.
109+
110+
### Generating VBs
111+
112+
The VB election lottery schedules a node to generate a VB at the onset of exactly one slot within the first `activeVotingStageLength`-many slots of the voting stage of every iteration.
113+
The probability distribution of the number of votes in that VB is determined by the `votingFrequencyPerStage` parameter.
114+
The distribution is `Poisson(stake*votingFrequencyPerStage)`.
115+
116+
Each VB (see `LeiosProtocol.Common.VoteMsg`) consists of the following fields.
117+
118+
- A globally unique ID, which for convenience is the ID of the issuing node and an incrementing counter.
119+
- The slot of its (implicit) election proof.
120+
- The number of lottery wins in this slot.
121+
- The list of voted EB IDs.
122+
- The byte size.
123+
124+
More details for some fields.
125+
126+
- If all votes are considered to have the same weight, then a VB determines `#wins * #EBs`-many unweighted votes.
127+
Otherwise, a VB determines `#EBs`-many weighted votes.
128+
- A VB from iteration `i` includes the IDs of all EBs that satisfy the following.
129+
- The EB must have already been adopted.
130+
- The EB must also be from iteration `i`.
131+
- The EB must only include IBs that have already been adopted, are from iteration `i`, and arrived before the end of `i`'s Endorse stage.
132+
- The EB must include all IBs that have already been adopted, are from iteration `i`, and arrived before the end of `i`'s Deliver1 stage.
133+
- If the Leios variant is set to `full`, then let X be the EB's included EBs in iteration order; let Y be the EBs this node would have considered eligible if it were to retroactively create an EB for iteration `i` right now with the only extra restriction being ignore EBs that arrived within Δ_hdr of the end of iteration `i`; then `and (zipWith elem X Y)` must be `True`.
134+
(TODO the `zipWith` is suspicious; whether it would misbehave in various scenarios depends on many implementation details.)
135+
- The byte size is computed as `voteBundleSizeBytesConstant + voteBundleSizeBytesPerEb * #EBs` (which implies the weighted-vote perspective).
136+
137+
Each generated VB begins diffusing immediately and is adopted immediately.
138+
If the node should validate its VB before diffusion and adoption, then that cost should be included in the generation cost.
139+
140+
### Generating RBs
141+
142+
The RB leader schedule allows for a node to generate at most one RB in a slot.
143+
144+
The probability distribution of the node's RB elections in a slot is determined by the `blockFrequencyPerSlot` parameter.
145+
The distribution is `Bernoulli(stake*inputBlockFrequencyPerSlot)`.
146+
147+
*Remark*.
148+
That distributions converges to Praos's `Bernoulli(ϕ_stake(inputBlockFrequencyPerSlot))` as `stake` approaches 0.
149+
150+
Each RB (see `LeiosProtocol.Common.RankingBlock`) consists of the following fields.
151+
152+
- The byte size of the RB header.
153+
- The slot of its (implicit) election proof.
154+
- The hash of the header content.
155+
- The hash of the body content.
156+
- The block number.
157+
- The hash of its predecessor RB.
158+
- The byte size of the RB body.
159+
- A list (TODO which is always length 0 or 1) of EB IDs paired with the IDs and weights of a quorum of votes for that EB.
160+
- The size of the RB's (implicit) tx payload.
161+
- The ID of the issuing node.
162+
163+
More details for some fields.
164+
165+
- The RB extends the node's preferred chain.
166+
- The tx payload is the constant `rankingBlockLegacyPraosPayloadAvgSize`.
167+
- The EB is the best eligible EB, if any.
168+
- An eligible EB is certified, not from a pipeline with a certificate is on the extended chain, only references IBs are already adopted, and is not more than `maxEndorseBlockAgeSlots` slots older than the RB.
169+
- If the Leios variant is set to `short`, the best of the eligible EBs is oldest, on a tie has more IBs, and on a tie arrived earlier.
170+
- If the Leios variant is set to `full`, the best of the eligible EBs is youngest, on a tie has more IBs, and on a tie arrived earlier.
171+
172+
Each generated RB begins diffusing immediately and is adopted immediately.
173+
If the node should validate its VB before diffusion and adoption, then that cost should be included in the generation cost.
174+
175+
## Leios diffusion threads
176+
177+
TODO
178+
179+
## Waiting&Validation threads
180+
181+
TODO
182+
183+
## Pruning threads
184+
185+
TODO
186+
187+
## Praos diffusion threads
188+
189+
TODO
190+
191+
# State
192+
193+
The `LeiosProtocol.Short.Node.LeiosNodeState` record type declares the state shared by the threads.
194+
195+
## Leios Diffusion state
196+
197+
TODO
198+
199+
## Waiting&Validation state
200+
201+
TODO
202+
203+
TODO include `taskQueue`
204+
205+
## Adopted IBs state
206+
207+
TODO
208+
209+
## Adopted EBs state
210+
211+
TODO
212+
213+
## Adopted VBs state
214+
215+
TODO
216+
217+
## Adopted RBs state
218+
219+
TODO
220+
221+
## Praos Diffusion state
222+
223+
TODO

0 commit comments

Comments
 (0)