abstract over most withStateVars/withState state var usage (#2484)

* abstract over most withStateVars/withState state var usage

* cleanups
This commit is contained in:
tersec 2021-04-13 15:05:44 +02:00 committed by GitHub
parent 03f478748f
commit 498c998552
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 51 additions and 39 deletions

View File

@ -51,13 +51,16 @@ proc updateStateData*(
dag: ChainDAGRef, state: var StateData, bs: BlockSlot, save: bool, dag: ChainDAGRef, state: var StateData, bs: BlockSlot, save: bool,
cache: var StateCache) {.gcsafe.} cache: var StateCache) {.gcsafe.}
template withStateVars*(stateData: var StateData, body: untyped): untyped = template withStateVars*(
stateDataInternal: var StateData, body: untyped): untyped =
## Inject a few more descriptive names for the members of `stateData` - ## Inject a few more descriptive names for the members of `stateData` -
## the stateData instance may get mutated through these names as well ## the stateData instance may get mutated through these names as well
template hashedState(): HashedBeaconState {.inject, used.} = stateData.data template stateData(): StateData {.inject, used.} = stateDataInternal
template state(): BeaconState {.inject, used.} = stateData.data.data template hashedState(): HashedBeaconState {.inject, used.} =
template blck(): BlockRef {.inject, used.} = stateData.blck stateDataInternal.data
template root(): Eth2Digest {.inject, used.} = stateData.data.root template state(): BeaconState {.inject, used.} = stateDataInternal.data.data
template blck(): BlockRef {.inject, used.} = stateDataInternal.blck
template root(): Eth2Digest {.inject, used.} = stateDataInternal.data.root
body body

View File

@ -479,7 +479,8 @@ proc getAttachedValidators(node: BeaconNode):
for validatorIndex in 0 ..< for validatorIndex in 0 ..<
getStateField(node.chainDag.headState, validators).len: getStateField(node.chainDag.headState, validators).len:
let attachedValidator = node.getAttachedValidator( let attachedValidator = node.getAttachedValidator(
node.chainDag.headState.data.data, validatorIndex.ValidatorIndex) getStateField(node.chainDag.headState, validators),
validatorIndex.ValidatorIndex)
if attachedValidator.isNil: if attachedValidator.isNil:
continue continue
result[validatorIndex.ValidatorIndex] = attachedValidator result[validatorIndex.ValidatorIndex] = attachedValidator

View File

@ -194,21 +194,23 @@ proc installBeaconApiHandlers*(rpcServer: RpcServer, node: BeaconNode) {.
rpcServer.rpc("get_v1_beacon_states_fork") do (stateId: string) -> Fork: rpcServer.rpc("get_v1_beacon_states_fork") do (stateId: string) -> Fork:
withStateForStateId(stateId): withStateForStateId(stateId):
return state.fork return getStateField(stateData, fork)
rpcServer.rpc("get_v1_beacon_states_finality_checkpoints") do ( rpcServer.rpc("get_v1_beacon_states_finality_checkpoints") do (
stateId: string) -> BeaconStatesFinalityCheckpointsTuple: stateId: string) -> BeaconStatesFinalityCheckpointsTuple:
withStateForStateId(stateId): withStateForStateId(stateId):
return (previous_justified: state.previous_justified_checkpoint, return (previous_justified:
current_justified: state.current_justified_checkpoint, getStateField(stateData, previous_justified_checkpoint),
finalized: state.finalized_checkpoint) current_justified:
getStateField(stateData, current_justified_checkpoint),
finalized: getStateField(stateData, finalized_checkpoint))
rpcServer.rpc("get_v1_beacon_states_stateId_validators") do ( rpcServer.rpc("get_v1_beacon_states_stateId_validators") do (
stateId: string, validatorIds: Option[seq[string]], stateId: string, validatorIds: Option[seq[string]],
status: Option[seq[string]]) -> seq[BeaconStatesValidatorsTuple]: status: Option[seq[string]]) -> seq[BeaconStatesValidatorsTuple]:
var vquery: ValidatorQuery var vquery: ValidatorQuery
var squery: StatusQuery var squery: StatusQuery
let current_epoch = get_current_epoch(node.chainDag.headState.data.data) let current_epoch = getStateField(node.chainDag.headState, slot).epoch
template statusCheck(status, statusQuery, vstatus, current_epoch): bool = template statusCheck(status, statusQuery, vstatus, current_epoch): bool =
if status.isNone(): if status.isNone():
@ -235,7 +237,7 @@ proc installBeaconApiHandlers*(rpcServer: RpcServer, node: BeaconNode) {.
vquery = vqres.get() vquery = vqres.get()
if validatorIds.isNone(): if validatorIds.isNone():
for index, validator in state.validators.pairs(): for index, validator in getStateField(stateData, validators).pairs():
let sres = validator.getStatus(current_epoch) let sres = validator.getStatus(current_epoch)
if sres.isOk: if sres.isOk:
let vstatus = sres.get() let vstatus = sres.get()
@ -245,11 +247,11 @@ proc installBeaconApiHandlers*(rpcServer: RpcServer, node: BeaconNode) {.
res.add((validator: validator, res.add((validator: validator,
index: uint64(index), index: uint64(index),
status: vstatus, status: vstatus,
balance: state.balances[index])) balance: getStateField(stateData, balances)[index]))
else: else:
for index in vquery.ids: for index in vquery.ids:
if index < lenu64(state.validators): if index < lenu64(getStateField(stateData, validators)):
let validator = state.validators[index] let validator = getStateField(stateData, validators)[index]
let sres = validator.getStatus(current_epoch) let sres = validator.getStatus(current_epoch)
if sres.isOk: if sres.isOk:
let vstatus = sres.get() let vstatus = sres.get()
@ -260,9 +262,9 @@ proc installBeaconApiHandlers*(rpcServer: RpcServer, node: BeaconNode) {.
res.add((validator: validator, res.add((validator: validator,
index: uint64(index), index: uint64(index),
status: vstatus, status: vstatus,
balance: state.balances[index])) balance: getStateField(stateData, balances)[index]))
for index, validator in state.validators.pairs(): for index, validator in getStateField(stateData, validators).pairs():
if validator.pubkey in vquery.keyset: if validator.pubkey in vquery.keyset:
let sres = validator.getStatus(current_epoch) let sres = validator.getStatus(current_epoch)
if sres.isOk: if sres.isOk:
@ -273,12 +275,12 @@ proc installBeaconApiHandlers*(rpcServer: RpcServer, node: BeaconNode) {.
res.add((validator: validator, res.add((validator: validator,
index: uint64(index), index: uint64(index),
status: vstatus, status: vstatus,
balance: state.balances[index])) balance: getStateField(stateData, balances)[index]))
return res return res
rpcServer.rpc("get_v1_beacon_states_stateId_validators_validatorId") do ( rpcServer.rpc("get_v1_beacon_states_stateId_validators_validatorId") do (
stateId: string, validatorId: string) -> BeaconStatesValidatorsTuple: stateId: string, validatorId: string) -> BeaconStatesValidatorsTuple:
let current_epoch = get_current_epoch(node.chainDag.headState.data.data) let current_epoch = getStateField(node.chainDag.headState, slot).epoch
let vqres = createIdQuery([validatorId]) let vqres = createIdQuery([validatorId])
if vqres.isErr: if vqres.isErr:
raise newException(CatchableError, vqres.error) raise newException(CatchableError, vqres.error)
@ -287,21 +289,23 @@ proc installBeaconApiHandlers*(rpcServer: RpcServer, node: BeaconNode) {.
withStateForStateId(stateId): withStateForStateId(stateId):
if len(vquery.ids) > 0: if len(vquery.ids) > 0:
let index = vquery.ids[0] let index = vquery.ids[0]
if index < lenu64(state.validators): if index < lenu64(getStateField(stateData, validators)):
let validator = state.validators[index] let validator = getStateField(stateData, validators)[index]
let sres = validator.getStatus(current_epoch) let sres = validator.getStatus(current_epoch)
if sres.isOk: if sres.isOk:
return (validator: validator, index: uint64(index), return (validator: validator, index: uint64(index),
status: sres.get(), balance: state.balances[index]) status: sres.get(),
balance: getStateField(stateData, balances)[index])
else: else:
raise newException(CatchableError, "Incorrect validator's state") raise newException(CatchableError, "Incorrect validator's state")
else: else:
for index, validator in state.validators.pairs(): for index, validator in getStateField(stateData, validators).pairs():
if validator.pubkey in vquery.keyset: if validator.pubkey in vquery.keyset:
let sres = validator.getStatus(current_epoch) let sres = validator.getStatus(current_epoch)
if sres.isOk: if sres.isOk:
return (validator: validator, index: uint64(index), return (validator: validator, index: uint64(index),
status: sres.get(), balance: state.balances[index]) status: sres.get(),
balance: getStateField(stateData, balances)[index])
else: else:
raise newException(CatchableError, "Incorrect validator's state") raise newException(CatchableError, "Incorrect validator's state")
@ -311,7 +315,7 @@ proc installBeaconApiHandlers*(rpcServer: RpcServer, node: BeaconNode) {.
var res: seq[BalanceTuple] var res: seq[BalanceTuple]
withStateForStateId(stateId): withStateForStateId(stateId):
if validatorsId.isNone(): if validatorsId.isNone():
for index, value in state.balances.pairs(): for index, value in getStateField(stateData, balances).pairs():
let balance = (index: uint64(index), balance: value) let balance = (index: uint64(index), balance: value)
res.add(balance) res.add(balance)
else: else:
@ -321,17 +325,17 @@ proc installBeaconApiHandlers*(rpcServer: RpcServer, node: BeaconNode) {.
var vquery = vqres.get() var vquery = vqres.get()
for index in vquery.ids: for index in vquery.ids:
if index < lenu64(state.validators): if index < lenu64(getStateField(stateData, validators)):
let validator = state.validators[index] let validator = getStateField(stateData, validators)[index]
vquery.keyset.excl(validator.pubkey) vquery.keyset.excl(validator.pubkey)
let balance = (index: uint64(index), let balance = (index: uint64(index),
balance: state.balances[index]) balance: getStateField(stateData, balances)[index])
res.add(balance) res.add(balance)
for index, validator in state.validators.pairs(): for index, validator in getStateField(stateData, validators).pairs():
if validator.pubkey in vquery.keyset: if validator.pubkey in vquery.keyset:
let balance = (index: uint64(index), let balance = (index: uint64(index),
balance: state.balances[index]) balance: getStateField(stateData, balances)[index])
res.add(balance) res.add(balance)
return res return res
@ -359,7 +363,7 @@ proc installBeaconApiHandlers*(rpcServer: RpcServer, node: BeaconNode) {.
let qepoch = let qepoch =
if epoch.isNone: if epoch.isNone:
compute_epoch_at_slot(state.slot) compute_epoch_at_slot(getStateField(stateData, slot))
else: else:
Epoch(epoch.get()) Epoch(epoch.get())

View File

@ -315,6 +315,9 @@ proc add*(x: var HashList, val: auto): bool =
false false
proc addDefault*(x: var HashList): ptr x.T = proc addDefault*(x: var HashList): ptr x.T =
if x.data.len >= x.maxLen:
return nil
distinctBase(x.data).setLen(x.data.len + 1) distinctBase(x.data).setLen(x.data.len + 1)
x.growHashes() x.growHashes()
clearCaches(x, x.data.len() - 1) clearCaches(x, x.data.len() - 1)

View File

@ -55,9 +55,9 @@ declarePublicGauge(attached_validator_balance_total,
logScope: topics = "beacval" logScope: topics = "beacval"
proc findValidator(state: BeaconState, pubKey: ValidatorPubKey): proc findValidator(validators: auto, pubKey: ValidatorPubKey):
Option[ValidatorIndex] = Option[ValidatorIndex] =
let idx = state.validators.asSeq.findIt(it.pubKey == pubKey) let idx = validators.asSeq.findIt(it.pubKey == pubKey)
if idx == -1: if idx == -1:
# We allow adding a validator even if its key is not in the state registry: # We allow adding a validator even if its key is not in the state registry:
# it might be that the deposit for this validator has not yet been processed # it might be that the deposit for this validator has not yet been processed
@ -71,7 +71,7 @@ proc addLocalValidator*(node: BeaconNode,
privKey: ValidatorPrivKey) = privKey: ValidatorPrivKey) =
let pubKey = privKey.toPubKey() let pubKey = privKey.toPubKey()
node.attachedValidators[].addLocalValidator( node.attachedValidators[].addLocalValidator(
pubKey, privKey, findValidator(state, pubKey)) pubKey, privKey, findValidator(state.validators, pubKey))
proc addLocalValidators*(node: BeaconNode) = proc addLocalValidators*(node: BeaconNode) =
for validatorKey in node.config.validatorKeys: for validatorKey in node.config.validatorKeys:
@ -84,7 +84,8 @@ proc addRemoteValidators*(node: BeaconNode) {.raises: [Defect, OSError, IOError]
if node.vcProcess.outputStream.readLine(line) and line != "end": if node.vcProcess.outputStream.readLine(line) and line != "end":
let let
key = ValidatorPubKey.fromHex(line).get() key = ValidatorPubKey.fromHex(line).get()
index = findValidator(node.chainDag.headState.data.data, key) index = findValidator(
getStateField(node.chainDag.headState, validators), key)
let v = AttachedValidator(pubKey: key, let v = AttachedValidator(pubKey: key,
index: index, index: index,
@ -100,10 +101,10 @@ proc getAttachedValidator*(node: BeaconNode,
node.attachedValidators[].getValidator(pubkey) node.attachedValidators[].getValidator(pubkey)
proc getAttachedValidator*(node: BeaconNode, proc getAttachedValidator*(node: BeaconNode,
state: BeaconState, state_validators: auto,
idx: ValidatorIndex): AttachedValidator = idx: ValidatorIndex): AttachedValidator =
if idx < state.validators.len.ValidatorIndex: if idx < state_validators.len.ValidatorIndex:
let validator = node.getAttachedValidator(state.validators[idx].pubkey) let validator = node.getAttachedValidator(state_validators[idx].pubkey)
if validator != nil and validator.index != some(idx.ValidatorIndex): if validator != nil and validator.index != some(idx.ValidatorIndex):
# Update index, in case the validator was activated! # Update index, in case the validator was activated!
notice "Validator activated", pubkey = validator.pubkey, index = idx notice "Validator activated", pubkey = validator.pubkey, index = idx
@ -111,7 +112,7 @@ proc getAttachedValidator*(node: BeaconNode,
validator validator
else: else:
warn "Validator index out of bounds", warn "Validator index out of bounds",
idx, stateSlot = state.slot, validators = state.validators.len idx, validators = state_validators.len
nil nil
proc getAttachedValidator*(node: BeaconNode, proc getAttachedValidator*(node: BeaconNode,