use of io.nuls.consensus.entity.BlockHashResponse in project nuls by nuls-io.
the class DistributedBlockInfoRequestUtils method calc.
private void calc() {
if (null == nodeIdList || nodeIdList.isEmpty()) {
throw new NulsRuntimeException(ErrorCode.FAILED, "success list of nodes is empty!");
}
int size = nodeIdList.size();
int halfSize = (size + 1) / 2;
//
if (hashesMap.size() < halfSize) {
return;
}
BlockInfo result = null;
for (String key : calcMap.keySet()) {
List<String> nodes = calcMap.get(key);
if (nodes == null) {
continue;
}
// todo =
if (nodes.size() >= halfSize) {
result = new BlockInfo();
BlockHashResponse response = hashesMap.get(nodes.get(0));
if (response == null || response.getHeightList() == null) {
// todo check it
continue;
}
Long bestHeight = 0L;
NulsDigestData bestHash = null;
for (int i = 0; i < response.getHeightList().size(); i++) {
Long height = response.getHeightList().get(i);
NulsDigestData hash = response.getHashList().get(i);
if (height >= bestHeight) {
bestHash = hash;
bestHeight = height;
}
result.putHash(height, hash);
}
result.setBestHash(bestHash);
result.setBestHeight(bestHeight);
result.setNodeIdList(nodes);
result.setFinished(true);
break;
}
}
if (null != result) {
bestBlockInfo = result;
}
// else if (size == calcMap.size()) {
// try {
// Thread.sleep(2000L);
// } catch (InterruptedException e) {
// Log.error(e);
// }
// try {
// this.request(start, end, split);
// } catch (Exception e) {
// Log.error(e.getMessage());
// }
// }
}
use of io.nuls.consensus.entity.BlockHashResponse 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.consensus.entity.BlockHashResponse in project nuls by nuls-io.
the class DistributedBlockInfoRequestUtils method addBlockHashResponse.
public boolean addBlockHashResponse(String nodeId, BlockHashResponse response) {
if (this.nodeIdList == null || !this.nodeIdList.contains(nodeId)) {
return false;
}
if (!requesting) {
return false;
}
if (response.getBestHeight() == 0 && NulsContext.getInstance().getBestHeight() > 0) {
hashesMap.remove(nodeId);
nodeIdList.remove(nodeId);
return false;
}
if (hashesMap.get(nodeId) == null) {
hashesMap.put(nodeId, response);
} else {
BlockHashResponse instance = hashesMap.get(nodeId);
instance.merge(response);
hashesMap.put(nodeId, instance);
}
if (response.getHeightList().get(response.getHeightList().size() - 1) < end) {
return true;
}
String key = response.getBestHash().getDigestHex();
List<String> nodes = calcMap.get(key);
if (null == nodes) {
nodes = new ArrayList<>();
}
if (!nodes.contains(nodeId)) {
nodes.add(nodeId);
}
calcMap.put(key, nodes);
calc();
return true;
}
use of io.nuls.consensus.entity.BlockHashResponse in project nuls by nuls-io.
the class DistributedBlockInfoRequestUtils method getBlockInfo.
private BlockInfo getBlockInfo() {
while (true) {
if (null != bestBlockInfo && bestBlockInfo.isFinished()) {
break;
}
try {
Thread.sleep(10L);
} catch (InterruptedException e) {
Log.error(e);
}
long timeout = 10000L;
if ((TimeService.currentTimeMillis() - startTime) > (timeout - 1000L) && hashesMap.size() >= ((nodeIdList.size() + 1) / 2) && start == end && start <= 0) {
long localHeight = NulsContext.getInstance().getBestBlock().getHeader().getHeight();
long minHeight = Long.MAX_VALUE;
NulsDigestData minHash = null;
List<String> nodeIds = new ArrayList<>();
try {
for (String nodeId : hashesMap.keySet()) {
BlockHashResponse response = hashesMap.get(nodeId);
long height = response.getHeightList().get(0);
NulsDigestData hash = response.getHashList().get(0);
if (height >= localHeight) {
if (height <= minHeight) {
minHeight = height;
minHash = hash;
}
nodeIds.add(nodeId);
}
}
} catch (Exception e) {
break;
}
BlockInfo result = new BlockInfo();
result.putHash(minHeight, minHash);
result.setBestHash(minHash);
result.setBestHeight(minHeight);
result.setNodeIdList(nodeIds);
result.setFinished(true);
if (result.getBestHeight() < Long.MAX_VALUE) {
bestBlockInfo = result;
} else {
throw new NulsRuntimeException(ErrorCode.TIME_OUT);
}
} else if ((TimeService.currentTimeMillis() - startTime) > timeout && !(hashesMap.size() >= ((nodeIdList.size() + 1) / 2) && start == end && start <= 0)) {
throw new NulsRuntimeException(ErrorCode.TIME_OUT);
}
}
BlockInfo info = bestBlockInfo;
bestBlockInfo = null;
requesting = false;
return info;
}
Aggregations