Skip to content

Commit

Permalink
Moved the chain heads iteration below unknown in AttestationStateSele…
Browse files Browse the repository at this point in the history
…ctor (#7251)

Signed-off-by: Paul Harris <[email protected]>
  • Loading branch information
rolfyone authored Jun 13, 2023
1 parent 3430c15 commit e434ca3
Showing 1 changed file with 33 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -74,33 +74,13 @@ public SafeFuture<Optional<BeaconState>> getStateToValidate(
}

final UInt64 headEpoch = spec.computeEpochAtSlot(chainHead.getSlot());
if (attestationEpoch
.plus(spec.getSpecConfig(headEpoch).getEpochsPerHistoricalVector())
.isGreaterThan(headEpoch)) {
// If it's an ancestor of head and within historic slots, use the chain head
if (isAncestorOfChainHead(chainHead.getRoot(), targetBlockRoot)) {
appliedSelectorRule.labels("ancestor_of_head").inc();
return chainHead.getState().thenApply(Optional::of);
}
// if it's an ancestor of any chain head within historic slots, use that chain head.
final Optional<BeaconState> maybeChainHeadData =
recentChainData.getChainHeads().stream()
.filter(head -> isAncestorOfChainHead(head.getRoot(), targetBlockRoot))
.findFirst()
.flatMap(
protoNodeData -> {
LOG.debug(
"Found chain for target {}, chain head {}",
() -> attestationData.getTarget().getRoot(),
protoNodeData::getStateRoot);
return recentChainData
.getStore()
.getBlockStateIfAvailable(protoNodeData.getRoot());
});
if (maybeChainHeadData.isPresent()) {
appliedSelectorRule.labels("ancestor_of_fork").inc();
return completedFuture(maybeChainHeadData);
}
final boolean isWithinHistoricalEpochs =
attestationEpoch
.plus(spec.getSpecConfig(headEpoch).getEpochsPerHistoricalVector())
.isGreaterThan(headEpoch);
if (isWithinHistoricalEpochs && isAncestorOfChainHead(chainHead.getRoot(), targetBlockRoot)) {
appliedSelectorRule.labels("ancestor_of_head").inc();
return chainHead.getState().thenApply(Optional::of);
}

final UInt64 earliestSlot =
Expand All @@ -113,17 +93,39 @@ public SafeFuture<Optional<BeaconState>> getStateToValidate(
return completedFuture(Optional.of(finalizedState));
}

// Otherwise, use the state from the earliest allowed slot.
// This maximises the chance that the state we get will be on the canonical fork and so useful
// for other requests, and means all attestations for that epoch refer to the same slot,
// minimising the number of states we need
final Optional<UInt64> targetBlockSlot = recentChainData.getSlotForBlockRoot(targetBlockRoot);
if (targetBlockSlot.isEmpty()) {
// Block became unknown, so ignore it
appliedSelectorRule.labels("block_became_unknown").inc();
return completedFuture(Optional.empty());
}

// We generally have the chain head states, so attempt to locate which chain head is a
// descendent and use that
if (isWithinHistoricalEpochs) {
// if it's an ancestor of any chain head within historic slots, use that chain head.
final Optional<BeaconState> maybeChainHeadData =
recentChainData.getChainHeads().stream()
.filter(
head ->
isAncestorOfChainHead(head.getRoot(), targetBlockRoot, targetBlockSlot.get()))
.findFirst()
.flatMap(
protoNodeData -> {
LOG.trace(
"Found chain for target {}, chain head {}",
() -> attestationData.getTarget().getRoot(),
protoNodeData::getStateRoot);
return recentChainData
.getStore()
.getBlockStateIfAvailable(protoNodeData.getRoot());
});
if (maybeChainHeadData.isPresent()) {
appliedSelectorRule.labels("ancestor_of_fork").inc();
return completedFuture(maybeChainHeadData);
}
}

// Check if the attestations head block state is already available in cache and usable
if (targetBlockSlot.get().isGreaterThanOrEqualTo(earliestSlot)) {
final Optional<BeaconState> maybeState =
Expand Down

0 comments on commit e434ca3

Please sign in to comment.