REST/JSON-RPC: speed up several requests (#3092)

REST/JSON-RPC and a few more also invalidate caches unnecessarily,
similar to https://github.com/status-im/nimbus-eth2/pull/3089

* avoid copying validator on balance request
This commit is contained in:
Jacek Sieka 2021-11-12 23:29:28 +01:00 committed by GitHub
parent 2da9309d2a
commit b22d86e161
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 33 additions and 36 deletions

View File

@ -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)
@ -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)
@ -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)
@ -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)

View File

@ -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:
@ -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:

View File

@ -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()
@ -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:
@ -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 (
@ -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:
@ -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")
@ -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

View File

@ -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,

View File

@ -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:

View File

@ -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)

View File

@ -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(