use of org.aion.zero.impl.blockchain.BlockWrapper 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