use of org.hyperledger.besu.ethereum.eth.manager.EthContext in project besu by hyperledger.
the class PendingTransactionsSenderTest method testSendEth65PeersOnly.
@Test
public void testSendEth65PeersOnly() {
PeerPendingTransactionTracker peerPendingTransactionTracker = mock(PeerPendingTransactionTracker.class);
PendingTransactionsMessageSender pendingTransactionsMessageSender = mock(PendingTransactionsMessageSender.class);
EthContext ethContext = mock(EthContext.class);
EthScheduler ethScheduler = mock(EthScheduler.class);
when(ethContext.getScheduler()).thenReturn(ethScheduler);
PendingTransactionSender sender = new PendingTransactionSender(peerPendingTransactionTracker, pendingTransactionsMessageSender, ethContext);
EthPeer peer1 = mock(EthPeer.class);
EthPeer peer2 = mock(EthPeer.class);
Transaction tx = mock(Transaction.class);
Hash hash = Hash.wrap(Bytes32.random());
when(tx.getHash()).thenReturn(hash);
EthPeers ethPeers = mock(EthPeers.class);
when(ethContext.getEthPeers()).thenReturn(ethPeers);
when(ethPeers.streamAvailablePeers()).thenReturn(Arrays.asList(peer1, peer2).stream());
when(peerPendingTransactionTracker.isPeerSupported(peer1, EthProtocol.ETH65)).thenReturn(true);
when(peerPendingTransactionTracker.isPeerSupported(peer2, EthProtocol.ETH65)).thenReturn(false);
sender.onTransactionsAdded(Collections.singleton(tx));
verify(peerPendingTransactionTracker, times(1)).addToPeerSendQueue(peer1, hash);
verify(peerPendingTransactionTracker, never()).addToPeerSendQueue(peer2, hash);
}
use of org.hyperledger.besu.ethereum.eth.manager.EthContext in project besu by hyperledger.
the class Istanbul99ProtocolManagerTest method respondToEth65GetHeadersUsingIstanbul99.
@Test
public void respondToEth65GetHeadersUsingIstanbul99() throws ExecutionException, InterruptedException, TimeoutException {
final CompletableFuture<Void> done = new CompletableFuture<>();
final EthScheduler ethScheduler = new DeterministicEthScheduler(() -> false);
EthPeers peers = new EthPeers(Istanbul99Protocol.NAME, TestClock.fixed(), new NoOpMetricsSystem(), 25);
EthMessages messages = new EthMessages();
final BigInteger networkId = BigInteger.ONE;
try (final EthProtocolManager ethManager = new Istanbul99ProtocolManager(blockchain, networkId, protocolContext.getWorldStateArchive(), transactionPool, EthProtocolConfiguration.defaultConfig(), peers, messages, new EthContext(peers, messages, ethScheduler), Collections.emptyList(), false, ethScheduler)) {
final long startBlock = blockchain.getChainHeadBlockNumber() + 1;
final int blockCount = 5;
final MessageData messageData = GetBlockHeadersMessage.create(startBlock, blockCount, 0, false);
final PeerSendHandler onSend = (cap, message, conn) -> {
if (message.getCode() == EthPV62.STATUS) {
// Ignore status message
return;
}
assertThat(message.getCode()).isEqualTo(EthPV62.BLOCK_HEADERS);
final BlockHeadersMessage headersMsg = BlockHeadersMessage.readFrom(message);
final List<BlockHeader> headers = Lists.newArrayList(headersMsg.getHeaders(protocolSchedule));
assertThat(headers.size()).isEqualTo(0);
done.complete(null);
};
final PeerConnection peer = setupPeer(ethManager, onSend);
ethManager.processMessage(Istanbul99Protocol.ISTANBUL99, new DefaultMessage(peer, messageData));
done.get(10, TimeUnit.SECONDS);
}
}
use of org.hyperledger.besu.ethereum.eth.manager.EthContext in project besu by hyperledger.
the class FastSyncTargetManager method confirmPivotBlockHeader.
private CompletableFuture<Optional<EthPeer>> confirmPivotBlockHeader(final EthPeer bestPeer) {
final BlockHeader pivotBlockHeader = fastSyncState.getPivotBlockHeader().get();
final RetryingGetHeaderFromPeerByNumberTask task = RetryingGetHeaderFromPeerByNumberTask.forSingleNumber(protocolSchedule, ethContext, metricsSystem, pivotBlockHeader.getNumber(), MAX_QUERY_RETRIES_PER_PEER);
task.assignPeer(bestPeer);
return ethContext.getScheduler().timeout(task).thenCompose(result -> {
if (peerHasDifferentPivotBlock(result)) {
if (!hasPivotChanged(pivotBlockHeader)) {
// if the pivot block has not changed, then warn and disconnect this peer
LOG.warn("Best peer has wrong pivot block (#{}) expecting {} but received {}. Disconnect: {}", pivotBlockHeader.getNumber(), pivotBlockHeader.getHash(), result.size() == 1 ? result.get(0).getHash() : "invalid response", bestPeer);
bestPeer.disconnect(DisconnectReason.USELESS_PEER);
return CompletableFuture.completedFuture(Optional.<EthPeer>empty());
}
LOG.debug("Retrying best peer {} with new pivot block {}", bestPeer.getShortNodeId(), pivotBlockHeader.toLogString());
return confirmPivotBlockHeader(bestPeer);
} else {
return CompletableFuture.completedFuture(Optional.of(bestPeer));
}
}).exceptionally(error -> {
LOG.debug("Could not confirm best peer had pivot block", error);
return Optional.empty();
});
}
use of org.hyperledger.besu.ethereum.eth.manager.EthContext in project besu by hyperledger.
the class PivotBlockConfirmer method executePivotQuery.
private CompletableFuture<BlockHeader> executePivotQuery(final long blockNumber) {
if (isCancelled.get() || result.isDone()) {
// Stop loop if this task is done
return CompletableFuture.failedFuture(new CancellationException());
}
final Optional<RetryingGetHeaderFromPeerByNumberTask> query = createPivotQuery(blockNumber);
final CompletableFuture<BlockHeader> pivotHeaderFuture;
if (query.isPresent()) {
final CompletableFuture<BlockHeader> headerQuery = query.get().getHeader();
pivotHeaderFuture = FutureUtils.exceptionallyCompose(headerQuery, (error) -> executePivotQuery(blockNumber));
} else {
// We were unable to find a peer to query, wait and try again
LOG.debug("No peer currently available to query for block {}.", blockNumber);
pivotHeaderFuture = ethContext.getScheduler().timeout(WaitForPeerTask.create(ethContext, metricsSystem), Duration.ofSeconds(5)).handle(// Ignore result
(err, res) -> null).thenCompose(res -> executePivotQuery(blockNumber));
}
return pivotHeaderFuture;
}
use of org.hyperledger.besu.ethereum.eth.manager.EthContext in project besu by hyperledger.
the class BlockPropagationManager method getBlockFromPeers.
private CompletableFuture<Block> getBlockFromPeers(final Optional<EthPeer> preferredPeer, final long blockNumber, final Optional<Hash> blockHash) {
final RetryingGetBlockFromPeersTask getBlockTask = RetryingGetBlockFromPeersTask.create(protocolContext, protocolSchedule, ethContext, metricsSystem, ethContext.getEthPeers().getMaxPeers(), blockHash, blockNumber);
preferredPeer.ifPresent(getBlockTask::assignPeer);
return ethContext.getScheduler().scheduleSyncWorkerTask(getBlockTask::run).thenCompose(r -> importOrSavePendingBlock(r.getResult(), r.getPeer().nodeId())).whenComplete((r, t) -> {
requestedNonAnnouncedBlocks.remove(blockNumber);
blockHash.ifPresentOrElse(requestedBlocks::remove, () -> {
if (r != null) {
// in case we successfully retrieved only by block number, when can remove
// the request by hash too
requestedBlocks.remove(r.getHash());
}
});
});
}
Aggregations