|
| 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