Skip to content

Commit

Permalink
REST/JSON-RPC: speed up several requests
Browse files Browse the repository at this point in the history
REST/JSON-RPC and a few more also invalidate caches unnecessarily,
similar to #3089

* avoid copying validator on balance request
  • Loading branch information
arnetheduck committed Nov 12, 2021
1 parent 00bbc8e commit 2672d30
Show file tree
Hide file tree
Showing 7 changed files with 33 additions and 36 deletions.
17 changes: 8 additions & 9 deletions beacon_chain/rpc/rest_beacon_api.nim
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
for index, validator in getStateField(stateData.data,
validators).pairs():
let
balance = getStateField(stateData.data, balances)[index]
balance = getStateField(stateData.data, balances).asSeq()[index]
status =
block:
let sres = validator.getStatus(current_epoch)
Expand All @@ -311,8 +311,8 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
else:
for index in indices:
let
validator = getStateField(stateData.data, validators)[index]
balance = getStateField(stateData.data, balances)[index]
validator = getStateField(stateData.data, validators).asSeq()[index]
balance = getStateField(stateData.data, balances).asSeq()[index]
status =
block:
let sres = validator.getStatus(current_epoch)
Expand Down Expand Up @@ -382,8 +382,8 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
index

let
validator = getStateField(stateData.data, validators)[vindex]
balance = getStateField(stateData.data, balances)[vindex]
validator = getStateField(stateData.data, validators).asSeq()[vindex]
balance = getStateField(stateData.data, balances).asSeq()[vindex]
status =
block:
let sres = validator.getStatus(current_epoch)
Expand Down Expand Up @@ -479,14 +479,13 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
if len(validatorIds) == 0:
# There is no indices, so we going to return balances of all
# known validators.
for index, validator in getStateField(stateData.data,
validators).pairs():
let balance = getStateField(stateData.data, balances)[index]
for index, balance in getStateField(stateData.data,
balances).pairs():
res.add(RestValidatorBalance.init(ValidatorIndex(index),
balance))
else:
for index in indices:
let balance = getStateField(stateData.data, balances)[index]
let balance = getStateField(stateData.data, balances).asSeq()[index]
res.add(RestValidatorBalance.init(index, balance))
res
return RestApiResponse.jsonResponse(response)
Expand Down
14 changes: 5 additions & 9 deletions beacon_chain/rpc/rest_validator_api.nim
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ proc installValidatorApiHandlers*(router: var RestRouter, node: BeaconNode) =
if not validatorIdx.isValidInState(state.data):
return RestApiResponse.jsonError(Http400, "Invalid index: " & $validatorIdx)

res[resIdx].pubkey = state.data.validators[validatorIdx].pubkey
res[resIdx].pubkey = state.data.validators.asSeq()[validatorIdx].pubkey
res[resIdx].validator_index = validatorIdx

for idx, pubkey in syncCommittee:
Expand Down Expand Up @@ -458,14 +458,10 @@ proc installValidatorApiHandlers*(router: var RestRouter, node: BeaconNode) =
if uint64(request.committee_index) >= uint64(MAX_COMMITTEES_PER_SLOT):
return RestApiResponse.jsonError(Http400,
InvalidCommitteeIndexValueError)
let validator_pubkey =
block:
let idx = request.validator_index
if uint64(idx) >=
lenu64(getStateField(node.dag.headState.data, validators)):
return RestApiResponse.jsonError(Http400,
InvalidValidatorIndexValueError)
getStateField(node.dag.headState.data, validators)[idx].pubkey
if uint64(request.validator_index) >=
lenu64(getStateField(node.dag.headState.data, validators)):
return RestApiResponse.jsonError(Http400,
InvalidValidatorIndexValueError)

let wallSlot = node.beaconClock.now.slotOrZero
if wallSlot > request.slot + 1:
Expand Down
20 changes: 10 additions & 10 deletions beacon_chain/rpc/rpc_beacon_api.nim
Original file line number Diff line number Diff line change
Expand Up @@ -246,11 +246,11 @@ proc installBeaconApiHandlers*(rpcServer: RpcServer, node: BeaconNode) {.
res.add((validator: validator,
index: uint64(index),
status: vstatus,
balance: getStateField(stateData.data, balances)[index]))
balance: getStateField(stateData.data, balances).asSeq()[index]))
else:
for index in vquery.ids:
if index < lenu64(getStateField(stateData.data, validators)):
let validator = getStateField(stateData.data, validators)[index]
let validator = getStateField(stateData.data, validators).asSeq()[index]
let sres = validator.getStatus(current_epoch)
if sres.isOk:
let vstatus = sres.get()
Expand All @@ -261,7 +261,7 @@ proc installBeaconApiHandlers*(rpcServer: RpcServer, node: BeaconNode) {.
res.add((validator: validator,
index: uint64(index),
status: vstatus,
balance: getStateField(stateData.data, balances)[index]))
balance: getStateField(stateData.data, balances).asSeq()[index]))

for index, validator in getStateField(stateData.data, validators).pairs():
if validator.pubkey in vquery.keyset:
Expand All @@ -274,7 +274,7 @@ proc installBeaconApiHandlers*(rpcServer: RpcServer, node: BeaconNode) {.
res.add((validator: validator,
index: uint64(index),
status: vstatus,
balance: getStateField(stateData.data, balances)[index]))
balance: getStateField(stateData.data, balances).asSeq()[index]))
return res

rpcServer.rpc("get_v1_beacon_states_stateId_validators_validatorId") do (
Expand All @@ -289,12 +289,12 @@ proc installBeaconApiHandlers*(rpcServer: RpcServer, node: BeaconNode) {.
if len(vquery.ids) > 0:
let index = vquery.ids[0]
if index < lenu64(getStateField(stateData.data, validators)):
let validator = getStateField(stateData.data, validators)[index]
let validator = getStateField(stateData.data, validators).asSeq()[index]
let sres = validator.getStatus(current_epoch)
if sres.isOk:
return (validator: validator, index: uint64(index),
status: sres.get(),
balance: getStateField(stateData.data, balances)[index])
balance: getStateField(stateData.data, balances).asSeq()[index])
else:
raise newException(CatchableError, "Incorrect validator's state")
else:
Expand All @@ -304,7 +304,7 @@ proc installBeaconApiHandlers*(rpcServer: RpcServer, node: BeaconNode) {.
if sres.isOk:
return (validator: validator, index: uint64(index),
status: sres.get(),
balance: getStateField(stateData.data, balances)[index])
balance: getStateField(stateData.data, balances).asSeq()[index])
else:
raise newException(CatchableError, "Incorrect validator's state")

Expand All @@ -325,16 +325,16 @@ proc installBeaconApiHandlers*(rpcServer: RpcServer, node: BeaconNode) {.
var vquery = vqres.get()
for index in vquery.ids:
if index < lenu64(getStateField(stateData.data, validators)):
let validator = getStateField(stateData.data, validators)[index]
let validator = getStateField(stateData.data, validators).asSeq()[index]
vquery.keyset.excl(validator.pubkey)
let balance = (index: uint64(index),
balance: getStateField(stateData.data, balances)[index])
balance: getStateField(stateData.data, balances).asSeq()[index])
res.add(balance)

for index, validator in getStateField(stateData.data, validators).pairs():
if validator.pubkey in vquery.keyset:
let balance = (index: uint64(index),
balance: getStateField(stateData.data, balances)[index])
balance: getStateField(stateData.data, balances).asSeq()[index])
res.add(balance)
return res

Expand Down
5 changes: 3 additions & 2 deletions beacon_chain/spec/beaconstate.nim
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,11 @@ func initiate_validator_exit*(cfg: RuntimeConfig, state: var ForkyBeaconState,
index: ValidatorIndex, cache: var StateCache) =
## Initiate the exit of the validator with index ``index``.

if state.validators.asSeq()[index].exit_epoch != FAR_FUTURE_EPOCH:
return # Before touching cache

# Return if validator already initiated exit
let validator = addr state.validators[index]
if validator.exit_epoch != FAR_FUTURE_EPOCH:
return

trace "Validator exiting",
index = index,
Expand Down
9 changes: 5 additions & 4 deletions beacon_chain/spec/eth2_apis/eth2_rest_serialization.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1028,13 +1028,14 @@ proc decodeBytes*[T: DecodeTypes](t: typedesc[T], value: openarray[byte],
err("Content-Type not supported")

proc decodeBytes*[T: SszDecodeTypes](t: typedesc[T], value: openarray[byte],
contentType: string): RestResult[T] =
contentType: string, updateRoot = true): RestResult[T] =
case contentType
of "application/octet-stream":
try:
var v: T
readSszBytes(value, v)
ok(v)
var v: RestResult[T]
v.ok(T()) # This optimistically avoids an expensive genericAssign
readSszBytes(value, v.get(), updateRoot)
v
except SerializationError as exc:
err("Serialization error")
else:
Expand Down
2 changes: 1 addition & 1 deletion beacon_chain/spec/state_transition_block.nim
Original file line number Diff line number Diff line change
Expand Up @@ -489,7 +489,7 @@ proc process_sync_aggregate*(
state.current_sync_committee.pubkeys.len,
aggregate.sync_committee_bits.len):
let participant_index =
pubkeyIndices.getOrDefault(state.current_sync_committee.pubkeys[i])
pubkeyIndices.getOrDefault(state.current_sync_committee.pubkeys.data[i])
if aggregate.sync_committee_bits[i]:
increase_balance(state, participant_index, participant_reward)
increase_balance(state, proposer_index.get, proposer_reward)
Expand Down
2 changes: 1 addition & 1 deletion beacon_chain/validators/validator_duties.nim
Original file line number Diff line number Diff line change
Expand Up @@ -913,7 +913,7 @@ proc updateValidatorMetrics*(node: BeaconNode) =
stateRoot = getStateRoot(node.dag.headState.data)
0.Gwei
else:
getStateField(node.dag.headState.data, balances)[v.index.get()]
getStateField(node.dag.headState.data, balances).asSeq()[v.index.get()]

if i < 64:
attached_validator_balance.set(
Expand Down

0 comments on commit 2672d30

Please sign in to comment.