Search in sources :

Example 6 with RedPunishData

use of io.nuls.consensus.poc.protocol.entity.RedPunishData in project nuls by nuls-io.

the class DepositTxProcessor method conflictDetect.

/**
 * 冲突检测,检测如果传入的交易列表中有相冲突的交易,则返回失败,写明失败原因及所有的应该舍弃的交易列表
 * 本方法不检查双花冲突,双花由账本接口实现
 * <p>
 * Conflict detection, which detects conflicting transactions in the incoming transaction list, returns failure,
 * indicating the cause of failure and all the list of trades that should be discarded.
 * This method does not check the double flower conflict, the double flower is realized by the accounting interface.
 *
 * @param txList 需要检查的交易列表/A list of transactions to be checked.
 * @return 操作结果:成功则返回successResult,失败时,data中返回丢弃列表,msg中返回冲突原因
 * Operation result: success returns successResult. When failure, data returns the discard list, and MSG returns the cause of conflict.
 */
@Override
public ValidateResult conflictDetect(List<Transaction> txList) {
    if (null == txList || txList.isEmpty()) {
        return ValidateResult.getSuccessResult();
    }
    Set<NulsDigestData> outAgentHash = new HashSet<>();
    Map<NulsDigestData, Na> naMap = new HashMap<>();
    List<DepositTransaction> dTxList = new ArrayList<>();
    for (Transaction transaction : txList) {
        switch(transaction.getType()) {
            case ConsensusConstant.TX_TYPE_STOP_AGENT:
                StopAgentTransaction stopAgentTransaction = (StopAgentTransaction) transaction;
                outAgentHash.add(stopAgentTransaction.getTxData().getCreateTxHash());
                break;
            case ConsensusConstant.TX_TYPE_JOIN_CONSENSUS:
                DepositTransaction depositTransaction = (DepositTransaction) transaction;
                Na na = naMap.get(depositTransaction.getTxData().getAgentHash());
                if (null == na) {
                    na = getAgentTotalDeposit(depositTransaction.getTxData().getAgentHash());
                }
                if (na == null) {
                    na = depositTransaction.getTxData().getDeposit();
                } else {
                    na = na.add(depositTransaction.getTxData().getDeposit());
                }
                if (na.isGreaterThan(PocConsensusProtocolConstant.SUM_OF_DEPOSIT_OF_AGENT_UPPER_LIMIT)) {
                    ValidateResult validateResult = ValidateResult.getFailedResult(this.getClass().getName(), PocConsensusErrorCode.DEPOSIT_TOO_MUCH);
                    validateResult.setData(transaction);
                    return validateResult;
                } else {
                    naMap.put(depositTransaction.getTxData().getAgentHash(), na);
                }
                dTxList.add(depositTransaction);
                break;
            case ConsensusConstant.TX_TYPE_RED_PUNISH:
                RedPunishTransaction redPunishTransaction = (RedPunishTransaction) transaction;
                RedPunishData redPunishData = redPunishTransaction.getTxData();
                AgentPo agent = this.getAgentByAddress(redPunishData.getAddress());
                if (null != agent) {
                    outAgentHash.add(agent.getHash());
                }
                break;
            default:
                continue;
        }
    }
    if (dTxList.isEmpty() || outAgentHash.isEmpty()) {
        return ValidateResult.getSuccessResult();
    }
    for (DepositTransaction depositTransaction : dTxList) {
        if (outAgentHash.contains(depositTransaction.getTxData().getAgentHash())) {
            ValidateResult validateResult = ValidateResult.getFailedResult(this.getClass().getName(), PocConsensusErrorCode.AGENT_STOPPED);
            validateResult.setData(depositTransaction);
            return validateResult;
        }
    }
    return ValidateResult.getSuccessResult();
}
Also used : DepositTransaction(io.nuls.consensus.poc.protocol.tx.DepositTransaction) RedPunishTransaction(io.nuls.consensus.poc.protocol.tx.RedPunishTransaction) ValidateResult(io.nuls.kernel.validate.ValidateResult) StopAgentTransaction(io.nuls.consensus.poc.protocol.tx.StopAgentTransaction) DepositTransaction(io.nuls.consensus.poc.protocol.tx.DepositTransaction) RedPunishTransaction(io.nuls.consensus.poc.protocol.tx.RedPunishTransaction) RedPunishData(io.nuls.consensus.poc.protocol.entity.RedPunishData) StopAgentTransaction(io.nuls.consensus.poc.protocol.tx.StopAgentTransaction) AgentPo(io.nuls.consensus.poc.storage.po.AgentPo)

Example 7 with RedPunishData

use of io.nuls.consensus.poc.protocol.entity.RedPunishData in project nuls by nuls-io.

the class RedPunishTxProcessor method onRollback.

@Override
public Result onRollback(RedPunishTransaction tx, Object secondaryData) {
    RedPunishData punishData = tx.getTxData();
    List<AgentPo> agentList = agentStorageService.getList();
    AgentPo agent = null;
    for (AgentPo agentPo : agentList) {
        if (agentPo.getDelHeight() <= 0) {
            continue;
        }
        if (Arrays.equals(agentPo.getAgentAddress(), punishData.getAddress())) {
            agent = agentPo;
            break;
        }
    }
    if (null == agent) {
        return Result.getFailed(PocConsensusErrorCode.AGENT_NOT_EXIST);
    }
    List<DepositPo> depositPoList = depositStorageService.getList();
    List<DepositPo> updatedList = new ArrayList<>();
    for (DepositPo po : depositPoList) {
        po.setDelHeight(-1);
        boolean success = this.depositStorageService.save(po);
        if (!success) {
            for (DepositPo po2 : depositPoList) {
                po2.setDelHeight(tx.getBlockHeight());
                this.depositStorageService.save(po2);
            }
            return Result.getFailed(PocConsensusErrorCode.UPDATE_DEPOSIT_FAILED);
        }
        updatedList.add(po);
    }
    AgentPo agentPo = agent;
    agentPo.setDelHeight(-1L);
    boolean success = agentStorageService.save(agentPo);
    if (!success) {
        for (DepositPo po2 : depositPoList) {
            po2.setDelHeight(tx.getBlockHeight());
            this.depositStorageService.save(po2);
        }
        return Result.getFailed(PocConsensusErrorCode.UPDATE_AGENT_FAILED);
    }
    byte[] key = ArraysTool.concatenate(punishData.getAddress(), new byte[] { PunishType.RED.getCode() }, SerializeUtils.uint64ToByteArray(tx.getBlockHeight()), new byte[] { 0 });
    success = storageService.delete(key);
    if (!success) {
        for (DepositPo po2 : depositPoList) {
            po2.setDelHeight(tx.getBlockHeight());
            this.depositStorageService.save(po2);
        }
        agentPo.setDelHeight(tx.getBlockHeight());
        agentStorageService.save(agentPo);
        throw new NulsRuntimeException(TransactionErrorCode.ROLLBACK_TRANSACTION_FAILED);
    }
    return Result.getSuccess();
}
Also used : DepositPo(io.nuls.consensus.poc.storage.po.DepositPo) RedPunishData(io.nuls.consensus.poc.protocol.entity.RedPunishData) ArrayList(java.util.ArrayList) NulsRuntimeException(io.nuls.kernel.exception.NulsRuntimeException) AgentPo(io.nuls.consensus.poc.storage.po.AgentPo)

Example 8 with RedPunishData

use of io.nuls.consensus.poc.protocol.entity.RedPunishData in project nuls by nuls-io.

the class ChainContainer method verifyRedPunish.

private boolean verifyRedPunish(RedPunishTransaction data) {
    RedPunishData punishData = data.getTxData();
    if (ConsensusConfig.getSeedNodeStringList().contains(AddressTool.getStringAddressByBytes(punishData.getAddress()))) {
        Log.warn("The seed node can not be punished!");
        return false;
    }
    HeaderSignValidator validator = NulsContext.getServiceBean(HeaderSignValidator.class);
    LedgerService ledgerService = NulsContext.getServiceBean(LedgerService.class);
    if (punishData.getReasonCode() == PunishReasonEnum.DOUBLE_SPEND.getCode()) {
        if (NulsContext.MAIN_NET_VERSION <= 1) {
            Log.warn("The red punish tx need higher version!");
            return false;
        }
        SmallBlock smallBlock = new SmallBlock();
        try {
            smallBlock.parse(punishData.getEvidence(), 0);
        } catch (NulsException e) {
            Log.error(e);
            return false;
        }
        BlockHeader header = smallBlock.getHeader();
        if (header.getTime() != data.getTime()) {
            return false;
        }
        ValidateResult result = validator.validate(header);
        if (result.isFailed()) {
            Log.warn(result.getMsg());
            return false;
        }
        List<NulsDigestData> txHashList = smallBlock.getTxHashList();
        if (!header.getMerkleHash().equals(NulsDigestData.calcMerkleDigestData(txHashList))) {
            Log.warn(TransactionErrorCode.TX_DATA_VALIDATION_ERROR.getMsg());
            return false;
        }
        List<Transaction> txList = smallBlock.getSubTxList();
        if (null == txList || txList.size() < 2) {
            Log.warn(TransactionErrorCode.TX_DATA_VALIDATION_ERROR.getMsg());
            return false;
        }
        result = ledgerService.verifyDoubleSpend(txList);
        if (result.isSuccess()) {
            Log.warn(PocConsensusErrorCode.TRANSACTIONS_NEVER_DOUBLE_SPEND.getMsg());
            return false;
        }
    } else if (punishData.getReasonCode() == PunishReasonEnum.BIFURCATION.getCode()) {
        if (NulsContext.MAIN_NET_VERSION <= 1) {
            Log.warn("The red punish tx need higher version!");
            return false;
        }
        NulsByteBuffer byteBuffer = new NulsByteBuffer(punishData.getEvidence());
        // 轮次
        long[] roundIndex = new long[NulsContext.REDPUNISH_BIFURCATION];
        for (int i = 0; i < NulsContext.REDPUNISH_BIFURCATION && !byteBuffer.isFinished(); i++) {
            BlockHeader header1 = null;
            BlockHeader header2 = null;
            try {
                header1 = byteBuffer.readNulsData(new BlockHeader());
                header2 = byteBuffer.readNulsData(new BlockHeader());
            } catch (NulsException e) {
                Log.error(e);
            }
            if (null == header1 || null == header2) {
                Log.warn(KernelErrorCode.DATA_NOT_FOUND.getMsg());
                return false;
            }
            if (header1.getHeight() != header2.getHeight()) {
                Log.warn(TransactionErrorCode.TX_DATA_VALIDATION_ERROR.getMsg());
                return false;
            }
            if (i == NulsContext.REDPUNISH_BIFURCATION - 1 && (header1.getTime() + header2.getTime()) / 2 != data.getTime()) {
                return false;
            }
            ValidateResult result = validator.validate(header1);
            if (result.isFailed()) {
                Log.warn(TransactionErrorCode.TX_DATA_VALIDATION_ERROR.getMsg());
                return false;
            }
            result = validator.validate(header2);
            if (result.isFailed()) {
                Log.warn(TransactionErrorCode.TX_DATA_VALIDATION_ERROR.getMsg());
                return false;
            }
            if (!Arrays.equals(header1.getBlockSignature().getPublicKey(), header2.getBlockSignature().getPublicKey())) {
                Log.warn(TransactionErrorCode.SIGNATURE_ERROR.getMsg());
                return false;
            }
            BlockExtendsData blockExtendsData = new BlockExtendsData(header1.getExtend());
            roundIndex[i] = blockExtendsData.getRoundIndex();
        }
        // 验证轮次是否连续
        boolean rs = true;
        for (int i = 0; i < roundIndex.length; i++) {
            if (i < roundIndex.length - 2 && roundIndex[i + 1] - roundIndex[i] != 1) {
                rs = false;
                break;
            }
        }
        if (!rs) {
            Log.warn(PocConsensusErrorCode.RED_CARD_VERIFICATION_FAILED.getMsg());
            return false;
        }
    } else if (punishData.getReasonCode() != PunishReasonEnum.TOO_MUCH_YELLOW_PUNISH.getCode()) {
        Log.warn(PocConsensusErrorCode.RED_CARD_VERIFICATION_FAILED.getMsg());
        return false;
    }
    try {
        return verifyCoinData(data);
    } catch (IOException e) {
        Log.error(e);
        return false;
    }
}
Also used : SmallBlock(io.nuls.protocol.model.SmallBlock) ValidateResult(io.nuls.kernel.validate.ValidateResult) IOException(java.io.IOException) LedgerService(io.nuls.ledger.service.LedgerService) HeaderSignValidator(io.nuls.protocol.model.validator.HeaderSignValidator) CoinBaseTransaction(io.nuls.protocol.model.tx.CoinBaseTransaction) RedPunishData(io.nuls.consensus.poc.protocol.entity.RedPunishData) NulsException(io.nuls.kernel.exception.NulsException) NulsByteBuffer(io.nuls.kernel.utils.NulsByteBuffer)

Example 9 with RedPunishData

use of io.nuls.consensus.poc.protocol.entity.RedPunishData in project nuls by nuls-io.

the class ChainContainer method verifyPunishTx.

// Verify penalties
// 验证处罚交易
public boolean verifyPunishTx(Block block, MeetingRound currentRound, MeetingMember member) {
    List<Transaction> txs = block.getTxs();
    Transaction tx = txs.get(0);
    if (tx.getType() != ProtocolConstant.TX_TYPE_COINBASE) {
        BlockLog.debug("Coinbase transaction order wrong! height: " + block.getHeader().getHeight() + " , hash : " + block.getHeader().getHash());
        // Log.error("Coinbase transaction order wrong! height: " + block.getHeader().getHeight() + " , hash : " + block.getHeader().getHash());
        return false;
    }
    List<RedPunishTransaction> redPunishTxList = new ArrayList<>();
    YellowPunishTransaction yellowPunishTx = null;
    for (int i = 1; i < txs.size(); i++) {
        Transaction transaction = txs.get(i);
        if (transaction.getType() == ProtocolConstant.TX_TYPE_COINBASE) {
            BlockLog.debug("Coinbase transaction more than one! height: " + block.getHeader().getHeight() + " , hash : " + block.getHeader().getHash());
            // Log.error("Coinbase transaction more than one! height: " + block.getHeader().getHeight() + " , hash : " + block.getHeader().getHash());
            return false;
        }
        if (null == yellowPunishTx && transaction.getType() == ConsensusConstant.TX_TYPE_YELLOW_PUNISH) {
            yellowPunishTx = (YellowPunishTransaction) transaction;
        } else if (null != yellowPunishTx && transaction.getType() == ConsensusConstant.TX_TYPE_YELLOW_PUNISH) {
            BlockLog.debug("Yellow punish transaction more than one! height: " + block.getHeader().getHeight() + " , hash : " + block.getHeader().getHash());
            // Log.error("Yellow punish transaction more than one! height: " + block.getHeader().getHeight() + " , hash : " + block.getHeader().getHash());
            return false;
        } else if (transaction.getType() == ConsensusConstant.TX_TYPE_RED_PUNISH) {
            redPunishTxList.add((RedPunishTransaction) transaction);
        }
    }
    YellowPunishTransaction yellowPunishTransaction = null;
    try {
        yellowPunishTransaction = ConsensusTool.createYellowPunishTx(chain.getBestBlock(), member, currentRound);
        if (yellowPunishTransaction == null && yellowPunishTx == null) {
        // 继续
        } else if (yellowPunishTransaction == null || yellowPunishTx == null) {
            BlockLog.debug("The yellow punish tx is wrong! height: " + block.getHeader().getHeight() + " , hash : " + block.getHeader().getHash());
            // Log.error("The yellow punish tx is wrong! height: " + block.getHeader().getHeight() + " , hash : " + block.getHeader().getHash());
            return false;
        } else if (!yellowPunishTransaction.getHash().equals(yellowPunishTx.getHash())) {
            BlockLog.debug("The yellow punish tx's hash is wrong! height: " + block.getHeader().getHeight() + " , hash : " + block.getHeader().getHash());
            // Log.error("The yellow punish tx's hash is wrong! height: " + block.getHeader().getHeight() + " , hash : " + block.getHeader().getHash());
            return false;
        }
    } catch (Exception e) {
        BlockLog.debug("The tx's wrong! height: " + block.getHeader().getHeight() + " , hash : " + block.getHeader().getHash(), e);
        // Log.error("The tx's wrong! height: " + block.getHeader().getHeight() + " , hash : " + block.getHeader().getHash(), e);
        return false;
    }
    if (!redPunishTxList.isEmpty()) {
        Set<String> punishAddress = new HashSet<>();
        if (null != yellowPunishTx) {
            List<byte[]> addressList = yellowPunishTx.getTxData().getAddressList();
            for (byte[] address : addressList) {
                MeetingMember item = currentRound.getMemberByAgentAddress(address);
                if (null == item) {
                    item = currentRound.getPreRound().getMemberByAgentAddress(address);
                }
                if (item.getCreditVal() <= PocConsensusConstant.RED_PUNISH_CREDIT_VAL) {
                    punishAddress.add(AddressTool.getStringAddressByBytes(item.getAgent().getAgentAddress()));
                }
            }
        }
        int countOfTooMuchYP = 0;
        Set<String> redPunishAddressSet = new HashSet<>();
        for (RedPunishTransaction redTx : redPunishTxList) {
            RedPunishData data = redTx.getTxData();
            if (data.getReasonCode() == PunishReasonEnum.TOO_MUCH_YELLOW_PUNISH.getCode()) {
                countOfTooMuchYP++;
                if (!punishAddress.contains(AddressTool.getStringAddressByBytes(redTx.getTxData().getAddress()))) {
                    BlockLog.debug("There is a wrong red punish tx!" + block.getHeader().getHash());
                    return false;
                }
                if (NulsContext.MAIN_NET_VERSION > 1 && redTx.getTime() != block.getHeader().getTime()) {
                    BlockLog.debug("red punish CoinData & TX time is wrong! " + block.getHeader().getHash());
                    return false;
                }
            }
            boolean result = verifyRedPunish(redTx);
            if (!result) {
                return result;
            }
            if (!redPunishAddressSet.add(AddressTool.getStringAddressByBytes(redTx.getTxData().getAddress()))) {
                BlockLog.debug("red punish repeat!" + block.getHeader().getHash());
                return false;
            }
        }
        if (countOfTooMuchYP != punishAddress.size()) {
            BlockLog.debug("There is a wrong red punish tx!" + block.getHeader().getHash());
            return false;
        }
    }
    return true;
}
Also used : CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) IOException(java.io.IOException) NulsException(io.nuls.kernel.exception.NulsException) CoinBaseTransaction(io.nuls.protocol.model.tx.CoinBaseTransaction) RedPunishData(io.nuls.consensus.poc.protocol.entity.RedPunishData)

Example 10 with RedPunishData

use of io.nuls.consensus.poc.protocol.entity.RedPunishData in project nuls by nuls-io.

the class RedPunishTxProcessor method onCommit.

@Override
public Result onCommit(RedPunishTransaction tx, Object secondaryData) {
    RedPunishData punishData = tx.getTxData();
    BlockHeader header = (BlockHeader) secondaryData;
    BlockExtendsData roundData = new BlockExtendsData(header.getExtend());
    PunishLogPo punishLogPo = new PunishLogPo();
    punishLogPo.setAddress(punishData.getAddress());
    punishLogPo.setHeight(tx.getBlockHeight());
    punishLogPo.setRoundIndex(roundData.getRoundIndex());
    punishLogPo.setTime(tx.getTime());
    punishLogPo.setType(PunishType.RED.getCode());
    punishLogPo.setEvidence(punishData.getEvidence());
    punishLogPo.setReasonCode(punishData.getReasonCode());
    List<AgentPo> agentList = agentStorageService.getList();
    AgentPo agent = null;
    for (AgentPo agentPo : agentList) {
        if (agentPo.getDelHeight() > 0) {
            continue;
        }
        if (Arrays.equals(agentPo.getAgentAddress(), punishLogPo.getAddress())) {
            agent = agentPo;
            break;
        }
    }
    if (null == agent) {
        Log.error("There is no agent can be punished.");
        return Result.getSuccess();
    }
    List<DepositPo> depositPoList = depositStorageService.getList();
    List<DepositPo> updatedList = new ArrayList<>();
    for (DepositPo po : depositPoList) {
        if (po.getDelHeight() >= 0) {
            continue;
        }
        if (!po.getAgentHash().equals(agent.getHash())) {
            continue;
        }
        po.setDelHeight(tx.getBlockHeight());
        boolean b = depositStorageService.save(po);
        if (!b) {
            for (DepositPo po2 : updatedList) {
                po2.setDelHeight(-1);
                this.depositStorageService.save(po2);
            }
            return ValidateResult.getFailedResult(this.getClass().getName(), PocConsensusErrorCode.UPDATE_DEPOSIT_FAILED);
        }
        updatedList.add(po);
    }
    boolean success = storageService.save(punishLogPo);
    if (!success) {
        for (DepositPo po2 : updatedList) {
            po2.setDelHeight(-1);
            this.depositStorageService.save(po2);
        }
        throw new NulsRuntimeException(TransactionErrorCode.ROLLBACK_TRANSACTION_FAILED);
    }
    AgentPo agentPo = agent;
    agentPo.setDelHeight(tx.getBlockHeight());
    success = agentStorageService.save(agentPo);
    if (!success) {
        for (DepositPo po2 : updatedList) {
            po2.setDelHeight(-1);
            this.depositStorageService.save(po2);
        }
        this.storageService.delete(punishLogPo.getKey());
        return Result.getFailed(PocConsensusErrorCode.UPDATE_AGENT_FAILED);
    }
    return Result.getSuccess();
}
Also used : DepositPo(io.nuls.consensus.poc.storage.po.DepositPo) RedPunishData(io.nuls.consensus.poc.protocol.entity.RedPunishData) BlockExtendsData(io.nuls.consensus.poc.model.BlockExtendsData) ArrayList(java.util.ArrayList) NulsRuntimeException(io.nuls.kernel.exception.NulsRuntimeException) BlockHeader(io.nuls.kernel.model.BlockHeader) PunishLogPo(io.nuls.consensus.poc.storage.po.PunishLogPo) AgentPo(io.nuls.consensus.poc.storage.po.AgentPo)

Aggregations

RedPunishData (io.nuls.consensus.poc.protocol.entity.RedPunishData)10 RedPunishTransaction (io.nuls.consensus.poc.protocol.tx.RedPunishTransaction)5 ValidateResult (io.nuls.kernel.validate.ValidateResult)5 Agent (io.nuls.consensus.poc.protocol.entity.Agent)4 IOException (java.io.IOException)4 AgentPo (io.nuls.consensus.poc.storage.po.AgentPo)3 CoinBaseTransaction (io.nuls.protocol.model.tx.CoinBaseTransaction)3 MeetingMember (io.nuls.consensus.poc.model.MeetingMember)2 DepositPo (io.nuls.consensus.poc.storage.po.DepositPo)2 PunishLogPo (io.nuls.consensus.poc.storage.po.PunishLogPo)2 NulsException (io.nuls.kernel.exception.NulsException)2 NulsRuntimeException (io.nuls.kernel.exception.NulsRuntimeException)2 BlockHeader (io.nuls.kernel.model.BlockHeader)2 SmallBlock (io.nuls.protocol.model.SmallBlock)2 ArrayList (java.util.ArrayList)2 BlockExtendsData (io.nuls.consensus.poc.model.BlockExtendsData)1 Evidence (io.nuls.consensus.poc.model.Evidence)1 MeetingRound (io.nuls.consensus.poc.model.MeetingRound)1 Deposit (io.nuls.consensus.poc.protocol.entity.Deposit)1 CreateAgentTransaction (io.nuls.consensus.poc.protocol.tx.CreateAgentTransaction)1