use of com.jd.blockchain.sdk.proxy.HttpBlockchainBrowserService 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);
}
use of com.jd.blockchain.sdk.proxy.HttpBlockchainBrowserService 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);
}
}
use of com.jd.blockchain.sdk.proxy.HttpBlockchainBrowserService 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);
}
}
}
}
Aggregations