Search in sources :

Example 26 with ValidateResult

use of io.nuls.kernel.validate.ValidateResult in project nuls by nuls-io.

the class ConsensusProcess method doPacking.

private Block doPacking(MeetingMember self, MeetingRound round) throws NulsException, IOException {
    Block bestBlock = chainManager.getBestBlock();
    /**
     ********************************************************************************************************
     */
    // pierre test comment out
    // try {
    // Log.info("");
    // Log.info("****************************************************");
    // Log.info("开始打包,获取当前bestblock, height:{},- {}", bestBlock.getHeader().getHeight(), bestBlock.getHeader().getHash());
    // Log.info("开始打包,获取当前EndBlockHeader, height:{},- {}", chainManager.getMasterChain().getChain().getEndBlockHeader().getHeight(),
    // chainManager.getMasterChain().getChain().getEndBlockHeader().getHash());
    // Log.info("****************************************************");
    // Log.info("");
    // 
    // } catch (Exception e) {
    // e.printStackTrace();
    // }
    /**
     ********************************************************************************************************
     */
    BlockData bd = new BlockData();
    bd.setHeight(bestBlock.getHeader().getHeight() + 1);
    bd.setPreHash(bestBlock.getHeader().getHash());
    bd.setTime(self.getPackEndTime());
    BlockExtendsData extendsData = new BlockExtendsData();
    extendsData.setRoundIndex(round.getIndex());
    extendsData.setConsensusMemberCount(round.getMemberCount());
    extendsData.setPackingIndexOfRound(self.getPackingIndexOfRound());
    extendsData.setRoundStartTime(round.getStartTime());
    // 添加版本升级相应协议数据
    if (NulsVersionManager.getCurrentVersion() > 1) {
        extendsData.setMainVersion(NulsVersionManager.getMainVersion());
        extendsData.setCurrentVersion(NulsVersionManager.getCurrentVersion());
        extendsData.setPercent(NulsVersionManager.getCurrentProtocolContainer().getPercent());
        extendsData.setDelay(NulsVersionManager.getCurrentProtocolContainer().getDelay());
    }
    if (NulsVersionManager.getMainVersion() >= 3) {
        RandomSeedStatusPo status = randomSeedsStorageService.getAddressStatus(self.getPackingAddress());
        byte[] seed = ConsensusStorageConstant.EMPTY_SEED;
        if (null != status && status.getNextSeed() != null) {
            seed = status.getNextSeed();
        }
        extendsData.setSeed(seed);
        byte[] nextSeed = RandomSeedUtils.createRandomSeed();
        byte[] nextSeedHash = RandomSeedUtils.getLastDigestEightBytes(nextSeed);
        extendsData.setNextSeedHash(nextSeedHash);
        RandomSeedStatusPo po = new RandomSeedStatusPo();
        po.setAddress(self.getPackingAddress());
        // Log.info("{}====={}====={}", bd.getHeight(), Hex.encode(nextSeed), Hex.encode(nextSeedHash));
        po.setSeedHash(nextSeedHash);
        po.setNextSeed(nextSeed);
        po.setHeight(bd.getHeight());
        RandomSeedUtils.CACHE_SEED = po;
    }
    StringBuilder str = new StringBuilder();
    str.append(AddressTool.getStringAddressByBytes(self.getPackingAddress()));
    str.append(" ,order:" + self.getPackingIndexOfRound());
    str.append(",packTime:" + new Date(self.getPackEndTime()));
    str.append("\n");
    Log.debug("pack round:" + str);
    bd.setExtendsData(extendsData);
    List<Transaction> packingTxList = new ArrayList<>();
    Set<NulsDigestData> outHashSet = new HashSet<>();
    long totalSize = 0L;
    Map<String, Coin> toMaps = new HashMap<>();
    Set<String> fromSet = new HashSet<>();
    /**
     * pierre add 智能合约相关
     */
    byte[] stateRoot = ConsensusTool.getStateRoot(bestBlock.getHeader());
    // 更新世界状态根
    bd.setStateRoot(stateRoot);
    long height = bestBlock.getHeader().getHeight();
    ContractResult contractResult;
    Map<String, Coin> contractUsedCoinMap = new HashMap<>();
    int totalGasUsed = 0;
    int count = 0;
    long start = 0;
    long ledgerUse = 0;
    long verifyUse = 0;
    long outHashSetUse = 0;
    long getTxUse = 0;
    long sleepTIme = 0;
    long whileTime = 0;
    long startWhile = System.currentTimeMillis();
    long sizeTime = 0;
    long failed1Use = 0;
    long addTime = 0;
    Block tempBlock = new Block();
    BlockHeader tempHeader = new BlockHeader();
    tempHeader.setTime(bd.getTime());
    tempHeader.setHeight(bd.getHeight());
    tempHeader.setPackingAddress(round.getLocalPacker().getAddress().getAddressBytes());
    tempBlock.setHeader(tempHeader);
    // 为本次打包区块增加一个合约的临时余额区,用于记录本次合约地址余额的变化
    contractService.createContractTempBalance();
    // 为本次打包区块创建一个批量执行合约的执行器
    contractService.createBatchExecute(stateRoot);
    // 为本地打包区块存储当前块的部分区块头信息(高度、时间、打包者地址)
    contractService.createCurrentBlockHeader(tempHeader);
    List<ContractResult> contractResultList = new ArrayList<>();
    Set<String> redPunishAddress = new HashSet<>();
    while (true) {
        if ((self.getPackEndTime() - TimeService.currentTimeMillis()) <= 500L) {
            break;
        }
        start = System.nanoTime();
        Transaction tx = txMemoryPool.get();
        getTxUse += (System.nanoTime() - start);
        if (tx == null) {
            try {
                sleepTIme += 100;
                Thread.sleep(100L);
            } catch (InterruptedException e) {
                Log.error("packaging error ", e);
            }
            continue;
        }
        start = System.nanoTime();
        long txSize = tx.size();
        sizeTime += (System.nanoTime() - start);
        if ((totalSize + txSize) > ProtocolConstant.MAX_BLOCK_SIZE) {
            txMemoryPool.addInFirst(tx, false);
            break;
        }
        // 区块中可以消耗的最大Gas总量,超过这个值,则本区块中不再继续组装消耗GAS智能合约交易
        if (totalGasUsed > ContractConstant.MAX_PACKAGE_GAS && ContractUtil.isGasCostContractTransaction(tx)) {
            txMemoryPool.addInFirst(tx, false);
            continue;
        }
        count++;
        start = System.nanoTime();
        Transaction repeatTx = ledgerService.getTx(tx.getHash());
        ledgerUse += (System.nanoTime() - start);
        if (repeatTx != null) {
            continue;
        }
        ValidateResult result = ValidateResult.getSuccessResult();
        if (tx.isSystemTx() && tx.getType() == ConsensusConstant.TX_TYPE_RED_PUNISH) {
            RedPunishTransaction rpTx = (RedPunishTransaction) tx;
            boolean con = redPunishAddress.add(AddressTool.getStringAddressByBytes(rpTx.getTxData().getAddress())) && PocConsensusContext.getChainManager().getMasterChain().getChain().getAgentByAddress(rpTx.getTxData().getAddress()) != null;
            result.setSuccess(con);
        } else if (tx.isSystemTx()) {
            result = ValidateResult.getFailedResult(this.getClass().getSimpleName(), TransactionErrorCode.TX_NOT_EFFECTIVE);
        } else {
            start = System.nanoTime();
            result = ledgerService.verifyCoinData(tx, toMaps, fromSet);
            verifyUse += (System.nanoTime() - start);
        }
        start = System.nanoTime();
        if (result.isFailed()) {
            if (tx == null) {
                continue;
            }
            if (result.getErrorCode().equals(TransactionErrorCode.ORPHAN_TX)) {
                txMemoryPool.add(tx, true);
            }
            failed1Use += (System.nanoTime() - start);
            continue;
        }
        start = System.nanoTime();
        if (!outHashSet.add(tx.getHash())) {
            outHashSetUse += (System.nanoTime() - start);
            Log.warn("重复的交易");
            continue;
        }
        outHashSetUse += (System.nanoTime() - start);
        // 打包时发现智能合约交易就调用智能合约
        if (ContractUtil.isContractTransaction(tx)) {
            contractResult = contractService.batchPackageTx(tx, height, tempBlock, stateRoot, toMaps, contractUsedCoinMap).getData();
            if (contractResult != null) {
                totalGasUsed += contractResult.getGasUsed();
                contractResultList.add(contractResult);
            }
        }
        tx.setBlockHeight(bd.getHeight());
        start = System.nanoTime();
        packingTxList.add(tx);
        addTime += (System.nanoTime() - start);
        totalSize += txSize;
    }
    // 打包结束后移除临时余额区
    contractService.removeContractTempBalance();
    stateRoot = contractService.commitBatchExecute().getData();
    // 打包结束后移除批量执行合约的执行器
    contractService.removeBatchExecute();
    // 打包结束后移除当前区块头信息
    contractService.removeCurrentBlockHeader();
    tempBlock.getHeader().setStateRoot(stateRoot);
    for (ContractResult result : contractResultList) {
        result.setStateRoot(stateRoot);
    }
    // 更新世界状态
    bd.setStateRoot(stateRoot);
    whileTime = System.currentTimeMillis() - startWhile;
    ValidateResult validateResult = null;
    int failedCount = 0;
    long failedUse = 0;
    start = System.nanoTime();
    while (null == validateResult || validateResult.isFailed()) {
        failedCount++;
        validateResult = transactionService.conflictDetect(packingTxList);
        if (validateResult.isFailed()) {
            if (validateResult.getData() instanceof Transaction) {
                packingTxList.remove(validateResult.getData());
            } else if (validateResult.getData() instanceof List) {
                List<Transaction> list = (List<Transaction>) validateResult.getData();
                if (list.size() == 2) {
                    packingTxList.remove(list.get(1));
                } else {
                    packingTxList.removeAll(list);
                }
            } else if (validateResult.getData() == null) {
                Log.error("Cann't find the wrong transaction!");
            }
        }
    }
    // 组装CoinBase交易,另外合约调用退还剩余的Gas
    failedUse = System.nanoTime() - start;
    start = System.nanoTime();
    addConsensusTx(bestBlock, packingTxList, self, round);
    long consensusTxUse = System.nanoTime() - start;
    bd.setTxList(packingTxList);
    start = System.nanoTime();
    // 更新本地打包最终世界状态根
    bd.getExtendsData().setStateRoot(bd.getStateRoot());
    Block newBlock = ConsensusTool.createBlock(bd, round.getLocalPacker());
    long createBlockUser = System.nanoTime() - start;
    Log.info("make block height:" + newBlock.getHeader().getHeight() + ",txCount: " + newBlock.getTxs().size() + " , block size: " + newBlock.size() + " , time:" + DateUtil.convertDate(new Date(newBlock.getHeader().getTime())) + ",packEndTime:" + DateUtil.convertDate(new Date(self.getPackEndTime())));
    // pierre test comment out
    Log.debug("\ncheck count:" + count + "\ngetTxUse:" + getTxUse / 1000000 + " ,\nledgerExistUse:" + ledgerUse / 1000000 + ", \nverifyUse:" + verifyUse / 1000000 + " ,\noutHashSetUse:" + outHashSetUse / 1000000 + " ,\nfailedTimes:" + failedCount + ", \nfailedUse:" + failedUse / 1000000 + " ,\nconsensusTx:" + consensusTxUse / 1000000 + ", \nblockUse:" + createBlockUser / 1000000 + ", \nsleepTIme:" + sleepTIme + ",\nwhileTime:" + whileTime + ", \naddTime:" + addTime / 1000000 + " ,\nsizeTime:" + sizeTime / 1000000 + " ,\nfailed1Use:" + failed1Use / 1000000);
    return newBlock;
}
Also used : RedPunishTransaction(io.nuls.consensus.poc.protocol.tx.RedPunishTransaction) BlockExtendsData(io.nuls.consensus.poc.model.BlockExtendsData) RandomSeedStatusPo(io.nuls.consensus.poc.storage.po.RandomSeedStatusPo) BlockData(io.nuls.consensus.poc.model.BlockData) ContractResult(io.nuls.contract.dto.ContractResult) ValidateResult(io.nuls.kernel.validate.ValidateResult) YellowPunishTransaction(io.nuls.consensus.poc.protocol.tx.YellowPunishTransaction) RedPunishTransaction(io.nuls.consensus.poc.protocol.tx.RedPunishTransaction) CoinBaseTransaction(io.nuls.protocol.model.tx.CoinBaseTransaction) SmallBlock(io.nuls.protocol.model.SmallBlock)

Example 27 with ValidateResult

use of io.nuls.kernel.validate.ValidateResult in project nuls by nuls-io.

the class TransactionServiceImpl 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.
 *
 * @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();
    }
    // ValidateResult result = ledgerService.verifyDoubleSpend(txList);
    // if (result.isFailed()) {
    // return result;
    // }
    List<Transaction> newTxList = new ArrayList<>();
    for (Transaction tx : txList) {
        if (tx.getType() == ProtocolConstant.TX_TYPE_COINBASE || tx.getType() == ProtocolConstant.TX_TYPE_TRANSFER) {
            continue;
        }
        newTxList.add(tx);
    }
    List<TransactionProcessor> processorList = TransactionManager.getAllProcessorList();
    ValidateResult result = ValidateResult.getSuccessResult();
    for (TransactionProcessor processor : processorList) {
        result = processor.conflictDetect(newTxList);
        if (result.isFailed()) {
            break;
        }
    }
    return result;
}
Also used : Transaction(io.nuls.kernel.model.Transaction) TransactionProcessor(io.nuls.kernel.processor.TransactionProcessor) ValidateResult(io.nuls.kernel.validate.ValidateResult) ArrayList(java.util.ArrayList)

Example 28 with ValidateResult

use of io.nuls.kernel.validate.ValidateResult in project nuls by nuls-io.

the class TransactionServiceImpl method broadcastTx.

/**
 * 广播交易给连接的其他对等节点
 * The broadcast transaction gives the connection to other peers.
 *
 * @param tx 完整交易/the whole transaction
 * @return 广播结果/Broadcast the results
 */
@Override
public Result broadcastTx(Transaction tx) {
    try {
        ValidateResult validateResult = contractService.baseValidate(tx);
        if (validateResult.isFailed()) {
            return validateResult;
        }
    } catch (NulsException e) {
        Log.error(e);
        return Result.getFailed();
    }
    TransactionMessage message = new TransactionMessage();
    message.setMsgBody(tx);
    consensusService.newTx(tx);
    // return Result.getSuccess();
    return messageBusService.broadcast(message, null, true, 50);
}
Also used : TransactionMessage(io.nuls.protocol.message.TransactionMessage) NulsException(io.nuls.kernel.exception.NulsException) ValidateResult(io.nuls.kernel.validate.ValidateResult)

Example 29 with ValidateResult

use of io.nuls.kernel.validate.ValidateResult in project nuls by nuls-io.

the class TransactionServiceImplTest method conflictDetect.

private void conflictDetect() {
    ValidateResult result = transactionService.conflictDetect(allList);
    this.txList = (List<Transaction>) result.getData();
    assertNotNull(txList);
    // 数值需要确定,目前随便写的
    assertEquals(2, 2);
}
Also used : TransferTransaction(io.nuls.protocol.model.tx.TransferTransaction) CoinBaseTransaction(io.nuls.protocol.model.tx.CoinBaseTransaction) ValidateResult(io.nuls.kernel.validate.ValidateResult)

Example 30 with ValidateResult

use of io.nuls.kernel.validate.ValidateResult in project nuls by nuls-io.

the class AliasTransactionValidator method validate.

@Override
public ValidateResult validate(AliasTransaction tx) {
    Alias alias = tx.getTxData();
    if (tx.isSystemTx()) {
        return ValidateResult.getFailedResult(this.getClass().getName(), TransactionErrorCode.TX_TYPE_ERROR);
    }
    if (NulsContext.CONTRACT_ADDRESS_TYPE == alias.getAddress()[2]) {
        return ValidateResult.getFailedResult(this.getClass().getName(), AccountErrorCode.ADDRESS_ERROR);
    }
    if (!StringUtils.validAlias(alias.getAlias())) {
        return ValidateResult.getFailedResult(this.getClass().getName(), AccountErrorCode.ALIAS_FORMAT_WRONG);
    }
    if (!aliasService.isAliasUsable(alias.getAlias())) {
        return ValidateResult.getFailedResult(this.getClass().getName(), AccountErrorCode.ALIAS_EXIST);
    }
    List<AliasPo> list = aliasStorageService.getAliasList().getData();
    for (AliasPo aliasPo : list) {
        if (Arrays.equals(aliasPo.getAddress(), alias.getAddress())) {
            return ValidateResult.getFailedResult(this.getClass().getName(), AccountErrorCode.ACCOUNT_ALREADY_SET_ALIAS);
        }
    }
    CoinData coinData = tx.getCoinData();
    if (null == coinData || null == coinData.getTo() || coinData.getTo().isEmpty()) {
        return ValidateResult.getFailedResult(this.getClass().getName(), TransactionErrorCode.COINDATA_NOT_FOUND);
    }
    boolean burned = false;
    for (Coin coin : coinData.getTo()) {
        if (ArraysTool.arrayEquals(coin.getOwner(), NulsConstant.BLACK_HOLE_ADDRESS) && coin.getNa().equals(Na.NA)) {
            burned = true;
            break;
        }
        if (!burned && !ArraysTool.arrayEquals(coin.getOwner(), NulsConstant.BLACK_HOLE_ADDRESS_TEST_NET) && coin.getNa().equals(Na.NA)) {
            burned = true;
            break;
        }
    }
    if (!burned) {
        return ValidateResult.getFailedResult(this.getClass().getName(), AccountErrorCode.MUST_BURN_A_NULS);
    }
    TransactionSignature sig = new TransactionSignature();
    try {
        sig.parse(tx.getTransactionSignature(), 0);
    } catch (NulsException e) {
        Log.error(e);
        return ValidateResult.getFailedResult(this.getClass().getName(), e.getErrorCode());
    }
    boolean sign;
    try {
        sign = SignatureUtil.containsAddress(tx, tx.getTxData().getAddress());
    } catch (NulsException e) {
        sign = false;
    }
    if (!sign) {
        ValidateResult result = ValidateResult.getFailedResult(this.getClass().getName(), AccountErrorCode.ADDRESS_ERROR);
        result.setLevel(SeverityLevelEnum.FLAGRANT_FOUL);
        return result;
    }
    return ValidateResult.getSuccessResult();
}
Also used : Coin(io.nuls.kernel.model.Coin) Alias(io.nuls.account.model.Alias) CoinData(io.nuls.kernel.model.CoinData) NulsException(io.nuls.kernel.exception.NulsException) ValidateResult(io.nuls.kernel.validate.ValidateResult) AliasPo(io.nuls.account.storage.po.AliasPo) TransactionSignature(io.nuls.kernel.script.TransactionSignature)

Aggregations

ValidateResult (io.nuls.kernel.validate.ValidateResult)31 NulsException (io.nuls.kernel.exception.NulsException)12 IOException (java.io.IOException)8 Agent (io.nuls.consensus.poc.protocol.entity.Agent)6 RedPunishTransaction (io.nuls.consensus.poc.protocol.tx.RedPunishTransaction)6 Coin (io.nuls.kernel.model.Coin)6 Transaction (io.nuls.kernel.model.Transaction)6 RedPunishData (io.nuls.consensus.poc.protocol.entity.RedPunishData)5 AgentPo (io.nuls.consensus.poc.storage.po.AgentPo)5 TransactionSignature (io.nuls.kernel.script.TransactionSignature)5 HashSet (java.util.HashSet)5 CreateAgentTransaction (io.nuls.consensus.poc.protocol.tx.CreateAgentTransaction)4 CoinData (io.nuls.kernel.model.CoinData)4 SmallBlock (io.nuls.protocol.model.SmallBlock)4 ArrayList (java.util.ArrayList)4 BaseTest (io.nuls.consensus.poc.BaseTest)3 DepositPo (io.nuls.consensus.poc.storage.po.DepositPo)3 ContractResult (io.nuls.contract.dto.ContractResult)3 NulsRuntimeException (io.nuls.kernel.exception.NulsRuntimeException)3 CoinBaseTransaction (io.nuls.protocol.model.tx.CoinBaseTransaction)3