Search in sources :

Example 1 with SyncMode

use of org.aion.zero.impl.sync.SyncHeaderRequestManager.SyncMode in project aion by aionnetwork.

the class TaskImportBlocks method importBlocks.

static void importBlocks(final AionBlockchainImpl chain, final SyncStats syncStats, final BlocksWrapper bw, final Map<ByteArrayWrapper, Object> importedBlockHashes, final SyncHeaderRequestManager syncHeaderRequestManager) {
    Thread.currentThread().setName("sync-ib");
    long startTime = System.nanoTime();
    SyncMode syncMode = syncHeaderRequestManager.getSyncMode(bw.nodeId);
    long duration = System.nanoTime() - startTime;
    surveyLog.debug("Import Stage 2: wait for peer state, duration = {} ns.", duration);
    if (syncMode == null) {
        // ignoring these blocks
        log.warn("Peer {} sent blocks that were not requested.", bw.displayId);
    } else {
        // the peerState is not null after this
        startTime = System.nanoTime();
        List<Block> batch = filterBatch(bw.blocks, chain, importedBlockHashes);
        duration = System.nanoTime() - startTime;
        surveyLog.debug("Import Stage 3: filter batch, duration = {} ns.", duration);
        startTime = System.nanoTime();
        // process batch and update the peer state
        SyncMode newMode = processBatch(chain, importedBlockHashes, syncStats, syncMode, batch, bw.displayId);
        duration = System.nanoTime() - startTime;
        surveyLog.debug("Import Stage 4: process received and disk batches, duration = {} ns.", duration);
        // transition to recommended sync mode
        if (syncMode != newMode) {
            syncHeaderRequestManager.runInMode(bw.nodeId, newMode);
        }
        syncStats.update(getBestBlockNumber(chain));
    }
}
Also used : Block(org.aion.zero.impl.types.Block) SyncMode(org.aion.zero.impl.sync.SyncHeaderRequestManager.SyncMode)

Example 2 with SyncMode

use of org.aion.zero.impl.sync.SyncHeaderRequestManager.SyncMode in project aion by aionnetwork.

the class TaskImportBlocks method processBatch.

/**
 * @implNote This method is called only when state is not null.
 */
private static SyncMode processBatch(AionBlockchainImpl chain, Map<ByteArrayWrapper, Object> importedBlockHashes, SyncStats syncStats, SyncMode syncMode, List<Block> batch, String displayId) {
    // for runtime survey information
    long startTime, duration;
    // interpreted as repeated work
    if (batch.isEmpty()) {
        log.debug("Empty batch received from node = {} in mode = {}.", displayId, syncMode);
        // we therefore reset this peer to (possibly) do something other than its previous mode
        return NORMAL;
    }
    // check last block in batch to see if we can skip batch
    if (syncMode != BACKWARD) {
        Block b = batch.get(batch.size() - 1);
        // implies the full batch was already imported (but not filtered by the queue)
        if (chain.isBlockStored(b.getHash(), b.getNumber())) {
            // keeping track of the last block check
            importedBlockHashes.put(ByteArrayWrapper.wrap(b.getHash()), true);
            // skipping the batch
            log.debug("Skip {} blocks from node = {} in mode = {}.", batch.size(), displayId, syncMode);
            batch.clear();
            if (syncMode == FORWARD) {
                return FORWARD;
            } else {
                return NORMAL;
            }
        }
    }
    // remembering imported range
    Block firstInBatch = batch.get(0);
    long first = firstInBatch.getNumber(), last = -1L, currentBest;
    ImportResult importResult = null;
    SyncMode returnMode = syncMode;
    startTime = System.nanoTime();
    try {
        long importDuration = System.currentTimeMillis();
        Triple<Long, Set<ByteArrayWrapper>, ImportResult> resultTriple = chain.tryToConnect(batch, displayId);
        importDuration = System.currentTimeMillis() - importDuration;
        currentBest = resultTriple.getLeft();
        Set<ByteArrayWrapper> importedHashes = resultTriple.getMiddle();
        importResult = resultTriple.getRight();
        int count = importedHashes.size();
        if (currentBest >= first) {
            last = currentBest + 1;
            importedHashes.stream().forEach(v -> importedBlockHashes.put(v, true));
            syncStats.updatePeerBlocks(displayId, count, BlockType.IMPORTED);
            log.info("<import-status: node = {}, from = #{}, to = #{}, time elapsed = {} ms>", displayId, first, currentBest, importDuration);
        }
    } catch (Exception e) {
        log.error("<import-block throw> ", e);
        if (e.getMessage() != null && e.getMessage().contains("No space left on device")) {
            log.error("Shutdown due to lack of disk space.", e);
            System.exit(SystemExitCodes.OUT_OF_DISK_SPACE);
        }
    }
    // if any block results in NO_PARENT, all subsequent blocks will too
    if (importResult == ImportResult.NO_PARENT) {
        int stored = chain.storePendingBlockRange(batch, log);
        syncStats.updatePeerBlocks(displayId, stored, BlockType.STORED);
        // check if it is below the current importable blocks
        if (firstInBatch.getNumber() <= getBestBlockNumber(chain) + 1) {
            duration = System.nanoTime() - startTime;
            surveyLog.debug("Import Stage 4.A: import received batch, duration = {} ns.", duration);
            return BACKWARD;
        }
        duration = System.nanoTime() - startTime;
        surveyLog.debug("Import Stage 4.A: import received batch, duration = {} ns.", duration);
        return returnMode;
    } else if (importResult.isStored()) {
        if (syncMode == BACKWARD) {
            returnMode = FORWARD;
        } else if (syncMode == FORWARD && importResult.isBest()) {
            returnMode = NORMAL;
        }
    }
    duration = System.nanoTime() - startTime;
    surveyLog.debug("Import Stage 4.A: import received batch, duration = {} ns.", duration);
    startTime = System.nanoTime();
    // check for stored blocks
    if (first < last) {
        returnMode = importFromStorage(chain, importedBlockHashes, returnMode, first, last);
    }
    duration = System.nanoTime() - startTime;
    surveyLog.debug("Import Stage 4.B: process all disk batches, duration = {} ns.", duration);
    return returnMode;
}
Also used : ImportResult(org.aion.zero.impl.core.ImportResult) Set(java.util.Set) ByteArrayWrapper(org.aion.util.types.ByteArrayWrapper) Block(org.aion.zero.impl.types.Block) SyncMode(org.aion.zero.impl.sync.SyncHeaderRequestManager.SyncMode)

Aggregations

SyncMode (org.aion.zero.impl.sync.SyncHeaderRequestManager.SyncMode)2 Block (org.aion.zero.impl.types.Block)2 Set (java.util.Set)1 ByteArrayWrapper (org.aion.util.types.ByteArrayWrapper)1 ImportResult (org.aion.zero.impl.core.ImportResult)1