Search in sources :

Example 1 with ONE

use of tech.pegasys.teku.infrastructure.unsigned.UInt64.ONE in project teku by ConsenSys.

the class SyncStallDetector method performStallCheck.

/**
 * We consider a sync stalled if it has not made progress in X seconds. Progress is tracked based
 * on getting new blocks onto the chain.
 */
private void performStallCheck() {
    eventThread.checkOnEventThread();
    if (!syncController.isSyncActive()) {
        LOG.debug("Not performing sync stall check as sync is not active");
        return;
    }
    // Check if a new batch has started importing since the last stall check
    final Optional<Batch> newImportingBatch = sync.getImportingBatch();
    if (!currentBatchImport.map(d -> d.importingBatch).equals(newImportingBatch)) {
        LOG.debug("Detected new batch being imported, sync is not stalled.");
        // New batch being imported so we must be making progress
        currentBatchImport = newImportingBatch.map(BatchImportData::new);
        return;
    }
    // Stall case 1 - no import started more than X seconds after last one completed
    final UInt64 secondsSinceLastCompletedImport = timeProvider.getTimeInSeconds().minusMinZero(sync.getLastImportTimerStartPointSeconds());
    if (currentBatchImport.isEmpty() && secondsSinceLastCompletedImport.isGreaterThan(MAX_SECONDS_BETWEEN_IMPORTS)) {
        LOG.warn("Sync has not started a batch importing for {} seconds after the previous batch import completed. Considering it stalled and restarting sync.", secondsSinceLastCompletedImport);
        sync.abort();
        return;
    }
    // Stall case 2 - an import was started but hasn't imported a new block for more than X seconds
    currentBatchImport.ifPresent(currentImport -> {
        final UInt64 timeSinceLastProgress = currentImport.calculateSecondsSinceLastProgress();
        if (timeSinceLastProgress.isGreaterThan(MAX_SECONDS_BETWEEN_IMPORT_PROGRESS)) {
            LOG.warn("Sync has not made progress importing batch {} for {} seconds after the previous batch import completed. Considering it stalled and restarting sync.", currentImport, secondsSinceLastCompletedImport);
            sync.abort();
        }
    });
}
Also used : Batch(tech.pegasys.teku.beacon.sync.forward.multipeer.batches.Batch) UInt64(tech.pegasys.teku.infrastructure.unsigned.UInt64)

Example 2 with ONE

use of tech.pegasys.teku.infrastructure.unsigned.UInt64.ONE in project teku by ConsenSys.

the class BlockPropagationIntegrationTest method shouldFetchUnknownAncestorsOfPropagatedBlock.

@Test
public void shouldFetchUnknownAncestorsOfPropagatedBlock() throws Exception {
    final GossipEncoding gossipEncoding = GossipEncoding.SSZ_SNAPPY;
    UInt64 currentSlot = SpecConfig.GENESIS_SLOT;
    // Setup node 1
    SyncingNodeManager node1 = SyncingNodeManager.create(asyncRunner, networkFactory, validatorKeys, c -> c.rpcEncoding(rpcEncoding).gossipEncoding(gossipEncoding));
    node1.chainUtil().setSlot(currentSlot);
    // Add some blocks to node1, which node 2 will need to fetch
    final List<SignedBeaconBlock> blocksToFetch = new ArrayList<>();
    for (int i = 0; i < 3; i++) {
        currentSlot = currentSlot.plus(UInt64.ONE);
        final SignedBeaconBlock block = node1.chainUtil().createAndImportBlockAtSlot(currentSlot);
        blocksToFetch.add(block);
    }
    // Setup node 2
    SyncingNodeManager node2 = SyncingNodeManager.create(asyncRunner, networkFactory, validatorKeys, c -> c.rpcEncoding(rpcEncoding).gossipEncoding(gossipEncoding));
    // Connect networks
    Waiter.waitFor(node1.connect(node2));
    // Wait for connections to get set up
    Waiter.waitFor(() -> {
        assertThat(node1.network().getPeerCount()).isEqualTo(1);
        assertThat(node2.network().getPeerCount()).isEqualTo(1);
    });
    // Wait for subscriptions to complete (jvm-libp2p does this asynchronously)
    Thread.sleep(2000);
    // Update slot so that blocks can be imported
    currentSlot = currentSlot.plus(UInt64.ONE);
    node1.setSlot(currentSlot);
    node2.setSlot(currentSlot);
    // Propagate new block
    final SignedBeaconBlock newBlock = node1.chainUtil().createBlockAtSlot(currentSlot);
    node1.gossipBlock(newBlock);
    // Verify that node2 fetches required blocks in response
    Waiter.waitFor(() -> {
        for (SignedBeaconBlock block : blocksToFetch) {
            final Bytes32 blockRoot = block.getMessage().hashTreeRoot();
            assertThatSafeFuture(node2.recentChainData().retrieveBlockByRoot(blockRoot)).isCompletedWithNonEmptyOptional();
        }
        // Last block should be imported as well
        final Bytes32 newBlockRoot = newBlock.getMessage().hashTreeRoot();
        assertThatSafeFuture(node2.recentChainData().retrieveBlockByRoot(newBlockRoot)).isCompletedWithNonEmptyOptional();
    });
}
Also used : GossipEncoding(tech.pegasys.teku.networking.eth2.gossip.encoding.GossipEncoding) ArrayList(java.util.ArrayList) UInt64(tech.pegasys.teku.infrastructure.unsigned.UInt64) SignedBeaconBlock(tech.pegasys.teku.spec.datastructures.blocks.SignedBeaconBlock) Bytes32(org.apache.tuweni.bytes.Bytes32) Test(org.junit.jupiter.api.Test)

Example 3 with ONE

use of tech.pegasys.teku.infrastructure.unsigned.UInt64.ONE in project teku by ConsenSys.

the class PeerSyncTest method sync_stopSyncIfPeerSendsBlocksInWrongOrder.

@Test
void sync_stopSyncIfPeerSendsBlocksInWrongOrder() {
    final UInt64 startSlot = UInt64.ONE;
    UInt64 peerHeadSlot = UInt64.valueOf(1000000);
    withPeerHeadSlot(peerHeadSlot);
    final SafeFuture<Void> requestFuture = new SafeFuture<>();
    when(peer.requestBlocksByRange(any(), any(), any(), any())).thenReturn(requestFuture);
    final SafeFuture<PeerSyncResult> syncFuture = peerSync.sync(peer);
    assertThat(syncFuture).isNotDone();
    verify(peer).requestBlocksByRange(eq(startSlot), eq(MAX_BLOCK_BY_RANGE_REQUEST_SIZE), eq(UInt64.ONE), responseListenerArgumentCaptor.capture());
    requestFuture.completeExceptionally(new BlocksByRangeResponseInvalidResponseException(peer, BlocksByRangeResponseInvalidResponseException.InvalidResponseType.BLOCK_SLOT_NOT_GREATER_THAN_PREVIOUS_BLOCK_SLOT));
    // Peer returns some blocks but they are not ordered
    assertThat(syncFuture).isCompletedWithValue(PeerSyncResult.INVALID_RESPONSE);
    verify(peer).disconnectCleanly(any());
}
Also used : SafeFuture(tech.pegasys.teku.infrastructure.async.SafeFuture) BlocksByRangeResponseInvalidResponseException(tech.pegasys.teku.networking.eth2.rpc.beaconchain.methods.BlocksByRangeResponseInvalidResponseException) UInt64(tech.pegasys.teku.infrastructure.unsigned.UInt64) Test(org.junit.jupiter.api.Test)

Example 4 with ONE

use of tech.pegasys.teku.infrastructure.unsigned.UInt64.ONE in project teku by ConsenSys.

the class PeerSyncTest method sync_longSyncWithTwoRequests.

@Test
void sync_longSyncWithTwoRequests() {
    final UInt64 secondRequestSize = UInt64.ONE;
    UInt64 peerHeadSlot = MAX_BLOCK_BY_RANGE_REQUEST_SIZE.plus(secondRequestSize);
    withPeerHeadSlot(peerHeadSlot);
    final SafeFuture<Void> requestFuture1 = new SafeFuture<>();
    final SafeFuture<Void> requestFuture2 = new SafeFuture<>();
    when(peer.requestBlocksByRange(any(), any(), any(), any())).thenReturn(requestFuture1).thenReturn(requestFuture2);
    final SafeFuture<PeerSyncResult> syncFuture = peerSync.sync(peer);
    assertThat(syncFuture).isNotDone();
    final UInt64 startSlot = UInt64.ONE;
    verify(peer).requestBlocksByRange(eq(startSlot), eq(MAX_BLOCK_BY_RANGE_REQUEST_SIZE), eq(UInt64.ONE), responseListenerArgumentCaptor.capture());
    final int lastReceivedBlockSlot = peerHeadSlot.intValue() - secondRequestSize.intValue();
    completeRequestWithBlockAtSlot(requestFuture1, lastReceivedBlockSlot);
    final UInt64 nextSlotStart = UInt64.valueOf(lastReceivedBlockSlot + 1);
    verify(peer).requestBlocksByRange(eq(nextSlotStart), eq(secondRequestSize), eq(UInt64.ONE), responseListenerArgumentCaptor.capture());
    when(storageClient.getFinalizedEpoch()).thenReturn(PEER_FINALIZED_EPOCH);
    // Respond with blocks and check they're passed to the block importer.
    completeRequestWithBlockAtSlot(requestFuture2, peerHeadSlot.intValue());
    // Check that the sync is done and the peer was not disconnected.
    assertThat(syncFuture).isCompleted();
    verify(peer, never()).disconnectCleanly(any());
}
Also used : SafeFuture(tech.pegasys.teku.infrastructure.async.SafeFuture) UInt64(tech.pegasys.teku.infrastructure.unsigned.UInt64) Test(org.junit.jupiter.api.Test)

Example 5 with ONE

use of tech.pegasys.teku.infrastructure.unsigned.UInt64.ONE in project teku by ConsenSys.

the class PeerSyncTest method sync_continueSyncIfPeerThrottlesAReasonableAmount.

@Test
void sync_continueSyncIfPeerThrottlesAReasonableAmount() {
    final UInt64 startSlot = UInt64.ONE;
    UInt64 peerHeadSlot = UInt64.valueOf(1000000);
    withPeerHeadSlot(peerHeadSlot);
    final SafeFuture<Void> requestFuture1 = new SafeFuture<>();
    final SafeFuture<Void> requestFuture2 = new SafeFuture<>();
    when(peer.requestBlocksByRange(any(), any(), any(), any())).thenReturn(requestFuture1).thenReturn(requestFuture2);
    final SafeFuture<PeerSyncResult> syncFuture = peerSync.sync(peer);
    assertThat(syncFuture).isNotDone();
    verify(peer).requestBlocksByRange(eq(startSlot), eq(MAX_BLOCK_BY_RANGE_REQUEST_SIZE), eq(UInt64.ONE), responseListenerArgumentCaptor.capture());
    // Peer only returns some blocks but not as many as were requested
    final int lastReceivedBlockSlot = 70;
    completeRequestWithBlockAtSlot(requestFuture1, lastReceivedBlockSlot);
    assertThat(syncFuture).isNotDone();
    // Next request should start after the last received block
    verify(peer).requestBlocksByRange(eq(UInt64.valueOf(lastReceivedBlockSlot + 1)), eq(MAX_BLOCK_BY_RANGE_REQUEST_SIZE), eq(UInt64.ONE), any());
    verify(peer, never()).disconnectCleanly(any());
}
Also used : SafeFuture(tech.pegasys.teku.infrastructure.async.SafeFuture) UInt64(tech.pegasys.teku.infrastructure.unsigned.UInt64) Test(org.junit.jupiter.api.Test)

Aggregations

UInt64 (tech.pegasys.teku.infrastructure.unsigned.UInt64)204 Test (org.junit.jupiter.api.Test)149 SignedBeaconBlock (tech.pegasys.teku.spec.datastructures.blocks.SignedBeaconBlock)45 SignedBlockAndState (tech.pegasys.teku.spec.datastructures.blocks.SignedBlockAndState)42 Bytes32 (org.apache.tuweni.bytes.Bytes32)36 Checkpoint (tech.pegasys.teku.spec.datastructures.state.Checkpoint)36 BeaconState (tech.pegasys.teku.spec.datastructures.state.beaconstate.BeaconState)32 Optional (java.util.Optional)31 SafeFuture (tech.pegasys.teku.infrastructure.async.SafeFuture)20 Attestation (tech.pegasys.teku.spec.datastructures.operations.Attestation)15 ArrayList (java.util.ArrayList)14 StoreTransaction (tech.pegasys.teku.storage.store.UpdatableStore.StoreTransaction)14 ParameterizedTest (org.junit.jupiter.params.ParameterizedTest)13 Spec (tech.pegasys.teku.spec.Spec)12 MockResponse (okhttp3.mockwebserver.MockResponse)11 ValidateableAttestation (tech.pegasys.teku.spec.datastructures.attestation.ValidateableAttestation)11 RecentChainData (tech.pegasys.teku.storage.client.RecentChainData)11 List (java.util.List)9 TestTemplate (org.junit.jupiter.api.TestTemplate)9 LogManager (org.apache.logging.log4j.LogManager)8