Add getCutoffs helper (buggy)

This commit is contained in:
mratsim 2018-07-23 16:22:37 +02:00
parent 4c6665832b
commit 585072ae15
2 changed files with 56 additions and 10 deletions

View File

@ -85,4 +85,4 @@ const
EpochLength* = 64 # blocks
SlotDuration* = 8 # seconds
MinCommitteeSize* = 128 # (rationale: see recommended minimum 111 here https://vitalik.ca/files/Ithaca201807_Sharding.pdf)
EndEpochGracePeriod = 8 # blocks
EndEpochGracePeriod* = 8 # blocks

View File

@ -8,8 +8,8 @@
# Helper functions
import ../datatypes, sequtils, nimcrypto
func getShuffling(seed: Blake2_256_Digest, validatorCount: int): seq[int] {.noInit.}=
# Pseudorandomly shuffles the validator set based on some seed
func getShuffling*(seed: Blake2_256_Digest, validatorCount: int): seq[int] {.noInit.}=
## Pseudorandomly shuffles the validator set based on some seed
assert validatorCount <= MaxValidatorCount
@ -31,3 +31,49 @@ func getShuffling(seed: Blake2_256_Digest, validatorCount: int): seq[int] {.noIn
let replacementPos = m mod remaining + i
swap result[i], result[replacementPos]
inc i
func getCutoffs*(validatorCount: int): tuple[height, shard: seq[int]] {.noInit.} =
## Split up validators into groups at the start of every epoch,
## determining at what height they can make attestations and what shard they are making crosslinks for
## Implementation should do the following: http://vitalik.ca/files/ShuffleAndAssign.png
## TODO: It doens't work.
result.height = @[0]
let cofactor = 39 # EpochLength / phi
const StandardCommitteeSize = MaxValidatorCount div ShardCount
var heightCount: int
var heights: seq[int]
if validatorCount < EpochLength * MinCommitteeSize:
# If there are not enough validators to fill a minimally
# sized committee at every height, skip some heights
heightCount = validatorCount div MinCommitteeSize or 1 # TODO div/or precedence ?
for i in 0 ..< heightCount:
heights.add (i * cofactor) mod EpochLength
else:
# If there are enough validators, fill all the heights
heightCount = EpochLength
heights = toSeq(0 ..< EpochLength)
var filled = 0
for i in 0 ..< EpochLength - 1:
if i notin heights: # TODO, this will be slow for seq, use intsets instead?
result.height.add result.height[^1]
else:
inc filled
result.height.add filled * validatorCount div heightCount
result.height.add validatorCount
# For the validators assigned to each height, split them up
# into committees for different shards. Do not assign the
# last END_EPOCH_GRACE_PERIOD heights in an epoch to any shards.
result.shard = @[0]
for i in 0 ..< EpochLength - EndEpochGracePeriod:
let
size = result.height[i+1] - result.height[i]
shards = (size + StandardCommitteeSize - 1) div StandardCommitteeSize
pre = result.shard[^1]
for j in 1 .. shards:
result.shard.add pre + size * j div shards