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();
}
});
}
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();
});
}
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());
}
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());
}
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());
}
Aggregations