diff --git a/beacon_chain/consensus_object_pools/blockchain_dag.nim b/beacon_chain/consensus_object_pools/blockchain_dag.nim index f7033e4ba..12ea15d21 100644 --- a/beacon_chain/consensus_object_pools/blockchain_dag.nim +++ b/beacon_chain/consensus_object_pools/blockchain_dag.nim @@ -51,13 +51,16 @@ proc updateStateData*( dag: ChainDAGRef, state: var StateData, bs: BlockSlot, save: bool, 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` - ## the stateData instance may get mutated through these names as well - template hashedState(): HashedBeaconState {.inject, used.} = stateData.data - template state(): BeaconState {.inject, used.} = stateData.data.data - template blck(): BlockRef {.inject, used.} = stateData.blck - template root(): Eth2Digest {.inject, used.} = stateData.data.root + template stateData(): StateData {.inject, used.} = stateDataInternal + template hashedState(): HashedBeaconState {.inject, used.} = + stateDataInternal.data + template state(): BeaconState {.inject, used.} = stateDataInternal.data.data + template blck(): BlockRef {.inject, used.} = stateDataInternal.blck + template root(): Eth2Digest {.inject, used.} = stateDataInternal.data.root body diff --git a/beacon_chain/nimbus_beacon_node.nim b/beacon_chain/nimbus_beacon_node.nim index 28d561756..472c89516 100644 --- a/beacon_chain/nimbus_beacon_node.nim +++ b/beacon_chain/nimbus_beacon_node.nim @@ -479,7 +479,8 @@ proc getAttachedValidators(node: BeaconNode): for validatorIndex in 0 ..< getStateField(node.chainDag.headState, validators).len: let attachedValidator = node.getAttachedValidator( - node.chainDag.headState.data.data, validatorIndex.ValidatorIndex) + getStateField(node.chainDag.headState, validators), + validatorIndex.ValidatorIndex) if attachedValidator.isNil: continue result[validatorIndex.ValidatorIndex] = attachedValidator diff --git a/beacon_chain/rpc/beacon_api.nim b/beacon_chain/rpc/beacon_api.nim index 38101a34c..97b2a4213 100644 --- a/beacon_chain/rpc/beacon_api.nim +++ b/beacon_chain/rpc/beacon_api.nim @@ -194,21 +194,23 @@ proc installBeaconApiHandlers*(rpcServer: RpcServer, node: BeaconNode) {. rpcServer.rpc("get_v1_beacon_states_fork") do (stateId: string) -> Fork: withStateForStateId(stateId): - return state.fork + return getStateField(stateData, fork) rpcServer.rpc("get_v1_beacon_states_finality_checkpoints") do ( stateId: string) -> BeaconStatesFinalityCheckpointsTuple: withStateForStateId(stateId): - return (previous_justified: state.previous_justified_checkpoint, - current_justified: state.current_justified_checkpoint, - finalized: state.finalized_checkpoint) + return (previous_justified: + getStateField(stateData, previous_justified_checkpoint), + current_justified: + getStateField(stateData, current_justified_checkpoint), + finalized: getStateField(stateData, finalized_checkpoint)) rpcServer.rpc("get_v1_beacon_states_stateId_validators") do ( stateId: string, validatorIds: Option[seq[string]], status: Option[seq[string]]) -> seq[BeaconStatesValidatorsTuple]: var vquery: ValidatorQuery 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 = if status.isNone(): @@ -235,7 +237,7 @@ proc installBeaconApiHandlers*(rpcServer: RpcServer, node: BeaconNode) {. vquery = vqres.get() if validatorIds.isNone(): - for index, validator in state.validators.pairs(): + for index, validator in getStateField(stateData, validators).pairs(): let sres = validator.getStatus(current_epoch) if sres.isOk: let vstatus = sres.get() @@ -245,11 +247,11 @@ proc installBeaconApiHandlers*(rpcServer: RpcServer, node: BeaconNode) {. res.add((validator: validator, index: uint64(index), status: vstatus, - balance: state.balances[index])) + balance: getStateField(stateData, balances)[index])) else: for index in vquery.ids: - if index < lenu64(state.validators): - let validator = state.validators[index] + if index < lenu64(getStateField(stateData, validators)): + let validator = getStateField(stateData, validators)[index] let sres = validator.getStatus(current_epoch) if sres.isOk: let vstatus = sres.get() @@ -260,9 +262,9 @@ proc installBeaconApiHandlers*(rpcServer: RpcServer, node: BeaconNode) {. res.add((validator: validator, index: uint64(index), 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: let sres = validator.getStatus(current_epoch) if sres.isOk: @@ -273,12 +275,12 @@ proc installBeaconApiHandlers*(rpcServer: RpcServer, node: BeaconNode) {. res.add((validator: validator, index: uint64(index), status: vstatus, - balance: state.balances[index])) + balance: getStateField(stateData, balances)[index])) return res rpcServer.rpc("get_v1_beacon_states_stateId_validators_validatorId") do ( 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]) if vqres.isErr: raise newException(CatchableError, vqres.error) @@ -287,21 +289,23 @@ proc installBeaconApiHandlers*(rpcServer: RpcServer, node: BeaconNode) {. withStateForStateId(stateId): if len(vquery.ids) > 0: let index = vquery.ids[0] - if index < lenu64(state.validators): - let validator = state.validators[index] + if index < lenu64(getStateField(stateData, validators)): + let validator = getStateField(stateData, validators)[index] let sres = validator.getStatus(current_epoch) if sres.isOk: return (validator: validator, index: uint64(index), - status: sres.get(), balance: state.balances[index]) + status: sres.get(), + balance: getStateField(stateData, balances)[index]) else: raise newException(CatchableError, "Incorrect validator's state") else: - for index, validator in state.validators.pairs(): + for index, validator in getStateField(stateData, validators).pairs(): if validator.pubkey in vquery.keyset: let sres = validator.getStatus(current_epoch) if sres.isOk: return (validator: validator, index: uint64(index), - status: sres.get(), balance: state.balances[index]) + status: sres.get(), + balance: getStateField(stateData, balances)[index]) else: raise newException(CatchableError, "Incorrect validator's state") @@ -311,7 +315,7 @@ proc installBeaconApiHandlers*(rpcServer: RpcServer, node: BeaconNode) {. var res: seq[BalanceTuple] withStateForStateId(stateId): 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) res.add(balance) else: @@ -321,17 +325,17 @@ proc installBeaconApiHandlers*(rpcServer: RpcServer, node: BeaconNode) {. var vquery = vqres.get() for index in vquery.ids: - if index < lenu64(state.validators): - let validator = state.validators[index] + if index < lenu64(getStateField(stateData, validators)): + let validator = getStateField(stateData, validators)[index] vquery.keyset.excl(validator.pubkey) let balance = (index: uint64(index), - balance: state.balances[index]) + balance: getStateField(stateData, balances)[index]) res.add(balance) - for index, validator in state.validators.pairs(): + for index, validator in getStateField(stateData, validators).pairs(): if validator.pubkey in vquery.keyset: let balance = (index: uint64(index), - balance: state.balances[index]) + balance: getStateField(stateData, balances)[index]) res.add(balance) return res @@ -359,7 +363,7 @@ proc installBeaconApiHandlers*(rpcServer: RpcServer, node: BeaconNode) {. let qepoch = if epoch.isNone: - compute_epoch_at_slot(state.slot) + compute_epoch_at_slot(getStateField(stateData, slot)) else: Epoch(epoch.get()) diff --git a/beacon_chain/ssz/types.nim b/beacon_chain/ssz/types.nim index 7a23d8751..e231765b5 100644 --- a/beacon_chain/ssz/types.nim +++ b/beacon_chain/ssz/types.nim @@ -315,6 +315,9 @@ proc add*(x: var HashList, val: auto): bool = false proc addDefault*(x: var HashList): ptr x.T = + if x.data.len >= x.maxLen: + return nil + distinctBase(x.data).setLen(x.data.len + 1) x.growHashes() clearCaches(x, x.data.len() - 1) diff --git a/beacon_chain/validators/validator_duties.nim b/beacon_chain/validators/validator_duties.nim index fff37f16c..a84c80b17 100644 --- a/beacon_chain/validators/validator_duties.nim +++ b/beacon_chain/validators/validator_duties.nim @@ -55,9 +55,9 @@ declarePublicGauge(attached_validator_balance_total, logScope: topics = "beacval" -proc findValidator(state: BeaconState, pubKey: ValidatorPubKey): +proc findValidator(validators: auto, pubKey: ValidatorPubKey): Option[ValidatorIndex] = - let idx = state.validators.asSeq.findIt(it.pubKey == pubKey) + let idx = validators.asSeq.findIt(it.pubKey == pubKey) if idx == -1: # 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 @@ -71,7 +71,7 @@ proc addLocalValidator*(node: BeaconNode, privKey: ValidatorPrivKey) = let pubKey = privKey.toPubKey() node.attachedValidators[].addLocalValidator( - pubKey, privKey, findValidator(state, pubKey)) + pubKey, privKey, findValidator(state.validators, pubKey)) proc addLocalValidators*(node: BeaconNode) = 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": let 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, index: index, @@ -100,10 +101,10 @@ proc getAttachedValidator*(node: BeaconNode, node.attachedValidators[].getValidator(pubkey) proc getAttachedValidator*(node: BeaconNode, - state: BeaconState, + state_validators: auto, idx: ValidatorIndex): AttachedValidator = - if idx < state.validators.len.ValidatorIndex: - let validator = node.getAttachedValidator(state.validators[idx].pubkey) + if idx < state_validators.len.ValidatorIndex: + let validator = node.getAttachedValidator(state_validators[idx].pubkey) if validator != nil and validator.index != some(idx.ValidatorIndex): # Update index, in case the validator was activated! notice "Validator activated", pubkey = validator.pubkey, index = idx @@ -111,7 +112,7 @@ proc getAttachedValidator*(node: BeaconNode, validator else: warn "Validator index out of bounds", - idx, stateSlot = state.slot, validators = state.validators.len + idx, validators = state_validators.len nil proc getAttachedValidator*(node: BeaconNode,