Search in sources :

Example 1 with Responder

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()));
}
Also used : RespondingEthPeer(org.hyperledger.besu.ethereum.eth.manager.RespondingEthPeer) Responder(org.hyperledger.besu.ethereum.eth.manager.RespondingEthPeer.Responder) Test(org.junit.Test)

Example 2 with Responder

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);
}
Also used : Arrays(java.util.Arrays) Assertions.assertThat(org.assertj.core.api.Assertions.assertThat) RunWith(org.junit.runner.RunWith) Parameters(org.junit.runners.Parameterized.Parameters) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) CompletableFuture(java.util.concurrent.CompletableFuture) NoOpMetricsSystem(org.hyperledger.besu.metrics.noop.NoOpMetricsSystem) Bytes(org.apache.tuweni.bytes.Bytes) Mockito.spy(org.mockito.Mockito.spy) ExceptionUtils(org.hyperledger.besu.util.ExceptionUtils) EthProtocolManagerTestUtil(org.hyperledger.besu.ethereum.eth.manager.EthProtocolManagerTestUtil) ProtocolSchedule(org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule) Responder(org.hyperledger.besu.ethereum.eth.manager.RespondingEthPeer.Responder) BlockchainSetupUtil(org.hyperledger.besu.ethereum.core.BlockchainSetupUtil) DataStorageFormat(org.hyperledger.besu.ethereum.worldstate.DataStorageFormat) Assertions.assertThatThrownBy(org.assertj.core.api.Assertions.assertThatThrownBy) Parameterized(org.junit.runners.Parameterized) Before(org.junit.Before) Difficulty(org.hyperledger.besu.ethereum.core.Difficulty) TransactionPool(org.hyperledger.besu.ethereum.eth.transactions.TransactionPool) EthProtocolConfiguration(org.hyperledger.besu.ethereum.eth.EthProtocolConfiguration) Collection(java.util.Collection) Blockchain(org.hyperledger.besu.ethereum.chain.Blockchain) Test(org.junit.Test) Mockito.when(org.mockito.Mockito.when) BlockHeaderTestFixture(org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture) RespondingEthPeer(org.hyperledger.besu.ethereum.eth.manager.RespondingEthPeer) EthProtocolManager(org.hyperledger.besu.ethereum.eth.manager.EthProtocolManager) PeerValidator(org.hyperledger.besu.ethereum.eth.peervalidation.PeerValidator) ProtocolContext(org.hyperledger.besu.ethereum.ProtocolContext) Optional(java.util.Optional) MetricsSystem(org.hyperledger.besu.plugin.services.MetricsSystem) MutableBlockchain(org.hyperledger.besu.ethereum.chain.MutableBlockchain) Mockito.mock(org.mockito.Mockito.mock) RespondingEthPeer(org.hyperledger.besu.ethereum.eth.manager.RespondingEthPeer) Responder(org.hyperledger.besu.ethereum.eth.manager.RespondingEthPeer.Responder) Test(org.junit.Test)

Example 3 with Responder

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()));
}
Also used : RespondingEthPeer(org.hyperledger.besu.ethereum.eth.manager.RespondingEthPeer) Responder(org.hyperledger.besu.ethereum.eth.manager.RespondingEthPeer.Responder) Test(org.junit.Test)

Example 4 with Responder

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()));
}
Also used : RespondingEthPeer(org.hyperledger.besu.ethereum.eth.manager.RespondingEthPeer) Responder(org.hyperledger.besu.ethereum.eth.manager.RespondingEthPeer.Responder) Test(org.junit.Test)

Example 5 with Responder

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()));
}
Also used : PeerValidator(org.hyperledger.besu.ethereum.eth.peervalidation.PeerValidator) RespondingEthPeer(org.hyperledger.besu.ethereum.eth.manager.RespondingEthPeer) Responder(org.hyperledger.besu.ethereum.eth.manager.RespondingEthPeer.Responder) Test(org.junit.Test)

Aggregations

Responder (org.hyperledger.besu.ethereum.eth.manager.RespondingEthPeer.Responder)33 Test (org.junit.Test)33 RespondingEthPeer (org.hyperledger.besu.ethereum.eth.manager.RespondingEthPeer)30 Block (org.hyperledger.besu.ethereum.core.Block)16 NewBlockMessage (org.hyperledger.besu.ethereum.eth.messages.NewBlockMessage)11 NewBlockHashesMessage (org.hyperledger.besu.ethereum.eth.messages.NewBlockHashesMessage)8 Bytes (org.apache.tuweni.bytes.Bytes)4 Difficulty (org.hyperledger.besu.ethereum.core.Difficulty)4 ProtocolSchedule (org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule)4 BlockDataGenerator (org.hyperledger.besu.ethereum.core.BlockDataGenerator)3 PeerValidator (org.hyperledger.besu.ethereum.eth.peervalidation.PeerValidator)3 Arrays (java.util.Arrays)2 Collection (java.util.Collection)2 Optional (java.util.Optional)2 CompletableFuture (java.util.concurrent.CompletableFuture)2 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)2 Assertions.assertThat (org.assertj.core.api.Assertions.assertThat)2 Assertions.assertThatThrownBy (org.assertj.core.api.Assertions.assertThatThrownBy)2 ProtocolContext (org.hyperledger.besu.ethereum.ProtocolContext)2 Blockchain (org.hyperledger.besu.ethereum.chain.Blockchain)2