Search in sources :

Example 11 with BlockExtendsData

use of io.nuls.consensus.poc.model.BlockExtendsData 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 12 with BlockExtendsData

use of io.nuls.consensus.poc.model.BlockExtendsData 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)

Example 13 with BlockExtendsData

use of io.nuls.consensus.poc.model.BlockExtendsData in project nuls by nuls-io.

the class ForkChainProcess method clearMasterChainData.

private void clearMasterChainData() {
    Chain masterChain = chainManager.getMasterChain().getChain();
    long bestHeight = masterChain.getEndBlockHeader().getHeight();
    List<Agent> agentList = masterChain.getAgentList();
    List<Deposit> depositList = masterChain.getDepositList();
    Iterator<Agent> ait = agentList.iterator();
    while (ait.hasNext()) {
        Agent agent = ait.next();
        if (agent.getDelHeight() > 0L && (bestHeight - 1000) > agent.getDelHeight()) {
            ait.remove();
        }
    }
    Iterator<Deposit> dit = depositList.iterator();
    while (dit.hasNext()) {
        Deposit deposit = dit.next();
        if (deposit.getDelHeight() > 0L && (bestHeight - 1000) > deposit.getDelHeight()) {
            dit.remove();
        }
    }
    BlockExtendsData roundData = new BlockExtendsData(chainManager.getBestBlock().getHeader().getExtend());
    List<PunishLogPo> yellowList = masterChain.getYellowPunishList();
    Iterator<PunishLogPo> yit = yellowList.iterator();
    while (yit.hasNext()) {
        PunishLogPo punishLog = yit.next();
        if (punishLog.getRoundIndex() < roundData.getPackingIndexOfRound() - PocConsensusConstant.INIT_HEADERS_OF_ROUND_COUNT) {
            yit.remove();
        }
    }
}
Also used : Chain(io.nuls.consensus.poc.model.Chain) Agent(io.nuls.consensus.poc.protocol.entity.Agent) Deposit(io.nuls.consensus.poc.protocol.entity.Deposit) BlockExtendsData(io.nuls.consensus.poc.model.BlockExtendsData) PunishLogPo(io.nuls.consensus.poc.storage.po.PunishLogPo)

Example 14 with BlockExtendsData

use of io.nuls.consensus.poc.model.BlockExtendsData 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 15 with BlockExtendsData

use of io.nuls.consensus.poc.model.BlockExtendsData in project nuls by nuls-io.

the class ConsensusTool method getStateRoot.

public static byte[] getStateRoot(BlockHeader blockHeader) {
    if (blockHeader == null || blockHeader.getExtend() == null) {
        return null;
    }
    byte[] stateRoot = blockHeader.getStateRoot();
    if (stateRoot != null && stateRoot.length > 0) {
        return stateRoot;
    }
    try {
        BlockExtendsData extendsData = new BlockExtendsData(blockHeader.getExtend());
        stateRoot = extendsData.getStateRoot();
        if ((stateRoot == null || stateRoot.length == 0) && NulsContext.MAIN_NET_VERSION > 1) {
            stateRoot = Hex.decode(NulsContext.INITIAL_STATE_ROOT);
        }
        blockHeader.setStateRoot(stateRoot);
        return stateRoot;
    } catch (Exception e) {
        Log.error("parse stateRoot of blockHeader error.", e);
        return null;
    }
}
Also used : BlockExtendsData(io.nuls.consensus.poc.model.BlockExtendsData) NulsRuntimeException(io.nuls.kernel.exception.NulsRuntimeException) IOException(java.io.IOException) NulsException(io.nuls.kernel.exception.NulsException)

Aggregations

BlockExtendsData (io.nuls.consensus.poc.model.BlockExtendsData)16 BlockHeader (io.nuls.kernel.model.BlockHeader)7 ArrayList (java.util.ArrayList)6 PunishLogPo (io.nuls.consensus.poc.storage.po.PunishLogPo)5 NulsRuntimeException (io.nuls.kernel.exception.NulsRuntimeException)5 MeetingRound (io.nuls.consensus.poc.model.MeetingRound)3 YellowPunishData (io.nuls.consensus.poc.protocol.entity.YellowPunishData)3 MeetingMember (io.nuls.consensus.poc.model.MeetingMember)2 YellowPunishTransaction (io.nuls.consensus.poc.protocol.tx.YellowPunishTransaction)2 RandomSeedStatusPo (io.nuls.consensus.poc.storage.po.RandomSeedStatusPo)2 ProtocolContainer (io.nuls.protocol.base.version.ProtocolContainer)2 CoinBaseTransaction (io.nuls.protocol.model.tx.CoinBaseTransaction)2 ProtocolTempInfoPo (io.nuls.protocol.storage.po.ProtocolTempInfoPo)2 IOException (java.io.IOException)2 BlockData (io.nuls.consensus.poc.model.BlockData)1 Chain (io.nuls.consensus.poc.model.Chain)1 Evidence (io.nuls.consensus.poc.model.Evidence)1 Agent (io.nuls.consensus.poc.protocol.entity.Agent)1 Deposit (io.nuls.consensus.poc.protocol.entity.Deposit)1 RedPunishData (io.nuls.consensus.poc.protocol.entity.RedPunishData)1