Skip to content

Commit

Permalink
Do not require a minimum block height when downloading headers or blo…
Browse files Browse the repository at this point in the history
…cks (#3911)

* If needed update peer chain state when processing the block headers response

Signed-off-by: Fabio Di Fabio <fabio.difabio@consensys.net>

* Do not require a minimum block height when downloading headers or blocks

Peers could have that header, bacause our internal record about the
status of the peer could not always be up-to-date, so it is better
to avoid setting that constraint when selecting peers to download block
headers.

Signed-off-by: Fabio Di Fabio <fabio.difabio@consensys.net>

* Add CHANGELOG

Signed-off-by: Fabio Di Fabio <fabio.difabio@consensys.net>

* Complete the removal of minimumRequiredBlockNumber from constructors

Signed-off-by: Fabio Di Fabio <fabio.difabio@consensys.net>

Co-authored-by: Sally MacFarlane <sally.macfarlane@consensys.net>
  • Loading branch information
fab-10 and macfarla authored Jun 17, 2022
1 parent d5739fb commit 261b1e0
Show file tree
Hide file tree
Showing 20 changed files with 119 additions and 201 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
- Support `finalized` and `safe` as tags for the block parameter in RPC APIs [#3950](https://github.com/hyperledger/besu/pull/3950)
- Added verification of payload attributes in ForkchoiceUpdated [#3837](https://github.com/hyperledger/besu/pull/3837)
- Add support for Gray Glacier hardfork [#3961](https://github.com/hyperledger/besu/issues/3961)
- Do not require a minimum block height when downloading headers or blocks [#3911](https://github.com/hyperledger/besu/pull/3911)

### Bug Fixes
- alias engine-rpc-port parameter with the former rpc param name [#3958](https://github.com/hyperledger/besu/pull/3958)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
package org.hyperledger.besu.ethereum.eth.manager.task;

import static com.google.common.base.Preconditions.checkArgument;
import static org.hyperledger.besu.util.Slf4jLambdaHelper.traceLambda;

import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.eth.manager.EthContext;
Expand Down Expand Up @@ -90,9 +91,10 @@ protected Optional<List<BlockHeader>> processResponse(
return Optional.empty();
}

final List<BlockHeader> headersList = new ArrayList<>();
final List<BlockHeader> headersList = new ArrayList<>(headers.size());
headersList.add(firstHeader);
BlockHeader prevBlockHeader = firstHeader;
updatePeerChainState(peer, firstHeader);
final int expectedDelta = reverse ? -(skip + 1) : (skip + 1);
for (int i = 1; i < headers.size(); i++) {
final BlockHeader header = headers.get(i);
Expand All @@ -114,11 +116,24 @@ protected Optional<List<BlockHeader>> processResponse(
}
prevBlockHeader = header;
headersList.add(header);
updatePeerChainState(peer, header);
}

LOG.debug("Received {} of {} headers requested from peer {}", headersList.size(), count, peer);
return Optional.of(headersList);
}

private void updatePeerChainState(final EthPeer peer, final BlockHeader blockHeader) {
if (blockHeader.getNumber() > peer.chainState().getEstimatedHeight()) {
traceLambda(
LOG,
"Updating chain state for peer {} to block header {}",
peer::getShortNodeId,
blockHeader::toLogString);
peer.chainState().update(blockHeader);
}
LOG.trace("Peer chain state {}", peer.chainState());
}

protected abstract boolean matchesFirstHeader(BlockHeader firstHeader);
}
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,10 @@ protected final void executeTask() {
});
}

public PendingPeerRequest sendRequestToPeer(final PeerRequest request) {
return sendRequestToPeer(request, 0L);
}

public PendingPeerRequest sendRequestToPeer(
final PeerRequest request, final long minimumBlockNumber) {
return ethContext.getEthPeers().executePeerRequest(request, minimumBlockNumber, assignedPeer);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ private CompletableFuture<PeerTaskResult<List<BlockHeader>>> downloadHeader() {
hash.map(
value ->
GetHeadersFromPeerByHashTask.forSingleHash(
protocolSchedule, ethContext, value, blockNumber, metricsSystem))
protocolSchedule, ethContext, value, metricsSystem))
.orElseGet(
() ->
GetHeadersFromPeerByNumberTask.forSingleNumber(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,14 +82,12 @@ public static GetBodiesFromPeerTask forHeaders(
protected PendingPeerRequest sendRequest() {
final List<Hash> blockHashes =
headers.stream().map(BlockHeader::getHash).collect(Collectors.toList());
final long minimumRequiredBlockNumber = headers.get(headers.size() - 1).getNumber();

return sendRequestToPeer(
peer -> {
LOG.debug("Requesting {} bodies from peer {}.", blockHashes.size(), peer);
return peer.getBodies(blockHashes);
},
minimumRequiredBlockNumber);
});
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,20 +32,17 @@ public class GetHeadersFromPeerByHashTask extends AbstractGetHeadersFromPeerTask
private static final Logger LOG = LoggerFactory.getLogger(GetHeadersFromPeerByHashTask.class);

private final Hash referenceHash;
private final long minimumRequiredBlockNumber;

@VisibleForTesting
GetHeadersFromPeerByHashTask(
final ProtocolSchedule protocolSchedule,
final EthContext ethContext,
final Hash referenceHash,
final long minimumRequiredBlockNumber,
final int count,
final int skip,
final boolean reverse,
final MetricsSystem metricsSystem) {
super(protocolSchedule, ethContext, count, skip, reverse, metricsSystem);
this.minimumRequiredBlockNumber = minimumRequiredBlockNumber;
checkNotNull(referenceHash);
this.referenceHash = referenceHash;
}
Expand All @@ -54,65 +51,40 @@ public static AbstractGetHeadersFromPeerTask startingAtHash(
final ProtocolSchedule protocolSchedule,
final EthContext ethContext,
final Hash firstHash,
final long firstBlockNumber,
final int segmentLength,
final MetricsSystem metricsSystem) {
return new GetHeadersFromPeerByHashTask(
protocolSchedule,
ethContext,
firstHash,
firstBlockNumber,
segmentLength,
0,
false,
metricsSystem);
protocolSchedule, ethContext, firstHash, segmentLength, 0, false, metricsSystem);
}

public static AbstractGetHeadersFromPeerTask startingAtHash(
final ProtocolSchedule protocolSchedule,
final EthContext ethContext,
final Hash firstHash,
final long firstBlockNumber,
final int segmentLength,
final int skip,
final MetricsSystem metricsSystem) {
return new GetHeadersFromPeerByHashTask(
protocolSchedule,
ethContext,
firstHash,
firstBlockNumber,
segmentLength,
skip,
false,
metricsSystem);
protocolSchedule, ethContext, firstHash, segmentLength, skip, false, metricsSystem);
}

public static AbstractGetHeadersFromPeerTask endingAtHash(
final ProtocolSchedule protocolSchedule,
final EthContext ethContext,
final Hash lastHash,
final long lastBlockNumber,
final int segmentLength,
final MetricsSystem metricsSystem) {
return new GetHeadersFromPeerByHashTask(
protocolSchedule,
ethContext,
lastHash,
lastBlockNumber,
segmentLength,
0,
true,
metricsSystem);
protocolSchedule, ethContext, lastHash, segmentLength, 0, true, metricsSystem);
}

public static AbstractGetHeadersFromPeerTask forSingleHash(
final ProtocolSchedule protocolSchedule,
final EthContext ethContext,
final Hash hash,
final long minimumRequiredBlockNumber,
final MetricsSystem metricsSystem) {
return new GetHeadersFromPeerByHashTask(
protocolSchedule, ethContext, hash, minimumRequiredBlockNumber, 1, 0, false, metricsSystem);
protocolSchedule, ethContext, hash, 1, 0, false, metricsSystem);
}

@Override
Expand All @@ -121,8 +93,7 @@ protected PendingPeerRequest sendRequest() {
peer -> {
LOG.debug("Requesting {} headers from peer {}.", count, peer);
return peer.getHeadersByHash(referenceHash, count, skip, reverse);
},
minimumRequiredBlockNumber);
});
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,7 @@ protected PendingPeerRequest sendRequest() {
peer -> {
LOG.debug("Requesting {} headers from peer {}.", count, peer);
return peer.getHeadersByNumber(blockNumber, count, skip, reverse);
},
blockNumber);
});
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,20 +35,17 @@ public class RetryingGetHeadersEndingAtFromPeerByHashTask

private final Hash referenceHash;
private final ProtocolSchedule protocolSchedule;
private final long minimumRequiredBlockNumber;
private final int count;

@VisibleForTesting
RetryingGetHeadersEndingAtFromPeerByHashTask(
final ProtocolSchedule protocolSchedule,
final EthContext ethContext,
final Hash referenceHash,
final long minimumRequiredBlockNumber,
final int count,
final MetricsSystem metricsSystem) {
super(ethContext, 3, List::isEmpty, metricsSystem);
this.protocolSchedule = protocolSchedule;
this.minimumRequiredBlockNumber = minimumRequiredBlockNumber;
this.count = count;
checkNotNull(referenceHash);
this.referenceHash = referenceHash;
Expand All @@ -58,29 +55,18 @@ public static RetryingGetHeadersEndingAtFromPeerByHashTask endingAtHash(
final ProtocolSchedule protocolSchedule,
final EthContext ethContext,
final Hash referenceHash,
final long minimumRequiredBlockNumber,
final int count,
final MetricsSystem metricsSystem) {
return new RetryingGetHeadersEndingAtFromPeerByHashTask(
protocolSchedule,
ethContext,
referenceHash,
minimumRequiredBlockNumber,
count,
metricsSystem);
protocolSchedule, ethContext, referenceHash, count, metricsSystem);
}

@Override
protected CompletableFuture<List<BlockHeader>> executePeerTask(
final Optional<EthPeer> assignedPeer) {
final AbstractGetHeadersFromPeerTask task =
GetHeadersFromPeerByHashTask.endingAtHash(
protocolSchedule,
getEthContext(),
referenceHash,
minimumRequiredBlockNumber,
count,
getMetricsSystem());
protocolSchedule, getEthContext(), referenceHash, count, getMetricsSystem());
assignedPeer.ifPresent(task::assignPeer);
return executeSubTask(task::run)
.thenApply(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@ public void onPeerConnected(final EthPeer peer) {
protocolSchedule,
ethContext,
Hash.wrap(peer.chainState().getBestBlock().getHash()),
0,
metricsSystem)
.assignPeer(peer)
.run()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,6 @@ private CompletableFuture<List<BlockHeader>> downloadHeaders(final SyncTargetRan
protocolSchedule,
ethContext,
range.getStart().getHash(),
range.getStart().getNumber(),
headerRequestSize,
metricsSystem)
.assignPeer(range.getSyncTarget())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,20 +62,13 @@ protected Hash possibleRestoreOldNodes(final BlockHeader firstAncestor) {
protected CompletableFuture<List<BlockHeader>> requestHeaders(final Hash hash) {
final int batchSize = context.getBatchSize();
debugLambda(LOG, "Requesting header for hash {}", hash::toHexString);
final Optional<BlockHeader> maybeFinalizedHeader =
context
.getProtocolContext()
.getBlockchain()
.getFinalized()
.flatMap(context.getProtocolContext().getBlockchain()::getBlockHeader);

final RetryingGetHeadersEndingAtFromPeerByHashTask
retryingGetHeadersEndingAtFromPeerByHashTask =
RetryingGetHeadersEndingAtFromPeerByHashTask.endingAtHash(
context.getProtocolSchedule(),
context.getEthContext(),
hash,
maybeFinalizedHeader.map(BlockHeader::getNumber).orElse(0L),
batchSize,
context.getMetricsSystem());
return context
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -253,11 +253,7 @@ public ChainDownloader createChainDownloader(final FastSyncState currentState) {

private CompletableFuture<FastSyncState> downloadPivotBlockHeader(final Hash hash) {
return RetryingGetHeaderFromPeerByHashTask.byHash(
protocolSchedule,
ethContext,
hash,
pivotBlockSelector.getMinRequiredBlockNumber(),
metricsSystem)
protocolSchedule, ethContext, hash, metricsSystem)
.getHeader()
.thenApply(
blockHeader -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,6 @@ private CompletableFuture<List<BlockHeader>> requestHeaders(
protocolSchedule,
ethContext,
referenceHeader.getHash(),
referenceHeader.getNumber(),
// + 1 because lastHeader will be returned as well.
headerCount + 1,
skip,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,12 +166,7 @@ private CompletableFuture<PeerTaskResult<List<BlockHeader>>> downloadHeaders(
// Ask for count + 1 because we'll retrieve the previous header as well
final AbstractGetHeadersFromPeerTask headersTask =
GetHeadersFromPeerByHashTask.endingAtHash(
protocolSchedule,
ethContext,
referenceHash,
referenceHeaderForNextRequest.getNumber(),
count + 1,
metricsSystem);
protocolSchedule, ethContext, referenceHash, count + 1, metricsSystem);
assignedPeer.ifPresent(headersTask::assignPeer);
return headersTask.run();
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,18 +37,15 @@ public class RetryingGetHeaderFromPeerByHashTask

private final Hash referenceHash;
private final ProtocolSchedule protocolSchedule;
private final long minimumRequiredBlockNumber;

@VisibleForTesting
RetryingGetHeaderFromPeerByHashTask(
final ProtocolSchedule protocolSchedule,
final EthContext ethContext,
final Hash referenceHash,
final long minimumRequiredBlockNumber,
final MetricsSystem metricsSystem) {
super(ethContext, 3, List::isEmpty, metricsSystem);
this.protocolSchedule = protocolSchedule;
this.minimumRequiredBlockNumber = minimumRequiredBlockNumber;
checkNotNull(referenceHash);
this.referenceHash = referenceHash;
}
Expand All @@ -57,22 +54,17 @@ public static RetryingGetHeaderFromPeerByHashTask byHash(
final ProtocolSchedule protocolSchedule,
final EthContext ethContext,
final Hash referenceHash,
final long minimumRequiredBlockNumber,
final MetricsSystem metricsSystem) {
return new RetryingGetHeaderFromPeerByHashTask(
protocolSchedule, ethContext, referenceHash, minimumRequiredBlockNumber, metricsSystem);
protocolSchedule, ethContext, referenceHash, metricsSystem);
}

@Override
protected CompletableFuture<List<BlockHeader>> executePeerTask(
final Optional<EthPeer> assignedPeer) {
final AbstractGetHeadersFromPeerTask task =
GetHeadersFromPeerByHashTask.forSingleHash(
protocolSchedule,
getEthContext(),
referenceHash,
minimumRequiredBlockNumber,
getMetricsSystem());
protocolSchedule, getEthContext(), referenceHash, getMetricsSystem());
assignedPeer.ifPresent(task::assignPeer);
return executeSubTask(task::run)
.thenApply(
Expand Down
Loading

0 comments on commit 261b1e0

Please sign in to comment.