mirror of
https://github.com/vacp2p/linea-besu.git
synced 2026-01-08 04:33:56 -05:00
Add a fallback pivot strategy when the safe block does not change for a long time (#8395)
Signed-off-by: Fabio Di Fabio <fabio.difabio@consensys.net>
This commit is contained in:
@@ -44,6 +44,7 @@
|
||||
|
||||
### Bug fixes
|
||||
- Add missing RPC method `debug_accountRange` to `RpcMethod.java` so this method can be used with `--rpc-http-api-method-no-auth` [#8153](https://github.com/hyperledger/besu/issues/8153)
|
||||
- Add a fallback pivot strategy when the safe block does not change for a long time, to make possible to complete the initial sync in case the chain is not finalizing [#8395](https://github.com/hyperledger/besu/pull/8395)
|
||||
|
||||
## 25.2.2 hotfix
|
||||
- Pectra - Sepolia: Fix for deposit contract log decoding [#8383](https://github.com/hyperledger/besu/pull/8383)
|
||||
|
||||
@@ -29,6 +29,7 @@ import org.hyperledger.besu.ethereum.eth.sync.tasks.RetryingGetHeaderFromPeerByH
|
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
|
||||
import org.hyperledger.besu.plugin.services.MetricsSystem;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
@@ -41,6 +42,9 @@ import org.slf4j.LoggerFactory;
|
||||
public class PivotSelectorFromSafeBlock implements PivotBlockSelector {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(PivotSelectorFromSafeBlock.class);
|
||||
private static final long NO_FCU_RECEIVED_LOGGING_THRESHOLD = Duration.ofMinutes(1).toMillis();
|
||||
private static final long UNCHANGED_PIVOT_BLOCK_FALLBACK_INTERVAL =
|
||||
Duration.ofMinutes(7).toMillis();
|
||||
private final ProtocolContext protocolContext;
|
||||
private final ProtocolSchedule protocolSchedule;
|
||||
private final EthContext ethContext;
|
||||
@@ -50,8 +54,12 @@ public class PivotSelectorFromSafeBlock implements PivotBlockSelector {
|
||||
private final Supplier<Optional<ForkchoiceEvent>> forkchoiceStateSupplier;
|
||||
private final Runnable cleanupAction;
|
||||
|
||||
private long lastNoFcuReceivedInfoLog = System.currentTimeMillis();
|
||||
private static final long NO_FCU_RECEIVED_LOGGING_THRESHOLD = 60000L;
|
||||
private volatile long lastNoFcuReceivedInfoLog = System.currentTimeMillis();
|
||||
private volatile long lastPivotBlockChange = System.currentTimeMillis();
|
||||
private volatile Hash lastSafeBlockHash = Hash.ZERO;
|
||||
private volatile Hash fallbackBlockHash;
|
||||
private volatile Hash lastFallbackBlockHash;
|
||||
private volatile boolean inFallbackMode = false;
|
||||
private volatile Optional<BlockHeader> maybeCachedHeadBlockHeader = Optional.empty();
|
||||
|
||||
public PivotSelectorFromSafeBlock(
|
||||
@@ -76,11 +84,38 @@ public class PivotSelectorFromSafeBlock implements PivotBlockSelector {
|
||||
@Override
|
||||
public Optional<FastSyncState> selectNewPivotBlock() {
|
||||
final Optional<ForkchoiceEvent> maybeForkchoice = forkchoiceStateSupplier.get();
|
||||
final var now = System.currentTimeMillis();
|
||||
|
||||
if (maybeForkchoice.isPresent() && maybeForkchoice.get().hasValidSafeBlockHash()) {
|
||||
return Optional.of(selectLastSafeBlockAsPivot(maybeForkchoice.get().getSafeBlockHash()));
|
||||
final var safeBlockHash = maybeForkchoice.get().getSafeBlockHash();
|
||||
|
||||
// if the safe has changed just return it and reset the timer and save the current head as
|
||||
// fallback
|
||||
if (!safeBlockHash.equals(lastSafeBlockHash)) {
|
||||
lastSafeBlockHash = safeBlockHash;
|
||||
lastPivotBlockChange = now;
|
||||
inFallbackMode = false;
|
||||
fallbackBlockHash = maybeForkchoice.get().getHeadBlockHash();
|
||||
return Optional.of(selectLastSafeBlockAsPivot(safeBlockHash));
|
||||
}
|
||||
|
||||
// otherwise verify if we need to fallback to a previous head block
|
||||
if (lastPivotBlockChange + UNCHANGED_PIVOT_BLOCK_FALLBACK_INTERVAL < now) {
|
||||
lastPivotBlockChange = now;
|
||||
inFallbackMode = true;
|
||||
lastFallbackBlockHash = fallbackBlockHash;
|
||||
final var fallbackPivot = selectFallbackBlockAsPivot(fallbackBlockHash);
|
||||
fallbackBlockHash = maybeForkchoice.get().getHeadBlockHash();
|
||||
return Optional.of(fallbackPivot);
|
||||
}
|
||||
|
||||
// if not enough time has passed the return again the previous value
|
||||
return Optional.of(
|
||||
selectLastSafeBlockAsPivot(inFallbackMode ? lastFallbackBlockHash : lastSafeBlockHash));
|
||||
}
|
||||
if (lastNoFcuReceivedInfoLog + NO_FCU_RECEIVED_LOGGING_THRESHOLD < System.currentTimeMillis()) {
|
||||
lastNoFcuReceivedInfoLog = System.currentTimeMillis();
|
||||
|
||||
if (lastNoFcuReceivedInfoLog + NO_FCU_RECEIVED_LOGGING_THRESHOLD < now) {
|
||||
lastNoFcuReceivedInfoLog = now;
|
||||
LOG.info(
|
||||
"Waiting for consensus client, this may be because your consensus client is still syncing");
|
||||
}
|
||||
@@ -99,6 +134,14 @@ public class PivotSelectorFromSafeBlock implements PivotBlockSelector {
|
||||
return new FastSyncState(safeHash);
|
||||
}
|
||||
|
||||
private FastSyncState selectFallbackBlockAsPivot(final Hash fallbackBlockHash) {
|
||||
LOG.debug(
|
||||
"Safe block not changed in the last {} min, using a previous head block {} as fallback",
|
||||
UNCHANGED_PIVOT_BLOCK_FALLBACK_INTERVAL / 60,
|
||||
fallbackBlockHash);
|
||||
return new FastSyncState(fallbackBlockHash);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
cleanupAction.run();
|
||||
@@ -188,7 +231,7 @@ public class PivotSelectorFromSafeBlock implements PivotBlockSelector {
|
||||
LOG.debug("Error downloading block header by hash {}", hash);
|
||||
} else {
|
||||
LOG.atDebug()
|
||||
.setMessage("Successfully downloaded pivot block header by hash {}")
|
||||
.setMessage("Successfully downloaded block header by hash {}")
|
||||
.addArgument(blockHeader::toLogString)
|
||||
.log();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user