Skip to content

Commit 74c63ed

Browse files
authored
More efficient implementation of the 'POST beacon_committee_subscriptions' API (#3153)
1 parent 6fddff5 commit 74c63ed

File tree

5 files changed

+36
-26
lines changed

5 files changed

+36
-26
lines changed

beacon_chain/consensus_object_pools/sync_committee_msg_pool.nim

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88
{.push raises: [Defect].}
99

1010
import
11-
std/[hashes, sets, tables],
11+
std/[sets, tables],
12+
stew/shims/hashes,
1213
chronicles,
1314
../spec/digest,
1415
../spec/datatypes/altair
@@ -53,7 +54,7 @@ type
5354
onContributionReceived*: OnSyncContributionCallback
5455

5556
func hash*(x: SyncCommitteeMsgKey): Hash =
56-
hashData(unsafeAddr x, sizeof(x))
57+
hashAllFields(x)
5758

5859
func init*(T: type SyncCommitteeMsgPool,
5960
onSyncContribution: OnSyncContributionCallback = nil

beacon_chain/eth1/eth1_monitor.nim

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@
88
{.push raises: [Defect].}
99

1010
import
11-
std/[deques, hashes, options, strformat, strutils, sequtils, tables,
11+
std/[deques, options, strformat, strutils, sequtils, tables,
1212
typetraits, uri, json],
1313
# Nimble packages:
1414
chronos, json, metrics, chronicles/timings,
1515
web3, web3/ethtypes as web3Types, web3/ethhexstrings, web3/engine_api,
1616
eth/common/eth_types,
17-
eth/async_utils, stew/[objects, byteutils],
17+
eth/async_utils, stew/[objects, byteutils, shims/hashes],
1818
# Local modules:
1919
../spec/[eth2_merkleization, forks, helpers],
2020
../spec/datatypes/[base, merge],
@@ -356,7 +356,7 @@ proc addBlock*(chain: var Eth1Chain, newBlock: Eth1Block) =
356356
eth1_chain_len.set chain.blocks.len.int64
357357

358358
func hash*(x: Eth1Data): Hash =
359-
hashData(unsafeAddr x, sizeof(x))
359+
hash(x.block_hash)
360360

361361
template hash*(x: Eth1Block): Hash =
362362
hash(x.voteData)

beacon_chain/rpc/rest_validator_api.nim

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -503,30 +503,38 @@ proc installValidatorApiHandlers*(router: var RestRouter, node: BeaconNode) =
503503
if not(node.isSynced(node.dag.head)):
504504
return RestApiResponse.jsonError(Http503, BeaconNodeInSyncError)
505505

506+
let
507+
wallSlot = node.beaconClock.now.slotOrZero
508+
wallEpoch = wallSlot.epoch
509+
head = node.dag.head
510+
511+
var currentEpoch, nextEpoch: Option[EpochRef]
512+
template getAndCacheEpochRef(epochRefVar: var Option[EpochRef],
513+
epoch: Epoch): EpochRef =
514+
if epochRefVar.isNone:
515+
epochRefVar = some node.dag.getEpochRef(head, epoch)
516+
epochRefVar.get
517+
506518
for request in requests:
507519
if uint64(request.committee_index) >= uint64(MAX_COMMITTEES_PER_SLOT):
508520
return RestApiResponse.jsonError(Http400,
509521
InvalidCommitteeIndexValueError)
510522
if uint64(request.validator_index) >=
511523
lenu64(getStateField(node.dag.headState.data, validators)):
512524
return RestApiResponse.jsonError(Http400,
513-
InvalidValidatorIndexValueError)
514-
515-
let wallSlot = node.beaconClock.now.slotOrZero
525+
InvalidValidatorIndexValueError)
516526
if wallSlot > request.slot + 1:
517527
return RestApiResponse.jsonError(Http400, SlotFromThePastError)
528+
518529
let epoch = request.slot.epoch
519-
if epoch >= wallSlot.epoch and epoch - wallSlot.epoch > 1:
530+
let epochRef = if epoch == wallEpoch:
531+
currentEpoch.getAndCacheEpochRef(wallEpoch)
532+
elif epoch == wallEpoch + 1:
533+
nextEpoch.getAndCacheEpochRef(wallEpoch + 1)
534+
else:
520535
return RestApiResponse.jsonError(Http400,
521536
SlotNotInNextWallSlotEpochError)
522-
let head =
523-
block:
524-
let res = node.getCurrentHead(epoch)
525-
if res.isErr():
526-
return RestApiResponse.jsonError(Http400, NoHeadForSlotError,
527-
$res.error())
528-
res.get()
529-
let epochRef = node.dag.getEpochRef(head, epoch)
537+
530538
let subnet_id = compute_subnet_for_attestation(
531539
get_committee_count_per_slot(epochRef), request.slot,
532540
request.committee_index)

beacon_chain/validators/action_tracker.nim

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import
2-
std/[sequtils, sets, tables],
3-
chronicles,
2+
std/[tables, sequtils],
43
bearssl,
4+
stew/shims/[sets, hashes], chronicles,
55
eth/p2p/discoveryv5/random2,
66
../spec/datatypes/base,
77
../spec/[helpers, network],
@@ -56,11 +56,14 @@ type
5656
## subnet for each such validator - the slot is used to expire validators
5757
## that no longer are posting duties
5858

59-
duties*: seq[AggregatorDuty] ##\
59+
duties*: HashSet[AggregatorDuty] ##\
6060
## Known aggregation duties in the near future - before each such
6161
## duty, we'll subscribe to the corresponding subnet to collect
6262
## attestations for the aggregate
6363

64+
func hash*(x: AggregatorDuty): Hash =
65+
hashAllFields(x)
66+
6467
# https://github.com/ethereum/consensus-specs/blob/v1.1.4/specs/phase0/validator.md#phase-0-attestation-subnet-stability
6568
func randomStabilitySubnet*(
6669
self: ActionTracker, epoch: Epoch): tuple[subnet_id: SubnetId, expiration: Epoch] =
@@ -84,12 +87,11 @@ proc registerDuty*(
8487
if isAggregator:
8588
let newDuty = AggregatorDuty(slot: slot, subnet_id: subnet_id)
8689

87-
for duty in tracker.duties.mitems():
88-
if duty == newDuty:
89-
return
90+
if newDuty in tracker.duties:
91+
return
9092

9193
debug "Registering aggregation duty", slot, subnet_id, vidx
92-
tracker.duties.add(newDuty)
94+
tracker.duties.incl(newDuty)
9395

9496
const allSubnetBits = block:
9597
var res: AttnetBits
@@ -100,7 +102,6 @@ func aggregateSubnets*(tracker: ActionTracker, wallSlot: Slot): AttnetBits =
100102
var res: AttnetBits
101103
# Subscribe to subnets for upcoming duties
102104
for duty in tracker.duties:
103-
104105
if wallSlot <= duty.slot and
105106
wallSlot + SUBNET_SUBSCRIPTION_LEAD_TIME_SLOTS > duty.slot:
106107

0 commit comments

Comments
 (0)