Search in sources :

Example 1 with ResStatus

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

the class ReqStatusHandler method receive.

@Override
public void receive(int _nodeIdHashcode, String _displayId, byte[] _msg) {
    long now = System.currentTimeMillis();
    if ((now - cacheTs) > this.UPDATE_INTERVAL) {
        synchronized (cache) {
            try {
                Block bestBlock = chain.getBestBlock();
                cache = new ResStatus(bestBlock.getNumber(), bestBlock.getTotalDifficulty().toByteArray(), bestBlock.getHash(), this.genesisHash, this.apiVersion, (short) this.mgr.getActiveNodes().size(), BigInteger.valueOf(this.pendingState.getPendingTxSize()).toByteArray(), this.mgr.getAvgLatency());
            } catch (Exception e) {
                if (log.isDebugEnabled()) {
                    log.debug("ReqStatus exception {}", e.toString());
                }
            }
            cacheTs = now;
        }
    }
    this.mgr.send(_nodeIdHashcode, _displayId, cache);
    if (log.isDebugEnabled()) {
        this.log.debug("<req-status node={} return-blk={}>", _displayId, cache.getBestBlockNumber());
    }
}
Also used : ResStatus(org.aion.zero.impl.sync.msg.ResStatus) Block(org.aion.zero.impl.types.Block)

Example 2 with ResStatus

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

the class ResStatusHandler method receive.

@Override
public void receive(int _nodeIdHashcode, String _displayId, final byte[] _msgBytes) {
    // for runtime survey information
    long startTime, duration;
    if (_msgBytes == null || _msgBytes.length == 0)
        return;
    startTime = System.nanoTime();
    ResStatus rs = ResStatus.decode(_msgBytes);
    if (rs == null) {
        this.log.error("<res-status decode-error from {} len: {}>", _displayId, _msgBytes.length);
        if (this.log.isTraceEnabled()) {
            this.log.trace("res-status decode-error dump: {}", ByteUtil.toHexString(_msgBytes));
        }
    }
    this.syncMgr.getSyncStats().updateResponseTime(_displayId, System.nanoTime(), RequestType.STATUS);
    this.syncMgr.getSyncStats().updatePeerBlocks(_displayId, 1, BlockType.RECEIVED);
    INode node = this.p2pMgr.getActiveNodes().get(_nodeIdHashcode);
    if (node != null && rs != null) {
        if (log.isDebugEnabled()) {
            this.log.debug("<res-status node={} best-blk={}>", _displayId, rs.getBestBlockNumber());
        }
        long remoteBestBlockNumber = rs.getBestBlockNumber();
        byte[] remoteBestBlockHash = rs.getBestHash();
        byte[] remoteTdBytes = rs.getTotalDifficulty();
        byte apiVersion = rs.getApiVersion();
        short peerCount = rs.getPeerCount();
        byte[] pendingTcBytes = rs.getPendingTxCount();
        int latency = rs.getLatency();
        if (remoteTdBytes != null && remoteBestBlockHash != null) {
            BigInteger remoteTotalDifficulty = new BigInteger(1, remoteTdBytes);
            int pendingTxCount = new BigInteger(1, pendingTcBytes).intValue();
            node.updateStatus(remoteBestBlockNumber, remoteBestBlockHash, remoteTotalDifficulty, apiVersion, peerCount, pendingTxCount, latency);
            syncMgr.updateNetworkStatus(_displayId, remoteBestBlockNumber, remoteBestBlockHash, remoteTotalDifficulty, apiVersion, peerCount, pendingTxCount, latency);
        }
    }
    duration = System.nanoTime() - startTime;
    surveyLog.debug("Receive Stage 1: process status, duration = {} ns.", duration);
}
Also used : INode(org.aion.p2p.INode) ResStatus(org.aion.zero.impl.sync.msg.ResStatus) BigInteger(java.math.BigInteger)

Example 3 with ResStatus

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

the class BlockPropagationHandler method processIncomingBlock.

public PropStatus processIncomingBlock(final int nodeId, final String displayId, final Block block) {
    if (block == null)
        return PropStatus.DROPPED;
    ByteArrayWrapper hashWrapped = block.getHashWrapper();
    if (!this.blockHeaderValidator.validate(block.getHeader(), log))
        return PropStatus.DROPPED;
    // guarantees if multiple requests of same block appears, only one goes through
    synchronized (this.cacheMap) {
        if (this.cacheMap.get(hashWrapped) != null) {
            if (log.isTraceEnabled()) {
                log.trace("block {} already cached", block.getShortHash());
            }
            return PropStatus.DROPPED;
        }
        // regardless if block processing is successful, place into cache
        this.cacheMap.put(hashWrapped, true);
    }
    // process
    long t1 = System.currentTimeMillis();
    ImportResult result;
    if (this.blockchain.skipTryToConnect(block.getNumber())) {
        result = ImportResult.NO_PARENT;
        if (log.isInfoEnabled()) {
            log.info("<import-status: node = {}, hash = {}, number = {}, txs = {}, result = NOT_IN_RANGE>", displayId, block.getShortHash(), block.getNumber(), block.getTransactionsList().size(), result);
        } else if (log.isDebugEnabled()) {
            log.debug("<import-status: node = {}, hash = {}, number = {}, txs = {}, block time = {}, result = NOT_IN_RANGE>", displayId, block.getShortHash(), block.getNumber(), block.getTransactionsList().size(), block.getTimestamp(), result);
        }
    } else {
        result = this.blockchain.tryToConnect(new BlockWrapper(block));
        long t2 = System.currentTimeMillis();
        if (result.isStored()) {
            this.syncStats.updatePeerBlocks(displayId, 1, BlockType.IMPORTED);
        }
        if (log.isInfoEnabled()) {
            log.info("<import-status: node = {}, hash = {}, number = {}, txs = {}, result = {}, time elapsed = {} ms>", displayId, block.getShortHash(), block.getNumber(), block.getTransactionsList().size(), result, t2 - t1);
        } else if (log.isDebugEnabled()) {
            log.debug("<import-status: node = {}, hash = {}, number = {}, td = {}, txs = {}, block time = {}, result = {}, time elapsed = {} ms>", displayId, block.getShortHash(), block.getNumber(), blockchain.getTotalDifficulty(), block.getTransactionsList().size(), block.getTimestamp(), result, t2 - t1);
        }
    }
    // send
    boolean sent = result.isBest() && send(block, nodeId);
    // notify higher td peers in order to limit the rebroadcast on delay of res status updating
    if (result.isBest()) {
        Block bestBlock = blockchain.getBestBlock();
        BigInteger td = bestBlock.getTotalDifficulty();
        ResStatus rs = new ResStatus(bestBlock.getNumber(), td.toByteArray(), bestBlock.getHash(), genesis, apiVersion, (short) p2pManager.getActiveNodes().size(), BigInteger.valueOf(this.pendingState.getPendingTxSize()).toByteArray(), p2pManager.getAvgLatency());
        this.p2pManager.getActiveNodes().values().stream().filter(n -> n.getIdHash() != nodeId).filter(n -> n.getTotalDifficulty().compareTo(td) >= 0).forEach(n -> {
            log.debug("<push-status blk={} hash={} to-node={} dd={} import-result={}>", block.getNumber(), block.getShortHash(), n.getIdShort(), td.longValue() - n.getTotalDifficulty().longValue(), result.name());
            this.p2pManager.send(n.getIdHash(), n.getIdShort(), rs);
        });
    }
    // process resulting state
    if (sent && result.isSuccessful())
        return PropStatus.PROP_CONNECTED;
    if (result.isSuccessful())
        return PropStatus.CONNECTED;
    if (sent)
        return PropStatus.PROPAGATED;
    // gets dropped when the result is not valid
    return PropStatus.DROPPED;
}
Also used : BlockWrapper(org.aion.zero.impl.blockchain.BlockWrapper) AionLoggerFactory(org.aion.log.AionLoggerFactory) IP2pMgr(org.aion.p2p.IP2pMgr) BlockHeaderValidator(org.aion.zero.impl.valid.BlockHeaderValidator) Logger(org.slf4j.Logger) BlockWrapper(org.aion.zero.impl.blockchain.BlockWrapper) IAionBlockchain(org.aion.zero.impl.blockchain.IAionBlockchain) ImportResult(org.aion.zero.impl.core.ImportResult) BroadcastNewBlock(org.aion.zero.impl.sync.msg.BroadcastNewBlock) BlockType(org.aion.zero.impl.sync.statistics.BlockType) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) LRUMap(org.apache.commons.collections4.map.LRUMap) AionPendingStateImpl(org.aion.zero.impl.pendingState.AionPendingStateImpl) ByteArrayWrapper(org.aion.util.types.ByteArrayWrapper) LogEnum(org.aion.log.LogEnum) SyncStats(org.aion.zero.impl.sync.SyncStats) Map(java.util.Map) ResStatus(org.aion.zero.impl.sync.msg.ResStatus) BigInteger(java.math.BigInteger) Block(org.aion.zero.impl.types.Block) CfgAion(org.aion.zero.impl.config.CfgAion) ImportResult(org.aion.zero.impl.core.ImportResult) ResStatus(org.aion.zero.impl.sync.msg.ResStatus) ByteArrayWrapper(org.aion.util.types.ByteArrayWrapper) BroadcastNewBlock(org.aion.zero.impl.sync.msg.BroadcastNewBlock) Block(org.aion.zero.impl.types.Block) BigInteger(java.math.BigInteger)

Aggregations

ResStatus (org.aion.zero.impl.sync.msg.ResStatus)3 BigInteger (java.math.BigInteger)2 Block (org.aion.zero.impl.types.Block)2 Map (java.util.Map)1 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)1 AionLoggerFactory (org.aion.log.AionLoggerFactory)1 LogEnum (org.aion.log.LogEnum)1 INode (org.aion.p2p.INode)1 IP2pMgr (org.aion.p2p.IP2pMgr)1 ByteArrayWrapper (org.aion.util.types.ByteArrayWrapper)1 BlockWrapper (org.aion.zero.impl.blockchain.BlockWrapper)1 IAionBlockchain (org.aion.zero.impl.blockchain.IAionBlockchain)1 CfgAion (org.aion.zero.impl.config.CfgAion)1 ImportResult (org.aion.zero.impl.core.ImportResult)1 AionPendingStateImpl (org.aion.zero.impl.pendingState.AionPendingStateImpl)1 SyncStats (org.aion.zero.impl.sync.SyncStats)1 BroadcastNewBlock (org.aion.zero.impl.sync.msg.BroadcastNewBlock)1 BlockType (org.aion.zero.impl.sync.statistics.BlockType)1 BlockHeaderValidator (org.aion.zero.impl.valid.BlockHeaderValidator)1 LRUMap (org.apache.commons.collections4.map.LRUMap)1