diff --git a/besu/src/main/java/org/hyperledger/besu/controller/QbftBesuControllerBuilder.java b/besu/src/main/java/org/hyperledger/besu/controller/QbftBesuControllerBuilder.java index 3d3412d4860..aec03ec7ee5 100644 --- a/besu/src/main/java/org/hyperledger/besu/controller/QbftBesuControllerBuilder.java +++ b/besu/src/main/java/org/hyperledger/besu/controller/QbftBesuControllerBuilder.java @@ -295,9 +295,18 @@ protected MiningCoordinator createMiningCoordinator( .getValue() .getBlockPeriodSeconds())); - if (syncState.isInitialSyncPhaseDone()) { - miningCoordinator.enable(); - } + syncState.subscribeSyncStatus( + syncStatus -> { + if (syncState.syncTarget().isPresent()) { + // We're syncing so stop doing other stuff + LOG.info("Stopping QBFT mining coordinator while we are syncing"); + miningCoordinator.stop(); + } else { + LOG.info("Starting QBFT mining coordinator following sync"); + miningCoordinator.enable(); + miningCoordinator.start(); + } + }); syncState.subscribeCompletionReached( new BesuEvents.InitialSyncCompletionListener() { diff --git a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/BftEventQueue.java b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/BftEventQueue.java index 4221fd1fac7..eec41ed4e9c 100644 --- a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/BftEventQueue.java +++ b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/BftEventQueue.java @@ -48,6 +48,11 @@ public void start() { started.set(true); } + /** Stop the event queue. Until it has been started no events will be queued for processing. */ + public void stop() { + started.set(false); + } + private boolean isStarted() { return started.get(); } diff --git a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/BftExecutors.java b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/BftExecutors.java index 30038add3d4..709d65faaad 100644 --- a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/BftExecutors.java +++ b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/BftExecutors.java @@ -78,7 +78,7 @@ public static BftExecutors create( /** Start. */ public synchronized void start() { - if (state != State.IDLE) { + if (state != State.IDLE && state != State.STOPPED) { // Nothing to do return; } diff --git a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/BftProcessor.java b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/BftProcessor.java index 93df77ea778..8834a30b2e4 100644 --- a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/BftProcessor.java +++ b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/BftProcessor.java @@ -44,8 +44,13 @@ public BftProcessor(final BftEventQueue incomingQueue, final EventMultiplexer ev this.eventMultiplexer = eventMultiplexer; } + /** Indicate to the processor that it should can be started */ + public synchronized void start() { + shutdown = false; + } + /** Indicate to the processor that it should gracefully stop at its next opportunity */ - public void stop() { + public synchronized void stop() { shutdown = true; } @@ -67,6 +72,8 @@ public void run() { while (!shutdown) { nextEvent().ifPresent(eventMultiplexer::handleBftEvent); } + + incomingQueue.stop(); } catch (final Throwable t) { LOG.error("BFT Mining thread has suffered a fatal error, mining has been halted", t); } diff --git a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/blockcreation/BftMiningCoordinator.java b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/blockcreation/BftMiningCoordinator.java index 83cd61beb31..f5f31a3326b 100644 --- a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/blockcreation/BftMiningCoordinator.java +++ b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/blockcreation/BftMiningCoordinator.java @@ -93,7 +93,9 @@ public BftMiningCoordinator( @Override public void start() { - if (state.compareAndSet(State.IDLE, State.RUNNING)) { + if (state.compareAndSet(State.IDLE, State.RUNNING) + || state.compareAndSet(State.STOPPED, State.RUNNING)) { + bftProcessor.start(); bftExecutors.start(); blockAddedObserverId = blockchain.observeBlockAdded(this); eventHandler.start(); @@ -110,7 +112,7 @@ public void stop() { try { bftProcessor.awaitStop(); } catch (final InterruptedException e) { - LOG.debug("Interrupted while waiting for IbftProcessor to stop.", e); + LOG.debug("Interrupted while waiting for BftProcessor to stop.", e); Thread.currentThread().interrupt(); } bftExecutors.stop(); @@ -135,6 +137,11 @@ public boolean enable() { @Override public boolean disable() { + if (state.get() == State.PAUSED + || state.compareAndSet(State.IDLE, State.PAUSED) + || state.compareAndSet(State.RUNNING, State.PAUSED)) { + return true; + } return false; }