2018-12-21 22:37:46 +00:00
|
|
|
import
|
|
|
|
cligen,
|
|
|
|
json, strformat,
|
2018-12-27 23:40:22 +00:00
|
|
|
options, sequtils, random,
|
|
|
|
milagro_crypto,
|
2018-12-21 22:37:46 +00:00
|
|
|
../tests/[testutil],
|
|
|
|
../beacon_chain/spec/[beaconstate, crypto, datatypes, digest, helpers],
|
2018-12-28 16:51:40 +00:00
|
|
|
../beacon_chain/[extras, ssz, state_transition, fork_choice]
|
2018-12-21 22:37:46 +00:00
|
|
|
|
|
|
|
proc `%`(v: uint64): JsonNode = newJInt(v.BiggestInt)
|
|
|
|
proc `%`(v: Eth2Digest): JsonNode = newJString($v)
|
2018-12-27 23:40:22 +00:00
|
|
|
proc `%`(v: ValidatorSig|ValidatorPubKey): JsonNode = newJString($v)
|
2018-12-21 22:37:46 +00:00
|
|
|
|
|
|
|
proc writeJson*(prefix, slot, v: auto) =
|
|
|
|
var f: File
|
|
|
|
defer: close(f)
|
|
|
|
discard open(f, fmt"{prefix:04}-{slot:08}.json", fmWrite)
|
|
|
|
write(f, pretty(%*(v)))
|
|
|
|
|
|
|
|
proc transition(
|
|
|
|
slots = 1945,
|
|
|
|
validators = EPOCH_LENGTH, # One per shard is minimum
|
|
|
|
json_interval = EPOCH_LENGTH,
|
2018-12-27 23:40:22 +00:00
|
|
|
prefix = 0,
|
|
|
|
attesterRatio = 0.0,
|
|
|
|
validate = false) =
|
2018-12-21 22:37:46 +00:00
|
|
|
let
|
2018-12-27 23:40:22 +00:00
|
|
|
flags = if validate: {} else: {skipValidation}
|
2018-12-21 22:37:46 +00:00
|
|
|
genesisState = get_initial_beacon_state(
|
2018-12-27 23:40:22 +00:00
|
|
|
makeInitialDeposits(validators, flags), 0, Eth2Digest(), flags)
|
2018-12-21 22:37:46 +00:00
|
|
|
genesisBlock = makeGenesisBlock(genesisState)
|
|
|
|
|
|
|
|
var
|
2018-12-27 23:40:22 +00:00
|
|
|
attestations: array[MIN_ATTESTATION_INCLUSION_DELAY, seq[Attestation]]
|
2018-12-21 22:37:46 +00:00
|
|
|
state = genesisState
|
2018-12-21 23:47:55 +00:00
|
|
|
latest_block_root = hash_tree_root_final(genesisBlock)
|
2018-12-21 22:37:46 +00:00
|
|
|
|
2018-12-27 23:40:22 +00:00
|
|
|
var r: Rand
|
2018-12-21 22:37:46 +00:00
|
|
|
for i in 0..<slots:
|
|
|
|
if state.slot mod json_interval.uint64 == 0:
|
|
|
|
writeJson(prefix, state.slot, state)
|
|
|
|
write(stdout, ":")
|
|
|
|
else:
|
|
|
|
write(stdout, ".")
|
|
|
|
|
2018-12-27 23:40:22 +00:00
|
|
|
let
|
|
|
|
attestations_idx = state.slot mod MIN_ATTESTATION_INCLUSION_DELAY
|
|
|
|
body = BeaconBlockBody(attestations: attestations[attestations_idx])
|
|
|
|
|
|
|
|
attestations[attestations_idx] = @[]
|
|
|
|
|
2018-12-21 23:47:55 +00:00
|
|
|
latest_block_root = hash_tree_root_final(
|
2018-12-27 23:40:22 +00:00
|
|
|
addBlock(state, latest_block_root, body, flags))
|
|
|
|
|
|
|
|
if attesterRatio > 0.0:
|
|
|
|
# attesterRatio is the fraction of attesters that actually do their
|
|
|
|
# work for every slot - we'll randimize it deterministically to give
|
|
|
|
# some variation
|
|
|
|
let scass = get_shard_committees_at_slot(state, state.slot)
|
|
|
|
|
|
|
|
for scas in scass:
|
|
|
|
var
|
|
|
|
attestation: Attestation
|
|
|
|
first = true
|
|
|
|
|
|
|
|
for v in scas.committee:
|
|
|
|
if (rand(r, high(int)).float * attesterRatio).int <= high(int):
|
|
|
|
if first:
|
|
|
|
attestation = makeAttestation(state, latest_block_root, v)
|
|
|
|
first = false
|
|
|
|
else:
|
|
|
|
attestation.combine(
|
|
|
|
makeAttestation(state, latest_block_root, v), flags)
|
|
|
|
|
|
|
|
if not first:
|
|
|
|
# add the attestation if any of the validators attested, as given
|
|
|
|
# by the randomness. We have to delay when the attestation is
|
|
|
|
# actually added to the block per the attestation delay rule!
|
|
|
|
attestations[
|
|
|
|
(state.slot + MIN_ATTESTATION_INCLUSION_DELAY - 1) mod
|
|
|
|
MIN_ATTESTATION_INCLUSION_DELAY].add attestation
|
2018-12-21 22:37:46 +00:00
|
|
|
|
|
|
|
flushFile(stdout)
|
|
|
|
|
|
|
|
echo "done!"
|
|
|
|
|
2018-12-27 23:40:22 +00:00
|
|
|
dispatch(
|
|
|
|
transition,
|
|
|
|
help = { "attesterRatio": "ratio of validators that attest in each round" }
|
|
|
|
)
|