use of io.nuls.consensus.utils.BlockInfo 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.consensus.utils.BlockInfo in project nuls by nuls-io.
the class BlockMaintenanceThread method rollbackBlock.
private void rollbackBlock(long startHeight) {
long height = startHeight - 1;
Block block = this.blockService.getBlock(height);
try {
this.blockService.rollbackBlock(startHeight);
NulsContext.getInstance().setBestBlock(block);
} catch (NulsException e) {
Log.error(e);
return;
}
boolean previousRb = false;
if (height > 0) {
NulsContext.getInstance().setBestBlock(block);
BlockInfo blockInfo = DistributedBlockInfoRequestUtils.getInstance().request(height, null);
if (null != blockInfo && null != blockInfo.getBestHash() && (!blockInfo.getBestHash().equals(block.getHeader().getHash()) && blockInfo.getBestHeight() == height)) {
previousRb = true;
}
}
if (previousRb) {
rollbackBlock(height);
}
}
use of io.nuls.consensus.utils.BlockInfo in project nuls by nuls-io.
the class ConsensusMeetingRunner method checkBestHash.
private boolean checkBestHash() {
BlockInfo blockInfo;
try {
blockInfo = DistributedBlockInfoRequestUtils.getInstance().request(-1, null);
} catch (Exception e) {
return false;
}
if (blockInfo == null || blockInfo.getBestHash() == null) {
return false;
}
boolean result = blockInfo.getBestHeight() <= context.getBestBlock().getHeader().getHeight();
if (!result) {
return result;
}
Block localBlock = blockService.getBlock(blockInfo.getBestHeight());
result = null != localBlock && blockInfo.getBestHash().getDigestHex().equals(localBlock.getHeader().getHash().getDigestHex());
return result;
}
use of io.nuls.consensus.utils.BlockInfo in project nuls by nuls-io.
the class BlockMaintenanceThread method syncBlock.
public synchronized void syncBlock() {
BestCorrectBlock bestCorrectBlock = getBestCorrectBlock();
boolean doit = false;
long startHeight = 1;
do {
if (null == bestCorrectBlock.getLocalBestBlock() && bestCorrectBlock.getNetBestBlockInfo() == null) {
doit = true;
BlockInfo blockInfo = BEST_HEIGHT_FROM_NET.request(-1, null);
bestCorrectBlock.setNetBestBlockInfo(blockInfo);
break;
}
startHeight = bestCorrectBlock.getLocalBestBlock().getHeader().getHeight() + 1;
long interval = TimeService.currentTimeMillis() - bestCorrectBlock.getLocalBestBlock().getHeader().getTime();
if (interval < (PocConsensusConstant.BLOCK_TIME_INTERVAL_SECOND * 2000)) {
doit = false;
try {
Thread.sleep(10000L);
} catch (InterruptedException e) {
Log.error(e);
}
break;
}
;
if (null == bestCorrectBlock.getNetBestBlockInfo()) {
bestCorrectBlock.setNetBestBlockInfo(BEST_HEIGHT_FROM_NET.request(0, null));
}
if (null == bestCorrectBlock.getNetBestBlockInfo()) {
break;
}
if (bestCorrectBlock.getNetBestBlockInfo().getBestHeight() > bestCorrectBlock.getLocalBestBlock().getHeader().getHeight()) {
doit = true;
break;
}
} while (false);
if (null == bestCorrectBlock.getNetBestBlockInfo()) {
try {
Thread.sleep(100L);
} catch (InterruptedException e) {
Log.error(e);
}
return;
}
if (doit) {
downloadBlocks(bestCorrectBlock.getNetBestBlockInfo().getNodeIdList(), startHeight, bestCorrectBlock.getNetBestBlockInfo().getBestHeight());
}
}
Aggregations