Release 22.4.3 (#3978)

* reverts disconnect of pow network
* updates gav coords to 22.4.3

Signed-off-by: Justin Florentine <justin+github@florentine.us>
pull/3979/head 22.4.3
Justin Florentine 2 years ago committed by GitHub
parent 5e32b05037
commit 963da3d7ac
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 54
      besu/src/main/java/org/hyperledger/besu/controller/BesuControllerBuilder.java
  2. 80
      besu/src/main/java/org/hyperledger/besu/controller/TransitionBesuControllerBuilder.java
  3. 1
      consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/FinalizedBlockHashSupplier.java
  4. 11
      consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/MergeContext.java
  5. 8
      consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/PostMergeContext.java
  6. 6
      consensus/merge/src/test/java/org/hyperledger/besu/consensus/merge/PostMergeContextTest.java
  7. 28
      ethereum/eth/src/main/java/org/hyperledger/besu/consensus/merge/NewForkchoiceMessageListener.java
  8. 26
      ethereum/eth/src/main/java/org/hyperledger/besu/consensus/merge/NewMergeStateCallback.java
  9. 94
      ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/EthProtocolManager.java
  10. 24
      ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/DefaultSynchronizer.java
  11. 129
      ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/EthProtocolManagerTest.java
  12. 2
      gradle.properties

@ -98,7 +98,6 @@ import java.util.Optional;
import java.util.OptionalLong; import java.util.OptionalLong;
import java.util.function.Supplier; import java.util.function.Supplier;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -360,15 +359,11 @@ public abstract class BesuControllerBuilder implements MiningParameterOverrides
Optional.of( Optional.of(
ImmutableCheckpoint.builder() ImmutableCheckpoint.builder()
.blockHash( .blockHash(
Hash.fromHexString( Hash.fromHexString(configOptions.getCheckpointOptions().getHash().get()))
configOptions.getCheckpointOptions().getHash().get())) // NOSONAR
.blockNumber(configOptions.getCheckpointOptions().getNumber().getAsLong()) .blockNumber(configOptions.getCheckpointOptions().getNumber().getAsLong())
.totalDifficulty( .totalDifficulty(
Difficulty.fromHexString( Difficulty.fromHexString(
configOptions configOptions.getCheckpointOptions().getTotalDifficulty().get()))
.getCheckpointOptions()
.getTotalDifficulty()
.get())) // NOSONAR
.build()); .build());
} }
@ -408,14 +403,19 @@ public abstract class BesuControllerBuilder implements MiningParameterOverrides
final PivotBlockSelector pivotBlockSelector = createPivotSelector(protocolContext); final PivotBlockSelector pivotBlockSelector = createPivotSelector(protocolContext);
final Synchronizer synchronizer = final Synchronizer synchronizer =
createSynchronizer( new DefaultSynchronizer(
syncConfig,
protocolSchedule, protocolSchedule,
worldStateStorage,
protocolContext, protocolContext,
worldStateStorage,
ethProtocolManager.getBlockBroadcaster(),
maybePruner, maybePruner,
ethContext, ethContext,
syncState, syncState,
ethProtocolManager, dataDirectory,
clock,
metricsSystem,
getFullSyncTerminationCondition(protocolContext.getBlockchain()),
pivotBlockSelector); pivotBlockSelector);
final MiningCoordinator miningCoordinator = final MiningCoordinator miningCoordinator =
@ -432,6 +432,7 @@ public abstract class BesuControllerBuilder implements MiningParameterOverrides
final SubProtocolConfiguration subProtocolConfiguration = final SubProtocolConfiguration subProtocolConfiguration =
createSubProtocolConfiguration(ethProtocolManager, maybeSnapProtocolManager); createSubProtocolConfiguration(ethProtocolManager, maybeSnapProtocolManager);
;
final JsonRpcMethods additionalJsonRpcMethodFactory = final JsonRpcMethods additionalJsonRpcMethodFactory =
createAdditionalJsonRpcMethodFactory(protocolContext); createAdditionalJsonRpcMethodFactory(protocolContext);
@ -460,32 +461,6 @@ public abstract class BesuControllerBuilder implements MiningParameterOverrides
additionalPluginServices); additionalPluginServices);
} }
@NotNull
protected DefaultSynchronizer createSynchronizer(
final ProtocolSchedule protocolSchedule,
final WorldStateStorage worldStateStorage,
final ProtocolContext protocolContext,
final Optional<Pruner> maybePruner,
final EthContext ethContext,
final SyncState syncState,
final EthProtocolManager ethProtocolManager,
final PivotBlockSelector pivotBlockSelector) {
return new DefaultSynchronizer(
syncConfig,
protocolSchedule,
protocolContext,
worldStateStorage,
ethProtocolManager.getBlockBroadcaster(),
maybePruner,
ethContext,
syncState,
dataDirectory,
clock,
metricsSystem,
getFullSyncTerminationCondition(protocolContext.getBlockchain()),
pivotBlockSelector);
}
private PivotBlockSelector createPivotSelector(final ProtocolContext protocolContext) { private PivotBlockSelector createPivotSelector(final ProtocolContext protocolContext) {
final PivotSelectorFromPeers pivotSelectorFromPeers = new PivotSelectorFromPeers(syncConfig); final PivotSelectorFromPeers pivotSelectorFromPeers = new PivotSelectorFromPeers(syncConfig);
@ -532,7 +507,7 @@ public abstract class BesuControllerBuilder implements MiningParameterOverrides
protected void prepForBuild() {} protected void prepForBuild() {}
protected JsonRpcMethods createAdditionalJsonRpcMethodFactory( protected JsonRpcMethods createAdditionalJsonRpcMethodFactory(
final ProtocolContext protocolContext) { // NOSONAR final ProtocolContext protocolContext) {
return apis -> Collections.emptyMap(); return apis -> Collections.emptyMap();
} }
@ -542,8 +517,9 @@ public abstract class BesuControllerBuilder implements MiningParameterOverrides
final SubProtocolConfiguration subProtocolConfiguration = final SubProtocolConfiguration subProtocolConfiguration =
new SubProtocolConfiguration().withSubProtocol(EthProtocol.get(), ethProtocolManager); new SubProtocolConfiguration().withSubProtocol(EthProtocol.get(), ethProtocolManager);
maybeSnapProtocolManager.ifPresent( maybeSnapProtocolManager.ifPresent(
snapProtocolManager -> snapProtocolManager -> {
subProtocolConfiguration.withSubProtocol(SnapProtocol.get(), snapProtocolManager)); subProtocolConfiguration.withSubProtocol(SnapProtocol.get(), snapProtocolManager);
});
return subProtocolConfiguration; return subProtocolConfiguration;
} }

@ -15,7 +15,6 @@
package org.hyperledger.besu.controller; package org.hyperledger.besu.controller;
import org.hyperledger.besu.config.GenesisConfigFile; import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.consensus.merge.MergeContext;
import org.hyperledger.besu.consensus.merge.PostMergeContext; import org.hyperledger.besu.consensus.merge.PostMergeContext;
import org.hyperledger.besu.consensus.merge.TransitionBackwardSyncContext; import org.hyperledger.besu.consensus.merge.TransitionBackwardSyncContext;
import org.hyperledger.besu.consensus.merge.TransitionContext; import org.hyperledger.besu.consensus.merge.TransitionContext;
@ -32,14 +31,7 @@ import org.hyperledger.besu.ethereum.chain.Blockchain;
import org.hyperledger.besu.ethereum.core.MiningParameters; import org.hyperledger.besu.ethereum.core.MiningParameters;
import org.hyperledger.besu.ethereum.core.PrivacyParameters; import org.hyperledger.besu.ethereum.core.PrivacyParameters;
import org.hyperledger.besu.ethereum.eth.EthProtocolConfiguration; import org.hyperledger.besu.ethereum.eth.EthProtocolConfiguration;
import org.hyperledger.besu.ethereum.eth.manager.EthContext;
import org.hyperledger.besu.ethereum.eth.manager.EthMessages;
import org.hyperledger.besu.ethereum.eth.manager.EthPeers;
import org.hyperledger.besu.ethereum.eth.manager.EthProtocolManager; import org.hyperledger.besu.ethereum.eth.manager.EthProtocolManager;
import org.hyperledger.besu.ethereum.eth.manager.EthScheduler;
import org.hyperledger.besu.ethereum.eth.peervalidation.PeerValidator;
import org.hyperledger.besu.ethereum.eth.sync.DefaultSynchronizer;
import org.hyperledger.besu.ethereum.eth.sync.PivotBlockSelector;
import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration; import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration;
import org.hyperledger.besu.ethereum.eth.sync.backwardsync.BackwardSyncContext; import org.hyperledger.besu.ethereum.eth.sync.backwardsync.BackwardSyncContext;
import org.hyperledger.besu.ethereum.eth.sync.state.SyncState; import org.hyperledger.besu.ethereum.eth.sync.state.SyncState;
@ -48,10 +40,8 @@ import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolConfigurati
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.ethereum.storage.StorageProvider; import org.hyperledger.besu.ethereum.storage.StorageProvider;
import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration; import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration;
import org.hyperledger.besu.ethereum.worldstate.Pruner;
import org.hyperledger.besu.ethereum.worldstate.PrunerConfiguration; import org.hyperledger.besu.ethereum.worldstate.PrunerConfiguration;
import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive; import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive;
import org.hyperledger.besu.ethereum.worldstate.WorldStateStorage;
import org.hyperledger.besu.evm.internal.EvmConfiguration; import org.hyperledger.besu.evm.internal.EvmConfiguration;
import org.hyperledger.besu.metrics.ObservableMetricsSystem; import org.hyperledger.besu.metrics.ObservableMetricsSystem;
import org.hyperledger.besu.plugin.services.permissioning.NodeMessagePermissioningProvider; import org.hyperledger.besu.plugin.services.permissioning.NodeMessagePermissioningProvider;
@ -155,79 +145,13 @@ public class TransitionBesuControllerBuilder extends BesuControllerBuilder {
return new NoopPluginServiceFactory(); return new NoopPluginServiceFactory();
} }
@Override
protected DefaultSynchronizer createSynchronizer(
final ProtocolSchedule protocolSchedule,
final WorldStateStorage worldStateStorage,
final ProtocolContext protocolContext,
final Optional<Pruner> maybePruner,
final EthContext ethContext,
final SyncState syncState,
final EthProtocolManager ethProtocolManager,
final PivotBlockSelector pivotBlockSelector) {
DefaultSynchronizer sync =
super.createSynchronizer(
protocolSchedule,
worldStateStorage,
protocolContext,
maybePruner,
ethContext,
syncState,
ethProtocolManager,
pivotBlockSelector);
ConsensusContext cc = protocolContext.getConsensusContext(ConsensusContext.class);
if (cc instanceof MergeContext) {
protocolContext.getConsensusContext(MergeContext.class).addNewForkchoiceMessageListener(sync);
}
return sync;
}
@Override
protected EthProtocolManager createEthProtocolManager(
final ProtocolContext protocolContext,
final boolean fastSyncEnabled,
final TransactionPool transactionPool,
final EthProtocolConfiguration ethereumWireProtocolConfiguration,
final EthPeers ethPeers,
final EthContext ethContext,
final EthMessages ethMessages,
final EthScheduler scheduler,
final List<PeerValidator> peerValidators) {
EthProtocolManager ethProtocolManager =
super.createEthProtocolManager(
protocolContext,
fastSyncEnabled,
transactionPool,
ethereumWireProtocolConfiguration,
ethPeers,
ethContext,
ethMessages,
scheduler,
peerValidators);
ConsensusContext cc = protocolContext.getConsensusContext(ConsensusContext.class);
if (cc instanceof MergeContext) {
protocolContext
.getConsensusContext(MergeContext.class)
.observeNewIsPostMergeState(ethProtocolManager);
protocolContext
.getConsensusContext(MergeContext.class)
.addNewForkchoiceMessageListener(ethProtocolManager);
}
return ethProtocolManager;
}
private void initTransitionWatcher( private void initTransitionWatcher(
final ProtocolContext protocolContext, final TransitionCoordinator composedCoordinator) { final ProtocolContext protocolContext, final TransitionCoordinator composedCoordinator) {
PostMergeContext postMergeContext = protocolContext.getConsensusContext(PostMergeContext.class); PostMergeContext postMergeContext = protocolContext.getConsensusContext(PostMergeContext.class);
postMergeContext.observeNewIsPostMergeState( postMergeContext.observeNewIsPostMergeState(
(isPoS, difficultyStoppedAt) -> { newIsPostMergeState -> {
if (isPoS) { if (newIsPostMergeState) {
// if we transitioned to post-merge, stop and disable any mining // if we transitioned to post-merge, stop and disable any mining
composedCoordinator.getPreMergeObject().disable(); composedCoordinator.getPreMergeObject().disable();
composedCoordinator.getPreMergeObject().stop(); composedCoordinator.getPreMergeObject().stop();

@ -14,6 +14,7 @@
*/ */
package org.hyperledger.besu.consensus.merge; package org.hyperledger.besu.consensus.merge;
import org.hyperledger.besu.consensus.merge.MergeContext.NewForkchoiceMessageListener;
import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.datatypes.Hash;
import java.util.Optional; import java.util.Optional;

@ -67,4 +67,15 @@ public interface MergeContext extends ConsensusContext {
final Hash headBlockHash, final Hash headBlockHash,
final Optional<Hash> maybeFinalizedBlockHash, final Optional<Hash> maybeFinalizedBlockHash,
final Hash safeBlockHash); final Hash safeBlockHash);
interface NewMergeStateCallback {
void onNewIsPostMergeState(final boolean newIsPostMergeState);
}
interface NewForkchoiceMessageListener {
void onNewForkchoiceMessage(
final Hash headBlockHash,
final Optional<Hash> maybeFinalizedBlockHash,
final Hash safeBlockHash);
}
} }

@ -83,13 +83,13 @@ public class PostMergeContext implements MergeContext {
} }
@Override @Override
public void setIsPostMerge(final Difficulty difficultyStoppedAt) { public void setIsPostMerge(final Difficulty totalDifficulty) {
if (isPostMerge.get().orElse(Boolean.FALSE) && lastFinalized.get() != null) { if (isPostMerge.get().orElse(Boolean.FALSE) && lastFinalized.get() != null) {
// if we have finalized, we never switch back to a pre-merge once we have transitioned // if we have finalized, we never switch back to a pre-merge once we have transitioned
// post-TTD. // post-TTD.
return; return;
} }
final boolean newState = terminalTotalDifficulty.get().lessOrEqualThan(difficultyStoppedAt); final boolean newState = terminalTotalDifficulty.get().lessOrEqualThan(totalDifficulty);
final Optional<Boolean> oldState = isPostMerge.getAndSet(Optional.of(newState)); final Optional<Boolean> oldState = isPostMerge.getAndSet(Optional.of(newState));
// if we are past TTD, set it: // if we are past TTD, set it:
@ -99,9 +99,7 @@ public class PostMergeContext implements MergeContext {
if (oldState.isEmpty() || oldState.get() != newState) { if (oldState.isEmpty() || oldState.get() != newState) {
newMergeStateCallbackSubscribers.forEach( newMergeStateCallbackSubscribers.forEach(
newMergeStateCallback -> newMergeStateCallback -> newMergeStateCallback.onNewIsPostMergeState(newState));
newMergeStateCallback.onCrossingMergeBoundary(
newState, Optional.of(difficultyStoppedAt)));
} }
} }

@ -22,6 +22,7 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoInteractions; import static org.mockito.Mockito.verifyNoInteractions;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import org.hyperledger.besu.consensus.merge.MergeContext.NewMergeStateCallback;
import org.hyperledger.besu.consensus.merge.blockcreation.PayloadIdentifier; import org.hyperledger.besu.consensus.merge.blockcreation.PayloadIdentifier;
import org.hyperledger.besu.ethereum.core.Block; import org.hyperledger.besu.ethereum.core.Block;
import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.core.BlockHeader;
@ -172,9 +173,8 @@ public class PostMergeContextTest {
final List<Boolean> stateChanges = new ArrayList<>(); final List<Boolean> stateChanges = new ArrayList<>();
@Override @Override
public void onCrossingMergeBoundary( public void onNewIsPostMergeState(final boolean newIsPostMergeState) {
final boolean isPoS, final Optional<Difficulty> difficultyStoppedAt) { stateChanges.add(newIsPostMergeState);
stateChanges.add(isPoS);
} }
public void reset() { public void reset() {

@ -1,28 +0,0 @@
/*
* Copyright Hyperledger Besu Contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*
*/
package org.hyperledger.besu.consensus.merge;
import org.hyperledger.besu.datatypes.Hash;
import java.util.Optional;
public interface NewForkchoiceMessageListener {
void onNewForkchoiceMessage(
final Hash headBlockHash,
final Optional<Hash> maybeFinalizedBlockHash,
final Hash safeBlockHash);
}

@ -1,26 +0,0 @@
/*
* Copyright Hyperledger Besu Contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*
*/
package org.hyperledger.besu.consensus.merge;
import org.hyperledger.besu.ethereum.core.Difficulty;
import java.util.Optional;
public interface NewMergeStateCallback {
void onCrossingMergeBoundary(final boolean isPoS, final Optional<Difficulty> difficultyStoppedAt);
}

@ -16,8 +16,6 @@ package org.hyperledger.besu.ethereum.eth.manager;
import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkArgument;
import org.hyperledger.besu.consensus.merge.NewForkchoiceMessageListener;
import org.hyperledger.besu.consensus.merge.NewMergeStateCallback;
import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.datatypes.Hash;
import org.hyperledger.besu.ethereum.chain.Blockchain; import org.hyperledger.besu.ethereum.chain.Blockchain;
import org.hyperledger.besu.ethereum.chain.MinedBlockObserver; import org.hyperledger.besu.ethereum.chain.MinedBlockObserver;
@ -49,8 +47,6 @@ import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.StampedLock;
import com.google.common.annotations.VisibleForTesting; import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
@ -58,16 +54,13 @@ import org.apache.tuweni.bytes.Bytes;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
public class EthProtocolManager public class EthProtocolManager implements ProtocolManager, MinedBlockObserver {
implements ProtocolManager,
MinedBlockObserver,
NewMergeStateCallback,
NewForkchoiceMessageListener {
private static final Logger LOG = LoggerFactory.getLogger(EthProtocolManager.class); private static final Logger LOG = LoggerFactory.getLogger(EthProtocolManager.class);
private final EthScheduler scheduler; private final EthScheduler scheduler;
private final CountDownLatch shutdown; private final CountDownLatch shutdown;
private final AtomicBoolean stopped = new AtomicBoolean(false); private final AtomicBoolean stopped = new AtomicBoolean(false);
private final Hash genesisHash; private final Hash genesisHash;
private final ForkIdManager forkIdManager; private final ForkIdManager forkIdManager;
private final BigInteger networkId; private final BigInteger networkId;
@ -78,10 +71,6 @@ public class EthProtocolManager
private final Blockchain blockchain; private final Blockchain blockchain;
private final BlockBroadcaster blockBroadcaster; private final BlockBroadcaster blockBroadcaster;
private final List<PeerValidator> peerValidators; private final List<PeerValidator> peerValidators;
private Optional<Difficulty> powTerminalDifficulty = Optional.empty();
private final StampedLock powTerminalDifficultyLock = new StampedLock();
private Hash lastFinalized = Hash.ZERO;
private final AtomicLong numFinalizedSeen = new AtomicLong(0);
public EthProtocolManager( public EthProtocolManager(
final Blockchain blockchain, final Blockchain blockchain,
@ -102,7 +91,7 @@ public class EthProtocolManager
this.blockchain = blockchain; this.blockchain = blockchain;
this.shutdown = new CountDownLatch(1); this.shutdown = new CountDownLatch(1);
this.genesisHash = blockchain.getBlockHashByNumber(0L).orElse(Hash.ZERO); genesisHash = blockchain.getBlockHashByNumber(0L).get();
this.forkIdManager = forkIdManager; this.forkIdManager = forkIdManager;
@ -248,7 +237,7 @@ public class EthProtocolManager
final EthPeer ethPeer = ethPeers.peer(message.getConnection()); final EthPeer ethPeer = ethPeers.peer(message.getConnection());
if (ethPeer == null) { if (ethPeer == null) {
LOG.debug( LOG.debug(
"Ignoring message received from unknown peer connection: {}", message.getConnection()); "Ignoring message received from unknown peer connection: " + message.getConnection());
return; return;
} }
@ -282,11 +271,6 @@ public class EthProtocolManager
return; return;
} }
if (isFinalized() && (code == EthPV62.NEW_BLOCK || code == EthPV62.NEW_BLOCK_HASHES)) {
LOG.debug("disconnecting peer for sending new blocks after transition to PoS");
ethPeer.disconnect(DisconnectReason.SUBPROTOCOL_TRIGGERED);
}
// This will handle responses // This will handle responses
ethPeers.dispatchMessage(ethPeer, ethMessage, getSupportedProtocol()); ethPeers.dispatchMessage(ethPeer, ethMessage, getSupportedProtocol());
@ -313,7 +297,7 @@ public class EthProtocolManager
responseData -> { responseData -> {
try { try {
ethPeer.send(responseData, getSupportedProtocol()); ethPeer.send(responseData, getSupportedProtocol());
} catch (final PeerNotConnected missingPeerException) { } catch (final PeerNotConnected __) {
// Peer disconnected before we could respond - nothing to do // Peer disconnected before we could respond - nothing to do
} }
}); });
@ -385,19 +369,6 @@ public class EthProtocolManager
networkId, networkId,
status.genesisHash()); status.genesisHash());
peer.disconnect(DisconnectReason.SUBPROTOCOL_TRIGGERED); peer.disconnect(DisconnectReason.SUBPROTOCOL_TRIGGERED);
} else if (isFinalized()) {
long lockStamp = this.powTerminalDifficultyLock.readLock();
try {
if (this.powTerminalDifficulty.isPresent()
&& status.totalDifficulty().greaterThan(this.powTerminalDifficulty.get())) {
LOG.debug(
"Disconnecting peer with difficulty {}, likely still on PoW chain",
status.totalDifficulty());
peer.disconnect(DisconnectReason.SUBPROTOCOL_TRIGGERED);
}
} finally {
this.powTerminalDifficultyLock.unlockRead(lockStamp);
}
} else { } else {
LOG.debug("Received status message from {}: {}", peer, status); LOG.debug("Received status message from {}: {}", peer, status);
peer.registerStatusReceived( peer.registerStatusReceived(
@ -411,10 +382,6 @@ public class EthProtocolManager
} }
} }
private boolean isFinalized() {
return this.numFinalizedSeen.get() > 1;
}
@Override @Override
public void blockMined(final Block block) { public void blockMined(final Block block) {
// This assumes the block has already been included in the chain // This assumes the block has already been included in the chain
@ -434,55 +401,4 @@ public class EthProtocolManager
? Collections.emptyList() ? Collections.emptyList()
: chainHeadForkId.getForkIdAsBytesList(); : chainHeadForkId.getForkIdAsBytesList();
} }
@Override
public void onCrossingMergeBoundary(
final boolean isPoS, final Optional<Difficulty> difficultyStoppedAt) {
if (isPoS) {
long lockStamp = this.powTerminalDifficultyLock.writeLock();
try {
this.powTerminalDifficulty = difficultyStoppedAt;
} finally {
this.powTerminalDifficultyLock.unlockWrite(lockStamp);
}
}
}
private void disconnectKnownPowPeers() {
long lockStamp = powTerminalDifficultyLock.readLock();
try {
if (powTerminalDifficulty.isPresent()) {
LOG.info(
"disconnecting peers with total difficulty over {}",
powTerminalDifficulty.get().toBigInteger());
ethPeers
.streamAllPeers()
.filter(
ethPeer ->
ethPeer
.chainState()
.getBestBlock()
.totalDifficulty
.greaterThan(powTerminalDifficulty.get()))
.forEach(ethPeer -> ethPeer.disconnect(DisconnectReason.SUBPROTOCOL_TRIGGERED));
}
} finally {
powTerminalDifficultyLock.unlockRead(lockStamp);
}
}
@Override
public void onNewForkchoiceMessage(
final Hash headBlockHash,
final Optional<Hash> maybeFinalizedBlockHash,
final Hash safeBlockHash) {
if (maybeFinalizedBlockHash.isPresent()
&& !maybeFinalizedBlockHash.get().equals(this.lastFinalized)) {
this.lastFinalized = maybeFinalizedBlockHash.get();
this.numFinalizedSeen.getAndIncrement();
if (isFinalized()) {
disconnectKnownPowPeers();
}
}
}
} }

@ -16,8 +16,6 @@ package org.hyperledger.besu.ethereum.eth.sync;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
import org.hyperledger.besu.consensus.merge.NewForkchoiceMessageListener;
import org.hyperledger.besu.datatypes.Hash;
import org.hyperledger.besu.ethereum.ProtocolContext; import org.hyperledger.besu.ethereum.ProtocolContext;
import org.hyperledger.besu.ethereum.core.Synchronizer; import org.hyperledger.besu.ethereum.core.Synchronizer;
import org.hyperledger.besu.ethereum.eth.manager.EthContext; import org.hyperledger.besu.ethereum.eth.manager.EthContext;
@ -43,12 +41,11 @@ import java.time.Clock;
import java.util.Optional; import java.util.Optional;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
public class DefaultSynchronizer implements Synchronizer, NewForkchoiceMessageListener { public class DefaultSynchronizer implements Synchronizer {
private static final Logger LOG = LoggerFactory.getLogger(DefaultSynchronizer.class); private static final Logger LOG = LoggerFactory.getLogger(DefaultSynchronizer.class);
@ -61,8 +58,6 @@ public class DefaultSynchronizer implements Synchronizer, NewForkchoiceMessageLi
private final ProtocolContext protocolContext; private final ProtocolContext protocolContext;
private final PivotBlockSelector pivotBlockSelector; private final PivotBlockSelector pivotBlockSelector;
private final SyncTerminationCondition terminationCondition; private final SyncTerminationCondition terminationCondition;
private Hash lastFinalized = Hash.ZERO;
private final AtomicLong numFinalizedSeen = new AtomicLong(0);
public DefaultSynchronizer( public DefaultSynchronizer(
final SynchronizerConfiguration syncConfig, final SynchronizerConfiguration syncConfig,
@ -293,21 +288,4 @@ public class DefaultSynchronizer implements Synchronizer, NewForkchoiceMessageLi
running.set(false); running.set(false);
return null; return null;
} }
@Override
public void onNewForkchoiceMessage(
final Hash headBlockHash,
final Optional<Hash> maybeFinalizedBlockHash,
final Hash safeBlockHash) {
if (maybeFinalizedBlockHash.isPresent()
&& !maybeFinalizedBlockHash.get().equals(this.lastFinalized)) {
this.lastFinalized = maybeFinalizedBlockHash.get();
this.numFinalizedSeen.getAndIncrement();
if (this.numFinalizedSeen.get() > 1
&& blockPropagationManager.isPresent()
&& blockPropagationManager.get().isRunning()) {
blockPropagationManager.get().stop();
}
}
}
} }

@ -66,7 +66,6 @@ import org.hyperledger.besu.ethereum.p2p.rlpx.wire.Capability;
import org.hyperledger.besu.ethereum.p2p.rlpx.wire.DefaultMessage; import org.hyperledger.besu.ethereum.p2p.rlpx.wire.DefaultMessage;
import org.hyperledger.besu.ethereum.p2p.rlpx.wire.MessageData; import org.hyperledger.besu.ethereum.p2p.rlpx.wire.MessageData;
import org.hyperledger.besu.ethereum.p2p.rlpx.wire.RawMessage; import org.hyperledger.besu.ethereum.p2p.rlpx.wire.RawMessage;
import org.hyperledger.besu.ethereum.p2p.rlpx.wire.messages.DisconnectMessage.DisconnectReason;
import org.hyperledger.besu.ethereum.worldstate.DataStorageFormat; import org.hyperledger.besu.ethereum.worldstate.DataStorageFormat;
import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive; import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive;
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
@ -79,7 +78,6 @@ import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
@ -203,101 +201,6 @@ public final class EthProtocolManagerTest {
} }
} }
@Test
public void disconnectPoWPeersAfterTransition() {
try (final EthProtocolManager ethManager =
EthProtocolManagerTestUtil.create(
blockchain,
() -> false,
protocolContext.getWorldStateArchive(),
transactionPool,
EthProtocolConfiguration.defaultConfig())) {
final MockPeerConnection workPeer = setupPeer(ethManager, (cap, msg, conn) -> {});
final MockPeerConnection stakePeer = setupPeer(ethManager, (cap, msg, conn) -> {});
final StatusMessage workPeerStatus =
StatusMessage.create(
EthProtocol.EthVersion.V63,
BigInteger.ONE,
blockchain.getChainHead().getTotalDifficulty().add(20),
blockchain.getChainHeadHash(),
blockchain.getBlockHeader(BlockHeader.GENESIS_BLOCK_NUMBER).get().getHash());
final StatusMessage stakePeerStatus =
StatusMessage.create(
EthProtocol.EthVersion.V63,
BigInteger.ONE,
blockchain.getChainHead().getTotalDifficulty(),
blockchain.getChainHeadHash(),
blockchain.getBlockHeader(BlockHeader.GENESIS_BLOCK_NUMBER).get().getHash());
ethManager.processMessage(EthProtocol.ETH63, new DefaultMessage(workPeer, workPeerStatus));
ethManager.processMessage(EthProtocol.ETH63, new DefaultMessage(stakePeer, stakePeerStatus));
ethManager.onCrossingMergeBoundary(
true, Optional.of(blockchain.getChainHead().getTotalDifficulty()));
ethManager.onNewForkchoiceMessage(
Hash.EMPTY, Optional.of(Hash.hash(Bytes.of(1))), Hash.EMPTY);
ethManager.onNewForkchoiceMessage(
Hash.EMPTY, Optional.of(Hash.hash(Bytes.of(2))), Hash.EMPTY);
assertThat(workPeer.isDisconnected()).isTrue();
assertThat(workPeer.getDisconnectReason()).isPresent();
assertThat(workPeer.getDisconnectReason())
.get()
.isEqualTo(DisconnectReason.SUBPROTOCOL_TRIGGERED);
assertThat(stakePeer.isDisconnected()).isFalse();
}
}
@Test
public void disconnectNewPoWPeers() {
try (final EthProtocolManager ethManager =
EthProtocolManagerTestUtil.create(
blockchain,
() -> false,
protocolContext.getWorldStateArchive(),
transactionPool,
EthProtocolConfiguration.defaultConfig())) {
final MockPeerConnection workPeer = setupPeer(ethManager, (cap, msg, conn) -> {});
final MockPeerConnection stakePeer = setupPeer(ethManager, (cap, msg, conn) -> {});
final StatusMessage workPeerStatus =
StatusMessage.create(
EthProtocol.EthVersion.V63,
BigInteger.ONE,
blockchain.getChainHead().getTotalDifficulty().add(20),
blockchain.getChainHeadHash(),
blockchain.getBlockHeader(BlockHeader.GENESIS_BLOCK_NUMBER).get().getHash());
final StatusMessage stakePeerStatus =
StatusMessage.create(
EthProtocol.EthVersion.V63,
BigInteger.ONE,
blockchain.getChainHead().getTotalDifficulty(),
blockchain.getChainHeadHash(),
blockchain.getBlockHeader(BlockHeader.GENESIS_BLOCK_NUMBER).get().getHash());
ethManager.processMessage(EthProtocol.ETH63, new DefaultMessage(stakePeer, stakePeerStatus));
ethManager.onCrossingMergeBoundary(
true, Optional.of(blockchain.getChainHead().getTotalDifficulty()));
ethManager.onNewForkchoiceMessage(
Hash.EMPTY, Optional.of(Hash.hash(Bytes.of(1))), Hash.EMPTY);
ethManager.onNewForkchoiceMessage(
Hash.EMPTY, Optional.of(Hash.hash(Bytes.of(2))), Hash.EMPTY);
ethManager.processMessage(EthProtocol.ETH63, new DefaultMessage(workPeer, workPeerStatus));
assertThat(workPeer.isDisconnected()).isTrue();
assertThat(workPeer.getDisconnectReason()).isPresent();
assertThat(workPeer.getDisconnectReason())
.get()
.isEqualTo(DisconnectReason.SUBPROTOCOL_TRIGGERED);
assertThat(stakePeer.isDisconnected()).isFalse();
}
}
@Test @Test
public void disconnectOnVeryLargeMessage() { public void disconnectOnVeryLargeMessage() {
try (final EthProtocolManager ethManager = try (final EthProtocolManager ethManager =
@ -390,7 +293,7 @@ public final class EthProtocolManagerTest {
final BlockHeadersMessage headersMsg = BlockHeadersMessage.readFrom(message); final BlockHeadersMessage headersMsg = BlockHeadersMessage.readFrom(message);
final List<BlockHeader> headers = final List<BlockHeader> headers =
Lists.newArrayList(headersMsg.getHeaders(protocolSchedule)); Lists.newArrayList(headersMsg.getHeaders(protocolSchedule));
assertThat(headers).hasSize(blockCount); assertThat(headers.size()).isEqualTo(blockCount);
for (int i = 0; i < blockCount; i++) { for (int i = 0; i < blockCount; i++) {
assertThat(headers.get(i).getNumber()).isEqualTo(startBlock + i); assertThat(headers.get(i).getNumber()).isEqualTo(startBlock + i);
} }
@ -427,7 +330,7 @@ public final class EthProtocolManagerTest {
final BlockHeadersMessage headersMsg = BlockHeadersMessage.readFrom(message); final BlockHeadersMessage headersMsg = BlockHeadersMessage.readFrom(message);
final List<BlockHeader> headers = final List<BlockHeader> headers =
Lists.newArrayList(headersMsg.getHeaders(protocolSchedule)); Lists.newArrayList(headersMsg.getHeaders(protocolSchedule));
assertThat(headers).hasSize(limit); assertThat(headers.size()).isEqualTo(limit);
for (int i = 0; i < limit; i++) { for (int i = 0; i < limit; i++) {
assertThat(headers.get(i).getNumber()).isEqualTo(startBlock + i); assertThat(headers.get(i).getNumber()).isEqualTo(startBlock + i);
} }
@ -463,7 +366,7 @@ public final class EthProtocolManagerTest {
final BlockHeadersMessage headersMsg = BlockHeadersMessage.readFrom(message); final BlockHeadersMessage headersMsg = BlockHeadersMessage.readFrom(message);
final List<BlockHeader> headers = final List<BlockHeader> headers =
Lists.newArrayList(headersMsg.getHeaders(protocolSchedule)); Lists.newArrayList(headersMsg.getHeaders(protocolSchedule));
assertThat(headers).hasSize(blockCount); assertThat(headers.size()).isEqualTo(blockCount);
for (int i = 0; i < blockCount; i++) { for (int i = 0; i < blockCount; i++) {
assertThat(headers.get(i).getNumber()).isEqualTo(endBlock - i); assertThat(headers.get(i).getNumber()).isEqualTo(endBlock - i);
} }
@ -501,7 +404,7 @@ public final class EthProtocolManagerTest {
final BlockHeadersMessage headersMsg = BlockHeadersMessage.readFrom(message); final BlockHeadersMessage headersMsg = BlockHeadersMessage.readFrom(message);
final List<BlockHeader> headers = final List<BlockHeader> headers =
Lists.newArrayList(headersMsg.getHeaders(protocolSchedule)); Lists.newArrayList(headersMsg.getHeaders(protocolSchedule));
assertThat(headers).hasSize(blockCount); assertThat(headers.size()).isEqualTo(blockCount);
for (int i = 0; i < blockCount; i++) { for (int i = 0; i < blockCount; i++) {
assertThat(headers.get(i).getNumber()).isEqualTo(startBlock + i * (skip + 1)); assertThat(headers.get(i).getNumber()).isEqualTo(startBlock + i * (skip + 1));
} }
@ -540,7 +443,7 @@ public final class EthProtocolManagerTest {
final BlockHeadersMessage headersMsg = BlockHeadersMessage.readFrom(message); final BlockHeadersMessage headersMsg = BlockHeadersMessage.readFrom(message);
final List<BlockHeader> headers = final List<BlockHeader> headers =
Lists.newArrayList(headersMsg.getHeaders(protocolSchedule)); Lists.newArrayList(headersMsg.getHeaders(protocolSchedule));
assertThat(headers).hasSize(blockCount); assertThat(headers.size()).isEqualTo(blockCount);
for (int i = 0; i < blockCount; i++) { for (int i = 0; i < blockCount; i++) {
assertThat(headers.get(i).getNumber()).isEqualTo(endBlock - i * (skip + 1)); assertThat(headers.get(i).getNumber()).isEqualTo(endBlock - i * (skip + 1));
} }
@ -599,7 +502,7 @@ public final class EthProtocolManagerTest {
final BlockHeadersMessage headersMsg = BlockHeadersMessage.readFrom(message); final BlockHeadersMessage headersMsg = BlockHeadersMessage.readFrom(message);
final List<BlockHeader> headers = final List<BlockHeader> headers =
Lists.newArrayList(headersMsg.getHeaders(protocolSchedule)); Lists.newArrayList(headersMsg.getHeaders(protocolSchedule));
assertThat(headers).hasSize(2); assertThat(headers.size()).isEqualTo(2);
for (int i = 0; i < 2; i++) { for (int i = 0; i < 2; i++) {
assertThat(headers.get(i).getNumber()).isEqualTo(startBlock + i); assertThat(headers.get(i).getNumber()).isEqualTo(startBlock + i);
} }
@ -636,7 +539,7 @@ public final class EthProtocolManagerTest {
final BlockHeadersMessage headersMsg = BlockHeadersMessage.readFrom(message); final BlockHeadersMessage headersMsg = BlockHeadersMessage.readFrom(message);
final List<BlockHeader> headers = final List<BlockHeader> headers =
Lists.newArrayList(headersMsg.getHeaders(protocolSchedule)); Lists.newArrayList(headersMsg.getHeaders(protocolSchedule));
assertThat(headers).isEmpty(); assertThat(headers.size()).isEqualTo(0);
done.complete(null); done.complete(null);
}; };
final PeerConnection peer = setupPeer(ethManager, onSend); final PeerConnection peer = setupPeer(ethManager, onSend);
@ -680,7 +583,7 @@ public final class EthProtocolManagerTest {
final BlockBodiesMessage blocksMessage = BlockBodiesMessage.readFrom(message); final BlockBodiesMessage blocksMessage = BlockBodiesMessage.readFrom(message);
final List<BlockBody> bodies = final List<BlockBody> bodies =
Lists.newArrayList(blocksMessage.bodies(protocolSchedule)); Lists.newArrayList(blocksMessage.bodies(protocolSchedule));
assertThat(bodies).hasSize(blockCount); assertThat(bodies.size()).isEqualTo(blockCount);
for (int i = 0; i < blockCount; i++) { for (int i = 0; i < blockCount; i++) {
assertThat(expectedBlocks[i].getBody()).isEqualTo(bodies.get(i)); assertThat(expectedBlocks[i].getBody()).isEqualTo(bodies.get(i));
} }
@ -729,7 +632,7 @@ public final class EthProtocolManagerTest {
final BlockBodiesMessage blocksMessage = BlockBodiesMessage.readFrom(message); final BlockBodiesMessage blocksMessage = BlockBodiesMessage.readFrom(message);
final List<BlockBody> bodies = final List<BlockBody> bodies =
Lists.newArrayList(blocksMessage.bodies(protocolSchedule)); Lists.newArrayList(blocksMessage.bodies(protocolSchedule));
assertThat(bodies).hasSize(limit); assertThat(bodies.size()).isEqualTo(limit);
for (int i = 0; i < limit; i++) { for (int i = 0; i < limit; i++) {
assertThat(expectedBlocks[i].getBody()).isEqualTo(bodies.get(i)); assertThat(expectedBlocks[i].getBody()).isEqualTo(bodies.get(i));
} }
@ -773,7 +676,7 @@ public final class EthProtocolManagerTest {
final BlockBodiesMessage blocksMessage = BlockBodiesMessage.readFrom(message); final BlockBodiesMessage blocksMessage = BlockBodiesMessage.readFrom(message);
final List<BlockBody> bodies = final List<BlockBody> bodies =
Lists.newArrayList(blocksMessage.bodies(protocolSchedule)); Lists.newArrayList(blocksMessage.bodies(protocolSchedule));
assertThat(bodies).hasSize(1); assertThat(bodies.size()).isEqualTo(1);
assertThat(expectedBlock.getBody()).isEqualTo(bodies.get(0)); assertThat(expectedBlock.getBody()).isEqualTo(bodies.get(0));
done.complete(null); done.complete(null);
}; };
@ -818,7 +721,7 @@ public final class EthProtocolManagerTest {
final ReceiptsMessage receiptsMessage = ReceiptsMessage.readFrom(message); final ReceiptsMessage receiptsMessage = ReceiptsMessage.readFrom(message);
final List<List<TransactionReceipt>> receipts = final List<List<TransactionReceipt>> receipts =
Lists.newArrayList(receiptsMessage.receipts()); Lists.newArrayList(receiptsMessage.receipts());
assertThat(receipts).hasSize(blockCount); assertThat(receipts.size()).isEqualTo(blockCount);
for (int i = 0; i < blockCount; i++) { for (int i = 0; i < blockCount; i++) {
assertThat(expectedReceipts.get(i)).isEqualTo(receipts.get(i)); assertThat(expectedReceipts.get(i)).isEqualTo(receipts.get(i));
} }
@ -866,7 +769,7 @@ public final class EthProtocolManagerTest {
final ReceiptsMessage receiptsMessage = ReceiptsMessage.readFrom(message); final ReceiptsMessage receiptsMessage = ReceiptsMessage.readFrom(message);
final List<List<TransactionReceipt>> receipts = final List<List<TransactionReceipt>> receipts =
Lists.newArrayList(receiptsMessage.receipts()); Lists.newArrayList(receiptsMessage.receipts());
assertThat(receipts).hasSize(limit); assertThat(receipts.size()).isEqualTo(limit);
for (int i = 0; i < limit; i++) { for (int i = 0; i < limit; i++) {
assertThat(expectedReceipts.get(i)).isEqualTo(receipts.get(i)); assertThat(expectedReceipts.get(i)).isEqualTo(receipts.get(i));
} }
@ -910,7 +813,7 @@ public final class EthProtocolManagerTest {
final ReceiptsMessage receiptsMessage = ReceiptsMessage.readFrom(message); final ReceiptsMessage receiptsMessage = ReceiptsMessage.readFrom(message);
final List<List<TransactionReceipt>> receipts = final List<List<TransactionReceipt>> receipts =
Lists.newArrayList(receiptsMessage.receipts()); Lists.newArrayList(receiptsMessage.receipts());
assertThat(receipts).hasSize(1); assertThat(receipts.size()).isEqualTo(1);
assertThat(expectedReceipts).isEqualTo(receipts.get(0)); assertThat(expectedReceipts).isEqualTo(receipts.get(0));
done.complete(null); done.complete(null);
}; };
@ -958,7 +861,7 @@ public final class EthProtocolManagerTest {
assertThat(message.getCode()).isEqualTo(EthPV63.NODE_DATA); assertThat(message.getCode()).isEqualTo(EthPV63.NODE_DATA);
final NodeDataMessage receiptsMessage = NodeDataMessage.readFrom(message); final NodeDataMessage receiptsMessage = NodeDataMessage.readFrom(message);
final List<Bytes> nodeData = receiptsMessage.nodeData(); final List<Bytes> nodeData = receiptsMessage.nodeData();
assertThat(nodeData).hasSize(blockCount); assertThat(nodeData.size()).isEqualTo(blockCount);
for (int i = 0; i < blockCount; i++) { for (int i = 0; i < blockCount; i++) {
assertThat(expectedResults.get(i)).isEqualTo(nodeData.get(i)); assertThat(expectedResults.get(i)).isEqualTo(nodeData.get(i));
} }
@ -1025,7 +928,7 @@ public final class EthProtocolManagerTest {
assertThat(msg.totalDifficulty(protocolSchdeule)).isEqualTo(expectedTotalDifficulty); assertThat(msg.totalDifficulty(protocolSchdeule)).isEqualTo(expectedTotalDifficulty);
} }
assertThat(receivingPeerCaptor.getAllValues()).containsAll(peers); assertThat(receivingPeerCaptor.getAllValues().containsAll(peers)).isTrue();
} }
} }
@ -1067,7 +970,7 @@ public final class EthProtocolManagerTest {
final BlockHeadersMessage headersMsg = BlockHeadersMessage.readFrom(message); final BlockHeadersMessage headersMsg = BlockHeadersMessage.readFrom(message);
final List<BlockHeader> headers = final List<BlockHeader> headers =
Lists.newArrayList(headersMsg.getHeaders(protocolSchedule)); Lists.newArrayList(headersMsg.getHeaders(protocolSchedule));
assertThat(headers).hasSize(receivedBlockCount); assertThat(headers.size()).isEqualTo(receivedBlockCount);
for (int i = 0; i < receivedBlockCount; i++) { for (int i = 0; i < receivedBlockCount; i++) {
assertThat(headers.get(i).getNumber()).isEqualTo(receivedBlockCount - 1 - i); assertThat(headers.get(i).getNumber()).isEqualTo(receivedBlockCount - 1 - i);
} }

@ -1,4 +1,4 @@
version=22.4.3-SNAPSHOT version=22.4.3
# Workaround for Java 16 and spotless bug 834 https://github.com/diffplug/spotless/issues/834 # Workaround for Java 16 and spotless bug 834 https://github.com/diffplug/spotless/issues/834
org.gradle.jvmargs=--add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED \ org.gradle.jvmargs=--add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED \

Loading…
Cancel
Save