use of io.nuls.core.chain.entity.BlockHeader in project nuls by nuls-io.
the class BlockMaintenanceThread method getBestCorrectBlock.
private BestCorrectBlock getBestCorrectBlock() {
BestCorrectBlock resultCorrentInfo = new BestCorrectBlock();
Block localBestBlock = this.blockService.getLocalBestBlock();
do {
if (null == localBestBlock || localBestBlock.getHeader().getHeight() <= 1) {
break;
}
BlockInfo netBestBlockInfo = DistributedBlockInfoRequestUtils.getInstance().request(0, null);
resultCorrentInfo.setNetBestBlockInfo(netBestBlockInfo);
if (null == netBestBlockInfo || netBestBlockInfo.getBestHash() == null) {
break;
}
// same to network nodes
if (netBestBlockInfo.getBestHeight() == localBestBlock.getHeader().getHeight() && netBestBlockInfo.getBestHash().equals(localBestBlock.getHeader().getHash())) {
break;
} else if (netBestBlockInfo.getBestHeight() <= localBestBlock.getHeader().getHeight()) {
if (netBestBlockInfo.getBestHeight() == 0) {
break;
}
// local height is highest
BlockHeader header = null;
try {
header = blockService.getBlockHeader(netBestBlockInfo.getBestHeight());
} catch (NulsException e) {
break;
}
if (null != header && header.getHash().equals(netBestBlockInfo.getBestHash())) {
break;
}
if (netBestBlockInfo.getNodeIdList().size() == 1) {
throw new NulsRuntimeException(ErrorCode.FAILED, "node count not enough!");
}
Log.warn("Rollback block start height:{},local is highest and wrong!", localBestBlock.getHeader().getHeight());
// bifurcation
rollbackBlock(localBestBlock.getHeader().getHeight());
localBestBlock = this.blockService.getLocalBestBlock();
break;
} else {
netBestBlockInfo = DistributedBlockInfoRequestUtils.getInstance().request(localBestBlock.getHeader().getHeight(), netBestBlockInfo.getNodeIdList());
if (netBestBlockInfo.getBestHash().equals(localBestBlock.getHeader().getHash())) {
break;
}
if (localBestBlock.getHeader().getHeight() != netBestBlockInfo.getBestHeight()) {
throw new NulsRuntimeException(ErrorCode.FAILED, "answer not asked!");
}
if (netBestBlockInfo.getNodeIdList().size() == 1) {
throw new NulsRuntimeException(ErrorCode.FAILED, "node count not enough!");
}
Log.warn("Rollback block start height:{},local has wrong blocks!", localBestBlock.getHeader().getHeight());
// bifurcation
rollbackBlock(localBestBlock.getHeader().getHeight());
localBestBlock = this.blockService.getLocalBestBlock();
}
} while (false);
resultCorrentInfo.setLocalBestBlock(localBestBlock);
return resultCorrentInfo;
}
use of io.nuls.core.chain.entity.BlockHeader in project nuls by nuls-io.
the class BlockHeaderHandler method onEvent.
@Override
public void onEvent(BlockHeaderEvent event, String fromId) {
BlockHeader header = event.getEventBody();
if (null == header) {
Log.warn("recieved a null blockHeader!");
return;
}
Block block = blockManager.getBlock(header.getHash().getDigestHex());
if (null != block) {
return;
}
GetSmallBlockRequest request = new GetSmallBlockRequest();
GetSmallBlockParam param = new GetSmallBlockParam();
param.setBlockHash(header.getHash());
request.setEventBody(param);
eventBroadcaster.sendToNode(request, fromId);
temporaryCacheManager.cacheBlockHeader(header);
}
use of io.nuls.core.chain.entity.BlockHeader in project nuls by nuls-io.
the class GetBlockHeaderHandler method onEvent.
@Override
public void onEvent(GetBlockHeaderEvent event, String fromId) {
BlockHeader header;
if (null == event.getEventBody() || event.getEventBody().getHeight() == 0) {
header = blockService.getLocalBestBlock().getHeader();
} else {
Block block = blockService.getBlock(event.getEventBody().getHeight());
if (null == block) {
header = new BlockHeader();
header.setHeight(event.getEventBody().getHeight());
} else {
header = block.getHeader();
}
}
if (header == null) {
Log.error("header cannot be null");
return;
}
this.eventBroadcaster.sendToNode(new BlockHeaderEvent(header), fromId);
}
use of io.nuls.core.chain.entity.BlockHeader in project nuls by nuls-io.
the class GetBlocksHashHandler method onEvent.
@Override
public void onEvent(GetBlocksHashRequest event, String fromId) {
if (event.getEventBody().getEnd() > NulsContext.getInstance().getBestBlock().getHeader().getHeight()) {
return;
}
boolean b = event.getEventBody().getStart() == event.getEventBody().getEnd();
if (b) {
BlockHashResponse response = new BlockHashResponse();
Block block;
if (event.getEventBody().getEnd() <= 0) {
block = NulsContext.getInstance().getBestBlock();
} else {
block = blockService.getBlock(event.getEventBody().getEnd());
}
if (null == block) {
Log.warn("block can not get:" + event.getEventBody().getEnd());
return;
}
response.put(block.getHeader().getHeight(), block.getHeader().getHash());
sendResponse(response, fromId);
} else {
List<BlockHeader> list = this.blockService.getBlockHeaderList(event.getEventBody().getStart(), event.getEventBody().getEnd(), event.getEventBody().getSplit());
List<Long> resultHeightList = new ArrayList<>();
List<NulsDigestData> resultHashList = new ArrayList<>();
for (int i = 0; i < list.size(); i++) {
resultHeightList.add(list.get(i).getHeight());
resultHashList.add(list.get(i).getHash());
}
if (resultHeightList.isEmpty() || resultHeightList.get(resultHeightList.size() - 1) < event.getEventBody().getEnd()) {
Block block = this.blockService.getBlock(event.getEventBody().getEnd());
if (block == null) {
// todo why?
Log.warn("block can not get:" + event.getEventBody().getEnd());
return;
}
resultHeightList.add(block.getHeader().getHeight());
resultHashList.add(block.getHeader().getHash());
}
final int size = 50000;
for (int i = 0; i < resultHashList.size(); i += size) {
BlockHashResponse response = new BlockHashResponse();
int end = i + size;
if (end > resultHeightList.size()) {
end = resultHeightList.size();
}
response.setHeightList(resultHeightList.subList(i, end));
response.setHashList(resultHashList.subList(i, end));
sendResponse(response, fromId);
}
}
}
use of io.nuls.core.chain.entity.BlockHeader in project nuls by nuls-io.
the class HeaderContinuityValidator method validate.
@Override
public ValidateResult validate(BlockHeader header) {
ValidateResult result = ValidateResult.getSuccessResult();
boolean failed = false;
do {
if (header.getHeight() == 0) {
failed = !header.getPreHash().equals(NulsDigestData.EMPTY_HASH);
break;
}
BlockHeader preHeader = null;
try {
preHeader = NulsContext.getServiceBean(BlockService.class).getBlockHeader(header.getHeight() - 1);
} catch (NulsException e) {
// todo
e.printStackTrace();
}
if (null == preHeader) {
break;
}
failed = !preHeader.getHash().equals(header.getPreHash());
if (failed) {
break;
}
BlockRoundData roundData = new BlockRoundData();
try {
roundData.parse(header.getExtend());
} catch (NulsException e) {
Log.error(e);
}
long shouldTime = roundData.getRoundStartTime() + roundData.getPackingIndexOfRound() * PocConsensusConstant.BLOCK_TIME_INTERVAL_SECOND * 1000;
// todo 3 seconds error
long difference = header.getTime() - shouldTime;
failed = difference > 3000 || difference < -3000;
if (failed) {
break;
}
} while (false);
if (failed) {
result = ValidateResult.getFailedResult(ERROR_MESSAGE);
}
return result;
}
Aggregations