use of com.jd.httpservice.agent.ServiceEndpoint in project jdchain-core by blockchain-jd-com.
the class BlockSyncService method onMessage.
@Override
public void onMessage(byte[] message) {
long untilHeight = Longs.fromByteArray(message);
long latestBlockHeight = repository.retrieveLatestBlockHeight();
if (latestBlockHeight >= untilHeight) {
LoggerUtils.debugIfEnabled(LOGGER, "sync height: {} less than current latest height: {}", untilHeight, latestBlockHeight);
return;
}
if (RaftNodeServerContext.getInstance().isLeader(repository.getHash())) {
LoggerUtils.debugIfEnabled(LOGGER, "current node is leader, can not sync block");
return;
}
PeerId leader = RaftNodeServerContext.getInstance().getLeader(repository.getHash());
if (leader == null) {
LoggerUtils.errorIfEnabled(LOGGER, "current leader is null");
return;
}
ServiceEndpoint consensusNodeManagerInfo = getConsensusNodeManagerInfo(leader.getEndpoint());
LOGGER.debug("get leader: {} manager info: {}", leader, consensusNodeManagerInfo);
if (consensusNodeManagerInfo == null) {
LoggerUtils.errorIfEnabled(LOGGER, "get leader: {} manager info is null", leader);
return;
}
isSyncing = true;
try {
for (long height = latestBlockHeight + 1; height <= untilHeight; height++) {
try {
sync(consensusNodeManagerInfo, repository.getHash(), height);
} catch (BlockSyncException e) {
LOGGER.error("sync height: {} error", height, e);
break;
}
}
} finally {
isSyncing = false;
}
}
use of com.jd.httpservice.agent.ServiceEndpoint in project jdchain-core by blockchain-jd-com.
the class ParticipantInactive method update.
public WebResponse update() throws Exception {
String url = (secure ? "https://" : "http://") + host + ":" + port + "/management/delegate/updateparticipant";
HttpPost httpPost = new HttpPost(url);
List<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>();
params.add(new BasicNameValuePair("ledgerHash", ledger));
params.add(new BasicNameValuePair("consensusHost", consensusHost));
params.add(new BasicNameValuePair("consensusPort", consensusPort + ""));
params.add(new BasicNameValuePair("consensusStorage", consensusStorage + ""));
params.add(new BasicNameValuePair("consensusSecure", consensusSecure + ""));
params.add(new BasicNameValuePair("shutdown", shutdown + ""));
httpPost.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
ServiceEndpoint endpoint = new ServiceEndpoint(host, port, secure);
if (secure) {
GmSSLProvider.enableGMSupport(participant.getSSLSecurity().getProtocol());
endpoint.setSslSecurity(participant.getSSLSecurity());
} else {
endpoint.setSslSecurity(new SSLSecurity());
}
HttpResponse response = ServiceConnectionManager.buildHttpClient(endpoint).execute(httpPost);
return (WebResponse) new JsonResponseConverter(WebResponse.class).getResponse(null, response.getEntity().getContent(), null);
}
use of com.jd.httpservice.agent.ServiceEndpoint in project jdchain-core by blockchain-jd-com.
the class ManagementController method syncBlock.
/**
* 区块同步:
* 从指定节点同步最新区块信息,调用此接口会执行NodeServer重建
*
* @param ledgerHash 账本
* @param syncHost 同步节点IP
* @param syncPort 同步节点端口
* @return
*/
@RequestMapping(path = "/block/sync", method = RequestMethod.POST)
public WebResponse syncBlock(@RequestParam("ledgerHash") String ledgerHash, @RequestParam("syncHost") String syncHost, @RequestParam("syncPort") int syncPort, @RequestParam(name = "syncSecure", required = false, defaultValue = "false") boolean syncSecure, @RequestParam(name = "restart", required = false, defaultValue = "false") boolean restart) {
try {
HashDigest ledger = Crypto.resolveAsHashDigest(Base58Utils.decode(ledgerHash));
if (!ledgerKeypairs.containsKey(ledger)) {
return WebResponse.createFailureResult(-1, "input ledger hash not exist!");
}
LedgerRepository ledgerRepo = (LedgerRepository) ledgerQuerys.get(ledger);
LedgerBlock ledgerLatestBlock = ledgerRepo.retrieveLatestBlock();
LedgerAdminInfo ledgerAdminInfo = ledgerRepo.getAdminInfo(ledgerLatestBlock);
// 目前仅支持BFT-SMaRt
if (ledgerAdminInfo.getSettings().getConsensusProvider().equals(ConsensusTypeEnum.BFTSMART.getProvider())) {
// 检查本地节点与远端节点在库上是否存在差异,有差异的进行差异交易重放
ServiceEndpoint endpoint = new ServiceEndpoint(new NetworkAddress(syncHost, syncPort, syncSecure));
SSLSecurity sslSecurity = bindingConfigs.get(ledger).getSslSecurity();
endpoint.setSslSecurity(sslSecurity);
WebResponse webResponse = checkLedgerDiff(ledger, ledgerRepo, ledgerLatestBlock, endpoint);
if (!webResponse.isSuccess()) {
return webResponse;
}
// 重建 NodeServer
if (restart) {
setupServer(ledgerRepo, false);
}
LOGGER.info("sync block success!");
return WebResponse.createSuccessResult(null);
} else {
return WebResponse.createSuccessResult(null);
}
} catch (Exception e) {
LOGGER.error("sync block failed!", e);
return WebResponse.createFailureResult(-1, "sync block failed! " + e.getMessage());
}
}
use of com.jd.httpservice.agent.ServiceEndpoint 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.httpservice.agent.ServiceEndpoint in project jdchain-core by blockchain-jd-com.
the class BlockSyncService method sync.
@Override
public void sync(Endpoint peerEndpoint, HashDigest ledger, long height) throws BlockSyncException {
ServiceEndpoint consensusNodeManagerInfo = getConsensusNodeManagerInfo(peerEndpoint);
if (consensusNodeManagerInfo == null) {
LoggerUtils.errorIfEnabled(LOGGER, "get peer: {} manager info is null", peerEndpoint);
throw new BlockSyncException("get peer manager info is null");
}
sync(consensusNodeManagerInfo, ledger, height);
}
Aggregations