Simulation 2.0 ============== Goal: Continue the simulation until failure. We should be able to tap in at various points to obtain results. Flush stats to file every sometime. Rules ----- 1. start at the age 4 (5 is adult) 2. age -> u64 instead of u8 3. section size capped at 60 (if more - then alert) 4. until you can split away from null prefix, every Live will bump the age of everyone in the section by 1. So at any point after inducting a new node you should have exactly 1 node (the new one) with the age of 4, rest should be all above this age. Once you have enough (at-least G+(G-Q), 11 if G==8) nodes starting with 0 and age > 4 and enough nodes starting with 1 and age > 4 the section will split into 0 and 1 prefix. One of these should have exactly 1 infant of age 4 (this is the node that would have caused the split) while the other half should have 0 infants at this point (this is not a rule, just something that would follow naturally). 5. after startup (which means you are at a prefix != null): every Live of non-infant (will happen via incoming relocation, let's say this live is Live(X)): repeat the following N times: hash last Live (would be the above Live(X) if it was an elder or an adult, else take the last Live of an existing elder in the chain) in the chain -> check relocation, if someone is to be relocated then relocate to the above hash break, otherwise continue N - configurable number (try 5, 50, ...) 6. split condition: both sections must have 8 elders and 3 adults post split 8. make group size configurable (default: 8), quorum: simple majority 9. trigger for aging: see point 5 10. make number of iterations configurable 11. on every iteration, for every section: toss a coin, on head: add new node then drop one, tails: the other way around: **Add node**: generate a random name that matches the prefix of the section, then try to add it to the section (section might reject it if it already has one infant). **Drop node**: sort the nodes of the section by age (youngest first), then generate random `bool` with probability `1:2^age`. If true, drop the node and stop. Otherwise continue to the next node. 12. All above are triggers for relocation unless it is an infant getting added or removed. To get the nodes to relocate take the latest `Live` block in the chain, hash it and apply the formula: `h % 2^age == 0` (where `h` is the hash of the latest `Live` block) to every node going from the oldest to the youngest. If `true`, relocate that node, otherwise take the hash of the hash and start again from the oldest node. Continue this process `N` times, where `N` is configurable number (experiment to find ideal value). If `N` attempts are exhausted and no matching node is found, then no one is relocated. 13. **NEVER** relocate someone if we are doing more harm than good. E.g. if relocation (which would result in a Dead in the chain or in adultsandinfants-container, but that being transient it will actually end up removing the corresponding Live and forget the node (PublicId) altogether) results in having us come down to a size wherein merge becomes necessary, then don't relocate. 14. Merge criteria - when you lose enough nodes such that the section has G-1 elders and no adults. 15. **NEVER** remove > (G-Q) nodes at a time from a section.