use of org.hyperledger.besu.ethereum.eth.manager.RespondingEthPeer.Responder in project besu by hyperledger.
the class PivotBlockRetrieverTest method shouldIgnorePeersThatDoNotHaveThePivotBlock.
@Test
public void shouldIgnorePeersThatDoNotHaveThePivotBlock() {
pivotBlockRetriever = createPivotBlockRetriever(3, 1, 1);
EthProtocolManagerTestUtil.disableEthSchedulerAutoRun(ethProtocolManager);
final Responder responder = RespondingEthPeer.blockchainResponder(blockchain, protocolContext.getWorldStateArchive(), transactionPool);
final RespondingEthPeer respondingPeerA = EthProtocolManagerTestUtil.createPeer(ethProtocolManager, 1000);
final RespondingEthPeer badPeerA = EthProtocolManagerTestUtil.createPeer(ethProtocolManager, 1);
final RespondingEthPeer badPeerB = EthProtocolManagerTestUtil.createPeer(ethProtocolManager, 1);
final CompletableFuture<FastSyncState> future = pivotBlockRetriever.downloadPivotBlockHeader();
respondingPeerA.respond(responder);
// With only one peer with sufficient height, we should not be done yet
assertThat(future).isNotCompleted();
// Check that invalid peers were not queried
assertThat(badPeerA.hasOutstandingRequests()).isFalse();
assertThat(badPeerB.hasOutstandingRequests()).isFalse();
// Add new peer that we can query
final RespondingEthPeer respondingPeerB = EthProtocolManagerTestUtil.createPeer(ethProtocolManager, 1000);
respondingPeerB.respond(responder);
// We need one more responsive peer before we're done
assertThat(future).isNotCompleted();
assertThat(badPeerA.hasOutstandingRequests()).isFalse();
assertThat(badPeerB.hasOutstandingRequests()).isFalse();
// Add new peer that we can query
final RespondingEthPeer respondingPeerC = EthProtocolManagerTestUtil.createPeer(ethProtocolManager, 1000);
respondingPeerC.respond(responder);
assertThat(badPeerA.hasOutstandingRequests()).isFalse();
assertThat(badPeerB.hasOutstandingRequests()).isFalse();
assertThat(future).isCompletedWithValue(new FastSyncState(blockchain.getBlockHeader(PIVOT_BLOCK_NUMBER).get()));
}
use of org.hyperledger.besu.ethereum.eth.manager.RespondingEthPeer.Responder in project besu by hyperledger.
the class PivotBlockRetrieverTest method shouldRetryWhenPeersDisagreeOnPivot_exceedMaxRetries.
@Test
public void shouldRetryWhenPeersDisagreeOnPivot_exceedMaxRetries() {
final long pivotBlockDelta = 1;
pivotBlockRetriever = createPivotBlockRetriever(2, pivotBlockDelta, 1);
final Responder responderA = RespondingEthPeer.blockchainResponder(blockchain, protocolContext.getWorldStateArchive(), transactionPool);
final RespondingEthPeer respondingPeerA = EthProtocolManagerTestUtil.createPeer(ethProtocolManager, 1000);
final Responder responderB = responderForFakeBlocks(PIVOT_BLOCK_NUMBER, PIVOT_BLOCK_NUMBER - pivotBlockDelta);
final RespondingEthPeer respondingPeerB = EthProtocolManagerTestUtil.createPeer(ethProtocolManager, 1000);
// Execute task and wait for response
final CompletableFuture<FastSyncState> future = pivotBlockRetriever.downloadPivotBlockHeader();
respondingPeerA.respond(responderA);
respondingPeerB.respond(responderB);
// When disagreement is detected, we should push the pivot block back and retry
final long newPivotBlock = PIVOT_BLOCK_NUMBER - 1;
assertThat(future).isNotCompleted();
assertThat(pivotBlockRetriever.pivotBlockNumber).hasValue(newPivotBlock);
// Another round of invalid responses should lead to failure
respondingPeerA.respond(responderA);
respondingPeerB.respond(responderB);
assertThat(future).isCompletedExceptionally();
assertThatThrownBy(future::get).hasRootCauseInstanceOf(FastSyncException.class).extracting(e -> ((FastSyncException) ExceptionUtils.rootCause(e)).getError()).isEqualTo(FastSyncError.PIVOT_BLOCK_HEADER_MISMATCH);
}
use of org.hyperledger.besu.ethereum.eth.manager.RespondingEthPeer.Responder in project besu by hyperledger.
the class PivotBlockRetrieverTest method shouldSucceedWhenAllPeersAgree.
@Test
public void shouldSucceedWhenAllPeersAgree() {
final RespondingEthPeer.Responder responder = RespondingEthPeer.blockchainResponder(blockchain, protocolContext.getWorldStateArchive(), transactionPool);
final RespondingEthPeer respondingPeerA = EthProtocolManagerTestUtil.createPeer(ethProtocolManager, 1000);
final RespondingEthPeer respondingPeerB = EthProtocolManagerTestUtil.createPeer(ethProtocolManager, 1000);
final RespondingEthPeer respondingPeerC = EthProtocolManagerTestUtil.createPeer(ethProtocolManager, 1000);
final CompletableFuture<FastSyncState> future = pivotBlockRetriever.downloadPivotBlockHeader();
respondingPeerA.respond(responder);
respondingPeerB.respond(responder);
respondingPeerC.respond(responder);
assertThat(future).isCompletedWithValue(new FastSyncState(blockchain.getBlockHeader(PIVOT_BLOCK_NUMBER).get()));
}
use of org.hyperledger.besu.ethereum.eth.manager.RespondingEthPeer.Responder in project besu by hyperledger.
the class PivotBlockRetrieverTest method shouldRecoverFromUnresponsivePeer.
@Test
public void shouldRecoverFromUnresponsivePeer() {
pivotBlockRetriever = createPivotBlockRetriever(2, 1, 1);
EthProtocolManagerTestUtil.disableEthSchedulerAutoRun(ethProtocolManager);
final Responder responder = RespondingEthPeer.blockchainResponder(blockchain, protocolContext.getWorldStateArchive(), transactionPool);
final Responder emptyResponder = RespondingEthPeer.emptyResponder();
final RespondingEthPeer peerA = EthProtocolManagerTestUtil.createPeer(ethProtocolManager, Difficulty.of(1000), 1000);
final RespondingEthPeer peerB = EthProtocolManagerTestUtil.createPeer(ethProtocolManager, Difficulty.of(1000), 1000);
final RespondingEthPeer peerC = EthProtocolManagerTestUtil.createPeer(ethProtocolManager, Difficulty.of(500), 500);
final CompletableFuture<FastSyncState> future = pivotBlockRetriever.downloadPivotBlockHeader();
peerA.respond(responder);
peerB.respondTimes(emptyResponder, 2);
// PeerA should have responded, while peerB is being retried, peerC shouldn't have been queried
// yet
assertThat(future).isNotCompleted();
assertThat(peerC.hasOutstandingRequests()).isFalse();
// After exhausting retries for peerB, we should try peerC
peerB.respondTimes(emptyResponder, 2);
peerC.respond(responder);
assertThat(future).isCompletedWithValue(new FastSyncState(blockchain.getBlockHeader(PIVOT_BLOCK_NUMBER).get()));
}
use of org.hyperledger.besu.ethereum.eth.manager.RespondingEthPeer.Responder in project besu by hyperledger.
the class PivotBlockRetrieverTest method shouldIgnorePeersThatAreNotFullyValidated.
@Test
public void shouldIgnorePeersThatAreNotFullyValidated() {
final PeerValidator peerValidator = mock(PeerValidator.class);
final RespondingEthPeer.Responder responder = RespondingEthPeer.blockchainResponder(blockchain, protocolContext.getWorldStateArchive(), transactionPool);
final RespondingEthPeer respondingPeerA = EthProtocolManagerTestUtil.createPeer(ethProtocolManager, 1000, peerValidator);
final RespondingEthPeer badPeerA = EthProtocolManagerTestUtil.createPeer(ethProtocolManager, 1000, peerValidator);
final RespondingEthPeer badPeerB = EthProtocolManagerTestUtil.createPeer(ethProtocolManager, 1000, peerValidator);
// Mark peerA valid
respondingPeerA.getEthPeer().markValidated(peerValidator);
final CompletableFuture<FastSyncState> future = pivotBlockRetriever.downloadPivotBlockHeader();
respondingPeerA.respond(responder);
// With only one peer with sufficient height, we should not be done yet
assertThat(future).isNotCompleted();
// Check that invalid peers were not queried
assertThat(badPeerA.hasOutstandingRequests()).isFalse();
assertThat(badPeerB.hasOutstandingRequests()).isFalse();
// Add new peer that we can query
final RespondingEthPeer respondingPeerB = EthProtocolManagerTestUtil.createPeer(ethProtocolManager, 1000, peerValidator);
respondingPeerB.getEthPeer().markValidated(peerValidator);
// When our new peer "connects", it is not yet valid, so we need to expire our retry timeout
// so that the peer will get re-processed
EthProtocolManagerTestUtil.expirePendingTimeouts(ethProtocolManager);
assertThat(respondingPeerB.hasOutstandingRequests()).isTrue();
respondingPeerB.respond(responder);
// We need one more responsive peer before we're done
assertThat(future).isNotCompleted();
assertThat(badPeerA.hasOutstandingRequests()).isFalse();
assertThat(badPeerB.hasOutstandingRequests()).isFalse();
// Add new peer that we can query
final RespondingEthPeer respondingPeerC = EthProtocolManagerTestUtil.createPeer(ethProtocolManager, 1000, peerValidator);
respondingPeerC.getEthPeer().markValidated(peerValidator);
EthProtocolManagerTestUtil.expirePendingTimeouts(ethProtocolManager);
assertThat(respondingPeerC.hasOutstandingRequests()).isTrue();
respondingPeerC.respond(responder);
assertThat(badPeerA.hasOutstandingRequests()).isFalse();
assertThat(badPeerB.hasOutstandingRequests()).isFalse();
assertThat(future).isCompletedWithValue(new FastSyncState(blockchain.getBlockHeader(PIVOT_BLOCK_NUMBER).get()));
}
Aggregations