Search in sources :

Example 1 with ReqBlocksBodies

use of org.aion.zero.impl.sync.msg.ReqBlocksBodies in project aion by aionnetwork.

the class TaskGetBodies method run.

@Override
public void run() {
    while (run.get()) {
        HeadersWrapper hw;
        try {
            hw = headersImported.take();
        } catch (InterruptedException e) {
            continue;
        }
        int idHash = hw.getNodeIdHash();
        List<A0BlockHeader> headers = hw.getHeaders();
        if (headers.isEmpty()) {
            continue;
        }
        HeadersWrapper hwPrevious = headersSent.get(idHash);
        if (hwPrevious == null || (System.currentTimeMillis() - hwPrevious.getTimestamp()) > SENT_HEADERS_TIMEOUT) {
            this.headersSent.put(idHash, hw);
            if (log.isDebugEnabled()) {
                log.debug("<get-bodies from-num={} to-num={} node={}>", headers.get(0).getNumber(), headers.get(headers.size() - 1).getNumber(), hw.getDisplayId());
            }
            this.p2p.send(idHash, new ReqBlocksBodies(headers.stream().map(k -> k.getHash()).collect(Collectors.toList())));
        }
    }
}
Also used : IP2pMgr(org.aion.p2p.IP2pMgr) A0BlockHeader(org.aion.zero.types.A0BlockHeader) List(java.util.List) Logger(org.slf4j.Logger) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) ReqBlocksBodies(org.aion.zero.impl.sync.msg.ReqBlocksBodies) BlockingQueue(java.util.concurrent.BlockingQueue) Collectors(java.util.stream.Collectors) ArrayList(java.util.ArrayList) A0BlockHeader(org.aion.zero.types.A0BlockHeader) ReqBlocksBodies(org.aion.zero.impl.sync.msg.ReqBlocksBodies)

Example 2 with ReqBlocksBodies

use of org.aion.zero.impl.sync.msg.ReqBlocksBodies in project aion by aionnetwork.

the class SyncMgr method requestBodies.

/**
 * Requests the bodies associated to the given block headers.
 */
void requestBodies(int nodeId, String displayId) {
    Thread.currentThread().setName("sync-gb-" + Thread.currentThread().getId());
    long startTime = System.nanoTime();
    List<List<BlockHeader>> forRequests = syncHeaderRequestManager.getHeadersForBodiesRequests(nodeId);
    for (List<BlockHeader> requestHeaders : forRequests) {
        // Filter headers again in case the blockchain has advanced while this task was waiting to be executed.
        List<BlockHeader> filtered = requestHeaders.stream().filter(h -> !importedBlockHashes.containsKey(ByteArrayWrapper.wrap(h.getHash()))).collect(Collectors.toList());
        // Check the peer state and discard blocks that are under the current best (in case the hashes already dropped from the above map).
        // This check is only applicable for SyncMode.NORMAL because the other sync modes deal with side chains.
        long currentBest = chain.getBestBlock() == null ? 0L : chain.getBestBlock().getNumber();
        long firstInBatch = requestHeaders.get(0).getNumber();
        if (syncHeaderRequestManager.getSyncMode(nodeId) == SyncMode.NORMAL && firstInBatch <= currentBest) {
            // remove all blocks in the batch that are under the current best
            for (Iterator<BlockHeader> it = filtered.iterator(); it.hasNext(); ) {
                if (it.next().getNumber() <= currentBest) {
                    it.remove();
                }
            }
        }
        if (filtered.size() == requestHeaders.size()) {
            // Log bodies request before sending the request.
            log.debug("<get-bodies from-num={} to-num={} node={}>", firstInBatch, requestHeaders.get(requestHeaders.size() - 1).getNumber(), displayId);
            p2pMgr.send(nodeId, displayId, new ReqBlocksBodies(requestHeaders.stream().map(k -> k.getHash()).collect(Collectors.toList())));
            stats.updateTotalRequestsToPeer(displayId, RequestType.BODIES);
            stats.updateRequestTime(displayId, System.nanoTime(), RequestType.BODIES);
        } else {
            // Drop the headers that are already known.
            syncHeaderRequestManager.dropHeaders(nodeId, requestHeaders);
            if (!filtered.isEmpty()) {
                // Store the subset that is still useful.
                syncHeaderRequestManager.storeHeaders(nodeId, filtered);
            }
        }
    }
    long duration = System.nanoTime() - startTime;
    survey_log.debug("TaskGetBodies: make request, duration = {} ns.", duration);
}
Also used : IP2pMgr(org.aion.p2p.IP2pMgr) ThreadPoolExecutor(java.util.concurrent.ThreadPoolExecutor) IEvent(org.aion.evtmgr.IEvent) LRUMap(org.apache.commons.collections4.map.LRUMap) ArrayList(java.util.ArrayList) BlockHeader(org.aion.zero.impl.types.BlockHeader) HashSet(java.util.HashSet) ByteArrayWrapper(org.aion.util.types.ByteArrayWrapper) IEventMgr(org.aion.evtmgr.IEventMgr) BlockUtil(org.aion.zero.impl.types.BlockUtil) Map(java.util.Map) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) INode(org.aion.p2p.INode) SharedRLPList(org.aion.rlp.SharedRLPList) SyncMode(org.aion.zero.impl.sync.SyncHeaderRequestManager.SyncMode) BigInteger(java.math.BigInteger) ReqBlocksBodies(org.aion.zero.impl.sync.msg.ReqBlocksBodies) RequestType(org.aion.zero.impl.sync.statistics.RequestType) Block(org.aion.zero.impl.types.Block) ExecutorService(java.util.concurrent.ExecutorService) AionLoggerFactory(org.aion.log.AionLoggerFactory) StringUtils.getNodeIdShort(org.aion.util.string.StringUtils.getNodeIdShort) BlockHeaderValidator(org.aion.zero.impl.valid.BlockHeaderValidator) Hex(org.aion.util.conversions.Hex) Logger(org.slf4j.Logger) Iterator(java.util.Iterator) BlockType(org.aion.zero.impl.sync.statistics.BlockType) Set(java.util.Set) AionBlockchainImpl(org.aion.zero.impl.blockchain.AionBlockchainImpl) LinkedBlockingQueue(java.util.concurrent.LinkedBlockingQueue) Collectors(java.util.stream.Collectors) ChainConfiguration(org.aion.zero.impl.blockchain.ChainConfiguration) Executors(java.util.concurrent.Executors) TimeUnit(java.util.concurrent.TimeUnit) List(java.util.List) LogEnum(org.aion.log.LogEnum) ReqStatus(org.aion.zero.impl.sync.msg.ReqStatus) StatsType(org.aion.zero.impl.config.StatsType) VisibleForTesting(com.google.common.annotations.VisibleForTesting) EventConsensus(org.aion.evtmgr.impl.evt.EventConsensus) Collections(java.util.Collections) ArrayList(java.util.ArrayList) SharedRLPList(org.aion.rlp.SharedRLPList) List(java.util.List) BlockHeader(org.aion.zero.impl.types.BlockHeader) ReqBlocksBodies(org.aion.zero.impl.sync.msg.ReqBlocksBodies)

Example 3 with ReqBlocksBodies

use of org.aion.zero.impl.sync.msg.ReqBlocksBodies in project aion by aionnetwork.

the class ReqBlocksBodiesHandler method receive.

@Override
public void receive(int _nodeIdHashcode, String _displayId, final byte[] _msgBytes) {
    if (isSyncOnlyNode)
        return;
    ReqBlocksBodies reqBlocks = ReqBlocksBodies.decode(_msgBytes);
    if (reqBlocks != null) {
        // limit number of blocks
        List<byte[]> hashes = reqBlocks.getBlocksHashes();
        hashes = hashes.size() > MAX_NUM_OF_BLOCKS ? hashes.subList(0, MAX_NUM_OF_BLOCKS) : hashes;
        // results
        List<byte[]> blockBodies = new ArrayList<>();
        // read from cache, then block store
        int out = 0;
        for (byte[] hash : hashes) {
            // ref for add.
            byte[] blockBytesForadd;
            byte[] blockBytes = cache.get(ByteArrayWrapper.wrap(hash));
            // if cached , add.
            if (blockBytes != null) {
                blockBytesForadd = blockBytes;
            } else {
                Block block = blockchain.getBlockByHash(hash);
                if (block != null) {
                    blockBytesForadd = block.getEncodedBody();
                    cache.put(ByteArrayWrapper.wrap(hash), block.getEncodedBody());
                } else {
                    // not found
                    break;
                }
            }
            if ((out += blockBytesForadd.length) > P2pConstant.MAX_BODY_SIZE) {
                log.debug("<req-blocks-bodies-max-size-reach size={}/{}>", out, P2pConstant.MAX_BODY_SIZE);
                break;
            }
            blockBodies.add(blockBytesForadd);
        }
        this.p2pMgr.send(_nodeIdHashcode, _displayId, new ResBlocksBodies(blockBodies.toArray()));
        this.syncMgr.getSyncStats().updateTotalBlockRequestsByPeer(_displayId, blockBodies.size());
        if (log.isDebugEnabled()) {
            this.log.debug("<req-bodies req-size={} res-size={} node={}>", reqBlocks.getBlocksHashes().size(), blockBodies.size(), _displayId);
        }
    } else {
        this.log.error("<req-bodies decode-error, unable to decode bodies from {}, len: {}>", _displayId, _msgBytes.length);
        if (this.log.isTraceEnabled()) {
            this.log.trace("req-bodies dump: {}", ByteUtil.toHexString(_msgBytes));
        }
    }
}
Also used : ResBlocksBodies(org.aion.zero.impl.sync.msg.ResBlocksBodies) ArrayList(java.util.ArrayList) Block(org.aion.zero.impl.types.Block) ReqBlocksBodies(org.aion.zero.impl.sync.msg.ReqBlocksBodies)

Aggregations

ArrayList (java.util.ArrayList)3 ReqBlocksBodies (org.aion.zero.impl.sync.msg.ReqBlocksBodies)3 List (java.util.List)2 Collectors (java.util.stream.Collectors)2 IP2pMgr (org.aion.p2p.IP2pMgr)2 Block (org.aion.zero.impl.types.Block)2 Logger (org.slf4j.Logger)2 VisibleForTesting (com.google.common.annotations.VisibleForTesting)1 BigInteger (java.math.BigInteger)1 Collections (java.util.Collections)1 HashSet (java.util.HashSet)1 Iterator (java.util.Iterator)1 Map (java.util.Map)1 Set (java.util.Set)1 BlockingQueue (java.util.concurrent.BlockingQueue)1 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)1 ExecutorService (java.util.concurrent.ExecutorService)1 Executors (java.util.concurrent.Executors)1 LinkedBlockingQueue (java.util.concurrent.LinkedBlockingQueue)1 ScheduledExecutorService (java.util.concurrent.ScheduledExecutorService)1