use of io.nuls.consensus.entity.meeting.PocMeetingRound in project nuls by nuls-io.
the class ConsensusMeetingRunner method startMeeting.
private void startMeeting() throws NulsException, IOException {
PocMeetingRound current = consensusManager.getCurrentRound();
if (null == current || null == consensusManager.getConsensusStatusInfo().getAccount() || current.getMember(consensusManager.getConsensusStatusInfo().getAccount().getAddress().toString()) == null) {
this.nextRound();
return;
}
PocMeetingMember self = current.getMember(consensusManager.getConsensusStatusInfo().getAccount().getAddress().toString());
self.setCreditVal(calcCreditVal());
long timeUnit = 1000L;
while (TimeService.currentTimeMillis() <= (self.getPackTime() - timeUnit)) {
try {
Thread.sleep(timeUnit);
} catch (InterruptedException e) {
Log.error(e);
}
}
packing(self);
}
use of io.nuls.consensus.entity.meeting.PocMeetingRound in project nuls by nuls-io.
the class ConsensusMeetingRunner method calcRound.
private PocMeetingRound calcRound() {
PocMeetingRound round = new PocMeetingRound(this.consensusManager.getCurrentRound());
Block bestBlock = context.getBestBlock();
BlockRoundData lastRoundData;
try {
lastRoundData = new BlockRoundData(bestBlock.getHeader().getExtend());
} catch (NulsException e) {
Log.error(e);
throw new NulsRuntimeException(e);
}
if (round.getPreviousRound() == null || round.getPreviousRound().getIndex() <= lastRoundData.getRoundIndex()) {
while (true) {
if (lastRoundData.getPackingIndexOfRound() == lastRoundData.getConsensusMemberCount() || lastRoundData.getRoundEndTime() <= TimeService.currentTimeMillis()) {
break;
}
try {
bestBlock = context.getBestBlock();
lastRoundData = new BlockRoundData(bestBlock.getHeader().getExtend());
} catch (NulsException e) {
Log.error(e);
}
try {
Thread.sleep(100L);
} catch (InterruptedException e) {
Log.error(e);
}
}
PocMeetingRound preRound = new PocMeetingRound(null);
preRound.setIndex(lastRoundData.getRoundIndex());
preRound.setStartTime(lastRoundData.getRoundStartTime());
preRound.setMemberCount(lastRoundData.getConsensusMemberCount());
round.setPreviousRound(preRound);
}
round.setStartTime(round.getPreviousRound().getEndTime());
round.setIndex(lastRoundData.getRoundIndex() + 1);
return round;
}
use of io.nuls.consensus.entity.meeting.PocMeetingRound in project nuls by nuls-io.
the class HeaderPackerValidator method validate.
@Override
public ValidateResult validate(BlockHeader header) {
BlockHeader preHeader = null;
try {
preHeader = NulsContext.getServiceBean(BlockService.class).getBlockHeader(header.getPreHash());
} catch (NulsException e) {
// todo
}
PocMeetingRound currentRound = consensusManager.getCurrentRound();
if (header.getHeight() == 0) {
return ValidateResult.getSuccessResult();
}
if (preHeader == null) {
return ValidateResult.getSuccessResult();
}
BlockRoundData roundData = null;
try {
roundData = new BlockRoundData(preHeader.getExtend());
} catch (NulsException e) {
Log.error(e);
return ValidateResult.getFailedResult(e.getMessage());
}
if (null == currentRound) {
return ValidateResult.getSuccessResult();
}
if (currentRound.getIndex() == roundData.getRoundIndex() && currentRound.getMemberCount() > (roundData.getPackingIndexOfRound() + 1)) {
if (currentRound.indexOf(header.getPackingAddress()) <= roundData.getPackingIndexOfRound()) {
return ValidateResult.getFailedResult(ERROR_MESSAGE);
}
}
byte[] packingHash160 = AccountTool.getHash160ByAddress(header.getPackingAddress());
byte[] hash160InScriptSig = header.getScriptSig().getSignerHash160();
if (!Arrays.equals(packingHash160, hash160InScriptSig)) {
return ValidateResult.getFailedResult(ERROR_MESSAGE);
}
BlockRoundData nowRoundData = null;
try {
nowRoundData = new BlockRoundData(header.getExtend());
} catch (NulsException e) {
Log.error(e);
return ValidateResult.getFailedResult(ERROR_MESSAGE);
}
if (!isAdjacent(roundData, nowRoundData)) {
return ValidateResult.getFailedResult(ERROR_MESSAGE);
}
return ValidateResult.getSuccessResult();
}
use of io.nuls.consensus.entity.meeting.PocMeetingRound in project nuls by nuls-io.
the class ConsensusMeetingRunner method nextRound.
private void nextRound() throws NulsException, IOException {
consensusManager.initConsensusStatusInfo();
PocMeetingRound currentRound = calcRound();
consensusManager.setCurrentRound(currentRound);
while (TimeService.currentTimeMillis() < (currentRound.getStartTime())) {
try {
Thread.sleep(100L);
} catch (InterruptedException e) {
Log.error(e);
}
}
boolean imIn = consensusManager.isPartakePacking();
List<Consensus<Agent>> list = calcConsensusAgentList();
currentRound.setMemberCount(list.size());
while (currentRound.getEndTime() < TimeService.currentTimeMillis()) {
long time = TimeService.currentTimeMillis() - currentRound.getStartTime();
long roundTime = currentRound.getEndTime() - currentRound.getStartTime();
long index = time / roundTime;
long startTime = currentRound.getStartTime() + index * roundTime;
currentRound.setStartTime(startTime);
currentRound.setIndex(currentRound.getPreviousRound().getIndex() + index);
}
Map<String, List<Consensus<Deposit>>> depositMap = new HashMap<>();
List<Consensus<Deposit>> delegateList = consensusCacheManager.getCachedDepositList();
Na totalDeposit = Na.ZERO;
for (Consensus<Deposit> cd : delegateList) {
List<Consensus<Deposit>> sonList = depositMap.get(cd.getExtend().getAgentHash());
if (null == sonList) {
sonList = new ArrayList<>();
}
sonList.add(cd);
depositMap.put(cd.getExtend().getAgentHash(), sonList);
totalDeposit = totalDeposit.add(cd.getExtend().getDeposit());
}
List<PocMeetingMember> memberList = new ArrayList<>();
for (Consensus<Agent> ca : list) {
boolean isSeed = ca.getExtend().getSeed();
if (!isSeed && ca.getExtend().getDeposit().isLessThan(PocConsensusConstant.AGENT_DEPOSIT_LOWER_LIMIT)) {
continue;
}
PocMeetingMember mm = new PocMeetingMember();
mm.setAgentConsensus(ca);
mm.setDelegateList(depositMap.get(ca.getHexHash()));
if (!isSeed && (mm.getDelegateList() == null || mm.getDelegateList().size() > PocConsensusConstant.MAX_ACCEPT_NUM_OF_DEPOSIT)) {
continue;
}
mm.calcDeposit();
if (!isSeed && mm.getTotolEntrustDeposit().isLessThan(PocConsensusConstant.SUM_OF_DEPOSIT_OF_AGENT_LOWER_LIMIT)) {
continue;
}
mm.setRoundIndex(currentRound.getIndex());
mm.setAgentHash(ca.getHexHash());
mm.setAgentAddress(ca.getAddress());
mm.setPackerAddress(ca.getExtend().getPackingAddress());
mm.setRoundStartTime(currentRound.getStartTime());
memberList.add(mm);
totalDeposit = totalDeposit.add(ca.getExtend().getDeposit());
}
Collections.sort(memberList);
currentRound.setMemberList(memberList);
currentRound.setTotalDeposit(totalDeposit);
if (imIn) {
startMeeting();
}
}
use of io.nuls.consensus.entity.meeting.PocMeetingRound in project nuls by nuls-io.
the class ConsensusMeetingRunner method yellowPunishTx.
private void yellowPunishTx(Block bestBlock, List<Transaction> txList, PocMeetingMember self) throws NulsException, IOException {
BlockRoundData lastBlockRoundData = new BlockRoundData();
try {
lastBlockRoundData.parse(bestBlock.getHeader().getExtend());
} catch (NulsException e) {
Log.error(e);
}
// continuous blocks in the same round
boolean ok = (self.getRoundIndex() == lastBlockRoundData.getRoundIndex()) && (self.getIndexOfRound() == (1 + lastBlockRoundData.getPackingIndexOfRound()));
// continuous blocks between two rounds
ok = ok || (self.getRoundIndex() == (lastBlockRoundData.getRoundIndex() + 1) && self.getIndexOfRound() == 1 && lastBlockRoundData.getPackingIndexOfRound() == lastBlockRoundData.getConsensusMemberCount());
// two rounds
ok = ok || (self.getRoundIndex() - 1) > lastBlockRoundData.getRoundIndex();
if (ok) {
return;
}
List<Address> addressList = new ArrayList<>();
PocMeetingRound round = consensusManager.getCurrentRound();
long roundIndex = lastBlockRoundData.getRoundIndex();
int packingIndex = 0;
if (lastBlockRoundData.getPackingIndexOfRound() == lastBlockRoundData.getConsensusMemberCount()) {
packingIndex = 1;
} else {
packingIndex = lastBlockRoundData.getPackingIndexOfRound() + 1;
}
while (true) {
PocMeetingRound tempRound;
if (roundIndex == self.getRoundIndex()) {
tempRound = round;
} else if (roundIndex == (self.getRoundIndex() - 1)) {
tempRound = round.getPreviousRound();
} else {
break;
}
if (tempRound.getIndex() > round.getIndex()) {
break;
}
if (tempRound.getIndex() == round.getIndex() && packingIndex >= self.getIndexOfRound()) {
break;
}
if (packingIndex >= tempRound.getMemberCount()) {
roundIndex++;
packingIndex = 1;
continue;
}
PocMeetingMember member;
try {
member = tempRound.getMember(packingIndex);
if (null == member) {
break;
}
} catch (Exception e) {
break;
}
packingIndex++;
addressList.add(Address.fromHashs(member.getAgentAddress()));
}
if (addressList.isEmpty()) {
return;
}
YellowPunishTransaction punishTx = new YellowPunishTransaction();
YellowPunishData data = new YellowPunishData();
data.setAddressList(addressList);
data.setHeight(bestBlock.getHeader().getHeight() + 1);
punishTx.setTxData(data);
punishTx.setTime(TimeService.currentTimeMillis());
punishTx.setFee(Na.ZERO);
punishTx.setHash(NulsDigestData.calcDigestData(punishTx));
punishTx.setScriptSig(accountService.createP2PKHScriptSigFromDigest(punishTx.getHash(), consensusManager.getConsensusStatusInfo().getAccount(), NulsContext.CACHED_PASSWORD_OF_WALLET).serialize());
txList.add(punishTx);
}
Aggregations