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