use of io.nuls.consensus.poc.protocol.tx.YellowPunishTransaction in project nuls by nuls-io.
the class ConsensusProcess method punishTx.
private void punishTx(Block bestBlock, List<Transaction> txList, MeetingMember self, MeetingRound round) throws NulsException, IOException {
YellowPunishTransaction yellowPunishTransaction = ConsensusTool.createYellowPunishTx(bestBlock, self, round);
if (null == yellowPunishTransaction) {
return;
}
txList.add(yellowPunishTransaction);
// 当连续100个黄牌时,给出一个红牌
// When 100 yellow CARDS in a row, give a red card.
List<byte[]> addressList = yellowPunishTransaction.getTxData().getAddressList();
Set<Integer> punishedSet = new HashSet<>();
for (byte[] address : addressList) {
MeetingMember member = round.getMemberByAgentAddress(address);
if (null == member) {
member = round.getPreRound().getMemberByAgentAddress(address);
}
if (member.getCreditVal() <= PocConsensusConstant.RED_PUNISH_CREDIT_VAL) {
if (!punishedSet.add(member.getPackingIndexOfRound())) {
continue;
}
if (member.getAgent().getDelHeight() > 0L) {
continue;
}
RedPunishTransaction redPunishTransaction = new RedPunishTransaction();
RedPunishData redPunishData = new RedPunishData();
redPunishData.setAddress(address);
redPunishData.setReasonCode(PunishReasonEnum.TOO_MUCH_YELLOW_PUNISH.getCode());
redPunishTransaction.setTxData(redPunishData);
redPunishTransaction.setTime(self.getPackEndTime());
CoinData coinData = ConsensusTool.getStopAgentCoinData(redPunishData.getAddress(), redPunishTransaction.getTime() + PocConsensusConstant.RED_PUNISH_LOCK_TIME);
redPunishTransaction.setCoinData(coinData);
redPunishTransaction.setHash(NulsDigestData.calcDigestData(redPunishTransaction.serializeForHash()));
txList.add(redPunishTransaction);
}
}
}
use of io.nuls.consensus.poc.protocol.tx.YellowPunishTransaction in project nuls by nuls-io.
the class ConsensusTool method createYellowPunishTx.
public static YellowPunishTransaction createYellowPunishTx(Block preBlock, MeetingMember self, MeetingRound round) throws NulsException, IOException {
BlockExtendsData preBlockRoundData = new BlockExtendsData(preBlock.getHeader().getExtend());
if (self.getRoundIndex() - preBlockRoundData.getRoundIndex() > 1) {
return null;
}
int yellowCount = 0;
if (self.getRoundIndex() == preBlockRoundData.getRoundIndex() && self.getPackingIndexOfRound() != preBlockRoundData.getPackingIndexOfRound() + 1) {
yellowCount = self.getPackingIndexOfRound() - preBlockRoundData.getPackingIndexOfRound() - 1;
}
if (self.getRoundIndex() != preBlockRoundData.getRoundIndex() && (self.getPackingIndexOfRound() != 1 || preBlockRoundData.getPackingIndexOfRound() != preBlockRoundData.getConsensusMemberCount())) {
yellowCount = self.getPackingIndexOfRound() + preBlockRoundData.getConsensusMemberCount() - preBlockRoundData.getPackingIndexOfRound() - 1;
}
if (yellowCount == 0) {
return null;
}
List<byte[]> addressList = new ArrayList<>();
for (int i = 1; i <= yellowCount; i++) {
int index = self.getPackingIndexOfRound() - i;
if (index > 0) {
MeetingMember member = round.getMember(index);
if (member.getAgent() == null) {
continue;
} else if (member.getAgent().getDelHeight() > 0) {
continue;
}
addressList.add(member.getAgentAddress());
} else {
MeetingRound preRound = round.getPreRound();
MeetingMember member = preRound.getMember(index + preRound.getMemberCount());
if (member.getAgent() == null || member.getAgent().getDelHeight() > 0) {
continue;
}
addressList.add(member.getAgentAddress());
}
}
if (addressList.isEmpty()) {
return null;
}
YellowPunishTransaction punishTx = new YellowPunishTransaction();
YellowPunishData data = new YellowPunishData();
data.setAddressList(addressList);
punishTx.setTxData(data);
punishTx.setTime(self.getPackEndTime());
punishTx.setHash(NulsDigestData.calcDigestData(punishTx.serializeForHash()));
return punishTx;
}
Aggregations