Search in sources :

Example 1 with MockExecutorService

use of org.hyperledger.besu.testutil.MockExecutorService in project besu by hyperledger.

the class FastWorldStateDownloaderTest method testCancellation.

@SuppressWarnings("unchecked")
private void testCancellation(final boolean shouldCancelFuture) {
    final EthProtocolManager ethProtocolManager = EthProtocolManagerTestUtil.create();
    // Prevent the persistence service from running
    final MockExecutorService serviceExecutor = ((DeterministicEthScheduler) ethProtocolManager.ethContext().getScheduler()).mockServiceExecutor();
    serviceExecutor.setAutoRun(false);
    // Setup "remote" state
    final WorldStateArchive remoteWorldStateArchive = createInMemoryWorldStateArchive();
    final MutableWorldState remoteWorldState = remoteWorldStateArchive.getMutable();
    // Generate accounts and save corresponding state root
    dataGen.createRandomContractAccountsWithNonEmptyStorage(remoteWorldState, 20);
    final Hash stateRoot = remoteWorldState.rootHash();
    final BlockHeader header = dataGen.block(BlockOptions.create().setStateRoot(stateRoot).setBlockNumber(10)).getHeader();
    // Create some peers
    final List<RespondingEthPeer> peers = Stream.generate(() -> EthProtocolManagerTestUtil.createPeer(ethProtocolManager, header.getNumber())).limit(5).collect(Collectors.toList());
    final InMemoryTasksPriorityQueues<NodeDataRequest> taskCollection = new InMemoryTasksPriorityQueues<>();
    final WorldStateStorage localStorage = new WorldStateKeyValueStorage(new InMemoryKeyValueStorage());
    final WorldStateDownloader downloader = createDownloader(ethProtocolManager.ethContext(), localStorage, taskCollection);
    final FastSyncState fastSyncState = new FastSyncState(header);
    final CompletableFuture<Void> result = downloader.run(null, fastSyncState);
    // Send a few responses
    final RespondingEthPeer.Responder responder = RespondingEthPeer.blockchainResponder(mock(Blockchain.class), remoteWorldStateArchive);
    for (int i = 0; i < 3; i++) {
        for (final RespondingEthPeer peer : peers) {
            peer.respond(responder);
        }
        giveOtherThreadsAGo();
    }
    // Sanity check
    assertThat(result.isDone()).isFalse();
    // Reset taskCollection so we can track interactions after the cancellation
    reset(taskCollection);
    if (shouldCancelFuture) {
        result.cancel(true);
    } else {
        downloader.cancel();
        assertThat(result).isCancelled();
    }
    // Send some more responses after cancelling
    for (int i = 0; i < 3; i++) {
        for (final RespondingEthPeer peer : peers) {
            peer.respond(responder);
        }
        giveOtherThreadsAGo();
    }
    // Now allow the persistence service to run which should exit immediately
    serviceExecutor.runPendingFutures();
    verify(taskCollection, times(1)).clear();
    verify(taskCollection, never()).remove();
    verify(taskCollection, never()).add(any(NodeDataRequest.class));
    // Target world state should not be available
    assertThat(localStorage.isWorldStateAvailable(header.getStateRoot(), header.getHash())).isFalse();
}
Also used : WorldStateStorage(org.hyperledger.besu.ethereum.worldstate.WorldStateStorage) MutableWorldState(org.hyperledger.besu.ethereum.core.MutableWorldState) InMemoryKeyValueStorage(org.hyperledger.besu.services.kvstore.InMemoryKeyValueStorage) RespondingEthPeer(org.hyperledger.besu.ethereum.eth.manager.RespondingEthPeer) Blockchain(org.hyperledger.besu.ethereum.chain.Blockchain) DeterministicEthScheduler(org.hyperledger.besu.ethereum.eth.manager.DeterministicEthScheduler) InMemoryTasksPriorityQueues(org.hyperledger.besu.services.tasks.InMemoryTasksPriorityQueues) Hash(org.hyperledger.besu.datatypes.Hash) WorldStateDownloader(org.hyperledger.besu.ethereum.eth.sync.worldstate.WorldStateDownloader) FastSyncState(org.hyperledger.besu.ethereum.eth.sync.fastsync.FastSyncState) EthProtocolManager(org.hyperledger.besu.ethereum.eth.manager.EthProtocolManager) WorldStateKeyValueStorage(org.hyperledger.besu.ethereum.storage.keyvalue.WorldStateKeyValueStorage) InMemoryKeyValueStorageProvider.createInMemoryWorldStateArchive(org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider.createInMemoryWorldStateArchive) DefaultWorldStateArchive(org.hyperledger.besu.ethereum.worldstate.DefaultWorldStateArchive) WorldStateArchive(org.hyperledger.besu.ethereum.worldstate.WorldStateArchive) MockExecutorService(org.hyperledger.besu.testutil.MockExecutorService) BlockHeader(org.hyperledger.besu.ethereum.core.BlockHeader)

Example 2 with MockExecutorService

use of org.hyperledger.besu.testutil.MockExecutorService in project besu by hyperledger.

the class FastWorldStateDownloaderTest method canRecoverFromTimeouts.

@Test
public void canRecoverFromTimeouts() {
    final DeterministicEthScheduler.TimeoutPolicy timeoutPolicy = DeterministicEthScheduler.TimeoutPolicy.timeoutXTimes(2);
    final EthProtocolManager ethProtocolManager = EthProtocolManagerTestUtil.create(timeoutPolicy);
    final MockExecutorService serviceExecutor = ((DeterministicEthScheduler) ethProtocolManager.ethContext().getScheduler()).mockServiceExecutor();
    serviceExecutor.setAutoRun(false);
    // Setup "remote" state
    final WorldStateArchive remoteWorldStateArchive = createInMemoryWorldStateArchive();
    final MutableWorldState remoteWorldState = remoteWorldStateArchive.getMutable();
    // Generate accounts and save corresponding state root
    final List<Account> accounts = dataGen.createRandomAccounts(remoteWorldState, 20);
    final Hash stateRoot = remoteWorldState.rootHash();
    // Sanity check
    assertThat(stateRoot).isNotEqualTo(EMPTY_TRIE_ROOT);
    final BlockHeader header = dataGen.block(BlockOptions.create().setStateRoot(stateRoot).setBlockNumber(10)).getHeader();
    // Create some peers
    final List<RespondingEthPeer> peers = Stream.generate(() -> EthProtocolManagerTestUtil.createPeer(ethProtocolManager, header.getNumber())).limit(5).collect(Collectors.toList());
    final InMemoryTasksPriorityQueues<NodeDataRequest> taskCollection = new InMemoryTasksPriorityQueues<>();
    final WorldStateStorage localStorage = new WorldStateKeyValueStorage(new InMemoryKeyValueStorage());
    final WorldStateDownloader downloader = createDownloader(ethProtocolManager.ethContext(), localStorage, taskCollection);
    final FastSyncState fastSyncState = new FastSyncState(header);
    final CompletableFuture<Void> result = downloader.run(null, fastSyncState);
    serviceExecutor.runPendingFuturesInSeparateThreads(persistenceThread);
    // Respond to node data requests
    final RespondingEthPeer.Responder responder = RespondingEthPeer.blockchainResponder(mock(Blockchain.class), remoteWorldStateArchive);
    respondUntilDone(peers, responder, result);
    // Check that all expected account data was downloaded
    final WorldStateArchive localWorldStateArchive = new DefaultWorldStateArchive(localStorage, createPreimageStorage());
    final WorldState localWorldState = localWorldStateArchive.get(stateRoot, null).get();
    assertThat(result).isDone();
    assertAccountsMatch(localWorldState, accounts);
}
Also used : Account(org.hyperledger.besu.evm.account.Account) WorldStateStorage(org.hyperledger.besu.ethereum.worldstate.WorldStateStorage) MutableWorldState(org.hyperledger.besu.ethereum.core.MutableWorldState) RespondingEthPeer(org.hyperledger.besu.ethereum.eth.manager.RespondingEthPeer) Blockchain(org.hyperledger.besu.ethereum.chain.Blockchain) DeterministicEthScheduler(org.hyperledger.besu.ethereum.eth.manager.DeterministicEthScheduler) WorldState(org.hyperledger.besu.evm.worldstate.WorldState) MutableWorldState(org.hyperledger.besu.ethereum.core.MutableWorldState) Hash(org.hyperledger.besu.datatypes.Hash) WorldStateDownloader(org.hyperledger.besu.ethereum.eth.sync.worldstate.WorldStateDownloader) EthProtocolManager(org.hyperledger.besu.ethereum.eth.manager.EthProtocolManager) WorldStateKeyValueStorage(org.hyperledger.besu.ethereum.storage.keyvalue.WorldStateKeyValueStorage) BlockHeader(org.hyperledger.besu.ethereum.core.BlockHeader) DefaultWorldStateArchive(org.hyperledger.besu.ethereum.worldstate.DefaultWorldStateArchive) InMemoryKeyValueStorage(org.hyperledger.besu.services.kvstore.InMemoryKeyValueStorage) InMemoryTasksPriorityQueues(org.hyperledger.besu.services.tasks.InMemoryTasksPriorityQueues) FastSyncState(org.hyperledger.besu.ethereum.eth.sync.fastsync.FastSyncState) InMemoryKeyValueStorageProvider.createInMemoryWorldStateArchive(org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider.createInMemoryWorldStateArchive) DefaultWorldStateArchive(org.hyperledger.besu.ethereum.worldstate.DefaultWorldStateArchive) WorldStateArchive(org.hyperledger.besu.ethereum.worldstate.WorldStateArchive) MockExecutorService(org.hyperledger.besu.testutil.MockExecutorService) Test(org.junit.Test)

Example 3 with MockExecutorService

use of org.hyperledger.besu.testutil.MockExecutorService in project besu by hyperledger.

the class PrunerIntegrationTest method testPruner.

private void testPruner(final int numCycles, final int accountsPerBlock, final int blockConfirmations, final int numBlocksToKeep, final int opsPerTransaction) {
    final var markSweepPruner = new MarkSweepPruner(worldStateStorage, blockchain, markStorage, metricsSystem, opsPerTransaction);
    final var pruner = new Pruner(markSweepPruner, blockchain, new PrunerConfiguration(blockConfirmations, numBlocksToKeep), new MockExecutorService());
    pruner.start();
    for (int cycle = 0; cycle < numCycles; ++cycle) {
        int numBlockInCycle = numBlocksToKeep + // +1 to get it to switch from MARKING_COMPLETE TO SWEEPING on each cycle
        1;
        var fullyMarkedBlockNum = cycle * numBlockInCycle + 1;
        // This should cause a full mark and sweep cycle
        assertThat(pruner.getPruningPhase()).isEqualByComparingTo(PruningPhase.IDLE);
        generateBlockchainData(numBlockInCycle, accountsPerBlock);
        assertThat(pruner.getPruningPhase()).isEqualByComparingTo(PruningPhase.IDLE);
        // Collect the nodes we expect to keep
        final Set<Bytes> expectedNodes = new HashSet<>();
        for (int i = fullyMarkedBlockNum; i <= blockchain.getChainHeadBlockNumber(); i++) {
            final Hash stateRoot = blockchain.getBlockHeader(i).get().getStateRoot();
            collectWorldStateNodes(stateRoot, expectedNodes);
        }
        if (accountsPerBlock != 0) {
            assertThat(hashValueStore.size()).isGreaterThanOrEqualTo(// Sanity check
            expectedNodes.size());
        }
        // Assert that blocks from mark point onward are still accessible
        for (int i = fullyMarkedBlockNum; i <= blockchain.getChainHeadBlockNumber(); i++) {
            final BlockHeader blockHeader = blockchain.getBlockHeader(i).get();
            final Hash stateRoot = blockHeader.getStateRoot();
            assertThat(worldStateArchive.get(stateRoot, blockHeader.getHash())).isPresent();
            final WorldState markedState = worldStateArchive.get(stateRoot, blockHeader.getHash()).get();
            // Traverse accounts and make sure all are accessible
            final int expectedAccounts = accountsPerBlock * i;
            final long accounts = markedState.streamAccounts(Bytes32.ZERO, expectedAccounts * 2).count();
            assertThat(accounts).isEqualTo(expectedAccounts);
            // Traverse storage to ensure that all storage is accessible
            markedState.streamAccounts(Bytes32.ZERO, expectedAccounts * 2).forEach(a -> a.storageEntriesFrom(Bytes32.ZERO, 1000));
        }
        // All other state roots should have been removed
        for (int i = 0; i < fullyMarkedBlockNum; i++) {
            final BlockHeader curHeader = blockchain.getBlockHeader(i).get();
            if (!curHeader.getStateRoot().equals(Hash.EMPTY_TRIE_HASH)) {
                assertThat(worldStateArchive.get(curHeader.getStateRoot(), curHeader.getHash())).isEmpty();
            }
        }
        // Check that storage contains only the values we expect
        assertThat(hashValueStore.size()).isEqualTo(expectedNodes.size());
        assertThat(hashValueStore.values()).containsExactlyInAnyOrderElementsOf(expectedNodes.stream().map(Bytes::toArrayUnsafe).collect(Collectors.toSet()));
    }
    pruner.stop();
}
Also used : WorldState(org.hyperledger.besu.evm.worldstate.WorldState) MutableWorldState(org.hyperledger.besu.ethereum.core.MutableWorldState) Hash(org.hyperledger.besu.datatypes.Hash) Bytes(org.apache.tuweni.bytes.Bytes) MockExecutorService(org.hyperledger.besu.testutil.MockExecutorService) BlockHeader(org.hyperledger.besu.ethereum.core.BlockHeader) HashSet(java.util.HashSet)

Example 4 with MockExecutorService

use of org.hyperledger.besu.testutil.MockExecutorService in project besu by hyperledger.

the class AbstractEthTaskTest method shouldIgnoreMultipleRuns.

@Test
public void shouldIgnoreMultipleRuns() {
    final AtomicInteger calls = new AtomicInteger(0);
    final AbstractEthTask<Void> incrementingTask = new AbstractEthTask<>(new NoOpMetricsSystem()) {

        @Override
        protected void executeTask() {
            calls.incrementAndGet();
            result.complete(null);
        }
    };
    incrementingTask.run();
    incrementingTask.run();
    incrementingTask.runAsync(new MockExecutorService());
    assertThat(calls).hasValue(1);
}
Also used : AtomicInteger(java.util.concurrent.atomic.AtomicInteger) NoOpMetricsSystem(org.hyperledger.besu.metrics.noop.NoOpMetricsSystem) MockExecutorService(org.hyperledger.besu.testutil.MockExecutorService) Test(org.junit.Test)

Aggregations

MockExecutorService (org.hyperledger.besu.testutil.MockExecutorService)4 Hash (org.hyperledger.besu.datatypes.Hash)3 BlockHeader (org.hyperledger.besu.ethereum.core.BlockHeader)3 MutableWorldState (org.hyperledger.besu.ethereum.core.MutableWorldState)3 Blockchain (org.hyperledger.besu.ethereum.chain.Blockchain)2 InMemoryKeyValueStorageProvider.createInMemoryWorldStateArchive (org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider.createInMemoryWorldStateArchive)2 DeterministicEthScheduler (org.hyperledger.besu.ethereum.eth.manager.DeterministicEthScheduler)2 EthProtocolManager (org.hyperledger.besu.ethereum.eth.manager.EthProtocolManager)2 RespondingEthPeer (org.hyperledger.besu.ethereum.eth.manager.RespondingEthPeer)2 FastSyncState (org.hyperledger.besu.ethereum.eth.sync.fastsync.FastSyncState)2 WorldStateDownloader (org.hyperledger.besu.ethereum.eth.sync.worldstate.WorldStateDownloader)2 WorldStateKeyValueStorage (org.hyperledger.besu.ethereum.storage.keyvalue.WorldStateKeyValueStorage)2 DefaultWorldStateArchive (org.hyperledger.besu.ethereum.worldstate.DefaultWorldStateArchive)2 WorldStateArchive (org.hyperledger.besu.ethereum.worldstate.WorldStateArchive)2 WorldStateStorage (org.hyperledger.besu.ethereum.worldstate.WorldStateStorage)2 WorldState (org.hyperledger.besu.evm.worldstate.WorldState)2 InMemoryKeyValueStorage (org.hyperledger.besu.services.kvstore.InMemoryKeyValueStorage)2 InMemoryTasksPriorityQueues (org.hyperledger.besu.services.tasks.InMemoryTasksPriorityQueues)2 Test (org.junit.Test)2 HashSet (java.util.HashSet)1