Some bits of randao

This commit is contained in:
Yuriy Glukhov 2018-12-08 16:17:47 +02:00 committed by zah
parent 360cf313e8
commit 61f81fb0c4
6 changed files with 130 additions and 19 deletions

View File

@ -4,7 +4,7 @@ author = "Status Research & Development GmbH"
description = "Eth2.0 research implementation of the beacon chain"
license = "MIT or Apache License 2.0"
installDirs = @["beacon_chain"]
bin = @["beacon_chain/beacon_node"]
bin = @["beacon_chain/beacon_node", "beacon_chain/validator_keygen"]
### Dependencies
requires "nim >= 0.18.0",

View File

@ -80,6 +80,7 @@ proc addLocalValidators*(node: BeaconNode) =
# 1. Parse the validator keys
let privKey = loadPrivKey(validator)
let pubKey = privKey.pubKey()
let randao = loadRandao(validator)
# 2. Check whether the validators exist in the beacon state.
# (Report a warning otherwise)
@ -89,7 +90,7 @@ proc addLocalValidators*(node: BeaconNode) =
else:
# 3. Add the validators to node.attachedValidators
# TODO: Parse randao secret
node.attachedValidators.addLocalValidator(idx, pubKey, privKey, @[])
node.attachedValidators.addLocalValidator(idx, pubKey, privKey, randao)
proc getAttachedValidator(node: BeaconNode, idx: int): AttachedValidator =
@ -114,6 +115,8 @@ proc proposeBlock(node: BeaconNode,
# TODO:
# 1. Produce a RANDAO reveal from attachedVadalidator.randaoSecret
# and its matching ValidatorRecord.
let randaoCommitment = node.beaconState.validator_registry[validator.idx].randao_commitment
proposal.randao_reveal = await validator.randaoReveal(randaoCommitment)
# 2. Get ancestors from the beacon_db

View File

@ -1,5 +1,5 @@
import
confutils/defs, spec/crypto, milagro_crypto
confutils/defs, spec/crypto, milagro_crypto, randao
type
ValidatorKeyPath* = distinct string
@ -28,11 +28,11 @@ type
proc loadPrivKey*(p: ValidatorKeyPath): ValidatorPrivKey =
initSigKey(cast[seq[byte]](readFile(string(p) & ".privkey")))
proc loadRandao*(p: ValidatorKeyPath): Randao =
initRandao(cast[seq[byte]](readFile(string(p) & ".randao")))
proc parse*(T: type ValidatorKeyPath, input: TaintedString): T =
discard loadPrivKey(ValidatorKeyPath(input))
# TODO:
# Check that the entered string is a valid base file name and
# that it has matching .privkey, and .randaosecret files
T(input)
result = T(input)
discard loadPrivKey(result)
discard loadRandao(result)

64
beacon_chain/randao.nim Normal file
View File

@ -0,0 +1,64 @@
import spec/digest
type Randao* = object
seed: Eth2Digest
const MaxRandaoLevels = 10000
proc initRandao*(seed: Eth2Digest): Randao =
result.seed = seed
proc initRandao*(bytes: openarray[byte]): Randao =
if bytes.len != sizeof(Eth2Digest):
raise newException(Exception, "Wrong randao size")
var s: Eth2Digest
s.data[0 .. ^1] = bytes
initRandao(bytes)
func repeatHash*(h: Eth2Digest, n: int): Eth2Digest =
if n == 0: h
else: repeatHash(eth2Hash(h.data), n - 1)
iterator items(r: Randao): Eth2Digest =
var h = r.seed
for i in 0 .. MaxRandaoLevels:
yield h
h = eth2hash(h.data)
proc initialCommitment*(r: Randao): Eth2Digest =
var i = 0
for h in r:
if i == MaxRandaoLevels:
return h
inc i
assert(false, "Unreachable")
proc reveal*(r: Randao, commitment: Eth2Digest): Eth2Digest =
if commitment == r.seed:
raise newException(Exception, "Randao: cannot reveal for seed")
result = r.seed
for h in r:
if h == commitment:
return
result = h
raise newException(Exception, "Randao: commitment not found")
when isMainModule:
import times, nimcrypto
var seed: Eth2Digest
let r = initRandao(seed)
var s = epochTime()
var ic = r.initialCommitment()
var e = epochTime()
echo "initialCommitment: ", ic
echo "Took time: ", e - s
s = epochTime()
let rev = r.reveal(ic)
e = epochTime()
echo "reveal: ", rev
echo "Took time: ", e - s
echo r.reveal(eth2hash([1.byte, 2, 3]))

View File

@ -0,0 +1,37 @@
import os, ospaths, milagro_crypto, nimcrypto, ./spec/digest
proc writeFile(filename: string, content: openarray[byte]) =
var s = newString(content.len)
if content.len != 0:
copyMem(addr s[0], unsafeAddr content[0], content.len)
writeFile(filename, s)
proc genKeys(path: string) =
let pk = newSigKey()
var randaoSeed: Eth2Digest
if randomBytes(randaoSeed.data) != sizeof(randaoSeed.data):
raise newException(Exception, "Could not generate randao seed")
createDir(parentDir(path))
let pkPath = path & ".privkey"
let randaoPath = path & ".randao"
writeFile(randaoPath, randaoSeed.data)
writeFile(pkPath, pk.getRaw())
echo "Generated privkey: ", pkPath
echo "Generated randao seed: ", randaoPath
proc printUsage() =
echo "Usage: validator_keygen <path>"
proc main() =
if paramCount() != 1:
printUsage()
return
let path = paramStr(1)
genKeys(path)
when isMainModule:
main()

View File

@ -1,7 +1,7 @@
import
tables, random,
asyncdispatch2,
spec/[datatypes, crypto]
spec/[datatypes, crypto, digest], randao
type
ValidatorKind = enum
@ -10,14 +10,12 @@ type
ValidatorConnection = object
RandaoSecret = seq[byte]
AttachedValidator* = ref object
idx*: int
idx*: int # index in the registry
case kind: ValidatorKind
of inProcess:
privKey: ValidatorPrivKey
randaoSecret: RandaoSecret
randaoSecret: Randao
else:
connection: ValidatorConnection
@ -31,11 +29,12 @@ proc addLocalValidator*(pool: var ValidatorPool,
idx: int,
pubKey: ValidatorPubKey,
privKey: ValidatorPrivKey,
randaoSecret: RandaoSecret) =
pool.validators[pubKey] = AttachedValidator(idx: idx,
randaoSecret: Randao) =
let v = AttachedValidator(idx: idx,
kind: inProcess,
privKey: privKey,
randaoSecret: randaoSecret)
pool.validators[pubKey] = v
proc getValidator*(pool: ValidatorPool,
validatorKey: ValidatorPubKey): AttachedValidator =
@ -64,3 +63,11 @@ proc signAttestation*(v: AttachedValidator,
# send RPC
discard
proc randaoReveal*(v: AttachedValidator, commitment: Eth2Digest): Future[Eth2Digest] {.async.} =
if v.kind == inProcess:
result = v.randaoSecret.reveal(commitment)
else:
# TODO:
# send RPC
discard