Search in sources :

Example 1 with RandomSeedStatusPo

use of io.nuls.consensus.poc.storage.po.RandomSeedStatusPo in project nuls by nuls-io.

the class RandomSeedsStorageServiceImpl method getAddressStatus.

@Override
public RandomSeedStatusPo getAddressStatus(byte[] address) {
    byte[] bytes = dbService.get(ConsensusStorageConstant.DB_NAME_RANDOM_SEEDS, address);
    if (null == bytes) {
        return null;
    }
    RandomSeedStatusPo po = new RandomSeedStatusPo();
    try {
        po.parse(new NulsByteBuffer(bytes, 0));
        po.setAddress(address);
    } catch (NulsException e) {
        Log.error(e);
    }
    return po;
}
Also used : NulsException(io.nuls.kernel.exception.NulsException) RandomSeedStatusPo(io.nuls.consensus.poc.storage.po.RandomSeedStatusPo) NulsByteBuffer(io.nuls.kernel.utils.NulsByteBuffer)

Example 2 with RandomSeedStatusPo

use of io.nuls.consensus.poc.storage.po.RandomSeedStatusPo 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 3 with RandomSeedStatusPo

use of io.nuls.consensus.poc.storage.po.RandomSeedStatusPo in project nuls by nuls-io.

the class RandomSeedService method processBlock.

public void processBlock(BlockHeader header, BlockHeader preHeader) {
    if (NulsVersionManager.getMainVersion() < 3) {
        return;
    }
    BlockExtendsData extendsData = new BlockExtendsData(header.getExtend());
    byte[] nextSeed = null;
    if (ArraysTool.arrayEquals(header.getPackingAddress(), RandomSeedUtils.CACHE_SEED.getAddress())) {
        nextSeed = RandomSeedUtils.CACHE_SEED.getNextSeed();
    }
    byte[] seed = extendsData.getSeed();
    RandomSeedStatusPo po = this.randomSeedsStorageService.getAddressStatus(header.getPackingAddress());
    long preHeight = 0;
    // pierre test comment out
    if (null == po || ArraysTool.arrayEquals(preHeader.getPackingAddress(), header.getPackingAddress()) || !ArraysTool.arrayEquals(RandomSeedUtils.getLastDigestEightBytes(extendsData.getSeed()), po.getSeedHash())) {
        seed = ConsensusStorageConstant.EMPTY_SEED;
    }
    if (null != po) {
        preHeight = po.getHeight();
    }
    randomSeedsStorageService.saveAddressStatus(header.getPackingAddress(), header.getHeight(), nextSeed, extendsData.getNextSeedHash());
    randomSeedsStorageService.saveRandomSeed(header.getHeight(), preHeight, seed, extendsData.getNextSeedHash());
}
Also used : BlockExtendsData(io.nuls.consensus.poc.model.BlockExtendsData) RandomSeedStatusPo(io.nuls.consensus.poc.storage.po.RandomSeedStatusPo)

Example 4 with RandomSeedStatusPo

use of io.nuls.consensus.poc.storage.po.RandomSeedStatusPo in project nuls by nuls-io.

the class RandomSeedsStorageServiceImpl method saveAddressStatus.

@Override
public boolean saveAddressStatus(byte[] address, long nowHeight, byte[] nextSeed, byte[] seedHash) {
    RandomSeedStatusPo po = new RandomSeedStatusPo();
    po.setAddress(address);
    po.setHeight(nowHeight);
    po.setNextSeed(nextSeed);
    po.setSeedHash(seedHash);
    // System.out.println(po.toString());
    try {
        dbService.put(ConsensusStorageConstant.DB_NAME_RANDOM_SEEDS, address, po.serialize());
        return true;
    } catch (IOException e) {
        Log.error(e);
    }
    return false;
}
Also used : IOException(java.io.IOException) RandomSeedStatusPo(io.nuls.consensus.poc.storage.po.RandomSeedStatusPo)

Aggregations

RandomSeedStatusPo (io.nuls.consensus.poc.storage.po.RandomSeedStatusPo)4 BlockExtendsData (io.nuls.consensus.poc.model.BlockExtendsData)2 BlockData (io.nuls.consensus.poc.model.BlockData)1 RedPunishTransaction (io.nuls.consensus.poc.protocol.tx.RedPunishTransaction)1 YellowPunishTransaction (io.nuls.consensus.poc.protocol.tx.YellowPunishTransaction)1 ContractResult (io.nuls.contract.dto.ContractResult)1 NulsException (io.nuls.kernel.exception.NulsException)1 NulsByteBuffer (io.nuls.kernel.utils.NulsByteBuffer)1 ValidateResult (io.nuls.kernel.validate.ValidateResult)1 SmallBlock (io.nuls.protocol.model.SmallBlock)1 CoinBaseTransaction (io.nuls.protocol.model.tx.CoinBaseTransaction)1 IOException (java.io.IOException)1