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