Cleanup: Synchronizer is always present in protocol context (#7791)

Signed-off-by: Fabio Di Fabio <fabio.difabio@consensys.net>
pull/7813/head
Fabio Di Fabio 4 weeks ago committed by GitHub
parent 71906fa9d4
commit 516559fadc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 2
      besu/src/main/java/org/hyperledger/besu/controller/BesuControllerBuilder.java
  2. 2
      consensus/merge/src/test/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeCoordinatorTest.java
  3. 11
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/MainnetBlockValidator.java
  4. 8
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/ProtocolContext.java
  5. 17
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Synchronizer.java
  6. 1
      ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/BlockchainSetupUtil.java
  7. 13
      ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/DummySynchronizer.java
  8. 2
      ethereum/core/src/test/java/org/hyperledger/besu/ethereum/MainnetBlockValidatorTest.java
  9. 14
      ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/snap/SnapServer.java
  10. 2
      ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/DefaultSynchronizer.java
  11. 1
      ethereum/retesteth/build.gradle
  12. 1
      ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/RetestethService.java

@ -717,7 +717,7 @@ public abstract class BesuControllerBuilder implements MiningParameterOverrides
ethPeers.snapServerPeersNeeded(false); ethPeers.snapServerPeersNeeded(false);
} }
protocolContext.setSynchronizer(Optional.of(synchronizer)); protocolContext.setSynchronizer(synchronizer);
final Optional<SnapProtocolManager> maybeSnapProtocolManager = final Optional<SnapProtocolManager> maybeSnapProtocolManager =
createSnapProtocolManager( createSnapProtocolManager(

@ -59,6 +59,7 @@ import org.hyperledger.besu.ethereum.core.ImmutableMiningParameters;
import org.hyperledger.besu.ethereum.core.ImmutableMiningParameters.MutableInitValues; import org.hyperledger.besu.ethereum.core.ImmutableMiningParameters.MutableInitValues;
import org.hyperledger.besu.ethereum.core.ImmutableMiningParameters.Unstable; import org.hyperledger.besu.ethereum.core.ImmutableMiningParameters.Unstable;
import org.hyperledger.besu.ethereum.core.MiningParameters; import org.hyperledger.besu.ethereum.core.MiningParameters;
import org.hyperledger.besu.ethereum.core.Synchronizer;
import org.hyperledger.besu.ethereum.core.TransactionTestFixture; import org.hyperledger.besu.ethereum.core.TransactionTestFixture;
import org.hyperledger.besu.ethereum.eth.manager.EthContext; import org.hyperledger.besu.ethereum.eth.manager.EthContext;
import org.hyperledger.besu.ethereum.eth.manager.EthScheduler; import org.hyperledger.besu.ethereum.eth.manager.EthScheduler;
@ -189,6 +190,7 @@ public class MergeCoordinatorTest implements MergeGenesisConfigHelper {
protocolContext = protocolContext =
new ProtocolContext(blockchain, worldStateArchive, mergeContext, badBlockManager); new ProtocolContext(blockchain, worldStateArchive, mergeContext, badBlockManager);
protocolContext.setSynchronizer(mock(Synchronizer.class));
var mutable = worldStateArchive.getMutable(); var mutable = worldStateArchive.getMutable();
genesisState.writeStateTo(mutable); genesisState.writeStateTo(mutable);
mutable.persist(null); mutable.persist(null);

@ -181,16 +181,7 @@ public class MainnetBlockValidator implements BlockValidator {
Optional.of(new BlockProcessingOutputs(worldState, receipts, maybeRequests))); Optional.of(new BlockProcessingOutputs(worldState, receipts, maybeRequests)));
} }
} catch (MerkleTrieException ex) { } catch (MerkleTrieException ex) {
context context.getSynchronizer().healWorldState(ex.getMaybeAddress(), ex.getLocation());
.getSynchronizer()
.ifPresentOrElse(
synchronizer -> synchronizer.healWorldState(ex.getMaybeAddress(), ex.getLocation()),
() ->
handleFailedBlockProcessing(
block,
new BlockProcessingResult(Optional.empty(), ex),
// Do not record bad black due to missing data
false));
return new BlockProcessingResult(Optional.empty(), ex); return new BlockProcessingResult(Optional.empty(), ex);
} catch (StorageException ex) { } catch (StorageException ex) {
var retval = new BlockProcessingResult(Optional.empty(), ex); var retval = new BlockProcessingResult(Optional.empty(), ex);

@ -32,8 +32,7 @@ public class ProtocolContext {
private final WorldStateArchive worldStateArchive; private final WorldStateArchive worldStateArchive;
private final BadBlockManager badBlockManager; private final BadBlockManager badBlockManager;
private final ConsensusContext consensusContext; private final ConsensusContext consensusContext;
private Synchronizer synchronizer;
private Optional<Synchronizer> synchronizer;
/** /**
* Constructs a new ProtocolContext with the given blockchain, world state archive, consensus * Constructs a new ProtocolContext with the given blockchain, world state archive, consensus
@ -52,7 +51,6 @@ public class ProtocolContext {
this.blockchain = blockchain; this.blockchain = blockchain;
this.worldStateArchive = worldStateArchive; this.worldStateArchive = worldStateArchive;
this.consensusContext = consensusContext; this.consensusContext = consensusContext;
this.synchronizer = Optional.empty();
this.badBlockManager = badBlockManager; this.badBlockManager = badBlockManager;
} }
@ -85,7 +83,7 @@ public class ProtocolContext {
* *
* @return the synchronizer of the protocol context * @return the synchronizer of the protocol context
*/ */
public Optional<Synchronizer> getSynchronizer() { public Synchronizer getSynchronizer() {
return synchronizer; return synchronizer;
} }
@ -94,7 +92,7 @@ public class ProtocolContext {
* *
* @param synchronizer the synchronizer to set * @param synchronizer the synchronizer to set
*/ */
public void setSynchronizer(final Optional<Synchronizer> synchronizer) { public void setSynchronizer(final Synchronizer synchronizer) {
this.synchronizer = synchronizer; this.synchronizer = synchronizer;
} }

@ -17,6 +17,7 @@ package org.hyperledger.besu.ethereum.core;
import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.plugin.data.SyncStatus; import org.hyperledger.besu.plugin.data.SyncStatus;
import org.hyperledger.besu.plugin.services.BesuEvents; import org.hyperledger.besu.plugin.services.BesuEvents;
import org.hyperledger.besu.plugin.services.BesuEvents.InitialSyncCompletionListener;
import java.util.Optional; import java.util.Optional;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
@ -82,6 +83,22 @@ public interface Synchronizer {
*/ */
boolean unsubscribeInSync(final long listenerId); boolean unsubscribeInSync(final long listenerId);
/**
* Add a listener that will be notified when this node initial sync status changes.
*
* @param listener The callback to invoke when the initial sync status changes
* @return A subscription id that can be used to unsubscribe from these events
*/
long subscribeInitialSync(final InitialSyncCompletionListener listener);
/**
* Unsubscribe from initial sync events.
*
* @param listenerId The id returned when subscribing
* @return {@code true} if a subscription was cancelled
*/
boolean unsubscribeInitialSync(final long listenerId);
@FunctionalInterface @FunctionalInterface
interface InSyncListener { interface InSyncListener {
void onInSyncStatusChange(boolean newSyncStatus); void onInSyncStatusChange(boolean newSyncStatus);

@ -194,6 +194,7 @@ public class BlockchainSetupUtil {
genesisState.writeStateTo(worldArchive.getMutable()); genesisState.writeStateTo(worldArchive.getMutable());
final ProtocolContext protocolContext = protocolContextProvider.get(blockchain, worldArchive); final ProtocolContext protocolContext = protocolContextProvider.get(blockchain, worldArchive);
protocolContext.setSynchronizer(new DummySynchronizer());
final Path blocksPath = Path.of(chainResources.getBlocksURL().toURI()); final Path blocksPath = Path.of(chainResources.getBlocksURL().toURI());
final List<Block> blocks = new ArrayList<>(); final List<Block> blocks = new ArrayList<>();

@ -12,10 +12,9 @@
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
package org.hyperledger.besu.ethereum.retesteth; package org.hyperledger.besu.ethereum.core;
import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.ethereum.core.Synchronizer;
import org.hyperledger.besu.plugin.data.SyncStatus; import org.hyperledger.besu.plugin.data.SyncStatus;
import org.hyperledger.besu.plugin.services.BesuEvents; import org.hyperledger.besu.plugin.services.BesuEvents;
@ -81,4 +80,14 @@ public class DummySynchronizer implements Synchronizer {
public boolean unsubscribeInSync(final long listenerId) { public boolean unsubscribeInSync(final long listenerId) {
return false; return false;
} }
@Override
public long subscribeInitialSync(final BesuEvents.InitialSyncCompletionListener listener) {
return 0;
}
@Override
public boolean unsubscribeInitialSync(final long listenerId) {
return false;
}
} }

@ -31,6 +31,7 @@ import org.hyperledger.besu.ethereum.core.Block;
import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.BlockchainSetupUtil; import org.hyperledger.besu.ethereum.core.BlockchainSetupUtil;
import org.hyperledger.besu.ethereum.core.MutableWorldState; import org.hyperledger.besu.ethereum.core.MutableWorldState;
import org.hyperledger.besu.ethereum.core.Synchronizer;
import org.hyperledger.besu.ethereum.mainnet.BlockBodyValidator; import org.hyperledger.besu.ethereum.mainnet.BlockBodyValidator;
import org.hyperledger.besu.ethereum.mainnet.BlockHeaderValidator; import org.hyperledger.besu.ethereum.mainnet.BlockHeaderValidator;
import org.hyperledger.besu.ethereum.mainnet.BlockProcessor; import org.hyperledger.besu.ethereum.mainnet.BlockProcessor;
@ -90,6 +91,7 @@ public class MainnetBlockValidatorTest {
when(protocolContext.getBlockchain()).thenReturn(blockchain); when(protocolContext.getBlockchain()).thenReturn(blockchain);
when(protocolContext.getWorldStateArchive()).thenReturn(worldStateArchive); when(protocolContext.getWorldStateArchive()).thenReturn(worldStateArchive);
when(protocolContext.getSynchronizer()).thenReturn(mock(Synchronizer.class));
when(worldStateArchive.getMutable(any(BlockHeader.class), anyBoolean())) when(worldStateArchive.getMutable(any(BlockHeader.class), anyBoolean()))
.thenReturn(Optional.of(worldState)); .thenReturn(Optional.of(worldState));
when(worldStateArchive.getMutable(any(Hash.class), any(Hash.class))) when(worldStateArchive.getMutable(any(Hash.class), any(Hash.class)))

@ -26,7 +26,6 @@ import org.hyperledger.besu.ethereum.eth.messages.snap.GetTrieNodesMessage;
import org.hyperledger.besu.ethereum.eth.messages.snap.SnapV1; import org.hyperledger.besu.ethereum.eth.messages.snap.SnapV1;
import org.hyperledger.besu.ethereum.eth.messages.snap.StorageRangeMessage; import org.hyperledger.besu.ethereum.eth.messages.snap.StorageRangeMessage;
import org.hyperledger.besu.ethereum.eth.messages.snap.TrieNodesMessage; import org.hyperledger.besu.ethereum.eth.messages.snap.TrieNodesMessage;
import org.hyperledger.besu.ethereum.eth.sync.DefaultSynchronizer;
import org.hyperledger.besu.ethereum.eth.sync.snapsync.SnapSyncConfiguration; import org.hyperledger.besu.ethereum.eth.sync.snapsync.SnapSyncConfiguration;
import org.hyperledger.besu.ethereum.p2p.rlpx.wire.MessageData; import org.hyperledger.besu.ethereum.p2p.rlpx.wire.MessageData;
import org.hyperledger.besu.ethereum.proof.WorldStateProofProvider; import org.hyperledger.besu.ethereum.proof.WorldStateProofProvider;
@ -49,7 +48,6 @@ import java.util.NavigableMap;
import java.util.Optional; import java.util.Optional;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Function; import java.util.function.Function;
import java.util.function.Predicate; import java.util.function.Predicate;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -84,7 +82,6 @@ class SnapServer implements BesuEvents.InitialSyncCompletionListener {
static final Hash HASH_LAST = Hash.wrap(Bytes32.leftPad(Bytes.fromHexString("FF"), (byte) 0xFF)); static final Hash HASH_LAST = Hash.wrap(Bytes32.leftPad(Bytes.fromHexString("FF"), (byte) 0xFF));
private final AtomicBoolean isStarted = new AtomicBoolean(false); private final AtomicBoolean isStarted = new AtomicBoolean(false);
private final AtomicLong listenerId = new AtomicLong();
private final EthMessages snapMessages; private final EthMessages snapMessages;
private final WorldStateStorageCoordinator worldStateStorageCoordinator; private final WorldStateStorageCoordinator worldStateStorageCoordinator;
@ -111,14 +108,9 @@ class SnapServer implements BesuEvents.InitialSyncCompletionListener {
this.protocolContext = Optional.of(protocolContext); this.protocolContext = Optional.of(protocolContext);
registerResponseConstructors(); registerResponseConstructors();
// subscribe to initial sync completed events to start/stop snap server: // subscribe to initial sync completed events to start/stop snap server,
this.protocolContext // not saving the listenerId since we never need to unsubscribe.
.flatMap(ProtocolContext::getSynchronizer) protocolContext.getSynchronizer().subscribeInitialSync(this);
.filter(z -> z instanceof DefaultSynchronizer)
.map(DefaultSynchronizer.class::cast)
.ifPresentOrElse(
z -> this.listenerId.set(z.subscribeInitialSync(this)),
() -> LOGGER.warn("SnapServer created without reference to sync status"));
} }
/** /**

@ -388,10 +388,12 @@ public class DefaultSynchronizer implements Synchronizer, UnverifiedForkchoiceLi
return syncState.unsubscribeSyncStatus(listenerId); return syncState.unsubscribeSyncStatus(listenerId);
} }
@Override
public long subscribeInitialSync(final BesuEvents.InitialSyncCompletionListener listener) { public long subscribeInitialSync(final BesuEvents.InitialSyncCompletionListener listener) {
return syncState.subscribeCompletionReached(listener); return syncState.subscribeCompletionReached(listener);
} }
@Override
public boolean unsubscribeInitialSync(final long listenerId) { public boolean unsubscribeInitialSync(final long listenerId) {
return syncState.unsubscribeInitialConditionReached(listenerId); return syncState.unsubscribeInitialConditionReached(listenerId);
} }

@ -35,6 +35,7 @@ dependencies {
implementation project(':ethereum:api') implementation project(':ethereum:api')
implementation project(':ethereum:blockcreation') implementation project(':ethereum:blockcreation')
implementation project(':ethereum:core') implementation project(':ethereum:core')
implementation project(path: ':ethereum:core', configuration: 'testSupportArtifacts')
implementation project(':ethereum:eth') implementation project(':ethereum:eth')
implementation project(':ethereum:p2p') implementation project(':ethereum:p2p')
implementation project(':ethereum:rlp') implementation project(':ethereum:rlp')

@ -30,6 +30,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.EthSendRawTran
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.Web3ClientVersion; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.Web3ClientVersion;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.BlockResultFactory; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.BlockResultFactory;
import org.hyperledger.besu.ethereum.core.DummySynchronizer;
import org.hyperledger.besu.ethereum.core.Synchronizer; import org.hyperledger.besu.ethereum.core.Synchronizer;
import org.hyperledger.besu.ethereum.retesteth.methods.TestGetLogHash; import org.hyperledger.besu.ethereum.retesteth.methods.TestGetLogHash;
import org.hyperledger.besu.ethereum.retesteth.methods.TestImportRawBlock; import org.hyperledger.besu.ethereum.retesteth.methods.TestImportRawBlock;

Loading…
Cancel
Save