Search in sources :

Example 1 with ServiceConnection

use of com.jd.httpservice.agent.ServiceConnection in project jdchain-core by blockchain-jd-com.

the class ManagementController method checkLedgerDiff.

private WebResponse checkLedgerDiff(HashDigest ledgerHash, LedgerRepository ledgerRepository, LedgerBlock ledgerLatestBlock, ServiceEndpoint endpoint) {
    LOGGER.info("check ledger diff from {}:{}:{}", endpoint.getHost(), endpoint.getPort(), endpoint.isSecure());
    long localLatestBlockHeight = ledgerLatestBlock.getHeight();
    HashDigest localLatestBlockHash = ledgerLatestBlock.getHash();
    TransactionBatchResultHandle handle = null;
    try (ServiceConnection httpConnection = ServiceConnectionManager.connect(endpoint)) {
        HttpBlockchainBrowserService queryService = HttpServiceAgent.createService(HttpBlockchainBrowserService.class, httpConnection, null);
        // 激活新节点时,远端管理节点最新区块高度
        long remoteLatestBlockHeight = queryService.getLedger(ledgerHash).getLatestBlockHeight();
        if ((localLatestBlockHeight <= remoteLatestBlockHeight)) {
            // 检查本节点与拉取节点相同高度的区块,哈希是否一致,不一致说明其中一个节点的数据库被污染了
            HashDigest remoteBlockHash = queryService.getBlock(ledgerHash, localLatestBlockHeight).getHash();
            if (!(localLatestBlockHash.toBase58().equals(remoteBlockHash.toBase58()))) {
                throw new IllegalStateException("checkLedgerDiff, ledger database is inconsistent, please check ledger database!");
            }
            // 本节点与拉取节点高度一致,不需要进行交易重放
            if (localLatestBlockHeight == remoteLatestBlockHeight) {
                return WebResponse.createSuccessResult(null);
            }
        } else {
            throw new IllegalStateException("checkLedgerDiff, local latest block height > remote node latest block height!");
        }
        OperationHandleRegisteration opReg = new DefaultOperationHandleRegisteration();
        // 对差异进行交易重放
        for (int height = (int) localLatestBlockHeight + 1; height <= remoteLatestBlockHeight; height++) {
            TransactionBatchProcessor txbatchProcessor = new TransactionBatchProcessor(ledgerRepository, opReg);
            // transactions replay
            try {
                HashDigest pullBlockHash = queryService.getBlock(ledgerHash, height).getHash();
                long pullBlockTime = queryService.getBlock(ledgerHash, height).getTimestamp();
                // 获取区块内的增量交易
                List<LedgerTransaction> addition_transactions = getAdditionalTransactions(queryService, ledgerHash, height);
                try {
                    for (LedgerTransaction ledgerTransaction : addition_transactions) {
                        txbatchProcessor.schedule(ledgerTransaction.getRequest());
                    }
                } catch (BlockRollbackException e) {
                    txbatchProcessor.cancel(LEDGER_ERROR);
                    continue;
                }
                LedgerEditor.TIMESTAMP_HOLDER.set(pullBlockTime);
                handle = txbatchProcessor.prepare();
                if (!(handle.getBlock().getHash().toBase58().equals(pullBlockHash.toBase58()))) {
                    LOGGER.error("checkLedgerDiff, transactions replay result is inconsistent at height {}", height);
                    throw new IllegalStateException("checkLedgerDiff, transactions replay, block hash result is inconsistent!");
                }
                handle.commit();
            } catch (Exception e) {
                handle.cancel(LEDGER_ERROR);
                throw new IllegalStateException("checkLedgerDiff, transactions replay failed!", e);
            }
        }
    } catch (Exception e) {
        LOGGER.error("checkLedgerDiff error!", e);
        return WebResponse.createFailureResult(-1, "checkLedgerDiff error!" + e);
    }
    return WebResponse.createSuccessResult(null);
}
Also used : ServiceConnection(com.jd.httpservice.agent.ServiceConnection) ServiceEndpoint(com.jd.httpservice.agent.ServiceEndpoint) BusinessException(utils.BusinessException) HttpBlockchainBrowserService(com.jd.blockchain.sdk.proxy.HttpBlockchainBrowserService) TransactionBatchResultHandle(com.jd.blockchain.service.TransactionBatchResultHandle)

Example 2 with ServiceConnection

use of com.jd.httpservice.agent.ServiceConnection in project jdchain-core by blockchain-jd-com.

the class BlockSyncService method sync.

public void sync(ServiceEndpoint serviceEndpoint, HashDigest ledger, long height) throws BlockSyncException {
    if (!repository.getHash().equals(ledger)) {
        LOGGER.error("sync ledger not match, expect: {} actual: {}", ledger, repository.getHash());
        return;
    }
    try {
        try (ServiceConnection httpConnection = ServiceConnectionManager.connect(serviceEndpoint)) {
            HttpBlockchainBrowserService queryService = HttpServiceAgent.createService(HttpBlockchainBrowserService.class, httpConnection, null);
            LedgerBlock block = queryService.getBlock(ledger, height);
            sync(queryService, ledger, block);
        }
    } catch (Exception e) {
        throw new BlockSyncException(e);
    }
}
Also used : HttpBlockchainBrowserService(com.jd.blockchain.sdk.proxy.HttpBlockchainBrowserService) ServiceConnection(com.jd.httpservice.agent.ServiceConnection) BlockSyncException(com.jd.blockchain.consensus.raft.consensus.BlockSyncException) BlockSyncException(com.jd.blockchain.consensus.raft.consensus.BlockSyncException)

Example 3 with ServiceConnection

use of com.jd.httpservice.agent.ServiceConnection in project jdchain-core by blockchain-jd-com.

the class ManagementController method replayTransaction.

private boolean replayTransaction(LedgerRepository ledgerRepository, ParticipantNode node, ServiceEndpoint endpoint) {
    long height = ledgerRepository.retrieveLatestBlock().getHeight();
    HashDigest ledgerHash = ledgerRepository.retrieveLatestBlock().getLedgerHash();
    TransactionBatchResultHandle handle = null;
    OperationHandleRegisteration opReg = new DefaultOperationHandleRegisteration();
    try (ServiceConnection httpConnection = ServiceConnectionManager.connect(endpoint)) {
        HttpBlockchainBrowserService queryService = HttpServiceAgent.createService(HttpBlockchainBrowserService.class, httpConnection, null);
        while (true) {
            boolean getout = false;
            TransactionBatchProcessor batchProcessor = new TransactionBatchProcessor(ledgerRepository, opReg);
            try {
                height++;
                long remoteLatestBlockHeight = queryService.getLedger(ledgerHash).getLatestBlockHeight();
                // fix endpoint write block to database slow bug, that lead to active node failed!
                int count = 0;
                while ((remoteLatestBlockHeight < height) && (count < 600)) {
                    Thread.sleep(1000);
                    remoteLatestBlockHeight = queryService.getLedger(ledgerHash).getLatestBlockHeight();
                    count++;
                }
                if (remoteLatestBlockHeight < height) {
                    throw new IllegalStateException("Remote endpoint block height exception!");
                }
                LedgerBlock block = queryService.getBlock(ledgerHash, height);
                // 获取区块内的增量交易
                List<LedgerTransaction> transactions = getAdditionalTransactions(queryService, ledgerHash, (int) height);
                try {
                    for (LedgerTransaction ledgerTransaction : transactions) {
                        batchProcessor.schedule(ledgerTransaction.getRequest());
                        Operation[] operations = ledgerTransaction.getRequest().getTransactionContent().getOperations();
                        for (Operation op : operations) {
                            if (op instanceof ParticipantStateUpdateOperation) {
                                ParticipantStateUpdateOperation psop = (ParticipantStateUpdateOperation) op;
                                if (psop.getParticipantID().getPubKey().equals(node.getPubKey())) {
                                    getout = true;
                                }
                            }
                        }
                    }
                } catch (BlockRollbackException e) {
                    batchProcessor.cancel(LEDGER_ERROR);
                    continue;
                }
                LedgerEditor.TIMESTAMP_HOLDER.set(block.getTimestamp());
                handle = batchProcessor.prepare();
                if (!(handle.getBlock().getHash().toBase58().equals(block.getHash().toBase58()))) {
                    LOGGER.error("replayTransaction, transactions replay result is inconsistent at height {}", height);
                    throw new IllegalStateException("checkLedgerDiff, transactions replay, block hash result is inconsistent!");
                }
                handle.commit();
                LOGGER.debug("replayTransaction, transactions replay result is consistent at height {}", height);
                if (getout) {
                    return true;
                }
            } catch (Exception e) {
                handle.cancel(LEDGER_ERROR);
                throw new IllegalStateException("replayTransaction, transactions replay failed!", e);
            }
        }
    }
}
Also used : ServiceConnection(com.jd.httpservice.agent.ServiceConnection) ServiceEndpoint(com.jd.httpservice.agent.ServiceEndpoint) BusinessException(utils.BusinessException) HttpBlockchainBrowserService(com.jd.blockchain.sdk.proxy.HttpBlockchainBrowserService) TransactionBatchResultHandle(com.jd.blockchain.service.TransactionBatchResultHandle)

Aggregations

HttpBlockchainBrowserService (com.jd.blockchain.sdk.proxy.HttpBlockchainBrowserService)3 ServiceConnection (com.jd.httpservice.agent.ServiceConnection)3 TransactionBatchResultHandle (com.jd.blockchain.service.TransactionBatchResultHandle)2 ServiceEndpoint (com.jd.httpservice.agent.ServiceEndpoint)2 BusinessException (utils.BusinessException)2 BlockSyncException (com.jd.blockchain.consensus.raft.consensus.BlockSyncException)1