From 07ef9b7fa3a1d260702077b82de651013f56aace Mon Sep 17 00:00:00 2001 From: Xinyi YAN <41045439+yanxinyi620@users.noreply.github.com> Date: Thu, 22 Aug 2024 17:16:40 +0800 Subject: [PATCH 1/9] update global plot and sync files --- python/ppc_model/common/global_context.py | 4 --- python/ppc_model/common/initializer.py | 7 +++- python/ppc_model/common/model_result.py | 35 +++---------------- python/ppc_model/metrics/evaluation.py | 3 +- python/ppc_model/metrics/model_plot.py | 3 +- .../secure_lgbm/monitor/evaluation_monitor.py | 4 +-- .../secure_lgbm/secure_lgbm_context.py | 19 ++++++++++ .../test_secure_lgbm_performance_training.py | 6 ++-- .../test/test_secure_lgbm_training.py | 12 ++++--- .../secure_lgbm/vertical/active_party.py | 3 +- 10 files changed, 47 insertions(+), 49 deletions(-) diff --git a/python/ppc_model/common/global_context.py b/python/ppc_model/common/global_context.py index d552bef5..186fe3f0 100644 --- a/python/ppc_model/common/global_context.py +++ b/python/ppc_model/common/global_context.py @@ -1,5 +1,4 @@ import os -import threading from ppc_model.common.initializer import Initializer @@ -9,6 +8,3 @@ components = Initializer( log_config_path='logging.conf', config_path=config_path) - -# matplotlib 线程不安全,并行任务绘图增加全局锁 -plot_lock = threading.Lock() diff --git a/python/ppc_model/common/initializer.py b/python/ppc_model/common/initializer.py index 6dd6258f..829e0182 100644 --- a/python/ppc_model/common/initializer.py +++ b/python/ppc_model/common/initializer.py @@ -1,6 +1,7 @@ import logging import logging.config import os +import threading import yaml @@ -14,7 +15,7 @@ class Initializer: - def __init__(self, log_config_path, config_path): + def __init__(self, log_config_path, config_path, plot_lock=None): self.log_config_path = log_config_path self.config_path = config_path self.config_data = None @@ -27,6 +28,10 @@ def __init__(self, log_config_path, config_path): self.mock_logger = None self.public_key_length = 2048 self.homo_algorithm = 0 + # matplotlib 线程不安全,并行任务绘图增加全局锁 + self.plot_lock = plot_lock + if plot_lock is None: + self.plot_lock = threading.Lock() def init_all(self): self.init_log() diff --git a/python/ppc_model/common/model_result.py b/python/ppc_model/common/model_result.py index 0cb55142..d42f4106 100644 --- a/python/ppc_model/common/model_result.py +++ b/python/ppc_model/common/model_result.py @@ -20,14 +20,14 @@ def __init__(self, ctx: Context) -> None: if ctx.algorithm_type == AlgorithmType.Train.name: self._process_fe_result() - # remove job workspace - # self._remove_workspace() - # Synchronization result file if (len(ctx.result_receiver_id_list) == 1 and ctx.participant_id_list[0] != ctx.result_receiver_id_list[0]) \ or len(ctx.result_receiver_id_list) > 1: self._sync_result_files() + # remove job workspace + self._remove_workspace() + def _process_fe_result(self): if os.path.exists(self.ctx.preprocessing_result_file): column_info_fm = pd.read_csv( @@ -134,33 +134,8 @@ def _remove_workspace(self): f'job {self.ctx.job_id}: {self.ctx.workspace} does not exist.') def _sync_result_files(self): - if self.ctx.algorithm_type == AlgorithmType.Train.name: - self.sync_result_file(self.ctx, self.ctx.metrics_iteration_file, - self.ctx.remote_metrics_iteration_file, 'f1') - self.sync_result_file(self.ctx, self.ctx.feature_importance_file, - self.ctx.remote_feature_importance_file, 'f2') - self.sync_result_file(self.ctx, self.ctx.summary_evaluation_file, - self.ctx.remote_summary_evaluation_file, 'f3') - self.sync_result_file(self.ctx, self.ctx.train_metric_ks_table, - self.ctx.remote_train_metric_ks_table, 'f4') - self.sync_result_file(self.ctx, self.ctx.train_metric_roc_file, - self.ctx.remote_train_metric_roc_file, 'f5') - self.sync_result_file(self.ctx, self.ctx.train_metric_ks_file, - self.ctx.remote_train_metric_ks_file, 'f6') - self.sync_result_file(self.ctx, self.ctx.train_metric_pr_file, - self.ctx.remote_train_metric_pr_file, 'f7') - self.sync_result_file(self.ctx, self.ctx.train_metric_acc_file, - self.ctx.remote_train_metric_acc_file, 'f8') - self.sync_result_file(self.ctx, self.ctx.test_metric_ks_table, - self.ctx.remote_test_metric_ks_table, 'f9') - self.sync_result_file(self.ctx, self.ctx.test_metric_roc_file, - self.ctx.remote_test_metric_roc_file, 'f10') - self.sync_result_file(self.ctx, self.ctx.test_metric_ks_file, - self.ctx.remote_test_metric_ks_file, 'f11') - self.sync_result_file(self.ctx, self.ctx.test_metric_pr_file, - self.ctx.remote_test_metric_pr_file, 'f12') - self.sync_result_file(self.ctx, self.ctx.test_metric_acc_file, - self.ctx.remote_test_metric_acc_file, 'f13') + for key, value in self.ctx.sync_file_list.items(): + self.sync_result_file(self.ctx, value[0], value[1], key) @staticmethod def sync_result_file(ctx, local_file, remote_file, key_file): diff --git a/python/ppc_model/metrics/evaluation.py b/python/ppc_model/metrics/evaluation.py index 2bf12ebb..b2f5dac2 100644 --- a/python/ppc_model/metrics/evaluation.py +++ b/python/ppc_model/metrics/evaluation.py @@ -12,7 +12,6 @@ from sklearn.metrics import roc_curve, auc from ppc_model.common.context import Context -from ppc_model.common.global_context import plot_lock from ppc_model.datasets.dataset import SecureDataset from ppc_model.common.model_result import ResultFileHandling from ppc_model.secure_lgbm.monitor.feature.feature_evaluation_info import EvaluationType @@ -156,7 +155,7 @@ def evaluation_file(self, ctx, data_index: np.ndarray, while retry_num < max_retry: retry_num += 1 try: - with plot_lock: + with ctx.components.plot_lock: ks_value, auc_value = Evaluation.plot_two_class_graph( self, y_true, y_praba) except: diff --git a/python/ppc_model/metrics/model_plot.py b/python/ppc_model/metrics/model_plot.py index bdae534b..dd3632a2 100644 --- a/python/ppc_model/metrics/model_plot.py +++ b/python/ppc_model/metrics/model_plot.py @@ -7,7 +7,6 @@ from networkx.drawing.nx_pydot import graphviz_layout from ppc_model.common.model_result import ResultFileHandling -from ppc_model.common.global_context import plot_lock from ppc_model.secure_lgbm.vertical.booster import VerticalBooster @@ -50,7 +49,7 @@ def plot_tree(self): while retry_num < max_retry: retry_num += 1 try: - with plot_lock: + with self.ctx.components.plot_lock: self._G.tree_plot( figsize=(10, 5), save_filename=tree_file_path) except: diff --git a/python/ppc_model/secure_lgbm/monitor/evaluation_monitor.py b/python/ppc_model/secure_lgbm/monitor/evaluation_monitor.py index 432149a7..edda3ba8 100644 --- a/python/ppc_model/secure_lgbm/monitor/evaluation_monitor.py +++ b/python/ppc_model/secure_lgbm/monitor/evaluation_monitor.py @@ -7,7 +7,6 @@ import matplotlib.pyplot as plt from ppc_common.ppc_utils.utils import METRICS_OVER_ITERATION_FILE -from ppc_model.common.global_context import plot_lock from ppc_model.secure_lgbm.monitor.callback import TrainingCallback from ppc_model.secure_lgbm.monitor.core import _Model @@ -110,8 +109,7 @@ def after_training(self, model: _Model) -> _Model: while retry_num < max_retry: retry_num += 1 try: - with plot_lock: - _draw_figure(model) + _draw_figure(model) except: self.logger.info(f'scores = {model.get_history()}') self.logger.info(f'path = {model.get_workspace()}') diff --git a/python/ppc_model/secure_lgbm/secure_lgbm_context.py b/python/ppc_model/secure_lgbm/secure_lgbm_context.py index d6a52db8..5475185b 100644 --- a/python/ppc_model/secure_lgbm/secure_lgbm_context.py +++ b/python/ppc_model/secure_lgbm/secure_lgbm_context.py @@ -3,6 +3,7 @@ from typing import Any, Dict from sklearn.base import BaseEstimator +from ppc_common.ppc_utils.utils import AlgorithmType from ppc_common.ppc_crypto.phe_factory import PheCipherFactory from ppc_model.common.context import Context from ppc_model.common.initializer import Initializer @@ -231,6 +232,10 @@ def __init__(self, self.lgbm_params.min_split_gain = model_setting.gamma self.lgbm_params.random_state = model_setting.seed + self.sync_file_list = {} + if self.algorithm_type == AlgorithmType.Train.name: + self.set_sync_file() + def set_lgbm_params(self, model_setting: ModelSetting): """设置lgbm参数""" self.lgbm_params.set_model_setting(model_setting) @@ -239,6 +244,20 @@ def get_lgbm_params(self): """获取lgbm参数""" return self.lgbm_params + def set_sync_file(self): + self.sync_file_list['metrics_iteration'] = [self.metrics_iteration_file, self.remote_metrics_iteration_file] + self.sync_file_list['feature_importance'] = [self.feature_importance_file, self.remote_feature_importance_file] + self.sync_file_list['summary_evaluation'] = [self.summary_evaluation_file, self.remote_summary_evaluation_file] + self.sync_file_list['train_ks_table'] = [self.train_metric_ks_table, self.remote_train_metric_ks_table] + self.sync_file_list['train_metric_roc'] = [self.train_metric_roc_file, self.remote_train_metric_roc_file] + self.sync_file_list['train_metric_ks'] = [self.train_metric_ks_file, self.remote_train_metric_ks_file] + self.sync_file_list['train_metric_pr'] = [self.train_metric_pr_file, self.remote_train_metric_pr_file] + self.sync_file_list['train_metric_acc'] = [self.train_metric_acc_file, self.remote_train_metric_acc_file] + self.sync_file_list['test_ks_table'] = [self.test_metric_ks_table, self.remote_test_metric_ks_table] + self.sync_file_list['test_metric_roc'] = [self.test_metric_roc_file, self.remote_test_metric_roc_file] + self.sync_file_list['test_metric_ks'] = [self.test_metric_ks_file, self.remote_test_metric_ks_file] + self.sync_file_list['test_metric_pr'] = [self.test_metric_pr_file, self.remote_test_metric_pr_file] + self.sync_file_list['test_metric_acc'] = [self.test_metric_acc_file, self.remote_test_metric_acc_file] class LGBMMessage(Enum): FEATURE_NAME = "FEATURE_NAME" diff --git a/python/ppc_model/secure_lgbm/test/test_secure_lgbm_performance_training.py b/python/ppc_model/secure_lgbm/test/test_secure_lgbm_performance_training.py index e992415d..0c1925ca 100644 --- a/python/ppc_model/secure_lgbm/test/test_secure_lgbm_performance_training.py +++ b/python/ppc_model/secure_lgbm/test/test_secure_lgbm_performance_training.py @@ -139,7 +139,8 @@ def active_worker(): booster_a.load_model() booster_a.predict() test_praba = booster_a.get_test_praba() - task_info_a.algorithm_type = 'PPC_PREDICT' + task_info_a.algorithm_type = 'Predict' + task_info_a.sync_file_list = {} Evaluation(task_info_a, secure_dataset_a, test_praba=test_praba) ResultFileHandling(task_info_a) @@ -159,7 +160,8 @@ def passive_worker(): booster_b.load_model() booster_b.predict() test_praba = booster_b.get_test_praba() - task_info_b.algorithm_type = 'PPC_PREDICT' + task_info_b.algorithm_type = 'Predict' + task_info_b.sync_file_list = {} Evaluation(task_info_b, secure_dataset_b, test_praba=test_praba) ResultFileHandling(task_info_b) diff --git a/python/ppc_model/secure_lgbm/test/test_secure_lgbm_training.py b/python/ppc_model/secure_lgbm/test/test_secure_lgbm_training.py index ea0806ce..d8e20c90 100644 --- a/python/ppc_model/secure_lgbm/test/test_secure_lgbm_training.py +++ b/python/ppc_model/secure_lgbm/test/test_secure_lgbm_training.py @@ -97,8 +97,9 @@ def setUp(self): def test_fit(self): args_a, args_b = mock_args() + plot_lock = threading.Lock() - active_components = Initializer(log_config_path='', config_path='') + active_components = Initializer(log_config_path='', config_path='', plot_lock=plot_lock) active_components.stub = self._active_stub active_components.config_data = { 'JOB_TEMP_DIR': '/tmp/active', 'AGENCY_ID': ACTIVE_PARTY} @@ -114,7 +115,8 @@ def test_fit(self): print(secure_dataset_a.test_X.shape) print(secure_dataset_a.test_y.shape) - passive_components = Initializer(log_config_path='', config_path='') + passive_components = Initializer(log_config_path='', config_path='', plot_lock=plot_lock) + passive_components.stub = self._passive_stub passive_components.stub = self._passive_stub passive_components.config_data = { 'JOB_TEMP_DIR': '/tmp/passive', 'AGENCY_ID': PASSIVE_PARTY} @@ -141,7 +143,8 @@ def active_worker(): booster_a.load_model() booster_a.predict() test_praba = booster_a.get_test_praba() - task_info_a.algorithm_type = 'PPC_PREDICT' + task_info_a.algorithm_type = 'Predict' + task_info_a.sync_file_list = {} Evaluation(task_info_a, secure_dataset_a, test_praba=test_praba) ResultFileHandling(task_info_a) @@ -161,7 +164,8 @@ def passive_worker(): booster_b.load_model() booster_b.predict() test_praba = booster_b.get_test_praba() - task_info_b.algorithm_type = 'PPC_PREDICT' + task_info_b.algorithm_type = 'Predict' + task_info_b.sync_file_list = {} Evaluation(task_info_b, secure_dataset_b, test_praba=test_praba) ResultFileHandling(task_info_b) diff --git a/python/ppc_model/secure_lgbm/vertical/active_party.py b/python/ppc_model/secure_lgbm/vertical/active_party.py index 6451db6b..4078ec35 100644 --- a/python/ppc_model/secure_lgbm/vertical/active_party.py +++ b/python/ppc_model/secure_lgbm/vertical/active_party.py @@ -475,7 +475,8 @@ def _end_active_data(self, is_train=True): remote_file_path=self.ctx.remote_feature_importance_file, storage_client=self.storage_client) if self.callback_container: - self.callback_container.after_training(self.model) + with self.ctx.components.plot_lock: + self.callback_container.after_training(self.model) for partner_index in range(1, len(self.ctx.participant_id_list)): if self.ctx.participant_id_list[partner_index] in self.ctx.result_receiver_id_list: From 6416da86dda36fc5a251216b0e9b3774650419c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?zachma=28=E9=A9=AC=E6=99=A8=29?= Date: Thu, 22 Aug 2024 20:21:50 +0800 Subject: [PATCH 2/9] =?UTF-8?q?[new-feature]=E5=8C=BF=E8=B8=AA=E6=9F=A5?= =?UTF-8?q?=E8=AF=A2=E8=8A=82=E7=82=B9=E5=92=8CSDK?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 + java/ppc-pir-services/build.gradle | 96 +++++++ .../gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 60756 bytes .../gradle/wrapper/gradle-wrapper.properties | 5 + java/ppc-pir-services/gradlew | 240 ++++++++++++++++++ java/ppc-pir-services/gradlew.bat | 91 +++++++ java/ppc-pir-services/script/start.sh | 126 +++++++++ java/ppc-pir-services/script/stop.sh | 45 ++++ java/ppc-pir-services/sdk/build.gradle | 26 ++ .../main/java/com/wedpr/pir/demo/Demo.java | 51 ++++ .../java/com/wedpr/pir/sdk/PirClient.java | 72 ++++++ .../com/wedpr/pir/sdk/crypto/IdHashVec.java | 51 ++++ .../pir/sdk/entity/body/PirDataBody.java | 17 ++ .../pir/sdk/entity/body/PirResultBody.java | 14 + .../pir/sdk/entity/body/ServerResultBody.java | 19 ++ .../pir/sdk/entity/body/ServerResultList.java | 17 ++ .../pir/sdk/entity/body/SimpleEntity.java | 15 ++ .../pir/sdk/entity/param/PirJobParam.java | 65 +++++ .../entity/request/ClientDecryptRequest.java | 17 ++ .../sdk/entity/request/ClientOTRequest.java | 17 ++ .../sdk/entity/request/PirBaseRequest.java | 21 ++ .../sdk/entity/request/ServerJobRequest.java | 19 ++ .../sdk/entity/request/ServerOTRequest.java | 19 ++ .../response/ClientDecryptResponse.java | 14 + .../entity/response/ClientJobResponse.java | 26 ++ .../sdk/entity/response/ClientOTResponse.java | 20 ++ .../entity/response/PirResultResponse.java | 15 ++ .../sdk/entity/response/ServerOTResponse.java | 18 ++ .../com/wedpr/pir/sdk/enums/ParamEnum.java | 35 +++ .../pir/sdk/exception/WedprException.java | 23 ++ .../pir/sdk/exception/WedprStatusEnum.java | 72 ++++++ .../wedpr/pir/sdk/gateway/GatewayClient.java | 80 ++++++ .../com/wedpr/pir/sdk/helper/AESHelper.java | 76 ++++++ .../wedpr/pir/sdk/helper/BasicTypeHelper.java | 15 ++ .../pir/sdk/helper/ConvertTypeHelper.java | 44 ++++ .../pir/sdk/helper/CryptoOperatorHelper.java | 51 ++++ .../pir/sdk/service/ClientDecryptService.java | 69 +++++ .../pir/sdk/service/ClientOTService.java | 94 +++++++ .../wedpr/pir/sdk/service/PirJobService.java | 64 +++++ java/ppc-pir-services/settings.gradle | 11 + .../webank/wedpr/pir/WedprPirApplication.java | 18 ++ .../wedpr/pir/crypto/entity/PirTable.java | 17 ++ .../pir/crypto/service/PirOTService.java | 25 ++ .../pir/crypto/service/PirTableService.java | 21 ++ .../crypto/service/impl/PirOTServiceImpl.java | 139 ++++++++++ .../service/impl/PirTableServiceImpl.java | 67 +++++ .../wedpr/pir/http/common/Constant.java | 10 + .../wedpr/pir/http/config/JacksonConfig.java | 59 +++++ .../pir/http/controller/PirController.java | 54 ++++ .../wedpr/pir/http/service/PirAppService.java | 50 ++++ .../main/resources/application-dev.properties | 9 + .../resources/application-mysql.properties | 6 + .../src/main/resources/application.properties | 7 + .../src/main/resources/log4j2.xml | 111 ++++++++ 54 files changed, 2366 insertions(+) create mode 100644 java/ppc-pir-services/build.gradle create mode 100644 java/ppc-pir-services/gradle/wrapper/gradle-wrapper.jar create mode 100644 java/ppc-pir-services/gradle/wrapper/gradle-wrapper.properties create mode 100644 java/ppc-pir-services/gradlew create mode 100644 java/ppc-pir-services/gradlew.bat create mode 100644 java/ppc-pir-services/script/start.sh create mode 100644 java/ppc-pir-services/script/stop.sh create mode 100644 java/ppc-pir-services/sdk/build.gradle create mode 100644 java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/demo/Demo.java create mode 100644 java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/PirClient.java create mode 100644 java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/crypto/IdHashVec.java create mode 100644 java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/entity/body/PirDataBody.java create mode 100644 java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/entity/body/PirResultBody.java create mode 100644 java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/entity/body/ServerResultBody.java create mode 100644 java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/entity/body/ServerResultList.java create mode 100644 java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/entity/body/SimpleEntity.java create mode 100644 java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/entity/param/PirJobParam.java create mode 100644 java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/entity/request/ClientDecryptRequest.java create mode 100644 java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/entity/request/ClientOTRequest.java create mode 100644 java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/entity/request/PirBaseRequest.java create mode 100644 java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/entity/request/ServerJobRequest.java create mode 100644 java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/entity/request/ServerOTRequest.java create mode 100644 java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/entity/response/ClientDecryptResponse.java create mode 100644 java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/entity/response/ClientJobResponse.java create mode 100644 java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/entity/response/ClientOTResponse.java create mode 100644 java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/entity/response/PirResultResponse.java create mode 100644 java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/entity/response/ServerOTResponse.java create mode 100644 java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/enums/ParamEnum.java create mode 100644 java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/exception/WedprException.java create mode 100644 java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/exception/WedprStatusEnum.java create mode 100644 java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/gateway/GatewayClient.java create mode 100644 java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/helper/AESHelper.java create mode 100644 java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/helper/BasicTypeHelper.java create mode 100644 java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/helper/ConvertTypeHelper.java create mode 100644 java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/helper/CryptoOperatorHelper.java create mode 100644 java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/service/ClientDecryptService.java create mode 100644 java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/service/ClientOTService.java create mode 100644 java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/service/PirJobService.java create mode 100644 java/ppc-pir-services/settings.gradle create mode 100644 java/ppc-pir-services/src/main/java/com/webank/wedpr/pir/WedprPirApplication.java create mode 100644 java/ppc-pir-services/src/main/java/com/webank/wedpr/pir/crypto/entity/PirTable.java create mode 100644 java/ppc-pir-services/src/main/java/com/webank/wedpr/pir/crypto/service/PirOTService.java create mode 100644 java/ppc-pir-services/src/main/java/com/webank/wedpr/pir/crypto/service/PirTableService.java create mode 100644 java/ppc-pir-services/src/main/java/com/webank/wedpr/pir/crypto/service/impl/PirOTServiceImpl.java create mode 100644 java/ppc-pir-services/src/main/java/com/webank/wedpr/pir/crypto/service/impl/PirTableServiceImpl.java create mode 100644 java/ppc-pir-services/src/main/java/com/webank/wedpr/pir/http/common/Constant.java create mode 100644 java/ppc-pir-services/src/main/java/com/webank/wedpr/pir/http/config/JacksonConfig.java create mode 100644 java/ppc-pir-services/src/main/java/com/webank/wedpr/pir/http/controller/PirController.java create mode 100644 java/ppc-pir-services/src/main/java/com/webank/wedpr/pir/http/service/PirAppService.java create mode 100644 java/ppc-pir-services/src/main/resources/application-dev.properties create mode 100644 java/ppc-pir-services/src/main/resources/application-mysql.properties create mode 100644 java/ppc-pir-services/src/main/resources/application.properties create mode 100644 java/ppc-pir-services/src/main/resources/log4j2.xml diff --git a/.gitignore b/.gitignore index bb7e592f..15029804 100644 --- a/.gitignore +++ b/.gitignore @@ -125,6 +125,9 @@ instance/ # dotenv .env +# javaenv +.gradle + # virtualenv venv/ ENV/ diff --git a/java/ppc-pir-services/build.gradle b/java/ppc-pir-services/build.gradle new file mode 100644 index 00000000..ce80f537 --- /dev/null +++ b/java/ppc-pir-services/build.gradle @@ -0,0 +1,96 @@ +plugins { + id 'java' + id 'com.github.sherter.google-java-format' version '0.8' +} + +group 'cn.webank.wedpr' +version '3.0.0' + +repositories { + maven { + url = "https://mirrors.huaweicloud.com/repository/maven/" + } +} + +configurations.all { + exclude group: "org.springframework.boot", module: "spring-boot-starter-logging" + exclude group: "org.slf4j", module: "slf4j-log4j12" +} + +dependencies { + implementation 'org.springframework.boot:spring-boot-starter-web:2.7.12' + implementation 'org.springframework.boot:spring-boot-starter-data-jpa:2.7.11' + implementation 'com.fasterxml.jackson.core:jackson-databind:2.14.0' + implementation 'com.mysql:mysql-connector-j:8.0.33' + implementation 'org.mybatis:mybatis:3.5.13' + implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:2.2.2' + implementation 'org.apache.logging.log4j:log4j-slf4j-impl:2.19.0' + implementation 'commons-codec:commons-codec:1.15' + implementation 'com.squareup.okhttp3:okhttp:4.9.1' + implementation project(":ppc-pir-sdk") + + compileOnly 'org.projectlombok:lombok:1.18.24' + annotationProcessor 'org.projectlombok:lombok:1.18.24' +} + +jar { + destinationDir file('dist/app') + archiveName project.name + "-" + project.version + '.jar' + exclude '**/*.xml' + exclude '**/*.toml' + exclude '**/*.properties' + exclude '**/*.yml' + exclude '**/*.crt' + exclude '**/*.key' + exclude '**/*.sql' + exclude '**/*.pem' + + doLast { + copy { + from file('src/main/resources/') + into 'dist/conf' + } + copy { + from configurations.runtimeClasspath + into 'dist/libs' + } + copy { + from file('.').listFiles().findAll { File f -> (f.name.endsWith('.sh') || f.name.endsWith('.env')) } + into 'dist' + } + copy { + from file('script/') + into 'dist' + } + } +} + +sourceSets { + main { + java { + srcDir 'src/main/java' + } + resources { + srcDir 'src/main/resources' + srcDir 'src/main/java' + } + } +} + +test { + useJUnitPlatform() +} + + +googleJavaFormat { + options style: 'AOSP' + source = sourceSets*.allJava + include '**/*.java' +} + +clean { + file("dist/").deleteDir() +} + + + diff --git a/java/ppc-pir-services/gradle/wrapper/gradle-wrapper.jar b/java/ppc-pir-services/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..249e5832f090a2944b7473328c07c9755baa3196 GIT binary patch literal 60756 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 '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit + +APP_NAME="Gradle" +APP_BASE_NAME=${0##*/} + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/java/ppc-pir-services/gradlew.bat b/java/ppc-pir-services/gradlew.bat new file mode 100644 index 00000000..f127cfd4 --- /dev/null +++ b/java/ppc-pir-services/gradlew.bat @@ -0,0 +1,91 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/java/ppc-pir-services/script/start.sh b/java/ppc-pir-services/script/start.sh new file mode 100644 index 00000000..fd8114ca --- /dev/null +++ b/java/ppc-pir-services/script/start.sh @@ -0,0 +1,126 @@ +#!/bin/bash + +dirpath="$(cd "$(dirname "$0")" && pwd)" +cd $dirpath + +JAVA_HOME=$JAVA_HOME +APP_MAIN=cn.webank.wedpr.http.PpcsPirApplication +CLASSPATH='conf/:app/*:libs/*' +CURRENT_DIR=`pwd` +LOG_DIR=${CURRENT_DIR}/logs +CONF_DIR=${CURRENT_DIR}/conf +os_platform=`uname -s` + + +if [ "${JAVA_HOME}" = "" ];then + echo "JAVA_HOME has not been configured" + exit -1 +fi + +log_path="/data/app/ppc/wedpr-pir-node/logs/wedpr-pir.log" +# 检查文件是否存在 +if [ ! -f "$log_path" ]; then + # 文件不存在,创建文件 + touch "$log_path" +fi + +# 初始化全局变量,用于标识系统的PID(0表示未启动) +tradePortalPID=0 +start_timestamp=0 +APP_NAME="wedpr-pir" + +getTradeProtalPID(){ + javaps=`$JAVA_HOME/bin/jps -l | grep $APP_MAIN` + if [ -n "$javaps" ]; then + tradePortalPID=`echo $javaps | awk '{print $1}'` + else + tradePortalPID=0 + fi +} + +#JAVA_OPTS=" -Dfile.encoding=UTF-8 -Dcom.sun.management.jmxremote.port=${JMXREMOTE_PORT} -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false" +JAVA_OPTS=" -Dlog4j.configurationfile=${CONF_DIR}/log4j2.xml -Dindex.log.home=${LOG_DIR} -Dconfig=${CONF_DIR}/" +JAVA_OPTS+=" -Xmx3072m -Xms3072m -XX:NewSize=1024m -XX:MaxNewSize=1024m -XX:PermSize=512m -XX:MaxPermSize=512m" +JAVA_OPTS+=" -XX:CompileThreshold=20000 -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=70" +JAVA_OPTS+=" -XX:+DisableExplicitGC -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:${LOG_DIR}/jvm.log" +JAVA_OPTS+=" -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=${LOG_DIR}/ -XX:ErrorFile=${LOG_DIR}/heap_error.log" + +function get_start_time() { + start_time=$(date "+%Y-%m-%d %H:%M:%S") + if [[ "${os_platform}" = "Darwin" ]];then + start_timestamp=$(date -j -f "%Y-%m-%d %H:%M:%S" "${start_time}" +%s) + elif [[ "${os_platform}" = "Linux" ]];then + start_timestamp=$(date -d "${start_time}" +%s) + else + echo -e "\033[31m[ERROR] Server start fail!\033[0m" + echo "check platform...[failed]" + echo "===============================================================================================" + kill $tradePortalPID + exit 1 + fi +} + +function waiting_for_start() { + echo "" + i=0 + while [ $i -le 30 ] + do + for j in '\\' '|' '/' '-' + do + printf "%c%c%c%c%c Waiting for server started %c%c%c%c%c\r" \ + "$j" "$j" "$j" "$j" "$j" "$j" "$j" "$j" "$j" "$j" + check_time=$(cat ${dirpath}/logs/${APP_NAME}.log | grep -a "JVM running for" | tail -n1 | awk -F "]" '{print $3}' | awk -F "[" '{print $2}' | awk -F " " '{print $1, $2}') + if [ -n "$check_time" ]; then + if [[ "${os_platform}" = "Darwin" ]];then + timestamp=$(date -j -f "%Y-%m-%d %H:%M:%S" "${check_time}" +%s) + elif [[ "${os_platform}" = "Linux" ]];then + timestamp=$(date -d "${check_time}" +%s) + else + echo -e "\033[31m[ERROR] Server start fail!\033[0m" + echo "check platform...[failed]" + echo "===============================================================================================" + kill $tradePortalPID + exit 1 + fi + if [[ ${timestamp} -gt ${start_timestamp} ]]; then + echo "" + echo -e "\033[32m[INFO] Server start Successful!\033[0m" + echo "(PID=$tradePortalPID)...[Success]" + echo "===============================================================================================" + exit 0 + fi + fi + sleep 1 + done + let i=i+5 + done + echo "" + echo -e "\033[31m[ERROR] Server start fail!\033[0m" + echo "timeout...[failed]" + echo "===============================================================================================" + kill $tradePortalPID + exit 1 +} + +start(){ + getTradeProtalPID + echo "===============================================================================================" + if [ $tradePortalPID -ne 0 ]; then + echo "$APP_MAIN already started(PID=$tradePortalPID)" + echo "===============================================================================================" + else + get_start_time + nohup $JAVA_HOME/bin/java $JAVA_OPTS -cp $CLASSPATH $APP_MAIN >start.out 2>&1 & + sleep 1 + getTradeProtalPID + if [ $tradePortalPID -ne 0 ]; then + waiting_for_start + else + echo -e "\033[31m[ERROR] Server start fail!\033[0m" + echo "[Failed]" + echo "===============================================================================================" + fi + fi +} + +start diff --git a/java/ppc-pir-services/script/stop.sh b/java/ppc-pir-services/script/stop.sh new file mode 100644 index 00000000..ac04bbde --- /dev/null +++ b/java/ppc-pir-services/script/stop.sh @@ -0,0 +1,45 @@ +#!/bin/bash + +rm -rf start.out + +dirpath="$(cd "$(dirname "$0")" && pwd)" +cd $dirpath + +JAVA_HOME=$JAVA_HOME +APP_MAIN=cn.webank.wedpr.http.PpcsPirApplication +CURRENT_DIR=`pwd` +CONF_DIR=${CURRENT_DIR}/conf + +# 初始化全局变量,用于标识系统的PID(0表示未启动) +tradePortalPID=0 + +getTradeProtalPID(){ + javaps=`$JAVA_HOME/bin/jps -l | grep $APP_MAIN` + if [ -n "$javaps" ]; then + tradePortalPID=`echo $javaps | awk '{print $1}'` + else + tradePortalPID=0 + fi +} + +stop(){ + getTradeProtalPID + echo "===============================================================================================" + if [ $tradePortalPID -ne 0 ]; then + echo -n "Stopping $APP_MAIN(PID=$tradePortalPID)..." + kill $tradePortalPID > /dev/null + if [ $? -eq 0 ]; then + echo "[Success]" + echo "===============================================================================================" + else + echo "[Failed]" + echo "===============================================================================================" + fi + getTradeProtalPID + else + echo "$APP_MAIN is not running" + echo "===============================================================================================" + fi +} + +stop diff --git a/java/ppc-pir-services/sdk/build.gradle b/java/ppc-pir-services/sdk/build.gradle new file mode 100644 index 00000000..355c101d --- /dev/null +++ b/java/ppc-pir-services/sdk/build.gradle @@ -0,0 +1,26 @@ +plugins { + id 'java' + id 'com.github.sherter.google-java-format' +} + +repositories { + maven { + url = "https://mirrors.huaweicloud.com/repository/maven/" + } +} + +project.version="1.0.0" + +dependencies { + implementation 'com.squareup.okhttp3:okhttp:4.9.1' + implementation 'com.fasterxml.jackson.core:jackson-databind:2.14.0' + + compileOnly 'org.projectlombok:lombok:1.18.24' + annotationProcessor 'org.projectlombok:lombok:1.18.24' +} + +googleJavaFormat { + options style: 'AOSP' + source = sourceSets*.allJava + include '**/*.java' +} \ No newline at end of file diff --git a/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/demo/Demo.java b/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/demo/Demo.java new file mode 100644 index 00000000..41f5ee8d --- /dev/null +++ b/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/demo/Demo.java @@ -0,0 +1,51 @@ +package com.wedpr.pir.demo; + +import com.wedpr.pir.sdk.PirClient; +import com.wedpr.pir.sdk.entity.param.PirJobParam; +import com.wedpr.pir.sdk.entity.response.PirResultResponse; +import com.wedpr.pir.sdk.enums.ParamEnum; +import com.wedpr.pir.sdk.exception.WedprException; +import java.util.Arrays; + +/** + * @author zachma + * @date 2024/8/22 + */ +public class Demo { + public static void main(String[] args) throws WedprException { + testIdObfuscation(); + testIdFilter(); + } + + private static void testIdFilter() throws WedprException { + PirJobParam pirJobParam = new PirJobParam(); + pirJobParam.setJobId("j-12345678912"); + pirJobParam.setJobType(ParamEnum.JobType.SearchValue.getValue()); + pirJobParam.setJobAlgorithmType(ParamEnum.AlgorithmType.idFilter.getValue()); + pirJobParam.setParticipateAgencyId("1002"); + pirJobParam.setDatasetId("t_login_token"); + pirJobParam.setJobCreator("1001"); + pirJobParam.setGatewayUrl("http://localhost:5831/api/pir/v3/server"); + pirJobParam.setSearchIdList(Arrays.asList(new String[] {"1", "20", "3", "456"})); + + PirClient pirClient = new PirClient(pirJobParam); + PirResultResponse pirResultResponse = pirClient.executePirJob(); + System.out.println(pirResultResponse); + } + + private static void testIdObfuscation() throws WedprException { + PirJobParam pirJobParam = new PirJobParam(); + pirJobParam.setJobId("j-12345678912"); + pirJobParam.setJobType(ParamEnum.JobType.SearchValue.getValue()); + pirJobParam.setJobAlgorithmType(ParamEnum.AlgorithmType.idObfuscation.getValue()); + pirJobParam.setParticipateAgencyId("1002"); + pirJobParam.setDatasetId("t_login_token"); + pirJobParam.setJobCreator("1001"); + pirJobParam.setGatewayUrl("http://localhost:5831/api/pir/v3/server"); + pirJobParam.setSearchIdList(Arrays.asList(new String[] {"1", "20", "3", "456"})); + + PirClient pirClient = new PirClient(pirJobParam); + PirResultResponse pirResultResponse = pirClient.executePirJob(); + System.out.println(pirResultResponse); + } +} diff --git a/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/PirClient.java b/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/PirClient.java new file mode 100644 index 00000000..b9e95e29 --- /dev/null +++ b/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/PirClient.java @@ -0,0 +1,72 @@ +package com.wedpr.pir.sdk; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.sun.org.slf4j.internal.Logger; +import com.sun.org.slf4j.internal.LoggerFactory; +import com.wedpr.pir.sdk.entity.body.SimpleEntity; +import com.wedpr.pir.sdk.entity.param.PirJobParam; +import com.wedpr.pir.sdk.entity.request.ServerJobRequest; +import com.wedpr.pir.sdk.entity.response.ClientOTResponse; +import com.wedpr.pir.sdk.entity.response.PirResultResponse; +import com.wedpr.pir.sdk.exception.WedprException; +import com.wedpr.pir.sdk.exception.WedprStatusEnum; +import com.wedpr.pir.sdk.gateway.GatewayClient; +import com.wedpr.pir.sdk.service.PirJobService; +import java.util.Objects; + +/** + * @author zachma + * @date 2024/8/19 + */ +public class PirClient { + private static final Logger logger = LoggerFactory.getLogger(PirClient.class); + private final PirJobService pirJobService; + + public PirClient(PirJobParam pirJobParam) throws WedprException { + pirJobParam.check(); + this.pirJobService = new PirJobService(pirJobParam); + } + + public PirResultResponse executePirJob() throws WedprException { + try { + ClientOTResponse otParamResponse = pirJobService.requesterOtCipher(); + PirJobParam pirJobParam = pirJobService.getPirJobParam(); + ServerJobRequest serverJobRequest = + generatePirJobRequestFromJobAndOTParam(pirJobParam, otParamResponse); + logger.debug("executePirJob start: ", serverJobRequest); + + String pirUrl = pirJobParam.getGatewayUrl(); + ObjectMapper objectMapper = new ObjectMapper(); + String body = objectMapper.writeValueAsString(serverJobRequest); + SimpleEntity otResult = + GatewayClient.sendPostRequestWithRetry(pirUrl, body, SimpleEntity.class); + logger.debug("executePirJob success return: ", otResult); + if (Objects.isNull(otResult) + || !otResult.getCode().equals(WedprStatusEnum.SUCCESS.getCode())) { + throw new WedprException(WedprStatusEnum.TASK_EXECUTE_ERROR); + } + return pirJobService.requesterOtRecover(otParamResponse, pirJobParam, otResult); + } catch (Exception e) { + logger.error("executePirJob cause exception: ", e.getMessage()); + throw new WedprException(WedprStatusEnum.CALL_PSI_ERROR); + } + } + + /** 根据 ClientOTResponse 和 PirJobParam 构建PirJobRequest */ + private ServerJobRequest generatePirJobRequestFromJobAndOTParam( + PirJobParam pirJobParam, ClientOTResponse otParamResponse) { + ServerJobRequest serverJobRequest = new ServerJobRequest(); + serverJobRequest.setJobId(pirJobParam.getJobId()); + serverJobRequest.setParticipateAgencyId(pirJobParam.getParticipateAgencyId()); + serverJobRequest.setDatasetId(pirJobParam.getDatasetId()); + serverJobRequest.setJobCreator(pirJobParam.getJobCreator()); + serverJobRequest.setJobAlgorithmType(pirJobParam.getJobAlgorithmType()); + serverJobRequest.setX(otParamResponse.getX()); + serverJobRequest.setY(otParamResponse.getY()); + serverJobRequest.setDataBodyList(otParamResponse.getDataBodyList()); + for (int i = 0; i < serverJobRequest.getDataBodyList().size(); i++) { + serverJobRequest.getDataBodyList().get(i).setIdIndex(0); + } + return serverJobRequest; + } +} diff --git a/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/crypto/IdHashVec.java b/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/crypto/IdHashVec.java new file mode 100644 index 00000000..1aed44d6 --- /dev/null +++ b/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/crypto/IdHashVec.java @@ -0,0 +1,51 @@ +package com.wedpr.pir.sdk.crypto; + +import com.wedpr.pir.sdk.exception.WedprException; +import com.wedpr.pir.sdk.exception.WedprStatusEnum; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +/** + * @author zachma + * @date 2024/8/20 + */ +public class IdHashVec { + public static List getIdHashVec(int obfuscationOrder, Integer idIndex, String searchId) + throws WedprException { + + List clientDataBodyList = new ArrayList<>(); + String searchIdTemp; + for (int i = 0; i < obfuscationOrder + 1; i++) { + if (idIndex == i) { + searchIdTemp = searchId; + } else { + String uuid = UUID.randomUUID().toString(); + searchIdTemp = makeHash(uuid.getBytes()); + } + clientDataBodyList.add(searchIdTemp); + } + return clientDataBodyList; + } + + private static String makeHash(byte[] data) throws WedprException { + try { + MessageDigest digest = MessageDigest.getInstance("SHA-256"); + byte[] hashBytes = digest.digest(data); + + StringBuilder hexString = new StringBuilder(); + for (byte b : hashBytes) { + String hex = Integer.toHexString(0xFF & b); + if (hex.length() == 1) { + hexString.append('0'); + } + hexString.append(hex); + } + return hexString.toString(); + } catch (NoSuchAlgorithmException e) { + throw new WedprException(WedprStatusEnum.WRONG_HASH_ERROR); + } + } +} diff --git a/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/entity/body/PirDataBody.java b/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/entity/body/PirDataBody.java new file mode 100644 index 00000000..0bf38256 --- /dev/null +++ b/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/entity/body/PirDataBody.java @@ -0,0 +1,17 @@ +package com.wedpr.pir.sdk.entity.body; + +import java.math.BigInteger; +import java.util.List; +import lombok.Data; + +/** + * @author zachma + * @date 2024/8/18 + */ +@Data +public class PirDataBody { + BigInteger z0; + String filter; + int idIndex; + List idHashList; +} diff --git a/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/entity/body/PirResultBody.java b/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/entity/body/PirResultBody.java new file mode 100644 index 00000000..c8bf5524 --- /dev/null +++ b/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/entity/body/PirResultBody.java @@ -0,0 +1,14 @@ +package com.wedpr.pir.sdk.entity.body; + +import lombok.Data; + +/** + * @author zachma + * @date 2024/8/21 + */ +@Data +public class PirResultBody { + String searchId; + Boolean searchExist; + String searchValue; +} diff --git a/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/entity/body/ServerResultBody.java b/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/entity/body/ServerResultBody.java new file mode 100644 index 00000000..f71b9896 --- /dev/null +++ b/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/entity/body/ServerResultBody.java @@ -0,0 +1,19 @@ +package com.wedpr.pir.sdk.entity.body; + +import java.math.BigInteger; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author zachma + * @date 2024/8/18 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class ServerResultBody { + BigInteger e; + BigInteger w; + String c; +} diff --git a/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/entity/body/ServerResultList.java b/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/entity/body/ServerResultList.java new file mode 100644 index 00000000..3f448180 --- /dev/null +++ b/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/entity/body/ServerResultList.java @@ -0,0 +1,17 @@ +package com.wedpr.pir.sdk.entity.body; + +import java.util.List; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author zachma + * @date 2024/8/18 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class ServerResultList { + List resultBodyList; +} diff --git a/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/entity/body/SimpleEntity.java b/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/entity/body/SimpleEntity.java new file mode 100644 index 00000000..7726c772 --- /dev/null +++ b/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/entity/body/SimpleEntity.java @@ -0,0 +1,15 @@ +package com.wedpr.pir.sdk.entity.body; + +import com.wedpr.pir.sdk.entity.response.ServerOTResponse; +import lombok.Data; + +/** + * @author zachma + * @date 2024/8/21 + */ +@Data +public class SimpleEntity { + String code; + String message; + ServerOTResponse data; +} diff --git a/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/entity/param/PirJobParam.java b/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/entity/param/PirJobParam.java new file mode 100644 index 00000000..1812d9c4 --- /dev/null +++ b/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/entity/param/PirJobParam.java @@ -0,0 +1,65 @@ +package com.wedpr.pir.sdk.entity.param; + +import com.wedpr.pir.sdk.entity.request.PirBaseRequest; +import com.wedpr.pir.sdk.enums.ParamEnum; +import com.wedpr.pir.sdk.exception.WedprException; +import com.wedpr.pir.sdk.exception.WedprStatusEnum; +import com.wedpr.pir.sdk.helper.BasicTypeHelper; +import java.util.Arrays; +import java.util.List; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * @author zachma + * @date 2024/8/19 + */ +@Data +@EqualsAndHashCode(callSuper = true) +public class PirJobParam extends PirBaseRequest { + + private Integer filterLength = 4; + + private String gatewayUrl; + + private List searchIdList; + + public void check() throws WedprException { + if (BasicTypeHelper.isStringEmpty(gatewayUrl)) { + throw new WedprException(WedprStatusEnum.CLIENT_PARAM_EXCEPTION, "访问gatewayUrl不能为空"); + } + + if (BasicTypeHelper.isStringEmpty(getJobId())) { + throw new WedprException(WedprStatusEnum.CLIENT_PARAM_EXCEPTION, "jobId 不能为空"); + } + + if (Arrays.stream(ParamEnum.JobType.values()) + .noneMatch(enumValue -> enumValue.getValue().equals(getJobType()))) { + throw new WedprException(WedprStatusEnum.CLIENT_PARAM_EXCEPTION, "jobType输入错误"); + } + + if (BasicTypeHelper.isStringEmpty(getParticipateAgencyId())) { + throw new WedprException(WedprStatusEnum.CLIENT_PARAM_EXCEPTION, "数据机构Id 不能为空"); + } + + if (BasicTypeHelper.isStringEmpty(getDatasetId())) { + throw new WedprException(WedprStatusEnum.CLIENT_PARAM_EXCEPTION, "datasetId 不能为空"); + } + + if (Arrays.stream(ParamEnum.AlgorithmType.values()) + .noneMatch(enumValue -> enumValue.getValue().equals(getJobAlgorithmType()))) { + throw new WedprException( + WedprStatusEnum.CLIENT_PARAM_EXCEPTION, "jobAlgorithmType输入错误"); + } + + if (searchIdList == null || searchIdList.size() == 0) { + throw new WedprException(WedprStatusEnum.CLIENT_PARAM_EXCEPTION, "searchId列表不能为空"); + } + + if (getJobAlgorithmType().equals(ParamEnum.AlgorithmType.idObfuscation.getValue()) + && getObfuscationOrder() == -1) { + throw new WedprException( + WedprStatusEnum.CLIENT_PARAM_EXCEPTION, "哈希披露算法中, obfuscationOrder未设置"); + } + } +} diff --git a/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/entity/request/ClientDecryptRequest.java b/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/entity/request/ClientDecryptRequest.java new file mode 100644 index 00000000..7a3ecfb3 --- /dev/null +++ b/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/entity/request/ClientDecryptRequest.java @@ -0,0 +1,17 @@ +package com.wedpr.pir.sdk.entity.request; + +import com.wedpr.pir.sdk.entity.response.ServerOTResponse; +import java.math.BigInteger; +import java.util.List; +import lombok.Data; + +/** + * @author zachma + * @date 2024/8/21 + */ +@Data +public class ClientDecryptRequest { + BigInteger b; + List dataBodyList; + ServerOTResponse serverResult; +} diff --git a/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/entity/request/ClientOTRequest.java b/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/entity/request/ClientOTRequest.java new file mode 100644 index 00000000..b4d54dcb --- /dev/null +++ b/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/entity/request/ClientOTRequest.java @@ -0,0 +1,17 @@ +package com.wedpr.pir.sdk.entity.request; + +import java.util.List; +import lombok.Data; + +/** + * @author zachma + * @date 2024/8/20 + */ +@Data +public class ClientOTRequest { + int filterLength = 4; + + int obfuscationOrder; + + List dataBodyList; +} diff --git a/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/entity/request/PirBaseRequest.java b/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/entity/request/PirBaseRequest.java new file mode 100644 index 00000000..028db290 --- /dev/null +++ b/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/entity/request/PirBaseRequest.java @@ -0,0 +1,21 @@ +package com.wedpr.pir.sdk.entity.request; + +import lombok.Data; + +@Data +public class PirBaseRequest { + // 任务ID + String jobId; + // 任务类型(0: 查询存在性, 1: 查询对应值) + String jobType; + // 数据方机构id + String participateAgencyId; + // 数据集id + String datasetId; + // 发起方用户名 + String jobCreator; + // 匿踪算法类型(0: hash披露算法, 1: hash混淆算法) + String jobAlgorithmType; + // 查询范围 + Integer obfuscationOrder = 9; +} diff --git a/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/entity/request/ServerJobRequest.java b/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/entity/request/ServerJobRequest.java new file mode 100644 index 00000000..0f91aa94 --- /dev/null +++ b/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/entity/request/ServerJobRequest.java @@ -0,0 +1,19 @@ +package com.wedpr.pir.sdk.entity.request; + +import com.wedpr.pir.sdk.entity.body.PirDataBody; +import java.math.BigInteger; +import java.util.List; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * @author zachma + * @date 2024/8/18 + */ +@EqualsAndHashCode(callSuper = true) +@Data +public class ServerJobRequest extends PirBaseRequest { + BigInteger x; + BigInteger y; + List dataBodyList; +} diff --git a/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/entity/request/ServerOTRequest.java b/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/entity/request/ServerOTRequest.java new file mode 100644 index 00000000..a1ad74de --- /dev/null +++ b/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/entity/request/ServerOTRequest.java @@ -0,0 +1,19 @@ +package com.wedpr.pir.sdk.entity.request; + +import com.wedpr.pir.sdk.entity.body.PirDataBody; +import java.math.BigInteger; +import java.util.List; +import lombok.Data; + +/** + * @author zachma + * @date 2024/8/18 + */ +@Data +public class ServerOTRequest { + String jobType; + String datasetId; + BigInteger x; + BigInteger y; + List dataBodyList; +} diff --git a/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/entity/response/ClientDecryptResponse.java b/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/entity/response/ClientDecryptResponse.java new file mode 100644 index 00000000..cf720cb8 --- /dev/null +++ b/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/entity/response/ClientDecryptResponse.java @@ -0,0 +1,14 @@ +package com.wedpr.pir.sdk.entity.response; + +import com.wedpr.pir.sdk.entity.body.PirResultBody; +import java.util.List; +import lombok.Data; + +/** + * @author zachma + * @date 2024/8/21 + */ +@Data +public class ClientDecryptResponse { + List detail; +} diff --git a/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/entity/response/ClientJobResponse.java b/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/entity/response/ClientJobResponse.java new file mode 100644 index 00000000..d367cf54 --- /dev/null +++ b/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/entity/response/ClientJobResponse.java @@ -0,0 +1,26 @@ +package com.wedpr.pir.sdk.entity.response; + +import com.wedpr.pir.sdk.exception.WedprStatusEnum; +import lombok.Data; + +/** + * @author zachma + * @date 2024/8/18 + */ +@Data +public class ClientJobResponse { + private String code; + private String message; + private Object data; + + public ClientJobResponse(WedprStatusEnum wedprStatusEnum) { + this.code = wedprStatusEnum.getCode(); + this.message = wedprStatusEnum.getMessage(); + } + + public ClientJobResponse(WedprStatusEnum wedprStatusEnum, Object data) { + this.code = wedprStatusEnum.getCode(); + this.message = wedprStatusEnum.getMessage(); + this.data = data; + } +} diff --git a/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/entity/response/ClientOTResponse.java b/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/entity/response/ClientOTResponse.java new file mode 100644 index 00000000..a26ce00b --- /dev/null +++ b/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/entity/response/ClientOTResponse.java @@ -0,0 +1,20 @@ +package com.wedpr.pir.sdk.entity.response; + +import com.wedpr.pir.sdk.entity.body.PirDataBody; +import java.math.BigInteger; +import java.util.List; +import lombok.AllArgsConstructor; +import lombok.Data; + +/** + * @author zachma + * @date 2024/8/20 + */ +@Data +@AllArgsConstructor +public class ClientOTResponse { + BigInteger b; + BigInteger x; + BigInteger y; + List dataBodyList; +} diff --git a/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/entity/response/PirResultResponse.java b/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/entity/response/PirResultResponse.java new file mode 100644 index 00000000..fd78b0df --- /dev/null +++ b/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/entity/response/PirResultResponse.java @@ -0,0 +1,15 @@ +package com.wedpr.pir.sdk.entity.response; + +import lombok.Data; + +/** + * @author zachma + * @date 2024/8/21 + */ +@Data +public class PirResultResponse { + String jobId; + String jobType; + // List detail; + ClientDecryptResponse detail; +} diff --git a/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/entity/response/ServerOTResponse.java b/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/entity/response/ServerOTResponse.java new file mode 100644 index 00000000..45d0a312 --- /dev/null +++ b/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/entity/response/ServerOTResponse.java @@ -0,0 +1,18 @@ +package com.wedpr.pir.sdk.entity.response; + +import com.wedpr.pir.sdk.entity.body.ServerResultList; +import java.util.List; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author zachma + * @date 2024/8/18 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class ServerOTResponse { + List resultBodyList; +} diff --git a/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/enums/ParamEnum.java b/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/enums/ParamEnum.java new file mode 100644 index 00000000..f3a2b321 --- /dev/null +++ b/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/enums/ParamEnum.java @@ -0,0 +1,35 @@ +package com.wedpr.pir.sdk.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * @author zachma + * @date 2024/8/18 + */ +public class ParamEnum { + @Getter + @AllArgsConstructor + public enum JobType { + SearchValue("0"), + SearchExist("1"); + private String value; + } + + @Getter + @AllArgsConstructor + public enum AlgorithmType { + idFilter("0"), + idObfuscation("1"); + + private String value; + } + + @Getter + @AllArgsConstructor + public enum HttpType { + HttpTimeout(180), + HttpMaxRetries(4); + private Integer value; + } +} diff --git a/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/exception/WedprException.java b/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/exception/WedprException.java new file mode 100644 index 00000000..3565318d --- /dev/null +++ b/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/exception/WedprException.java @@ -0,0 +1,23 @@ +package com.wedpr.pir.sdk.exception; + +/** + * @author zachma + * @date 2024/8/18 + */ +public class WedprException extends Exception { + private final WedprStatusEnum status; + + public WedprException(WedprStatusEnum status) { + super(status.getMessage()); + this.status = status; + } + + public WedprException(WedprStatusEnum status, String message) { + super(message); + this.status = status; + } + + public WedprStatusEnum getStatus() { + return status; + } +} diff --git a/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/exception/WedprStatusEnum.java b/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/exception/WedprStatusEnum.java new file mode 100644 index 00000000..f1070a74 --- /dev/null +++ b/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/exception/WedprStatusEnum.java @@ -0,0 +1,72 @@ +package com.wedpr.pir.sdk.exception; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * @author zachma + * @date 2024/8/18 + */ +@AllArgsConstructor +@Getter +public enum WedprStatusEnum { + SUCCESS("0", "成功"), + FAILURE("1", "系统内部错误"), + INTERNAL_SERVER_ERROR("3", "系统内部错误"), + SYSTEM_CONFIG_ERROR("4", "系统配置参数错误"), + HANDLE_FILE_ERROR("5", "处理文件错误"), + TASK_EXECUTE_ERROR("6", "任务执行失败"), + + // 1000 未定义错误 + SYSTEM_EXCEPTION("1000", "系统抛出异常,请检查日志记录"), + CLIENT_PARAM_EXCEPTION("1001", "发起方参数错误"), + + // 2000 参数解析错误 + INVALID_INPUT_VALUE("2000", "输入参数异常"), + JSON_ERROR("2001", "输入参数JSON解析失败"), + INVALID_SYSTEM_KEY("2002", "系统密钥解析失败"), + INVALID_CUSTOMER_TYPE("2003", "未定义的客户类型"), + INVALID_HASH_VALUE("2004", "输入的哈希值不合法"), + INVALID_INPUT_LENGTH("2005", "输入参数列表长度不合法"), + INVALID_INPUT_PREFIX("2006", "输入参数前缀不匹配"), + INVALID_TIMESTAMP_VALUE("2007", "输入时间戳不合法"), + JSON_GET_ERROR("2008", "JSON解析返回值失败"), + INVALID_TRANS_TYPE("2009", "不合法的交易类型"), + INVALID_FILE_PATH("2010", "不合法交集文件路径"), + INVALID_ROLE_VALUE("2011", "pir.Role设置错误"), + + // 3000 db错误 + DB_ERROR("3000", "DB查询失败"), + // DB_TIMEOUT("3000", "DB访问超时"), + DB_INSERT_FAILURE("3001", "DB插入失败"), + DB_DELETE_FAILURE("3002", "DB删除失败"), + UNENCRYPTED_DATA("3003", "查询的数据未被加密"), + DB_MISSED_USER("3004", "无法写入未命中用户"), + + // 4000 被请求服务端异常 + SERVICE_UNAVAILABLE("4000", "对方PIR服务访问失败"), + INVALID_ENCRYPTION_KEY("4001", "服务端加密密钥异常"), + SEARCHED_DB_UNAVAILABLE("4002", "服务端db无法访问"), + HTTP_CALL_ERROR("4003", "HTTP调用异常"), + CALL_PSI_ERROR("4004", "调用PIR服务异常"), + UPLOAD_FPS_ERROR("4005", "上传文件至Fps失败"), + DOWNLOAD_FPS_ERROR("4006", "下载Fps文件失败"), + CLIENT_LOCAL_FILE("4007", "本地初始化./client/local.txt没有设置"), + SERVER_LOCAL_FILE("4008", "本地初始化./server/local.txt没有设置"), + + // 5000 密码学运算错误 + AES_ENCRYPT_ERROR("5000", "AES加密明文信息错误"), + AES_DECRYPT_ERROR("5001", "AES解密密文信息错误"), + MATCH_RESULT_ERROR("5002", "找不到匹配结果查询值"), + ENCODE_BIG_NUMBER_ERROR("5003", "转换输入哈希到BIG NUMBER类型失败"), + DECODE_ECC_POINT_ERROR("5004", "解码密文到椭圆曲线上点失败"), + MATCH_CIPHER_ERROR("5005", "计算匹配结果失败"), + CLIENT_CIPHER_ERROR("5006", "计算客户端密文失败"), + CIPHER_LENGTH_ERROR("5007", "根据前缀索引到的密文太多"), + WRONG_HASH_ERROR("5008", "输入哈希算法错误"), + + CRYPTO_SPE_ERROR("5099", "密码运算通用错误"); + + private String code; + private String message; +} diff --git a/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/gateway/GatewayClient.java b/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/gateway/GatewayClient.java new file mode 100644 index 00000000..ce58e8e2 --- /dev/null +++ b/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/gateway/GatewayClient.java @@ -0,0 +1,80 @@ +package com.wedpr.pir.sdk.gateway; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.wedpr.pir.sdk.enums.ParamEnum; +import com.wedpr.pir.sdk.exception.WedprException; +import com.wedpr.pir.sdk.exception.WedprStatusEnum; +import java.io.IOException; +import java.util.Objects; +import java.util.concurrent.TimeUnit; +import okhttp3.Call; +import okhttp3.MediaType; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.RequestBody; +import okhttp3.Response; + +/** + * @author zachma + * @date 2024/8/20 + */ +public class GatewayClient { + + private static final MediaType JSON_MEDIA_TYPE = + MediaType.get("application/json; charset=utf-8"); + + private static String sendGetRequest(String url) throws IOException, WedprException { + int timeout = ParamEnum.HttpType.HttpTimeout.getValue(); + OkHttpClient httpClient = + new OkHttpClient() + .newBuilder() + .connectTimeout(timeout, TimeUnit.SECONDS) + .readTimeout(timeout, TimeUnit.SECONDS) + .writeTimeout(timeout, TimeUnit.SECONDS) + .build(); + + Request getRequest = new Request.Builder().url(url).get().build(); + + Call call = httpClient.newCall(getRequest); + Response response = call.execute(); + String responseBody = ""; + if (response.isSuccessful() && Objects.nonNull(response.body())) { + responseBody = response.body().string(); + } else { + throw new WedprException(WedprStatusEnum.HTTP_CALL_ERROR); + } + return responseBody; + } + + private static Response sendPostRequest(String url, String jsonBody) throws IOException { + OkHttpClient httpClient = new OkHttpClient().newBuilder().build(); + RequestBody body = RequestBody.create(jsonBody, JSON_MEDIA_TYPE); + Request request = new Request.Builder().post(body).url(url).build(); + Call call = httpClient.newCall(request); + return call.execute(); + } + + public static T sendPostRequestWithRetry(String url, String body, Class responseType) + throws WedprException { + int maxRetries = ParamEnum.HttpType.HttpMaxRetries.getValue(); + int retries = 1; + while (retries <= maxRetries) { + try { + Response response = sendPostRequest(url, body); + if (response.isSuccessful() && Objects.nonNull(response.body())) { + ObjectMapper objectMapper = new ObjectMapper(); + return objectMapper.readValue(response.body().string(), responseType); + } else { + throw new WedprException(WedprStatusEnum.HTTP_CALL_ERROR); + } + + } catch (Exception e) { + retries++; + if (retries > maxRetries) { + throw new WedprException(WedprStatusEnum.HTTP_CALL_ERROR); + } + } + } + return null; + } +} diff --git a/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/helper/AESHelper.java b/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/helper/AESHelper.java new file mode 100644 index 00000000..8288ccb9 --- /dev/null +++ b/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/helper/AESHelper.java @@ -0,0 +1,76 @@ +package com.wedpr.pir.sdk.helper; + +import com.wedpr.pir.sdk.exception.WedprException; +import com.wedpr.pir.sdk.exception.WedprStatusEnum; +import java.nio.charset.StandardCharsets; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.util.Base64; +import javax.crypto.Cipher; +import javax.crypto.KeyGenerator; +import javax.crypto.SecretKey; +import javax.crypto.spec.GCMParameterSpec; +import javax.crypto.spec.SecretKeySpec; + +/** + * @author zachma + * @date 2024/8/21 + */ +public class AESHelper { + private static final SecureRandom SECURE_RANDOM = new SecureRandom(); + + private static final String AES_ALGORITHM_TRANSFORMATION = "AES/GCM/NoPadding"; + + public static String generateRandomKey() { + // 随机生成 16 位字符串格式的密钥 + byte[] keyBytes = new byte[16]; + SECURE_RANDOM.nextBytes(keyBytes); + return Base64.getEncoder().encodeToString(keyBytes); + } + + public static String encrypt(String plainText, String keyString) throws WedprException { + try { + byte[] iv = new byte[12]; + SecureRandom secureRandom = new SecureRandom(); + secureRandom.nextBytes(iv); + byte[] contentBytes = plainText.getBytes(StandardCharsets.UTF_8); + Cipher cipher = Cipher.getInstance(AES_ALGORITHM_TRANSFORMATION); + GCMParameterSpec params = new GCMParameterSpec(128, iv); + cipher.init(Cipher.ENCRYPT_MODE, getSecretKey(keyString), params); + byte[] encryptData = cipher.doFinal(contentBytes); + assert encryptData.length == contentBytes.length + 16; + byte[] message = new byte[12 + contentBytes.length + 16]; + System.arraycopy(iv, 0, message, 0, 12); + System.arraycopy(encryptData, 0, message, 12, encryptData.length); + return Base64.getEncoder().encodeToString(message); + } catch (Exception e) { + throw new WedprException(WedprStatusEnum.AES_ENCRYPT_ERROR); + } + } + + public static String decrypt(String encryptedText, String keyString) throws WedprException { + try { + byte[] content = Base64.getDecoder().decode(encryptedText); + if (content.length < 12 + 16) { + throw new IllegalArgumentException(); + } + GCMParameterSpec params = new GCMParameterSpec(128, content, 0, 12); + Cipher cipher = Cipher.getInstance(AES_ALGORITHM_TRANSFORMATION); + cipher.init(Cipher.DECRYPT_MODE, getSecretKey(keyString), params); + byte[] decryptData = cipher.doFinal(content, 12, content.length - 12); + return new String(decryptData, StandardCharsets.UTF_8); + } catch (Exception e) { + throw new WedprException(WedprStatusEnum.AES_DECRYPT_ERROR); + } + } + + private static SecretKeySpec getSecretKey(String key) throws NoSuchAlgorithmException { + KeyGenerator kg = KeyGenerator.getInstance("AES"); + // 初始化密钥生成器,AES要求密钥长度为128位、192位、256位 + SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG"); + secureRandom.setSeed(key.getBytes(StandardCharsets.UTF_8)); + kg.init(128, secureRandom); + SecretKey secretKey = kg.generateKey(); + return new SecretKeySpec(secretKey.getEncoded(), "AES"); + } +} diff --git a/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/helper/BasicTypeHelper.java b/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/helper/BasicTypeHelper.java new file mode 100644 index 00000000..3e8aebc0 --- /dev/null +++ b/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/helper/BasicTypeHelper.java @@ -0,0 +1,15 @@ +package com.wedpr.pir.sdk.helper; + +/** + * @author zachma + * @date 2024/8/21 + */ +public class BasicTypeHelper { + public static boolean isStringEmpty(String str) { + return str == null || str.length() == 0; + } + + public static boolean isStringNotEmpty(String str) { + return !isStringEmpty(str); + } +} diff --git a/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/helper/ConvertTypeHelper.java b/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/helper/ConvertTypeHelper.java new file mode 100644 index 00000000..6e5728fd --- /dev/null +++ b/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/helper/ConvertTypeHelper.java @@ -0,0 +1,44 @@ +package com.wedpr.pir.sdk.helper; + +import java.math.BigInteger; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; + +/** + * @author zachma + * @date 2024/8/19 + */ +public class ConvertTypeHelper { + public static int bytesToInt(byte[] bytes, ByteOrder byteOrder) { + ByteBuffer buffer = ByteBuffer.wrap(bytes).order(byteOrder); + return buffer.getInt(); + } + + public static byte[] intToBytes(int number, ByteOrder byteOrder) { + ByteBuffer buffer = ByteBuffer.allocate(Integer.BYTES).order(byteOrder); + buffer.putInt(number); + return buffer.array(); + } + + public static BigInteger bytesToBigInteger(byte[] bytes) { + return new BigInteger(1, bytes); + } + + public static byte[] bigIntegerToBytes(BigInteger number) { + byte[] bytes = number.toByteArray(); + if (bytes[0] == 0) { + byte[] tmpBytes = new byte[bytes.length - 1]; + System.arraycopy(bytes, 1, tmpBytes, 0, tmpBytes.length); + return tmpBytes; + } + return bytes; + } + + public static String bytesToHexString(byte[] bytes) { + StringBuilder sb = new StringBuilder(); + for (byte b : bytes) { + sb.append(String.format("%02X ", b)); + } + return sb.toString().trim(); + } +} diff --git a/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/helper/CryptoOperatorHelper.java b/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/helper/CryptoOperatorHelper.java new file mode 100644 index 00000000..187cfcb7 --- /dev/null +++ b/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/helper/CryptoOperatorHelper.java @@ -0,0 +1,51 @@ +package com.wedpr.pir.sdk.helper; + +import java.math.BigInteger; +import java.security.SecureRandom; + +/** + * @author zachma + * @date 2024/8/19 + */ +public class CryptoOperatorHelper { + private static final BigInteger DEFAULT_G = + new BigInteger( + "9020881489161854992071763483314773468341853433975756385639545080944698236944020124874820917267762049756743282301106459062535797137327360192691469027152272"); + private static final BigInteger DEFAULT_N = + new BigInteger( + "102724610959913950919762303151320427896415051258714708724768326174083057407299433043362228762657118029566890747043004760241559786931866234640457856691885212534669604964926915306738569799518792945024759514373214412797317972739022405456550476153212687312211184540248262330559143446510677062823907392904449451177"); + private static final BigInteger DEFAULT_FI = + new BigInteger( + "102724610959913950919762303151320427896415051258714708724768326174083057407299433043362228762657118029566890747043004760241559786931866234640457856691885192126363163670343672910761259882348623401714459980712242233796355982147797162316532450768783823909695360736554767341443201861573989081253763975895939627220"); + + private static final SecureRandom RANDOM = new SecureRandom(); + + /** 生成随机数 * */ + public static BigInteger getRandomInt() { + BigInteger num = new BigInteger(DEFAULT_N.bitLength(), RANDOM); + while (num.compareTo(DEFAULT_N) >= 0) { + num = new BigInteger(DEFAULT_N.bitLength(), RANDOM); + } + return num; + } + + /** b*G mod N */ + public static BigInteger powMod(BigInteger b) { + return DEFAULT_G.modPow(b, DEFAULT_N); + } + + /** a^b mod N */ + public static BigInteger OTPow(BigInteger a, BigInteger b) { + return a.modPow(b, DEFAULT_N); + } + + /** a*b mod FI */ + public static BigInteger mulMod(BigInteger a, BigInteger b) { + return a.multiply(b).mod(DEFAULT_FI); + } + + /** a*b mod N */ + public static BigInteger OTMul(BigInteger a, BigInteger b) { + return a.multiply(b).mod(DEFAULT_N); + } +} diff --git a/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/service/ClientDecryptService.java b/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/service/ClientDecryptService.java new file mode 100644 index 00000000..6e1d2f2a --- /dev/null +++ b/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/service/ClientDecryptService.java @@ -0,0 +1,69 @@ +package com.wedpr.pir.sdk.service; + +import com.sun.org.slf4j.internal.Logger; +import com.sun.org.slf4j.internal.LoggerFactory; +import com.wedpr.pir.sdk.entity.body.PirResultBody; +import com.wedpr.pir.sdk.entity.body.ServerResultBody; +import com.wedpr.pir.sdk.entity.request.ClientDecryptRequest; +import com.wedpr.pir.sdk.entity.response.ClientDecryptResponse; +import com.wedpr.pir.sdk.exception.WedprException; +import com.wedpr.pir.sdk.helper.AESHelper; +import com.wedpr.pir.sdk.helper.BasicTypeHelper; +import com.wedpr.pir.sdk.helper.ConvertTypeHelper; +import com.wedpr.pir.sdk.helper.CryptoOperatorHelper; +import java.math.BigInteger; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; + +/** + * @author zachma + * @date 2024/8/21 + */ +public class ClientDecryptService { + private static final Logger logger = LoggerFactory.getLogger(ClientDecryptService.class); + private void decryptServerResultList( + PirResultBody pirResultBody, List serverResultList, BigInteger b) { + for (ServerResultBody body : serverResultList) { + BigInteger e = body.getE(); + BigInteger w = body.getW(); + String cipherStr = body.getC(); + BigInteger w1 = CryptoOperatorHelper.OTPow(w, b); + try { + // 对整数AES密钥OT解密,报错后不处理 + BigInteger messageRecover = w1.xor(e); + byte[] convertedBytes = ConvertTypeHelper.bigIntegerToBytes(messageRecover); + String convertedStr = new String(convertedBytes, StandardCharsets.UTF_8); + String decryptedText = AESHelper.decrypt(cipherStr, convertedStr); + pirResultBody.setSearchValue(decryptedText); + } catch (WedprException ignored) { + + } + } + } + + protected ClientDecryptResponse runDecryptOTparam(ClientDecryptRequest clientDecryptRequest) { + logger.debug("runDecryptOTparam Start: ", clientDecryptRequest); + List pirResultBodyArrayList = new ArrayList<>(); + for (int i = 0; + i < clientDecryptRequest.getServerResult().getResultBodyList().size(); + i++) { + PirResultBody pirResultBody = new PirResultBody(); + pirResultBody.setSearchId(clientDecryptRequest.getDataBodyList().get(i)); + List serverResultlist = + clientDecryptRequest + .getServerResult() + .getResultBodyList() + .get(i) + .getResultBodyList(); + decryptServerResultList(pirResultBody, serverResultlist, clientDecryptRequest.getB()); + pirResultBody.setSearchExist( + BasicTypeHelper.isStringNotEmpty(pirResultBody.getSearchValue())); + pirResultBodyArrayList.add(pirResultBody); + } + logger.debug("runDecryptOTparam Success: ", pirResultBodyArrayList); + ClientDecryptResponse clientDecryptResponse = new ClientDecryptResponse(); + clientDecryptResponse.setDetail(pirResultBodyArrayList); + return clientDecryptResponse; + } +} diff --git a/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/service/ClientOTService.java b/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/service/ClientOTService.java new file mode 100644 index 00000000..63d096df --- /dev/null +++ b/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/service/ClientOTService.java @@ -0,0 +1,94 @@ +package com.wedpr.pir.sdk.service; + +import com.sun.org.slf4j.internal.Logger; +import com.sun.org.slf4j.internal.LoggerFactory; +import com.wedpr.pir.sdk.crypto.IdHashVec; +import com.wedpr.pir.sdk.entity.body.PirDataBody; +import com.wedpr.pir.sdk.entity.request.ClientOTRequest; +import com.wedpr.pir.sdk.entity.response.ClientOTResponse; +import com.wedpr.pir.sdk.exception.WedprException; +import com.wedpr.pir.sdk.helper.ConvertTypeHelper; +import com.wedpr.pir.sdk.helper.CryptoOperatorHelper; +import java.math.BigInteger; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +/** + * @author zachma + * @date 2024/8/20 + */ +public class ClientOTService { + private static final Logger logger = LoggerFactory.getLogger(ClientOTService.class); + private final Random rand = new Random(); + + /* hash披露, 请求方选择id,生成随机数a、b */ + protected ClientOTResponse runClientOTParam(ClientOTRequest clientOTRequest) { + logger.debug("runClientOTParam start: ", clientOTRequest); + int filterLength = clientOTRequest.getFilterLength(); + BigInteger blindingA = CryptoOperatorHelper.getRandomInt(); + BigInteger blindingB = CryptoOperatorHelper.getRandomInt(); + + BigInteger x = CryptoOperatorHelper.powMod(blindingA); + BigInteger y = CryptoOperatorHelper.powMod(blindingB); + BigInteger blindingC = CryptoOperatorHelper.mulMod(blindingA, blindingB); + + List pirDataArrayList = new ArrayList<>(); + for (String searchId : clientOTRequest.getDataBodyList()) { + String filter = + searchId.length() < filterLength + ? searchId + : searchId.substring(0, filterLength); + BigInteger z0 = calculateZ0(searchId, blindingC); + PirDataBody pirDataBody = new PirDataBody(); + pirDataBody.setFilter(filter); + pirDataBody.setZ0(z0); + pirDataArrayList.add(pirDataBody); + } + logger.debug("runClientOTParam success: ", pirDataArrayList); + return new ClientOTResponse(blindingB, x, y, pirDataArrayList); + } + + /* hash筛选, 请求方选择顺序\delta\in \{0,1,..,m-1\},生成随机数a、b */ + protected ClientOTResponse runClientOTCipher(ClientOTRequest clientOTRequest) + throws WedprException { + logger.debug("runClientOTCipher start: ", clientOTRequest); + + int obfuscationOrder = clientOTRequest.getObfuscationOrder(); + BigInteger blindingA = CryptoOperatorHelper.getRandomInt(); + BigInteger blindingB = CryptoOperatorHelper.getRandomInt(); + + BigInteger x = CryptoOperatorHelper.powMod(blindingA); + BigInteger y = CryptoOperatorHelper.powMod(blindingB); + BigInteger blindingC = CryptoOperatorHelper.mulMod(blindingA, blindingB); + + List pirDataArrayList = new ArrayList<>(); + for (String searchId : clientOTRequest.getDataBodyList()) { + int idIndex = rand.nextInt(obfuscationOrder + 1); + BigInteger z0 = calculateIndexZ0(idIndex, blindingC); + List idHashVecList = + IdHashVec.getIdHashVec(obfuscationOrder, idIndex, searchId); + + PirDataBody pirDataBody = new PirDataBody(); + pirDataBody.setZ0(z0); + pirDataBody.setIdIndex(idIndex); + pirDataBody.setIdHashList(idHashVecList); + pirDataArrayList.add(pirDataBody); + } + logger.debug("runClientOTCipher success: ", pirDataArrayList); + return new ClientOTResponse(blindingB, x, y, pirDataArrayList); + } + + private BigInteger calculateZ0(String searchId, BigInteger blindingC) { + byte[] idBytes = searchId.getBytes(StandardCharsets.UTF_8); + BigInteger idNumber = ConvertTypeHelper.bytesToBigInteger(idBytes); + return CryptoOperatorHelper.powMod(blindingC.subtract(idNumber)); + } + + private BigInteger calculateIndexZ0(Integer idIndex, BigInteger blindingC) { + // 将整数转长整数 + BigInteger idNumber = BigInteger.valueOf(idIndex); + return CryptoOperatorHelper.powMod(blindingC.subtract(idNumber)); + } +} diff --git a/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/service/PirJobService.java b/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/service/PirJobService.java new file mode 100644 index 00000000..5d6c0e1d --- /dev/null +++ b/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/service/PirJobService.java @@ -0,0 +1,64 @@ +package com.wedpr.pir.sdk.service; + +import com.wedpr.pir.sdk.entity.body.SimpleEntity; +import com.wedpr.pir.sdk.entity.param.PirJobParam; +import com.wedpr.pir.sdk.entity.request.ClientDecryptRequest; +import com.wedpr.pir.sdk.entity.request.ClientOTRequest; +import com.wedpr.pir.sdk.entity.response.ClientDecryptResponse; +import com.wedpr.pir.sdk.entity.response.ClientOTResponse; +import com.wedpr.pir.sdk.entity.response.PirResultResponse; +import com.wedpr.pir.sdk.enums.ParamEnum; +import com.wedpr.pir.sdk.exception.WedprException; +import com.wedpr.pir.sdk.exception.WedprStatusEnum; +import lombok.Getter; + +/** + * @author zachma + * @date 2024/8/20 + */ +public class PirJobService { + + @Getter private final PirJobParam pirJobParam; + private final ClientOTService clientOTService; + private final ClientDecryptService clientDecryptService; + + public PirJobService(PirJobParam pirJobParam) { + this.pirJobParam = pirJobParam; + this.clientOTService = new ClientOTService(); + this.clientDecryptService = new ClientDecryptService(); + } + + public ClientOTResponse requesterOtCipher() throws WedprException { + ClientOTRequest clientOTRequest = new ClientOTRequest(); + ClientOTResponse otParamResponse; + clientOTRequest.setDataBodyList(pirJobParam.getSearchIdList()); + if (pirJobParam.getJobAlgorithmType().equals(ParamEnum.AlgorithmType.idFilter.getValue())) { + clientOTRequest.setFilterLength(pirJobParam.getFilterLength()); + otParamResponse = clientOTService.runClientOTParam(clientOTRequest); + } else if (pirJobParam + .getJobAlgorithmType() + .equals(ParamEnum.AlgorithmType.idObfuscation.getValue())) { + otParamResponse = clientOTService.runClientOTCipher(clientOTRequest); + } else { + throw new WedprException(WedprStatusEnum.INVALID_INPUT_VALUE); + } + return otParamResponse; + } + + public PirResultResponse requesterOtRecover( + ClientOTResponse otParamResponse, PirJobParam clientJobRequest, SimpleEntity otResult) { + ClientDecryptRequest clientDecryptRequest = new ClientDecryptRequest(); + clientDecryptRequest.setB(otParamResponse.getB()); + clientDecryptRequest.setDataBodyList(clientJobRequest.getSearchIdList()); + clientDecryptRequest.setServerResult(otResult.getData()); + + ClientDecryptResponse clientDecryptResponse = + clientDecryptService.runDecryptOTparam(clientDecryptRequest); + + PirResultResponse pirResultResponse = new PirResultResponse(); + pirResultResponse.setJobId(clientJobRequest.getJobId()); + pirResultResponse.setJobType(clientJobRequest.getJobType()); + pirResultResponse.setDetail(clientDecryptResponse); + return pirResultResponse; + } +} diff --git a/java/ppc-pir-services/settings.gradle b/java/ppc-pir-services/settings.gradle new file mode 100644 index 00000000..301af393 --- /dev/null +++ b/java/ppc-pir-services/settings.gradle @@ -0,0 +1,11 @@ +pluginManagement { + repositories { + gradlePluginPortal() + } +} + +rootProject.name = "ppc-pir-services" + +include ':ppc-pir-sdk' +project(":ppc-pir-sdk").projectDir = file("sdk") + diff --git a/java/ppc-pir-services/src/main/java/com/webank/wedpr/pir/WedprPirApplication.java b/java/ppc-pir-services/src/main/java/com/webank/wedpr/pir/WedprPirApplication.java new file mode 100644 index 00000000..9d016653 --- /dev/null +++ b/java/ppc-pir-services/src/main/java/com/webank/wedpr/pir/WedprPirApplication.java @@ -0,0 +1,18 @@ +package com.webank.wedpr.pir; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * @author zachma + * @date 2024/8/18 + */ +@SpringBootApplication +@EnableAutoConfiguration +public class WedprPirApplication { + public static void main(String[] args) { + SpringApplication.run(WedprPirApplication.class, args); + System.out.println("Start WedprPirApplication Server successfully!"); + } +} diff --git a/java/ppc-pir-services/src/main/java/com/webank/wedpr/pir/crypto/entity/PirTable.java b/java/ppc-pir-services/src/main/java/com/webank/wedpr/pir/crypto/entity/PirTable.java new file mode 100644 index 00000000..d153c4a8 --- /dev/null +++ b/java/ppc-pir-services/src/main/java/com/webank/wedpr/pir/crypto/entity/PirTable.java @@ -0,0 +1,17 @@ +package com.webank.wedpr.pir.crypto.entity; + +import lombok.Data; + +/** + * @author zachma + * @date 2024/8/19 + */ +@Data +public class PirTable { + + private Integer id; + + private String pirKey; + + private String pirValue; +} diff --git a/java/ppc-pir-services/src/main/java/com/webank/wedpr/pir/crypto/service/PirOTService.java b/java/ppc-pir-services/src/main/java/com/webank/wedpr/pir/crypto/service/PirOTService.java new file mode 100644 index 00000000..68be68e0 --- /dev/null +++ b/java/ppc-pir-services/src/main/java/com/webank/wedpr/pir/crypto/service/PirOTService.java @@ -0,0 +1,25 @@ +package com.webank.wedpr.pir.crypto.service; + +import com.wedpr.pir.sdk.entity.request.ServerOTRequest; +import com.wedpr.pir.sdk.entity.response.ServerOTResponse; +import com.wedpr.pir.sdk.exception.WedprException; + +/** + * @author zachma + * @date 2024/8/19 + */ +public interface PirOTService { + /** + * @param serverOTRequest + * @return PirOTResponse + * @throws WedprException + */ + ServerOTResponse runServerOTParam(ServerOTRequest serverOTRequest) throws WedprException; + + /** + * @param serverOTRequest + * @return PirOTResponse + * @throws WedprException + */ + ServerOTResponse runServerOTCipher(ServerOTRequest serverOTRequest) throws WedprException; +} diff --git a/java/ppc-pir-services/src/main/java/com/webank/wedpr/pir/crypto/service/PirTableService.java b/java/ppc-pir-services/src/main/java/com/webank/wedpr/pir/crypto/service/PirTableService.java new file mode 100644 index 00000000..a70db535 --- /dev/null +++ b/java/ppc-pir-services/src/main/java/com/webank/wedpr/pir/crypto/service/PirTableService.java @@ -0,0 +1,21 @@ +package com.webank.wedpr.pir.crypto.service; + +import com.webank.wedpr.pir.crypto.entity.PirTable; +import java.util.List; + +/** + * @author zachma + * @date 2024/8/19 + */ +public interface PirTableService { + /** 根据id查询 */ + List idFilterTable(String datasetId, String filter); + + List idFilterTable(String datasetId, String filter, String[] params); + + List idObfuscationTable(String datasetId, String searchId); + + List idObfuscationTable(String datasetId, String searchId, String[] params); + + List objectsToPirTableList(List params); +} diff --git a/java/ppc-pir-services/src/main/java/com/webank/wedpr/pir/crypto/service/impl/PirOTServiceImpl.java b/java/ppc-pir-services/src/main/java/com/webank/wedpr/pir/crypto/service/impl/PirOTServiceImpl.java new file mode 100644 index 00000000..a61fa4c3 --- /dev/null +++ b/java/ppc-pir-services/src/main/java/com/webank/wedpr/pir/crypto/service/impl/PirOTServiceImpl.java @@ -0,0 +1,139 @@ +package com.webank.wedpr.pir.crypto.service.impl; + +import com.webank.wedpr.pir.crypto.entity.PirTable; +import com.webank.wedpr.pir.crypto.service.PirOTService; +import com.webank.wedpr.pir.crypto.service.PirTableService; +import com.wedpr.pir.sdk.entity.body.ServerResultBody; +import com.wedpr.pir.sdk.entity.body.ServerResultList; +import com.wedpr.pir.sdk.entity.request.ServerOTRequest; +import com.wedpr.pir.sdk.entity.response.ServerOTResponse; +import com.wedpr.pir.sdk.exception.WedprException; +import com.wedpr.pir.sdk.helper.AESHelper; +import com.wedpr.pir.sdk.helper.ConvertTypeHelper; +import com.wedpr.pir.sdk.helper.CryptoOperatorHelper; +import java.math.BigInteger; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +/** + * @author zachma + * @date 2024/8/18 + */ +@Service +public class PirOTServiceImpl implements PirOTService { + private static final Logger logger = LoggerFactory.getLogger(PirOTServiceImpl.class); + @Autowired PirTableService pirTableService; + + public ServerOTResponse runServerOTParam(ServerOTRequest serverOTRequest) + throws WedprException { + logger.info("Server start runServerOTParam."); + String datasetId = serverOTRequest.getDatasetId(); + BigInteger x = serverOTRequest.getX(); + BigInteger y = serverOTRequest.getY(); + List serverResultlist = new ArrayList<>(); + for (int i = 0; i < serverOTRequest.getDataBodyList().size(); i++) { + BigInteger z0 = serverOTRequest.getDataBodyList().get(i).getZ0(); + String filter = serverOTRequest.getDataBodyList().get(i).getFilter(); + List objects = pirTableService.idFilterTable(datasetId, filter); + List pirTables = pirTableService.objectsToPirTableList(objects); + List serverResultBodyTempList = new ArrayList<>(); + for (PirTable pirTable : pirTables) { + ServerResultBody serverResultBody = + cipherPirTableContentIdSearch(pirTable, x, y, z0); + serverResultBodyTempList.add(serverResultBody); + } + serverResultlist.add(new ServerResultList(serverResultBodyTempList)); + } + logger.info("Server runServerOTParam success"); + return new ServerOTResponse(serverResultlist); + } + + public ServerOTResponse runServerOTCipher(ServerOTRequest serverOTRequest) + throws WedprException { + logger.info("Server start runServerOTCipher."); + String datasetId = serverOTRequest.getDatasetId(); + BigInteger x = serverOTRequest.getX(); + BigInteger y = serverOTRequest.getY(); + + List serverResultlist = new ArrayList<>(); + for (int i = 0; i < serverOTRequest.getDataBodyList().size(); i++) { + BigInteger z0 = serverOTRequest.getDataBodyList().get(i).getZ0(); + List idHashList = serverOTRequest.getDataBodyList().get(i).getIdHashList(); + List serverResultBodyTempList = new ArrayList<>(); + + for (int j = 0; j < idHashList.size(); j++) { + List objects = + pirTableService.idObfuscationTable(datasetId, idHashList.get(j)); + List pirTables = pirTableService.objectsToPirTableList(objects); + for (PirTable pirTable : pirTables) { + ServerResultBody serverResultBody = + cipherPirTableContentIdObfuscation(pirTable, x, y, z0, j); + serverResultBodyTempList.add(serverResultBody); + } + } + serverResultlist.add(new ServerResultList(serverResultBodyTempList)); + } + logger.info("Server runServerOTCipher success."); + return new ServerOTResponse(serverResultlist); + } + + private ServerResultBody cipherPirTableContentIdSearch( + PirTable pirTable, BigInteger x, BigInteger y, BigInteger z0) throws WedprException { + String uid = pirTable.getPirKey(); + String message = pirTable.getPirValue(); + byte[] uidBytes = uid.getBytes(StandardCharsets.UTF_8); + BigInteger uidNum = ConvertTypeHelper.bytesToBigInteger(uidBytes); + + BigInteger blindingR = CryptoOperatorHelper.getRandomInt(); + BigInteger blindingS = CryptoOperatorHelper.getRandomInt(); + BigInteger w = + CryptoOperatorHelper.OTMul( + CryptoOperatorHelper.OTPow(x, blindingS), + CryptoOperatorHelper.powMod(blindingR)); + BigInteger z1 = CryptoOperatorHelper.OTMul(z0, CryptoOperatorHelper.powMod(uidNum)); + BigInteger key = + CryptoOperatorHelper.OTMul( + CryptoOperatorHelper.OTPow(z1, blindingS), + CryptoOperatorHelper.OTPow(y, blindingR)); + + String aesKey = AESHelper.generateRandomKey(); + BigInteger aesNum = + ConvertTypeHelper.bytesToBigInteger(aesKey.getBytes(StandardCharsets.UTF_8)); + BigInteger messageCipherNum = key.xor(aesNum); + String c = AESHelper.encrypt(message, aesKey); + + return new ServerResultBody(messageCipherNum, w, c); + } + + private ServerResultBody cipherPirTableContentIdObfuscation( + PirTable pirTable, BigInteger x, BigInteger y, BigInteger z0, int index) + throws WedprException { + String message = pirTable.getPirValue(); + BigInteger blindingR = CryptoOperatorHelper.getRandomInt(); + BigInteger blindingS = CryptoOperatorHelper.getRandomInt(); + BigInteger w = + CryptoOperatorHelper.OTMul( + CryptoOperatorHelper.OTPow(x, blindingS), + CryptoOperatorHelper.powMod(blindingR)); + BigInteger z1 = + CryptoOperatorHelper.OTMul( + z0, CryptoOperatorHelper.powMod(BigInteger.valueOf(index))); + BigInteger key = + CryptoOperatorHelper.OTMul( + CryptoOperatorHelper.OTPow(z1, blindingS), + CryptoOperatorHelper.OTPow(y, blindingR)); + + String aesKey = AESHelper.generateRandomKey(); + BigInteger aesNum = + ConvertTypeHelper.bytesToBigInteger(aesKey.getBytes(StandardCharsets.UTF_8)); + BigInteger messageCipherNum = key.xor(aesNum); + String c = AESHelper.encrypt(message, aesKey); + + return new ServerResultBody(messageCipherNum, w, c); + } +} diff --git a/java/ppc-pir-services/src/main/java/com/webank/wedpr/pir/crypto/service/impl/PirTableServiceImpl.java b/java/ppc-pir-services/src/main/java/com/webank/wedpr/pir/crypto/service/impl/PirTableServiceImpl.java new file mode 100644 index 00000000..7d319b5f --- /dev/null +++ b/java/ppc-pir-services/src/main/java/com/webank/wedpr/pir/crypto/service/impl/PirTableServiceImpl.java @@ -0,0 +1,67 @@ +package com.webank.wedpr.pir.crypto.service.impl; + +import com.webank.wedpr.pir.crypto.entity.PirTable; +import com.webank.wedpr.pir.crypto.service.PirTableService; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; +import javax.persistence.Query; +import org.springframework.stereotype.Service; + +/** + * @author zachma + * @date 2024/8/19 + */ +@Service +public class PirTableServiceImpl implements PirTableService { + + @PersistenceContext private EntityManager entityManager; + + @Override + public List idFilterTable(String datasetId, String filter) { + String sqlFormat = "SELECT * FROM %s WHERE id LIKE CONCAT(%s, '%%')"; + String sql = String.format(sqlFormat, datasetId, filter); + Query query = entityManager.createNativeQuery(sql); + return query.getResultList(); + } + + @Override + public List idFilterTable(String datasetId, String filter, String[] params) { + String sqlFormat = "SELECT %s FROM %s WHERE id LIKE CONCAT(%s, '%%')"; + String sql = String.format(sqlFormat, String.join(", ", params), datasetId, filter); + Query query = entityManager.createNativeQuery(sql); + return query.getResultList(); + } + + @Override + public List idObfuscationTable(String datasetId, String searchId) { + String sqlFormat = "SELECT * FROM %s WHERE id = %s"; + String sql = String.format(sqlFormat, datasetId, searchId); + Query query = entityManager.createNativeQuery(sql); + return query.getResultList(); + } + + @Override + public List idObfuscationTable(String datasetId, String searchId, String[] params) { + String sqlFormat = "SELECT %s FROM %s WHERE id = %s"; + String sql = String.format(sqlFormat, String.join(", ", params), datasetId, searchId); + Query query = entityManager.createNativeQuery(sql); + return query.getResultList(); + } + + public List objectsToPirTableList(List params) { + List result = new LinkedList<>(); + for (int i = 0; i < params.size(); i++) { + Object[] temp = (Object[]) params.get(i); + PirTable pirTable = new PirTable(); + pirTable.setId(i + 1); + pirTable.setPirKey(String.valueOf(temp[0])); + Object[] objects = Arrays.copyOfRange(temp, 1, temp.length); + pirTable.setPirValue(Arrays.toString(objects)); + result.add(pirTable); + } + return result; + } +} diff --git a/java/ppc-pir-services/src/main/java/com/webank/wedpr/pir/http/common/Constant.java b/java/ppc-pir-services/src/main/java/com/webank/wedpr/pir/http/common/Constant.java new file mode 100644 index 00000000..9ddfd9bb --- /dev/null +++ b/java/ppc-pir-services/src/main/java/com/webank/wedpr/pir/http/common/Constant.java @@ -0,0 +1,10 @@ +package com.webank.wedpr.pir.http.common; + +/** + * @author zachma + * @date 2024/8/18 + */ +public class Constant { + + public static final String PIR_API_PREFIX = "/api/pir/v3"; +} diff --git a/java/ppc-pir-services/src/main/java/com/webank/wedpr/pir/http/config/JacksonConfig.java b/java/ppc-pir-services/src/main/java/com/webank/wedpr/pir/http/config/JacksonConfig.java new file mode 100644 index 00000000..ef6adad2 --- /dev/null +++ b/java/ppc-pir-services/src/main/java/com/webank/wedpr/pir/http/config/JacksonConfig.java @@ -0,0 +1,59 @@ +/** Copyright (C) @2014-2022 Webank */ +package com.webank.wedpr.pir.http.config; + +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.format.DateTimeFormatter; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class JacksonConfig { + @Value("${spring.jackson.local-date-time-format:yyyy-MM-dd HH:mm:ss}") + String localDateTimeFormat; + + @Value("${spring.jackson.local-date-format:yyyy-MM-dd}") + String localDateFormat; + + @Value("${spring.jackson.local-time-format:HH:mm:ss}") + String localTimeFormat; + + @Bean + public ObjectMapper objectMapper() { + ObjectMapper objectMapper = new ObjectMapper(); + JavaTimeModule javaTimeModule = new JavaTimeModule(); + javaTimeModule.addSerializer( + LocalDateTime.class, + new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(localDateTimeFormat))); + javaTimeModule.addSerializer( + LocalDate.class, + new LocalDateSerializer(DateTimeFormatter.ofPattern(localDateFormat))); + javaTimeModule.addSerializer( + LocalTime.class, + new LocalTimeSerializer(DateTimeFormatter.ofPattern(localTimeFormat))); + + javaTimeModule.addDeserializer( + LocalDateTime.class, + new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(localDateTimeFormat))); + javaTimeModule.addDeserializer( + LocalDate.class, + new LocalDateDeserializer(DateTimeFormatter.ofPattern(localDateFormat))); + javaTimeModule.addDeserializer( + LocalTime.class, + new LocalTimeDeserializer(DateTimeFormatter.ofPattern(localTimeFormat))); + objectMapper.registerModule(javaTimeModule); + objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + return objectMapper; + } +} diff --git a/java/ppc-pir-services/src/main/java/com/webank/wedpr/pir/http/controller/PirController.java b/java/ppc-pir-services/src/main/java/com/webank/wedpr/pir/http/controller/PirController.java new file mode 100644 index 00000000..c33e3320 --- /dev/null +++ b/java/ppc-pir-services/src/main/java/com/webank/wedpr/pir/http/controller/PirController.java @@ -0,0 +1,54 @@ +package com.webank.wedpr.pir.http.controller; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.webank.wedpr.pir.http.common.Constant; +import com.webank.wedpr.pir.http.service.PirAppService; +import com.wedpr.pir.sdk.entity.request.ServerJobRequest; +import com.wedpr.pir.sdk.entity.response.ClientJobResponse; +import com.wedpr.pir.sdk.entity.response.ServerOTResponse; +import com.wedpr.pir.sdk.exception.WedprStatusEnum; +import lombok.extern.slf4j.Slf4j; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +/** + * @author zachma + * @date 2024/8/18 + */ +@RestController +@Slf4j +public class PirController { + private static final Logger logger = LoggerFactory.getLogger(PirController.class); + + @Autowired private ObjectMapper objectMapper; + @Autowired private PirAppService pirAppService; + + @PostMapping(Constant.PIR_API_PREFIX + "/server") + public ClientJobResponse pirServerController(@RequestBody ServerJobRequest serverJobRequest) { + try { + logger.info( + "WedprServerjob: serverJobRequest: {}.", + objectMapper.writeValueAsString(serverJobRequest)); + // 1. 根据请求,筛选数据,加密密钥,返回筛选结果及AES消息密文 + ServerOTResponse serverOTResponse = pirAppService.providerOtCipher(serverJobRequest); + pirAppService.reportToAdm(); + return new ClientJobResponse(WedprStatusEnum.SUCCESS, serverOTResponse); + } catch (Exception e) { + logger.warn( + "匿踪任务失败, jobID: {}, response: {}", + serverJobRequest.getJobId(), + WedprStatusEnum.SYSTEM_EXCEPTION.getMessage()); + return new ClientJobResponse(WedprStatusEnum.SYSTEM_EXCEPTION, e.getMessage()); + } + } + + // @PostMapping(Constant.PIR_API_PREFIX + "/client") + // public ClientJobResponse pirClientController(@RequestBody ClientJobRequest + // clientJobRequest) { + // + // } +} diff --git a/java/ppc-pir-services/src/main/java/com/webank/wedpr/pir/http/service/PirAppService.java b/java/ppc-pir-services/src/main/java/com/webank/wedpr/pir/http/service/PirAppService.java new file mode 100644 index 00000000..ca73bdc0 --- /dev/null +++ b/java/ppc-pir-services/src/main/java/com/webank/wedpr/pir/http/service/PirAppService.java @@ -0,0 +1,50 @@ +package com.webank.wedpr.pir.http.service; + +import com.webank.wedpr.pir.crypto.service.PirOTService; +import com.wedpr.pir.sdk.entity.request.ServerJobRequest; +import com.wedpr.pir.sdk.entity.request.ServerOTRequest; +import com.wedpr.pir.sdk.entity.response.ServerOTResponse; +import com.wedpr.pir.sdk.enums.ParamEnum; +import com.wedpr.pir.sdk.exception.WedprException; +import com.wedpr.pir.sdk.exception.WedprStatusEnum; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +/** + * @author zachma + * @date 2024/8/18 + */ +@Service +public class PirAppService { + + @Autowired private PirOTService pirOTService; + + public ServerOTResponse providerOtCipher(ServerJobRequest serverJobRequest) + throws WedprException { + // 1. 根据请求,筛选数据,加密密钥,返回筛选结果及AES消息密文 + ServerOTRequest serverOTRequest = new ServerOTRequest(); + serverOTRequest.setJobType(serverJobRequest.getJobType()); + serverOTRequest.setDatasetId(serverJobRequest.getDatasetId()); + serverOTRequest.setX(serverJobRequest.getX()); + serverOTRequest.setY(serverJobRequest.getY()); + serverOTRequest.setDataBodyList(serverJobRequest.getDataBodyList()); + + ServerOTResponse otResultResponse; + if (serverJobRequest + .getJobAlgorithmType() + .equals(ParamEnum.AlgorithmType.idFilter.getValue())) { + otResultResponse = pirOTService.runServerOTParam(serverOTRequest); + } else if (serverJobRequest + .getJobAlgorithmType() + .equals(ParamEnum.AlgorithmType.idObfuscation.getValue())) { + otResultResponse = pirOTService.runServerOTCipher(serverOTRequest); + } else { + throw new WedprException(WedprStatusEnum.INVALID_INPUT_VALUE); + } + return otResultResponse; + } + + public void reportToAdm() { + // TODO: 任务结束上报 + } +} diff --git a/java/ppc-pir-services/src/main/resources/application-dev.properties b/java/ppc-pir-services/src/main/resources/application-dev.properties new file mode 100644 index 00000000..86233b92 --- /dev/null +++ b/java/ppc-pir-services/src/main/resources/application-dev.properties @@ -0,0 +1,9 @@ +### Spring boot configuration +server.address=0.0.0.0 +server.port=5831 +server.session.timeout=60 +banner.charset=UTF-8 +spring.jackson.local-date-time-format=yyyy-MM-dd HH:mm:ss +spring.jackson.local-date-format=yyyy-MM-dd +spring.jackson.local-time-format=HH:mm:ss +spring.jackson.time-zone=GMT+8 \ No newline at end of file diff --git a/java/ppc-pir-services/src/main/resources/application-mysql.properties b/java/ppc-pir-services/src/main/resources/application-mysql.properties new file mode 100644 index 00000000..4c82652f --- /dev/null +++ b/java/ppc-pir-services/src/main/resources/application-mysql.properties @@ -0,0 +1,6 @@ +spring.datasource.url=jdbc:mysql://139.159.202.235:3306/ppc1?serverTimezone=Asia/Shanghai&useUnicode=true&autoReconnect=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&useFractionalSeconds=true&useUnbufferedInput=false&useSSL=false +spring.datasource.username=root +spring.datasource.password=Wedpr2023 +spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver +spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect +spring.jpa.database=mysql diff --git a/java/ppc-pir-services/src/main/resources/application.properties b/java/ppc-pir-services/src/main/resources/application.properties new file mode 100644 index 00000000..80c5d0e0 --- /dev/null +++ b/java/ppc-pir-services/src/main/resources/application.properties @@ -0,0 +1,7 @@ + +spring.profiles.active=dev +# mysql or dm or gauss or kingbase or shentong or postgresql +spring.profiles.include=mysql + +server.shutdown=graceful +spring.lifecycle.timeout-per-shutdown-phase=30s diff --git a/java/ppc-pir-services/src/main/resources/log4j2.xml b/java/ppc-pir-services/src/main/resources/log4j2.xml new file mode 100644 index 00000000..b3c6d126 --- /dev/null +++ b/java/ppc-pir-services/src/main/resources/log4j2.xml @@ -0,0 +1,111 @@ + + + + + + info + log location + ./logs + + + wedpr-pir + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From cb24aa1afb0af445b06c41e900a578cd7876ec4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?zachma=28=E9=A9=AC=E6=99=A8=29?= Date: Mon, 26 Aug 2024 11:21:10 +0800 Subject: [PATCH 3/9] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BE=9D=E8=B5=96PIR?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/wedpr/pir/demo/Demo.java | 4 +- .../java/com/wedpr/pir/sdk/PirClient.java | 6 --- .../com/wedpr/pir/sdk/crypto/IdHashVec.java | 51 ------------------- .../com/wedpr/pir/sdk/helper/AESHelper.java | 3 +- .../pir/sdk/helper/CryptoOperatorHelper.java | 47 +++++++++++++++++ .../pir/sdk/service/ClientDecryptService.java | 5 -- .../pir/sdk/service/ClientOTService.java | 11 +--- .../pir/http/controller/PirController.java | 7 --- .../wedpr/pir/http/service/PirAppService.java | 4 -- 9 files changed, 51 insertions(+), 87 deletions(-) delete mode 100644 java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/crypto/IdHashVec.java diff --git a/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/demo/Demo.java b/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/demo/Demo.java index 41f5ee8d..f88a121b 100644 --- a/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/demo/Demo.java +++ b/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/demo/Demo.java @@ -26,7 +26,7 @@ private static void testIdFilter() throws WedprException { pirJobParam.setDatasetId("t_login_token"); pirJobParam.setJobCreator("1001"); pirJobParam.setGatewayUrl("http://localhost:5831/api/pir/v3/server"); - pirJobParam.setSearchIdList(Arrays.asList(new String[] {"1", "20", "3", "456"})); + pirJobParam.setSearchIdList(Arrays.asList("1", "20", "3", "456")); PirClient pirClient = new PirClient(pirJobParam); PirResultResponse pirResultResponse = pirClient.executePirJob(); @@ -42,7 +42,7 @@ private static void testIdObfuscation() throws WedprException { pirJobParam.setDatasetId("t_login_token"); pirJobParam.setJobCreator("1001"); pirJobParam.setGatewayUrl("http://localhost:5831/api/pir/v3/server"); - pirJobParam.setSearchIdList(Arrays.asList(new String[] {"1", "20", "3", "456"})); + pirJobParam.setSearchIdList(Arrays.asList("1", "20", "3", "456")); PirClient pirClient = new PirClient(pirJobParam); PirResultResponse pirResultResponse = pirClient.executePirJob(); diff --git a/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/PirClient.java b/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/PirClient.java index b9e95e29..ecf6ba75 100644 --- a/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/PirClient.java +++ b/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/PirClient.java @@ -1,8 +1,6 @@ package com.wedpr.pir.sdk; import com.fasterxml.jackson.databind.ObjectMapper; -import com.sun.org.slf4j.internal.Logger; -import com.sun.org.slf4j.internal.LoggerFactory; import com.wedpr.pir.sdk.entity.body.SimpleEntity; import com.wedpr.pir.sdk.entity.param.PirJobParam; import com.wedpr.pir.sdk.entity.request.ServerJobRequest; @@ -19,7 +17,6 @@ * @date 2024/8/19 */ public class PirClient { - private static final Logger logger = LoggerFactory.getLogger(PirClient.class); private final PirJobService pirJobService; public PirClient(PirJobParam pirJobParam) throws WedprException { @@ -33,21 +30,18 @@ public PirResultResponse executePirJob() throws WedprException { PirJobParam pirJobParam = pirJobService.getPirJobParam(); ServerJobRequest serverJobRequest = generatePirJobRequestFromJobAndOTParam(pirJobParam, otParamResponse); - logger.debug("executePirJob start: ", serverJobRequest); String pirUrl = pirJobParam.getGatewayUrl(); ObjectMapper objectMapper = new ObjectMapper(); String body = objectMapper.writeValueAsString(serverJobRequest); SimpleEntity otResult = GatewayClient.sendPostRequestWithRetry(pirUrl, body, SimpleEntity.class); - logger.debug("executePirJob success return: ", otResult); if (Objects.isNull(otResult) || !otResult.getCode().equals(WedprStatusEnum.SUCCESS.getCode())) { throw new WedprException(WedprStatusEnum.TASK_EXECUTE_ERROR); } return pirJobService.requesterOtRecover(otParamResponse, pirJobParam, otResult); } catch (Exception e) { - logger.error("executePirJob cause exception: ", e.getMessage()); throw new WedprException(WedprStatusEnum.CALL_PSI_ERROR); } } diff --git a/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/crypto/IdHashVec.java b/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/crypto/IdHashVec.java deleted file mode 100644 index 1aed44d6..00000000 --- a/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/crypto/IdHashVec.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.wedpr.pir.sdk.crypto; - -import com.wedpr.pir.sdk.exception.WedprException; -import com.wedpr.pir.sdk.exception.WedprStatusEnum; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; - -/** - * @author zachma - * @date 2024/8/20 - */ -public class IdHashVec { - public static List getIdHashVec(int obfuscationOrder, Integer idIndex, String searchId) - throws WedprException { - - List clientDataBodyList = new ArrayList<>(); - String searchIdTemp; - for (int i = 0; i < obfuscationOrder + 1; i++) { - if (idIndex == i) { - searchIdTemp = searchId; - } else { - String uuid = UUID.randomUUID().toString(); - searchIdTemp = makeHash(uuid.getBytes()); - } - clientDataBodyList.add(searchIdTemp); - } - return clientDataBodyList; - } - - private static String makeHash(byte[] data) throws WedprException { - try { - MessageDigest digest = MessageDigest.getInstance("SHA-256"); - byte[] hashBytes = digest.digest(data); - - StringBuilder hexString = new StringBuilder(); - for (byte b : hashBytes) { - String hex = Integer.toHexString(0xFF & b); - if (hex.length() == 1) { - hexString.append('0'); - } - hexString.append(hex); - } - return hexString.toString(); - } catch (NoSuchAlgorithmException e) { - throw new WedprException(WedprStatusEnum.WRONG_HASH_ERROR); - } - } -} diff --git a/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/helper/AESHelper.java b/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/helper/AESHelper.java index 8288ccb9..f3260060 100644 --- a/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/helper/AESHelper.java +++ b/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/helper/AESHelper.java @@ -31,8 +31,7 @@ public static String generateRandomKey() { public static String encrypt(String plainText, String keyString) throws WedprException { try { byte[] iv = new byte[12]; - SecureRandom secureRandom = new SecureRandom(); - secureRandom.nextBytes(iv); + SECURE_RANDOM.nextBytes(iv); byte[] contentBytes = plainText.getBytes(StandardCharsets.UTF_8); Cipher cipher = Cipher.getInstance(AES_ALGORITHM_TRANSFORMATION); GCMParameterSpec params = new GCMParameterSpec(128, iv); diff --git a/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/helper/CryptoOperatorHelper.java b/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/helper/CryptoOperatorHelper.java index 187cfcb7..51c89168 100644 --- a/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/helper/CryptoOperatorHelper.java +++ b/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/helper/CryptoOperatorHelper.java @@ -1,7 +1,15 @@ package com.wedpr.pir.sdk.helper; +import com.wedpr.pir.sdk.exception.WedprException; +import com.wedpr.pir.sdk.exception.WedprStatusEnum; + import java.math.BigInteger; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; /** * @author zachma @@ -48,4 +56,43 @@ public static BigInteger mulMod(BigInteger a, BigInteger b) { public static BigInteger OTMul(BigInteger a, BigInteger b) { return a.multiply(b).mod(DEFAULT_N); } + + /** + * 批量获取searchID的Hash值 + * */ + public static List getIdHashVec(int obfuscationOrder, Integer idIndex, String searchId) + throws WedprException { + + List clientDataBodyList = new ArrayList<>(); + String searchIdTemp; + for (int i = 0; i < obfuscationOrder + 1; i++) { + if (idIndex == i) { + searchIdTemp = searchId; + } else { + String uuid = UUID.randomUUID().toString(); + searchIdTemp = makeHash(uuid.getBytes()); + } + clientDataBodyList.add(searchIdTemp); + } + return clientDataBodyList; + } + + private static String makeHash(byte[] data) throws WedprException { + try { + MessageDigest digest = MessageDigest.getInstance("SHA-256"); + byte[] hashBytes = digest.digest(data); + + StringBuilder hexString = new StringBuilder(); + for (byte b : hashBytes) { + String hex = Integer.toHexString(0xFF & b); + if (hex.length() == 1) { + hexString.append('0'); + } + hexString.append(hex); + } + return hexString.toString(); + } catch (NoSuchAlgorithmException e) { + throw new WedprException(WedprStatusEnum.WRONG_HASH_ERROR); + } + } } diff --git a/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/service/ClientDecryptService.java b/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/service/ClientDecryptService.java index 6e1d2f2a..2321dec4 100644 --- a/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/service/ClientDecryptService.java +++ b/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/service/ClientDecryptService.java @@ -1,7 +1,5 @@ package com.wedpr.pir.sdk.service; -import com.sun.org.slf4j.internal.Logger; -import com.sun.org.slf4j.internal.LoggerFactory; import com.wedpr.pir.sdk.entity.body.PirResultBody; import com.wedpr.pir.sdk.entity.body.ServerResultBody; import com.wedpr.pir.sdk.entity.request.ClientDecryptRequest; @@ -21,7 +19,6 @@ * @date 2024/8/21 */ public class ClientDecryptService { - private static final Logger logger = LoggerFactory.getLogger(ClientDecryptService.class); private void decryptServerResultList( PirResultBody pirResultBody, List serverResultList, BigInteger b) { for (ServerResultBody body : serverResultList) { @@ -43,7 +40,6 @@ private void decryptServerResultList( } protected ClientDecryptResponse runDecryptOTparam(ClientDecryptRequest clientDecryptRequest) { - logger.debug("runDecryptOTparam Start: ", clientDecryptRequest); List pirResultBodyArrayList = new ArrayList<>(); for (int i = 0; i < clientDecryptRequest.getServerResult().getResultBodyList().size(); @@ -61,7 +57,6 @@ protected ClientDecryptResponse runDecryptOTparam(ClientDecryptRequest clientDec BasicTypeHelper.isStringNotEmpty(pirResultBody.getSearchValue())); pirResultBodyArrayList.add(pirResultBody); } - logger.debug("runDecryptOTparam Success: ", pirResultBodyArrayList); ClientDecryptResponse clientDecryptResponse = new ClientDecryptResponse(); clientDecryptResponse.setDetail(pirResultBodyArrayList); return clientDecryptResponse; diff --git a/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/service/ClientOTService.java b/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/service/ClientOTService.java index 63d096df..7d867479 100644 --- a/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/service/ClientOTService.java +++ b/java/ppc-pir-services/sdk/src/main/java/com/wedpr/pir/sdk/service/ClientOTService.java @@ -1,8 +1,5 @@ package com.wedpr.pir.sdk.service; -import com.sun.org.slf4j.internal.Logger; -import com.sun.org.slf4j.internal.LoggerFactory; -import com.wedpr.pir.sdk.crypto.IdHashVec; import com.wedpr.pir.sdk.entity.body.PirDataBody; import com.wedpr.pir.sdk.entity.request.ClientOTRequest; import com.wedpr.pir.sdk.entity.response.ClientOTResponse; @@ -20,12 +17,10 @@ * @date 2024/8/20 */ public class ClientOTService { - private static final Logger logger = LoggerFactory.getLogger(ClientOTService.class); private final Random rand = new Random(); /* hash披露, 请求方选择id,生成随机数a、b */ protected ClientOTResponse runClientOTParam(ClientOTRequest clientOTRequest) { - logger.debug("runClientOTParam start: ", clientOTRequest); int filterLength = clientOTRequest.getFilterLength(); BigInteger blindingA = CryptoOperatorHelper.getRandomInt(); BigInteger blindingB = CryptoOperatorHelper.getRandomInt(); @@ -46,15 +41,12 @@ protected ClientOTResponse runClientOTParam(ClientOTRequest clientOTRequest) { pirDataBody.setZ0(z0); pirDataArrayList.add(pirDataBody); } - logger.debug("runClientOTParam success: ", pirDataArrayList); return new ClientOTResponse(blindingB, x, y, pirDataArrayList); } /* hash筛选, 请求方选择顺序\delta\in \{0,1,..,m-1\},生成随机数a、b */ protected ClientOTResponse runClientOTCipher(ClientOTRequest clientOTRequest) throws WedprException { - logger.debug("runClientOTCipher start: ", clientOTRequest); - int obfuscationOrder = clientOTRequest.getObfuscationOrder(); BigInteger blindingA = CryptoOperatorHelper.getRandomInt(); BigInteger blindingB = CryptoOperatorHelper.getRandomInt(); @@ -68,7 +60,7 @@ protected ClientOTResponse runClientOTCipher(ClientOTRequest clientOTRequest) int idIndex = rand.nextInt(obfuscationOrder + 1); BigInteger z0 = calculateIndexZ0(idIndex, blindingC); List idHashVecList = - IdHashVec.getIdHashVec(obfuscationOrder, idIndex, searchId); + CryptoOperatorHelper.getIdHashVec(obfuscationOrder, idIndex, searchId); PirDataBody pirDataBody = new PirDataBody(); pirDataBody.setZ0(z0); @@ -76,7 +68,6 @@ protected ClientOTResponse runClientOTCipher(ClientOTRequest clientOTRequest) pirDataBody.setIdHashList(idHashVecList); pirDataArrayList.add(pirDataBody); } - logger.debug("runClientOTCipher success: ", pirDataArrayList); return new ClientOTResponse(blindingB, x, y, pirDataArrayList); } diff --git a/java/ppc-pir-services/src/main/java/com/webank/wedpr/pir/http/controller/PirController.java b/java/ppc-pir-services/src/main/java/com/webank/wedpr/pir/http/controller/PirController.java index c33e3320..361c63b0 100644 --- a/java/ppc-pir-services/src/main/java/com/webank/wedpr/pir/http/controller/PirController.java +++ b/java/ppc-pir-services/src/main/java/com/webank/wedpr/pir/http/controller/PirController.java @@ -35,7 +35,6 @@ public ClientJobResponse pirServerController(@RequestBody ServerJobRequest serve objectMapper.writeValueAsString(serverJobRequest)); // 1. 根据请求,筛选数据,加密密钥,返回筛选结果及AES消息密文 ServerOTResponse serverOTResponse = pirAppService.providerOtCipher(serverJobRequest); - pirAppService.reportToAdm(); return new ClientJobResponse(WedprStatusEnum.SUCCESS, serverOTResponse); } catch (Exception e) { logger.warn( @@ -45,10 +44,4 @@ public ClientJobResponse pirServerController(@RequestBody ServerJobRequest serve return new ClientJobResponse(WedprStatusEnum.SYSTEM_EXCEPTION, e.getMessage()); } } - - // @PostMapping(Constant.PIR_API_PREFIX + "/client") - // public ClientJobResponse pirClientController(@RequestBody ClientJobRequest - // clientJobRequest) { - // - // } } diff --git a/java/ppc-pir-services/src/main/java/com/webank/wedpr/pir/http/service/PirAppService.java b/java/ppc-pir-services/src/main/java/com/webank/wedpr/pir/http/service/PirAppService.java index ca73bdc0..4d0db22f 100644 --- a/java/ppc-pir-services/src/main/java/com/webank/wedpr/pir/http/service/PirAppService.java +++ b/java/ppc-pir-services/src/main/java/com/webank/wedpr/pir/http/service/PirAppService.java @@ -43,8 +43,4 @@ public ServerOTResponse providerOtCipher(ServerJobRequest serverJobRequest) } return otResultResponse; } - - public void reportToAdm() { - // TODO: 任务结束上报 - } } From 3f202aeb448218600b643c6e53586384b6ddf934 Mon Sep 17 00:00:00 2001 From: cyjseagull Date: Thu, 22 Aug 2024 20:06:39 +0800 Subject: [PATCH 4/9] rename ppc-crypto-c-sdk to wedpr-component-c-sdk --- cpp/ppc-crypto-c-sdk/CMakeLists.txt | 23 ------------------ cpp/wedpr-component-c-sdk/CMakeLists.txt | 15 ++++++++++++ .../bindings/java/build.gradle | 0 .../java/gradle/wrapper/gradle-wrapper.jar | Bin .../gradle/wrapper/gradle-wrapper.properties | 0 .../bindings/java/gradlew | 0 .../bindings/java/gradlew.bat | 0 .../bindings/java/settings.gradle | 0 .../wedpr/sdk/jni/jmh/BenchmarkMain.java | 0 .../wedpr/sdk/jni/jmh/PaillierBenchmark.java | 0 .../bindings/java/src/main/c/CMakeLists.txt | 0 .../bindings/java/src/main/c/jni/Common.cpp | 0 .../bindings/java/src/main/c/jni/Common.h | 0 .../java/src/main/c/jni/JNIException.cpp | 0 .../java/src/main/c/jni/JNIException.h | 0 ...om_webank_wedpr_sdk_jni_crypto_FastOre.cpp | 0 .../com_webank_wedpr_sdk_jni_crypto_FastOre.h | 0 ...dpr_sdk_jni_crypto_SymmetricEncryption.cpp | 0 ...wedpr_sdk_jni_crypto_SymmetricEncryption.h | 0 ...k_wedpr_sdk_jni_homo_NativeFloatingIhc.cpp | 0 ...ank_wedpr_sdk_jni_homo_NativeFloatingIhc.h | 0 ...k_jni_homo_NativeFloatingPointPaillier.cpp | 0 ...sdk_jni_homo_NativeFloatingPointPaillier.h | 0 .../com_webank_wedpr_sdk_jni_homo_NativeIhc.h | 0 ...bank_wedpr_sdk_jni_homo_NativePaillier.cpp | 0 ...webank_wedpr_sdk_jni_homo_NativePaillier.h | 0 .../webank/wedpr/sdk/demo/GenerateKeys.java | 0 .../sdk/jni/codec/FloatingPointNumber.java | 0 .../wedpr/sdk/jni/codec/NumberCodec.java | 0 .../sdk/jni/codec/NumberCodecException.java | 0 .../wedpr/sdk/jni/codec/NumberCodecImpl.java | 0 .../wedpr/sdk/jni/common/JniException.java | 0 .../wedpr/sdk/jni/common/JniLibLoader.java | 0 .../wedpr/sdk/jni/common/Utilities.java | 0 .../webank/wedpr/sdk/jni/crypto/FastOre.java | 0 .../sdk/jni/crypto/SymmetricEncryption.java | 0 .../wedpr/sdk/jni/homo/NativeFloatingIhc.java | 0 .../jni/homo/NativeFloatingPointPaillier.java | 0 .../wedpr/sdk/jni/homo/NativePaillier.java | 0 .../resources/META-INF/native/win/file.list | 0 .../sdk/jni/test/NativeFloatingIhcTest.java | 0 .../test/NativeFloatingPointPaillierTest.java | 0 .../sdk/jni/test/NativePaillierTest.java | 0 .../wedpr/sdk/jni/test/NumberCodecTest.java | 0 .../sdk/jni/test/SymmetricEncryptionTest.java | 0 .../ppc-crypto-c-sdk/CMakeLists.txt | 9 +++++++ .../ppc-crypto-c-sdk/fast_ore.cpp | 0 .../ppc-crypto-c-sdk/fast_ore.h | 0 .../ppc-crypto-c-sdk/floating_point_ihc.cpp | 0 .../ppc-crypto-c-sdk/floating_point_ihc.h | 0 .../floating_point_paillier.cpp | 0 .../floating_point_paillier.h | 0 .../ppc-crypto-c-sdk/homo_ihc.cpp | 0 .../ppc-crypto-c-sdk/homo_ihc.h | 0 .../ppc-crypto-c-sdk/homo_paillier.cpp | 0 .../ppc-crypto-c-sdk/homo_paillier.h | 0 .../ppc-crypto-c-sdk/symmetric_encryption.cpp | 0 .../ppc-crypto-c-sdk/symmetric_encryption.h | 0 .../ppc-crypto-c-sdk/utils/error.cpp | 0 .../ppc-crypto-c-sdk/utils/error.h | 0 .../ppc-crypto-c-sdk/utils/utilities.cpp | 0 .../ppc-crypto-c-sdk/utils/utilities.h | 0 .../tests/CMakeLists.txt | 0 .../tests/TestFastOre.cpp | 0 .../tests/TestHomoPaillier.cpp | 0 .../tests/main.cpp | 0 66 files changed, 24 insertions(+), 23 deletions(-) delete mode 100644 cpp/ppc-crypto-c-sdk/CMakeLists.txt create mode 100644 cpp/wedpr-component-c-sdk/CMakeLists.txt rename cpp/{ppc-crypto-c-sdk => wedpr-component-c-sdk}/bindings/java/build.gradle (100%) rename cpp/{ppc-crypto-c-sdk => wedpr-component-c-sdk}/bindings/java/gradle/wrapper/gradle-wrapper.jar (100%) rename cpp/{ppc-crypto-c-sdk => wedpr-component-c-sdk}/bindings/java/gradle/wrapper/gradle-wrapper.properties (100%) rename cpp/{ppc-crypto-c-sdk => wedpr-component-c-sdk}/bindings/java/gradlew (100%) rename cpp/{ppc-crypto-c-sdk => wedpr-component-c-sdk}/bindings/java/gradlew.bat (100%) rename cpp/{ppc-crypto-c-sdk => wedpr-component-c-sdk}/bindings/java/settings.gradle (100%) rename cpp/{ppc-crypto-c-sdk => wedpr-component-c-sdk}/bindings/java/src/jmh/java/com/webank/wedpr/sdk/jni/jmh/BenchmarkMain.java (100%) rename cpp/{ppc-crypto-c-sdk => wedpr-component-c-sdk}/bindings/java/src/jmh/java/com/webank/wedpr/sdk/jni/jmh/PaillierBenchmark.java (100%) rename cpp/{ppc-crypto-c-sdk => wedpr-component-c-sdk}/bindings/java/src/main/c/CMakeLists.txt (100%) rename cpp/{ppc-crypto-c-sdk => wedpr-component-c-sdk}/bindings/java/src/main/c/jni/Common.cpp (100%) rename cpp/{ppc-crypto-c-sdk => wedpr-component-c-sdk}/bindings/java/src/main/c/jni/Common.h (100%) rename cpp/{ppc-crypto-c-sdk => wedpr-component-c-sdk}/bindings/java/src/main/c/jni/JNIException.cpp (100%) rename cpp/{ppc-crypto-c-sdk => wedpr-component-c-sdk}/bindings/java/src/main/c/jni/JNIException.h (100%) rename cpp/{ppc-crypto-c-sdk => wedpr-component-c-sdk}/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_crypto_FastOre.cpp (100%) rename cpp/{ppc-crypto-c-sdk => wedpr-component-c-sdk}/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_crypto_FastOre.h (100%) rename cpp/{ppc-crypto-c-sdk => wedpr-component-c-sdk}/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_crypto_SymmetricEncryption.cpp (100%) rename cpp/{ppc-crypto-c-sdk => wedpr-component-c-sdk}/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_crypto_SymmetricEncryption.h (100%) rename cpp/{ppc-crypto-c-sdk => wedpr-component-c-sdk}/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativeFloatingIhc.cpp (100%) rename cpp/{ppc-crypto-c-sdk => wedpr-component-c-sdk}/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativeFloatingIhc.h (100%) rename cpp/{ppc-crypto-c-sdk => wedpr-component-c-sdk}/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier.cpp (100%) rename cpp/{ppc-crypto-c-sdk => wedpr-component-c-sdk}/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier.h (100%) rename cpp/{ppc-crypto-c-sdk => wedpr-component-c-sdk}/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativeIhc.h (100%) rename cpp/{ppc-crypto-c-sdk => wedpr-component-c-sdk}/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativePaillier.cpp (100%) rename cpp/{ppc-crypto-c-sdk => wedpr-component-c-sdk}/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativePaillier.h (100%) rename cpp/{ppc-crypto-c-sdk => wedpr-component-c-sdk}/bindings/java/src/main/java/com/webank/wedpr/sdk/demo/GenerateKeys.java (100%) rename cpp/{ppc-crypto-c-sdk => wedpr-component-c-sdk}/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/codec/FloatingPointNumber.java (100%) rename cpp/{ppc-crypto-c-sdk => wedpr-component-c-sdk}/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/codec/NumberCodec.java (100%) rename cpp/{ppc-crypto-c-sdk => wedpr-component-c-sdk}/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/codec/NumberCodecException.java (100%) rename cpp/{ppc-crypto-c-sdk => wedpr-component-c-sdk}/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/codec/NumberCodecImpl.java (100%) rename cpp/{ppc-crypto-c-sdk => wedpr-component-c-sdk}/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/common/JniException.java (100%) rename cpp/{ppc-crypto-c-sdk => wedpr-component-c-sdk}/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/common/JniLibLoader.java (100%) rename cpp/{ppc-crypto-c-sdk => wedpr-component-c-sdk}/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/common/Utilities.java (100%) rename cpp/{ppc-crypto-c-sdk => wedpr-component-c-sdk}/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/crypto/FastOre.java (100%) rename cpp/{ppc-crypto-c-sdk => wedpr-component-c-sdk}/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/crypto/SymmetricEncryption.java (100%) rename cpp/{ppc-crypto-c-sdk => wedpr-component-c-sdk}/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/homo/NativeFloatingIhc.java (100%) rename cpp/{ppc-crypto-c-sdk => wedpr-component-c-sdk}/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/homo/NativeFloatingPointPaillier.java (100%) rename cpp/{ppc-crypto-c-sdk => wedpr-component-c-sdk}/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/homo/NativePaillier.java (100%) rename cpp/{ppc-crypto-c-sdk => wedpr-component-c-sdk}/bindings/java/src/main/resources/META-INF/native/win/file.list (100%) rename cpp/{ppc-crypto-c-sdk => wedpr-component-c-sdk}/bindings/java/src/test/java/com/webank/wedpr/sdk/jni/test/NativeFloatingIhcTest.java (100%) rename cpp/{ppc-crypto-c-sdk => wedpr-component-c-sdk}/bindings/java/src/test/java/com/webank/wedpr/sdk/jni/test/NativeFloatingPointPaillierTest.java (100%) rename cpp/{ppc-crypto-c-sdk => wedpr-component-c-sdk}/bindings/java/src/test/java/com/webank/wedpr/sdk/jni/test/NativePaillierTest.java (100%) rename cpp/{ppc-crypto-c-sdk => wedpr-component-c-sdk}/bindings/java/src/test/java/com/webank/wedpr/sdk/jni/test/NumberCodecTest.java (100%) rename cpp/{ppc-crypto-c-sdk => wedpr-component-c-sdk}/bindings/java/src/test/java/com/webank/wedpr/sdk/jni/test/SymmetricEncryptionTest.java (100%) create mode 100644 cpp/wedpr-component-c-sdk/ppc-crypto-c-sdk/CMakeLists.txt rename cpp/{ppc-crypto-c-sdk => wedpr-component-c-sdk}/ppc-crypto-c-sdk/fast_ore.cpp (100%) rename cpp/{ppc-crypto-c-sdk => wedpr-component-c-sdk}/ppc-crypto-c-sdk/fast_ore.h (100%) rename cpp/{ppc-crypto-c-sdk => wedpr-component-c-sdk}/ppc-crypto-c-sdk/floating_point_ihc.cpp (100%) rename cpp/{ppc-crypto-c-sdk => wedpr-component-c-sdk}/ppc-crypto-c-sdk/floating_point_ihc.h (100%) rename cpp/{ppc-crypto-c-sdk => wedpr-component-c-sdk}/ppc-crypto-c-sdk/floating_point_paillier.cpp (100%) rename cpp/{ppc-crypto-c-sdk => wedpr-component-c-sdk}/ppc-crypto-c-sdk/floating_point_paillier.h (100%) rename cpp/{ppc-crypto-c-sdk => wedpr-component-c-sdk}/ppc-crypto-c-sdk/homo_ihc.cpp (100%) rename cpp/{ppc-crypto-c-sdk => wedpr-component-c-sdk}/ppc-crypto-c-sdk/homo_ihc.h (100%) rename cpp/{ppc-crypto-c-sdk => wedpr-component-c-sdk}/ppc-crypto-c-sdk/homo_paillier.cpp (100%) rename cpp/{ppc-crypto-c-sdk => wedpr-component-c-sdk}/ppc-crypto-c-sdk/homo_paillier.h (100%) rename cpp/{ppc-crypto-c-sdk => wedpr-component-c-sdk}/ppc-crypto-c-sdk/symmetric_encryption.cpp (100%) rename cpp/{ppc-crypto-c-sdk => wedpr-component-c-sdk}/ppc-crypto-c-sdk/symmetric_encryption.h (100%) rename cpp/{ppc-crypto-c-sdk => wedpr-component-c-sdk}/ppc-crypto-c-sdk/utils/error.cpp (100%) rename cpp/{ppc-crypto-c-sdk => wedpr-component-c-sdk}/ppc-crypto-c-sdk/utils/error.h (100%) rename cpp/{ppc-crypto-c-sdk => wedpr-component-c-sdk}/ppc-crypto-c-sdk/utils/utilities.cpp (100%) rename cpp/{ppc-crypto-c-sdk => wedpr-component-c-sdk}/ppc-crypto-c-sdk/utils/utilities.h (100%) rename cpp/{ppc-crypto-c-sdk => wedpr-component-c-sdk}/tests/CMakeLists.txt (100%) rename cpp/{ppc-crypto-c-sdk => wedpr-component-c-sdk}/tests/TestFastOre.cpp (100%) rename cpp/{ppc-crypto-c-sdk => wedpr-component-c-sdk}/tests/TestHomoPaillier.cpp (100%) rename cpp/{ppc-crypto-c-sdk => wedpr-component-c-sdk}/tests/main.cpp (100%) diff --git a/cpp/ppc-crypto-c-sdk/CMakeLists.txt b/cpp/ppc-crypto-c-sdk/CMakeLists.txt deleted file mode 100644 index e55eb59d..00000000 --- a/cpp/ppc-crypto-c-sdk/CMakeLists.txt +++ /dev/null @@ -1,23 +0,0 @@ -project(ppc-crypto-c-sdk VERSION ${VERSION}) - -# export windows dll symbol -if(WIN32) - message(STATUS "Compile on Windows") - set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS "ON") -endif() - -file(GLOB_RECURSE SRCS ppc-crypto-c-sdk/*.cpp ppc-crypto-c-sdk/*.c) - -# generate the static lib -add_library(${PPC_CRYPTO_C_SDK_STATIC_TARGET} ${SRCS}) -target_link_libraries(${PPC_CRYPTO_C_SDK_STATIC_TARGET} PUBLIC ${PAILLIER_TARGET} ${IHC_TARGET} ${CRYPTO_CORE_TARGET}) - -# generate the shared lib -add_library(${PPC_CRYPTO_C_SDK_TARGET} SHARED ${SRCS}) -target_link_libraries(${PPC_CRYPTO_C_SDK_TARGET} PUBLIC ${PAILLIER_TARGET} ${IHC_TARGET} ${CRYPTO_CORE_TARGET}) - -if (TESTS) - enable_testing() - set(CTEST_OUTPUT_ON_FAILURE TRUE) - add_subdirectory(tests) -endif() \ No newline at end of file diff --git a/cpp/wedpr-component-c-sdk/CMakeLists.txt b/cpp/wedpr-component-c-sdk/CMakeLists.txt new file mode 100644 index 00000000..474f39c6 --- /dev/null +++ b/cpp/wedpr-component-c-sdk/CMakeLists.txt @@ -0,0 +1,15 @@ +project(wedpr-component-c-sdk VERSION ${VERSION}) + +# export windows dll symbol +if(WIN32) + message(STATUS "Compile on Windows") + set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS "ON") +endif() +add_subdirectory(ppc-crypto-c-sdk) +add_subdirectory(ppc-front-c-sdk) + +if (TESTS) + enable_testing() + set(CTEST_OUTPUT_ON_FAILURE TRUE) + add_subdirectory(tests) +endif() \ No newline at end of file diff --git a/cpp/ppc-crypto-c-sdk/bindings/java/build.gradle b/cpp/wedpr-component-c-sdk/bindings/java/build.gradle similarity index 100% rename from cpp/ppc-crypto-c-sdk/bindings/java/build.gradle rename to cpp/wedpr-component-c-sdk/bindings/java/build.gradle diff --git a/cpp/ppc-crypto-c-sdk/bindings/java/gradle/wrapper/gradle-wrapper.jar b/cpp/wedpr-component-c-sdk/bindings/java/gradle/wrapper/gradle-wrapper.jar similarity index 100% rename from cpp/ppc-crypto-c-sdk/bindings/java/gradle/wrapper/gradle-wrapper.jar rename to cpp/wedpr-component-c-sdk/bindings/java/gradle/wrapper/gradle-wrapper.jar diff --git a/cpp/ppc-crypto-c-sdk/bindings/java/gradle/wrapper/gradle-wrapper.properties b/cpp/wedpr-component-c-sdk/bindings/java/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from cpp/ppc-crypto-c-sdk/bindings/java/gradle/wrapper/gradle-wrapper.properties rename to cpp/wedpr-component-c-sdk/bindings/java/gradle/wrapper/gradle-wrapper.properties diff --git a/cpp/ppc-crypto-c-sdk/bindings/java/gradlew b/cpp/wedpr-component-c-sdk/bindings/java/gradlew similarity index 100% rename from cpp/ppc-crypto-c-sdk/bindings/java/gradlew rename to cpp/wedpr-component-c-sdk/bindings/java/gradlew diff --git a/cpp/ppc-crypto-c-sdk/bindings/java/gradlew.bat b/cpp/wedpr-component-c-sdk/bindings/java/gradlew.bat similarity index 100% rename from cpp/ppc-crypto-c-sdk/bindings/java/gradlew.bat rename to cpp/wedpr-component-c-sdk/bindings/java/gradlew.bat diff --git a/cpp/ppc-crypto-c-sdk/bindings/java/settings.gradle b/cpp/wedpr-component-c-sdk/bindings/java/settings.gradle similarity index 100% rename from cpp/ppc-crypto-c-sdk/bindings/java/settings.gradle rename to cpp/wedpr-component-c-sdk/bindings/java/settings.gradle diff --git a/cpp/ppc-crypto-c-sdk/bindings/java/src/jmh/java/com/webank/wedpr/sdk/jni/jmh/BenchmarkMain.java b/cpp/wedpr-component-c-sdk/bindings/java/src/jmh/java/com/webank/wedpr/sdk/jni/jmh/BenchmarkMain.java similarity index 100% rename from cpp/ppc-crypto-c-sdk/bindings/java/src/jmh/java/com/webank/wedpr/sdk/jni/jmh/BenchmarkMain.java rename to cpp/wedpr-component-c-sdk/bindings/java/src/jmh/java/com/webank/wedpr/sdk/jni/jmh/BenchmarkMain.java diff --git a/cpp/ppc-crypto-c-sdk/bindings/java/src/jmh/java/com/webank/wedpr/sdk/jni/jmh/PaillierBenchmark.java b/cpp/wedpr-component-c-sdk/bindings/java/src/jmh/java/com/webank/wedpr/sdk/jni/jmh/PaillierBenchmark.java similarity index 100% rename from cpp/ppc-crypto-c-sdk/bindings/java/src/jmh/java/com/webank/wedpr/sdk/jni/jmh/PaillierBenchmark.java rename to cpp/wedpr-component-c-sdk/bindings/java/src/jmh/java/com/webank/wedpr/sdk/jni/jmh/PaillierBenchmark.java diff --git a/cpp/ppc-crypto-c-sdk/bindings/java/src/main/c/CMakeLists.txt b/cpp/wedpr-component-c-sdk/bindings/java/src/main/c/CMakeLists.txt similarity index 100% rename from cpp/ppc-crypto-c-sdk/bindings/java/src/main/c/CMakeLists.txt rename to cpp/wedpr-component-c-sdk/bindings/java/src/main/c/CMakeLists.txt diff --git a/cpp/ppc-crypto-c-sdk/bindings/java/src/main/c/jni/Common.cpp b/cpp/wedpr-component-c-sdk/bindings/java/src/main/c/jni/Common.cpp similarity index 100% rename from cpp/ppc-crypto-c-sdk/bindings/java/src/main/c/jni/Common.cpp rename to cpp/wedpr-component-c-sdk/bindings/java/src/main/c/jni/Common.cpp diff --git a/cpp/ppc-crypto-c-sdk/bindings/java/src/main/c/jni/Common.h b/cpp/wedpr-component-c-sdk/bindings/java/src/main/c/jni/Common.h similarity index 100% rename from cpp/ppc-crypto-c-sdk/bindings/java/src/main/c/jni/Common.h rename to cpp/wedpr-component-c-sdk/bindings/java/src/main/c/jni/Common.h diff --git a/cpp/ppc-crypto-c-sdk/bindings/java/src/main/c/jni/JNIException.cpp b/cpp/wedpr-component-c-sdk/bindings/java/src/main/c/jni/JNIException.cpp similarity index 100% rename from cpp/ppc-crypto-c-sdk/bindings/java/src/main/c/jni/JNIException.cpp rename to cpp/wedpr-component-c-sdk/bindings/java/src/main/c/jni/JNIException.cpp diff --git a/cpp/ppc-crypto-c-sdk/bindings/java/src/main/c/jni/JNIException.h b/cpp/wedpr-component-c-sdk/bindings/java/src/main/c/jni/JNIException.h similarity index 100% rename from cpp/ppc-crypto-c-sdk/bindings/java/src/main/c/jni/JNIException.h rename to cpp/wedpr-component-c-sdk/bindings/java/src/main/c/jni/JNIException.h diff --git a/cpp/ppc-crypto-c-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_crypto_FastOre.cpp b/cpp/wedpr-component-c-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_crypto_FastOre.cpp similarity index 100% rename from cpp/ppc-crypto-c-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_crypto_FastOre.cpp rename to cpp/wedpr-component-c-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_crypto_FastOre.cpp diff --git a/cpp/ppc-crypto-c-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_crypto_FastOre.h b/cpp/wedpr-component-c-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_crypto_FastOre.h similarity index 100% rename from cpp/ppc-crypto-c-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_crypto_FastOre.h rename to cpp/wedpr-component-c-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_crypto_FastOre.h diff --git a/cpp/ppc-crypto-c-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_crypto_SymmetricEncryption.cpp b/cpp/wedpr-component-c-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_crypto_SymmetricEncryption.cpp similarity index 100% rename from cpp/ppc-crypto-c-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_crypto_SymmetricEncryption.cpp rename to cpp/wedpr-component-c-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_crypto_SymmetricEncryption.cpp diff --git a/cpp/ppc-crypto-c-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_crypto_SymmetricEncryption.h b/cpp/wedpr-component-c-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_crypto_SymmetricEncryption.h similarity index 100% rename from cpp/ppc-crypto-c-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_crypto_SymmetricEncryption.h rename to cpp/wedpr-component-c-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_crypto_SymmetricEncryption.h diff --git a/cpp/ppc-crypto-c-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativeFloatingIhc.cpp b/cpp/wedpr-component-c-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativeFloatingIhc.cpp similarity index 100% rename from cpp/ppc-crypto-c-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativeFloatingIhc.cpp rename to cpp/wedpr-component-c-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativeFloatingIhc.cpp diff --git a/cpp/ppc-crypto-c-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativeFloatingIhc.h b/cpp/wedpr-component-c-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativeFloatingIhc.h similarity index 100% rename from cpp/ppc-crypto-c-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativeFloatingIhc.h rename to cpp/wedpr-component-c-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativeFloatingIhc.h diff --git a/cpp/ppc-crypto-c-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier.cpp b/cpp/wedpr-component-c-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier.cpp similarity index 100% rename from cpp/ppc-crypto-c-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier.cpp rename to cpp/wedpr-component-c-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier.cpp diff --git a/cpp/ppc-crypto-c-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier.h b/cpp/wedpr-component-c-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier.h similarity index 100% rename from cpp/ppc-crypto-c-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier.h rename to cpp/wedpr-component-c-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier.h diff --git a/cpp/ppc-crypto-c-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativeIhc.h b/cpp/wedpr-component-c-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativeIhc.h similarity index 100% rename from cpp/ppc-crypto-c-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativeIhc.h rename to cpp/wedpr-component-c-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativeIhc.h diff --git a/cpp/ppc-crypto-c-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativePaillier.cpp b/cpp/wedpr-component-c-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativePaillier.cpp similarity index 100% rename from cpp/ppc-crypto-c-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativePaillier.cpp rename to cpp/wedpr-component-c-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativePaillier.cpp diff --git a/cpp/ppc-crypto-c-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativePaillier.h b/cpp/wedpr-component-c-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativePaillier.h similarity index 100% rename from cpp/ppc-crypto-c-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativePaillier.h rename to cpp/wedpr-component-c-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativePaillier.h diff --git a/cpp/ppc-crypto-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/demo/GenerateKeys.java b/cpp/wedpr-component-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/demo/GenerateKeys.java similarity index 100% rename from cpp/ppc-crypto-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/demo/GenerateKeys.java rename to cpp/wedpr-component-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/demo/GenerateKeys.java diff --git a/cpp/ppc-crypto-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/codec/FloatingPointNumber.java b/cpp/wedpr-component-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/codec/FloatingPointNumber.java similarity index 100% rename from cpp/ppc-crypto-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/codec/FloatingPointNumber.java rename to cpp/wedpr-component-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/codec/FloatingPointNumber.java diff --git a/cpp/ppc-crypto-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/codec/NumberCodec.java b/cpp/wedpr-component-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/codec/NumberCodec.java similarity index 100% rename from cpp/ppc-crypto-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/codec/NumberCodec.java rename to cpp/wedpr-component-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/codec/NumberCodec.java diff --git a/cpp/ppc-crypto-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/codec/NumberCodecException.java b/cpp/wedpr-component-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/codec/NumberCodecException.java similarity index 100% rename from cpp/ppc-crypto-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/codec/NumberCodecException.java rename to cpp/wedpr-component-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/codec/NumberCodecException.java diff --git a/cpp/ppc-crypto-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/codec/NumberCodecImpl.java b/cpp/wedpr-component-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/codec/NumberCodecImpl.java similarity index 100% rename from cpp/ppc-crypto-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/codec/NumberCodecImpl.java rename to cpp/wedpr-component-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/codec/NumberCodecImpl.java diff --git a/cpp/ppc-crypto-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/common/JniException.java b/cpp/wedpr-component-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/common/JniException.java similarity index 100% rename from cpp/ppc-crypto-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/common/JniException.java rename to cpp/wedpr-component-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/common/JniException.java diff --git a/cpp/ppc-crypto-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/common/JniLibLoader.java b/cpp/wedpr-component-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/common/JniLibLoader.java similarity index 100% rename from cpp/ppc-crypto-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/common/JniLibLoader.java rename to cpp/wedpr-component-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/common/JniLibLoader.java diff --git a/cpp/ppc-crypto-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/common/Utilities.java b/cpp/wedpr-component-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/common/Utilities.java similarity index 100% rename from cpp/ppc-crypto-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/common/Utilities.java rename to cpp/wedpr-component-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/common/Utilities.java diff --git a/cpp/ppc-crypto-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/crypto/FastOre.java b/cpp/wedpr-component-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/crypto/FastOre.java similarity index 100% rename from cpp/ppc-crypto-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/crypto/FastOre.java rename to cpp/wedpr-component-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/crypto/FastOre.java diff --git a/cpp/ppc-crypto-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/crypto/SymmetricEncryption.java b/cpp/wedpr-component-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/crypto/SymmetricEncryption.java similarity index 100% rename from cpp/ppc-crypto-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/crypto/SymmetricEncryption.java rename to cpp/wedpr-component-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/crypto/SymmetricEncryption.java diff --git a/cpp/ppc-crypto-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/homo/NativeFloatingIhc.java b/cpp/wedpr-component-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/homo/NativeFloatingIhc.java similarity index 100% rename from cpp/ppc-crypto-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/homo/NativeFloatingIhc.java rename to cpp/wedpr-component-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/homo/NativeFloatingIhc.java diff --git a/cpp/ppc-crypto-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/homo/NativeFloatingPointPaillier.java b/cpp/wedpr-component-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/homo/NativeFloatingPointPaillier.java similarity index 100% rename from cpp/ppc-crypto-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/homo/NativeFloatingPointPaillier.java rename to cpp/wedpr-component-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/homo/NativeFloatingPointPaillier.java diff --git a/cpp/ppc-crypto-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/homo/NativePaillier.java b/cpp/wedpr-component-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/homo/NativePaillier.java similarity index 100% rename from cpp/ppc-crypto-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/homo/NativePaillier.java rename to cpp/wedpr-component-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/homo/NativePaillier.java diff --git a/cpp/ppc-crypto-c-sdk/bindings/java/src/main/resources/META-INF/native/win/file.list b/cpp/wedpr-component-c-sdk/bindings/java/src/main/resources/META-INF/native/win/file.list similarity index 100% rename from cpp/ppc-crypto-c-sdk/bindings/java/src/main/resources/META-INF/native/win/file.list rename to cpp/wedpr-component-c-sdk/bindings/java/src/main/resources/META-INF/native/win/file.list diff --git a/cpp/ppc-crypto-c-sdk/bindings/java/src/test/java/com/webank/wedpr/sdk/jni/test/NativeFloatingIhcTest.java b/cpp/wedpr-component-c-sdk/bindings/java/src/test/java/com/webank/wedpr/sdk/jni/test/NativeFloatingIhcTest.java similarity index 100% rename from cpp/ppc-crypto-c-sdk/bindings/java/src/test/java/com/webank/wedpr/sdk/jni/test/NativeFloatingIhcTest.java rename to cpp/wedpr-component-c-sdk/bindings/java/src/test/java/com/webank/wedpr/sdk/jni/test/NativeFloatingIhcTest.java diff --git a/cpp/ppc-crypto-c-sdk/bindings/java/src/test/java/com/webank/wedpr/sdk/jni/test/NativeFloatingPointPaillierTest.java b/cpp/wedpr-component-c-sdk/bindings/java/src/test/java/com/webank/wedpr/sdk/jni/test/NativeFloatingPointPaillierTest.java similarity index 100% rename from cpp/ppc-crypto-c-sdk/bindings/java/src/test/java/com/webank/wedpr/sdk/jni/test/NativeFloatingPointPaillierTest.java rename to cpp/wedpr-component-c-sdk/bindings/java/src/test/java/com/webank/wedpr/sdk/jni/test/NativeFloatingPointPaillierTest.java diff --git a/cpp/ppc-crypto-c-sdk/bindings/java/src/test/java/com/webank/wedpr/sdk/jni/test/NativePaillierTest.java b/cpp/wedpr-component-c-sdk/bindings/java/src/test/java/com/webank/wedpr/sdk/jni/test/NativePaillierTest.java similarity index 100% rename from cpp/ppc-crypto-c-sdk/bindings/java/src/test/java/com/webank/wedpr/sdk/jni/test/NativePaillierTest.java rename to cpp/wedpr-component-c-sdk/bindings/java/src/test/java/com/webank/wedpr/sdk/jni/test/NativePaillierTest.java diff --git a/cpp/ppc-crypto-c-sdk/bindings/java/src/test/java/com/webank/wedpr/sdk/jni/test/NumberCodecTest.java b/cpp/wedpr-component-c-sdk/bindings/java/src/test/java/com/webank/wedpr/sdk/jni/test/NumberCodecTest.java similarity index 100% rename from cpp/ppc-crypto-c-sdk/bindings/java/src/test/java/com/webank/wedpr/sdk/jni/test/NumberCodecTest.java rename to cpp/wedpr-component-c-sdk/bindings/java/src/test/java/com/webank/wedpr/sdk/jni/test/NumberCodecTest.java diff --git a/cpp/ppc-crypto-c-sdk/bindings/java/src/test/java/com/webank/wedpr/sdk/jni/test/SymmetricEncryptionTest.java b/cpp/wedpr-component-c-sdk/bindings/java/src/test/java/com/webank/wedpr/sdk/jni/test/SymmetricEncryptionTest.java similarity index 100% rename from cpp/ppc-crypto-c-sdk/bindings/java/src/test/java/com/webank/wedpr/sdk/jni/test/SymmetricEncryptionTest.java rename to cpp/wedpr-component-c-sdk/bindings/java/src/test/java/com/webank/wedpr/sdk/jni/test/SymmetricEncryptionTest.java diff --git a/cpp/wedpr-component-c-sdk/ppc-crypto-c-sdk/CMakeLists.txt b/cpp/wedpr-component-c-sdk/ppc-crypto-c-sdk/CMakeLists.txt new file mode 100644 index 00000000..61caffc7 --- /dev/null +++ b/cpp/wedpr-component-c-sdk/ppc-crypto-c-sdk/CMakeLists.txt @@ -0,0 +1,9 @@ +file(GLOB_RECURSE SRCS *.cpp *.c) + +# generate the static lib +add_library(${PPC_CRYPTO_C_SDK_STATIC_TARGET} ${SRCS}) +target_link_libraries(${PPC_CRYPTO_C_SDK_STATIC_TARGET} PUBLIC ${PAILLIER_TARGET} ${IHC_TARGET} ${CRYPTO_CORE_TARGET}) + +# generate the shared lib +add_library(${PPC_CRYPTO_C_SDK_TARGET} SHARED ${SRCS}) +target_link_libraries(${PPC_CRYPTO_C_SDK_TARGET} PUBLIC ${PAILLIER_TARGET} ${IHC_TARGET} ${CRYPTO_CORE_TARGET}) \ No newline at end of file diff --git a/cpp/ppc-crypto-c-sdk/ppc-crypto-c-sdk/fast_ore.cpp b/cpp/wedpr-component-c-sdk/ppc-crypto-c-sdk/fast_ore.cpp similarity index 100% rename from cpp/ppc-crypto-c-sdk/ppc-crypto-c-sdk/fast_ore.cpp rename to cpp/wedpr-component-c-sdk/ppc-crypto-c-sdk/fast_ore.cpp diff --git a/cpp/ppc-crypto-c-sdk/ppc-crypto-c-sdk/fast_ore.h b/cpp/wedpr-component-c-sdk/ppc-crypto-c-sdk/fast_ore.h similarity index 100% rename from cpp/ppc-crypto-c-sdk/ppc-crypto-c-sdk/fast_ore.h rename to cpp/wedpr-component-c-sdk/ppc-crypto-c-sdk/fast_ore.h diff --git a/cpp/ppc-crypto-c-sdk/ppc-crypto-c-sdk/floating_point_ihc.cpp b/cpp/wedpr-component-c-sdk/ppc-crypto-c-sdk/floating_point_ihc.cpp similarity index 100% rename from cpp/ppc-crypto-c-sdk/ppc-crypto-c-sdk/floating_point_ihc.cpp rename to cpp/wedpr-component-c-sdk/ppc-crypto-c-sdk/floating_point_ihc.cpp diff --git a/cpp/ppc-crypto-c-sdk/ppc-crypto-c-sdk/floating_point_ihc.h b/cpp/wedpr-component-c-sdk/ppc-crypto-c-sdk/floating_point_ihc.h similarity index 100% rename from cpp/ppc-crypto-c-sdk/ppc-crypto-c-sdk/floating_point_ihc.h rename to cpp/wedpr-component-c-sdk/ppc-crypto-c-sdk/floating_point_ihc.h diff --git a/cpp/ppc-crypto-c-sdk/ppc-crypto-c-sdk/floating_point_paillier.cpp b/cpp/wedpr-component-c-sdk/ppc-crypto-c-sdk/floating_point_paillier.cpp similarity index 100% rename from cpp/ppc-crypto-c-sdk/ppc-crypto-c-sdk/floating_point_paillier.cpp rename to cpp/wedpr-component-c-sdk/ppc-crypto-c-sdk/floating_point_paillier.cpp diff --git a/cpp/ppc-crypto-c-sdk/ppc-crypto-c-sdk/floating_point_paillier.h b/cpp/wedpr-component-c-sdk/ppc-crypto-c-sdk/floating_point_paillier.h similarity index 100% rename from cpp/ppc-crypto-c-sdk/ppc-crypto-c-sdk/floating_point_paillier.h rename to cpp/wedpr-component-c-sdk/ppc-crypto-c-sdk/floating_point_paillier.h diff --git a/cpp/ppc-crypto-c-sdk/ppc-crypto-c-sdk/homo_ihc.cpp b/cpp/wedpr-component-c-sdk/ppc-crypto-c-sdk/homo_ihc.cpp similarity index 100% rename from cpp/ppc-crypto-c-sdk/ppc-crypto-c-sdk/homo_ihc.cpp rename to cpp/wedpr-component-c-sdk/ppc-crypto-c-sdk/homo_ihc.cpp diff --git a/cpp/ppc-crypto-c-sdk/ppc-crypto-c-sdk/homo_ihc.h b/cpp/wedpr-component-c-sdk/ppc-crypto-c-sdk/homo_ihc.h similarity index 100% rename from cpp/ppc-crypto-c-sdk/ppc-crypto-c-sdk/homo_ihc.h rename to cpp/wedpr-component-c-sdk/ppc-crypto-c-sdk/homo_ihc.h diff --git a/cpp/ppc-crypto-c-sdk/ppc-crypto-c-sdk/homo_paillier.cpp b/cpp/wedpr-component-c-sdk/ppc-crypto-c-sdk/homo_paillier.cpp similarity index 100% rename from cpp/ppc-crypto-c-sdk/ppc-crypto-c-sdk/homo_paillier.cpp rename to cpp/wedpr-component-c-sdk/ppc-crypto-c-sdk/homo_paillier.cpp diff --git a/cpp/ppc-crypto-c-sdk/ppc-crypto-c-sdk/homo_paillier.h b/cpp/wedpr-component-c-sdk/ppc-crypto-c-sdk/homo_paillier.h similarity index 100% rename from cpp/ppc-crypto-c-sdk/ppc-crypto-c-sdk/homo_paillier.h rename to cpp/wedpr-component-c-sdk/ppc-crypto-c-sdk/homo_paillier.h diff --git a/cpp/ppc-crypto-c-sdk/ppc-crypto-c-sdk/symmetric_encryption.cpp b/cpp/wedpr-component-c-sdk/ppc-crypto-c-sdk/symmetric_encryption.cpp similarity index 100% rename from cpp/ppc-crypto-c-sdk/ppc-crypto-c-sdk/symmetric_encryption.cpp rename to cpp/wedpr-component-c-sdk/ppc-crypto-c-sdk/symmetric_encryption.cpp diff --git a/cpp/ppc-crypto-c-sdk/ppc-crypto-c-sdk/symmetric_encryption.h b/cpp/wedpr-component-c-sdk/ppc-crypto-c-sdk/symmetric_encryption.h similarity index 100% rename from cpp/ppc-crypto-c-sdk/ppc-crypto-c-sdk/symmetric_encryption.h rename to cpp/wedpr-component-c-sdk/ppc-crypto-c-sdk/symmetric_encryption.h diff --git a/cpp/ppc-crypto-c-sdk/ppc-crypto-c-sdk/utils/error.cpp b/cpp/wedpr-component-c-sdk/ppc-crypto-c-sdk/utils/error.cpp similarity index 100% rename from cpp/ppc-crypto-c-sdk/ppc-crypto-c-sdk/utils/error.cpp rename to cpp/wedpr-component-c-sdk/ppc-crypto-c-sdk/utils/error.cpp diff --git a/cpp/ppc-crypto-c-sdk/ppc-crypto-c-sdk/utils/error.h b/cpp/wedpr-component-c-sdk/ppc-crypto-c-sdk/utils/error.h similarity index 100% rename from cpp/ppc-crypto-c-sdk/ppc-crypto-c-sdk/utils/error.h rename to cpp/wedpr-component-c-sdk/ppc-crypto-c-sdk/utils/error.h diff --git a/cpp/ppc-crypto-c-sdk/ppc-crypto-c-sdk/utils/utilities.cpp b/cpp/wedpr-component-c-sdk/ppc-crypto-c-sdk/utils/utilities.cpp similarity index 100% rename from cpp/ppc-crypto-c-sdk/ppc-crypto-c-sdk/utils/utilities.cpp rename to cpp/wedpr-component-c-sdk/ppc-crypto-c-sdk/utils/utilities.cpp diff --git a/cpp/ppc-crypto-c-sdk/ppc-crypto-c-sdk/utils/utilities.h b/cpp/wedpr-component-c-sdk/ppc-crypto-c-sdk/utils/utilities.h similarity index 100% rename from cpp/ppc-crypto-c-sdk/ppc-crypto-c-sdk/utils/utilities.h rename to cpp/wedpr-component-c-sdk/ppc-crypto-c-sdk/utils/utilities.h diff --git a/cpp/ppc-crypto-c-sdk/tests/CMakeLists.txt b/cpp/wedpr-component-c-sdk/tests/CMakeLists.txt similarity index 100% rename from cpp/ppc-crypto-c-sdk/tests/CMakeLists.txt rename to cpp/wedpr-component-c-sdk/tests/CMakeLists.txt diff --git a/cpp/ppc-crypto-c-sdk/tests/TestFastOre.cpp b/cpp/wedpr-component-c-sdk/tests/TestFastOre.cpp similarity index 100% rename from cpp/ppc-crypto-c-sdk/tests/TestFastOre.cpp rename to cpp/wedpr-component-c-sdk/tests/TestFastOre.cpp diff --git a/cpp/ppc-crypto-c-sdk/tests/TestHomoPaillier.cpp b/cpp/wedpr-component-c-sdk/tests/TestHomoPaillier.cpp similarity index 100% rename from cpp/ppc-crypto-c-sdk/tests/TestHomoPaillier.cpp rename to cpp/wedpr-component-c-sdk/tests/TestHomoPaillier.cpp diff --git a/cpp/ppc-crypto-c-sdk/tests/main.cpp b/cpp/wedpr-component-c-sdk/tests/main.cpp similarity index 100% rename from cpp/ppc-crypto-c-sdk/tests/main.cpp rename to cpp/wedpr-component-c-sdk/tests/main.cpp From 4cad628f524bbe1232d2e72e8d82d184691d8e7c Mon Sep 17 00:00:00 2001 From: cyjseagull Date: Thu, 22 Aug 2024 22:19:18 +0800 Subject: [PATCH 5/9] add interface for wedpr-front-c-sdk --- .github/workflows/cpp_workflow.yml | 6 +- cpp/CMakeLists.txt | 17 ++- cpp/cmake/IncludeDirectories.cmake | 2 +- cpp/cmake/Options.cmake | 1 + cpp/cmake/TargetSettings.cmake | 14 ++- .../CMakeLists.txt | 6 +- .../bindings/java/build.gradle | 0 .../java/gradle/wrapper/gradle-wrapper.jar | Bin .../gradle/wrapper/gradle-wrapper.properties | 0 .../bindings/java/gradlew | 0 .../bindings/java/gradlew.bat | 0 .../bindings/java/settings.gradle | 0 .../wedpr/sdk/jni/jmh/BenchmarkMain.java | 0 .../wedpr/sdk/jni/jmh/PaillierBenchmark.java | 0 .../bindings/java/src/main/c/CMakeLists.txt | 0 .../bindings/java/src/main/c/jni/Common.cpp | 0 .../bindings/java/src/main/c/jni/Common.h | 0 .../java/src/main/c/jni/JNIException.cpp | 0 .../java/src/main/c/jni/JNIException.h | 0 ...om_webank_wedpr_sdk_jni_crypto_FastOre.cpp | 0 .../com_webank_wedpr_sdk_jni_crypto_FastOre.h | 0 ...dpr_sdk_jni_crypto_SymmetricEncryption.cpp | 0 ...wedpr_sdk_jni_crypto_SymmetricEncryption.h | 0 ...k_wedpr_sdk_jni_homo_NativeFloatingIhc.cpp | 0 ...ank_wedpr_sdk_jni_homo_NativeFloatingIhc.h | 0 ...k_jni_homo_NativeFloatingPointPaillier.cpp | 0 ...sdk_jni_homo_NativeFloatingPointPaillier.h | 0 .../com_webank_wedpr_sdk_jni_homo_NativeIhc.h | 0 ...bank_wedpr_sdk_jni_homo_NativePaillier.cpp | 0 ...webank_wedpr_sdk_jni_homo_NativePaillier.h | 0 .../webank/wedpr/sdk/demo/GenerateKeys.java | 0 .../sdk/jni/codec/FloatingPointNumber.java | 0 .../wedpr/sdk/jni/codec/NumberCodec.java | 0 .../sdk/jni/codec/NumberCodecException.java | 0 .../wedpr/sdk/jni/codec/NumberCodecImpl.java | 0 .../wedpr/sdk/jni/common/JniException.java | 0 .../wedpr/sdk/jni/common/JniLibLoader.java | 0 .../wedpr/sdk/jni/common/Utilities.java | 0 .../webank/wedpr/sdk/jni/crypto/FastOre.java | 0 .../sdk/jni/crypto/SymmetricEncryption.java | 0 .../wedpr/sdk/jni/homo/NativeFloatingIhc.java | 0 .../jni/homo/NativeFloatingPointPaillier.java | 0 .../wedpr/sdk/jni/homo/NativePaillier.java | 0 .../resources/META-INF/native/win/file.list | 0 .../sdk/jni/test/NativeFloatingIhcTest.java | 0 .../test/NativeFloatingPointPaillierTest.java | 0 .../sdk/jni/test/NativePaillierTest.java | 0 .../wedpr/sdk/jni/test/NumberCodecTest.java | 0 .../sdk/jni/test/SymmetricEncryptionTest.java | 0 .../ppc-crypto-c-sdk/CMakeLists.txt | 0 .../ppc-crypto-c-sdk/fast_ore.cpp | 0 .../ppc-crypto-c-sdk/fast_ore.h | 0 .../ppc-crypto-c-sdk/floating_point_ihc.cpp | 0 .../ppc-crypto-c-sdk/floating_point_ihc.h | 0 .../floating_point_paillier.cpp | 0 .../floating_point_paillier.h | 0 .../ppc-crypto-c-sdk/homo_ihc.cpp | 0 .../ppc-crypto-c-sdk/homo_ihc.h | 0 .../ppc-crypto-c-sdk/homo_paillier.cpp | 0 .../ppc-crypto-c-sdk/homo_paillier.h | 0 .../ppc-crypto-c-sdk/symmetric_encryption.cpp | 0 .../ppc-crypto-c-sdk/symmetric_encryption.h | 0 .../ppc-crypto-c-sdk/utils/error.cpp | 0 .../ppc-crypto-c-sdk/utils/error.h | 0 .../ppc-crypto-c-sdk/utils/utilities.cpp | 0 .../ppc-crypto-c-sdk/utils/utilities.h | 0 .../tests/CMakeLists.txt | 0 .../tests/TestFastOre.cpp | 0 .../tests/TestHomoPaillier.cpp | 0 .../tests/main.cpp | 0 .../wedpr-front-cpp-sdk/CMakeLists.txt | 9 ++ .../wedpr-front-cpp-sdk/wedpr_front_c.cpp | 92 ++++++++++++++++ .../wedpr-front-cpp-sdk/wedpr_front_c.h | 98 ++++++++++++++++++ .../wedpr-front-cpp-sdk/wedpr_front_common.h | 28 +++++ .../wedpr-front-cpp-sdk/wedpr_front_config.h | 56 ++++++++++ .../wedpr-front-cpp-sdk/wedpr_msg.h | 81 +++++++++++++++ 76 files changed, 398 insertions(+), 12 deletions(-) rename cpp/{wedpr-component-c-sdk => wedpr-component-sdk}/CMakeLists.txt (74%) rename cpp/{wedpr-component-c-sdk => wedpr-component-sdk}/bindings/java/build.gradle (100%) rename cpp/{wedpr-component-c-sdk => wedpr-component-sdk}/bindings/java/gradle/wrapper/gradle-wrapper.jar (100%) rename cpp/{wedpr-component-c-sdk => wedpr-component-sdk}/bindings/java/gradle/wrapper/gradle-wrapper.properties (100%) rename cpp/{wedpr-component-c-sdk => wedpr-component-sdk}/bindings/java/gradlew (100%) rename cpp/{wedpr-component-c-sdk => wedpr-component-sdk}/bindings/java/gradlew.bat (100%) rename cpp/{wedpr-component-c-sdk => wedpr-component-sdk}/bindings/java/settings.gradle (100%) rename cpp/{wedpr-component-c-sdk => wedpr-component-sdk}/bindings/java/src/jmh/java/com/webank/wedpr/sdk/jni/jmh/BenchmarkMain.java (100%) rename cpp/{wedpr-component-c-sdk => wedpr-component-sdk}/bindings/java/src/jmh/java/com/webank/wedpr/sdk/jni/jmh/PaillierBenchmark.java (100%) rename cpp/{wedpr-component-c-sdk => wedpr-component-sdk}/bindings/java/src/main/c/CMakeLists.txt (100%) rename cpp/{wedpr-component-c-sdk => wedpr-component-sdk}/bindings/java/src/main/c/jni/Common.cpp (100%) rename cpp/{wedpr-component-c-sdk => wedpr-component-sdk}/bindings/java/src/main/c/jni/Common.h (100%) rename cpp/{wedpr-component-c-sdk => wedpr-component-sdk}/bindings/java/src/main/c/jni/JNIException.cpp (100%) rename cpp/{wedpr-component-c-sdk => wedpr-component-sdk}/bindings/java/src/main/c/jni/JNIException.h (100%) rename cpp/{wedpr-component-c-sdk => wedpr-component-sdk}/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_crypto_FastOre.cpp (100%) rename cpp/{wedpr-component-c-sdk => wedpr-component-sdk}/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_crypto_FastOre.h (100%) rename cpp/{wedpr-component-c-sdk => wedpr-component-sdk}/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_crypto_SymmetricEncryption.cpp (100%) rename cpp/{wedpr-component-c-sdk => wedpr-component-sdk}/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_crypto_SymmetricEncryption.h (100%) rename cpp/{wedpr-component-c-sdk => wedpr-component-sdk}/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativeFloatingIhc.cpp (100%) rename cpp/{wedpr-component-c-sdk => wedpr-component-sdk}/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativeFloatingIhc.h (100%) rename cpp/{wedpr-component-c-sdk => wedpr-component-sdk}/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier.cpp (100%) rename cpp/{wedpr-component-c-sdk => wedpr-component-sdk}/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier.h (100%) rename cpp/{wedpr-component-c-sdk => wedpr-component-sdk}/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativeIhc.h (100%) rename cpp/{wedpr-component-c-sdk => wedpr-component-sdk}/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativePaillier.cpp (100%) rename cpp/{wedpr-component-c-sdk => wedpr-component-sdk}/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativePaillier.h (100%) rename cpp/{wedpr-component-c-sdk => wedpr-component-sdk}/bindings/java/src/main/java/com/webank/wedpr/sdk/demo/GenerateKeys.java (100%) rename cpp/{wedpr-component-c-sdk => wedpr-component-sdk}/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/codec/FloatingPointNumber.java (100%) rename cpp/{wedpr-component-c-sdk => wedpr-component-sdk}/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/codec/NumberCodec.java (100%) rename cpp/{wedpr-component-c-sdk => wedpr-component-sdk}/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/codec/NumberCodecException.java (100%) rename cpp/{wedpr-component-c-sdk => wedpr-component-sdk}/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/codec/NumberCodecImpl.java (100%) rename cpp/{wedpr-component-c-sdk => wedpr-component-sdk}/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/common/JniException.java (100%) rename cpp/{wedpr-component-c-sdk => wedpr-component-sdk}/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/common/JniLibLoader.java (100%) rename cpp/{wedpr-component-c-sdk => wedpr-component-sdk}/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/common/Utilities.java (100%) rename cpp/{wedpr-component-c-sdk => wedpr-component-sdk}/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/crypto/FastOre.java (100%) rename cpp/{wedpr-component-c-sdk => wedpr-component-sdk}/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/crypto/SymmetricEncryption.java (100%) rename cpp/{wedpr-component-c-sdk => wedpr-component-sdk}/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/homo/NativeFloatingIhc.java (100%) rename cpp/{wedpr-component-c-sdk => wedpr-component-sdk}/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/homo/NativeFloatingPointPaillier.java (100%) rename cpp/{wedpr-component-c-sdk => wedpr-component-sdk}/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/homo/NativePaillier.java (100%) rename cpp/{wedpr-component-c-sdk => wedpr-component-sdk}/bindings/java/src/main/resources/META-INF/native/win/file.list (100%) rename cpp/{wedpr-component-c-sdk => wedpr-component-sdk}/bindings/java/src/test/java/com/webank/wedpr/sdk/jni/test/NativeFloatingIhcTest.java (100%) rename cpp/{wedpr-component-c-sdk => wedpr-component-sdk}/bindings/java/src/test/java/com/webank/wedpr/sdk/jni/test/NativeFloatingPointPaillierTest.java (100%) rename cpp/{wedpr-component-c-sdk => wedpr-component-sdk}/bindings/java/src/test/java/com/webank/wedpr/sdk/jni/test/NativePaillierTest.java (100%) rename cpp/{wedpr-component-c-sdk => wedpr-component-sdk}/bindings/java/src/test/java/com/webank/wedpr/sdk/jni/test/NumberCodecTest.java (100%) rename cpp/{wedpr-component-c-sdk => wedpr-component-sdk}/bindings/java/src/test/java/com/webank/wedpr/sdk/jni/test/SymmetricEncryptionTest.java (100%) rename cpp/{wedpr-component-c-sdk => wedpr-component-sdk}/ppc-crypto-c-sdk/CMakeLists.txt (100%) rename cpp/{wedpr-component-c-sdk => wedpr-component-sdk}/ppc-crypto-c-sdk/fast_ore.cpp (100%) rename cpp/{wedpr-component-c-sdk => wedpr-component-sdk}/ppc-crypto-c-sdk/fast_ore.h (100%) rename cpp/{wedpr-component-c-sdk => wedpr-component-sdk}/ppc-crypto-c-sdk/floating_point_ihc.cpp (100%) rename cpp/{wedpr-component-c-sdk => wedpr-component-sdk}/ppc-crypto-c-sdk/floating_point_ihc.h (100%) rename cpp/{wedpr-component-c-sdk => wedpr-component-sdk}/ppc-crypto-c-sdk/floating_point_paillier.cpp (100%) rename cpp/{wedpr-component-c-sdk => wedpr-component-sdk}/ppc-crypto-c-sdk/floating_point_paillier.h (100%) rename cpp/{wedpr-component-c-sdk => wedpr-component-sdk}/ppc-crypto-c-sdk/homo_ihc.cpp (100%) rename cpp/{wedpr-component-c-sdk => wedpr-component-sdk}/ppc-crypto-c-sdk/homo_ihc.h (100%) rename cpp/{wedpr-component-c-sdk => wedpr-component-sdk}/ppc-crypto-c-sdk/homo_paillier.cpp (100%) rename cpp/{wedpr-component-c-sdk => wedpr-component-sdk}/ppc-crypto-c-sdk/homo_paillier.h (100%) rename cpp/{wedpr-component-c-sdk => wedpr-component-sdk}/ppc-crypto-c-sdk/symmetric_encryption.cpp (100%) rename cpp/{wedpr-component-c-sdk => wedpr-component-sdk}/ppc-crypto-c-sdk/symmetric_encryption.h (100%) rename cpp/{wedpr-component-c-sdk => wedpr-component-sdk}/ppc-crypto-c-sdk/utils/error.cpp (100%) rename cpp/{wedpr-component-c-sdk => wedpr-component-sdk}/ppc-crypto-c-sdk/utils/error.h (100%) rename cpp/{wedpr-component-c-sdk => wedpr-component-sdk}/ppc-crypto-c-sdk/utils/utilities.cpp (100%) rename cpp/{wedpr-component-c-sdk => wedpr-component-sdk}/ppc-crypto-c-sdk/utils/utilities.h (100%) rename cpp/{wedpr-component-c-sdk => wedpr-component-sdk}/tests/CMakeLists.txt (100%) rename cpp/{wedpr-component-c-sdk => wedpr-component-sdk}/tests/TestFastOre.cpp (100%) rename cpp/{wedpr-component-c-sdk => wedpr-component-sdk}/tests/TestHomoPaillier.cpp (100%) rename cpp/{wedpr-component-c-sdk => wedpr-component-sdk}/tests/main.cpp (100%) create mode 100644 cpp/wedpr-component-sdk/wedpr-front-cpp-sdk/CMakeLists.txt create mode 100644 cpp/wedpr-component-sdk/wedpr-front-cpp-sdk/wedpr_front_c.cpp create mode 100644 cpp/wedpr-component-sdk/wedpr-front-cpp-sdk/wedpr_front_c.h create mode 100644 cpp/wedpr-component-sdk/wedpr-front-cpp-sdk/wedpr_front_common.h create mode 100644 cpp/wedpr-component-sdk/wedpr-front-cpp-sdk/wedpr_front_config.h create mode 100644 cpp/wedpr-component-sdk/wedpr-front-cpp-sdk/wedpr_msg.h diff --git a/.github/workflows/cpp_workflow.yml b/.github/workflows/cpp_workflow.yml index 3ec7f9c1..ce682ad2 100644 --- a/.github/workflows/cpp_workflow.yml +++ b/.github/workflows/cpp_workflow.yml @@ -141,12 +141,12 @@ jobs: if: runner.os == 'macos' with: name: libppc-crypto-sdk-jni.dylib - path: ./cpp/ppc-crypto-c-sdk/bindings/java/src/main/resources/META-INF/native/libppc-crypto-sdk-jni.dylib + path: ./cpp/wedpr-component-sdk/bindings/java/src/main/resources/META-INF/native/libppc-crypto-sdk-jni.dylib - uses: actions/upload-artifact@v2 if: runner.os == 'Windows' with: name: libppc-crypto-sdk-jni.dylib - path: D:\a\WeDPR-Component\cpp\ppc-crypto-c-sdk\bindings\java\src\main\resources\META-INF\native\Release\ppc-crypto-sdk-jni.dll + path: D:\a\WeDPR-Component\cpp\wedpr-component-sdk\bindings\java\src\main\resources\META-INF\native\Release\ppc-crypto-sdk-jni.dll build_centos: name: build_centos full node @@ -221,4 +221,4 @@ jobs: - uses: actions/upload-artifact@v2 with: name: libppc-crypto-sdk-jni.so - path: ./cpp/ppc-crypto-c-sdk/bindings/java/src/main/resources/META-INF/native/libppc-crypto-sdk-jni.so \ No newline at end of file + path: ./cpp/wedpr-component-sdk/bindings/java/src/main/resources/META-INF/native/libppc-crypto-sdk-jni.so \ No newline at end of file diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index 698343ec..75586dc4 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -63,8 +63,8 @@ include(TargetSettings) include(Dependencies) ########### set the sources ########### -set(JNI_SOURCE_PATH ppc-crypto-c-sdk/bindings/java/src/main/c) -set(SDK_SOURCE_LIST ppc-homo ppc-crypto-core ppc-crypto-c-sdk ${JNI_SOURCE_PATH}) +set(JNI_SOURCE_PATH wedpr-component-sdk/bindings/java/src/main/c) +set(SDK_SOURCE_LIST ppc-homo ppc-crypto-core wedpr-component-sdk ${JNI_SOURCE_PATH}) # Note: the udf depends on mysql, not enabled in the full node mode set(UDF_SOURCE_LIST ${SDK_SOURCE_LIST} ppc-udf) set(ALL_SOURCE_LIST @@ -79,6 +79,19 @@ if(BUILD_CEM) set(CEM_SOURCE "ppc-cem") endif() +if(BUILD_WEDPR_TOOLKIT) + # fetch the python dependencies + option(FETCH_PYTHON_DEPS "Install python required modules if not available" ON) + message(STATUS "Python fetch dependencies: ${FETCH_PYTHON_DEPS}") + include(python) + if(WIN32) + message(STATUS "Getting SWIG for Windows: ...") + include(swig) + message(STATUS "Getting SWIG for Windows: ...DONE") + endif() + add_subdirectory(wedpr-toolkit-wrapper) +endif() + if(BUILD_ALL) add_sources("${ALL_SOURCE_LIST}") elseif(BUILD_UDF) diff --git a/cpp/cmake/IncludeDirectories.cmake b/cpp/cmake/IncludeDirectories.cmake index c22d3cce..7bd1fb86 100644 --- a/cpp/cmake/IncludeDirectories.cmake +++ b/cpp/cmake/IncludeDirectories.cmake @@ -2,7 +2,7 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR}) include_directories(${CMAKE_CURRENT_BINARY_DIR}) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/ppc-front) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/ppc-gateway) -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/ppc-crypto-c-sdk) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/wedpr-component-c-sdk) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/ppc-tars-protocol) set(VCPKG_INCLUDE_PATH "${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/include") diff --git a/cpp/cmake/Options.cmake b/cpp/cmake/Options.cmake index 1b4245ab..bf631af3 100644 --- a/cpp/cmake/Options.cmake +++ b/cpp/cmake/Options.cmake @@ -52,6 +52,7 @@ macro(configure_project) default_option(BUILD_ALL ON) default_option(BUILD_SDK OFF) default_option(BUILD_UDF OFF) + default_option(BUILD_WEDPR_TOOLKIT OFF) # Suffix like "-rc1" e.t.c. to append to versions wherever needed. if (NOT DEFINED VERSION_SUFFIX) diff --git a/cpp/cmake/TargetSettings.cmake b/cpp/cmake/TargetSettings.cmake index 61b17f44..da9e9626 100644 --- a/cpp/cmake/TargetSettings.cmake +++ b/cpp/cmake/TargetSettings.cmake @@ -85,17 +85,22 @@ if (ENABLE_CPU_FEATURES) set(CPU_FEATURES_LIB CpuFeatures::cpu_features) endif () -#====== ppc-crypto-c-sdk =========== +#====== wedpr-component-sdk =========== set(PPC_CRYPTO_C_SDK_STATIC_TARGET ppc-crypto-c-sdk-static) set(PPC_CRYPTO_C_SDK_TARGET ppc-crypto-c-sdk) +set(PPC_FRONT_C_SDK_STATIC_TARGET ppc-front-c-sdk-static) +set(PPC_FRONT_C_SDK_TARGET ppc-front-c-sdk) + # add suffix for arm if(ARCH_NATIVE) message(STATUS "Building arm architecture, CMAKE_HOST_SYSTEM_PROCESSOR => ${CMAKE_HOST_SYSTEM_PROCESSOR}") set(PPC_CRYPTO_C_SDK_STATIC_TARGET "ppc-crypto-c-sdk-aarch64") set(PPC_CRYPTO_C_SDK_TARGET "ppc-crypto-c-sdk-static-aarch64") + set(PPC_FRONT_C_SDK_STATIC_TARGET ppc-front-c-sdk-static-aarch64) + set(PPC_FRONT_C_SDK_TARGET ppc-front-c-sdk-aarch64) endif() -#====== ppc-crypto-c-sdk =========== +#====== wedpr-component-sdk =========== #====== ppc-crypto-sdk-jni =========== @@ -119,4 +124,7 @@ if(ARCH_NATIVE) endif() # ========== ppc-udf =========== -set(BOOST_UNIT_TEST Boost::unit_test_framework) \ No newline at end of file +set(BOOST_UNIT_TEST Boost::unit_test_framework) + +# ==== the swig wrapper ===== +set(WEDPR_PYTHON_TOOLKIT "wedpr_python_toolkit") \ No newline at end of file diff --git a/cpp/wedpr-component-c-sdk/CMakeLists.txt b/cpp/wedpr-component-sdk/CMakeLists.txt similarity index 74% rename from cpp/wedpr-component-c-sdk/CMakeLists.txt rename to cpp/wedpr-component-sdk/CMakeLists.txt index 474f39c6..8f389e80 100644 --- a/cpp/wedpr-component-c-sdk/CMakeLists.txt +++ b/cpp/wedpr-component-sdk/CMakeLists.txt @@ -1,4 +1,4 @@ -project(wedpr-component-c-sdk VERSION ${VERSION}) +project(wedpr-component-sdk VERSION ${VERSION}) # export windows dll symbol if(WIN32) @@ -6,10 +6,10 @@ if(WIN32) set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS "ON") endif() add_subdirectory(ppc-crypto-c-sdk) -add_subdirectory(ppc-front-c-sdk) +add_subdirectory(wedpr-front-cpp-sdk) if (TESTS) enable_testing() set(CTEST_OUTPUT_ON_FAILURE TRUE) add_subdirectory(tests) -endif() \ No newline at end of file +endif() diff --git a/cpp/wedpr-component-c-sdk/bindings/java/build.gradle b/cpp/wedpr-component-sdk/bindings/java/build.gradle similarity index 100% rename from cpp/wedpr-component-c-sdk/bindings/java/build.gradle rename to cpp/wedpr-component-sdk/bindings/java/build.gradle diff --git a/cpp/wedpr-component-c-sdk/bindings/java/gradle/wrapper/gradle-wrapper.jar b/cpp/wedpr-component-sdk/bindings/java/gradle/wrapper/gradle-wrapper.jar similarity index 100% rename from cpp/wedpr-component-c-sdk/bindings/java/gradle/wrapper/gradle-wrapper.jar rename to cpp/wedpr-component-sdk/bindings/java/gradle/wrapper/gradle-wrapper.jar diff --git a/cpp/wedpr-component-c-sdk/bindings/java/gradle/wrapper/gradle-wrapper.properties b/cpp/wedpr-component-sdk/bindings/java/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from cpp/wedpr-component-c-sdk/bindings/java/gradle/wrapper/gradle-wrapper.properties rename to cpp/wedpr-component-sdk/bindings/java/gradle/wrapper/gradle-wrapper.properties diff --git a/cpp/wedpr-component-c-sdk/bindings/java/gradlew b/cpp/wedpr-component-sdk/bindings/java/gradlew similarity index 100% rename from cpp/wedpr-component-c-sdk/bindings/java/gradlew rename to cpp/wedpr-component-sdk/bindings/java/gradlew diff --git a/cpp/wedpr-component-c-sdk/bindings/java/gradlew.bat b/cpp/wedpr-component-sdk/bindings/java/gradlew.bat similarity index 100% rename from cpp/wedpr-component-c-sdk/bindings/java/gradlew.bat rename to cpp/wedpr-component-sdk/bindings/java/gradlew.bat diff --git a/cpp/wedpr-component-c-sdk/bindings/java/settings.gradle b/cpp/wedpr-component-sdk/bindings/java/settings.gradle similarity index 100% rename from cpp/wedpr-component-c-sdk/bindings/java/settings.gradle rename to cpp/wedpr-component-sdk/bindings/java/settings.gradle diff --git a/cpp/wedpr-component-c-sdk/bindings/java/src/jmh/java/com/webank/wedpr/sdk/jni/jmh/BenchmarkMain.java b/cpp/wedpr-component-sdk/bindings/java/src/jmh/java/com/webank/wedpr/sdk/jni/jmh/BenchmarkMain.java similarity index 100% rename from cpp/wedpr-component-c-sdk/bindings/java/src/jmh/java/com/webank/wedpr/sdk/jni/jmh/BenchmarkMain.java rename to cpp/wedpr-component-sdk/bindings/java/src/jmh/java/com/webank/wedpr/sdk/jni/jmh/BenchmarkMain.java diff --git a/cpp/wedpr-component-c-sdk/bindings/java/src/jmh/java/com/webank/wedpr/sdk/jni/jmh/PaillierBenchmark.java b/cpp/wedpr-component-sdk/bindings/java/src/jmh/java/com/webank/wedpr/sdk/jni/jmh/PaillierBenchmark.java similarity index 100% rename from cpp/wedpr-component-c-sdk/bindings/java/src/jmh/java/com/webank/wedpr/sdk/jni/jmh/PaillierBenchmark.java rename to cpp/wedpr-component-sdk/bindings/java/src/jmh/java/com/webank/wedpr/sdk/jni/jmh/PaillierBenchmark.java diff --git a/cpp/wedpr-component-c-sdk/bindings/java/src/main/c/CMakeLists.txt b/cpp/wedpr-component-sdk/bindings/java/src/main/c/CMakeLists.txt similarity index 100% rename from cpp/wedpr-component-c-sdk/bindings/java/src/main/c/CMakeLists.txt rename to cpp/wedpr-component-sdk/bindings/java/src/main/c/CMakeLists.txt diff --git a/cpp/wedpr-component-c-sdk/bindings/java/src/main/c/jni/Common.cpp b/cpp/wedpr-component-sdk/bindings/java/src/main/c/jni/Common.cpp similarity index 100% rename from cpp/wedpr-component-c-sdk/bindings/java/src/main/c/jni/Common.cpp rename to cpp/wedpr-component-sdk/bindings/java/src/main/c/jni/Common.cpp diff --git a/cpp/wedpr-component-c-sdk/bindings/java/src/main/c/jni/Common.h b/cpp/wedpr-component-sdk/bindings/java/src/main/c/jni/Common.h similarity index 100% rename from cpp/wedpr-component-c-sdk/bindings/java/src/main/c/jni/Common.h rename to cpp/wedpr-component-sdk/bindings/java/src/main/c/jni/Common.h diff --git a/cpp/wedpr-component-c-sdk/bindings/java/src/main/c/jni/JNIException.cpp b/cpp/wedpr-component-sdk/bindings/java/src/main/c/jni/JNIException.cpp similarity index 100% rename from cpp/wedpr-component-c-sdk/bindings/java/src/main/c/jni/JNIException.cpp rename to cpp/wedpr-component-sdk/bindings/java/src/main/c/jni/JNIException.cpp diff --git a/cpp/wedpr-component-c-sdk/bindings/java/src/main/c/jni/JNIException.h b/cpp/wedpr-component-sdk/bindings/java/src/main/c/jni/JNIException.h similarity index 100% rename from cpp/wedpr-component-c-sdk/bindings/java/src/main/c/jni/JNIException.h rename to cpp/wedpr-component-sdk/bindings/java/src/main/c/jni/JNIException.h diff --git a/cpp/wedpr-component-c-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_crypto_FastOre.cpp b/cpp/wedpr-component-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_crypto_FastOre.cpp similarity index 100% rename from cpp/wedpr-component-c-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_crypto_FastOre.cpp rename to cpp/wedpr-component-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_crypto_FastOre.cpp diff --git a/cpp/wedpr-component-c-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_crypto_FastOre.h b/cpp/wedpr-component-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_crypto_FastOre.h similarity index 100% rename from cpp/wedpr-component-c-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_crypto_FastOre.h rename to cpp/wedpr-component-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_crypto_FastOre.h diff --git a/cpp/wedpr-component-c-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_crypto_SymmetricEncryption.cpp b/cpp/wedpr-component-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_crypto_SymmetricEncryption.cpp similarity index 100% rename from cpp/wedpr-component-c-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_crypto_SymmetricEncryption.cpp rename to cpp/wedpr-component-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_crypto_SymmetricEncryption.cpp diff --git a/cpp/wedpr-component-c-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_crypto_SymmetricEncryption.h b/cpp/wedpr-component-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_crypto_SymmetricEncryption.h similarity index 100% rename from cpp/wedpr-component-c-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_crypto_SymmetricEncryption.h rename to cpp/wedpr-component-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_crypto_SymmetricEncryption.h diff --git a/cpp/wedpr-component-c-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativeFloatingIhc.cpp b/cpp/wedpr-component-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativeFloatingIhc.cpp similarity index 100% rename from cpp/wedpr-component-c-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativeFloatingIhc.cpp rename to cpp/wedpr-component-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativeFloatingIhc.cpp diff --git a/cpp/wedpr-component-c-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativeFloatingIhc.h b/cpp/wedpr-component-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativeFloatingIhc.h similarity index 100% rename from cpp/wedpr-component-c-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativeFloatingIhc.h rename to cpp/wedpr-component-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativeFloatingIhc.h diff --git a/cpp/wedpr-component-c-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier.cpp b/cpp/wedpr-component-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier.cpp similarity index 100% rename from cpp/wedpr-component-c-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier.cpp rename to cpp/wedpr-component-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier.cpp diff --git a/cpp/wedpr-component-c-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier.h b/cpp/wedpr-component-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier.h similarity index 100% rename from cpp/wedpr-component-c-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier.h rename to cpp/wedpr-component-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativeFloatingPointPaillier.h diff --git a/cpp/wedpr-component-c-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativeIhc.h b/cpp/wedpr-component-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativeIhc.h similarity index 100% rename from cpp/wedpr-component-c-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativeIhc.h rename to cpp/wedpr-component-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativeIhc.h diff --git a/cpp/wedpr-component-c-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativePaillier.cpp b/cpp/wedpr-component-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativePaillier.cpp similarity index 100% rename from cpp/wedpr-component-c-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativePaillier.cpp rename to cpp/wedpr-component-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativePaillier.cpp diff --git a/cpp/wedpr-component-c-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativePaillier.h b/cpp/wedpr-component-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativePaillier.h similarity index 100% rename from cpp/wedpr-component-c-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativePaillier.h rename to cpp/wedpr-component-sdk/bindings/java/src/main/c/jni/com_webank_wedpr_sdk_jni_homo_NativePaillier.h diff --git a/cpp/wedpr-component-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/demo/GenerateKeys.java b/cpp/wedpr-component-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/demo/GenerateKeys.java similarity index 100% rename from cpp/wedpr-component-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/demo/GenerateKeys.java rename to cpp/wedpr-component-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/demo/GenerateKeys.java diff --git a/cpp/wedpr-component-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/codec/FloatingPointNumber.java b/cpp/wedpr-component-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/codec/FloatingPointNumber.java similarity index 100% rename from cpp/wedpr-component-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/codec/FloatingPointNumber.java rename to cpp/wedpr-component-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/codec/FloatingPointNumber.java diff --git a/cpp/wedpr-component-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/codec/NumberCodec.java b/cpp/wedpr-component-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/codec/NumberCodec.java similarity index 100% rename from cpp/wedpr-component-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/codec/NumberCodec.java rename to cpp/wedpr-component-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/codec/NumberCodec.java diff --git a/cpp/wedpr-component-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/codec/NumberCodecException.java b/cpp/wedpr-component-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/codec/NumberCodecException.java similarity index 100% rename from cpp/wedpr-component-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/codec/NumberCodecException.java rename to cpp/wedpr-component-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/codec/NumberCodecException.java diff --git a/cpp/wedpr-component-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/codec/NumberCodecImpl.java b/cpp/wedpr-component-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/codec/NumberCodecImpl.java similarity index 100% rename from cpp/wedpr-component-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/codec/NumberCodecImpl.java rename to cpp/wedpr-component-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/codec/NumberCodecImpl.java diff --git a/cpp/wedpr-component-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/common/JniException.java b/cpp/wedpr-component-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/common/JniException.java similarity index 100% rename from cpp/wedpr-component-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/common/JniException.java rename to cpp/wedpr-component-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/common/JniException.java diff --git a/cpp/wedpr-component-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/common/JniLibLoader.java b/cpp/wedpr-component-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/common/JniLibLoader.java similarity index 100% rename from cpp/wedpr-component-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/common/JniLibLoader.java rename to cpp/wedpr-component-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/common/JniLibLoader.java diff --git a/cpp/wedpr-component-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/common/Utilities.java b/cpp/wedpr-component-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/common/Utilities.java similarity index 100% rename from cpp/wedpr-component-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/common/Utilities.java rename to cpp/wedpr-component-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/common/Utilities.java diff --git a/cpp/wedpr-component-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/crypto/FastOre.java b/cpp/wedpr-component-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/crypto/FastOre.java similarity index 100% rename from cpp/wedpr-component-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/crypto/FastOre.java rename to cpp/wedpr-component-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/crypto/FastOre.java diff --git a/cpp/wedpr-component-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/crypto/SymmetricEncryption.java b/cpp/wedpr-component-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/crypto/SymmetricEncryption.java similarity index 100% rename from cpp/wedpr-component-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/crypto/SymmetricEncryption.java rename to cpp/wedpr-component-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/crypto/SymmetricEncryption.java diff --git a/cpp/wedpr-component-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/homo/NativeFloatingIhc.java b/cpp/wedpr-component-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/homo/NativeFloatingIhc.java similarity index 100% rename from cpp/wedpr-component-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/homo/NativeFloatingIhc.java rename to cpp/wedpr-component-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/homo/NativeFloatingIhc.java diff --git a/cpp/wedpr-component-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/homo/NativeFloatingPointPaillier.java b/cpp/wedpr-component-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/homo/NativeFloatingPointPaillier.java similarity index 100% rename from cpp/wedpr-component-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/homo/NativeFloatingPointPaillier.java rename to cpp/wedpr-component-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/homo/NativeFloatingPointPaillier.java diff --git a/cpp/wedpr-component-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/homo/NativePaillier.java b/cpp/wedpr-component-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/homo/NativePaillier.java similarity index 100% rename from cpp/wedpr-component-c-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/homo/NativePaillier.java rename to cpp/wedpr-component-sdk/bindings/java/src/main/java/com/webank/wedpr/sdk/jni/homo/NativePaillier.java diff --git a/cpp/wedpr-component-c-sdk/bindings/java/src/main/resources/META-INF/native/win/file.list b/cpp/wedpr-component-sdk/bindings/java/src/main/resources/META-INF/native/win/file.list similarity index 100% rename from cpp/wedpr-component-c-sdk/bindings/java/src/main/resources/META-INF/native/win/file.list rename to cpp/wedpr-component-sdk/bindings/java/src/main/resources/META-INF/native/win/file.list diff --git a/cpp/wedpr-component-c-sdk/bindings/java/src/test/java/com/webank/wedpr/sdk/jni/test/NativeFloatingIhcTest.java b/cpp/wedpr-component-sdk/bindings/java/src/test/java/com/webank/wedpr/sdk/jni/test/NativeFloatingIhcTest.java similarity index 100% rename from cpp/wedpr-component-c-sdk/bindings/java/src/test/java/com/webank/wedpr/sdk/jni/test/NativeFloatingIhcTest.java rename to cpp/wedpr-component-sdk/bindings/java/src/test/java/com/webank/wedpr/sdk/jni/test/NativeFloatingIhcTest.java diff --git a/cpp/wedpr-component-c-sdk/bindings/java/src/test/java/com/webank/wedpr/sdk/jni/test/NativeFloatingPointPaillierTest.java b/cpp/wedpr-component-sdk/bindings/java/src/test/java/com/webank/wedpr/sdk/jni/test/NativeFloatingPointPaillierTest.java similarity index 100% rename from cpp/wedpr-component-c-sdk/bindings/java/src/test/java/com/webank/wedpr/sdk/jni/test/NativeFloatingPointPaillierTest.java rename to cpp/wedpr-component-sdk/bindings/java/src/test/java/com/webank/wedpr/sdk/jni/test/NativeFloatingPointPaillierTest.java diff --git a/cpp/wedpr-component-c-sdk/bindings/java/src/test/java/com/webank/wedpr/sdk/jni/test/NativePaillierTest.java b/cpp/wedpr-component-sdk/bindings/java/src/test/java/com/webank/wedpr/sdk/jni/test/NativePaillierTest.java similarity index 100% rename from cpp/wedpr-component-c-sdk/bindings/java/src/test/java/com/webank/wedpr/sdk/jni/test/NativePaillierTest.java rename to cpp/wedpr-component-sdk/bindings/java/src/test/java/com/webank/wedpr/sdk/jni/test/NativePaillierTest.java diff --git a/cpp/wedpr-component-c-sdk/bindings/java/src/test/java/com/webank/wedpr/sdk/jni/test/NumberCodecTest.java b/cpp/wedpr-component-sdk/bindings/java/src/test/java/com/webank/wedpr/sdk/jni/test/NumberCodecTest.java similarity index 100% rename from cpp/wedpr-component-c-sdk/bindings/java/src/test/java/com/webank/wedpr/sdk/jni/test/NumberCodecTest.java rename to cpp/wedpr-component-sdk/bindings/java/src/test/java/com/webank/wedpr/sdk/jni/test/NumberCodecTest.java diff --git a/cpp/wedpr-component-c-sdk/bindings/java/src/test/java/com/webank/wedpr/sdk/jni/test/SymmetricEncryptionTest.java b/cpp/wedpr-component-sdk/bindings/java/src/test/java/com/webank/wedpr/sdk/jni/test/SymmetricEncryptionTest.java similarity index 100% rename from cpp/wedpr-component-c-sdk/bindings/java/src/test/java/com/webank/wedpr/sdk/jni/test/SymmetricEncryptionTest.java rename to cpp/wedpr-component-sdk/bindings/java/src/test/java/com/webank/wedpr/sdk/jni/test/SymmetricEncryptionTest.java diff --git a/cpp/wedpr-component-c-sdk/ppc-crypto-c-sdk/CMakeLists.txt b/cpp/wedpr-component-sdk/ppc-crypto-c-sdk/CMakeLists.txt similarity index 100% rename from cpp/wedpr-component-c-sdk/ppc-crypto-c-sdk/CMakeLists.txt rename to cpp/wedpr-component-sdk/ppc-crypto-c-sdk/CMakeLists.txt diff --git a/cpp/wedpr-component-c-sdk/ppc-crypto-c-sdk/fast_ore.cpp b/cpp/wedpr-component-sdk/ppc-crypto-c-sdk/fast_ore.cpp similarity index 100% rename from cpp/wedpr-component-c-sdk/ppc-crypto-c-sdk/fast_ore.cpp rename to cpp/wedpr-component-sdk/ppc-crypto-c-sdk/fast_ore.cpp diff --git a/cpp/wedpr-component-c-sdk/ppc-crypto-c-sdk/fast_ore.h b/cpp/wedpr-component-sdk/ppc-crypto-c-sdk/fast_ore.h similarity index 100% rename from cpp/wedpr-component-c-sdk/ppc-crypto-c-sdk/fast_ore.h rename to cpp/wedpr-component-sdk/ppc-crypto-c-sdk/fast_ore.h diff --git a/cpp/wedpr-component-c-sdk/ppc-crypto-c-sdk/floating_point_ihc.cpp b/cpp/wedpr-component-sdk/ppc-crypto-c-sdk/floating_point_ihc.cpp similarity index 100% rename from cpp/wedpr-component-c-sdk/ppc-crypto-c-sdk/floating_point_ihc.cpp rename to cpp/wedpr-component-sdk/ppc-crypto-c-sdk/floating_point_ihc.cpp diff --git a/cpp/wedpr-component-c-sdk/ppc-crypto-c-sdk/floating_point_ihc.h b/cpp/wedpr-component-sdk/ppc-crypto-c-sdk/floating_point_ihc.h similarity index 100% rename from cpp/wedpr-component-c-sdk/ppc-crypto-c-sdk/floating_point_ihc.h rename to cpp/wedpr-component-sdk/ppc-crypto-c-sdk/floating_point_ihc.h diff --git a/cpp/wedpr-component-c-sdk/ppc-crypto-c-sdk/floating_point_paillier.cpp b/cpp/wedpr-component-sdk/ppc-crypto-c-sdk/floating_point_paillier.cpp similarity index 100% rename from cpp/wedpr-component-c-sdk/ppc-crypto-c-sdk/floating_point_paillier.cpp rename to cpp/wedpr-component-sdk/ppc-crypto-c-sdk/floating_point_paillier.cpp diff --git a/cpp/wedpr-component-c-sdk/ppc-crypto-c-sdk/floating_point_paillier.h b/cpp/wedpr-component-sdk/ppc-crypto-c-sdk/floating_point_paillier.h similarity index 100% rename from cpp/wedpr-component-c-sdk/ppc-crypto-c-sdk/floating_point_paillier.h rename to cpp/wedpr-component-sdk/ppc-crypto-c-sdk/floating_point_paillier.h diff --git a/cpp/wedpr-component-c-sdk/ppc-crypto-c-sdk/homo_ihc.cpp b/cpp/wedpr-component-sdk/ppc-crypto-c-sdk/homo_ihc.cpp similarity index 100% rename from cpp/wedpr-component-c-sdk/ppc-crypto-c-sdk/homo_ihc.cpp rename to cpp/wedpr-component-sdk/ppc-crypto-c-sdk/homo_ihc.cpp diff --git a/cpp/wedpr-component-c-sdk/ppc-crypto-c-sdk/homo_ihc.h b/cpp/wedpr-component-sdk/ppc-crypto-c-sdk/homo_ihc.h similarity index 100% rename from cpp/wedpr-component-c-sdk/ppc-crypto-c-sdk/homo_ihc.h rename to cpp/wedpr-component-sdk/ppc-crypto-c-sdk/homo_ihc.h diff --git a/cpp/wedpr-component-c-sdk/ppc-crypto-c-sdk/homo_paillier.cpp b/cpp/wedpr-component-sdk/ppc-crypto-c-sdk/homo_paillier.cpp similarity index 100% rename from cpp/wedpr-component-c-sdk/ppc-crypto-c-sdk/homo_paillier.cpp rename to cpp/wedpr-component-sdk/ppc-crypto-c-sdk/homo_paillier.cpp diff --git a/cpp/wedpr-component-c-sdk/ppc-crypto-c-sdk/homo_paillier.h b/cpp/wedpr-component-sdk/ppc-crypto-c-sdk/homo_paillier.h similarity index 100% rename from cpp/wedpr-component-c-sdk/ppc-crypto-c-sdk/homo_paillier.h rename to cpp/wedpr-component-sdk/ppc-crypto-c-sdk/homo_paillier.h diff --git a/cpp/wedpr-component-c-sdk/ppc-crypto-c-sdk/symmetric_encryption.cpp b/cpp/wedpr-component-sdk/ppc-crypto-c-sdk/symmetric_encryption.cpp similarity index 100% rename from cpp/wedpr-component-c-sdk/ppc-crypto-c-sdk/symmetric_encryption.cpp rename to cpp/wedpr-component-sdk/ppc-crypto-c-sdk/symmetric_encryption.cpp diff --git a/cpp/wedpr-component-c-sdk/ppc-crypto-c-sdk/symmetric_encryption.h b/cpp/wedpr-component-sdk/ppc-crypto-c-sdk/symmetric_encryption.h similarity index 100% rename from cpp/wedpr-component-c-sdk/ppc-crypto-c-sdk/symmetric_encryption.h rename to cpp/wedpr-component-sdk/ppc-crypto-c-sdk/symmetric_encryption.h diff --git a/cpp/wedpr-component-c-sdk/ppc-crypto-c-sdk/utils/error.cpp b/cpp/wedpr-component-sdk/ppc-crypto-c-sdk/utils/error.cpp similarity index 100% rename from cpp/wedpr-component-c-sdk/ppc-crypto-c-sdk/utils/error.cpp rename to cpp/wedpr-component-sdk/ppc-crypto-c-sdk/utils/error.cpp diff --git a/cpp/wedpr-component-c-sdk/ppc-crypto-c-sdk/utils/error.h b/cpp/wedpr-component-sdk/ppc-crypto-c-sdk/utils/error.h similarity index 100% rename from cpp/wedpr-component-c-sdk/ppc-crypto-c-sdk/utils/error.h rename to cpp/wedpr-component-sdk/ppc-crypto-c-sdk/utils/error.h diff --git a/cpp/wedpr-component-c-sdk/ppc-crypto-c-sdk/utils/utilities.cpp b/cpp/wedpr-component-sdk/ppc-crypto-c-sdk/utils/utilities.cpp similarity index 100% rename from cpp/wedpr-component-c-sdk/ppc-crypto-c-sdk/utils/utilities.cpp rename to cpp/wedpr-component-sdk/ppc-crypto-c-sdk/utils/utilities.cpp diff --git a/cpp/wedpr-component-c-sdk/ppc-crypto-c-sdk/utils/utilities.h b/cpp/wedpr-component-sdk/ppc-crypto-c-sdk/utils/utilities.h similarity index 100% rename from cpp/wedpr-component-c-sdk/ppc-crypto-c-sdk/utils/utilities.h rename to cpp/wedpr-component-sdk/ppc-crypto-c-sdk/utils/utilities.h diff --git a/cpp/wedpr-component-c-sdk/tests/CMakeLists.txt b/cpp/wedpr-component-sdk/tests/CMakeLists.txt similarity index 100% rename from cpp/wedpr-component-c-sdk/tests/CMakeLists.txt rename to cpp/wedpr-component-sdk/tests/CMakeLists.txt diff --git a/cpp/wedpr-component-c-sdk/tests/TestFastOre.cpp b/cpp/wedpr-component-sdk/tests/TestFastOre.cpp similarity index 100% rename from cpp/wedpr-component-c-sdk/tests/TestFastOre.cpp rename to cpp/wedpr-component-sdk/tests/TestFastOre.cpp diff --git a/cpp/wedpr-component-c-sdk/tests/TestHomoPaillier.cpp b/cpp/wedpr-component-sdk/tests/TestHomoPaillier.cpp similarity index 100% rename from cpp/wedpr-component-c-sdk/tests/TestHomoPaillier.cpp rename to cpp/wedpr-component-sdk/tests/TestHomoPaillier.cpp diff --git a/cpp/wedpr-component-c-sdk/tests/main.cpp b/cpp/wedpr-component-sdk/tests/main.cpp similarity index 100% rename from cpp/wedpr-component-c-sdk/tests/main.cpp rename to cpp/wedpr-component-sdk/tests/main.cpp diff --git a/cpp/wedpr-component-sdk/wedpr-front-cpp-sdk/CMakeLists.txt b/cpp/wedpr-component-sdk/wedpr-front-cpp-sdk/CMakeLists.txt new file mode 100644 index 00000000..f2fbbf92 --- /dev/null +++ b/cpp/wedpr-component-sdk/wedpr-front-cpp-sdk/CMakeLists.txt @@ -0,0 +1,9 @@ +file(GLOB_RECURSE SRCS *.cpp *.c) + +# generate the static lib +add_library(${PPC_FRONT_C_SDK_STATIC_TARGET} ${SRCS}) +target_link_libraries(${PPC_FRONT_C_SDK_STATIC_TARGET} PUBLIC ${BCOS_UTILITIES_TARGET}) + +# generate the shared lib +add_library(${PPC_FRONT_C_SDK_TARGET} SHARED ${SRCS}) +target_link_libraries(${PPC_FRONT_C_SDK_TARGET} PUBLIC ${BCOS_UTILITIES_TARGET}) \ No newline at end of file diff --git a/cpp/wedpr-component-sdk/wedpr-front-cpp-sdk/wedpr_front_c.cpp b/cpp/wedpr-component-sdk/wedpr-front-cpp-sdk/wedpr_front_c.cpp new file mode 100644 index 00000000..e3b59381 --- /dev/null +++ b/cpp/wedpr-component-sdk/wedpr-front-cpp-sdk/wedpr_front_c.cpp @@ -0,0 +1,92 @@ +/** + * Copyright (C) 2023 WeDPR. + * SPDX-License-Identifier: Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @file wedpr_front_c.h + * @author: yujiechen + * @date 2024-08-22 + */ +#include "wedpr_front_c.h" + +/** + * @brief create the wedpr_front using specified config + * + * @param config the config used to build the wedpr_front + * @return void* the created wedpr_front + */ +void* wedpr_front_create(struct wedpr_front_config* config) +{ + return nullptr; +} + +/** + * @brief start the wedpr_front + * + * @param front the front to start + */ +void wedpr_front_start(void* front) {} + +/** + * @brief stop the wedpr_front + * + * @param front the front to stop + */ +void wedpr_front_stop(void* front) {} + +/** + * @brief destroy the wedpr_front + * + * @param front the front to destroy + */ +void wedpr_front_destroy(void* front) {} + +/** + * @brief register the topic handler + * + * @param front the front object + * @param topic the topic + * @param callback the callback called when receive specified topic + */ +void register_topic_handler(void* front, InputBuffer const* topic, wedpr_msg_handler_cb callback) {} + +/** + * @brief async send message + * + * @param front the front to send the message + * @param routerPolicy the router policy: + * 0: route by nodeID + * 1: route by component + * 2: route by agency + * @param topic the topic + * @param dstInst the dst agency(must set when 'route by agency' and 'route by + * component') + * @param dstNodeID the dst nodeID(must set when 'route by nodeID') + * @param componentType the componentType(must set when 'route by component') + * @param payload the payload to send + * @param seq the message seq + * @param timeout timeout + * @param callback callback + */ +void async_send_message(void* front, int routerPolicy, InputBuffer const* topic, + InputBuffer const* dstInst, InputBuffer const* dstNodeID, uint8_t componentType, + InputBuffer const* payload, int seq, long timeout, wedpr_msg_handler_cb callback) +{} + +// the sync interface for async_send_message +wedpr_msg* push(void* front, int routerPolicy, InputBuffer const* topic, InputBuffer const* dstInst, + InputBuffer const* dstNodeID, uint8_t componentType, InputBuffer const* payload, int seq, + long timeout) +{ + return nullptr; +} diff --git a/cpp/wedpr-component-sdk/wedpr-front-cpp-sdk/wedpr_front_c.h b/cpp/wedpr-component-sdk/wedpr-front-cpp-sdk/wedpr_front_c.h new file mode 100644 index 00000000..ed918ce8 --- /dev/null +++ b/cpp/wedpr-component-sdk/wedpr-front-cpp-sdk/wedpr_front_c.h @@ -0,0 +1,98 @@ +/** + * Copyright (C) 2023 WeDPR. + * SPDX-License-Identifier: Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @file wedpr_front_c.h + * @author: yujiechen + * @date 2024-08-22 + */ +#ifndef __WEDPR_FRONT_C_H__ +#define __WEDPR_FRONT_C_H__ +#include "ppc-framework/libwrapper/Buffer.h" +#include "wedpr_front_common.h" +#include "wedpr_front_config.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief create the wedpr_front using specified config + * + * @param config the config used to build the wedpr_front + * @return void* the created wedpr_front + */ +void* wedpr_front_create(struct wedpr_front_config* config); + +/** + * @brief start the wedpr_front + * + * @param front the front to start + */ +void wedpr_front_start(void* front); + +/** + * @brief stop the wedpr_front + * + * @param front the front to stop + */ +void wedpr_front_stop(void* front); + +/** + * @brief destroy the wedpr_front + * + * @param front the front to destroy + */ +void wedpr_front_destroy(void* front); + +/** + * @brief register the topic handler + * + * @param front the front object + * @param topic the topic + * @param callback the callback called when receive specified topic + */ +void register_topic_handler(void* front, InputBuffer const* topic, wedpr_msg_handler_cb callback); + +/** + * @brief async send message + * + * @param front the front to send the message + * @param routerPolicy the router policy: + * 0: route by nodeID + * 1: route by component + * 2: route by agency + * @param topic the topic + * @param dstInst the dst agency(must set when 'route by agency' and 'route by + * component') + * @param dstNodeID the dst nodeID(must set when 'route by nodeID') + * @param componentType the componentType(must set when 'route by component') + * @param payload the payload to send + * @param seq the message seq + * @param timeout timeout + * @param callback callback + */ +void async_send_message(void* front, int routerPolicy, InputBuffer const* topic, + InputBuffer const* dstInst, InputBuffer const* dstNodeID, uint8_t componentType, + InputBuffer const* payload, int seq, long timeout, wedpr_msg_handler_cb callback); + +// the sync interface for async_send_message +wedpr_msg* push(void* front, int routerPolicy, InputBuffer const* topic, InputBuffer const* dstInst, + InputBuffer const* dstNodeID, uint8_t componentType, InputBuffer const* payload, int seq, + long timeout); + +#ifdef __cplusplus +} +#endif +#endif \ No newline at end of file diff --git a/cpp/wedpr-component-sdk/wedpr-front-cpp-sdk/wedpr_front_common.h b/cpp/wedpr-component-sdk/wedpr-front-cpp-sdk/wedpr_front_common.h new file mode 100644 index 00000000..22473223 --- /dev/null +++ b/cpp/wedpr-component-sdk/wedpr-front-cpp-sdk/wedpr_front_common.h @@ -0,0 +1,28 @@ +/** + * Copyright (C) 2023 WeDPR. + * SPDX-License-Identifier: Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @file wedpr_front_common.h + * @author: yujiechen + * @date 2024-08-22 + */ + +#ifndef __WEDPR_FRONT_COMMON_H__ +#define __WEDPR_FRONT_COMMON_H__ + +#include "wedpr_msg.h" + +typedef void (*wedpr_msg_handler_cb)(struct wedpr_msg* response, void* context); + +#endif diff --git a/cpp/wedpr-component-sdk/wedpr-front-cpp-sdk/wedpr_front_config.h b/cpp/wedpr-component-sdk/wedpr-front-cpp-sdk/wedpr_front_config.h new file mode 100644 index 00000000..cbe665d3 --- /dev/null +++ b/cpp/wedpr-component-sdk/wedpr-front-cpp-sdk/wedpr_front_config.h @@ -0,0 +1,56 @@ +/** + * Copyright (C) 2023 WeDPR. + * SPDX-License-Identifier: Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @file wedpr_front_config.h + * @author: yujiechen + * @date 2024-08-22 + */ + +#ifndef __WEDPR_FRONT_CONFIG_H__ +#define __WEDPR_FRONT_CONFIG_H__ +#include "ppc-framework/libwrapper/Buffer.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief the gateway endpoint information + * + */ +struct wedpr_gateway_endpoint +{ + InputBuffer const* host; + uint16_t port; +}; + +struct wedpr_gateway_info +{ + struct wedpr_gateway_endpoint* gatewayEndpoints; + uint16_t gatewayCount; +}; + +struct wedpr_front_config +{ + int threadPoolSize; + // the agency id + InputBuffer const* agencyID; + // the gateway-endpoints + struct wedpr_gateway_info* gateway_info; +}; +#ifdef __cplusplus +} +#endif +#endif \ No newline at end of file diff --git a/cpp/wedpr-component-sdk/wedpr-front-cpp-sdk/wedpr_msg.h b/cpp/wedpr-component-sdk/wedpr-front-cpp-sdk/wedpr_msg.h new file mode 100644 index 00000000..ae6f280e --- /dev/null +++ b/cpp/wedpr-component-sdk/wedpr-front-cpp-sdk/wedpr_msg.h @@ -0,0 +1,81 @@ +/** + * Copyright (C) 2023 WeDPR. + * SPDX-License-Identifier: Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @file wedpr_front_common.h + * @author: yujiechen + * @date 2024-08-22 + */ + +#ifndef __WEDPR_MSG_H__ +#define __WEDPR_MSG_H__ + +#include "ppc-framework/libwrapper/Buffer.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct gateway_optional_header +{ + // the componentType + uint8_t componentType; + // the source nodeID that send the message + OutputBuffer* srcNode; + // the target nodeID that should receive the message + OutputBuffer* dstNode; + // the target agency that need receive the message + OutputBuffer* dstInst; +}; + +struct gateway_msg_header +{ + // the msg version, used to support compatibility + uint8_t version; + // the traceID + OutputBuffer* traceID; + // the srcGwNode + OutputBuffer* srcGwNode; + // the dstGwNode + OutputBuffer* dstGwNode; + // the packetType + uint16_t packetType; + // the seq + uint32_t seq; + // the ttl + int16_t ttl; + // the ext(contains the router policy and response flag) + uint16_t ext; + //// the optional field(used to route between components and nodes) + struct gateway_optional_header* optionalFields; +}; + +struct front_payload +{ + // the front payload version, used to support compatibility + uint8_t version; + // the topic + OutputBuffer* topic; + OutputBuffer* data; +}; + +struct wedpr_msg +{ + gateway_msg_header* header; + front_payload* payload; +}; +#ifdef __cplusplus +} +#endif +#endif From ceb0f929c3f0d78e68bb289add1e938e73f8f7b8 Mon Sep 17 00:00:00 2001 From: cyjseagull Date: Fri, 23 Aug 2024 21:11:14 +0800 Subject: [PATCH 6/9] remove wedpr-front-cpp-sdk --- cpp/cmake/IncludeDirectories.cmake | 2 +- cpp/cmake/TargetSettings.cmake | 6 +- cpp/cmake/Version.cmake | 1 + cpp/ppc-framework/Common.h | 12 ++ cpp/ppc-framework/protocol/Message.h | 195 ++++++++++++++++++ cpp/ppc-front/ppc-front/Common.h | 1 - cpp/ppc-protocol/src/PPCMessage.h | 5 +- cpp/ppc-tools/src/codec/CodecUtility.h | 13 +- .../Utilities.h} | 51 ++--- cpp/wedpr-component-sdk/CMakeLists.txt | 1 - .../wedpr-front-cpp-sdk/CMakeLists.txt | 9 - .../wedpr-front-cpp-sdk/wedpr_front_c.cpp | 92 --------- .../wedpr-front-cpp-sdk/wedpr_front_c.h | 98 --------- .../wedpr-front-cpp-sdk/wedpr_front_common.h | 28 --- .../wedpr-front-cpp-sdk/wedpr_msg.h | 81 -------- 15 files changed, 230 insertions(+), 365 deletions(-) create mode 100644 cpp/ppc-framework/protocol/Message.h rename cpp/{wedpr-component-sdk/wedpr-front-cpp-sdk/wedpr_front_config.h => ppc-utilities/Utilities.h} (50%) delete mode 100644 cpp/wedpr-component-sdk/wedpr-front-cpp-sdk/CMakeLists.txt delete mode 100644 cpp/wedpr-component-sdk/wedpr-front-cpp-sdk/wedpr_front_c.cpp delete mode 100644 cpp/wedpr-component-sdk/wedpr-front-cpp-sdk/wedpr_front_c.h delete mode 100644 cpp/wedpr-component-sdk/wedpr-front-cpp-sdk/wedpr_front_common.h delete mode 100644 cpp/wedpr-component-sdk/wedpr-front-cpp-sdk/wedpr_msg.h diff --git a/cpp/cmake/IncludeDirectories.cmake b/cpp/cmake/IncludeDirectories.cmake index 7bd1fb86..f63512f5 100644 --- a/cpp/cmake/IncludeDirectories.cmake +++ b/cpp/cmake/IncludeDirectories.cmake @@ -2,7 +2,7 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR}) include_directories(${CMAKE_CURRENT_BINARY_DIR}) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/ppc-front) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/ppc-gateway) -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/wedpr-component-c-sdk) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/wedpr-component-sdk) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/ppc-tars-protocol) set(VCPKG_INCLUDE_PATH "${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/include") diff --git a/cpp/cmake/TargetSettings.cmake b/cpp/cmake/TargetSettings.cmake index da9e9626..7f29bb81 100644 --- a/cpp/cmake/TargetSettings.cmake +++ b/cpp/cmake/TargetSettings.cmake @@ -90,15 +90,12 @@ set(PPC_CRYPTO_C_SDK_STATIC_TARGET ppc-crypto-c-sdk-static) set(PPC_CRYPTO_C_SDK_TARGET ppc-crypto-c-sdk) set(PPC_FRONT_C_SDK_STATIC_TARGET ppc-front-c-sdk-static) -set(PPC_FRONT_C_SDK_TARGET ppc-front-c-sdk) # add suffix for arm if(ARCH_NATIVE) message(STATUS "Building arm architecture, CMAKE_HOST_SYSTEM_PROCESSOR => ${CMAKE_HOST_SYSTEM_PROCESSOR}") set(PPC_CRYPTO_C_SDK_STATIC_TARGET "ppc-crypto-c-sdk-aarch64") set(PPC_CRYPTO_C_SDK_TARGET "ppc-crypto-c-sdk-static-aarch64") - set(PPC_FRONT_C_SDK_STATIC_TARGET ppc-front-c-sdk-static-aarch64) - set(PPC_FRONT_C_SDK_TARGET ppc-front-c-sdk-aarch64) endif() #====== wedpr-component-sdk =========== @@ -127,4 +124,5 @@ endif() set(BOOST_UNIT_TEST Boost::unit_test_framework) # ==== the swig wrapper ===== -set(WEDPR_PYTHON_TOOLKIT "wedpr_python_toolkit") \ No newline at end of file +set(WEDPR_PYTHON_TOOLKIT "wedpr_python_toolkit") +set(WEDPR_PYTHON_TOOLKIT_DIR ${PROJECT_BINARY_DIR}/python/${WEDPR_PYTHON_TOOLKIT}) \ No newline at end of file diff --git a/cpp/cmake/Version.cmake b/cpp/cmake/Version.cmake index 84833fb8..206620b2 100644 --- a/cpp/cmake/Version.cmake +++ b/cpp/cmake/Version.cmake @@ -1 +1,2 @@ set(VERSION "1.0.0") +set(PYTHON_TOOLKIT_VERSION "1.0.0") diff --git a/cpp/ppc-framework/Common.h b/cpp/ppc-framework/Common.h index ea80b504..6034c5b6 100644 --- a/cpp/ppc-framework/Common.h +++ b/cpp/ppc-framework/Common.h @@ -44,6 +44,18 @@ namespace ppc { \ } +#define CHECK_OFFSET_WITH_THROW_EXCEPTION(offset, length) \ + do \ + { \ + if (offset > length) \ + { \ + throw std::out_of_range("Out of range error, offset:" + std::to_string(offset) + \ + " ,length: " + std::to_string(length) + \ + " ,file: " + __FILE__ + " ,func: " + __func__ + \ + " ,line: " + std::to_string(__LINE__)); \ + } \ + } while (0); + DERIVE_PPC_EXCEPTION(OpenFileFailed); DERIVE_PPC_EXCEPTION(DataSchemaNotSetted); DERIVE_PPC_EXCEPTION(UnsupportedDataSchema); diff --git a/cpp/ppc-framework/protocol/Message.h b/cpp/ppc-framework/protocol/Message.h new file mode 100644 index 00000000..0aa7443a --- /dev/null +++ b/cpp/ppc-framework/protocol/Message.h @@ -0,0 +1,195 @@ +/** + * Copyright (C) 2023 WeDPR. + * SPDX-License-Identifier: Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @file Message.h + * @author: yujiechen + * @date 2024-08-22 + */ +#pragma once +#include +#include +#include + +namespace ppc::protocol +{ +class MessageOptionalHeader +{ +public: + using Ptr = std::shared_ptr; + MessageOptionalHeader() = default; + virtual ~MessageOptionalHeader() = default; + + virtual bcos::bytes encode() const = 0; + // the componentType + virtual uint8_t componentType() const { return m_componentType; } + // the source nodeID that send the message + virtual bcos::bytes const& srcNode() const { return m_srcNode; } + // the target nodeID that should receive the message + virtual bcos::bytes const& dstNode() const { return m_dstNode; } + // the target agency that need receive the message + virtual bcos::bytes const& dstInst() const { return m_dstInst; } + +protected: + virtual uint32_t decode(bcos::bytesConstRef data) = 0; + +protected: + // the componentType + uint8_t m_componentType; + // the source nodeID that send the message + bcos::bytes m_srcNode; + // the target nodeID that should receive the message + bcos::bytes m_dstNode; + // the target agency that need receive the message + bcos::bytes m_dstInst; +}; +class MessageHeader +{ +public: + using Ptr = std::shared_ptr; + MessageHeader() = default; + virtual ~MessageHeader() = default; + + virtual bcos::bytes encode() const = 0; + + // the msg version, used to support compatibility + virtual uint8_t version() const { return m_version; } + // the traceID + virtual std::string const& traceID() const { return m_traceID; } + // the srcGwNode + virtual bcos::bytes const& srcGwNode() const { return m_srcGwNode; } + // the dstGwNode + virtual bcos::bytes const& dstGwNode() const { return m_dstGwNode; } + // the packetType + virtual uint16_t packetType() const { return m_packetType; } + // the ttl + virtual int16_t ttl() const { return m_ttl; } + // the ext(contains the router policy and response flag) + virtual uint16_t ext() const { return m_ext; } + //// the optional field(used to route between components and nodes) + virtual MessageOptionalHeader::Ptr optionalFields() const { return m_optionalFields; } + + virtual uint32_t length() const { return m_length; } + + virtual void setVersion(uint16_t version) { m_version = version; } + virtual void setPacketType(uint16_t packetType) { m_packetType = packetType; } + // the seq is the traceID + virtual void setTraceID(std::string traceID) { m_traceID = traceID; } + virtual void setExt(uint16_t ext) { m_ext = ext; } + + uint64_t packetLen() const { return m_packetLen; } + uint16_t headerLen() const { return m_headerLen; } + + virtual bool isRespPacket() const = 0; + virtual void setRespPacket() = 0; + +protected: + virtual uint32_t decode(bcos::bytesConstRef data) = 0; + +protected: + // the msg version, used to support compatibility + uint8_t m_version; + // the traceID + std::string m_traceID; + // the srcGwNode + bcos::bytes m_srcGwNode; + // the dstGwNode + bcos::bytes m_dstGwNode; + // the packetType + uint16_t m_packetType; + // the ttl + int16_t m_ttl; + // the ext(contains the router policy and response flag) + uint16_t m_ext; + //// the optional field(used to route between components and nodes) + MessageOptionalHeader::Ptr m_optionalFields; + uint64_t m_packetLen; + uint16_t m_headerLen; +}; + +class MessagePayload +{ +public: + using Ptr = std::shared_ptr; + MessagePayload() = default; + virtual ~MessagePayload() = default; + + virtual bcos::bytes encode() const = 0; + + // the version + virtual uint8_t version() const { return m_version; } + // the topic + virtual std::string const& topic() const { return m_topic; } + virtual bcos::bytes const& data() const { return m_data; } + virtual uint32_t length() const { return m_length; } + +protected: + virtual uint32_t decode(uint32_t startPos, bcos::bytesConstRef data) = 0; + +protected: + // the front payload version, used to support compatibility + uint8_t m_version; + // the topic + std::string m_topic; + bcos::bytes m_data; + uint32_t m_length; +}; + +class Message : virtual public bcos::boostssl::MessageFace +{ +public: + using Ptr = std::shared_ptr; + Message() = default; + ~Message() override {} + + virtual MessageHeader::Ptr header() const { return m_header; } + virtual MessagePayLoad::Ptr payload() const { return m_payload; } + + uint16_t version() const override { return m_header->version(); } + void setVersion(uint16_t version) override{m_header->setVersion(version)} uint16_t + packetType() const override + { + return m_header->packetType(); + } + void setPacketType(uint16_t packetType) override { m_header->setPacketType(packetType); } + std::string const& seq() const override { return m_header->traceID(); } + void setSeq(std::string traceID) override { m_header->setTraceID(traceID); } + uint16_t ext() const override { return m_header->ext(); } + void setExt(uint16_t ext) override { m_header->setExt(except); } + + bool isRespPacket() const override { return m_header->isRespPacket(); } + void setRespPacket() override { m_header->setRespPacket(); } + + virtual uint32_t length() const override { return m_header->packetLen(); } + std::shared_ptr payload() const override { return m_payload; } + void setPayload(std::shared_ptr _payload) override + { + m_payload = std::move(_payload); + } + + +protected: + MessageHeader::Ptr m_header; + std::shared_ptr m_payload; +}; + +class MessageBuilder +{ +public: + MessageBuilder() = default; + virtual ~MessageBuilder() = default; + + virtual Message::Ptr build() = 0; +} +} // namespace ppc::protocol \ No newline at end of file diff --git a/cpp/ppc-front/ppc-front/Common.h b/cpp/ppc-front/ppc-front/Common.h index 677ed467..a221d179 100644 --- a/cpp/ppc-front/ppc-front/Common.h +++ b/cpp/ppc-front/ppc-front/Common.h @@ -32,7 +32,6 @@ namespace ppc::front { - #define FRONT_LOG(LEVEL) BCOS_LOG(LEVEL) << "[FRONT]" #define HOLDING_MESSAGE_TIMEOUT_M 30 diff --git a/cpp/ppc-protocol/src/PPCMessage.h b/cpp/ppc-protocol/src/PPCMessage.h index c62f890f..ca34657b 100644 --- a/cpp/ppc-protocol/src/PPCMessage.h +++ b/cpp/ppc-protocol/src/PPCMessage.h @@ -64,10 +64,7 @@ class PPCMessage : public PPCMessageFace std::shared_ptr data() const override { return m_data; } // Note: here directly use passed-in _data, make-sure _data not changed before send the message void setData(std::shared_ptr _data) override { m_data = _data; } - std::map header() override - { - return decodeMap(m_header); - } + std::map header() override { return decodeMap(m_header); } void setHeader(std::map _header) override { m_header = encodeMap(_header); diff --git a/cpp/ppc-tools/src/codec/CodecUtility.h b/cpp/ppc-tools/src/codec/CodecUtility.h index 5d37ddf0..ce7a208a 100644 --- a/cpp/ppc-tools/src/codec/CodecUtility.h +++ b/cpp/ppc-tools/src/codec/CodecUtility.h @@ -20,21 +20,10 @@ #pragma once #include "openssl/bn.h" #include "ppc-framework/libwrapper/BigNum.h" +#include "ppc-utilities/Utilities.h" #include #include #include - -#define CHECK_OFFSET_WITH_THROW_EXCEPTION(offset, length) \ - do \ - { \ - if (offset > length) \ - { \ - throw std::out_of_range("Out of range error, offset:" + std::to_string(offset) + \ - " ,length: " + std::to_string(length) + \ - " ,file: " + __FILE__ + " ,func: " + __func__ + \ - " ,line: " + std::to_string(__LINE__)); \ - } \ - } while (0); namespace ppc { inline bcos::byte* encodeBuffer( diff --git a/cpp/wedpr-component-sdk/wedpr-front-cpp-sdk/wedpr_front_config.h b/cpp/ppc-utilities/Utilities.h similarity index 50% rename from cpp/wedpr-component-sdk/wedpr-front-cpp-sdk/wedpr_front_config.h rename to cpp/ppc-utilities/Utilities.h index cbe665d3..b9b8e0ae 100644 --- a/cpp/wedpr-component-sdk/wedpr-front-cpp-sdk/wedpr_front_config.h +++ b/cpp/ppc-utilities/Utilities.h @@ -13,44 +13,27 @@ * See the License for the specific language governing permissions and * limitations under the License. * - * @file wedpr_front_config.h + * @file Utilitiles.cpp * @author: yujiechen - * @date 2024-08-22 + * @date 2024-08-23 */ +#pragma once -#ifndef __WEDPR_FRONT_CONFIG_H__ -#define __WEDPR_FRONT_CONFIG_H__ -#include "ppc-framework/libwrapper/Buffer.h" +#include "ppc-framework/Common.h" -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief the gateway endpoint information - * - */ -struct wedpr_gateway_endpoint +namespace ppc { - InputBuffer const* host; - uint16_t port; -}; - -struct wedpr_gateway_info -{ - struct wedpr_gateway_endpoint* gatewayEndpoints; - uint16_t gatewayCount; -}; - -struct wedpr_front_config +inline uint64_t decodeNetworkBuffer( + bcos::bytes& _result, bcos::byte const* buffer, unsigned int bufferLen, uint64_t const offset) { - int threadPoolSize; - // the agency id - InputBuffer const* agencyID; - // the gateway-endpoints - struct wedpr_gateway_info* gateway_info; -}; -#ifdef __cplusplus + CHECK_OFFSET_WITH_THROW_EXCEPTION(offset, bufferLen); + auto dataLen = + boost::asio::detail::socket_ops::network_to_host_short(*((uint16_t*)buffer + offset)); + offset += 2; + CHECK_OFFSET_WITH_THROW_EXCEPTION(offset, bufferLen); + buffer.insert( + buffer.end(), (bcos::byte*)_buffer + offset, (bcos::byte*)_buffer + offset + dataLen); + offset += dataLen; + return offset; } -#endif -#endif \ No newline at end of file +} // namespace ppc \ No newline at end of file diff --git a/cpp/wedpr-component-sdk/CMakeLists.txt b/cpp/wedpr-component-sdk/CMakeLists.txt index 8f389e80..fae969e6 100644 --- a/cpp/wedpr-component-sdk/CMakeLists.txt +++ b/cpp/wedpr-component-sdk/CMakeLists.txt @@ -6,7 +6,6 @@ if(WIN32) set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS "ON") endif() add_subdirectory(ppc-crypto-c-sdk) -add_subdirectory(wedpr-front-cpp-sdk) if (TESTS) enable_testing() diff --git a/cpp/wedpr-component-sdk/wedpr-front-cpp-sdk/CMakeLists.txt b/cpp/wedpr-component-sdk/wedpr-front-cpp-sdk/CMakeLists.txt deleted file mode 100644 index f2fbbf92..00000000 --- a/cpp/wedpr-component-sdk/wedpr-front-cpp-sdk/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -file(GLOB_RECURSE SRCS *.cpp *.c) - -# generate the static lib -add_library(${PPC_FRONT_C_SDK_STATIC_TARGET} ${SRCS}) -target_link_libraries(${PPC_FRONT_C_SDK_STATIC_TARGET} PUBLIC ${BCOS_UTILITIES_TARGET}) - -# generate the shared lib -add_library(${PPC_FRONT_C_SDK_TARGET} SHARED ${SRCS}) -target_link_libraries(${PPC_FRONT_C_SDK_TARGET} PUBLIC ${BCOS_UTILITIES_TARGET}) \ No newline at end of file diff --git a/cpp/wedpr-component-sdk/wedpr-front-cpp-sdk/wedpr_front_c.cpp b/cpp/wedpr-component-sdk/wedpr-front-cpp-sdk/wedpr_front_c.cpp deleted file mode 100644 index e3b59381..00000000 --- a/cpp/wedpr-component-sdk/wedpr-front-cpp-sdk/wedpr_front_c.cpp +++ /dev/null @@ -1,92 +0,0 @@ -/** - * Copyright (C) 2023 WeDPR. - * SPDX-License-Identifier: Apache-2.0 - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * @file wedpr_front_c.h - * @author: yujiechen - * @date 2024-08-22 - */ -#include "wedpr_front_c.h" - -/** - * @brief create the wedpr_front using specified config - * - * @param config the config used to build the wedpr_front - * @return void* the created wedpr_front - */ -void* wedpr_front_create(struct wedpr_front_config* config) -{ - return nullptr; -} - -/** - * @brief start the wedpr_front - * - * @param front the front to start - */ -void wedpr_front_start(void* front) {} - -/** - * @brief stop the wedpr_front - * - * @param front the front to stop - */ -void wedpr_front_stop(void* front) {} - -/** - * @brief destroy the wedpr_front - * - * @param front the front to destroy - */ -void wedpr_front_destroy(void* front) {} - -/** - * @brief register the topic handler - * - * @param front the front object - * @param topic the topic - * @param callback the callback called when receive specified topic - */ -void register_topic_handler(void* front, InputBuffer const* topic, wedpr_msg_handler_cb callback) {} - -/** - * @brief async send message - * - * @param front the front to send the message - * @param routerPolicy the router policy: - * 0: route by nodeID - * 1: route by component - * 2: route by agency - * @param topic the topic - * @param dstInst the dst agency(must set when 'route by agency' and 'route by - * component') - * @param dstNodeID the dst nodeID(must set when 'route by nodeID') - * @param componentType the componentType(must set when 'route by component') - * @param payload the payload to send - * @param seq the message seq - * @param timeout timeout - * @param callback callback - */ -void async_send_message(void* front, int routerPolicy, InputBuffer const* topic, - InputBuffer const* dstInst, InputBuffer const* dstNodeID, uint8_t componentType, - InputBuffer const* payload, int seq, long timeout, wedpr_msg_handler_cb callback) -{} - -// the sync interface for async_send_message -wedpr_msg* push(void* front, int routerPolicy, InputBuffer const* topic, InputBuffer const* dstInst, - InputBuffer const* dstNodeID, uint8_t componentType, InputBuffer const* payload, int seq, - long timeout) -{ - return nullptr; -} diff --git a/cpp/wedpr-component-sdk/wedpr-front-cpp-sdk/wedpr_front_c.h b/cpp/wedpr-component-sdk/wedpr-front-cpp-sdk/wedpr_front_c.h deleted file mode 100644 index ed918ce8..00000000 --- a/cpp/wedpr-component-sdk/wedpr-front-cpp-sdk/wedpr_front_c.h +++ /dev/null @@ -1,98 +0,0 @@ -/** - * Copyright (C) 2023 WeDPR. - * SPDX-License-Identifier: Apache-2.0 - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * @file wedpr_front_c.h - * @author: yujiechen - * @date 2024-08-22 - */ -#ifndef __WEDPR_FRONT_C_H__ -#define __WEDPR_FRONT_C_H__ -#include "ppc-framework/libwrapper/Buffer.h" -#include "wedpr_front_common.h" -#include "wedpr_front_config.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief create the wedpr_front using specified config - * - * @param config the config used to build the wedpr_front - * @return void* the created wedpr_front - */ -void* wedpr_front_create(struct wedpr_front_config* config); - -/** - * @brief start the wedpr_front - * - * @param front the front to start - */ -void wedpr_front_start(void* front); - -/** - * @brief stop the wedpr_front - * - * @param front the front to stop - */ -void wedpr_front_stop(void* front); - -/** - * @brief destroy the wedpr_front - * - * @param front the front to destroy - */ -void wedpr_front_destroy(void* front); - -/** - * @brief register the topic handler - * - * @param front the front object - * @param topic the topic - * @param callback the callback called when receive specified topic - */ -void register_topic_handler(void* front, InputBuffer const* topic, wedpr_msg_handler_cb callback); - -/** - * @brief async send message - * - * @param front the front to send the message - * @param routerPolicy the router policy: - * 0: route by nodeID - * 1: route by component - * 2: route by agency - * @param topic the topic - * @param dstInst the dst agency(must set when 'route by agency' and 'route by - * component') - * @param dstNodeID the dst nodeID(must set when 'route by nodeID') - * @param componentType the componentType(must set when 'route by component') - * @param payload the payload to send - * @param seq the message seq - * @param timeout timeout - * @param callback callback - */ -void async_send_message(void* front, int routerPolicy, InputBuffer const* topic, - InputBuffer const* dstInst, InputBuffer const* dstNodeID, uint8_t componentType, - InputBuffer const* payload, int seq, long timeout, wedpr_msg_handler_cb callback); - -// the sync interface for async_send_message -wedpr_msg* push(void* front, int routerPolicy, InputBuffer const* topic, InputBuffer const* dstInst, - InputBuffer const* dstNodeID, uint8_t componentType, InputBuffer const* payload, int seq, - long timeout); - -#ifdef __cplusplus -} -#endif -#endif \ No newline at end of file diff --git a/cpp/wedpr-component-sdk/wedpr-front-cpp-sdk/wedpr_front_common.h b/cpp/wedpr-component-sdk/wedpr-front-cpp-sdk/wedpr_front_common.h deleted file mode 100644 index 22473223..00000000 --- a/cpp/wedpr-component-sdk/wedpr-front-cpp-sdk/wedpr_front_common.h +++ /dev/null @@ -1,28 +0,0 @@ -/** - * Copyright (C) 2023 WeDPR. - * SPDX-License-Identifier: Apache-2.0 - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * @file wedpr_front_common.h - * @author: yujiechen - * @date 2024-08-22 - */ - -#ifndef __WEDPR_FRONT_COMMON_H__ -#define __WEDPR_FRONT_COMMON_H__ - -#include "wedpr_msg.h" - -typedef void (*wedpr_msg_handler_cb)(struct wedpr_msg* response, void* context); - -#endif diff --git a/cpp/wedpr-component-sdk/wedpr-front-cpp-sdk/wedpr_msg.h b/cpp/wedpr-component-sdk/wedpr-front-cpp-sdk/wedpr_msg.h deleted file mode 100644 index ae6f280e..00000000 --- a/cpp/wedpr-component-sdk/wedpr-front-cpp-sdk/wedpr_msg.h +++ /dev/null @@ -1,81 +0,0 @@ -/** - * Copyright (C) 2023 WeDPR. - * SPDX-License-Identifier: Apache-2.0 - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * @file wedpr_front_common.h - * @author: yujiechen - * @date 2024-08-22 - */ - -#ifndef __WEDPR_MSG_H__ -#define __WEDPR_MSG_H__ - -#include "ppc-framework/libwrapper/Buffer.h" - -#ifdef __cplusplus -extern "C" { -#endif - -struct gateway_optional_header -{ - // the componentType - uint8_t componentType; - // the source nodeID that send the message - OutputBuffer* srcNode; - // the target nodeID that should receive the message - OutputBuffer* dstNode; - // the target agency that need receive the message - OutputBuffer* dstInst; -}; - -struct gateway_msg_header -{ - // the msg version, used to support compatibility - uint8_t version; - // the traceID - OutputBuffer* traceID; - // the srcGwNode - OutputBuffer* srcGwNode; - // the dstGwNode - OutputBuffer* dstGwNode; - // the packetType - uint16_t packetType; - // the seq - uint32_t seq; - // the ttl - int16_t ttl; - // the ext(contains the router policy and response flag) - uint16_t ext; - //// the optional field(used to route between components and nodes) - struct gateway_optional_header* optionalFields; -}; - -struct front_payload -{ - // the front payload version, used to support compatibility - uint8_t version; - // the topic - OutputBuffer* topic; - OutputBuffer* data; -}; - -struct wedpr_msg -{ - gateway_msg_header* header; - front_payload* payload; -}; -#ifdef __cplusplus -} -#endif -#endif From ef3a682f8a6a11f3b89d3585822c63903a1d1343 Mon Sep 17 00:00:00 2001 From: cyjseagull Date: Sat, 24 Aug 2024 00:35:57 +0800 Subject: [PATCH 7/9] add Message and router implement --- cpp/cmake/IncludeDirectories.cmake | 1 + cpp/ppc-framework/Common.h | 15 + cpp/ppc-framework/gateway/GatewayProtocol.h | 37 +++ cpp/ppc-framework/protocol/Message.h | 150 +++++---- cpp/ppc-framework/protocol/MessagePayload.h | 68 ++++ cpp/ppc-gateway/ppc-gateway/p2p/Service.cpp | 299 ++++++++++++++++++ cpp/ppc-gateway/ppc-gateway/p2p/Service.h | 86 +++++ .../ppc-gateway/p2p/router/RouterManager.cpp | 189 +++++++++++ .../ppc-gateway/p2p/router/RouterManager.h | 72 +++++ .../p2p/router/RouterTableImpl.cpp | 273 ++++++++++++++++ .../ppc-gateway/p2p/router/RouterTableImpl.h | 132 ++++++++ .../p2p/router/RouterTableInterface.h | 92 ++++++ cpp/ppc-protocol/src/JsonTaskImpl.h | 23 +- cpp/ppc-protocol/src/v1/MessageHeaderImpl.cpp | 146 +++++++++ cpp/ppc-protocol/src/v1/MessageHeaderImpl.h | 82 +++++ cpp/ppc-protocol/src/v1/MessageImpl.cpp | 63 ++++ cpp/ppc-protocol/src/v1/MessageImpl.h | 84 +++++ .../src/v1/MessagePayloadImpl.cpp | 67 ++++ cpp/ppc-protocol/src/v1/MessagePayloadImpl.h | 54 ++++ .../ppc-tars-protocol/tars/RouterTable.tars | 13 + cpp/ppc-tools/src/codec/CodecUtility.h | 1 - cpp/ppc-utilities/Utilities.h | 18 +- cpp/vcpkg-configuration.json | 4 +- 23 files changed, 1884 insertions(+), 85 deletions(-) create mode 100644 cpp/ppc-framework/gateway/GatewayProtocol.h create mode 100644 cpp/ppc-framework/protocol/MessagePayload.h create mode 100644 cpp/ppc-gateway/ppc-gateway/p2p/Service.cpp create mode 100644 cpp/ppc-gateway/ppc-gateway/p2p/Service.h create mode 100644 cpp/ppc-gateway/ppc-gateway/p2p/router/RouterManager.cpp create mode 100644 cpp/ppc-gateway/ppc-gateway/p2p/router/RouterManager.h create mode 100644 cpp/ppc-gateway/ppc-gateway/p2p/router/RouterTableImpl.cpp create mode 100644 cpp/ppc-gateway/ppc-gateway/p2p/router/RouterTableImpl.h create mode 100644 cpp/ppc-gateway/ppc-gateway/p2p/router/RouterTableInterface.h create mode 100644 cpp/ppc-protocol/src/v1/MessageHeaderImpl.cpp create mode 100644 cpp/ppc-protocol/src/v1/MessageHeaderImpl.h create mode 100644 cpp/ppc-protocol/src/v1/MessageImpl.cpp create mode 100644 cpp/ppc-protocol/src/v1/MessageImpl.h create mode 100644 cpp/ppc-protocol/src/v1/MessagePayloadImpl.cpp create mode 100644 cpp/ppc-protocol/src/v1/MessagePayloadImpl.h create mode 100644 cpp/ppc-tars-protocol/ppc-tars-protocol/tars/RouterTable.tars diff --git a/cpp/cmake/IncludeDirectories.cmake b/cpp/cmake/IncludeDirectories.cmake index f63512f5..d6be1b25 100644 --- a/cpp/cmake/IncludeDirectories.cmake +++ b/cpp/cmake/IncludeDirectories.cmake @@ -1,5 +1,6 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR}) include_directories(${CMAKE_CURRENT_BINARY_DIR}) +include_directories(${CMAKE_BINARY_DIR}/generated/) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/ppc-front) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/ppc-gateway) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/wedpr-component-sdk) diff --git a/cpp/ppc-framework/Common.h b/cpp/ppc-framework/Common.h index 6034c5b6..2ae44dfd 100644 --- a/cpp/ppc-framework/Common.h +++ b/cpp/ppc-framework/Common.h @@ -59,10 +59,25 @@ namespace ppc DERIVE_PPC_EXCEPTION(OpenFileFailed); DERIVE_PPC_EXCEPTION(DataSchemaNotSetted); DERIVE_PPC_EXCEPTION(UnsupportedDataSchema); +DERIVE_PPC_EXCEPTION(WeDPRException); constexpr static int MAX_PORT = 65535; constexpr static int DEFAULT_SECURITY_PARAM = 128; +constexpr static size_t RSA_PUBLIC_KEY_PREFIX = 18; +constexpr static size_t RSA_PUBLIC_KEY_TRUNC = 8; +constexpr static size_t RSA_PUBLIC_KEY_TRUNC_LENGTH = 26; + +inline std::string_view printP2PIDElegantly(std::string_view p2pId) noexcept +{ + if (p2pId.length() < RSA_PUBLIC_KEY_TRUNC_LENGTH) + { + return p2pId; + } + return p2pId.substr(RSA_PUBLIC_KEY_PREFIX, RSA_PUBLIC_KEY_TRUNC); +} + + #if ENABLE_CPU_FEATURES #if X86 static const cpu_features::X86Features CPU_FEATURES = cpu_features::GetX86Info().features; diff --git a/cpp/ppc-framework/gateway/GatewayProtocol.h b/cpp/ppc-framework/gateway/GatewayProtocol.h new file mode 100644 index 00000000..c3c0a94d --- /dev/null +++ b/cpp/ppc-framework/gateway/GatewayProtocol.h @@ -0,0 +1,37 @@ +/** + * Copyright (C) 2023 WeDPR. + * SPDX-License-Identifier: Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @file Message.h + * @author: yujiechen + * @date 2024-08-22 + */ +#pragma once +#include + +namespace ppc::gateway +{ +enum class GatewayPacketType : uint16_t +{ + P2PMessage = 0x00, + RouterTableSyncSeq = 0x10, + RouterTableResponse = 0x11, + RouterTableRequest = 0x12 +}; + +enum class GatewayMsgExtFlag : uint16_t +{ + Response = 0x1, +}; +} // namespace ppc::gateway \ No newline at end of file diff --git a/cpp/ppc-framework/protocol/Message.h b/cpp/ppc-framework/protocol/Message.h index 0aa7443a..40c5f614 100644 --- a/cpp/ppc-framework/protocol/Message.h +++ b/cpp/ppc-framework/protocol/Message.h @@ -18,9 +18,12 @@ * @date 2024-08-22 */ #pragma once +#include "../Common.h" #include #include +#include #include +#include namespace ppc::protocol { @@ -31,18 +34,24 @@ class MessageOptionalHeader MessageOptionalHeader() = default; virtual ~MessageOptionalHeader() = default; - virtual bcos::bytes encode() const = 0; + virtual void encode(bcos::bytes& buffer) const = 0; + virtual int64_t decode(bcos::bytesConstRef data, uint64_t const _offset) = 0; + // the componentType virtual uint8_t componentType() const { return m_componentType; } + virtual void setComponentType(uint8_t componentType) { m_componentType = componentType; } + // the source nodeID that send the message virtual bcos::bytes const& srcNode() const { return m_srcNode; } + virtual void setSrcNode(bcos::bytes const& srcNode) { m_srcNode = srcNode; } + // the target nodeID that should receive the message virtual bcos::bytes const& dstNode() const { return m_dstNode; } + virtual void setDstNode(bcos::bytes const& dstNode) { m_dstNode = dstNode; } + // the target agency that need receive the message virtual bcos::bytes const& dstInst() const { return m_dstInst; } - -protected: - virtual uint32_t decode(bcos::bytesConstRef data) = 0; + virtual void setDstInst(bcos::bytes const& dstInst) { m_dstInst = dstInst; } protected: // the componentType @@ -54,6 +63,7 @@ class MessageOptionalHeader // the target agency that need receive the message bcos::bytes m_dstInst; }; + class MessageHeader { public: @@ -61,41 +71,51 @@ class MessageHeader MessageHeader() = default; virtual ~MessageHeader() = default; - virtual bcos::bytes encode() const = 0; + virtual void encode(bcos::bytes& buffer) const = 0; + virtual int64_t decode(bcos::bytesConstRef data) = 0; // the msg version, used to support compatibility virtual uint8_t version() const { return m_version; } + virtual void setVersion(uint16_t version) { m_version = version; } // the traceID virtual std::string const& traceID() const { return m_traceID; } + virtual void setTraceID(std::string traceID) { m_traceID = traceID; } + // the srcGwNode - virtual bcos::bytes const& srcGwNode() const { return m_srcGwNode; } + virtual std::string const& srcGwNode() const { return m_srcGwNode; } + virtual void setSrcGwNode(std::string const& srcGwNode) { m_srcGwNode = srcGwNode; } + // the dstGwNode - virtual bcos::bytes const& dstGwNode() const { return m_dstGwNode; } + virtual std::string const& dstGwNode() const { return m_dstGwNode; } + virtual void setDstGwNode(std::string const& dstGwNode) { m_dstGwNode = dstGwNode; } + // the packetType virtual uint16_t packetType() const { return m_packetType; } + virtual void setPacketType(uint16_t packetType) { m_packetType = packetType; } // the ttl virtual int16_t ttl() const { return m_ttl; } + virtual void setTTL(uint16_t ttl) { m_ttl = ttl; } + // the ext(contains the router policy and response flag) virtual uint16_t ext() const { return m_ext; } - //// the optional field(used to route between components and nodes) - virtual MessageOptionalHeader::Ptr optionalFields() const { return m_optionalFields; } - - virtual uint32_t length() const { return m_length; } - - virtual void setVersion(uint16_t version) { m_version = version; } - virtual void setPacketType(uint16_t packetType) { m_packetType = packetType; } - // the seq is the traceID - virtual void setTraceID(std::string traceID) { m_traceID = traceID; } virtual void setExt(uint16_t ext) { m_ext = ext; } + //// the optional field(used to route between components and nodes) + virtual MessageOptionalHeader::Ptr optionalField() const { return m_optionalField; } + void setOptionalField(MessageOptionalHeader::Ptr optionalField) + { + m_optionalField = std::move(optionalField); + } - uint64_t packetLen() const { return m_packetLen; } - uint16_t headerLen() const { return m_headerLen; } + virtual uint16_t length() const { return m_length; } virtual bool isRespPacket() const = 0; virtual void setRespPacket() = 0; -protected: - virtual uint32_t decode(bcos::bytesConstRef data) = 0; + + // Note: only for log + std::string_view srcP2PNodeIDView() const { return printP2PIDElegantly(m_srcGwNode); } + // Note: only for log + std::string_view dstP2PNodeIDView() const { return printP2PIDElegantly(m_dstGwNode); } protected: // the msg version, used to support compatibility @@ -103,9 +123,9 @@ class MessageHeader // the traceID std::string m_traceID; // the srcGwNode - bcos::bytes m_srcGwNode; + std::string m_srcGwNode; // the dstGwNode - bcos::bytes m_dstGwNode; + std::string m_dstGwNode; // the packetType uint16_t m_packetType; // the ttl @@ -113,37 +133,8 @@ class MessageHeader // the ext(contains the router policy and response flag) uint16_t m_ext; //// the optional field(used to route between components and nodes) - MessageOptionalHeader::Ptr m_optionalFields; - uint64_t m_packetLen; - uint16_t m_headerLen; -}; - -class MessagePayload -{ -public: - using Ptr = std::shared_ptr; - MessagePayload() = default; - virtual ~MessagePayload() = default; - - virtual bcos::bytes encode() const = 0; - - // the version - virtual uint8_t version() const { return m_version; } - // the topic - virtual std::string const& topic() const { return m_topic; } - virtual bcos::bytes const& data() const { return m_data; } - virtual uint32_t length() const { return m_length; } - -protected: - virtual uint32_t decode(uint32_t startPos, bcos::bytesConstRef data) = 0; - -protected: - // the front payload version, used to support compatibility - uint8_t m_version; - // the topic - std::string m_topic; - bcos::bytes m_data; - uint32_t m_length; + MessageOptionalHeader::Ptr m_optionalField; + uint16_t mutable m_length; }; class Message : virtual public bcos::boostssl::MessageFace @@ -154,36 +145,48 @@ class Message : virtual public bcos::boostssl::MessageFace ~Message() override {} virtual MessageHeader::Ptr header() const { return m_header; } - virtual MessagePayLoad::Ptr payload() const { return m_payload; } + virtual void setHeader(MessageHeader::Ptr header) { m_header = std::move(header); } + /// the overloaed implementation === uint16_t version() const override { return m_header->version(); } - void setVersion(uint16_t version) override{m_header->setVersion(version)} uint16_t - packetType() const override - { - return m_header->packetType(); - } + void setVersion(uint16_t version) override { m_header->setVersion(version); } + uint16_t packetType() const override { return m_header->packetType(); } void setPacketType(uint16_t packetType) override { m_header->setPacketType(packetType); } std::string const& seq() const override { return m_header->traceID(); } void setSeq(std::string traceID) override { m_header->setTraceID(traceID); } uint16_t ext() const override { return m_header->ext(); } - void setExt(uint16_t ext) override { m_header->setExt(except); } + void setExt(uint16_t ext) override { m_header->setExt(ext); } bool isRespPacket() const override { return m_header->isRespPacket(); } void setRespPacket() override { m_header->setRespPacket(); } - virtual uint32_t length() const override { return m_header->packetLen(); } + virtual uint32_t length() const override + { + return m_header->length() + (m_payload ? m_payload->size() : 0); + } + std::shared_ptr payload() const override { return m_payload; } void setPayload(std::shared_ptr _payload) override { m_payload = std::move(_payload); } - protected: MessageHeader::Ptr m_header; std::shared_ptr m_payload; }; +class MessageHeaderBuilder +{ +public: + using Ptr = std::shared_ptr; + MessageHeaderBuilder() = default; + virtual ~MessageHeaderBuilder() = default; + + virtual MessageHeader::Ptr build(bcos::bytesConstRef _data) = 0; + virtual MessageHeader::Ptr build() = 0; +}; + class MessageBuilder { public: @@ -191,5 +194,28 @@ class MessageBuilder virtual ~MessageBuilder() = default; virtual Message::Ptr build() = 0; + virtual Message::Ptr build(bcos::bytesConstRef buffer) = 0; +}; + +inline std::string printMessage(Message::Ptr const& _msg) +{ + std::ostringstream stringstream; + stringstream << LOG_KV("from", _msg->header()->srcP2PNodeIDView()) + << LOG_KV("to", _msg->header()->dstP2PNodeIDView()) + << LOG_KV("ttl", _msg->header()->ttl()) + << LOG_KV("rsp", _msg->header()->isRespPacket()) + << LOG_KV("traceID", _msg->header()->traceID()) + << LOG_KV("packetType", _msg->header()->packetType()) + << LOG_KV("length", _msg->length()); + return stringstream.str(); +} + +inline std::string printWsMessage(bcos::boostssl::MessageFace::Ptr const& _msg) +{ + std::ostringstream stringstream; + stringstream << LOG_KV("rsp", _msg->isRespPacket()) << LOG_KV("traceID", _msg->seq()) + << LOG_KV("packetType", _msg->packetType()) << LOG_KV("length", _msg->length()); + return stringstream.str(); } + } // namespace ppc::protocol \ No newline at end of file diff --git a/cpp/ppc-framework/protocol/MessagePayload.h b/cpp/ppc-framework/protocol/MessagePayload.h new file mode 100644 index 00000000..4329aae2 --- /dev/null +++ b/cpp/ppc-framework/protocol/MessagePayload.h @@ -0,0 +1,68 @@ +/** + * Copyright (C) 2023 WeDPR. + * SPDX-License-Identifier: Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @file MessagePayload.h + * @author: yujiechen + * @date 2024-08-22 + */ +#pragma once +#include +#include + +namespace ppc::protocol +{ +class MessagePayload +{ +public: + using Ptr = std::shared_ptr; + MessagePayload() = default; + virtual ~MessagePayload() = default; + + virtual int64_t encode(bcos::bytes& buffer) const = 0; + virtual int64_t decode(bcos::bytesConstRef data) = 0; + + // the version + virtual uint8_t version() const { return m_version; } + virtual void setVersion(uint8_t version) { m_version = version; } + // the topic + virtual std::string const& topic() const { return m_topic; } + virtual void setTopic(std::string&& topic) { m_topic = std::move(topic); } + virtual void setTopic(std::string const& topic) { m_topic = topic; } + // data + virtual bcos::bytes const& data() const { return m_data; } + virtual void setData(bcos::bytes&& data) { m_data = std::move(data); } + virtual void setData(bcos::bytes const& data) { m_data = data; } + // the length + virtual int64_t length() const { return m_length; } + +protected: + // the front payload version, used to support compatibility + uint8_t m_version; + // the topic + std::string m_topic; + bcos::bytes m_data; + int64_t mutable m_length; +}; + +class MessagePayloadBuilder +{ +public: + using Ptr = std::shared_ptr; + MessagePayloadBuilder() = default; + virtual ~MessagePayloadBuilder() = default; + virtual MessagePayload::Ptr build() = 0; + virtual MessagePayload::Ptr build(bcos::bytesConstRef buffer) = 0; +}; +} // namespace ppc::protocol \ No newline at end of file diff --git a/cpp/ppc-gateway/ppc-gateway/p2p/Service.cpp b/cpp/ppc-gateway/ppc-gateway/p2p/Service.cpp new file mode 100644 index 00000000..469e5b27 --- /dev/null +++ b/cpp/ppc-gateway/ppc-gateway/p2p/Service.cpp @@ -0,0 +1,299 @@ +/** + * Copyright (C) 2023 WeDPR. + * SPDX-License-Identifier: Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @file Service.cpp + * @author: yujiechen + * @date 2024-08-26 + */ + +#include "Service.h" +#include "bcos-boostssl/websocket/WsError.h" +#include "ppc-framework/Common.h" + +using namespace bcos; +using namespace ppc; +using namespace ppc::gateway; +using namespace ppc::protocol; +using namespace bcos::boostssl::ws; +using namespace bcos::boostssl; + +Service::Service(std::string const& _nodeID, RouterTableFactory::Ptr const& _routerTableFactory, + int unreachableDistance, std::string _moduleName) + : WsService(_moduleName) +{ + m_nodeID = _nodeID; + m_routerTableFactory = _routerTableFactory; + // create the local router + m_routerTable = m_routerTableFactory->createRouterTable(); + m_routerTable->setNodeID(m_nodeID); + m_routerTable->setUnreachableDistance(unreachableDistance); + + GATEWAY_LOG(INFO) << LOG_DESC("create P2PService") << LOG_KV("module", _moduleName); + WsService::registerConnectHandler( + boost::bind(&Service::onP2PConnect, this, boost::placeholders::_1)); + WsService::registerDisconnectHandler( + boost::bind(&Service::onP2PDisconnect, this, boost::placeholders::_1)); +} + + +void Service::onP2PConnect(WsSession::Ptr _session) +{ + GATEWAY_LOG(INFO) << LOG_DESC("onP2PConnect") << LOG_KV("p2pid", _session->nodeId()) + << LOG_KV("endpoint", _session->endPoint()); + + + RecursiveGuard l(x_nodeID2Session); + auto it = m_nodeID2Session.find(_session->nodeId()); + // the session already connected + if (it != m_nodeID2Session.end() && it->second->isConnected()) + { + GATEWAY_LOG(INFO) << LOG_DESC("onP2PConnect, drop the duplicated connection") + << LOG_KV("nodeID", _session->nodeId()) + << LOG_KV("endpoint", _session->endPoint()); + _session->drop(WsError::UserDisconnect); + updateNodeIDInfo(_session); + return; + } + // the node-self + if (_session->nodeId() == m_nodeID) + { + updateNodeIDInfo(_session); + GATEWAY_LOG(INFO) << LOG_DESC("onP2PConnect, drop the node-self connection") + << LOG_KV("nodeID", _session->nodeId()) + << LOG_KV("endpoint", _session->endPoint()); + _session->drop(WsError::UserDisconnect); + return; + } + // the new session + updateNodeIDInfo(_session); + if (it != m_nodeID2Session.end()) + { + it->second = _session; + } + else + { + m_nodeID2Session.insert(std::make_pair(_session->nodeId(), _session)); + } + GATEWAY_LOG(INFO) << LOG_DESC("onP2PConnect established") << LOG_KV("p2pid", _session->nodeId()) + << LOG_KV("endpoint", _session->endPoint()); +} + + +void Service::updateNodeIDInfo(WsSession::Ptr const& _session) +{ + bcos::WriteGuard l(x_configuredNode2ID); + std::string p2pNodeID = _session->nodeId(); + auto it = m_configuredNode2ID.find(_session->endPointInfo()); + if (it != m_configuredNode2ID.end()) + { + it->second = p2pNodeID; + GATEWAY_LOG(INFO) << LOG_DESC("updateNodeIDInfo: update the nodeID") + << LOG_KV("nodeid", p2pNodeID) + << LOG_KV("endpoint", _session->endPoint()); + } + else + { + GATEWAY_LOG(INFO) << LOG_DESC("updateNodeIDInfo can't find endpoint") + << LOG_KV("nodeid", p2pNodeID) + << LOG_KV("endpoint", _session->endPoint()); + } +} + +void Service::removeSessionInfo(WsSession::Ptr const& _session) +{ + RecursiveGuard l(x_nodeID2Session); + auto it = m_nodeID2Session.find(_session->nodeId()); + if (it != m_nodeID2Session.end()) + { + GATEWAY_LOG(INFO) << "onP2PDisconnectand remove from m_nodeID2Session" + << LOG_KV("p2pid", _session->nodeId()) + << LOG_KV("endpoint", _session->endPoint()); + + m_nodeID2Session.erase(it); + } +} +void Service::onP2PDisconnect(WsSession::Ptr _session) +{ + // remove the session information + removeSessionInfo(_session); + // update the session nodeID to empty + UpgradableGuard l(x_configuredNode2ID); + for (auto& it : m_configuredNode2ID) + { + if (it.second == _session->nodeId()) + { + UpgradeGuard ul(l); + it.second.clear(); + break; + } + } +} + +void Service::reconnect() +{ + // obtain the un-connected peers information + EndPointsPtr unconnectedPeers = std::make_shared>(); + { + bcos::ReadGuard l(x_configuredNode2ID); + for (auto const& it : m_configuredNode2ID) + { + if (it.second == nodeID()) + { + continue; + } + if (!it.second.empty() && isConnected(it.first)) + { + continue; + } + unconnectedPeers->insert(it.first); + } + } + setReconnectedPeers(unconnectedPeers); + WsService::reconnect(); +} + +WsSession::Ptr Service::getSessionByNodeID(std::string const& _nodeID) +{ + RecursiveGuard l(x_nodeID2Session); + auto it = m_nodeID2Session.find(_nodeID); + if (it == m_nodeID2Session.end()) + { + return nullptr; + } + return it->second; +} + +void Service::asyncSendMessageByNodeID( + std::string const& dstNodeID, MessageFace::Ptr msg, Options options, RespCallBack respFunc) +{ + auto p2pMsg = std::dynamic_pointer_cast(msg); + if (p2pMsg->header()->dstGwNode().empty()) + { + p2pMsg->header()->setDstGwNode(dstNodeID); + } + if (p2pMsg->header()->srcGwNode().empty()) + { + p2pMsg->header()->setSrcGwNode(m_nodeID); + } + return asyncSendMessageWithForward(dstNodeID, msg, options, respFunc); +} + +void Service::asyncSendMessageWithForward( + std::string const& dstNodeID, MessageFace::Ptr msg, Options options, RespCallBack respFunc) +{ + auto p2pMsg = std::dynamic_pointer_cast(msg); + // without nextHop: maybe network unreachable or with distance equal to 1 + auto nextHop = m_routerTable->getNextHop(dstNodeID); + if (nextHop.empty()) + { + return asyncSendMessage(dstNodeID, msg, options, respFunc); + } + // with nextHop, send the message to nextHop + GATEWAY_LOG(TRACE) << LOG_DESC("asyncSendMessageByNodeID") << printMessage(p2pMsg); + return asyncSendMessage(nextHop, msg, options, respFunc); +} + + +void Service::asyncSendMessage( + std::string const& dstNodeID, MessageFace::Ptr msg, Options options, RespCallBack respFunc) +{ + try + { + // ignore self + if (dstNodeID == m_nodeID) + { + return; + } + auto session = getSessionByNodeID(dstNodeID); + if (session) + { + WsSessions sessions = WsSessions(); + sessions.emplace_back(session); + return WsService::asyncSendMessage(sessions, msg, options, respFunc); + } + + if (respFunc) + { + Error::Ptr error = std::make_shared( + -1, "send message to " + dstNodeID + + " failed for no network established, msg: " + printWsMessage(msg)); + respFunc(std::move(error), nullptr, nullptr); + } + GATEWAY_LOG(WARNING) + << LOG_DESC("asyncSendMessageByNodeID failed for no network established, msg detail:") + << printWsMessage(msg); + } + catch (std::exception const& e) + { + GATEWAY_LOG(ERROR) << "asyncSendMessageByNodeID" << LOG_KV("dstNode", dstNodeID) + << LOG_KV("what", boost::diagnostic_information(e)); + if (respFunc) + { + respFunc(std::make_shared(-1, "send message to " + dstNodeID + " failed for " + + boost::diagnostic_information(e)), + nullptr, nullptr); + } + } +} + +void Service::onRecvMessage(MessageFace::Ptr _msg, std::shared_ptr _session) +{ + auto p2pMsg = std::dynamic_pointer_cast(_msg); + // find the dstNode + if (p2pMsg->header()->dstGwNode().empty() || p2pMsg->header()->dstGwNode() == m_nodeID) + { + GATEWAY_LOG(TRACE) << LOG_DESC("onRecvMessage, dispatch for find the dst node") + << printMessage(p2pMsg); + WsService::onRecvMessage(_msg, _session); + return; + } + // forward the message + if (p2pMsg->header()->ttl() >= m_routerTable->unreachableDistance()) + { + GATEWAY_LOG(WARNING) << LOG_DESC("onRecvMessage: ttl expired") << printMessage(p2pMsg); + return; + } + p2pMsg->header()->setTTL(p2pMsg->header()->ttl() + 1); + asyncSendMessageWithForward( + p2pMsg->header()->dstGwNode(), p2pMsg, bcos::boostssl::ws::Options(), nullptr); +} + + +void Service::asyncBroadcastMessage(bcos::boostssl::MessageFace::Ptr msg, Options options) +{ + auto reachableNodes = m_routerTable->getAllReachableNode(); + try + { + for (auto const& node : reachableNodes) + { + asyncSendMessageByNodeID(node, msg, options); + } + } + catch (std::exception& e) + { + GATEWAY_LOG(WARNING) << LOG_BADGE("asyncBroadcastMessage exception") + << LOG_KV("msg", printWsMessage(msg)) + << LOG_KV("error", boost::diagnostic_information(e)); + } +} + +void Service::asyncSendMessageByP2PNodeID(uint16_t type, std::string const& dstNodeID, + std::shared_ptr payload, Options options, RespCallBack callback) +{ + auto message = m_messageFactory->buildMessage(); + message->setPacketType(type); + message->setPayload(payload); + asyncSendMessageByNodeID(dstNodeID, message, options, callback); +} \ No newline at end of file diff --git a/cpp/ppc-gateway/ppc-gateway/p2p/Service.h b/cpp/ppc-gateway/ppc-gateway/p2p/Service.h new file mode 100644 index 00000000..a3c8f5ea --- /dev/null +++ b/cpp/ppc-gateway/ppc-gateway/p2p/Service.h @@ -0,0 +1,86 @@ +/** + * Copyright (C) 2023 WeDPR. + * SPDX-License-Identifier: Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @file Service.h + * @author: yujiechen + * @date 2024-08-26 + */ + +#pragma once +#include "../Common.h" +#include "ppc-framework/protocol/Message.h" +#include "router/RouterTableInterface.h" +#include +namespace ppc::gateway +{ +class Service : public bcos::boostssl::ws::WsService +{ +public: + using Ptr = std::shared_ptr; + Service(std::string const& _nodeID, RouterTableFactory::Ptr const& _routerTableFactory, + int unreachableDistance, std::string _moduleName = "DEFAULT"); + + virtual void asyncSendMessageByNodeID(std::string const& dstNodeID, + bcos::boostssl::MessageFace::Ptr msg, + bcos::boostssl::ws::Options options = bcos::boostssl::ws::Options(), + bcos::boostssl::ws::RespCallBack respFunc = bcos::boostssl::ws::RespCallBack()); + virtual void asyncSendMessageByP2PNodeID(uint16_t type, std::string const& dstNodeID, + std::shared_ptr payload, + bcos::boostssl::ws::Options options = bcos::boostssl::ws::Options(), + bcos::boostssl::ws::RespCallBack callback = bcos::boostssl::ws::RespCallBack()); + + virtual void asyncBroadcastMessage(bcos::boostssl::MessageFace::Ptr msg, + bcos::boostssl::ws::Options options = bcos::boostssl::ws::Options()); + + RouterTableFactory::Ptr const& routerTableFactory() const { return m_routerTableFactory; } + RouterTableInterface::Ptr const& routerTable() const { return m_routerTable; } + + std::string const& nodeID() const { return m_nodeID; } + +protected: + void onRecvMessage(bcos::boostssl::MessageFace::Ptr _msg, + bcos::boostssl::ws::WsSession::Ptr _session) override; + + virtual void onP2PConnect(bcos::boostssl::ws::WsSession::Ptr _session); + virtual void onP2PDisconnect(bcos::boostssl::ws::WsSession::Ptr _session); + + void reconnect() override; + + void updateNodeIDInfo(bcos::boostssl::ws::WsSession::Ptr const& _session); + void removeSessionInfo(bcos::boostssl::ws::WsSession::Ptr const& _session); + bcos::boostssl::ws::WsSession::Ptr getSessionByNodeID(std::string const& _nodeID); + + virtual void asyncSendMessageWithForward(std::string const& dstNodeID, + bcos::boostssl::MessageFace::Ptr msg, bcos::boostssl::ws::Options options, + bcos::boostssl::ws::RespCallBack respFunc); + + virtual void asyncSendMessage(std::string const& dstNodeID, + bcos::boostssl::MessageFace::Ptr msg, bcos::boostssl::ws::Options options, + bcos::boostssl::ws::RespCallBack respFunc); + +protected: + std::string m_nodeID; + // nodeID=>session + std::unordered_map m_nodeID2Session; + bcos::RecursiveMutex x_nodeID2Session; + + RouterTableFactory::Ptr m_routerTableFactory; + RouterTableInterface::Ptr m_routerTable; + + // configuredNode=>nodeID + std::map m_configuredNode2ID; + mutable bcos::SharedMutex x_configuredNode2ID; +}; +} // namespace ppc::gateway \ No newline at end of file diff --git a/cpp/ppc-gateway/ppc-gateway/p2p/router/RouterManager.cpp b/cpp/ppc-gateway/ppc-gateway/p2p/router/RouterManager.cpp new file mode 100644 index 00000000..00f3e7c7 --- /dev/null +++ b/cpp/ppc-gateway/ppc-gateway/p2p/router/RouterManager.cpp @@ -0,0 +1,189 @@ +/** + * Copyright (C) 2023 WeDPR. + * SPDX-License-Identifier: Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @file RouterManager.cpp + * @author: yujiechen + * @date 2024-08-26 + */ +#include "RouterManager.h" +#include "ppc-framework/gateway/GatewayProtocol.h" +#include "ppc-framework/protocol/Message.h" +#include + +using namespace bcos; +using namespace bcos::boostssl::ws; +using namespace bcos::boostssl; +using namespace ppc::gateway; +using namespace ppc::protocol; + +RouterManager::RouterManager(Service::Ptr service) : m_service(std::move(service)) +{ + // process router packet related logic + m_service->registerMsgHandler((uint16_t)GatewayPacketType::RouterTableSyncSeq, + boost::bind(&RouterManager::onReceiveRouterSeq, this, boost::placeholders::_1, + boost::placeholders::_2)); + + m_service->registerMsgHandler((uint16_t)GatewayPacketType::RouterTableResponse, + boost::bind(&RouterManager::onReceivePeersRouterTable, this, boost::placeholders::_1, + boost::placeholders::_2)); + + m_service->registerMsgHandler((uint16_t)GatewayPacketType::RouterTableRequest, + boost::bind(&RouterManager::onReceiveRouterTableRequest, this, boost::placeholders::_1, + boost::placeholders::_2)); + m_routerTimer = std::make_shared(3000, "routerSeqSync"); + m_routerTimer->registerTimeoutHandler([this]() { broadcastRouterSeq(); }); +} + +void RouterManager::start() +{ + if (m_routerTimer) + { + m_routerTimer->start(); + } +} + +void RouterManager::stop() +{ + if (m_routerTimer) + { + m_routerTimer->stop(); + } +} + +void RouterManager::onReceiveRouterSeq(MessageFace::Ptr msg, WsSession::Ptr session) +{ + auto statusSeq = + boost::asio::detail::socket_ops::network_to_host_long(*((uint32_t*)msg->payload()->data())); + if (!tryToUpdateSeq(session->nodeId(), statusSeq)) + { + return; + } + GATEWAY_LOG(INFO) << LOG_BADGE("onReceiveRouterSeq") + << LOG_DESC("receive router seq and request router table") + << LOG_KV("peer", session->nodeId()) << LOG_KV("seq", statusSeq); + // request router table to peer + auto p2pMsg = std::dynamic_pointer_cast(msg); + auto dstP2PNodeID = (!p2pMsg->header()->srcGwNode().empty()) ? p2pMsg->header()->srcGwNode() : + session->nodeId(); + m_service->asyncSendMessageByP2PNodeID((uint16_t)GatewayPacketType::RouterTableRequest, + dstP2PNodeID, std::make_shared()); +} + +bool RouterManager::tryToUpdateSeq(std::string const& _p2pNodeID, uint32_t _seq) +{ + UpgradableGuard l(x_node2Seq); + auto it = m_node2Seq.find(_p2pNodeID); + if (it != m_node2Seq.end() && it->second >= _seq) + { + return false; + } + UpgradeGuard upgradeGuard(l); + m_node2Seq[_p2pNodeID] = _seq; + return true; +} + +// receive routerTable from peers +void RouterManager::onReceivePeersRouterTable(MessageFace::Ptr msg, WsSession::Ptr session) +{ + auto routerTable = m_service->routerTableFactory()->createRouterTable(ref(*(msg->payload()))); + + GATEWAY_LOG(INFO) << LOG_BADGE("onReceivePeersRouterTable") << LOG_KV("peer", session->nodeId()) + << LOG_KV("entrySize", routerTable->routerEntries().size()); + joinRouterTable(session->nodeId(), routerTable); +} + +// receive routerTable request from peer +void RouterManager::onReceiveRouterTableRequest(MessageFace::Ptr msg, WsSession::Ptr session) +{ + GATEWAY_LOG(INFO) << LOG_BADGE("onReceiveRouterTableRequest") + << LOG_KV("peer", session->nodeId()) + << LOG_KV("entrySize", m_service->routerTable()->routerEntries().size()); + + auto routerTableData = std::make_shared(); + m_service->routerTable()->encode(*routerTableData); + auto p2pMsg = std::dynamic_pointer_cast(msg); + auto dstP2PNodeID = (!p2pMsg->header()->srcGwNode().empty()) ? p2pMsg->header()->srcGwNode() : + session->nodeId(); + m_service->asyncSendMessageByP2PNodeID( + (uint16_t)GatewayPacketType::RouterTableResponse, dstP2PNodeID, routerTableData); +} + +void RouterManager::joinRouterTable( + std::string const& _generatedFrom, RouterTableInterface::Ptr _routerTable) +{ + std::set unreachableNodes; + bool updated = false; + auto const& entries = _routerTable->routerEntries(); + for (auto const& it : entries) + { + auto entry = it.second; + if (m_service->routerTable()->update(unreachableNodes, _generatedFrom, entry) && !updated) + { + updated = true; + } + } + + GATEWAY_LOG(INFO) << LOG_BADGE("joinRouterTable") << LOG_DESC("create router entry") + << LOG_KV("dst", _generatedFrom); + + auto entry = m_service->routerTableFactory()->createRouterEntry(); + entry->setDstNode(_generatedFrom); + entry->setDistance(0); + if (m_service->routerTable()->update(unreachableNodes, m_service->nodeID(), entry) && !updated) + { + updated = true; + } + if (!updated) + { + GATEWAY_LOG(DEBUG) << LOG_BADGE("joinRouterTable") << LOG_DESC("router table not updated") + << LOG_KV("dst", _generatedFrom); + return; + } + onP2PNodesUnreachable(unreachableNodes); + m_statusSeq++; + broadcastRouterSeq(); +} + + +// called when the nodes become unreachable +void RouterManager::onP2PNodesUnreachable(std::set const& _p2pNodeIDs) +{ + std::vector> handlers; + { + ReadGuard readGuard(x_unreachableHandlers); + handlers = m_unreachableHandlers; + } + // TODO: async here + for (auto const& node : _p2pNodeIDs) + { + for (auto const& it : m_unreachableHandlers) + { + it(node); + } + } +} + +void RouterManager::broadcastRouterSeq() +{ + m_routerTimer->restart(); + + auto seq = m_statusSeq.load(); + auto statusSeq = boost::asio::detail::socket_ops::host_to_network_long(seq); + auto message = m_service->messageFactory()->buildMessage(); + message->setPacketType((uint16_t)GatewayPacketType::RouterTableSyncSeq); + message->setPayload(std::make_shared((byte*)&statusSeq, (byte*)&statusSeq + 4)); + // the router table should only exchange between neighbor + m_service->broadcastMessage(message); +} \ No newline at end of file diff --git a/cpp/ppc-gateway/ppc-gateway/p2p/router/RouterManager.h b/cpp/ppc-gateway/ppc-gateway/p2p/router/RouterManager.h new file mode 100644 index 00000000..f99c0182 --- /dev/null +++ b/cpp/ppc-gateway/ppc-gateway/p2p/router/RouterManager.h @@ -0,0 +1,72 @@ +/** + * Copyright (C) 2023 WeDPR. + * SPDX-License-Identifier: Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @file RouterManager.h + * @author: yujiechen + * @date 2024-08-26 + */ + +#pragma once +#include "../Service.h" +#include "RouterTableInterface.h" +#include + +namespace ppc::gateway +{ +class RouterManager +{ +public: + RouterManager(Service::Ptr service); + virtual ~RouterManager() = default; + + // handlers called when the node is unreachable + void registerUnreachableHandler(std::function _handler) + { + bcos::WriteGuard l(x_unreachableHandlers); + m_unreachableHandlers.emplace_back(_handler); + } + + virtual void start(); + virtual void stop(); + +private: + void onReceiveRouterSeq( + bcos::boostssl::MessageFace::Ptr msg, bcos::boostssl::ws::WsSession::Ptr session); + bool tryToUpdateSeq(std::string const& _p2pNodeID, uint32_t _seq); + void broadcastRouterSeq(); + + void onReceivePeersRouterTable( + bcos::boostssl::MessageFace::Ptr msg, bcos::boostssl::ws::WsSession::Ptr session); + void onReceiveRouterTableRequest( + bcos::boostssl::MessageFace::Ptr msg, bcos::boostssl::ws::WsSession::Ptr session); + + void joinRouterTable(std::string const& _generatedFrom, RouterTableInterface::Ptr _routerTable); + + void onP2PNodesUnreachable(std::set const& _p2pNodeIDs); + +private: + // for message forward + Service::Ptr m_service; + std::shared_ptr m_routerTimer; + std::atomic m_statusSeq{1}; + + // called when the given node unreachable + std::vector> m_unreachableHandlers; + mutable bcos::SharedMutex x_unreachableHandlers; + + std::map m_node2Seq; + mutable bcos::SharedMutex x_node2Seq; +}; +} // namespace ppc::gateway \ No newline at end of file diff --git a/cpp/ppc-gateway/ppc-gateway/p2p/router/RouterTableImpl.cpp b/cpp/ppc-gateway/ppc-gateway/p2p/router/RouterTableImpl.cpp new file mode 100644 index 00000000..f8a2a22a --- /dev/null +++ b/cpp/ppc-gateway/ppc-gateway/p2p/router/RouterTableImpl.cpp @@ -0,0 +1,273 @@ +/* + * Copyright (C) 2024 WeDPR. + * SPDX-License-Identifier: Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @file RouterTableImpl.cpp + * @author: yujiechen + * @date 2022-5-24 + */ +#include "RouterTableImpl.h" +#include "ppc-gateway/Common.h" + +using namespace bcos; +using namespace ppc::gateway; +using namespace ppc::protocol; + +void RouterTable::encode(bcos::bytes& _encodedData) +{ + WriteGuard writeGuard(x_routerEntries); + m_inner()->routerEntries.clear(); + // encode m_routerEntries + for (auto const& it : m_routerEntries) + { + auto entry = std::dynamic_pointer_cast(it.second); + m_inner()->routerEntries.emplace_back(entry->inner()); + } + tars::TarsOutputStream output; + m_inner()->writeTo(output); + output.getByteBuffer().swap(_encodedData); +} + +void RouterTable::decode(bcos::bytesConstRef _decodedData) +{ + tars::TarsInputStream input; + input.setBuffer((const char*)_decodedData.data(), _decodedData.size()); + WriteGuard writeGuard(x_routerEntries); + m_inner()->readFrom(input); + // decode into m_routerEntries + m_routerEntries.clear(); + for (auto& it : m_inner()->routerEntries) + { + auto entry = + std::make_shared([m_entry = it]() mutable { return &m_entry; }); + m_routerEntries.insert(std::make_pair(entry->dstNode(), entry)); + } +} + +bool RouterTable::erase(std::set& _unreachableNodes, std::string const& _p2pNodeID) +{ + bool updated = false; + WriteGuard writeGuard(x_routerEntries); + // erase router-entry of the _p2pNodeID + auto it = m_routerEntries.find(_p2pNodeID); + if (it != m_routerEntries.end()) + { + // Note: reset the distance to m_unreachableDistance, to notify that the _p2pNodeID is + // unreachable + it->second->setDistance(m_unreachableDistance); + it->second->clearNextHop(); + _unreachableNodes.insert(it->second->dstNode()); + + GATEWAY_LOG(INFO) << LOG_BADGE("erase") << LOG_DESC("make the router unreachable") + << LOG_KV("dst", _p2pNodeID) << LOG_KV("distance", it->second->distance()) + << LOG_KV("size", m_routerEntries.size()); + updated = true; + } + // update the router-entry with nextHop equal to _p2pNodeID to be unreachable + updateDistanceForAllRouterEntries(_unreachableNodes, _p2pNodeID, m_unreachableDistance); + return updated; +} + +void RouterTable::updateDistanceForAllRouterEntries( + std::set& _unreachableNodes, std::string const& _nextHop, int32_t _newDistance) +{ + for (auto& it : m_routerEntries) + { + auto entry = it.second; + if (entry->nextHop() == _nextHop) + { + auto oldDistance = entry->distance(); + entry->setDistance(_newDistance + (oldDistance - 1)); + if (entry->distance() >= m_unreachableDistance) + { + entry->clearNextHop(); + _unreachableNodes.insert(entry->dstNode()); + } + GATEWAY_LOG(INFO) << LOG_BADGE("updateDistanceForAllRouterEntries") + << LOG_DESC( + "update entry since the nextHop distance has been updated") + << LOG_KV("dst", entry->dstNode()) << LOG_KV("nextHop", _nextHop) + << LOG_KV("distance", entry->distance()) + << LOG_KV("oldDistance", oldDistance) + << LOG_KV("size", m_routerEntries.size()); + } + } +} + +bool RouterTable::update(std::set& _unreachableNodes, + std::string const& _generatedFrom, RouterTableEntryInterface::Ptr _entry) +{ + if (c_fileLogLevel <= TRACE) + [[unlikely]] + { + GATEWAY_LOG(TRACE) << LOG_BADGE("update") << LOG_DESC("receive entry") + << LOG_KV("dst", printP2PIDElegantly(_entry->dstNode())) + << LOG_KV("distance", _entry->distance()) + << LOG_KV("from", _generatedFrom); + } + auto ret = updateDstNodeEntry(_generatedFrom, _entry); + // the dst entry has not been updated + if (!ret) + { + return false; + } + + UpgradableGuard l(x_routerEntries); + auto it = m_routerEntries.find(_entry->dstNode()); + if (it == m_routerEntries.end()) + { + return false; + } + // get the latest distance + auto& currentEntry = it->second; + auto _newDistance = currentEntry->distance(); + if (_newDistance >= m_unreachableDistance) + { + currentEntry->clearNextHop(); + _unreachableNodes.insert(_entry->dstNode()); + } + // the dst entry has updated, update the distance of the router-entries with nextHop equal to + // dstNode + UpgradeGuard upgradeGuard(l); + if (_newDistance == 1) + { + currentEntry->clearNextHop(); + } + updateDistanceForAllRouterEntries(_unreachableNodes, _entry->dstNode(), _newDistance); + return true; +} + +bool RouterTable::updateDstNodeEntry( + std::string const& _generatedFrom, RouterTableEntryInterface::Ptr _entry) +{ + UpgradableGuard upgradableGuard(x_routerEntries); + // the node self + if (_entry->dstNode() == m_nodeID) + { + return false; + } + // insert new entry + auto it = m_routerEntries.find(_entry->dstNode()); + if (it == m_routerEntries.end()) + { + UpgradeGuard upgradeGuard(upgradableGuard); + _entry->incDistance(1); + if (_generatedFrom != m_nodeID) + { + _entry->setNextHop(_generatedFrom); + } + m_routerEntries.insert(std::make_pair(_entry->dstNode(), _entry)); + GATEWAY_LOG(INFO) << LOG_BADGE("updateDstNodeEntry") + << LOG_DESC("insert new entry into the routerTable") + << LOG_KV("distance", _entry->distance()) + << LOG_KV("dst", _entry->dstNode()) + << LOG_KV("nextHop", _entry->nextHop()) + << LOG_KV("size", m_routerEntries.size()); + return true; + } + + // discover smaller distance + auto currentEntry = it->second; + auto currentDistance = currentEntry->distance(); + auto distance = _entry->distance() + 1; + if (currentDistance > distance) + { + UpgradeGuard upgradeGuard(upgradableGuard); + if (_generatedFrom != m_nodeID) + { + currentEntry->setNextHop(_generatedFrom); + } + currentEntry->setDistance(distance); + GATEWAY_LOG(INFO) << LOG_BADGE("updateDstNodeEntry") + << LOG_DESC("discover smaller distance, update entry") + << LOG_KV("distance", currentEntry->distance()) + << LOG_KV("oldDistance", currentDistance) + << LOG_KV("dst", _entry->dstNode()) + << LOG_KV("nextHop", _entry->nextHop()) + << LOG_KV("size", m_routerEntries.size()); + return true; + } + // the distance information for the nextHop changed + if (currentEntry->nextHop() == _generatedFrom) + { + // distance not updated + if (currentEntry->distance() == distance) + { + return false; + } + // unreachable condition + if (currentEntry->distance() >= m_unreachableDistance && distance >= m_unreachableDistance) + { + return false; + } + currentEntry->setDistance(distance); + if (currentEntry->distance() >= m_unreachableDistance) + { + currentEntry->clearNextHop(); + } + GATEWAY_LOG(INFO) << LOG_BADGE("updateDstNodeEntry") + << LOG_DESC( + "distance of the nextHop entry " + "updated, update the current entry") + << LOG_KV("dst", currentEntry->dstNode()) + << LOG_KV("nextHop", currentEntry->nextHop()) + << LOG_KV("distance", currentEntry->distance()) + << LOG_KV("size", m_routerEntries.size()); + return true; + } + return false; +} + +std::string RouterTable::getNextHop(std::string const& _nodeID) +{ + std::string emptyNextHop; + ReadGuard readGuard(x_routerEntries); + auto it = m_routerEntries.find(_nodeID); + if (it == m_routerEntries.end()) + { + return emptyNextHop; + } + if (it->second->distance() >= m_unreachableDistance) + { + return emptyNextHop; + } + return it->second->nextHop(); +} + +std::set RouterTable::getAllReachableNode() +{ + std::set reachableNodes; + ReadGuard readGuard(x_routerEntries); + for (auto const& it : m_routerEntries) + { + auto entry = it.second; + if (entry->distance() < m_unreachableDistance) + { + reachableNodes.insert(entry->dstNode()); + } + } + + if (c_fileLogLevel <= LogLevel::TRACE) + [[unlikely]] + { + std::stringstream nodes; + std::for_each(reachableNodes.begin(), reachableNodes.end(), + [&](const auto& item) { nodes << printP2PIDElegantly(item) << ","; }); + GATEWAY_LOG(TRACE) << LOG_BADGE("getAllReachableNode") + << LOG_KV("nodes size", reachableNodes.size()) + << LOG_KV("nodes", nodes.str()); + } + + return reachableNodes; +} diff --git a/cpp/ppc-gateway/ppc-gateway/p2p/router/RouterTableImpl.h b/cpp/ppc-gateway/ppc-gateway/p2p/router/RouterTableImpl.h new file mode 100644 index 00000000..72eda232 --- /dev/null +++ b/cpp/ppc-gateway/ppc-gateway/p2p/router/RouterTableImpl.h @@ -0,0 +1,132 @@ +/* + * Copyright (C) 2024 WeDPR. + * SPDX-License-Identifier: Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @file RouterTableImpl.h + * @author: yujiechen + * @date 2022-5-24 + */ +#pragma once +#pragma GCC diagnostic ignored "-Wunused-variable" +#pragma GCC diagnostic ignored "-Wunused-parameter" + +#include "RouterTableInterface.h" +#include +#include +#include + +namespace ppc::gateway +{ +class RouterTableEntry : public RouterTableEntryInterface +{ +public: + using Ptr = std::shared_ptr; + RouterTableEntry() + : m_inner([m_entry = ppctars::RouterTableEntry()]() mutable { return &m_entry; }) + {} + RouterTableEntry(std::function _inner) + : m_inner(std::move(_inner)) + {} + RouterTableEntry(RouterTableEntry&&) = delete; + RouterTableEntry(const RouterTableEntry&) = delete; + RouterTableEntry& operator=(const RouterTableEntry&) = delete; + RouterTableEntry& operator=(RouterTableEntry&&) = delete; + ~RouterTableEntry() override = default; + + void setDstNode(std::string const& _dstNode) override { m_inner()->dstNode = _dstNode; } + void setNextHop(std::string const& _nextHop) override { m_inner()->nextHop = _nextHop; } + void clearNextHop() override { m_inner()->nextHop = std::string(); } + void setDistance(int32_t _distance) override { m_inner()->distance = _distance; } + void incDistance(int32_t _deltaDistance) override { m_inner()->distance += _deltaDistance; } + + std::string const& dstNode() const override { return m_inner()->dstNode; } + std::string const& nextHop() const override { return m_inner()->nextHop; } + int32_t distance() const override { return m_inner()->distance; } + + ppctars::RouterTableEntry const& inner() const { return *(m_inner()); } + +private: + std::function m_inner; +}; + +class RouterTable : public RouterTableInterface +{ +public: + using Ptr = std::shared_ptr; + RouterTable() : m_inner([m_table = ppctars::RouterTable()]() mutable { return &m_table; }) {} + RouterTable(bcos::bytesConstRef _decodedData) : RouterTable() { decode(_decodedData); } + RouterTable(RouterTable&&) = delete; + RouterTable(const RouterTable&) = delete; + RouterTable& operator=(const RouterTable&) = delete; + RouterTable& operator=(RouterTable&&) = delete; + ~RouterTable() override = default; + + void encode(bcos::bytes& _encodedData) override; + void decode(bcos::bytesConstRef _decodedData) override; + + std::map const& routerEntries() override + { + return m_routerEntries; + } + // append the unreachableNodes into param _unreachableNodes + bool update(std::set& _unreachableNodes, std::string const& _generatedFrom, + RouterTableEntryInterface::Ptr _entry) override; + // append the unreachableNodes into param _unreachableNodes + bool erase(std::set& _unreachableNodes, std::string const& _p2pNodeID) override; + + void setNodeID(std::string const& _nodeID) override { m_nodeID = _nodeID; } + std::string const& nodeID() const override { return m_nodeID; } + + void setUnreachableDistance(int _unreachableDistance) override + { + m_unreachableDistance = _unreachableDistance; + } + + int unreachableDistance() const override { return m_unreachableDistance; } + std::string getNextHop(std::string const& _nodeID) override; + std::set getAllReachableNode() override; + + bool updateDstNodeEntry( + std::string const& _generatedFrom, RouterTableEntryInterface::Ptr _entry); + void updateDistanceForAllRouterEntries(std::set& _unreachableNodes, + std::string const& _nextHop, int32_t _newDistance); + +private: + std::string m_nodeID; + std::function m_inner; + std::map m_routerEntries; + mutable bcos::SharedMutex x_routerEntries; + + int m_unreachableDistance = 10; +}; + +class RouterTableFactoryImpl : public RouterTableFactory +{ +public: + using Ptr = std::shared_ptr; + RouterTableInterface::Ptr createRouterTable() override + { + return std::make_shared(); + } + RouterTableInterface::Ptr createRouterTable(bcos::bytesConstRef _decodedData) override + { + return std::make_shared(_decodedData); + } + + RouterTableEntryInterface::Ptr createRouterEntry() override + { + return std::make_shared(); + } +}; +} // namespace ppc::gateway \ No newline at end of file diff --git a/cpp/ppc-gateway/ppc-gateway/p2p/router/RouterTableInterface.h b/cpp/ppc-gateway/ppc-gateway/p2p/router/RouterTableInterface.h new file mode 100644 index 00000000..e60d3096 --- /dev/null +++ b/cpp/ppc-gateway/ppc-gateway/p2p/router/RouterTableInterface.h @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2024 WeDPR. + * SPDX-License-Identifier: Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @file RouterTableInterface.h + * @author: yujiechen + * @date 2022-5-24 + */ +#pragma once +#include +#include +#include +namespace ppc::gateway +{ +class RouterTableEntryInterface +{ +public: + using Ptr = std::shared_ptr; + RouterTableEntryInterface() = default; + RouterTableEntryInterface(const RouterTableEntryInterface&) = delete; + RouterTableEntryInterface(RouterTableEntryInterface&&) = delete; + RouterTableEntryInterface& operator=(RouterTableEntryInterface&&) = delete; + RouterTableEntryInterface& operator=(const RouterTableEntryInterface&) = delete; + virtual ~RouterTableEntryInterface() = default; + + virtual void setDstNode(std::string const& _dstNode) = 0; + virtual void setNextHop(std::string const& _nextHop) = 0; + virtual void clearNextHop() = 0; + virtual void setDistance(int32_t _distance) = 0; + virtual void incDistance(int32_t _deltaDistance) = 0; + + virtual std::string const& dstNode() const = 0; + virtual std::string const& nextHop() const = 0; + virtual int32_t distance() const = 0; +}; + +class RouterTableInterface +{ +public: + using Ptr = std::shared_ptr; + RouterTableInterface() = default; + RouterTableInterface(const RouterTableInterface&) = delete; + RouterTableInterface(RouterTableInterface&&) = delete; + RouterTableInterface& operator=(RouterTableInterface&&) = delete; + RouterTableInterface& operator=(const RouterTableInterface&) = delete; + virtual ~RouterTableInterface() = default; + + virtual bool update(std::set& _unreachableNodes, std::string const& _generatedFrom, + RouterTableEntryInterface::Ptr _entry) = 0; + virtual bool erase(std::set& _unreachableNodes, std::string const& _p2pNodeID) = 0; + + virtual std::map const& routerEntries() = 0; + + virtual void setNodeID(std::string const& _nodeID) = 0; + virtual std::string const& nodeID() const = 0; + virtual void setUnreachableDistance(int _unreachableDistance) = 0; + virtual int unreachableDistance() const = 0; + virtual std::string getNextHop(std::string const& _nodeID) = 0; + virtual std::set getAllReachableNode() = 0; + + virtual void encode(bcos::bytes& _encodedData) = 0; + virtual void decode(bcos::bytesConstRef _decodedData) = 0; +}; + +class RouterTableFactory +{ +public: + using Ptr = std::shared_ptr; + RouterTableFactory() = default; + RouterTableFactory(RouterTableFactory&&) = delete; + RouterTableFactory(const RouterTableFactory&) = delete; + RouterTableFactory& operator=(const RouterTableFactory&) = delete; + RouterTableFactory& operator=(RouterTableFactory&&) = delete; + virtual ~RouterTableFactory() = default; + + virtual RouterTableInterface::Ptr createRouterTable() = 0; + virtual RouterTableInterface::Ptr createRouterTable(bcos::bytesConstRef _decodedData) = 0; + virtual RouterTableEntryInterface::Ptr createRouterEntry() = 0; +}; + +} // namespace ppc::gateway \ No newline at end of file diff --git a/cpp/ppc-protocol/src/JsonTaskImpl.h b/cpp/ppc-protocol/src/JsonTaskImpl.h index dea185b8..b0883b31 100644 --- a/cpp/ppc-protocol/src/JsonTaskImpl.h +++ b/cpp/ppc-protocol/src/JsonTaskImpl.h @@ -30,14 +30,19 @@ class JsonTaskImpl : public Task { public: using Ptr = std::shared_ptr; - JsonTaskImpl(std::string const& _selfPartyID, std::string const& _prePath = "data") : m_selfPartyID(_selfPartyID), m_prePath(_prePath) + JsonTaskImpl(std::string const& _selfPartyID, std::string const& _prePath = "data") + : m_selfPartyID(_selfPartyID), m_prePath(_prePath) {} - JsonTaskImpl(std::string const& _selfPartyID, std::string_view _taskData, std::string const& _prePath = "data") : JsonTaskImpl(_selfPartyID, _prePath) + JsonTaskImpl(std::string const& _selfPartyID, std::string_view _taskData, + std::string const& _prePath = "data") + : JsonTaskImpl(_selfPartyID, _prePath) { decode(_taskData); } - JsonTaskImpl(std::string const& _selfPartyID, Json::Value const& _taskJson, std::string const& _prePath = "data") : JsonTaskImpl(_selfPartyID, _prePath) + JsonTaskImpl(std::string const& _selfPartyID, Json::Value const& _taskJson, + std::string const& _prePath = "data") + : JsonTaskImpl(_selfPartyID, _prePath) { decodeJsonValue(_taskJson); } @@ -64,10 +69,7 @@ class JsonTaskImpl : public Task return m_peerParties; } - std::vector const& getReceiverLists() const override - { - return m_receiverLists; - } + std::vector const& getReceiverLists() const override { return m_receiverLists; } // params of the task, can be deserialized using json std::string const& param() const override { return m_param; } @@ -89,11 +91,8 @@ class JsonTaskImpl : public Task { m_syncResultToPeer = _syncResultToPeer; } - void setLowBandwidth(bool _lowBandwidth) override - { - m_lowBandwidth = _lowBandwidth; - } - + void setLowBandwidth(bool _lowBandwidth) override { m_lowBandwidth = _lowBandwidth; } + // decode the task void decode(std::string_view _taskData) override; virtual void decodeJsonValue(Json::Value const& root); diff --git a/cpp/ppc-protocol/src/v1/MessageHeaderImpl.cpp b/cpp/ppc-protocol/src/v1/MessageHeaderImpl.cpp new file mode 100644 index 00000000..08ba9cdd --- /dev/null +++ b/cpp/ppc-protocol/src/v1/MessageHeaderImpl.cpp @@ -0,0 +1,146 @@ +/** + * Copyright (C) 2023 WeDPR. + * SPDX-License-Identifier: Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @file MessageHeaderImpl.cpp + * @author: yujiechen + * @date 2024-08-23 + */ +#include "MessageHeaderImpl.h" +#include "ppc-framework/Common.h" +#include "ppc-utilities/Utilities.h" +#include + +using namespace ppc::protocol; +using namespace bcos; +using namespace ppc; + +void MessageOptionalHeaderImpl::encode(bcos::bytes& buffer) const +{ + // the componentType + uint16_t componentType = + boost::asio::detail::socket_ops::host_to_network_short(m_componentType); + buffer.insert(buffer.end(), (byte*)&componentType, (byte*)&componentType + 2); + // the source nodeID that send the message + uint16_t srcNodeLen = boost::asio::detail::socket_ops::host_to_network_short(m_srcNode.size()); + buffer.insert(buffer.end(), (byte*)&srcNodeLen, (byte*)&srcNodeLen + 2); + buffer.insert(buffer.end(), m_srcNode.begin(), m_srcNode.end()); + // the target nodeID that should receive the message + uint16_t dstNodeLen = boost::asio::detail::socket_ops::host_to_network_short(m_dstNode.size()); + buffer.insert(buffer.end(), (byte*)&dstNodeLen, (byte*)&dstNodeLen + 2); + buffer.insert(buffer.end(), m_dstNode.begin(), m_dstNode.end()); + bcos::bytes m_dstNode; + // the target agency that need receive the message + uint16_t dstInstLen = boost::asio::detail::socket_ops::host_to_network_short(m_dstInst.size()); + buffer.insert(buffer.end(), (byte*)&dstInstLen, (byte*)&dstInstLen + 2); + buffer.insert(buffer.end(), m_dstInst.begin(), m_dstInst.end()); +} + + +int64_t MessageOptionalHeaderImpl::decode(bcos::bytesConstRef data, uint64_t const _offset) +{ + auto offset = _offset; + CHECK_OFFSET_WITH_THROW_EXCEPTION(offset, data.size()); + // the componentType + auto pointer = data.data() + offset; + m_componentType = boost::asio::detail::socket_ops::network_to_host_short(*((uint16_t*)pointer)); + pointer += 2; + // srcNode + offset = decodeNetworkBuffer(m_srcNode, data.data(), data.size(), (pointer - data.data())); + // dstNode + offset = decodeNetworkBuffer(m_dstNode, data.data(), data.size(), offset); + // dstInst + offset = decodeNetworkBuffer(m_dstInst, data.data(), data.size(), offset); + return offset; +} + +void MessageHeaderImpl::encode(bcos::bytes& buffer) const +{ + buffer.clear(); + // the version, 2Bytes + uint16_t version = boost::asio::detail::socket_ops::host_to_network_short(m_version); + buffer.insert(buffer.end(), (byte*)&version, (byte*)&version + 2); + // the packetType, 2Bytes + uint16_t packetType = boost::asio::detail::socket_ops::host_to_network_short(m_packetType); + buffer.insert(buffer.end(), (byte*)&packetType, (byte*)&packetType + 2); + // the ttl, 2Bytes + uint16_t ttl = boost::asio::detail::socket_ops::host_to_network_short(m_ttl); + buffer.insert(buffer.end(), (byte*)&ttl, (byte*)&ttl + 2); + // the ext, 2Bytes + uint16_t ext = boost::asio::detail::socket_ops::host_to_network_short(m_ext); + buffer.insert(buffer.end(), (byte*)&ext, (byte*)&ext + 2); + // the traceID, 2+Bytes + uint16_t traceIDLen = boost::asio::detail::socket_ops::host_to_network_short(m_traceID.size()); + buffer.insert(buffer.end(), (byte*)&traceIDLen, (byte*)&traceIDLen + 2); + buffer.insert(buffer.end(), m_traceID.begin(), m_traceID.end()); + // srcGwNode, 2+Bytes + uint16_t srcGwNodeLen = + boost::asio::detail::socket_ops::host_to_network_short(m_srcGwNode.size()); + buffer.insert(buffer.end(), (byte*)&srcGwNodeLen, (byte*)&srcGwNodeLen + 2); + buffer.insert(buffer.end(), m_srcGwNode.begin(), m_srcGwNode.end()); + // dstGwNode, 2+Bytes + uint16_t dstGwNodeLen = + boost::asio::detail::socket_ops::host_to_network_short(m_dstGwNode.size()); + buffer.insert(buffer.end(), (byte*)&dstGwNodeLen, (byte*)&dstGwNodeLen + 2); + buffer.insert(buffer.end(), m_dstGwNode.begin(), m_dstGwNode.end()); + if (!hasOptionalField()) + { + return; + } + // encode the optionalField + m_optionalField->encode(buffer); + m_length = buffer.size(); +} + +int64_t MessageHeaderImpl::decode(bcos::bytesConstRef data) +{ + if (data.size() < MESSAGE_MIN_LENGTH) + { + BOOST_THROW_EXCEPTION( + WeDPRException() << errinfo_comment("Malform message for too small!")); + } + auto pointer = data.data(); + // the version + m_version = boost::asio::detail::socket_ops::network_to_host_short(*((uint16_t*)pointer)); + pointer += 2; + // the pacektType + m_packetType = boost::asio::detail::socket_ops::network_to_host_short(*((uint16_t*)pointer)); + pointer += 2; + // the ttl + m_ttl = boost::asio::detail::socket_ops::network_to_host_short(*((uint16_t*)pointer)); + pointer += 2; + // the ext + m_ext = boost::asio::detail::socket_ops::network_to_host_short(*((uint16_t*)pointer)); + pointer += 2; + // the traceID + bcos::bytes traceIDData; + auto offset = + decodeNetworkBuffer(traceIDData, data.data(), data.size(), (pointer - data.data())); + m_traceID = std::string(traceIDData.begin(), traceIDData.end()); + // srcGwNode + bcos::bytes srcGWNodeData; + offset = decodeNetworkBuffer(srcGWNodeData, data.data(), data.size(), offset); + m_srcGwNode = std::string(srcGWNodeData.begin(), srcGWNodeData.end()); + // dstGwNode + bcos::bytes dstGWNodeData; + offset = decodeNetworkBuffer(dstGWNodeData, data.data(), data.size(), offset); + m_dstGwNode = std::string(dstGWNodeData.begin(), dstGWNodeData.end()); + // optionalField + if (hasOptionalField()) + { + offset = m_optionalField->decode(data, offset); + } + m_length = offset; + return offset; +} diff --git a/cpp/ppc-protocol/src/v1/MessageHeaderImpl.h b/cpp/ppc-protocol/src/v1/MessageHeaderImpl.h new file mode 100644 index 00000000..a8dda5a9 --- /dev/null +++ b/cpp/ppc-protocol/src/v1/MessageHeaderImpl.h @@ -0,0 +1,82 @@ +/** + * Copyright (C) 2023 WeDPR. + * SPDX-License-Identifier: Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @file MessageHeaderImpl.h + * @author: yujiechen + * @date 2024-08-23 + */ +#pragma once +#include "ppc-framework/gateway/GatewayProtocol.h" +#include "ppc-framework/protocol/Message.h" + +namespace ppc::protocol +{ +class MessageOptionalHeaderImpl : public MessageOptionalHeader +{ +public: + using Ptr = std::shared_ptr; + MessageOptionalHeaderImpl() = default; + MessageOptionalHeaderImpl(bcos::bytesConstRef data, uint64_t const offset) + { + decode(data, offset); + } + + ~MessageOptionalHeaderImpl() override = default; + + void encode(bcos::bytes& buffer) const override; + int64_t decode(bcos::bytesConstRef data, uint64_t const offset) override; +}; + +class MessageHeaderImpl : public MessageHeader +{ +public: + using Ptr = std::shared_ptr; + MessageHeaderImpl() { m_optionalField = std::make_shared(); } + MessageHeaderImpl(bcos::bytesConstRef data) { decode(data); } + ~MessageHeaderImpl() override {} + + void encode(bcos::bytes& buffer) const override; + int64_t decode(bcos::bytesConstRef data) override; + + virtual bool hasOptionalField() const + { + return m_packetType == (uint16_t)ppc::gateway::GatewayPacketType::P2PMessage; + } + + bool isRespPacket() const override + { + return m_ext & (uint16_t)ppc::gateway::GatewayMsgExtFlag::Response; + } + void setRespPacket() override { m_ext |= (uint16_t)ppc::gateway::GatewayMsgExtFlag::Response; } + +private: + // version(2) + packetType(2) + ttl(2) + ext(2) + traceIDLen(2) + srcGwNodeLen(2) + dstGwNode(2) + const size_t MESSAGE_MIN_LENGTH = 14; +}; + +class MessageHeaderBuilderImpl : public MessageHeaderBuilder +{ +public: + using Ptr = std::shared_ptr; + MessageHeaderBuilderImpl() = default; + ~MessageHeaderBuilderImpl() {} + + MessageHeader::Ptr build(bcos::bytesConstRef data) override + { + return std::make_shared(data); + } + MessageHeader::Ptr build() override { return std::make_shared(); } +}; +} // namespace ppc::protocol \ No newline at end of file diff --git a/cpp/ppc-protocol/src/v1/MessageImpl.cpp b/cpp/ppc-protocol/src/v1/MessageImpl.cpp new file mode 100644 index 00000000..09f4183a --- /dev/null +++ b/cpp/ppc-protocol/src/v1/MessageImpl.cpp @@ -0,0 +1,63 @@ +/** + * Copyright (C) 2023 WeDPR. + * SPDX-License-Identifier: Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @file MessageImpl.cpp + * @author: yujiechen + * @date 2024-08-23 + */ + +#include "MessageImpl.h" + +using namespace bcos; +using namespace ppc::protocol; + +bool MessageImpl::encode(bcos::bytes& _buffer) +{ + // encode the header + bcos::bytes headerData; + m_header->encode(headerData); + // encode the payload + if (m_payload) + { + headerData.insert(headerData.end(), m_payload->begin(), m_payload->end()); + } +} + +bool MessageImpl::encode(bcos::boostssl::EncodedMsg& encodedMsg) +{ + // header + m_header->encode(encodedMsg.header); + // assign the payload back + encodedMsg.payload = m_payload; +} + +int64_t MessageImpl::decode(bytesConstRef buffer) +{ + if (buffer.size() > m_maxMessageLen) + { + BOOST_THROW_EXCEPTION(WeDPRException() << errinfo_comment( + "Malform message for over the size limit, max allowed size is: " + + std::to_string(m_maxMessageLen))); + } + // decode the header + m_header = m_headerBuilder->build(buffer); + // decode the payload + if (!m_payload) + { + m_payload = std::make_shared(); + } + m_payload->clear(); + m_payload->insert(m_payload->end(), buffer.data() + m_header->length(), buffer.end()); +} \ No newline at end of file diff --git a/cpp/ppc-protocol/src/v1/MessageImpl.h b/cpp/ppc-protocol/src/v1/MessageImpl.h new file mode 100644 index 00000000..208db1b3 --- /dev/null +++ b/cpp/ppc-protocol/src/v1/MessageImpl.h @@ -0,0 +1,84 @@ +/** + * Copyright (C) 2023 WeDPR. + * SPDX-License-Identifier: Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @file MessageImpl.h + * @author: yujiechen + * @date 2024-08-23 + */ +#pragma once +#include "ppc-framework/Common.h" +#include "ppc-framework/protocol/Message.h" + +namespace ppc::protocol +{ +class MessageImpl : public Message +{ +public: + using Ptr = std::shared_ptr; + MessageImpl(MessageHeaderBuilder::Ptr headerBuilder, size_t maxMessageLen) + : m_headerBuilder(std::move(headerBuilder)), m_maxMessageLen(maxMessageLen) + {} + MessageImpl( + MessageHeaderBuilder::Ptr headerBuilder, size_t maxMessageLen, bcos::bytesConstRef buffer) + : MessageImpl(headerBuilder, maxMessageLen) + { + decode(buffer); + } + + ~MessageImpl() override = default; + + bool encode(bcos::bytes& _buffer) override; + // encode and return the {header, payload} + bool encode(bcos::boostssl::EncodedMsg& _encodedMsg) override; + int64_t decode(bcos::bytesConstRef _buffer) override; + +private: + MessageHeaderBuilder::Ptr m_headerBuilder; + + // default max message length is 100MB + size_t m_maxMessageLen = 100 * 1024 * 1024; +}; + +class MessageBuilderImpl : public MessageBuilder +{ +public: + using Ptr = std::shared_ptr; + MessageBuilderImpl(MessageHeaderBuilder::Ptr msgHeaderBuilder) + : m_msgHeaderBuilder(std::move(msgHeaderBuilder)) + {} + + MessageBuilderImpl(MessageHeaderBuilder::Ptr msgHeaderBuilder, size_t maxMessageLen) + : MessageBuilderImpl(std::move(msgHeaderBuilder)) + { + m_maxMessageLen = maxMessageLen; + } + + ~MessageBuilderImpl() override {} + + Message::Ptr build() override + { + return std::make_shared(m_msgHeaderBuilder, m_maxMessageLen); + } + Message::Ptr build(bcos::bytesConstRef buffer) override + { + return std::make_shared(m_msgHeaderBuilder, m_maxMessageLen, buffer); + } + +private: + MessageHeaderBuilder::Ptr m_msgHeaderBuilder; + // default max message length is 100MB + size_t m_maxMessageLen = 100 * 1024 * 1024; +}; +} // namespace ppc::protocol \ No newline at end of file diff --git a/cpp/ppc-protocol/src/v1/MessagePayloadImpl.cpp b/cpp/ppc-protocol/src/v1/MessagePayloadImpl.cpp new file mode 100644 index 00000000..59397edf --- /dev/null +++ b/cpp/ppc-protocol/src/v1/MessagePayloadImpl.cpp @@ -0,0 +1,67 @@ +/** + * Copyright (C) 2023 WeDPR. + * SPDX-License-Identifier: Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @file MessagePayloadImpl.h + * @author: yujiechen + * @date 2024-08-22 + */ + +#include "MessagePayloadImpl.h" + +#include "ppc-utilities/Utilities.h" +#include + +using namespace ppc::protocol; +using namespace bcos; + +int64_t MessagePayloadImpl::encode(bcos::bytes& buffer) const +{ + // version + uint16_t version = boost::asio::detail::socket_ops::host_to_network_short(m_version); + buffer.insert(buffer.end(), (byte*)&version, (byte*)&version + 2); + // topic + uint16_t topicLen = boost::asio::detail::socket_ops::host_to_network_short(m_topic.size()); + buffer.insert(buffer.end(), (byte*)&topicLen, (byte*)&topicLen + 2); + buffer.insert(buffer.end(), m_topic.begin(), m_topic.end()); + // data + uint16_t dataLen = boost::asio::detail::socket_ops::host_to_network_short(m_data.size()); + buffer.insert(buffer.end(), (byte*)&dataLen, (byte*)&dataLen + 2); + buffer.insert(buffer.end(), m_data.begin(), m_data.end()); + // update the length + m_length = buffer.size(); + return m_length; +} + +int64_t MessagePayloadImpl::decode(bcos::bytesConstRef buffer) +{ + // check the message + if (buffer.size() < MIN_PAYLOAD_LEN) + { + BOOST_THROW_EXCEPTION( + WeDPRException() << errinfo_comment("Malform payload for too small!")); + } + auto pointer = buffer.data(); + // the version + m_version = boost::asio::detail::socket_ops::network_to_host_short(*((uint16_t*)pointer)); + pointer += 2; + // topic + bcos::bytes topicData; + auto offset = + decodeNetworkBuffer(topicData, buffer.data(), buffer.size(), (pointer - buffer.data())); + m_topic = std::string(topicData.begin(), topicData.end()); + // data + offset = decodeNetworkBuffer(m_data, buffer.data(), buffer.size(), offset); + return offset; +} \ No newline at end of file diff --git a/cpp/ppc-protocol/src/v1/MessagePayloadImpl.h b/cpp/ppc-protocol/src/v1/MessagePayloadImpl.h new file mode 100644 index 00000000..f7f5a3e8 --- /dev/null +++ b/cpp/ppc-protocol/src/v1/MessagePayloadImpl.h @@ -0,0 +1,54 @@ +/** + * Copyright (C) 2023 WeDPR. + * SPDX-License-Identifier: Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @file MessagePayloadImpl.h + * @author: yujiechen + * @date 2024-08-22 + */ +#pragma once +#include "ppc-framework/Common.h" +#include "ppc-framework/protocol/MessagePayload.h" + +namespace ppc::protocol +{ +class MessagePayloadImpl : public MessagePayload +{ +public: + using Ptr = std::shared_ptr; + MessagePayloadImpl() = default; + MessagePayloadImpl(bcos::bytesConstRef buffer) { decode(buffer); } + ~MessagePayloadImpl() override {} + + int64_t encode(bcos::bytes& buffer) const override; + int64_t decode(bcos::bytesConstRef data) override; + +private: + const unsigned int MIN_PAYLOAD_LEN = 6; +}; + + +class MessagePayloadBuilderImpl : public MessagePayloadBuilder +{ +public: + using Ptr = std::shared_ptr; + MessagePayloadBuilderImpl() = default; + ~MessagePayloadBuilderImpl() override {} + MessagePayload::Ptr build() override { return std::make_shared(); } + MessagePayload::Ptr build(bcos::bytesConstRef buffer) override + { + return std::make_shared(buffer); + } +}; +} // namespace ppc::protocol \ No newline at end of file diff --git a/cpp/ppc-tars-protocol/ppc-tars-protocol/tars/RouterTable.tars b/cpp/ppc-tars-protocol/ppc-tars-protocol/tars/RouterTable.tars new file mode 100644 index 00000000..48096cdd --- /dev/null +++ b/cpp/ppc-tars-protocol/ppc-tars-protocol/tars/RouterTable.tars @@ -0,0 +1,13 @@ +module ppctars +{ +struct RouterTableEntry +{ + 1 require string dstNode; + 2 optional string nextHop; + 3 require int distance; +}; +struct RouterTable +{ + 1 optional vector routerEntries; +}; +}; \ No newline at end of file diff --git a/cpp/ppc-tools/src/codec/CodecUtility.h b/cpp/ppc-tools/src/codec/CodecUtility.h index ce7a208a..d8f83201 100644 --- a/cpp/ppc-tools/src/codec/CodecUtility.h +++ b/cpp/ppc-tools/src/codec/CodecUtility.h @@ -20,7 +20,6 @@ #pragma once #include "openssl/bn.h" #include "ppc-framework/libwrapper/BigNum.h" -#include "ppc-utilities/Utilities.h" #include #include #include diff --git a/cpp/ppc-utilities/Utilities.h b/cpp/ppc-utilities/Utilities.h index b9b8e0ae..4b04ea21 100644 --- a/cpp/ppc-utilities/Utilities.h +++ b/cpp/ppc-utilities/Utilities.h @@ -20,20 +20,22 @@ #pragma once #include "ppc-framework/Common.h" +#include namespace ppc { inline uint64_t decodeNetworkBuffer( bcos::bytes& _result, bcos::byte const* buffer, unsigned int bufferLen, uint64_t const offset) { - CHECK_OFFSET_WITH_THROW_EXCEPTION(offset, bufferLen); + uint64_t curOffset = offset; + CHECK_OFFSET_WITH_THROW_EXCEPTION(curOffset, bufferLen); auto dataLen = - boost::asio::detail::socket_ops::network_to_host_short(*((uint16_t*)buffer + offset)); - offset += 2; - CHECK_OFFSET_WITH_THROW_EXCEPTION(offset, bufferLen); - buffer.insert( - buffer.end(), (bcos::byte*)_buffer + offset, (bcos::byte*)_buffer + offset + dataLen); - offset += dataLen; - return offset; + boost::asio::detail::socket_ops::network_to_host_short(*((uint16_t*)buffer + curOffset)); + curOffset += 2; + CHECK_OFFSET_WITH_THROW_EXCEPTION(curOffset, bufferLen); + _result.insert( + _result.end(), (bcos::byte*)buffer + curOffset, (bcos::byte*)buffer + curOffset + dataLen); + curOffset += dataLen; + return curOffset; } } // namespace ppc \ No newline at end of file diff --git a/cpp/vcpkg-configuration.json b/cpp/vcpkg-configuration.json index 5913a7c1..a6334850 100644 --- a/cpp/vcpkg-configuration.json +++ b/cpp/vcpkg-configuration.json @@ -2,8 +2,8 @@ "registries": [ { "kind": "git", - "repository": "https://github.com/FISCO-BCOS/registry", - "baseline": "070f336149afdac5cc9ace97df01de7ee31aab30", + "repository": "https://github.com/cyjseagull/registry", + "baseline": "6160f4167d4ab801f16a18bdd842a75edf7b069e", "packages": [ "openssl", "bcos-utilities", From 6dcefa067b912dd5ac1db1c83cb3dab9ef0f727f Mon Sep 17 00:00:00 2001 From: cyjseagull Date: Tue, 27 Aug 2024 19:39:32 +0800 Subject: [PATCH 8/9] add gateway router (#11) --- cpp/ppc-framework/front/FrontConfig.h | 95 ++++++++ cpp/ppc-framework/front/IFront.h | 106 +++++++++ cpp/ppc-framework/gateway/GatewayProtocol.h | 12 + cpp/ppc-framework/gateway/IGateway.h | 70 ++++++ cpp/ppc-framework/protocol/INodeInfo.h | 65 ++++++ cpp/ppc-framework/protocol/Message.h | 42 +++- cpp/ppc-framework/protocol/MessagePayload.h | 11 +- cpp/ppc-framework/protocol/RouteType.h | 54 +++++ .../ppc-gateway/gateway/GatewayImpl.cpp | 195 +++++++++++++++++ .../ppc-gateway/gateway/GatewayImpl.h | 88 ++++++++ .../gateway/SendMessageWithRetry.cpp | 114 ++++++++++ .../gateway/SendMessageWithRetry.h | 62 ++++++ .../gateway/cache/MessageCache.cpp | 94 ++++++++ .../ppc-gateway/gateway/cache/MessageCache.h | 70 ++++++ .../gateway/router/GatewayNodeInfo.h | 74 +++++++ .../gateway/router/GatewayNodeInfoImpl.cpp | 206 ++++++++++++++++++ .../gateway/router/GatewayNodeInfoImpl.h | 100 +++++++++ .../gateway/router/LocalRouter.cpp | 122 +++++++++++ .../ppc-gateway/gateway/router/LocalRouter.h | 71 ++++++ .../gateway/router/PeerRouterTable.cpp | 138 ++++++++++++ .../gateway/router/PeerRouterTable.h | 57 +++++ cpp/ppc-gateway/ppc-gateway/p2p/Service.cpp | 24 ++ cpp/ppc-gateway/ppc-gateway/p2p/Service.h | 10 +- .../ppc-gateway/p2p/router/RouterManager.h | 1 + cpp/ppc-protocol/src/v1/MessageHeaderImpl.cpp | 63 +++++- cpp/ppc-protocol/src/v1/MessageHeaderImpl.h | 3 + cpp/ppc-protocol/src/v1/MessageImpl.h | 28 +++ .../src/v1/MessagePayloadImpl.cpp | 19 +- cpp/ppc-protocol/src/v1/MessagePayloadImpl.h | 1 + .../ppc-tars-protocol/impl/NodeInfoImpl.cpp | 40 ++++ .../ppc-tars-protocol/impl/NodeInfoImpl.h | 88 ++++++++ .../ppc-tars-protocol/tars/NodeInfo.tars | 15 ++ 32 files changed, 2102 insertions(+), 36 deletions(-) create mode 100644 cpp/ppc-framework/front/FrontConfig.h create mode 100644 cpp/ppc-framework/front/IFront.h create mode 100644 cpp/ppc-framework/gateway/IGateway.h create mode 100644 cpp/ppc-framework/protocol/INodeInfo.h create mode 100644 cpp/ppc-framework/protocol/RouteType.h create mode 100644 cpp/ppc-gateway/ppc-gateway/gateway/GatewayImpl.cpp create mode 100644 cpp/ppc-gateway/ppc-gateway/gateway/GatewayImpl.h create mode 100644 cpp/ppc-gateway/ppc-gateway/gateway/SendMessageWithRetry.cpp create mode 100644 cpp/ppc-gateway/ppc-gateway/gateway/SendMessageWithRetry.h create mode 100644 cpp/ppc-gateway/ppc-gateway/gateway/cache/MessageCache.cpp create mode 100644 cpp/ppc-gateway/ppc-gateway/gateway/cache/MessageCache.h create mode 100644 cpp/ppc-gateway/ppc-gateway/gateway/router/GatewayNodeInfo.h create mode 100644 cpp/ppc-gateway/ppc-gateway/gateway/router/GatewayNodeInfoImpl.cpp create mode 100644 cpp/ppc-gateway/ppc-gateway/gateway/router/GatewayNodeInfoImpl.h create mode 100644 cpp/ppc-gateway/ppc-gateway/gateway/router/LocalRouter.cpp create mode 100644 cpp/ppc-gateway/ppc-gateway/gateway/router/LocalRouter.h create mode 100644 cpp/ppc-gateway/ppc-gateway/gateway/router/PeerRouterTable.cpp create mode 100644 cpp/ppc-gateway/ppc-gateway/gateway/router/PeerRouterTable.h create mode 100644 cpp/ppc-tars-protocol/ppc-tars-protocol/impl/NodeInfoImpl.cpp create mode 100644 cpp/ppc-tars-protocol/ppc-tars-protocol/impl/NodeInfoImpl.h create mode 100644 cpp/ppc-tars-protocol/ppc-tars-protocol/tars/NodeInfo.tars diff --git a/cpp/ppc-framework/front/FrontConfig.h b/cpp/ppc-framework/front/FrontConfig.h new file mode 100644 index 00000000..e9775c79 --- /dev/null +++ b/cpp/ppc-framework/front/FrontConfig.h @@ -0,0 +1,95 @@ +/** + * Copyright (C) 2023 WeDPR. + * SPDX-License-Identifier: Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @file FrontConfig.h + * @author: yujiechen + * @date 2024-08-22 + */ + +#pragma once +#include +#include +#include + +namespace ppc::front +{ +/** + * @brief the gateway endpoint + * + */ +class GatewayEndPoint +{ +public: + GatewayEndPoint() = default; + GatewayEndPoint(std::string const& host, uint16_t port) : m_host(std::move(host)), m_port(port) + {} + virtual ~GatewayEndPoint() = default; + + virtual std::string const& host() const { return m_host; } + uint16_t port() const { return m_port; } + + void setHost(std::string host) { m_host = std::move(host); } + void setPort(uint16_t port) { m_port = port; } + +private: + // the host + std::string m_host; + // the port + uint16_t m_port; +}; + +// Note: swig explosed interface +class FrontConfig +{ +public: + using Ptr = std::shared_ptr; + FrontConfig(int threadPoolSize, std::string agencyID) + : m_threadPoolSize(threadPoolSize), m_agencyID(std::move(agencyID)) + {} + virtual ~FrontConfig() = default; + + virtual int threadPoolSize() const { return m_threadPoolSize; } + virtual std::string const agencyID() const { return m_agencyID; } + virtual std::vector const& gatewayInfo() const { return m_gatewayInfo; } + virtual void setGatewayInfo(std::vector gatewayInfo) + { + m_gatewayInfo = std::move(gatewayInfo); + } + + virtual void appendGatewayInfo(GatewayEndPoint&& endpoint) + { + // TODO:check the endpoint + m_gatewayInfo.push_back(endpoint); + } + +private: + int m_threadPoolSize; + std::string m_agencyID; + std::vector m_gatewayInfo; +}; + +class FrontConfigBuilder +{ +public: + using Ptr = std::shared_ptr; + FrontConfigBuilder() = default; + virtual ~FrontConfigBuilder() = default; + + FrontConfig::Ptr build(int threadPoolSize, std::string agencyID) + { + return std::make_shared(threadPoolSize, agencyID); + } +}; +} // namespace ppc::front \ No newline at end of file diff --git a/cpp/ppc-framework/front/IFront.h b/cpp/ppc-framework/front/IFront.h new file mode 100644 index 00000000..be850b65 --- /dev/null +++ b/cpp/ppc-framework/front/IFront.h @@ -0,0 +1,106 @@ +/** + * Copyright (C) 2023 WeDPR. + * SPDX-License-Identifier: Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @file IFront.h + * @author: yujiechen + * @date 2024-08-22 + */ +#pragma once +#include "FrontConfig.h" +#include "ppc-framework/protocol/Message.h" +#include "ppc-framework/protocol/RouteType.h" +#include + +namespace ppc::front +{ +class IFront +{ +public: + using Ptr = std::shared_ptr; + + IFront() = default; + virtual ~IFront() = default; + + /** + * @brief start the IFront + * + * @param front the IFront to start + */ + virtual void start() const = 0; + /** + * @brief stop the IFront + * + * @param front the IFront to stop + */ + virtual void stop() const = 0; + + /** + * + * @param front the front object + * @param topic the topic + * @param callback the callback called when receive specified topic + */ + virtual void registerTopicHandler( + std::string const& topic, ppc::protocol::MessageCallback callback) = 0; + + /** + * @brief async send message + * + * @param routeType the route type + * @param topic the topic + * @param dstInst the dst agency(must set when 'route by agency' and 'route by + * component') + * @param dstNodeID the dst nodeID(must set when 'route by nodeID') + * @param componentType the componentType(must set when 'route by component') + * @param payload the payload to send + * @param seq the message seq + * @param timeout timeout + * @param callback callback + */ + virtual void asyncSendMessage(ppc::protocol::RouteType routeType, std::string const& topic, + std::string const& dstInst, bcos::bytes const& dstNodeID, std::string const& componentType, + bcos::bytes&& payload, int seq, long timeout, ppc::protocol::MessageCallback callback) = 0; + + // the sync interface for async_send_message + virtual ppc::protocol::Message::Ptr push(ppc::protocol::RouteType routeType, std::string topic, + std::string dstInst, std::string dstNodeID, std::string const& componentType, + bcos::bytes&& payload, int seq, long timeout) = 0; + + /** + * @brief: receive message from gateway, call by gateway + * @param _message: received ppc message + * @return void + */ + virtual void onReceiveMessage( + ppc::protocol::Message::Ptr const& _msg, ppc::protocol::ReceiveMsgFunc _callback) = 0; +}; + +class IFrontBuilder +{ +public: + using Ptr = std::shared_ptr; + IFrontBuilder() = default; + virtual ~IFrontBuilder() = default; + + /** + * @brief create the Front using specified config + * + * @param config the config used to build the Front + * @return IFront::Ptr he created Front + */ + virtual IFront::Ptr build(ppc::front::FrontConfig::Ptr config) const = 0; + virtual IFront::Ptr buildClient(std::string endPoint) const = 0; +}; +} // namespace ppc::front \ No newline at end of file diff --git a/cpp/ppc-framework/gateway/GatewayProtocol.h b/cpp/ppc-framework/gateway/GatewayProtocol.h index c3c0a94d..b91137d6 100644 --- a/cpp/ppc-framework/gateway/GatewayProtocol.h +++ b/cpp/ppc-framework/gateway/GatewayProtocol.h @@ -25,6 +25,7 @@ namespace ppc::gateway enum class GatewayPacketType : uint16_t { P2PMessage = 0x00, + BroadcastMessage = 0x01, RouterTableSyncSeq = 0x10, RouterTableResponse = 0x11, RouterTableRequest = 0x12 @@ -33,5 +34,16 @@ enum class GatewayPacketType : uint16_t enum class GatewayMsgExtFlag : uint16_t { Response = 0x1, + RouteByNodeID = 0x2, + RouteByAgency = 0x4, + RouteByComponent = 0x8, + RouteByTopic = 0x10 +}; + +enum CommonError : int32_t +{ + SUCCESS = 0, + TIMEOUT = 1000, // for gateway + NotFoundFrontServiceDispatchMsg = 1001 }; } // namespace ppc::gateway \ No newline at end of file diff --git a/cpp/ppc-framework/gateway/IGateway.h b/cpp/ppc-framework/gateway/IGateway.h new file mode 100644 index 00000000..9af59dba --- /dev/null +++ b/cpp/ppc-framework/gateway/IGateway.h @@ -0,0 +1,70 @@ +/** + * Copyright (C) 2023 WeDPR. + * SPDX-License-Identifier: Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @file IGateway.h + * @author: yujiechen + * @date 2024-08-26 + */ +#pragma once +#include "../protocol/INodeInfo.h" +#include "../protocol/Message.h" +#include "../protocol/RouteType.h" +#include + + +namespace ppc::gateway +{ +using ErrorCallbackFunc = std::function; +/** + * @brief: A list of interfaces provided by the gateway which are called by the front service. + */ +class IGateway +{ +public: + using Ptr = std::shared_ptr; + IGateway() = default; + virtual ~IGateway() {} + + /** + * @brief: start/stop service + */ + virtual void start() = 0; + virtual void stop() = 0; + + /** + * @brief send message to gateway + * + * @param routeType the route type + * @param topic the topic + * @param dstInst the dst agency(must set when 'route by agency' and 'route by + * component') + * @param dstNodeID the dst nodeID(must set when 'route by nodeID') + * @param componentType the componentType(must set when 'route by component') + * @param payload the payload to send + * @param seq the message seq + * @param timeout timeout + * @param callback callback + */ + virtual void asyncSendMessage(ppc::protocol::RouteType routeType, std::string const& topic, + std::string const& dstInst, bcos::bytes const& dstNodeID, std::string const& componentType, + bcos::bytes&& payload, long timeout, ppc::protocol::ReceiveMsgFunc callback) = 0; + + virtual void registerNodeInfo(ppc::protocol::INodeInfo::Ptr const& nodeInfo); + virtual void unRegisterNodeInfo(bcos::bytesConstRef nodeID); + virtual void registerTopic(bcos::bytesConstRef nodeID, std::string const& topic); + virtual void unRegisterTopic(bcos::bytesConstRef nodeID, std::string const& topic); +}; + +} // namespace ppc::gateway diff --git a/cpp/ppc-framework/protocol/INodeInfo.h b/cpp/ppc-framework/protocol/INodeInfo.h new file mode 100644 index 00000000..859d6ac6 --- /dev/null +++ b/cpp/ppc-framework/protocol/INodeInfo.h @@ -0,0 +1,65 @@ +/** + * Copyright (C) 2023 WeDPR. + * SPDX-License-Identifier: Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @file INodeInfo.h + * @author: yujiechen + * @date 2024-08-26 + */ +#pragma once +#include "ppc-framework/front/IFront.h" +#include + +namespace ppc::protocol +{ +// the node information +class INodeInfo +{ +public: + using Ptr = std::shared_ptr; + INodeInfo() = default; + virtual ~INodeInfo() = default; + + virtual std::string const& endPoint() const = 0; + virtual bcos::bytesConstRef nodeID() const = 0; + + // components + virtual void setComponents(std::vector const& components) = 0; + virtual std::set const& components() const = 0; + + virtual void encode(bcos::bytes& data) const = 0; + virtual void decode(bcos::bytesConstRef data) = 0; + + virtual void setFront(ppc::front::IFront::Ptr&& front) = 0; + virtual ppc::front::IFront::Ptr const& getFront() const = 0; + + virtual bool equal(INodeInfo::Ptr const& info) + { + return (nodeID() == info->nodeID()) && (components() == info->components()); + } +}; +class INodeInfoFactory +{ +public: + using Ptr = std::shared_ptr; + INodeInfoFactory(bcos::bytes nodeID) : m_nodeID(std::move(nodeID)) {} + virtual ~INodeInfoFactory() = default; + + virtual INodeInfo::Ptr build() = 0; + virtual INodeInfo::Ptr build(std::string const& endPoint) = 0; + +protected: + bcos::bytes m_nodeID; +}; +} // namespace ppc::protocol \ No newline at end of file diff --git a/cpp/ppc-framework/protocol/Message.h b/cpp/ppc-framework/protocol/Message.h index 40c5f614..b318c1c0 100644 --- a/cpp/ppc-framework/protocol/Message.h +++ b/cpp/ppc-framework/protocol/Message.h @@ -19,12 +19,13 @@ */ #pragma once #include "../Common.h" +#include "RouteType.h" #include #include +#include #include #include #include - namespace ppc::protocol { class MessageOptionalHeader @@ -38,8 +39,8 @@ class MessageOptionalHeader virtual int64_t decode(bcos::bytesConstRef data, uint64_t const _offset) = 0; // the componentType - virtual uint8_t componentType() const { return m_componentType; } - virtual void setComponentType(uint8_t componentType) { m_componentType = componentType; } + virtual std::string componentType() const { return m_componentType; } + virtual void setComponentType(std::string componentType) { m_componentType = componentType; } // the source nodeID that send the message virtual bcos::bytes const& srcNode() const { return m_srcNode; } @@ -50,18 +51,24 @@ class MessageOptionalHeader virtual void setDstNode(bcos::bytes const& dstNode) { m_dstNode = dstNode; } // the target agency that need receive the message - virtual bcos::bytes const& dstInst() const { return m_dstInst; } - virtual void setDstInst(bcos::bytes const& dstInst) { m_dstInst = dstInst; } + virtual std::string const& dstInst() const { return m_dstInst; } + virtual void setDstInst(std::string const& dstInst) { m_dstInst = dstInst; } + + // the topic + virtual std::string const& topic() const { return m_topic; } + virtual void setTopic(std::string&& topic) { m_topic = std::move(topic); } + virtual void setTopic(std::string const& topic) { m_topic = topic; } protected: + std::string m_topic; // the componentType - uint8_t m_componentType; + std::string m_componentType; // the source nodeID that send the message bcos::bytes m_srcNode; // the target nodeID that should receive the message bcos::bytes m_dstNode; // the target agency that need receive the message - bcos::bytes m_dstInst; + std::string m_dstInst; }; class MessageHeader @@ -117,9 +124,12 @@ class MessageHeader // Note: only for log std::string_view dstP2PNodeIDView() const { return printP2PIDElegantly(m_dstGwNode); } + virtual uint16_t routeType() const = 0; + virtual void setRouteType(ppc::protocol::RouteType type) = 0; + protected: // the msg version, used to support compatibility - uint8_t m_version; + uint8_t m_version = 0; // the traceID std::string m_traceID; // the srcGwNode @@ -129,7 +139,7 @@ class MessageHeader // the packetType uint16_t m_packetType; // the ttl - int16_t m_ttl; + int16_t m_ttl = 0; // the ext(contains the router policy and response flag) uint16_t m_ext; //// the optional field(used to route between components and nodes) @@ -187,14 +197,18 @@ class MessageHeaderBuilder virtual MessageHeader::Ptr build() = 0; }; -class MessageBuilder +class MessageBuilder : public bcos::boostssl::MessageFaceFactory { public: + using Ptr = std::shared_ptr; MessageBuilder() = default; - virtual ~MessageBuilder() = default; + ~MessageBuilder() override = default; virtual Message::Ptr build() = 0; virtual Message::Ptr build(bcos::bytesConstRef buffer) = 0; + virtual Message::Ptr build(ppc::protocol::RouteType routeType, std::string const& topic, + std::string const& dstInst, bcos::bytes const& dstNodeID, std::string const& componentType, + bcos::bytes&& payload) = 0; }; inline std::string printMessage(Message::Ptr const& _msg) @@ -218,4 +232,10 @@ inline std::string printWsMessage(bcos::boostssl::MessageFace::Ptr const& _msg) return stringstream.str(); } +// function to send response +using SendResponseFunction = std::function; +using ReceiveMsgFunc = std::function; +using MessageCallback = std::function; + } // namespace ppc::protocol \ No newline at end of file diff --git a/cpp/ppc-framework/protocol/MessagePayload.h b/cpp/ppc-framework/protocol/MessagePayload.h index 4329aae2..14304a16 100644 --- a/cpp/ppc-framework/protocol/MessagePayload.h +++ b/cpp/ppc-framework/protocol/MessagePayload.h @@ -36,22 +36,21 @@ class MessagePayload // the version virtual uint8_t version() const { return m_version; } virtual void setVersion(uint8_t version) { m_version = version; } - // the topic - virtual std::string const& topic() const { return m_topic; } - virtual void setTopic(std::string&& topic) { m_topic = std::move(topic); } - virtual void setTopic(std::string const& topic) { m_topic = topic; } // data virtual bcos::bytes const& data() const { return m_data; } virtual void setData(bcos::bytes&& data) { m_data = std::move(data); } virtual void setData(bcos::bytes const& data) { m_data = data; } + // the seq + virtual uint16_t seq() const { return m_seq; } + virtual void setSeq(uint16_t seq) { m_seq = seq; } // the length virtual int64_t length() const { return m_length; } protected: // the front payload version, used to support compatibility uint8_t m_version; - // the topic - std::string m_topic; + // the seq + uint16_t m_seq; bcos::bytes m_data; int64_t mutable m_length; }; diff --git a/cpp/ppc-framework/protocol/RouteType.h b/cpp/ppc-framework/protocol/RouteType.h new file mode 100644 index 00000000..1e3a715e --- /dev/null +++ b/cpp/ppc-framework/protocol/RouteType.h @@ -0,0 +1,54 @@ +/** + * Copyright (C) 2023 WeDPR. + * SPDX-License-Identifier: Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @file RouteType.h + * @author: yujiechen + * @date 2024-08-22 + */ + +#pragma once +#include +#include + +namespace ppc::protocol +{ +enum class RouteType : uint8_t +{ + ROUTE_THROUGH_NODEID = 0x00, + ROUTE_THROUGH_COMPONENT = 0x01, + ROUTE_THROUGH_AGENCY = 0x02, + ROUTE_THROUGH_TOPIC = 0x03 +}; + +inline std::ostream& operator<<(std::ostream& _out, RouteType const& _type) +{ + switch (_type) + { + case RouteType::ROUTE_THROUGH_NODEID: + _out << "RouteThroughNodeID"; + break; + case RouteType::ROUTE_THROUGH_COMPONENT: + _out << "RouteThroughComponent"; + break; + case RouteType::ROUTE_THROUGH_AGENCY: + _out << "RouteThroughAgency"; + break; + default: + _out << "UnknownRouteType"; + break; + } + return _out; +} +} // namespace ppc::front \ No newline at end of file diff --git a/cpp/ppc-gateway/ppc-gateway/gateway/GatewayImpl.cpp b/cpp/ppc-gateway/ppc-gateway/gateway/GatewayImpl.cpp new file mode 100644 index 00000000..7b4240c9 --- /dev/null +++ b/cpp/ppc-gateway/ppc-gateway/gateway/GatewayImpl.cpp @@ -0,0 +1,195 @@ +/** + * Copyright (C) 2023 WeDPR. + * SPDX-License-Identifier: Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @file GatewayImpl.cpp + * @author: yujiechen + * @date 2024-08-26 + */ +#include "GatewayImpl.h" +#include "SendMessageWithRetry.h" +#include "cache/MessageCache.h" +#include "ppc-framework/gateway/GatewayProtocol.h" +#include "router/GatewayNodeInfoImpl.h" + +using namespace bcos; +using namespace ppc; +using namespace ppc::protocol; +using namespace ppc::gateway; +using namespace bcos::boostssl; +using namespace bcos::boostssl::ws; + +GatewayImpl::GatewayImpl(Service::Ptr const& service, + ppc::front::IFrontBuilder::Ptr const& frontBuilder, + std::shared_ptr ioService, std::string const& agency) + : m_service(service), + m_msgBuilder( + std::dynamic_pointer_cast(service->messageFactory())), + m_frontBuilder(frontBuilder), + m_agency(agency), + m_p2pRouterManager(std::make_shared(service)), + m_gatewayInfoFactory(std::make_shared(service->nodeID(), agency)), + m_localRouter(std::make_shared( + m_gatewayInfoFactory, m_frontBuilder, std::make_shared(ioService))), + m_peerRouter(std::make_shared(m_service)) +{ + m_service->registerMsgHandler((uint16_t)GatewayPacketType::P2PMessage, + boost::bind(&GatewayImpl::onReceiveP2PMessage, this, boost::placeholders::_1, + boost::placeholders::_2)); + + m_service->registerMsgHandler((uint16_t)GatewayPacketType::BroadcastMessage, + boost::bind(&GatewayImpl::onReceiveBroadcastMessage, this, boost::placeholders::_1, + boost::placeholders::_2)); +} + +void GatewayImpl::start() +{ + if (m_running) + { + GATEWAY_LOG(INFO) << LOG_DESC("Gateway has already been started"); + return; + } + m_running = true; + m_service->start(); + m_p2pRouterManager->start(); + GATEWAY_LOG(INFO) << LOG_DESC("Start gateway success"); +} + +void GatewayImpl::stop() +{ + if (!m_running) + { + GATEWAY_LOG(INFO) << LOG_DESC("Gateway has already been stopped"); + return; + } + m_running = false; + m_service->stop(); + m_p2pRouterManager->stop(); + GATEWAY_LOG(INFO) << LOG_DESC("Stop gateway success"); +} + +void GatewayImpl::asyncSendbroadcastMessage(ppc::protocol::RouteType routeType, + std::string const& topic, std::string const& dstInst, std::string const& componentType, + bcos::bytes&& payload) +{ + // dispatcher to all the local front + auto p2pMessage = m_msgBuilder->build( + routeType, topic, dstInst, bcos::bytes(), componentType, std::move(payload)); + p2pMessage->setPacketType((uint16_t)GatewayPacketType::BroadcastMessage); + m_localRouter->dispatcherMessage(p2pMessage, nullptr); + // broadcast message to all peers + m_peerRouter->asyncBroadcastMessage(p2pMessage); +} + + +void GatewayImpl::asyncSendMessage(ppc::protocol::RouteType routeType, std::string const& topic, + std::string const& dstInst, bcos::bytes const& dstNodeID, std::string const& componentType, + bcos::bytes&& payload, long timeout, ReceiveMsgFunc callback) +{ + // check the localRouter + auto p2pMessage = m_msgBuilder->build( + routeType, topic, dstInst, dstNodeID, componentType, std::move(payload)); + p2pMessage->setPacketType((uint16_t)GatewayPacketType::P2PMessage); + auto nodeList = m_localRouter->chooseReceiver(p2pMessage); + // case send to the same agency + if (!nodeList.empty()) + { + GATEWAY_LOG(TRACE) << LOG_DESC("hit the local router, dispatch message directly") + << LOG_KV("msg", printMessage(p2pMessage)); + m_localRouter->dispatcherMessage(p2pMessage, callback); + return; + } + // try to find the dstP2PNode + auto selectedP2PNodes = m_peerRouter->selectRouter(routeType, p2pMessage); + if (selectedP2PNodes.empty()) + { + GATEWAY_LOG(INFO) << LOG_DESC("can't find the gateway to send the message") + << LOG_KV("detail", printMessage(p2pMessage)); + if (callback) + { + callback(std::make_shared( + -1, "can't find the gateway to send the message, traceID: " + + p2pMessage->header()->traceID())); + } + return; + } + // send the message to gateway + auto retry = std::make_shared( + m_service, std::move(selectedP2PNodes), std::move(p2pMessage), callback, timeout); + retry->trySendMessage(); +} + +void GatewayImpl::onReceiveP2PMessage(MessageFace::Ptr msg, WsSession::Ptr session) +{ + // try to dispatcher to the front + auto p2pMessage = std::dynamic_pointer_cast(msg); + auto self = std::weak_ptr(shared_from_this()); + auto callback = [p2pMessage, session, self](Error::Ptr error) { + auto gateway = self.lock(); + if (!gateway) + { + return; + } + std::string errorCode = std::to_string(CommonError::SUCCESS); + if (error && error->errorCode() != 0) + { + GATEWAY_LOG(WARNING) << LOG_DESC("onReceiveP2PMessage: dispatcherMessage failed") + << LOG_KV("code", error->errorCode()) + << LOG_KV("msg", error->errorMessage()); + errorCode = std::to_string(error->errorCode()); + } + + std::shared_ptr payload = + std::make_shared(errorCode.begin(), errorCode.end()); + gateway->m_service->sendRespMessageBySession(session, p2pMessage, std::move(payload)); + }; + + auto ret = m_localRouter->dispatcherMessage(p2pMessage, callback); + if (!ret) + { + GATEWAY_LOG(ERROR) + << LOG_DESC( + "onReceiveP2PMessage failed to find the node that can dispatch this message") + << LOG_KV("msg", printMessage(p2pMessage)); + callback(std::make_shared(CommonError::NotFoundFrontServiceDispatchMsg, + "unable to find the ndoe to dispatcher this message, message detail: " + + printMessage(p2pMessage))); + } +} + +void GatewayImpl::onReceiveBroadcastMessage(MessageFace::Ptr msg, WsSession::Ptr) +{ + auto p2pMessage = std::dynamic_pointer_cast(msg); + GATEWAY_LOG(TRACE) << LOG_DESC("onReceiveBroadcastMessage, dispatcher") + << LOG_KV("msg", printMessage(p2pMessage)); + m_localRouter->dispatcherMessage(p2pMessage, nullptr); +} + +void GatewayImpl::registerNodeInfo(ppc::protocol::INodeInfo::Ptr const& nodeInfo) +{ + m_localRouter->registerNodeInfo(nodeInfo); +} + +void GatewayImpl::unRegisterNodeInfo(bcos::bytesConstRef nodeID) +{ + m_localRouter->unRegisterNode(nodeID.toBytes()); +} +void GatewayImpl::registerTopic(bcos::bytesConstRef nodeID, std::string const& topic) +{ + m_localRouter->registerTopic(nodeID, topic); +} +void GatewayImpl::unRegisterTopic(bcos::bytesConstRef nodeID, std::string const& topic) +{ + m_localRouter->unRegisterTopic(nodeID, topic); +} \ No newline at end of file diff --git a/cpp/ppc-gateway/ppc-gateway/gateway/GatewayImpl.h b/cpp/ppc-gateway/ppc-gateway/gateway/GatewayImpl.h new file mode 100644 index 00000000..b71bd5b1 --- /dev/null +++ b/cpp/ppc-gateway/ppc-gateway/gateway/GatewayImpl.h @@ -0,0 +1,88 @@ +/** + * Copyright (C) 2023 WeDPR. + * SPDX-License-Identifier: Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @file GatewayImpl.h + * @author: yujiechen + * @date 2024-08-26 + */ +#pragma once +#include "ppc-framework/gateway/IGateway.h" +#include "ppc-gateway/gateway/router/GatewayNodeInfo.h" +#include "ppc-gateway/p2p/Service.h" +#include "ppc-gateway/p2p/router/RouterManager.h" +#include "router/LocalRouter.h" +#include "router/PeerRouterTable.h" + +namespace ppc::gateway +{ +class GatewayImpl : public IGateway, public std::enable_shared_from_this +{ +public: + using Ptr = std::shared_ptr; + GatewayImpl(Service::Ptr const& service, ppc::front::IFrontBuilder::Ptr const& frontBuilder, + std::shared_ptr ioService, std::string const& agency); + ~GatewayImpl() override = default; + + void start() override; + void stop() override; + + /** + * @brief send message to gateway + * + * @param routeType the route type + * @param topic the topic + * @param dstInst the dst agency(must set when 'route by agency' and 'route by + * component') + * @param dstNodeID the dst nodeID(must set when 'route by nodeID') + * @param componentType the componentType(must set when 'route by component') + * @param payload the payload to send + * @param seq the message seq + * @param timeout timeout + * @param callback callback + */ + void asyncSendMessage(ppc::protocol::RouteType routeType, std::string const& topic, + std::string const& dstInst, bcos::bytes const& dstNodeID, std::string const& componentType, + bcos::bytes&& payload, long timeout, ppc::protocol::ReceiveMsgFunc callback) override; + + void asyncSendbroadcastMessage(ppc::protocol::RouteType routeType, std::string const& topic, + std::string const& dstInst, std::string const& componentType, bcos::bytes&& payload); + + + void registerNodeInfo(ppc::protocol::INodeInfo::Ptr const& nodeInfo) override; + void unRegisterNodeInfo(bcos::bytesConstRef nodeID) override; + void registerTopic(bcos::bytesConstRef nodeID, std::string const& topic) override; + void unRegisterTopic(bcos::bytesConstRef nodeID, std::string const& topic) override; + +protected: + virtual void onReceiveP2PMessage( + bcos::boostssl::MessageFace::Ptr msg, bcos::boostssl::ws::WsSession::Ptr session); + virtual void onReceiveBroadcastMessage( + bcos::boostssl::MessageFace::Ptr msg, bcos::boostssl::ws::WsSession::Ptr session); + +private: + bool m_running = false; + Service::Ptr m_service; + ppc::protocol::MessageBuilder::Ptr m_msgBuilder; + + ppc::front::IFrontBuilder::Ptr m_frontBuilder; + std::string m_agency; + + RouterManager::Ptr m_p2pRouterManager; + + GatewayNodeInfoFactory::Ptr m_gatewayInfoFactory; + LocalRouter::Ptr m_localRouter; + PeerRouterTable::Ptr m_peerRouter; +}; +} // namespace ppc::gateway \ No newline at end of file diff --git a/cpp/ppc-gateway/ppc-gateway/gateway/SendMessageWithRetry.cpp b/cpp/ppc-gateway/ppc-gateway/gateway/SendMessageWithRetry.cpp new file mode 100644 index 00000000..19093b32 --- /dev/null +++ b/cpp/ppc-gateway/ppc-gateway/gateway/SendMessageWithRetry.cpp @@ -0,0 +1,114 @@ +/** + * Copyright (C) 2023 WeDPR. + * SPDX-License-Identifier: Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @file SendMessageWithRetry.h + * @author: yujiechen + * @date 2024-08-26 + */ +#include "SendMessageWithRetry.h" +#include "ppc-framework/gateway/GatewayProtocol.h" +#include "ppc-gateway/Common.h" + +using namespace bcos; +using namespace ppc; +using namespace bcos::boostssl; +using namespace bcos::boostssl::ws; +using namespace ppc::gateway; +using namespace ppc::protocol; + +// random choose one p2pID to send message +GatewayNodeInfo::Ptr SendMessageWithRetry::chooseP2pNode() +{ + RecursiveGuard lock(x_mutex); + if (!m_dstNodeList.empty()) + { + auto selectedNode = m_dstNodeList.begin(); + m_dstNodeList.erase(m_dstNodeList.begin()); + return *selectedNode; + } + return nullptr; +} + +// send the message with retry +void SendMessageWithRetry::trySendMessage() +{ + if (m_dstNodeList.empty()) + { + GATEWAY_LOG(DEBUG) << LOG_DESC("Gateway::SendMessageWithRetry") + << LOG_DESC("unable to send the message") << printMessage(m_p2pMessage); + if (m_respFunc) + { + m_respFunc(std::make_shared( + -1, "can't find the gateway to send the message, detail: " + + printMessage(m_p2pMessage))); + } + return; + } + auto choosedNode = chooseP2pNode(); + auto self = shared_from_this(); + auto startT = utcTime(); + auto callback = [self, startT]( + bcos::Error::Ptr error, MessageFace::Ptr msg, WsSession::Ptr session) { + std::ignore = session; + if (error && error->errorCode() != 0) + { + GATEWAY_LOG(DEBUG) << LOG_BADGE("trySendMessage") + << LOG_DESC("send message failed, retry again") + << LOG_KV("msg", printMessage(self->m_p2pMessage)) + << LOG_KV("code", error->errorCode()) + << LOG_KV("msg", error->errorMessage()) + << LOG_KV("timeCost", (utcTime() - startT)); + // try again + self->trySendMessage(); + return; + } + // check the errorCode + try + { + auto payload = msg->payload(); + int respCode = boost::lexical_cast(std::string(payload->begin(), payload->end())); + // the peer gateway not response not ok ,it means the gateway not dispatch the + // message successfully,find another gateway and try again + if (respCode != CommonError::SUCCESS) + { + GATEWAY_LOG(DEBUG) + << LOG_BADGE("trySendMessage again") << LOG_KV("respCode", respCode) + << LOG_KV("msg", printMessage(self->m_p2pMessage)); + // try again + self->trySendMessage(); + return; + } + GATEWAY_LOG(TRACE) << LOG_BADGE("asyncSendMessageByNodeID success") + << LOG_KV("msg", printMessage(self->m_p2pMessage)); + // send message successfully + if (self->m_respFunc) + { + self->m_respFunc(nullptr); + } + return; + } + catch (const std::exception& e) + { + GATEWAY_LOG(ERROR) << LOG_BADGE("trySendMessage and receive response exception") + << LOG_KV("msg", printMessage(self->m_p2pMessage)) + << LOG_KV("error", boost::diagnostic_information(e)); + + self->trySendMessage(); + } + }; + // Note: make 10s configuarable here + m_service->asyncSendMessageByNodeID( + choosedNode->p2pNodeID(), m_p2pMessage, bcos::boostssl::ws::Options(m_timeout), callback); +} \ No newline at end of file diff --git a/cpp/ppc-gateway/ppc-gateway/gateway/SendMessageWithRetry.h b/cpp/ppc-gateway/ppc-gateway/gateway/SendMessageWithRetry.h new file mode 100644 index 00000000..7df3b6f3 --- /dev/null +++ b/cpp/ppc-gateway/ppc-gateway/gateway/SendMessageWithRetry.h @@ -0,0 +1,62 @@ +/** + * Copyright (C) 2023 WeDPR. + * SPDX-License-Identifier: Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @file SendMessageWithRetry.h + * @author: yujiechen + * @date 2024-08-26 + */ +#pragma once +#include "ppc-framework/protocol/Message.h" +#include "ppc-gateway/gateway/router/GatewayNodeInfo.h" +#include "ppc-gateway/p2p/Service.h" +#include +#include + +namespace ppc::gateway +{ +class SendMessageWithRetry : public std::enable_shared_from_this +{ +public: + using Ptr = std::shared_ptr; + SendMessageWithRetry(Service::Ptr const& service, GatewayNodeInfos&& dstNodeList, + ppc::protocol::Message::Ptr&& p2pMessage, ppc::protocol::ReceiveMsgFunc respFunc, + long timeout) + : m_service(service), + m_dstNodeList(std::move(dstNodeList)), + m_p2pMessage(std::move(p2pMessage)), + m_respFunc(std::move(respFunc)), + m_timeout(timeout) + { + if (m_timeout < 0) + { + m_timeout = 10000; + } + } + // random choose one p2pID to send message + GatewayNodeInfo::Ptr chooseP2pNode(); + + // send the message with retry + void trySendMessage(); + +private: + // mutex for p2pIDs + mutable bcos::RecursiveMutex x_mutex; + GatewayNodeInfos m_dstNodeList; + ppc::protocol::Message::Ptr m_p2pMessage; + Service::Ptr m_service; + ppc::protocol::ReceiveMsgFunc m_respFunc; + long m_timeout; +}; +} // namespace ppc::gateway \ No newline at end of file diff --git a/cpp/ppc-gateway/ppc-gateway/gateway/cache/MessageCache.cpp b/cpp/ppc-gateway/ppc-gateway/gateway/cache/MessageCache.cpp new file mode 100644 index 00000000..09c8f8e2 --- /dev/null +++ b/cpp/ppc-gateway/ppc-gateway/gateway/cache/MessageCache.cpp @@ -0,0 +1,94 @@ +/** + * Copyright (C) 2023 WeDPR. + * SPDX-License-Identifier: Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @file MessageCache.cpp + * @author: yujiechen + * @date 2024-08-26 + */ + +#include "MessageCache.h" +#include "ppc-gateway/Common.h" + +using namespace ppc; +using namespace bcos; +using namespace ppc::protocol; +using namespace ppc::gateway; + +void MessageCache::insertCache( + std::string const& topic, ppc::protocol::Message::Ptr const& msg, ReceiveMsgFunc callback) +{ + // hold the message + GATEWAY_LOG(DEBUG) << LOG_BADGE("MessageCache: insertCache") << LOG_KV("topic", topic); + bcos::ReadGuard l(x_msgCache); + auto it = m_msgCache.find(topic); + if (it == m_msgCache.end()) + { + it->second->messages.emplace_back(MessageInfo{msg, callback}); + return; + } + // insert new holding-queue + auto queue = std::make_shared(); + queue->messages.emplace_back(MessageInfo{msg, callback}); + // create timer to handle timeout + queue->timer = std::make_shared( + *m_ioService, boost::posix_time::minutes(m_holdingMessageMinutes)); + queue->timer->async_wait([self = weak_from_this(), topic](boost::system::error_code _error) { + if (!_error) + { + auto cache = self.lock(); + if (cache) + { + // remove timeout message + auto msgQueue = cache->pop(topic); + if (!msgQueue) + { + return; + } + msgQueue->timer->cancel(); + cache->onTimeout(msgQueue); + } + } + }); + m_msgCache[topic] = queue; +} + +HoldingMessageQueue::Ptr MessageCache::pop(const std::string& topic) +{ + WriteGuard lock(x_msgCache); + auto it = m_msgCache.find(topic); + if (it == m_msgCache.end()) + { + return nullptr; + } + HoldingMessageQueue::Ptr ret = it->second; + m_msgCache.erase(topic); + return ret; +} + +void MessageCache::onTimeout(HoldingMessageQueue::Ptr const& queue) +{ + if (!queue) + { + return; + } + // dispatch the ack + for (auto& msgInfo : queue->messages) + { + if (msgInfo.callback) + { + msgInfo.callback(std::make_shared(-1, SEND_MESSAGE_TO_FRONT_TIMEOUT)); + } + } +} \ No newline at end of file diff --git a/cpp/ppc-gateway/ppc-gateway/gateway/cache/MessageCache.h b/cpp/ppc-gateway/ppc-gateway/gateway/cache/MessageCache.h new file mode 100644 index 00000000..65502edb --- /dev/null +++ b/cpp/ppc-gateway/ppc-gateway/gateway/cache/MessageCache.h @@ -0,0 +1,70 @@ +/** + * Copyright (C) 2023 WeDPR. + * SPDX-License-Identifier: Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @file MessageCache.h + * @author: yujiechen + * @date 2024-08-26 + */ +#pragma once +#include "ppc-framework/front/IFront.h" +#include "ppc-framework/protocol/Message.h" +#include "tbb/concurrent_vector.h" +#include +#include +#include + +namespace ppc::gateway +{ +struct MessageInfo +{ + ppc::protocol::Message::Ptr msg; + ppc::protocol::ReceiveMsgFunc callback; +}; +struct HoldingMessageQueue +{ + using Ptr = std::shared_ptr; + HoldingMessageQueue() = default; + + tbb::concurrent_vector messages; + std::shared_ptr timer; +}; + +class MessageCache : public std::enable_shared_from_this +{ +public: + using Ptr = std::shared_ptr; + MessageCache(std::shared_ptr ioService) + : m_ioService(std::move(ioService)) + {} + virtual ~MessageCache() = default; + + void insertCache(std::string const& topic, ppc::protocol::Message::Ptr const& msg, + ppc::protocol::ReceiveMsgFunc callback); + HoldingMessageQueue::Ptr pop(std::string const& topic); + +private: + void onTimeout(HoldingMessageQueue::Ptr const& queue); + +private: + int m_holdingMessageMinutes = 30; + std::shared_ptr m_ioService; + /** + * hold the message for the situation that + * gateway receives message from the other side while the task has not been registered. + */ + mutable bcos::SharedMutex x_msgCache; + std::unordered_map m_msgCache; +}; +} // namespace ppc::gateway \ No newline at end of file diff --git a/cpp/ppc-gateway/ppc-gateway/gateway/router/GatewayNodeInfo.h b/cpp/ppc-gateway/ppc-gateway/gateway/router/GatewayNodeInfo.h new file mode 100644 index 00000000..e25db02e --- /dev/null +++ b/cpp/ppc-gateway/ppc-gateway/gateway/router/GatewayNodeInfo.h @@ -0,0 +1,74 @@ +/** + * Copyright (C) 2023 WeDPR. + * SPDX-License-Identifier: Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @file GatewayNodeInfo.h + * @author: yujiechen + * @date 2024-08-26 + */ +#pragma once +#include "ppc-framework/protocol/INodeInfo.h" +#include +namespace ppc::gateway +{ +class GatewayNodeInfo +{ +public: + using Ptr = std::shared_ptr; + GatewayNodeInfo() = default; + virtual ~GatewayNodeInfo() = default; + + // the gateway nodeID + virtual std::string const& p2pNodeID() const = 0; + // the agency + virtual std::string const& agency() const = 0; + // get the node information by nodeID + virtual ppc::protocol::INodeInfo::Ptr nodeInfo(bcos::bytes const& nodeID) const = 0; + virtual bool tryAddNodeInfo(ppc::protocol::INodeInfo::Ptr const& nodeInfo) = 0; + virtual void removeNodeInfo(bcos::bytes const& nodeID) = 0; + + virtual std::vector chooseRouteByComponent( + bool selectAll, std::string const& component) const = 0; + virtual std::vector chooseRouterByAgency(bool selectAll) const = 0; + virtual std::vector chooseRouterByTopic( + bool selectAll, std::string const& topic) const = 0; + + virtual void encode(bcos::bytes& data) const = 0; + virtual void decode(bcos::bytesConstRef data) = 0; + + virtual void registerTopic(bcos::bytes const& nodeID, std::string const& topic) = 0; + virtual void unRegisterTopic(bcos::bytes const& nodeID, std::string const& topic) = 0; + + virtual std::map nodeList() const = 0; +}; + +class GatewayNodeInfoFactory +{ +public: + using Ptr = std::shared_ptr; + GatewayNodeInfoFactory() = default; + virtual ~GatewayNodeInfoFactory() = default; + + virtual GatewayNodeInfo::Ptr build() const = 0; +}; +struct GatewayNodeInfoCmp +{ + bool operator()(GatewayNodeInfo::Ptr const& _first, GatewayNodeInfo::Ptr const& _second) const + { + // increase order + return _first->p2pNodeID() > _second->p2pNodeID(); + } +}; +using GatewayNodeInfos = std::set; +} // namespace ppc::gateway \ No newline at end of file diff --git a/cpp/ppc-gateway/ppc-gateway/gateway/router/GatewayNodeInfoImpl.cpp b/cpp/ppc-gateway/ppc-gateway/gateway/router/GatewayNodeInfoImpl.cpp new file mode 100644 index 00000000..f7c9cefe --- /dev/null +++ b/cpp/ppc-gateway/ppc-gateway/gateway/router/GatewayNodeInfoImpl.cpp @@ -0,0 +1,206 @@ +/** + * Copyright (C) 2023 WeDPR. + * SPDX-License-Identifier: Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @file GatewayNodeInfoImpl.cpp + * @author: yujiechen + * @date 2024-08-26 + */ +#include "GatewayNodeInfoImpl.h" +#include "ppc-tars-protocol/Common.h" +#include "ppc-tars-protocol/impl/NodeInfoImpl.h" + +using namespace ppctars; +using namespace ppc::protocol; +using namespace ppc::gateway; + + +// the gateway nodeID +std::string const& GatewayNodeInfoImpl::p2pNodeID() const +{ + return m_inner()->p2pNodeID; +} +// the agency +std::string const& GatewayNodeInfoImpl::agency() const +{ + return m_inner()->agency; +} +// get the node information by nodeID +INodeInfo::Ptr GatewayNodeInfoImpl::nodeInfo(bcos::bytes const& nodeID) const +{ + bcos::ReadGuard l(x_nodeList); + if (m_nodeList.count(nodeID)) + { + return m_nodeList.at(nodeID); + } + return nullptr; +} + +bool GatewayNodeInfoImpl::tryAddNodeInfo(INodeInfo::Ptr const& info) +{ + auto nodeID = info->nodeID().toBytes(); + auto existedNodeInfo = nodeInfo(nodeID); + // update the info + if (existedNodeInfo == nullptr || !existedNodeInfo->equal(info)) + { + bcos::WriteGuard l(x_nodeList); + m_nodeList[nodeID] = info; + return true; + } + return false; +} + +void GatewayNodeInfoImpl::removeNodeInfo(bcos::bytes const& nodeID) +{ + // remove the nodeInfo + { + bcos::UpgradableGuard l(x_nodeList); + auto it = m_nodeList.find(nodeID); + if (it == m_nodeList.end()) + { + return; + } + bcos::UpgradeGuard ul(l); + m_nodeList.erase(it); + } + // remove the topic info + { + bcos::UpgradableGuard l(x_topicInfo); + auto it = m_topicInfo.find(nodeID); + if (it != m_topicInfo.end()) + { + bcos::UpgradeGuard ul(l); + m_topicInfo.erase(it); + } + } +} + +std::vector GatewayNodeInfoImpl::chooseRouteByComponent( + bool selectAll, std::string const& component) const +{ + std::vector result; + bcos::ReadGuard l(x_nodeList); + for (auto const& it : m_nodeList) + { + if (it.second->components().count(component)) + { + result.emplace_back(it.second->getFront()); + } + if (!result.empty() && !selectAll) + { + break; + } + } + return result; +} + + +vector GatewayNodeInfoImpl::chooseRouterByAgency(bool selectAll) const +{ + std::vector result; + bcos::ReadGuard l(x_nodeList); + for (auto const& it : m_nodeList) + { + result.emplace_back(it.second->getFront()); + if (!result.empty() && !selectAll) + { + break; + } + } + return result; +} + +std::vector GatewayNodeInfoImpl::chooseRouterByTopic( + bool selectAll, std::string const& topic) const +{ + std::vector result; + bcos::ReadGuard l(x_topicInfo); + for (auto const& it : m_topicInfo) + { + INodeInfo::Ptr selectedNode = nullptr; + if (it.second.count(topic)) + { + selectedNode = nodeInfo(it.first); + } + if (selectedNode != nullptr) + { + result.emplace_back(selectedNode->getFront()); + } + if (!result.empty() && !selectAll) + { + break; + } + } + return result; +} +void GatewayNodeInfoImpl::registerTopic(bcos::bytes const& nodeID, std::string const& topic) +{ + bcos::UpgradableGuard l(x_topicInfo); + if (m_topicInfo.count(nodeID) && m_topicInfo.at(nodeID).count(topic)) + { + return; + } + bcos::UpgradeGuard ul(l); + if (!m_topicInfo.count(nodeID)) + { + m_topicInfo[nodeID] = std::set(); + } + m_topicInfo[nodeID].insert(topic); +} + +void GatewayNodeInfoImpl::unRegisterTopic(bcos::bytes const& nodeID, std::string const& topic) +{ + bcos::UpgradableGuard l(x_topicInfo); + if (!m_topicInfo.count(nodeID) || !m_topicInfo.at(nodeID).count(topic)) + { + return; + } + bcos::UpgradeGuard ul(l); + m_topicInfo[nodeID].erase(topic); +} + +void GatewayNodeInfoImpl::encode(bcos::bytes& data) const +{ + m_inner()->nodeList.clear(); + { + bcos::ReadGuard l(x_nodeList); + // encode nodeList + for (auto const& it : m_nodeList) + { + auto nodeInfo = std::dynamic_pointer_cast(it.second); + m_inner()->nodeList.emplace_back(nodeInfo->inner()); + } + } + tars::TarsOutputStream output; + m_inner()->writeTo(output); + output.getByteBuffer().swap(data); +} + +void GatewayNodeInfoImpl::decode(bcos::bytesConstRef data) +{ + tars::TarsInputStream input; + input.setBuffer((const char*)data.data(), data.size()); + m_inner()->readFrom(input); + { + bcos::WriteGuard l(x_nodeList); + // decode into m_nodeList + m_nodeList.clear(); + for (auto& it : m_inner()->nodeList) + { + auto nodeInfoPtr = + std::make_shared([m_entry = it]() mutable { return &m_entry; }); + m_nodeList.insert(std::make_pair(nodeInfoPtr->nodeID().toBytes(), nodeInfoPtr)); + } + } +} \ No newline at end of file diff --git a/cpp/ppc-gateway/ppc-gateway/gateway/router/GatewayNodeInfoImpl.h b/cpp/ppc-gateway/ppc-gateway/gateway/router/GatewayNodeInfoImpl.h new file mode 100644 index 00000000..cb0dfc10 --- /dev/null +++ b/cpp/ppc-gateway/ppc-gateway/gateway/router/GatewayNodeInfoImpl.h @@ -0,0 +1,100 @@ +/** + * Copyright (C) 2023 WeDPR. + * SPDX-License-Identifier: Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @file GatewayNodeInfoImpl.h + * @author: yujiechen + * @date 2024-08-26 + */ +#pragma once +#include "GatewayNodeInfo.h" +#include "ppc-tars-protocol/tars/NodeInfo.h" +#include +#include + +namespace ppc::gateway +{ +class GatewayNodeInfoImpl : public GatewayNodeInfo +{ +public: + using Ptr = std::shared_ptr; + GatewayNodeInfoImpl(std::string const& p2pNodeID, std::string const& agency) + : m_inner([inner = ppctars::GatewayNodeInfo()]() mutable { return &inner; }) + { + m_inner()->p2pNodeID = p2pNodeID; + m_inner()->agency = agency; + } + ~GatewayNodeInfoImpl() override = default; + + // the gateway nodeID + std::string const& p2pNodeID() const override; + // the agency + std::string const& agency() const override; + // the node information + + // get the node information by nodeID + ppc::protocol::INodeInfo::Ptr nodeInfo(bcos::bytes const& nodeID) const override; + + void encode(bcos::bytes& data) const override; + void decode(bcos::bytesConstRef data) override; + + bool tryAddNodeInfo(ppc::protocol::INodeInfo::Ptr const& nodeInfo) override; + void removeNodeInfo(bcos::bytes const& nodeID) override; + + std::vector chooseRouteByComponent( + bool selectAll, std::string const& component) const override; + std::vector chooseRouterByAgency(bool selectAll) const override; + std::vector chooseRouterByTopic( + bool selectAll, std::string const& topic) const override; + + void registerTopic(bcos::bytes const& nodeID, std::string const& topic) override; + void unRegisterTopic(bcos::bytes const& nodeID, std::string const& topic) override; + + std::map nodeList() const override + { + bcos::WriteGuard l(x_nodeList); + return m_nodeList; + } + +private: + std::function m_inner; + // NodeID => nodeInfo + std::map m_nodeList; + mutable bcos::SharedMutex x_nodeList; + + // NodeID=>topics + using Topics = std::set; + std::map m_topicInfo; + mutable bcos::SharedMutex x_topicInfo; +}; + +class GatewayNodeInfoFactoryImpl : public GatewayNodeInfoFactory +{ +public: + using Ptr = std::shared_ptr; + GatewayNodeInfoFactoryImpl(std::string const& p2pNodeID, std::string const& agency) + : m_p2pNodeID(p2pNodeID), m_agency(agency) + {} + ~GatewayNodeInfoFactoryImpl() override = default; + + GatewayNodeInfo::Ptr build() const override + { + return std::make_shared(m_p2pNodeID, m_agency); + } + +private: + std::string m_p2pNodeID; + std::string m_agency; +}; +} // namespace ppc::gateway \ No newline at end of file diff --git a/cpp/ppc-gateway/ppc-gateway/gateway/router/LocalRouter.cpp b/cpp/ppc-gateway/ppc-gateway/gateway/router/LocalRouter.cpp new file mode 100644 index 00000000..9df4e45f --- /dev/null +++ b/cpp/ppc-gateway/ppc-gateway/gateway/router/LocalRouter.cpp @@ -0,0 +1,122 @@ +/** + * Copyright (C) 2023 WeDPR. + * SPDX-License-Identifier: Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @file LocalRouter.h + * @author: yujiechen + * @date 2024-08-26 + */ +#include "LocalRouter.h" +#include "ppc-framework/Common.h" +#include "ppc-framework/gateway/GatewayProtocol.h" + +using namespace bcos; +using namespace ppc::protocol; +using namespace ppc::gateway; + +void LocalRouter::registerTopic(bcos::bytesConstRef _nodeID, std::string const& topic) +{ + m_routerInfo->registerTopic(_nodeID.toBytes(), topic); + // try to dispatch the cacheInfo + if (!m_cache) + { + return; + } + auto msgQueue = m_cache->pop(topic); + if (!msgQueue) + { + return; + } + if (msgQueue->timer) + { + msgQueue->timer->cancel(); + } + for (auto const& msgInfo : msgQueue->messages) + { + dispatcherMessage(msgInfo.msg, msgInfo.callback, false); + } +} + +void LocalRouter::unRegisterTopic(bcos::bytesConstRef _nodeID, std::string const& topic) +{ + m_routerInfo->unRegisterTopic(_nodeID.toBytes(), topic); +} + +bool LocalRouter::dispatcherMessage(Message::Ptr const& msg, ReceiveMsgFunc callback, bool holding) +{ + auto frontList = chooseReceiver(msg); + // send success + if (!frontList.empty()) + { + for (auto const& front : frontList) + { + front->onReceiveMessage(msg, callback); + } + return true; + } + if (!holding) + { + return false; + } + // no connection found, cache the topic message and dispatcher later + if (msg->header()->routeType() == (uint16_t)RouteType::ROUTE_THROUGH_TOPIC && m_cache) + { + m_cache->insertCache(msg->header()->optionalField()->topic(), msg, callback); + return true; + } + return false; +} + +std::vector LocalRouter::chooseReceiver( + ppc::protocol::Message::Ptr const& msg) +{ + std::vector receivers; + if (msg->header()->optionalField()->dstInst() != m_routerInfo->agency()) + { + return receivers; + } + bool selectAll = + (msg->header()->packetType() == (uint16_t)GatewayPacketType::BroadcastMessage ? true : + false); + switch (msg->header()->routeType()) + { + case (uint16_t)RouteType::ROUTE_THROUGH_NODEID: + { + auto gatewayInfo = m_routerInfo->nodeInfo(msg->header()->optionalField()->dstNode()); + if (gatewayInfo != nullptr) + { + receivers.emplace_back(gatewayInfo->getFront()); + } + return receivers; + } + case (uint16_t)RouteType::ROUTE_THROUGH_COMPONENT: + { + return m_routerInfo->chooseRouteByComponent( + selectAll, msg->header()->optionalField()->componentType()); + } + case (uint16_t)RouteType::ROUTE_THROUGH_AGENCY: + { + return m_routerInfo->chooseRouterByAgency(selectAll); + } + case (uint16_t)RouteType::ROUTE_THROUGH_TOPIC: + { + return m_routerInfo->chooseRouterByTopic( + selectAll, msg->header()->optionalField()->topic()); + } + default: + BOOST_THROW_EXCEPTION(WeDPRException() << errinfo_comment( + "chooseReceiver failed for unknown routeType, message detail: " + + printMessage(msg))); + } +} diff --git a/cpp/ppc-gateway/ppc-gateway/gateway/router/LocalRouter.h b/cpp/ppc-gateway/ppc-gateway/gateway/router/LocalRouter.h new file mode 100644 index 00000000..194ef6ab --- /dev/null +++ b/cpp/ppc-gateway/ppc-gateway/gateway/router/LocalRouter.h @@ -0,0 +1,71 @@ +/** + * Copyright (C) 2023 WeDPR. + * SPDX-License-Identifier: Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @file LocalRouter.h + * @author: yujiechen + * @date 2024-08-26 + */ +#pragma once +#include "../cache/MessageCache.h" +#include "GatewayNodeInfo.h" +#include "ppc-framework/protocol/INodeInfo.h" +#include "ppc-framework/protocol/Message.h" +#include "ppc-framework/protocol/RouteType.h" + +namespace ppc::gateway +{ +class LocalRouter +{ +public: + using Ptr = std::shared_ptr; + LocalRouter(GatewayNodeInfoFactory::Ptr nodeInfoFactory, + ppc::front::IFrontBuilder::Ptr frontBuilder, MessageCache::Ptr msgCache) + : m_routerInfo(std::move(nodeInfoFactory->build())), + m_frontBuilder(std::move(frontBuilder)), + m_cache(std::move(msgCache)) + {} + + virtual ~LocalRouter() = default; + + virtual bool registerNodeInfo(ppc::protocol::INodeInfo::Ptr const& nodeInfo) + { + nodeInfo->setFront(m_frontBuilder->buildClient(nodeInfo->endPoint())); + return m_routerInfo->tryAddNodeInfo(nodeInfo); + } + + virtual void unRegisterNode(bcos::bytes const& nodeID) { m_routerInfo->removeNodeInfo(nodeID); } + + virtual void registerTopic(bcos::bytesConstRef nodeID, std::string const& topic); + virtual void unRegisterTopic(bcos::bytesConstRef nodeID, std::string const& topic); + + virtual std::vector chooseReceiver( + ppc::protocol::Message::Ptr const& msg); + + // TODO: register component + virtual bool dispatcherMessage(ppc::protocol::Message::Ptr const& msg, + ppc::protocol::ReceiveMsgFunc callback, bool holding = true); + +private: + ppc::front::IFrontBuilder::Ptr m_frontBuilder; + GatewayNodeInfo::Ptr m_routerInfo; + + // NodeID=>topics + using Topics = std::set; + std::map m_topicInfo; + mutable bcos::SharedMutex x_topicInfo; + + MessageCache::Ptr m_cache; +}; +} // namespace ppc::gateway \ No newline at end of file diff --git a/cpp/ppc-gateway/ppc-gateway/gateway/router/PeerRouterTable.cpp b/cpp/ppc-gateway/ppc-gateway/gateway/router/PeerRouterTable.cpp new file mode 100644 index 00000000..a2bccd0a --- /dev/null +++ b/cpp/ppc-gateway/ppc-gateway/gateway/router/PeerRouterTable.cpp @@ -0,0 +1,138 @@ +/** + * Copyright (C) 2023 WeDPR. + * SPDX-License-Identifier: Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @file PeerRouterTable.cpp + * @author: yujiechen + * @date 2024-08-27 + */ +#include "PeerRouterTable.h" +#include "ppc-framework/Common.h" +#include + +using namespace bcos; +using namespace ppc; +using namespace ppc::gateway; +using namespace ppc::protocol; + +void PeerRouterTable::updateGatewayInfo(GatewayNodeInfo::Ptr const& gatewayInfo) +{ + auto nodeList = gatewayInfo->nodeList(); + bcos::WriteGuard l(x_mutex); + for (auto const& it : nodeList) + { + // update nodeID => gatewayInfos + m_nodeID2GatewayInfos[it.first].insert(gatewayInfo); + } + // update agency => gatewayInfos + m_agency2GatewayInfos[gatewayInfo->agency()].insert(gatewayInfo); +} + +GatewayNodeInfos PeerRouterTable::selectRouter( + RouteType const& routeType, Message::Ptr const& msg) const +{ + switch (routeType) + { + case RouteType::ROUTE_THROUGH_NODEID: + return selectRouterByNodeID(msg); + case RouteType::ROUTE_THROUGH_COMPONENT: + return selectRouterByComponent(msg); + case RouteType::ROUTE_THROUGH_AGENCY: + case RouteType::ROUTE_THROUGH_TOPIC: + return selectRouterByAgency(msg); + default: + BOOST_THROW_EXCEPTION(WeDPRException() << errinfo_comment( + "selectRouter failed for encounter unsupported routeType: " + + std::to_string((uint16_t)routeType))); + } +} + +GatewayNodeInfos PeerRouterTable::selectRouterByNodeID(Message::Ptr const& msg) const +{ + GatewayNodeInfos result; + bcos::ReadGuard l(x_mutex); + auto it = m_nodeID2GatewayInfos.find(msg->header()->optionalField()->dstNode()); + // no router found + if (it == m_nodeID2GatewayInfos.end()) + { + return result; + } + return it->second; +} + + +GatewayNodeInfos PeerRouterTable::selectRouterByAgency(Message::Ptr const& msg) const +{ + GatewayNodeInfos result; + bcos::ReadGuard l(x_mutex); + auto it = m_agency2GatewayInfos.find(msg->header()->optionalField()->dstInst()); + // no router found + if (it == m_agency2GatewayInfos.end()) + { + return result; + } + return it->second; +} + +GatewayNodeInfos PeerRouterTable::selectRouterByComponent(Message::Ptr const& msg) const +{ + GatewayNodeInfos result; + bcos::ReadGuard l(x_mutex); + auto it = m_agency2GatewayInfos.find(msg->header()->optionalField()->dstInst()); + // no router found + if (it == m_agency2GatewayInfos.end()) + { + return result; + } + auto const& gatewayInfos = it->second; + // foreach all gateways to find the component + for (auto const& it : gatewayInfos) + { + auto const& nodeListInfo = it->nodeList(); + for (auto const& nodeInfo : nodeListInfo) + { + if (nodeInfo.second->components().count( + msg->header()->optionalField()->componentType())) + { + result.insert(it); + break; + } + } + } + return result; +} + +void PeerRouterTable::asyncBroadcastMessage(ppc::protocol::Message::Ptr const& msg) const +{ + bcos::ReadGuard l(x_mutex); + for (auto const& it : m_agency2GatewayInfos) + { + auto selectedIndex = rand() % it.second.size(); + auto iterator = it.second.begin(); + if (selectedIndex > 0) + { + std::advance(iterator, selectedIndex); + } + auto selectedNode = *iterator; + // ignore self + if (selectedNode->p2pNodeID() == m_service->nodeID()) + { + continue; + } + GATEWAY_LOG(TRACE) << LOG_DESC("asyncBroadcastMessage") + << LOG_KV("nodeID", printP2PIDElegantly(selectedNode->p2pNodeID())) + << LOG_KV("msg", printMessage(msg)); + m_service->asyncSendMessageByNodeID(selectedNode->p2pNodeID(), msg); + } +} diff --git a/cpp/ppc-gateway/ppc-gateway/gateway/router/PeerRouterTable.h b/cpp/ppc-gateway/ppc-gateway/gateway/router/PeerRouterTable.h new file mode 100644 index 00000000..7a433303 --- /dev/null +++ b/cpp/ppc-gateway/ppc-gateway/gateway/router/PeerRouterTable.h @@ -0,0 +1,57 @@ +/** + * Copyright (C) 2023 WeDPR. + * SPDX-License-Identifier: Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @file PeerRouterTable.h + * @author: yujiechen + * @date 2024-08-27 + */ +#pragma once +#include "GatewayNodeInfo.h" +#include "ppc-framework/protocol/Message.h" +#include "ppc-framework/protocol/RouteType.h" +#include "ppc-gateway/p2p/Service.h" +#include +#include + +namespace ppc::gateway +{ +class PeerRouterTable +{ +public: + using Ptr = std::shared_ptr; + PeerRouterTable(Service::Ptr service) : m_service(std::move(service)) {} + virtual ~PeerRouterTable() = default; + + virtual void updateGatewayInfo(GatewayNodeInfo::Ptr const& gatewayInfo); + virtual GatewayNodeInfos selectRouter( + ppc::protocol::RouteType const& routeType, ppc::protocol::Message::Ptr const& msg) const; + + virtual void asyncBroadcastMessage(ppc::protocol::Message::Ptr const& msg) const; + +private: + virtual GatewayNodeInfos selectRouterByNodeID(ppc::protocol::Message::Ptr const& msg) const; + virtual GatewayNodeInfos selectRouterByComponent(ppc::protocol::Message::Ptr const& msg) const; + virtual GatewayNodeInfos selectRouterByAgency(ppc::protocol::Message::Ptr const& msg) const; + + +private: + Service::Ptr m_service; + // nodeID => p2pNodes + std::map m_nodeID2GatewayInfos; + // agency => p2pNodes + std::map m_agency2GatewayInfos; + mutable bcos::SharedMutex x_mutex; +}; +} // namespace ppc::gateway \ No newline at end of file diff --git a/cpp/ppc-gateway/ppc-gateway/p2p/Service.cpp b/cpp/ppc-gateway/ppc-gateway/p2p/Service.cpp index 469e5b27..fd36e94e 100644 --- a/cpp/ppc-gateway/ppc-gateway/p2p/Service.cpp +++ b/cpp/ppc-gateway/ppc-gateway/p2p/Service.cpp @@ -296,4 +296,28 @@ void Service::asyncSendMessageByP2PNodeID(uint16_t type, std::string const& dstN message->setPacketType(type); message->setPayload(payload); asyncSendMessageByNodeID(dstNodeID, message, options, callback); +} + +void Service::sendRespMessageBySession(bcos::boostssl::ws::WsSession::Ptr const& session, + bcos::boostssl::MessageFace::Ptr msg, std::shared_ptr&& payload) +{ + auto respMessage = std::dynamic_pointer_cast(m_messageFactory->buildMessage()); + auto requestMsg = std::dynamic_pointer_cast(msg); + if (requestMsg->header() && requestMsg->header()->optionalField()) + { + respMessage->header()->optionalField()->setDstNode( + requestMsg->header()->optionalField()->srcNode()); + respMessage->header()->optionalField()->setSrcNode( + requestMsg->header()->optionalField()->dstNode()); + } + respMessage->header()->setTraceID(requestMsg->header()->traceID()); + respMessage->header()->setRespPacket(); + respMessage->header()->setRouteType(ppc::protocol::RouteType::ROUTE_THROUGH_NODEID); + respMessage->setPayload(std::move(payload)); + + WsSessions sessions; + sessions.emplace_back(session); + WsService::asyncSendMessage(sessions, respMessage); + GATEWAY_LOG(TRACE) << "sendRespMessageBySession" << LOG_KV("resp", printMessage(respMessage)) + << LOG_KV("payload size", payload->size()); } \ No newline at end of file diff --git a/cpp/ppc-gateway/ppc-gateway/p2p/Service.h b/cpp/ppc-gateway/ppc-gateway/p2p/Service.h index a3c8f5ea..e78aff23 100644 --- a/cpp/ppc-gateway/ppc-gateway/p2p/Service.h +++ b/cpp/ppc-gateway/ppc-gateway/p2p/Service.h @@ -36,7 +36,8 @@ class Service : public bcos::boostssl::ws::WsService bcos::boostssl::MessageFace::Ptr msg, bcos::boostssl::ws::Options options = bcos::boostssl::ws::Options(), bcos::boostssl::ws::RespCallBack respFunc = bcos::boostssl::ws::RespCallBack()); - virtual void asyncSendMessageByP2PNodeID(uint16_t type, std::string const& dstNodeID, + + virtual void asyncSendMessageByP2PNodeID(uint16_t packetType, std::string const& dstNodeID, std::shared_ptr payload, bcos::boostssl::ws::Options options = bcos::boostssl::ws::Options(), bcos::boostssl::ws::RespCallBack callback = bcos::boostssl::ws::RespCallBack()); @@ -44,10 +45,17 @@ class Service : public bcos::boostssl::ws::WsService virtual void asyncBroadcastMessage(bcos::boostssl::MessageFace::Ptr msg, bcos::boostssl::ws::Options options = bcos::boostssl::ws::Options()); + virtual void sendRespMessageBySession(bcos::boostssl::ws::WsSession::Ptr const& session, + bcos::boostssl::MessageFace::Ptr msg, std::shared_ptr&& payload); + RouterTableFactory::Ptr const& routerTableFactory() const { return m_routerTableFactory; } RouterTableInterface::Ptr const& routerTable() const { return m_routerTable; } std::string const& nodeID() const { return m_nodeID; } + bcos::boostssl::MessageFaceFactory::Ptr const& messageFactory() const + { + return m_messageFactory; + } protected: void onRecvMessage(bcos::boostssl::MessageFace::Ptr _msg, diff --git a/cpp/ppc-gateway/ppc-gateway/p2p/router/RouterManager.h b/cpp/ppc-gateway/ppc-gateway/p2p/router/RouterManager.h index f99c0182..a1701c9e 100644 --- a/cpp/ppc-gateway/ppc-gateway/p2p/router/RouterManager.h +++ b/cpp/ppc-gateway/ppc-gateway/p2p/router/RouterManager.h @@ -28,6 +28,7 @@ namespace ppc::gateway class RouterManager { public: + using Ptr = std::shared_ptr; RouterManager(Service::Ptr service); virtual ~RouterManager() = default; diff --git a/cpp/ppc-protocol/src/v1/MessageHeaderImpl.cpp b/cpp/ppc-protocol/src/v1/MessageHeaderImpl.cpp index 08ba9cdd..f14e1cac 100644 --- a/cpp/ppc-protocol/src/v1/MessageHeaderImpl.cpp +++ b/cpp/ppc-protocol/src/v1/MessageHeaderImpl.cpp @@ -29,9 +29,10 @@ using namespace ppc; void MessageOptionalHeaderImpl::encode(bcos::bytes& buffer) const { // the componentType - uint16_t componentType = - boost::asio::detail::socket_ops::host_to_network_short(m_componentType); - buffer.insert(buffer.end(), (byte*)&componentType, (byte*)&componentType + 2); + uint16_t componentTypeLen = + boost::asio::detail::socket_ops::host_to_network_short(m_componentType.size()); + buffer.insert(buffer.end(), (byte*)&componentTypeLen, (byte*)&componentTypeLen + 2); + buffer.insert(buffer.end(), m_componentType.begin(), m_componentType.end()); // the source nodeID that send the message uint16_t srcNodeLen = boost::asio::detail::socket_ops::host_to_network_short(m_srcNode.size()); buffer.insert(buffer.end(), (byte*)&srcNodeLen, (byte*)&srcNodeLen + 2); @@ -55,13 +56,17 @@ int64_t MessageOptionalHeaderImpl::decode(bcos::bytesConstRef data, uint64_t con // the componentType auto pointer = data.data() + offset; m_componentType = boost::asio::detail::socket_ops::network_to_host_short(*((uint16_t*)pointer)); - pointer += 2; + bcos::bytes componentType; + offset = decodeNetworkBuffer(componentType, data.data(), data.size(), (pointer - data.data())); + m_componentType = std::string(componentType.begin(), componentType.end()); // srcNode - offset = decodeNetworkBuffer(m_srcNode, data.data(), data.size(), (pointer - data.data())); + offset = decodeNetworkBuffer(m_srcNode, data.data(), data.size(), offset); // dstNode offset = decodeNetworkBuffer(m_dstNode, data.data(), data.size(), offset); - // dstInst - offset = decodeNetworkBuffer(m_dstInst, data.data(), data.size(), offset); + // dstInst, TODO: optimize here + bcos::bytes dstInstData; + offset = decodeNetworkBuffer(dstInstData, data.data(), data.size(), offset); + m_dstInst = std::string(dstInstData.begin(), dstInstData.end()); return offset; } @@ -144,3 +149,47 @@ int64_t MessageHeaderImpl::decode(bcos::bytesConstRef data) m_length = offset; return offset; } + +uint16_t MessageHeaderImpl::routeType() const +{ + if (m_ext & (uint16_t)ppc::gateway::GatewayMsgExtFlag::RouteByComponent) + { + return (uint16_t)RouteType::ROUTE_THROUGH_COMPONENT; + } + if (m_ext & (uint16_t)ppc::gateway::GatewayMsgExtFlag::RouteByAgency) + { + return (uint16_t)RouteType::ROUTE_THROUGH_AGENCY; + } + if (m_ext & (uint16_t)ppc::gateway::GatewayMsgExtFlag::RouteByAgency) + { + return (uint16_t)RouteType::ROUTE_THROUGH_AGENCY; + } + if (m_ext & (uint16_t)ppc::gateway::GatewayMsgExtFlag::RouteByTopic) + { + return (uint16_t)RouteType::ROUTE_THROUGH_TOPIC; + } + // default is route though nodeID + return (uint16_t)RouteType::ROUTE_THROUGH_NODEID; +} + +void MessageHeaderImpl::setRouteType(ppc::protocol::RouteType type) +{ + switch (type) + { + case RouteType::ROUTE_THROUGH_NODEID: + m_ext |= (uint16_t)ppc::gateway::GatewayMsgExtFlag::RouteByNodeID; + break; + case RouteType::ROUTE_THROUGH_COMPONENT: + m_ext |= (uint16_t)ppc::gateway::GatewayMsgExtFlag::RouteByComponent; + break; + case RouteType::ROUTE_THROUGH_AGENCY: + m_ext |= (uint16_t)ppc::gateway::GatewayMsgExtFlag::RouteByAgency; + break; + case RouteType::ROUTE_THROUGH_TOPIC: + m_ext |= (uint16_t)ppc::gateway::GatewayMsgExtFlag::RouteByTopic; + break; + default: + BOOST_THROW_EXCEPTION(WeDPRException() << errinfo_comment( + "Invalid route type: " + std::to_string((uint16_t)type))); + } +} \ No newline at end of file diff --git a/cpp/ppc-protocol/src/v1/MessageHeaderImpl.h b/cpp/ppc-protocol/src/v1/MessageHeaderImpl.h index a8dda5a9..9d9c3850 100644 --- a/cpp/ppc-protocol/src/v1/MessageHeaderImpl.h +++ b/cpp/ppc-protocol/src/v1/MessageHeaderImpl.h @@ -61,6 +61,9 @@ class MessageHeaderImpl : public MessageHeader } void setRespPacket() override { m_ext |= (uint16_t)ppc::gateway::GatewayMsgExtFlag::Response; } + uint16_t routeType() const override; + void setRouteType(ppc::protocol::RouteType type) override; + private: // version(2) + packetType(2) + ttl(2) + ext(2) + traceIDLen(2) + srcGwNodeLen(2) + dstGwNode(2) const size_t MESSAGE_MIN_LENGTH = 14; diff --git a/cpp/ppc-protocol/src/v1/MessageImpl.h b/cpp/ppc-protocol/src/v1/MessageImpl.h index 208db1b3..aec9cb3d 100644 --- a/cpp/ppc-protocol/src/v1/MessageImpl.h +++ b/cpp/ppc-protocol/src/v1/MessageImpl.h @@ -20,6 +20,9 @@ #pragma once #include "ppc-framework/Common.h" #include "ppc-framework/protocol/Message.h" +#include +#include +#include namespace ppc::protocol { @@ -75,6 +78,31 @@ class MessageBuilderImpl : public MessageBuilder { return std::make_shared(m_msgHeaderBuilder, m_maxMessageLen, buffer); } + Message::Ptr build(ppc::protocol::RouteType routeType, std::string const& topic, + std::string const& dstInst, bcos::bytes const& dstNodeID, std::string const& componentType, + bcos::bytes&& payload) override + { + auto msg = build(); + msg->header()->setRouteType(routeType); + msg->header()->optionalField()->setDstInst(dstInst); + msg->header()->optionalField()->setDstNode(dstNodeID); + msg->header()->optionalField()->setTopic(topic); + msg->header()->optionalField()->setComponentType(componentType); + msg->setPayload(std::make_shared(std::move(payload))); + return msg; + } + + bcos::boostssl::MessageFace::Ptr buildMessage() override + { + return std::make_shared(m_msgHeaderBuilder, m_maxMessageLen); + } + + std::string newSeq() override + { + std::string seq = boost::uuids::to_string(boost::uuids::random_generator()()); + seq.erase(std::remove(seq.begin(), seq.end(), '-'), seq.end()); + return seq; + } private: MessageHeaderBuilder::Ptr m_msgHeaderBuilder; diff --git a/cpp/ppc-protocol/src/v1/MessagePayloadImpl.cpp b/cpp/ppc-protocol/src/v1/MessagePayloadImpl.cpp index 59397edf..360567b4 100644 --- a/cpp/ppc-protocol/src/v1/MessagePayloadImpl.cpp +++ b/cpp/ppc-protocol/src/v1/MessagePayloadImpl.cpp @@ -31,10 +31,9 @@ int64_t MessagePayloadImpl::encode(bcos::bytes& buffer) const // version uint16_t version = boost::asio::detail::socket_ops::host_to_network_short(m_version); buffer.insert(buffer.end(), (byte*)&version, (byte*)&version + 2); - // topic - uint16_t topicLen = boost::asio::detail::socket_ops::host_to_network_short(m_topic.size()); - buffer.insert(buffer.end(), (byte*)&topicLen, (byte*)&topicLen + 2); - buffer.insert(buffer.end(), m_topic.begin(), m_topic.end()); + // seq + uint16_t seq = boost::asio::detail::socket_ops::host_to_network_short(m_seq); + buffer.insert(buffer.end(), (byte*)&seq, (byte*)&seq + 2); // data uint16_t dataLen = boost::asio::detail::socket_ops::host_to_network_short(m_data.size()); buffer.insert(buffer.end(), (byte*)&dataLen, (byte*)&dataLen + 2); @@ -56,12 +55,10 @@ int64_t MessagePayloadImpl::decode(bcos::bytesConstRef buffer) // the version m_version = boost::asio::detail::socket_ops::network_to_host_short(*((uint16_t*)pointer)); pointer += 2; - // topic - bcos::bytes topicData; - auto offset = - decodeNetworkBuffer(topicData, buffer.data(), buffer.size(), (pointer - buffer.data())); - m_topic = std::string(topicData.begin(), topicData.end()); + // the seq + CHECK_OFFSET_WITH_THROW_EXCEPTION((pointer - buffer.data()), buffer.size()); + m_seq = boost::asio::detail::socket_ops::network_to_host_short(*((uint16_t*)pointer)); + pointer += 2; // data - offset = decodeNetworkBuffer(m_data, buffer.data(), buffer.size(), offset); - return offset; + return decodeNetworkBuffer(m_data, buffer.data(), buffer.size(), (pointer - buffer.data())); } \ No newline at end of file diff --git a/cpp/ppc-protocol/src/v1/MessagePayloadImpl.h b/cpp/ppc-protocol/src/v1/MessagePayloadImpl.h index f7f5a3e8..c85c0589 100644 --- a/cpp/ppc-protocol/src/v1/MessagePayloadImpl.h +++ b/cpp/ppc-protocol/src/v1/MessagePayloadImpl.h @@ -35,6 +35,7 @@ class MessagePayloadImpl : public MessagePayload int64_t decode(bcos::bytesConstRef data) override; private: + // version + seq + dataLen const unsigned int MIN_PAYLOAD_LEN = 6; }; diff --git a/cpp/ppc-tars-protocol/ppc-tars-protocol/impl/NodeInfoImpl.cpp b/cpp/ppc-tars-protocol/ppc-tars-protocol/impl/NodeInfoImpl.cpp new file mode 100644 index 00000000..e8f585d4 --- /dev/null +++ b/cpp/ppc-tars-protocol/ppc-tars-protocol/impl/NodeInfoImpl.cpp @@ -0,0 +1,40 @@ +/** + * Copyright (C) 2023 WeDPR. + * SPDX-License-Identifier: Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @file NodeInfoImpl.h + * @author: yujiechen + * @date 2024-08-26 + */ + +#include "NodeInfoImpl.h" +#include "../Common.h" + +using namespace ppctars; +using namespace ppc::protocol; + +void NodeInfoImpl::encode(bcos::bytes& data) const +{ + tars::TarsOutputStream output; + m_inner()->writeTo(output); + output.getByteBuffer().swap(data); +} +void NodeInfoImpl::decode(bcos::bytesConstRef data) +{ + tars::TarsInputStream input; + input.setBuffer((const char*)data.data(), data.size()); + m_inner()->readFrom(input); + m_components = + std::set(m_inner()->components.begin(), m_inner()->components.end()); +} \ No newline at end of file diff --git a/cpp/ppc-tars-protocol/ppc-tars-protocol/impl/NodeInfoImpl.h b/cpp/ppc-tars-protocol/ppc-tars-protocol/impl/NodeInfoImpl.h new file mode 100644 index 00000000..ff4e1627 --- /dev/null +++ b/cpp/ppc-tars-protocol/ppc-tars-protocol/impl/NodeInfoImpl.h @@ -0,0 +1,88 @@ +/** + * Copyright (C) 2023 WeDPR. + * SPDX-License-Identifier: Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @file NodeInfoImpl.h + * @author: yujiechen + * @date 2024-08-26 + */ +#pragma once +#include "ppc-framework/protocol/INodeInfo.h" +#include "ppc-tars-protocol/tars/NodeInfo.h" +#include +namespace ppc::protocol +{ +// the node information +class NodeInfoImpl : public INodeInfo +{ +public: + using Ptr = std::shared_ptr; + explicit NodeInfoImpl(std::function inner) : m_inner(std::move(inner)) {} + + NodeInfoImpl(bcos::bytesConstRef const& nodeID) + : m_inner([inner = ppctars::NodeInfo()]() mutable { return &inner; }) + { + m_inner()->nodeID = std::vector(nodeID.begin(), nodeID.end()); + } + NodeInfoImpl(bcos::bytesConstRef const& nodeID, std::string const& endPoint) + : NodeInfoImpl(nodeID) + { + m_inner()->endPoint = endPoint; + } + ~NodeInfoImpl() override = default; + + void setComponents(std::vector const& components) override + { + m_components = std::set(components.begin(), components.end()); + m_inner()->components = components; + } + std::set const& components() const override { return m_components; } + + std::string const& endPoint() const override { return m_inner()->endPoint; } + + bcos::bytesConstRef nodeID() const override + { + return {reinterpret_cast(m_inner()->nodeID.data()), + m_inner()->nodeID.size()}; + } + + void encode(bcos::bytes& data) const override; + void decode(bcos::bytesConstRef data) override; + ppctars::NodeInfo const& inner() { return *(m_inner()); } + + void setFront(ppc::front::IFront::Ptr&& front) override { m_front = std::move(front); } + ppc::front::IFront::Ptr const& getFront() const override { return m_front; } + +private: + ppc::front::IFront::Ptr m_front; + std::set m_components; + std::function m_inner; +}; + +class NodeInfoFactory : public INodeInfoFactory +{ +public: + using Ptr = std::shared_ptr; + NodeInfoFactory(bcos::bytesConstRef const& nodeID) : INodeInfoFactory(nodeID.toBytes()) {} + ~NodeInfoFactory() override {} + + INodeInfo::Ptr build() override { return std::make_shared(bcos::ref(m_nodeID)); } + + + INodeInfo::Ptr build(std::string const& endPoint) override + { + return std::make_shared(bcos::ref(m_nodeID), endPoint); + } +}; +} // namespace ppc::protocol \ No newline at end of file diff --git a/cpp/ppc-tars-protocol/ppc-tars-protocol/tars/NodeInfo.tars b/cpp/ppc-tars-protocol/ppc-tars-protocol/tars/NodeInfo.tars new file mode 100644 index 00000000..9a0c67ec --- /dev/null +++ b/cpp/ppc-tars-protocol/ppc-tars-protocol/tars/NodeInfo.tars @@ -0,0 +1,15 @@ +module ppctars +{ + struct NodeInfo + { + 1 require vector nodeID; + 2 require string endPoint; + 3 optional vector components; + }; + struct GatewayNodeInfo + { + 1 require string p2pNodeID; + 2 require string agency; + 3 optional vector nodeList; + }; +}; From b6cee04154585dff832b7f48d4aeb4ad9c1f46c5 Mon Sep 17 00:00:00 2001 From: cyjseagull Date: Tue, 27 Aug 2024 20:58:32 +0800 Subject: [PATCH 9/9] add gateway-router-manager (#12) --- cpp/ppc-framework/gateway/GatewayProtocol.h | 5 +- .../ppc-gateway/gateway/GatewayImpl.cpp | 4 + .../ppc-gateway/gateway/GatewayImpl.h | 2 + .../gateway/router/GatewayNodeInfo.h | 15 ++ .../gateway/router/GatewayNodeInfoImpl.cpp | 10 + .../gateway/router/GatewayNodeInfoImpl.h | 4 + .../gateway/router/GatewayRouterManager.cpp | 183 ++++++++++++++++++ .../gateway/router/GatewayRouterManager.h | 70 +++++++ .../gateway/router/LocalRouter.cpp | 2 + .../ppc-gateway/gateway/router/LocalRouter.h | 31 ++- .../gateway/router/PeerRouterTable.cpp | 8 + .../ppc-gateway/p2p/router/RouterManager.h | 3 +- .../ppc-tars-protocol/tars/NodeInfo.tars | 1 + 13 files changed, 334 insertions(+), 4 deletions(-) create mode 100644 cpp/ppc-gateway/ppc-gateway/gateway/router/GatewayRouterManager.cpp create mode 100644 cpp/ppc-gateway/ppc-gateway/gateway/router/GatewayRouterManager.h diff --git a/cpp/ppc-framework/gateway/GatewayProtocol.h b/cpp/ppc-framework/gateway/GatewayProtocol.h index b91137d6..ebd9b7a3 100644 --- a/cpp/ppc-framework/gateway/GatewayProtocol.h +++ b/cpp/ppc-framework/gateway/GatewayProtocol.h @@ -28,7 +28,10 @@ enum class GatewayPacketType : uint16_t BroadcastMessage = 0x01, RouterTableSyncSeq = 0x10, RouterTableResponse = 0x11, - RouterTableRequest = 0x12 + RouterTableRequest = 0x12, + SyncNodeSeq = 0x20, + RequestNodeStatus = 0x21, + ResponseNodeStatus = 0x22, }; enum class GatewayMsgExtFlag : uint16_t diff --git a/cpp/ppc-gateway/ppc-gateway/gateway/GatewayImpl.cpp b/cpp/ppc-gateway/ppc-gateway/gateway/GatewayImpl.cpp index 7b4240c9..6707fae9 100644 --- a/cpp/ppc-gateway/ppc-gateway/gateway/GatewayImpl.cpp +++ b/cpp/ppc-gateway/ppc-gateway/gateway/GatewayImpl.cpp @@ -51,6 +51,8 @@ GatewayImpl::GatewayImpl(Service::Ptr const& service, m_service->registerMsgHandler((uint16_t)GatewayPacketType::BroadcastMessage, boost::bind(&GatewayImpl::onReceiveBroadcastMessage, this, boost::placeholders::_1, boost::placeholders::_2)); + m_gatewayRouterManager = std::make_shared( + m_service, m_gatewayInfoFactory, m_localRouter, m_peerRouter); } void GatewayImpl::start() @@ -63,6 +65,7 @@ void GatewayImpl::start() m_running = true; m_service->start(); m_p2pRouterManager->start(); + m_gatewayRouterManager->start(); GATEWAY_LOG(INFO) << LOG_DESC("Start gateway success"); } @@ -76,6 +79,7 @@ void GatewayImpl::stop() m_running = false; m_service->stop(); m_p2pRouterManager->stop(); + m_gatewayRouterManager->stop(); GATEWAY_LOG(INFO) << LOG_DESC("Stop gateway success"); } diff --git a/cpp/ppc-gateway/ppc-gateway/gateway/GatewayImpl.h b/cpp/ppc-gateway/ppc-gateway/gateway/GatewayImpl.h index b71bd5b1..9d2ced23 100644 --- a/cpp/ppc-gateway/ppc-gateway/gateway/GatewayImpl.h +++ b/cpp/ppc-gateway/ppc-gateway/gateway/GatewayImpl.h @@ -22,6 +22,7 @@ #include "ppc-gateway/gateway/router/GatewayNodeInfo.h" #include "ppc-gateway/p2p/Service.h" #include "ppc-gateway/p2p/router/RouterManager.h" +#include "router/GatewayRouterManager.h" #include "router/LocalRouter.h" #include "router/PeerRouterTable.h" @@ -80,6 +81,7 @@ class GatewayImpl : public IGateway, public std::enable_shared_from_this #include +#include namespace ppc::gateway { class GatewayNodeInfo @@ -33,6 +35,9 @@ class GatewayNodeInfo virtual std::string const& p2pNodeID() const = 0; // the agency virtual std::string const& agency() const = 0; + virtual uint32_t statusSeq() const = 0; + virtual void setStatusSeq(uint32_t statusSeq) = 0; + // get the node information by nodeID virtual ppc::protocol::INodeInfo::Ptr nodeInfo(bcos::bytes const& nodeID) const = 0; virtual bool tryAddNodeInfo(ppc::protocol::INodeInfo::Ptr const& nodeInfo) = 0; @@ -51,6 +56,7 @@ class GatewayNodeInfo virtual void unRegisterTopic(bcos::bytes const& nodeID, std::string const& topic) = 0; virtual std::map nodeList() const = 0; + virtual uint16_t nodeSize() const = 0; }; class GatewayNodeInfoFactory @@ -71,4 +77,13 @@ struct GatewayNodeInfoCmp } }; using GatewayNodeInfos = std::set; + +inline std::string printNodeStatus(GatewayNodeInfo::Ptr const& status) +{ + std::ostringstream stringstream; + stringstream << LOG_KV("p2pNodeID", status->p2pNodeID()) << LOG_KV("agency", status->agency()) + << LOG_KV("statusSeq", status->statusSeq()) + << LOG_KV("nodeSize", status->nodeSize()); + return stringstream.str(); +} } // namespace ppc::gateway \ No newline at end of file diff --git a/cpp/ppc-gateway/ppc-gateway/gateway/router/GatewayNodeInfoImpl.cpp b/cpp/ppc-gateway/ppc-gateway/gateway/router/GatewayNodeInfoImpl.cpp index f7c9cefe..3c718fe9 100644 --- a/cpp/ppc-gateway/ppc-gateway/gateway/router/GatewayNodeInfoImpl.cpp +++ b/cpp/ppc-gateway/ppc-gateway/gateway/router/GatewayNodeInfoImpl.cpp @@ -36,6 +36,16 @@ std::string const& GatewayNodeInfoImpl::agency() const { return m_inner()->agency; } + +uint32_t GatewayNodeInfoImpl::statusSeq() const +{ + return m_inner()->statusSeq; +} +void GatewayNodeInfoImpl::setStatusSeq(uint32_t statusSeq) +{ + m_inner()->statusSeq = statusSeq; +} + // get the node information by nodeID INodeInfo::Ptr GatewayNodeInfoImpl::nodeInfo(bcos::bytes const& nodeID) const { diff --git a/cpp/ppc-gateway/ppc-gateway/gateway/router/GatewayNodeInfoImpl.h b/cpp/ppc-gateway/ppc-gateway/gateway/router/GatewayNodeInfoImpl.h index cb0dfc10..72c6d440 100644 --- a/cpp/ppc-gateway/ppc-gateway/gateway/router/GatewayNodeInfoImpl.h +++ b/cpp/ppc-gateway/ppc-gateway/gateway/router/GatewayNodeInfoImpl.h @@ -66,6 +66,10 @@ class GatewayNodeInfoImpl : public GatewayNodeInfo bcos::WriteGuard l(x_nodeList); return m_nodeList; } + uint32_t statusSeq() const override; + void setStatusSeq(uint32_t statusSeq) override; + + virtual uint16_t nodeSize() const override { return m_nodeList.size(); } private: std::function m_inner; diff --git a/cpp/ppc-gateway/ppc-gateway/gateway/router/GatewayRouterManager.cpp b/cpp/ppc-gateway/ppc-gateway/gateway/router/GatewayRouterManager.cpp new file mode 100644 index 00000000..a26844e4 --- /dev/null +++ b/cpp/ppc-gateway/ppc-gateway/gateway/router/GatewayRouterManager.cpp @@ -0,0 +1,183 @@ +/** + * Copyright (C) 2023 WeDPR. + * SPDX-License-Identifier: Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @file GatewayRouterManager.h + * @author: yujiechen + * @date 2024-08-26 + */ +#include "GatewayRouterManager.h" +#include "ppc-framework/gateway/GatewayProtocol.h" +#include + +using namespace ppc::protocol; +using namespace ppc; +using namespace bcos; +using namespace ppc::gateway; +using namespace bcos::boostssl; +using namespace bcos::boostssl::ws; + +GatewayRouterManager::GatewayRouterManager(Service::Ptr service, + GatewayNodeInfoFactory::Ptr nodeStatusFactory, LocalRouter::Ptr localRouter, + PeerRouterTable::Ptr peerRouter) + : m_service(std::move(service)), + m_nodeStatusFactory(std::move(nodeStatusFactory)), + m_localRouter(std::move(localRouter)), + m_peerRouter(std::move(peerRouter)) +{ + m_service->registerMsgHandler((uint16_t)GatewayPacketType::SyncNodeSeq, + boost::bind(&GatewayRouterManager::onReceiveNodeSeqMessage, this, boost::placeholders::_1, + boost::placeholders::_2)); + + m_service->registerMsgHandler((uint16_t)GatewayPacketType::RequestNodeStatus, + boost::bind(&GatewayRouterManager::onReceiveRequestNodeStatusMsg, this, + boost::placeholders::_1, boost::placeholders::_2)); + + m_service->registerMsgHandler((uint16_t)GatewayPacketType::ResponseNodeStatus, + boost::bind(&GatewayRouterManager::onRecvResponseNodeStatusMsg, this, + boost::placeholders::_1, boost::placeholders::_2)); + + m_timer = std::make_shared(SEQ_SYNC_PERIOD, "seqSync"); + // broadcast seq periodically + m_timer->registerTimeoutHandler([this]() { broadcastStatusSeq(); }); +} + + +void GatewayRouterManager::start() +{ + if (m_running) + { + GATEWAY_LOG(INFO) << LOG_DESC("GatewayRouterManager has already been started"); + return; + } + m_running = true; + m_timer->start(); + GATEWAY_LOG(INFO) << LOG_DESC("start GatewayRouterManager success"); +} + +void GatewayRouterManager::stop() +{ + if (!m_running) + { + GATEWAY_LOG(INFO) << LOG_DESC("GatewayRouterManager has already been stopped"); + return; + } + m_running = false; + m_timer->stop(); + GATEWAY_LOG(INFO) << LOG_DESC("stop GatewayRouterManager success"); +} + +void GatewayRouterManager::onReceiveNodeSeqMessage(MessageFace::Ptr msg, WsSession::Ptr session) +{ + auto statusSeq = + boost::asio::detail::socket_ops::network_to_host_long(*((uint32_t*)msg->payload()->data())); + + auto p2pMessage = std::dynamic_pointer_cast(msg); + auto const& from = (p2pMessage->header()->srcGwNode().size() > 0) ? + p2pMessage->header()->srcGwNode() : + session->nodeId(); + auto statusSeqChanged = statusChanged(from, statusSeq); + if (!statusSeqChanged) + { + return; + } + // status changed, request for the nodeStatus + GATEWAY_LOG(TRACE) << LOG_DESC("onReceiveNodeSeqMessage") << LOG_KV("from", from) + << LOG_KV("statusSeq", statusSeq); + m_service->asyncSendMessageByP2PNodeID( + (uint16_t)GatewayPacketType::RequestNodeStatus, from, std::make_shared()); +} + + +bool GatewayRouterManager::statusChanged(std::string const& p2pNodeID, uint32_t seq) +{ + bool ret = true; + ReadGuard l(x_p2pID2Seq); + auto it = m_p2pID2Seq.find(p2pNodeID); + if (it != m_p2pID2Seq.end()) + { + ret = (seq > it->second); + } + return ret; +} + +void GatewayRouterManager::broadcastStatusSeq() +{ + m_timer->restart(); + auto message = std::dynamic_pointer_cast(m_service->messageFactory()->buildMessage()); + message->setPacketType((uint16_t)GatewayPacketType::SyncNodeSeq); + auto seq = m_localRouter->statusSeq(); + auto statusSeq = boost::asio::detail::socket_ops::host_to_network_long(seq); + auto payload = std::make_shared((byte*)&statusSeq, (byte*)&statusSeq + 4); + message->setPayload(payload); + GATEWAY_LOG(TRACE) << LOG_DESC("broadcastStatusSeq") << LOG_KV("seq", seq); + m_service->asyncBroadcastMessage(message); +} + + +void GatewayRouterManager::onReceiveRequestNodeStatusMsg( + MessageFace::Ptr msg, WsSession::Ptr session) +{ + auto p2pMessage = std::dynamic_pointer_cast(msg); + auto const& from = (!p2pMessage->header()->srcGwNode().empty()) ? + p2pMessage->header()->srcGwNode() : + session->nodeId(); + + auto nodeStatusData = m_localRouter->generateNodeStatus(); + if (!nodeStatusData) + { + GATEWAY_LOG(WARNING) << LOG_DESC("onReceiveRequestNodeStatusMsg: generate nodeInfo error") + << LOG_KV("from", from); + return; + } + GATEWAY_LOG(TRACE) << LOG_DESC("onReceiveRequestNodeStatusMsg: response the latest nodeStatus") + << LOG_KV("from", from); + m_service->asyncSendMessageByP2PNodeID( + (uint16_t)GatewayPacketType::ResponseNodeStatus, from, nodeStatusData); +} + +void GatewayRouterManager::onRecvResponseNodeStatusMsg(MessageFace::Ptr msg, WsSession::Ptr session) +{ + auto nodeStatus = m_nodeStatusFactory->build(); + nodeStatus->decode(bytesConstRef(msg->payload()->data(), msg->payload()->size())); + + auto p2pMessage = std::dynamic_pointer_cast(msg); + auto const& from = (!p2pMessage->header()->srcGwNode().empty()) ? + p2pMessage->header()->srcGwNode() : + session->nodeId(); + + GATEWAY_LOG(INFO) << LOG_DESC("onRecvResponseNodeStatusMsg") << LOG_KV("from", from) + << LOG_KV("statusSeq", nodeStatus->statusSeq()) + << LOG_KV("agency", nodeStatus->agency()); + updatePeerNodeStatus(from, nodeStatus); +} + +void GatewayRouterManager::updatePeerNodeStatus( + std::string const& p2pID, GatewayNodeInfo::Ptr status) +{ + auto statusSeq = status->statusSeq(); + { + UpgradableGuard l(x_p2pID2Seq); + if (m_p2pID2Seq.contains(p2pID) && (m_p2pID2Seq.at(p2pID) >= statusSeq)) + { + return; + } + UpgradeGuard ul(l); + m_p2pID2Seq[p2pID] = statusSeq; + } + GATEWAY_LOG(INFO) << LOG_DESC("updatePeerNodeStatus") << LOG_KV("from", p2pID) + << LOG_KV("statusSeq", status->statusSeq()) + << LOG_KV("agency", status->agency()); + m_peerRouter->updateGatewayInfo(status); +} \ No newline at end of file diff --git a/cpp/ppc-gateway/ppc-gateway/gateway/router/GatewayRouterManager.h b/cpp/ppc-gateway/ppc-gateway/gateway/router/GatewayRouterManager.h new file mode 100644 index 00000000..4cf9b0ba --- /dev/null +++ b/cpp/ppc-gateway/ppc-gateway/gateway/router/GatewayRouterManager.h @@ -0,0 +1,70 @@ +/** + * Copyright (C) 2023 WeDPR. + * SPDX-License-Identifier: Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @file GatewayRouterManager.h + * @author: yujiechen + * @date 2024-08-26 + */ +#pragma once +#include "ppc-gateway/gateway/router/GatewayNodeInfo.h" +#include "ppc-gateway/gateway/router/LocalRouter.h" +#include "ppc-gateway/gateway/router/PeerRouterTable.h" +#include "ppc-gateway/p2p/Service.h" +#include +#include + +namespace ppc::gateway +{ +class GatewayRouterManager +{ +public: + using Ptr = std::shared_ptr; + GatewayRouterManager(Service::Ptr service, GatewayNodeInfoFactory::Ptr nodeStatusFactory, + LocalRouter::Ptr localRouter, PeerRouterTable::Ptr peerRouter); + virtual void start(); + virtual void stop(); + +protected: + virtual void onReceiveNodeSeqMessage( + bcos::boostssl::MessageFace::Ptr msg, bcos::boostssl::ws::WsSession::Ptr session); + + virtual void onReceiveRequestNodeStatusMsg( + bcos::boostssl::MessageFace::Ptr msg, bcos::boostssl::ws::WsSession::Ptr session); + + virtual void onRecvResponseNodeStatusMsg( + bcos::boostssl::MessageFace::Ptr msg, bcos::boostssl::ws::WsSession::Ptr session); + bool statusChanged(std::string const& p2pNodeID, uint32_t seq); + void broadcastStatusSeq(); + + void updatePeerNodeStatus(std::string const& p2pID, GatewayNodeInfo::Ptr status); + +private: + Service::Ptr m_service; + GatewayNodeInfoFactory::Ptr m_nodeStatusFactory; + std::shared_ptr m_timer; + + LocalRouter::Ptr m_localRouter; + PeerRouterTable::Ptr m_peerRouter; + + bool m_running = false; + + // P2pID => statusSeq + std::map m_p2pID2Seq; + mutable bcos::SharedMutex x_p2pID2Seq; + + // TODO: make this configurable + unsigned const SEQ_SYNC_PERIOD = 3000; +}; +} // namespace ppc::gateway \ No newline at end of file diff --git a/cpp/ppc-gateway/ppc-gateway/gateway/router/LocalRouter.cpp b/cpp/ppc-gateway/ppc-gateway/gateway/router/LocalRouter.cpp index 9df4e45f..7d934daa 100644 --- a/cpp/ppc-gateway/ppc-gateway/gateway/router/LocalRouter.cpp +++ b/cpp/ppc-gateway/ppc-gateway/gateway/router/LocalRouter.cpp @@ -25,6 +25,7 @@ using namespace bcos; using namespace ppc::protocol; using namespace ppc::gateway; +// Note: the change of the topic will not trigger router-update void LocalRouter::registerTopic(bcos::bytesConstRef _nodeID, std::string const& topic) { m_routerInfo->registerTopic(_nodeID.toBytes(), topic); @@ -48,6 +49,7 @@ void LocalRouter::registerTopic(bcos::bytesConstRef _nodeID, std::string const& } } +// Note: the change of the topic will not trigger router-update void LocalRouter::unRegisterTopic(bcos::bytesConstRef _nodeID, std::string const& topic) { m_routerInfo->unRegisterTopic(_nodeID.toBytes(), topic); diff --git a/cpp/ppc-gateway/ppc-gateway/gateway/router/LocalRouter.h b/cpp/ppc-gateway/ppc-gateway/gateway/router/LocalRouter.h index 194ef6ab..8b931c9c 100644 --- a/cpp/ppc-gateway/ppc-gateway/gateway/router/LocalRouter.h +++ b/cpp/ppc-gateway/ppc-gateway/gateway/router/LocalRouter.h @@ -42,10 +42,19 @@ class LocalRouter virtual bool registerNodeInfo(ppc::protocol::INodeInfo::Ptr const& nodeInfo) { nodeInfo->setFront(m_frontBuilder->buildClient(nodeInfo->endPoint())); - return m_routerInfo->tryAddNodeInfo(nodeInfo); + auto ret = m_routerInfo->tryAddNodeInfo(nodeInfo); + if (ret) + { + increaseSeq(); + } + return ret; } - virtual void unRegisterNode(bcos::bytes const& nodeID) { m_routerInfo->removeNodeInfo(nodeID); } + virtual void unRegisterNode(bcos::bytes const& nodeID) + { + m_routerInfo->removeNodeInfo(nodeID); + increaseSeq(); + } virtual void registerTopic(bcos::bytesConstRef nodeID, std::string const& topic); virtual void unRegisterTopic(bcos::bytesConstRef nodeID, std::string const& topic); @@ -57,10 +66,28 @@ class LocalRouter virtual bool dispatcherMessage(ppc::protocol::Message::Ptr const& msg, ppc::protocol::ReceiveMsgFunc callback, bool holding = true); + std::shared_ptr generateNodeStatus() + { + auto data = std::make_shared(); + m_routerInfo->encode(*data); + return data; + } + uint32_t statusSeq() { return m_statusSeq; } + +private: + uint32_t increaseSeq() + { + uint32_t statusSeq = ++m_statusSeq; + return statusSeq; + } + + private: ppc::front::IFrontBuilder::Ptr m_frontBuilder; GatewayNodeInfo::Ptr m_routerInfo; + std::atomic m_statusSeq{1}; + // NodeID=>topics using Topics = std::set; std::map m_topicInfo; diff --git a/cpp/ppc-gateway/ppc-gateway/gateway/router/PeerRouterTable.cpp b/cpp/ppc-gateway/ppc-gateway/gateway/router/PeerRouterTable.cpp index a2bccd0a..e5367eda 100644 --- a/cpp/ppc-gateway/ppc-gateway/gateway/router/PeerRouterTable.cpp +++ b/cpp/ppc-gateway/ppc-gateway/gateway/router/PeerRouterTable.cpp @@ -33,8 +33,16 @@ void PeerRouterTable::updateGatewayInfo(GatewayNodeInfo::Ptr const& gatewayInfo) for (auto const& it : nodeList) { // update nodeID => gatewayInfos + if (!m_nodeID2GatewayInfos.count(it.first)) + { + m_nodeID2GatewayInfos.insert(std::make_pair(it.first, GatewayNodeInfos())); + } m_nodeID2GatewayInfos[it.first].insert(gatewayInfo); } + if (!m_agency2GatewayInfos.count(gatewayInfo->agency())) + { + m_agency2GatewayInfos.insert(std::make_pair(gatewayInfo->agency(), GatewayNodeInfos())); + } // update agency => gatewayInfos m_agency2GatewayInfos[gatewayInfo->agency()].insert(gatewayInfo); } diff --git a/cpp/ppc-gateway/ppc-gateway/p2p/router/RouterManager.h b/cpp/ppc-gateway/ppc-gateway/p2p/router/RouterManager.h index a1701c9e..64ebf4c8 100644 --- a/cpp/ppc-gateway/ppc-gateway/p2p/router/RouterManager.h +++ b/cpp/ppc-gateway/ppc-gateway/p2p/router/RouterManager.h @@ -61,7 +61,6 @@ class RouterManager // for message forward Service::Ptr m_service; std::shared_ptr m_routerTimer; - std::atomic m_statusSeq{1}; // called when the given node unreachable std::vector> m_unreachableHandlers; @@ -69,5 +68,7 @@ class RouterManager std::map m_node2Seq; mutable bcos::SharedMutex x_node2Seq; + + std::atomic m_statusSeq{1}; }; } // namespace ppc::gateway \ No newline at end of file diff --git a/cpp/ppc-tars-protocol/ppc-tars-protocol/tars/NodeInfo.tars b/cpp/ppc-tars-protocol/ppc-tars-protocol/tars/NodeInfo.tars index 9a0c67ec..06055197 100644 --- a/cpp/ppc-tars-protocol/ppc-tars-protocol/tars/NodeInfo.tars +++ b/cpp/ppc-tars-protocol/ppc-tars-protocol/tars/NodeInfo.tars @@ -11,5 +11,6 @@ module ppctars 1 require string p2pNodeID; 2 require string agency; 3 optional vector nodeList; + 4 optional int statusSeq; }; };